diff --git a/lib/parfait/binary_code.rb b/lib/parfait/binary_code.rb index ea314f07..823daf00 100644 --- a/lib/parfait/binary_code.rb +++ b/lib/parfait/binary_code.rb @@ -25,8 +25,11 @@ module Parfait end def extend_one() @next = BinaryCode.new(1) - #puts "extending #{total_size - data_length} in #{self}" - Risc::Position.reset(self) if Risc::Position.set?(self) + if Risc::Position.set?(self) + Risc::Position.log.debug "extending #{total_size - data_length} in #{self}" + my_pos = Risc::Position.get(self) + Risc::Position.reset(my_pos , my_pos.at) + end end def each( &block ) diff --git a/lib/risc/interpreter.rb b/lib/risc/interpreter.rb index 066869bd..00cf3b6c 100644 --- a/lib/risc/interpreter.rb +++ b/lib/risc/interpreter.rb @@ -14,7 +14,7 @@ module Risc # fire events for changed pc and register contents include Util::Eventable include Util::Logging - log_level :debug + log_level :info attr_reader :instruction , :clock , :pc # current instruction and pc attr_reader :registers # the registers, 16 (a hash, sym -> contents) diff --git a/lib/risc/machine.rb b/lib/risc/machine.rb index b709f26e..fa327278 100644 --- a/lib/risc/machine.rb +++ b/lib/risc/machine.rb @@ -74,7 +74,7 @@ module Risc def position_all raise "Not translated " unless @translated #need the initial jump at 0 and then functions - Position.set(cpu_init , 0 , cpu_init) + Position.set(cpu_init , 0 , nil) @code_start = position_objects( @platform.padding ) # and then everything code position_code @@ -131,7 +131,7 @@ module Risc def boot initialize - Position.positions.clear + Position.clear_positions @objects = nil @translated = false boot_parfait! diff --git a/lib/risc/position.rb b/lib/risc/position.rb index 30e6f8a1..567438be 100644 --- a/lib/risc/position.rb +++ b/lib/risc/position.rb @@ -16,21 +16,22 @@ module Risc module Position include Util::Logging - log_level :debug + log_level :info @positions = {} + @reverse_cache = {} def self.positions @positions end + def self.clear_positions + @positions = {} + @reverse_cache = {} + end + def self.at( int ) - self.positions.each do |object , position| - next unless position.at == int - return position unless position.is_a?(InstructionPosition) - return position unless position.instruction.is_a?(Label) - end - nil + @reverse_cache[int] end def self.set?(object) @@ -48,30 +49,40 @@ module Risc pos end - # set to the same position as before, thus triggering whatever code that propagates - # position _must have been set, otherwise raises def self.reset(obj) old = self.get(obj) old.reset_to( old.at ) end - def self.set( object , pos , extra = nil) - # resetting of position used to be error, but since relink and dynamic instruction size it is ok. - # in measures - log.debug "Setting #{pos.to_s(16)} for #{object.class}-#{object}" - old = Position.positions[object] - testing = self.at( pos ) - if old != nil - raise "Mismatch was:#{old}#{old.class} , should #{testing}#{testing.class}" if testing and testing.class != old.class - old.reset_to(pos) - log.debug "Reset #{pos.to_s(16)} for #{old.class}" - return old + # resetting of position used to be error, but since relink and dynamic instruction size it is ok. + # in measures + # + # reseting to the same position as before, triggers code that propagates + def self.reset(position , to) + log.debug "ReSetting #{position}, to:#{to.to_s(16)}, for #{position.object.class}-#{position.object}" + position.reset_to(to) + if testing = @reverse_cache[ to ] + if testing.class != position.class + raise "Mismatch (at #{to.to_s(16)}) new:#{position}:#{position.class} , was #{testing}:#{testing.class}" + end + @reverse_cache.delete(to) end + @reverse_cache[position.at] = position + log.debug "Reset #{position} (#{to.to_s(16)}) for #{position.class}" + return position + end + + def self.set( object , pos , extra = nil) + old = Position.positions[object] + return self.reset(old , pos) if old + log.debug "Setting #{pos.to_s(16)} for #{object.class}-#{object}" + testing = self.at( pos ) position = for_at( object , pos , extra) - raise "Mismatch was:#{position}#{position.class} , should #{testing}#{testing.class}" if testing and testing.class != old.class + raise "Mismatch (at #{pos.to_s(16)}) was:#{position} #{position.class} #{position.object} , should #{testing}#{testing.class}" if testing and testing.class != position.class self.positions[object] = position position.init(pos) - log.debug "Set #{pos.to_s(16)} for #{position.class}" + @reverse_cache[position.at] = position + log.debug "Set #{position} (#{pos.to_s(16)}) for #{position.class}" position end diff --git a/lib/risc/position/code_position.rb b/lib/risc/position/code_position.rb index c60e27a7..79ec9cde 100644 --- a/lib/risc/position/code_position.rb +++ b/lib/risc/position/code_position.rb @@ -31,9 +31,9 @@ module Risc end end def reset_to(pos) - super(pos) - Position.log.debug "Reset (#{pos.to_s(16)}) #{code}" init(pos) + super(pos) + Position.log.debug "ResetCode (#{pos.to_s(16)}) #{code}" end def next_method next_m = @method.next_method diff --git a/lib/risc/position/instruction_position.rb b/lib/risc/position/instruction_position.rb index 353e6c5f..c1508e80 100644 --- a/lib/risc/position/instruction_position.rb +++ b/lib/risc/position/instruction_position.rb @@ -17,28 +17,32 @@ module Risc class InstructionPosition < ObjectPosition attr_reader :instruction , :binary def initialize(instruction, pos , binary) - raise "not set " unless binary + raise "not set #{binary}" if pos != 0 and !binary.is_a?(Parfait::BinaryCode) super(instruction,pos) @instruction = instruction @binary = binary end def init(at) - diff = at - Position.get(@binary).at - if( diff % 60 == 13*4) + return if at == 0 and binary.nil? + return unless @instruction.next + nekst = at + @instruction.byte_length + diff = nekst - Position.get(@binary).at + Position.log.debug "Diff: #{diff.to_s(16)} , next #{nekst.to_s(16)} , binary #{Position.get(@binary)}" + raise "Invalid position #{diff.to_s(16)} , next #{nekst.to_s(16)} #{self}" if diff < 8 + if( (diff % @binary.padded_length ) == 0 ) @binary.extend_one unless @binary.next @binary = @binary.next raise "end of line " unless @binary - at = Position.get(@binary).at + Parfait::BinaryCode.offset + nekst = Position.get(@binary).at + Parfait::BinaryCode.offset + Position.log.debug "Jump to: #{nekst.to_s(16)}" end - return unless @instruction.next - at += @instruction.byte_length - Position.set(@instruction.next, at , @binary) + Position.set(@instruction.next, nekst , @binary) end def reset_to(pos) - super(pos) - Position.log.debug "Reset (#{pos}) #{instruction}" init(pos) + super(pos) + Position.log.debug "ResetInstruction (#{pos.to_s(16)}) #{instruction}" end end end diff --git a/test/risc/position/test_instruction_position.rb b/test/risc/position/test_instruction_position.rb index b803488f..4e6f4d68 100644 --- a/test/risc/position/test_instruction_position.rb +++ b/test/risc/position/test_instruction_position.rb @@ -23,15 +23,15 @@ module Risc second = Arm::ArmMachine.b( @label) @label.set_next(second) Position.set( @label , 8 , @binary) - Position.set(second , 2 , @binary) + Position.set(second , 12 , @binary) Position.set( @label , 8 , @binary) assert_equal 8 , Position.get(@label.next).at end def test_label_at branch = Branch.new("b" , @label) - Position.set(@label , 4 , @binary) - Position.set(branch , 4 , @binary) - at_4 = Position.at(4) + Position.set(@label , 8 , @binary) + Position.set(branch , 8 , @binary) + at_4 = Position.at(8) assert_equal InstructionPosition , at_4.class assert_equal Branch , at_4.instruction.class end diff --git a/test/risc/test_machine.rb b/test/risc/test_machine.rb index 6f5d951e..b62d1a7c 100644 --- a/test/risc/test_machine.rb +++ b/test/risc/test_machine.rb @@ -29,10 +29,10 @@ module Risc assert_equal 0 , Position.get(@machine.cpu_init).at end def test_cpu_at - assert_equal "0x5bd8" , Position.get(@machine.cpu_init.first).to_s + assert_equal "0x5714" , Position.get(@machine.cpu_init.first).to_s end def test_cpu_bin - assert_equal "0x5bcc" , Position.get(Position.get(@machine.cpu_init.first).binary).to_s + assert_equal "0x570c" , Position.get(Position.get(@machine.cpu_init.first).binary).to_s end def test_cpu_label assert_equal Position::InstructionPosition , Position.get(@machine.cpu_init.first).class