make the instructions jump over the BinaryCode end

This commit is contained in:
Torsten Ruger 2018-06-07 19:27:44 +03:00
parent 2d218bbc48
commit 5815d32bde
5 changed files with 38 additions and 18 deletions

View File

@ -24,15 +24,16 @@ module Risc
# Taking into account that BinaryCodes only take 13 instructions,
# meaning that chain may have to be extended
def position_changed(position)
fix_binary
my_pos = Position.get(@instruction)
next_pos = position.at + position.object.byte_length
fix_binary_for(next_pos)
my_pos = Position.get(@instruction)
diff = next_pos - Position.get(@binary).at
Position.log.debug "Diff: #{diff.to_s(16)} , next #{next_pos.to_s(16)} , binary #{Position.get(@binary)}"
Position.log.debug "Diff: 0x#{diff.to_s(16)} , next 0x#{next_pos.to_s(16)} , binary #{Position.get(@binary)}"
raise "Invalid position #{diff.to_s(16)} , next #{next_pos.to_s(16)} #{position}" if diff < 8
if( (diff % (@binary.padded_length - @instruction.byte_length)) == 0 )
@binary = @binary.ensure_next
next_pos = Position.get(@binary).at + Parfait::BinaryCode.byte_offset
#Insert/Position the jump (its missing)
Position.log.debug "Jump to: #{next_pos.to_s(16)}"
end
my_pos.set(next_pos)
@ -66,24 +67,26 @@ module Risc
# check that the binary we use is the one where the current position falls
# if not move up and register/unregister (soon)
def fix_binary
#
# Because the position for the @instruction may not be set yet,
# we use the one that it will be set to (the arg)
def fix_binary_for(new_pos)
raise "Binary has no position (-1)" if Position.get(@binary).at == -1
return if Position.get(@instruction).at == -1
count = 0
org_pos = Position.get(@binary)
return if org_pos.at == -1
while( !pos_in_binary)
bin_pos = Position.get(@binary)
while( !pos_in_binary(new_pos))
@binary = @binary.ensure_next
count += 1
raise "Positions messed #{Position.get(@instruction)}:#{org_pos}"
raise "Positions too far out (#{count}) #{Position.get(@instruction)}:#{bin_pos}" if count > 5
end
end
def pos_in_binary
me = Position.get(@instruction)
# check if the given position is inside the @binary
# ie not below start or above end
def pos_in_binary(new_pos)
bin = Position.get(@binary)
return false if me < bin
return false if me > (bin + @binary.padded_length)
return false if bin > new_pos
return false if new_pos > (bin + @binary.padded_length)
return true
end

View File

@ -108,6 +108,12 @@ module Risc
"0x#{@at.to_s(16)}"
end
def object_class
return :object if @object.is_a?(Parfait::Object)
return :object if @object.class.name.include?("Test")
:instruction
end
def next_slot
return -1 if at < 0
self.log.debug "Next Slot @#{at.to_s(16)} for #{object.class} == #{(at + object.byte_length).to_s(16)}"
@ -159,12 +165,12 @@ module Risc
raise "Mismatch #{position}" if postest and postest != position
@reverse_cache.delete(position.at) unless position.object.is_a?(Label)
testing = self.at( position.at ) unless position.at < 0
if testing and testing.object.class != position.object.class
raise "Mismatch (at #{to.to_s(16)}) was:#{position} #{position.class} #{position.object} , should #{testing}#{testing.class}"
if testing and testing.object_class != position.object_class
raise "Mismatch (at #{to.to_s(16)}) new:#{position} #{position.object.class} , was:#{testing}#{testing.object.class}"
end
self.positions[position.object] = position
@reverse_cache[to] = position unless position.object.is_a?(Label)
log.debug "Set #{position} (#{to.to_s(16)}) for #{position.object.class} #{position.object.object_id.to_s(16)}"
log.debug "Set #{position} to 0x#{to.to_s(16)} for #{position.object.class} #{position.object.object_id.to_s(16)}"
position
end
end

View File

@ -26,7 +26,7 @@ module Arm
end
def test_mov_big
code = @machine.mov :r0, 0x222 # is not 8 bit and can't be rotated by the arm system in one instruction
Risc::Position.set(code,0, nil)
Risc::Position.new(code,0)
# mov 512(0x200) = e3 a0 0c 02 add 34(0x22) = e2 90 00 22
assert_code code , :mov , [ 0x02,0x0c,0xb0,0xe3]
assert_code code.next , :add , [ 0x22,0x00,0x90,0xe2]

View File

@ -5,7 +5,7 @@ module Risc
def setup
Risc.machine.boot
@binary = Parfait::BinaryCode.new(1)
@bin_pos = Position.new(@binary,0)
@bin_pos = CodeListener.init(@binary,0)
@instruction = DummyInstruction.new
13.times {@instruction.last.insert(DummyInstruction.new) }
@position = InstructionListener.init(@instruction , @binary)
@ -28,5 +28,10 @@ module Risc
@instruction.insert DummyInstruction.new
assert_equal 76 , Position.get(@instruction.last).at
end
def test_pushes_after_insert
@instruction.insert DummyInstruction.new
@position.set(12)
assert_equal 80 , Position.get(@instruction.last).at
end
end
end

View File

@ -28,6 +28,12 @@ module Risc
pos = @pos.set(10)
assert_equal 10 , pos
end
def test_object_class_test
assert_equal :object , @pos.object_class
end
def test_object_class_instr
assert_equal :instruction , Position.new(Label.new("hi","ho",FakeAddress.new(1)),4).object_class
end
def test_at
pos = Position.at(5)
assert_equal 5 , pos.at