propagate instruction positions

still overlapping onto binaries, but a start
This commit is contained in:
Torsten Ruger
2018-06-05 18:11:25 +03:00
parent f35ee6425a
commit 8d953a619f
12 changed files with 68 additions and 69 deletions

View File

@ -15,11 +15,10 @@ module Risc
class InstructionListener
attr_reader :instruction , :binary
def initialize(instruction , binary)
pos = 0
@instruction = instruction
@binary = binary
end
def init(at, binary)
def old_code(at, binary)
@binary = binary
instruction.address.set_value(at) if instruction.is_a?(Label)
return if at == 0 and binary.nil?
@ -39,6 +38,10 @@ module Risc
Position.set(@instruction.next, nekst , binary)
end
def position_changed(position)
my_pos = Position.get(@instruction)
my_pos.set(position.at + position.object.byte_length)
end
# initialize the dependency graph for instructions
#
# starting from the given instruction, create Positions
@ -50,6 +53,7 @@ module Risc
# set all positions in the chain
def self.init( instruction , code )
raise "Not Binary Code #{code.class}" unless code.is_a?(Parfait::BinaryCode)
raise "Must init with instruction, not nil" unless instruction
first = nil
while(instruction)
position = Position.new(instruction , -1)

View File

@ -57,10 +57,10 @@ module Risc
end
def set(int)
same = int == self.at
return int if int == self.at
Position.set_to(self , int)
@at = int
trigger(:position_changed , self ) unless same
trigger(:position_changed , self )
int
end
@ -79,6 +79,7 @@ module Risc
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)}"
at + object.byte_length
end
@ -103,6 +104,8 @@ module Risc
self.positions.has_key?(object)
end
# get a position from the cache (object -> position)
# unless it's a label, then get the position of it's next
def self.get(object)
pos = self.positions[object]
if pos == nil
@ -116,17 +119,21 @@ module Risc
pos
end
# populate the position caches (forward and revese) with the given position
# forward caches object -> position
# reverse caches position.at > position
# Labels do not participatein reverse cache
def self.set_to( position , to)
postest = Position.positions[position.object] unless to < 0
raise "Mismatch #{position}" if postest and postest != position
@reverse_cache.delete(position.at) unless position.object.is_a? Label
@reverse_cache.delete(position.at) unless position.object.is_a?(Label)
testing = self.at( position.at ) unless position.at < 0
if testing and testing.class != position.class
if testing and testing.object.class != position.object.class
raise "Mismatch (at #{pos.to_s(16)}) was:#{position} #{position.class} #{position.object} , should #{testing}#{testing.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.class}"
@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)}"
position
end
end