From d0d857bbe07b6a0b1260402134cd4a69412f1551 Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Fri, 26 Jun 2015 20:36:00 +0300 Subject: [PATCH] fix object loading by (ahem) copying the code from MoveInst. --- lib/arm/instructions/logic_instruction.rb | 29 ++++++++++++++++++++--- lib/arm/passes/constant_implementation.rb | 2 +- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/lib/arm/instructions/logic_instruction.rb b/lib/arm/instructions/logic_instruction.rb index 6e0adade..e3faa544 100644 --- a/lib/arm/instructions/logic_instruction.rb +++ b/lib/arm/instructions/logic_instruction.rb @@ -27,10 +27,13 @@ module Arm immediate = @immediate right = @right - if @left.is_a?(Parfait::Object) + if @left.is_a?(Parfait::Object) or + @left.is_a?(Symbol) and !Register::RegisterReference.look_like_reg(@left) # do pc relative addressing with the difference to the instuction # 8 is for the funny pipeline adjustment (ie pointing to fetch and not execute) - right = @left.position - self.position - 8 + right = @left.position - self.position + raise "todo in direction #{right}" if( opcode == :add and right < 0 ) + raise "No negatives implemented #{right} " if right < 0 left = :pc end if (right.is_a?(Numeric)) @@ -42,7 +45,17 @@ module Arm operand = op_with_rot immediate = 1 else - raise "cannot fit numeric literal argument in operand #{right.inspect}" + #TODO this is copied from MoveInstruction, should rework + unless @extra + @extra = 1 + raise ::Register::LinkException.new("cannot fit numeric literal argument in operand #{right.inspect}") + end + # now we can do the actual breaking of instruction, by splitting the operand + first = right & 0xFFFFFF00 + operand = calculate_u8_with_rr( first ) + raise "no fit for #{right}" unless operand + immediate = 1 + @extra = ArmMachine.add( result , result , (right & 0xFF) ) end elsif (right.is_a?(Symbol) or right.is_a?(::Register::RegisterReference)) operand = reg_code(right) #integer means the register the integer is in (otherwise constant) @@ -62,12 +75,22 @@ module Arm 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) + @extra.assemble(io) + #puts "Assemble extra at #{val.to_s(16)}" + end end + def shift val , by raise "Not integer #{val}:#{val.class} #{inspect}" unless val.is_a? Fixnum val << by end + def word_length + @extra ? 8 : 4 + end + def uses ret = [] ret << @left.register if @left and not @left.is_a? Constant diff --git a/lib/arm/passes/constant_implementation.rb b/lib/arm/passes/constant_implementation.rb index 7d307efd..bd147d01 100644 --- a/lib/arm/passes/constant_implementation.rb +++ b/lib/arm/passes/constant_implementation.rb @@ -7,7 +7,7 @@ module Arm constant = code.constant if constant.is_a?(Parfait::Object) or constant.is_a? Symbol - load = ArmMachine.add( code.register , :pc , constant ) + load = ArmMachine.add( code.register , constant ) else load = ArmMachine.mov( code.register , code.constant ) end