fix (re)positioning when link exceptions are thrown
slow design, but sort of works
This commit is contained in:
parent
1c52ab6b67
commit
6be28e7f55
@ -11,26 +11,9 @@ module Risc
|
|||||||
@code = code
|
@code = code
|
||||||
end
|
end
|
||||||
|
|
||||||
# write into the given BinaryCode instance
|
|
||||||
# LinkException may be thrown, possibly several times
|
|
||||||
# So repeat until it works
|
|
||||||
def assemble( instruction )
|
|
||||||
not_ok = 1
|
|
||||||
while(not_ok)
|
|
||||||
begin
|
|
||||||
#puts "Not ok #{not_ok}"
|
|
||||||
#FIXME really need to reposition here, so jumps go right
|
|
||||||
assemble_all(instruction)
|
|
||||||
not_ok = false
|
|
||||||
rescue LinkException
|
|
||||||
not_ok += 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Go through and assemble all instructions.
|
# Go through and assemble all instructions.
|
||||||
# Assembly may cause LinkException, which is caught by caller
|
# Assembly may cause LinkException, which is caught by caller
|
||||||
def assemble_all( instruction )
|
def assemble( instruction )
|
||||||
@index = 1
|
@index = 1
|
||||||
while(instruction)
|
while(instruction)
|
||||||
instruction.assemble(self)
|
instruction.assemble(self)
|
||||||
|
@ -79,14 +79,15 @@ module Risc
|
|||||||
cpu_init.set_position( 0 )
|
cpu_init.set_position( 0 )
|
||||||
#Positioned.set_position(cpu_init.first , 0)
|
#Positioned.set_position(cpu_init.first , 0)
|
||||||
Positioned.set_position(binary_init,0)
|
Positioned.set_position(binary_init,0)
|
||||||
at = position_objects( binary_init.padded_length )
|
@code_start = position_objects( binary_init.padded_length )
|
||||||
# and then everything code
|
# and then everything code
|
||||||
position_code_from( at )
|
position_code
|
||||||
end
|
end
|
||||||
|
|
||||||
# go through everything that is not code (BinaryCode) and set position
|
# go through everything that is not code (BinaryCode) and set position
|
||||||
# padded_length is what determines an objects (byte) length
|
# padded_length is what determines an objects (byte) length
|
||||||
def position_objects( at )
|
# return final position that is stored in code_start
|
||||||
|
def position_objects(at)
|
||||||
# want to have the objects first in the executable
|
# want to have the objects first in the executable
|
||||||
objects.each do | id , objekt|
|
objects.each do | id , objekt|
|
||||||
next if objekt.is_a?( Parfait::BinaryCode) or objekt.is_a?( Risc::Label )
|
next if objekt.is_a?( Parfait::BinaryCode) or objekt.is_a?( Risc::Label )
|
||||||
@ -98,9 +99,13 @@ module Risc
|
|||||||
|
|
||||||
# Position all BinaryCode.
|
# Position all BinaryCode.
|
||||||
#
|
#
|
||||||
# So that all code from one method is layed out linearly (for debuggin)
|
# So that all code from one method is layed out linearly (for debugging)
|
||||||
# we go through methods, and then through all codes from the method
|
# we go through methods, and then through all codes from the method
|
||||||
def position_code_from( at )
|
#
|
||||||
|
# start at @code_start. The method is called until
|
||||||
|
# assembly stops throwing errors
|
||||||
|
def position_code
|
||||||
|
at = @code_start
|
||||||
objects.each do |id , method|
|
objects.each do |id , method|
|
||||||
next unless method.is_a? Parfait::TypedMethod
|
next unless method.is_a? Parfait::TypedMethod
|
||||||
log.debug "POS1 #{method.name}:#{at.to_s(16)}"
|
log.debug "POS1 #{method.name}:#{at.to_s(16)}"
|
||||||
@ -119,16 +124,32 @@ module Risc
|
|||||||
|
|
||||||
# Create Binary code for all methods and the initial jump
|
# Create Binary code for all methods and the initial jump
|
||||||
# BinaryWriter handles the writing from instructions into BinaryCode objects
|
# BinaryWriter handles the writing from instructions into BinaryCode objects
|
||||||
|
#
|
||||||
|
# current (poor) design throws an exception when the assembly can't fit
|
||||||
|
# constant loads into one instruction.
|
||||||
|
#
|
||||||
def create_binary
|
def create_binary
|
||||||
|
not_ok = 1
|
||||||
|
while(not_ok)
|
||||||
|
begin
|
||||||
|
return do_create_binary
|
||||||
|
rescue LinkException
|
||||||
|
not_ok += 1
|
||||||
|
puts "relink no #{not_ok}"
|
||||||
|
position_code
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# have to retry until it works. Unfortunately (FIXME) jumps can go be both
|
||||||
|
# directions, and so already assembled codes get wrong by moving/ inserting
|
||||||
|
# instructions. And we end up assmebling all code again :-(
|
||||||
|
def do_create_binary
|
||||||
objects.each do |id , method|
|
objects.each do |id , method|
|
||||||
next unless method.is_a? Parfait::TypedMethod
|
next unless method.is_a? Parfait::TypedMethod
|
||||||
writer = BinaryWriter.new(method.binary)
|
writer = BinaryWriter.new(method.binary)
|
||||||
writer.assemble(method.cpu_instructions)
|
writer.assemble(method.cpu_instructions)
|
||||||
end
|
end
|
||||||
puts "CPU init"
|
|
||||||
puts cpu_init.first.inspect[0...130]
|
|
||||||
puts Parfait.object_space.get_init.risc_instructions.inspect[0...130]
|
|
||||||
puts Parfait.object_space.get_init.cpu_instructions.inspect[0...130]
|
|
||||||
BinaryWriter.new(binary_init).assemble(cpu_init)
|
BinaryWriter.new(binary_init).assemble(cpu_init)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ module Risc
|
|||||||
|
|
||||||
class TextWriter
|
class TextWriter
|
||||||
include Logging
|
include Logging
|
||||||
log_level :debug
|
log_level :info
|
||||||
|
|
||||||
MARKER = 0xBAD4C0DE
|
MARKER = 0xBAD4C0DE
|
||||||
|
|
||||||
@ -109,7 +109,7 @@ module Risc
|
|||||||
def write_object_check(object)
|
def write_object_check(object)
|
||||||
log.debug "Write object #{object.class} #{object.inspect[0..100]}"
|
log.debug "Write object #{object.class} #{object.inspect[0..100]}"
|
||||||
#Only initially created codes are collected. Binary_init and method "tails" not
|
#Only initially created codes are collected. Binary_init and method "tails" not
|
||||||
if !@objects.has_key?(object.object_id) and !object.is_a?(Parfait::BinaryCode)
|
if !@machine.objects.has_key?(object.object_id) and !object.is_a?(Parfait::BinaryCode)
|
||||||
log.debug "Object at 0x#{Positioned.position(object).to_s(16)}:#{object.get_type()}"
|
log.debug "Object at 0x#{Positioned.position(object).to_s(16)}:#{object.get_type()}"
|
||||||
raise "Object(0x#{object.object_id.to_s(16)}) not linked #{object.inspect}"
|
raise "Object(0x#{object.object_id.to_s(16)}) not linked #{object.inspect}"
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user