a little renaming and moving around of constants
This commit is contained in:
parent
2fdc59c13c
commit
7ff8fa8802
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user