diff --git a/lib/arm/memory_instruction.rb b/lib/arm/memory_instruction.rb index 84dfb6fd..318daaf2 100644 --- a/lib/arm/memory_instruction.rb +++ b/lib/arm/memory_instruction.rb @@ -6,8 +6,8 @@ module Arm class MemoryInstruction < Vm::MemoryInstruction include Arm::Constants - def initialize(first , attributes) - super(first , attributes) + def initialize(result , left , right = nil , attributes = {}) + super(result , left , right , attributes) @attributes[:update_status] = 0 if @attributes[:update_status] == nil @attributes[:condition_code] = :al if @attributes[:condition_code] == nil @operand = 0 @@ -24,13 +24,13 @@ module Arm # Build representation for target address def build - arg = @attributes[:right] + arg = @left arg = "r#{arg.register}".to_sym if( arg.is_a? Vm::Word ) #str / ldr are _serious instructions. With BIG possibilities not half are implemented if (arg.is_a?(Symbol)) #symbol is register @rn = arg - if @attributes[:offset] - @operand = @attributes[:offset] + if @right + @operand = @right if (@operand < 0) @add_offset = 0 #TODO test/check/understand @@ -62,6 +62,7 @@ module Arm def assemble(io) build + puts inspect i = 0 #I flag (third bit) #not sure about these 2 constants. They produce the correct output for str r0 , r1 # but i can't help thinking that that is because they are not used in that instruction and @@ -77,7 +78,7 @@ module Arm val = reg_code(@operand) if @operand.is_a?(Symbol) val = shift(val , 0 ) # for the test @pre_post_index = 0 if @attributes[:flaggie] - val |= shift(reg_code(@first) , 12 ) + val |= shift(reg_code(@result) , 12 ) val |= shift(reg_code(@rn) , 12+4) #16 val |= shift(@is_load , 12+4 +4) val |= shift(w , 12+4 +4+1) diff --git a/lib/vm/instruction.rb b/lib/vm/instruction.rb index 8890d1e8..019d88e9 100644 --- a/lib/vm/instruction.rb +++ b/lib/vm/instruction.rb @@ -49,8 +49,10 @@ module Vm end end class MemoryInstruction < Instruction - def initialize first , options = {} - @first = first + def initialize result , left , right = nil , options = {} + @result = result + @left = left + @right = right super(options) end end diff --git a/lib/vm/register_machine.rb b/lib/vm/register_machine.rb index 3bbdda87..b5dcb49e 100644 --- a/lib/vm/register_machine.rb +++ b/lib/vm/register_machine.rb @@ -57,7 +57,7 @@ module Vm define_instruction_two(inst , CompareInstruction) end [:strb, :str , :ldrb, :ldr].each do |inst| - define_instruction_one(inst , MemoryInstruction) + define_instruction_three(inst , MemoryInstruction) end [:b, :call , :swi].each do |inst| define_instruction_one(inst , CallInstruction) @@ -126,7 +126,7 @@ module Vm # same for three args (result = left right,) def define_instruction_three(inst , clazz , defaults = {} ) clazz = self.class_for(clazz) - create_method(inst) do |result , left ,right , options = nil| + create_method(inst) do |result , left ,right = nil , options = nil| options = {} if options == nil options.merge defaults options[:opcode] = inst diff --git a/test/arm/test_memory.rb b/test/arm/test_memory.rb index c4f07253..41bf752c 100644 --- a/test/arm/test_memory.rb +++ b/test/arm/test_memory.rb @@ -4,30 +4,34 @@ class TestMemory < MiniTest::Test include ArmHelper def test_ldr - code = @machine.ldr :r0, right: :r0 + code = @machine.ldr :r0, :r0 assert_code code, :ldr , [0x00,0x00,0x90,0xe5] #e5 90 00 00 end - def test_ldr2 - code = @machine.ldr :r0, right: :r0 , :offset => 4 + def test_ldr_const_offset + code = @machine.ldr :r0, :r0 , 4 assert_code code, :ldr , [0x04,0x00,0x90,0xe5] #e5 90 00 04 end + def test_ldr_reg_offset + code = @machine.ldr :r0, :r1 , :r2 + assert_code code, :ldr , [0x02,0x00,0x91,0xe6] #e6 91 00 02 + end def test_ldrb - code = @machine.ldrb :r0, right: :r0 + code = @machine.ldrb :r0, :r0 assert_code code, :ldrb , [0x00,0x00,0xd0,0xe5] #e5 d0 00 00 end def test_str - code = @machine.str :r0, right: :r1 + code = @machine.str :r0, :r1 assert_code code, :str , [0x00,0x00,0x81,0xe5] #e5 81 00 00 end def test_strb_add - code = @machine.strb :r0, right: :r1 , :offset => 1 , flaggie: 1 + code = @machine.strb :r0, :r1 , 1 , flaggie: 1 assert_code code, :strb , [0x01,0x00,0xc1,0xe4] #e4 c1 00 01 end def test_strb - code = @machine.strb :r0, right: :r0 + code = @machine.strb :r0, :r0 assert_code code, :strb , [0x00,0x00,0xc0,0xe5] #e5 c0 00 00 end end