a little renaming and moving around of constants

This commit is contained in:
Torsten Ruger 2014-04-22 23:35:15 +03:00
parent 2fdc59c13c
commit 7ff8fa8802
5 changed files with 55 additions and 52 deletions

View File

@ -78,6 +78,11 @@ module Asm
end end
def assemble_to_string def assemble_to_string
#put the strings at the end of the assembled code.
# adding them will fix their position and make them assemble after
@string_table.values.each do |data|
add_value data
end
io = StringIO.new io = StringIO.new
assemble(io) assemble(io)
io.string io.string

View File

@ -45,42 +45,6 @@ module Asm
4 4
end end
OPC_DATA_PROCESSING = 0b00
OPC_MEMORY_ACCESS = 0b01
OPC_STACK = 0b10
# These are used differently in the
# instruction encoders
OPCODES = {
:adc => 0b0101, :add => 0b0100,
:and => 0b0000, :bic => 0b1110,
:eor => 0b0001, :orr => 0b1100,
:rsb => 0b0011, :rsc => 0b0111,
:sbc => 0b0110, :sub => 0b0010,
# for these Rn is sbz (should be zero)
:mov => 0b1101,
:mvn => 0b1111,
# for these Rd is sbz and S=1
:cmn => 0b1011,
:cmp => 0b1010,
:teq => 0b1001,
:tst => 0b1000,
:b => 0b1010,
:bl => 0b1011,
:bx => 0b00010010
}
COND_BITS = {
:al => 0b1110, :eq => 0b0000,
:ne => 0b0001, :cs => 0b0010,
:mi => 0b0100, :hi => 0b1000,
:cc => 0b0011, :pl => 0b0101,
:ls => 0b1001, :vc => 0b0111,
:lt => 0b1011, :le => 0b1101,
:ge => 0b1010, :gt => 0b1100,
:vs => 0b0110
}
RelocHandler = nil # Asm::Arm.method(:write_resolved_relocation) RelocHandler = nil # Asm::Arm.method(:write_resolved_relocation)
def assemble(io, as) def assemble(io, as)
@ -88,34 +52,34 @@ module Asm
case opcode case opcode
when :adc, :add, :and, :bic, :eor, :orr, :rsb, :rsc, :sbc, :sub when :adc, :add, :and, :bic, :eor, :orr, :rsb, :rsc, :sbc, :sub
builder = NormalBuilder.new(OPC_DATA_PROCESSING, OPCODES[opcode], s) builder = NormalBuilder.new(OPC_DATA_PROCESSING, OPCODES[opcode], s)
builder.cond = COND_BITS[@cond] builder.cond = COND_CODES[@cond]
builder.rd = reg_ref(args[0]) builder.rd = reg_ref(args[0])
builder.rn = reg_ref(args[1]) builder.rn = reg_ref(args[1])
builder.build_operand args[2] builder.build_operand args[2]
builder.assemble io, as builder.assemble io, as
when :cmn, :cmp, :teq, :tst when :cmn, :cmp, :teq, :tst
builder = NormalBuilder.new(OPC_DATA_PROCESSING, OPCODES[opcode], 1) builder = NormalBuilder.new(OPC_DATA_PROCESSING, OPCODES[opcode], 1)
builder.cond = COND_BITS[@cond] builder.cond = COND_CODES[@cond]
builder.rn = reg_ref(args[0]) builder.rn = reg_ref(args[0])
builder.rd = 0 builder.rd = 0
builder.build_operand args[1] builder.build_operand args[1]
builder.assemble io, as builder.assemble io, as
when :mov, :mvn when :mov, :mvn
builder = NormalBuilder.new(OPC_DATA_PROCESSING, OPCODES[opcode], s) builder = NormalBuilder.new(OPC_DATA_PROCESSING, OPCODES[opcode], s)
builder.cond = COND_BITS[@cond] builder.cond = COND_CODES[@cond]
builder.rn = 0 builder.rn = 0
builder.rd = reg_ref(args[0]) builder.rd = reg_ref(args[0])
builder.build_operand args[1] builder.build_operand args[1]
builder.assemble io, as builder.assemble io, as
when :strb, :str when :strb, :str
builder = MemoryAccessBuilder.new(OPC_MEMORY_ACCESS, (opcode == :strb ? 1 : 0), 0) builder = MemoryAccessBuilder.new(OPC_MEMORY_ACCESS, (opcode == :strb ? 1 : 0), 0)
builder.cond = COND_BITS[@cond] builder.cond = COND_CODES[@cond]
builder.rd = reg_ref(args[1]) builder.rd = reg_ref(args[1])
builder.build_operand args[0] builder.build_operand args[0]
builder.assemble io, as, self builder.assemble io, as, self
when :ldrb, :ldr when :ldrb, :ldr
builder = MemoryAccessBuilder.new(OPC_MEMORY_ACCESS, (opcode == :ldrb ? 1 : 0), 1) builder = MemoryAccessBuilder.new(OPC_MEMORY_ACCESS, (opcode == :ldrb ? 1 : 0), 1)
builder.cond = COND_BITS[@cond] builder.cond = COND_CODES[@cond]
builder.rd = reg_ref(args[0]) builder.rd = reg_ref(args[0])
builder.build_operand args[1] builder.build_operand args[1]
builder.assemble io, as, self builder.assemble io, as, self
@ -127,7 +91,7 @@ module Asm
else else
builder = StackBuilder.new(0,1,1,1) builder = StackBuilder.new(0,1,1,1)
end end
builder.cond = COND_BITS[@cond] builder.cond = COND_CODES[@cond]
builder.rn = 13 # sp builder.rn = 13 # sp
builder.build_operand args builder.build_operand args
builder.assemble io, as builder.assemble io, as
@ -148,17 +112,13 @@ module Asm
else else
raise "else not coded #{arg.inspect}" raise "else not coded #{arg.inspect}"
end end
io.write_uint8 OPCODES[opcode] | (COND_BITS[@cond] << 4) io.write_uint8 OPCODES[opcode] | (COND_CODES[@cond] << 4)
when :bx
rm = reg_ref(args[0])
io.write_uint32 rm | (0b1111111111110001 << 4) | (OPCODES[:bx] << 16+4) |
(COND_BITS[@cond] << 16+4+8)
when :swi when :swi
arg = args[0] arg = args[0]
if (arg.is_a?(Asm::NumLiteralNode)) if (arg.is_a?(Asm::NumLiteralNode))
packed = [arg.value].pack('L')[0,3] packed = [arg.value].pack('L')[0,3]
io << packed io << packed
io.write_uint8 0b1111 | (COND_BITS[@cond] << 4) io.write_uint8 0b1111 | (COND_CODES[@cond] << 4)
else else
raise Asm::AssemblyError.new(Asm::ERRSTR_INVALID_ARG, arg) raise Asm::AssemblyError.new(Asm::ERRSTR_INVALID_ARG, arg)
end end

View File

@ -1,6 +1,40 @@
module Asm module Asm
module Arm module Arm
module InstructionTools module InstructionTools
OPCODES = {
:adc => 0b0101, :add => 0b0100,
:and => 0b0000, :bic => 0b1110,
:eor => 0b0001, :orr => 0b1100,
:rsb => 0b0011, :rsc => 0b0111,
:sbc => 0b0110, :sub => 0b0010,
# for these Rn is sbz (should be zero)
:mov => 0b1101,
:mvn => 0b1111,
# for these Rd is sbz and S=1
:cmn => 0b1011,
:cmp => 0b1010,
:teq => 0b1001,
:tst => 0b1000,
:b => 0b1010,
:bl => 0b1011,
:bx => 0b00010010
}
COND_CODES = {
:al => 0b1110, :eq => 0b0000,
:ne => 0b0001, :cs => 0b0010,
:mi => 0b0100, :hi => 0b1000,
:cc => 0b0011, :pl => 0b0101,
:ls => 0b1001, :vc => 0b0111,
:lt => 0b1011, :le => 0b1101,
:ge => 0b1010, :gt => 0b1100,
:vs => 0b0110
}
OPC_DATA_PROCESSING = 0b00
OPC_MEMORY_ACCESS = 0b01
OPC_STACK = 0b10
def reg_ref(arg) def reg_ref(arg)
if (not arg.is_a?(Asm::RegisterNode)) if (not arg.is_a?(Asm::RegisterNode))
raise Asm::AssemblyError.new('argument must be a register', arg) raise Asm::AssemblyError.new('argument must be a register', arg)

View File

@ -9,7 +9,6 @@ module Asm
@cond = 0b1110 @cond = 0b1110
@inst_class = 0 @inst_class = 0
@i = 0 @i = 0
@opcode = 0
@s = 0 @s = 0
@rn = 0 @rn = 0
@rd = 0 @rd = 0
@ -83,7 +82,10 @@ module Asm
end end
@operand = rm_ref | (shift_op << 4) | (shift_imm << 4+3) @operand = rm_ref | (shift_op << 4) | (shift_imm << 4+3)
elsif arg.is_a?(Asm::DataObject)
# do pc relative addressing with the difference to the instuction
else else
puts "#{self.inspect}"
raise Asm::AssemblyError.new(Asm::ERRSTR_INVALID_ARG + " " + arg.inspect, arg) raise Asm::AssemblyError.new(Asm::ERRSTR_INVALID_ARG + " " + arg.inspect, arg)
end end
end end

View File

@ -6,7 +6,7 @@ module Asm
class Assembler class Assembler
def initialize def initialize
@values = [] @values = []
@position = -1 # marks not set @position = 0 # marks not set
@labels = [] @labels = []
@string_table = {} @string_table = {}
#@relocations = [] #@relocations = []
@ -17,7 +17,6 @@ module Asm
value = @string_table[str] value = @string_table[str]
return value if value return value if value
data = Asm::DataObject.new(str) data = Asm::DataObject.new(str)
add_value data
@string_table[str] = data @string_table[str] = data
end end
@ -27,7 +26,10 @@ module Asm
def add_value(val) def add_value(val)
val.at(@position) val.at(@position)
@position += val.length length = val.length
#rounding up to the next 4
length = (((length - 1 ) / 4 ) + 1 ) * 4
@position += length
@values << val @values << val
end end