implement offset addressing for load (ie reg+num)

This commit is contained in:
Torsten Ruger 2014-04-22 12:23:55 +03:00
parent 2784a8da98
commit 5127deeeff
3 changed files with 21 additions and 16 deletions

View File

@ -28,32 +28,25 @@ module Asm
# Build representation for target address # Build representation for target address
def build_operand(arg) def build_operand(arg)
#str / ldr are _seruous instructions. With BIG possibilities no half are implemented #str / ldr are _serious instructions. With BIG possibilities not half are implemented
@i = 0 @i = 0
@pre_post_index = 0 @pre_post_index = 0
@w = 0 @w = 0
@operand = 0 @operand = 0
if (arg.is_a?(Asm::RegisterNode)) if (arg.is_a?(Asm::RegisterNode))
@rn = reg_ref(arg) @rn = reg_ref(arg)
if(arg.offset != 0)
if (false ) #argr.op and argr.right.is_a?(Asm::NumLiteralNode)) @operand = arg.offset
if (@operand < 0)
# this if was buggy even before
# but as mentioned here we'd have to implement the options
# though a better syntax will have to be found
val = argr.right.value
if (val < 0)
@add_offset = 0 @add_offset = 0
val *= -1 #TODO test/check/understand
@operand *= -1
else else
@add_offset = 1 @add_offset = 1
end end
if (val.abs > 4095) if (@operand.abs > 4095)
raise Asm::AssemblyError.new('reference offset too large/small (max 4095)', argr.right) raise Asm::AssemblyError.new('reference offset too large/small (max 4095)', argr.right)
end end
@operand = val
else
# raise Asm::AssemblyError.new(Asm::ERRSTR_INVALID_ARG, arg)
end end
elsif (arg.is_a?(Asm::LabelRefNode) or arg.is_a?(Asm::NumLiteralNode)) elsif (arg.is_a?(Asm::LabelRefNode) or arg.is_a?(Asm::NumLiteralNode))
@pre_post_index = 1 @pre_post_index = 1

View File

@ -11,10 +11,22 @@ module Asm
attr_accessor :type, :value, :argument attr_accessor :type, :value, :argument
end end
# Registers have off course a name (r1-16 for arm)
# but also refer to an address. In other words they can be an operand for instructions.
# Arm has addressing modes abound, and so can add to a register before actually using it
# If can actually shift or indeed shift what it adds, but not implemented
class RegisterNode < Node class RegisterNode < Node
attr_accessor :name attr_accessor :name , :offset
def initialize name def initialize name
@name = name @name = name
@offset = 0
end
# this is for the dsl, so we can write pretty code like r1 + 4
# when we want to access the next word (4) after r1
def + number
@offset = number
self
end end
end end

View File

@ -70,7 +70,7 @@ class TestArmAsm < MiniTest::Test
end end
def test_ldr2 def test_ldr2
code = @generator.instance_eval { ldr r0, r0 + 4 }.first code = @generator.instance_eval { ldr r0, r0 + 4 }.first
assert_code code, :ldr , [0x00,0x00,0x90,0xe5] #e5 90 00 00 assert_code code, :ldr , [0x04,0x00,0x90,0xe5] #e5 90 00 04
end end
def test_ldrb def test_ldrb
code = @generator.instance_eval { ldrb r0, r0 }.first code = @generator.instance_eval { ldrb r0, r0 }.first