From 37403f1139d58fbdda7db158aa49ae664a62a049 Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Fri, 26 Jun 2015 20:00:33 +0300 Subject: [PATCH] fix misunderstood mov usage When moving a reference (pointer) to a register one needs to ADD to the pc i.e. one needs an add, not mov instruction --- lib/arm/instructions/move_instruction.rb | 21 ++++++++------------- test/arm/test_move.rb | 19 ------------------- 2 files changed, 8 insertions(+), 32 deletions(-) diff --git a/lib/arm/instructions/move_instruction.rb b/lib/arm/instructions/move_instruction.rb index fdf68314..4eda03e8 100644 --- a/lib/arm/instructions/move_instruction.rb +++ b/lib/arm/instructions/move_instruction.rb @@ -4,6 +4,9 @@ module Arm def initialize to , from , options = {} super(options) + if( from.is_a?(Symbol) and Register::RegisterReference.look_like_reg(from) ) + from = Register::RegisterReference.new(from) + end @from = from @to = to raise "move must have from set #{inspect}" unless from @@ -35,14 +38,6 @@ module Arm operand = @operand immediate = @immediate right = @from - if right.is_a?(Parfait::Object) - r_pos = right.position - # do pc relative addressing with the difference to the instuction - # 8 is for the funny pipeline adjustment (ie pc pointing to fetch and not execute) - right = r_pos - self.position - 8 - puts "Position #{r_pos} from #{self.position} = #{right}" - rn = :pc - end if (right.is_a?(Numeric)) if (right.fits_u8?) # no shifting needed @@ -79,7 +74,7 @@ module Arm # The way it _should_ be done # is to check that the first part is doabe with u8_with_rr AND leaves a u8 remainder end - elsif (right.is_a?(Symbol) or right.is_a?(::Register::RegisterReference)) + elsif( right.is_a? Register::RegisterReference) operand = reg_code(right) immediate = 0 # ie not immediate is register else @@ -92,10 +87,10 @@ module Arm val |= shift(reg_code(@to) , 12) val |= shift(reg_code(rn) , 12+4) val |= shift(@attributes[:update_status] , 12+4+4)#20 - val |= shift(op_bit_code , 12+4+4 +1) - val |= shift(immediate , 12+4+4 +1+4) - val |= shift(instuction_class , 12+4+4 +1+4+1) - val |= shift(cond_bit_code , 12+4+4 +1+4+1+2) + val |= shift(op_bit_code , 12+4+4 + 1) + val |= shift(immediate , 12+4+4 + 1+4) + val |= shift(instuction_class , 12+4+4 + 1+4+1) + val |= shift(cond_bit_code , 12+4+4 + 1+4+1+2) io.write_uint32 val # by now we have the extra add so assemble that if(@extra) diff --git a/test/arm/test_move.rb b/test/arm/test_move.rb index 32780001..63a3956b 100644 --- a/test/arm/test_move.rb +++ b/test/arm/test_move.rb @@ -32,23 +32,4 @@ class TestMoves < MiniTest::Test code = @machine.mvn :r1, 5 assert_code code , :mvn , [0x05,0x10,0xe0,0xe3] #e3 e0 10 05 end - def test_constant_small # like test_mov - const = :harvey - const.set_position( 13 ) # 13 = 5 + 8 , 8 for the arm pipeline offset, gets subtracted - code = @machine.mov :r1 , 5 - code.set_position(0) - #TODO check this in decompile - assert_code code , :mov , [0x05,0x10,0xa0,0xe3] #e3 ef 10 05 - end - def test_constant_big # like test_mov_big - const = :harvey - const.set_position( 0x222 ) - code = @machine.mov :r0 , 0x222 - code.set_position(0) - begin # mov 512(0x200) = e3 a0 0c 02 add 34(0x22) = e2 80 00 22 - assert_code code , :mov , [ 0x02,0x0c,0xa0,0xe3 , 0x22,0x00,0x80,0xe2] - rescue Register::LinkException - retry - end - end end