diff --git a/lib/arm/instructions/instruction.rb b/lib/arm/instructions/instruction.rb index c6b17b2f..32296595 100644 --- a/lib/arm/instructions/instruction.rb +++ b/lib/arm/instructions/instruction.rb @@ -21,6 +21,11 @@ module Arm ret end + def insert(instruction) + super + @next.set_position( Risc::Position.position(self) + self.byte_length , 0) #FIXME + end + def set_position( position , count ) Risc::Position.set_position(self,position) position += byte_length diff --git a/lib/arm/instructions/logic_instruction.rb b/lib/arm/instructions/logic_instruction.rb index 33a978e7..bfcb0262 100644 --- a/lib/arm/instructions/logic_instruction.rb +++ b/lib/arm/instructions/logic_instruction.rb @@ -69,16 +69,13 @@ module Arm else unless @extra @extra = 1 - #puts "RELINK L at #{self.position.to_s(16)}" - extra = ArmMachine.send( opcode , result , result , 0 ) #noop - extra.set_next( @next ) - @next = extra - raise ::Risc::LinkException.new("cannot fit numeric literal argument in operand #{right.inspect}") + # puts "RELINK L at #{Risc::Position.position(self)}" + # use sub for sub and add for add, ie same as opcode + insert ArmMachine.send( opcode , result , result , 0 ) #noop end # now we can do the actual breaking of instruction, by splitting the operand operand = calculate_u8_with_rr( right & 0xFFFFFF00 ) - raise "no fit for #{right}" unless operand - # use sub for sub and add for add, ie same as opcode + raise "no fit for #{right} in #{self}" unless operand @next.set_value(right & 0xFF ) end return operand diff --git a/lib/arm/instructions/move_instruction.rb b/lib/arm/instructions/move_instruction.rb index 7ab88e24..876b47b9 100644 --- a/lib/arm/instructions/move_instruction.rb +++ b/lib/arm/instructions/move_instruction.rb @@ -65,13 +65,11 @@ module Arm if (op_with_rot = calculate_u8_with_rr(right)) return op_with_rot end - raise "No negatives implemented #{right} " if right < 0 + raise "Negatives not implemented #{right} " if right < 0 unless @extra - @extra = 1 # puts "RELINK M at #{self.position.to_s(16)}" - extra = ArmMachine.add( to , to , 0 ) #noop that we change below - extra.set_next(@next) - @next = extra - raise ::Risc::LinkException.new("cannot fit numeric literal argument in operand #{right.inspect}") + puts "RELINK M at #{Risc::Position.position(self)}" + @extra = 1 + insert ArmMachine.add( to , to , 0 ) #noop that we change below end # now we can do the actual breaking of instruction, by splitting the operand operand = calculate_u8_with_rr( right & 0xFFFFFF00 ) diff --git a/stash/plock.rb b/stash/plock.rb deleted file mode 100644 index 66b48fc4..00000000 --- a/stash/plock.rb +++ /dev/null @@ -1,68 +0,0 @@ -module Risc - # Plock (Proc-Block) is mostly a Block but also somewhat Proc-ish: A Block that carries data. - # - # Data in a Block is usefull in the same way data in objects is. Plocks being otherwise just code. - # - # But the concept is not quite straigtforwrd: If one thinks of a Plock embedded in a normal method, - # the a data in the Plock would be static data. In OO terms this comes quite close to a Proc, - # if the data is the local variables. - # Quite possibly they shall be used to implement procs, but that is not the direction now. - # - # For now we use Plocks behaind the scenes as it were. In the code that you never see, - # method invocation mainly. - # - # In terms of implementation the Plock is a Block with data - # (Not too much data, mainly a couple of references). - # The block writes it's instructions as normal, but a jump is inserted as the last instruction. - # The jump is to the next block, over the data that is inserted after the block code - # (and so before the next) - # - # It follows that Plocks should be linear blocks. - class Plock < Block - - def initialize(name , method , next_block ) - super - @data = [] - @branch_code = RiscMachine.instance.b next_block - end - - def set_next next_b - super - @branch_code = RiscMachine.instance.b next_block - end - - # Data gets assembled after methods - def add_data o - return if @objects.include? o - raise "must be derived from Code #{o.inspect}" unless o.is_a? Risc::Code - @data << o # TODO check type , no basic values allowed (must be wrapped) - end - - # Code interface follows. Note position is inheitted as is from Code - - # length of the Plock is the length of the block, plus the branch, plus data. - def byte_length - len = @data.inject(super) {| sum , item | sum + item.word_length} - len + @branch_code.word_length - end - - # again, super + branch plus data - def link_at pos , context - super(pos , context) - @branch_code.link_at pos , context - @data.each do |code| - code.link_at(pos , context) - pos += code.word_length - end - end - - # again, super + branch plus data - def assemble(io) - super - @branch_code.assemble(io) - @data.each do |obj| - obj.assemble io - end - end - end -end diff --git a/test/arm/test_logic.rb b/test/arm/test_logic.rb index 867c3a1b..2824f6c3 100644 --- a/test/arm/test_logic.rb +++ b/test/arm/test_logic.rb @@ -82,11 +82,9 @@ module Arm end def test_too_big_add code = @machine.add :r1 , :r1, 0x222 - begin # add 0x02 (first instruction) and then 0x220 shifted - assert_code code , :add , [0x02,0x1c,0x91,0xe2] #e2 91 1e 02 - rescue Risc::LinkException - retry - end + code.set_position(0,0) + # add 0x02 (first instruction) and then 0x220 shifted + assert_code code , :add , [0x02,0x1c,0x91,0xe2] #e2 91 1e 02 # added extra instruction to add "extra" assert_code code.next , :add , [0x22,0x10,0x91,0xe2] #e2 91 10 22 end