propagate instruction positions
still overlapping onto binaries, but a start
This commit is contained in:
@ -24,8 +24,8 @@ module Arm
|
||||
def insert(instruction)
|
||||
super
|
||||
my_pos = Risc::Position.get(self)
|
||||
# set my position to set next according to rules
|
||||
Risc::InstructionListener.init(instruction , my_pos.get_code)
|
||||
listener = Risc::InstructionListener.new( instruction , my_pos.get_code )
|
||||
my_pos.position_listener(listener)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -14,7 +14,7 @@ module Risc
|
||||
# fire events for changed pc and register contents
|
||||
include Util::Eventable
|
||||
include Util::Logging
|
||||
log_level :info
|
||||
log_level :debug
|
||||
|
||||
attr_reader :instruction , :clock , :pc # current instruction and pc
|
||||
attr_reader :registers # the registers, 16 (a hash, sym -> contents)
|
||||
@ -48,7 +48,7 @@ module Risc
|
||||
def set_pc( pos )
|
||||
raise "Not int #{pos}" unless pos.is_a? Numeric
|
||||
position = Position.at(pos)
|
||||
raise "No position #{pos.to_s(16)}" unless position
|
||||
raise "No position at 0x#{pos.to_s(16)}" unless position
|
||||
if position.is_a?(CodeListener)
|
||||
raise "Setting Code #{clock}-#{position}, #{position.method}"
|
||||
#return set_pc(position.at + Parfait::BinaryCode.byte_offset)
|
||||
|
@ -123,7 +123,7 @@ module Risc
|
||||
type.methods.each_method do |method|
|
||||
last_code = CodeListener.init(method.binary , code_start)
|
||||
first_position = InstructionListener.init(method.cpu_instructions, method.binary)
|
||||
first_position.set_position( code_start + Parfait::BinaryCode.byte_offset)
|
||||
first_position.set( code_start + Parfait::BinaryCode.byte_offset)
|
||||
last_code.position_listener( prev_code.object) if prev_code
|
||||
prev_code = last_code
|
||||
code_start = last_code.next_slot
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user