split create_binary into two phases

Which gives instructions a chance to check everything
and in Arms case check the constant loads/ instruction adding
So that during assembly no more change happens (and we don't have to reassemble)
This commit is contained in:
Torsten Ruger 2018-06-17 13:53:17 +03:00
parent c94f6eaa78
commit 3298651238
7 changed files with 37 additions and 8 deletions

View File

@ -1,4 +1,6 @@
require "util/list"
require "util/dev_null"
module Arm
# Arm instruction base class
# Mostly linked list functionality that all instructions have
@ -21,6 +23,13 @@ module Arm
ret
end
# precheck that everything is ok, before asembly
# in arm, we use the oppertunity to assemble to dev_null, so any
# additions are done _before_ assemnly
def precheck
assemble(Util::DevNull.new)
end
def insert(instruction)
ret = super
Risc::Position.get(self).trigger_inserted if Risc::Position.set?(self)

View File

@ -37,6 +37,10 @@ module Risc
ret
end
# just part of the protocol, noop in this case
def precheck
end
def to_cpu( translator )
translator.translate( self )
end

View File

@ -22,6 +22,7 @@ module Risc
@constants = []
@next_address = nil
end
attr_reader :constants , :cpu_init
attr_reader :booted , :translated
attr_reader :platform
@ -143,12 +144,23 @@ module Risc
# constant loads into one instruction.
#
def create_binary
object_positions.keys.each do |method|
next unless method.is_a? Parfait::TypedMethod
methods = object_positions.keys.find_all{|obj| obj.is_a? Parfait::TypedMethod}
prerun(methods)
assemble(methods)
log.debug "BinaryInit #{cpu_init.object_id.to_s(16)}"
end
def prerun(methods)
methods.each do |method|
method.cpu_instructions.each {|i| i.precheck }
end
end
def assemble(methods)
methods.each do |method|
writer = BinaryWriter.new(method.binary)
writer.assemble(method.cpu_instructions)
end
log.debug "BinaryInit #{cpu_init.object_id.to_s(16)}"
end
def boot

7
lib/util/dev_null.rb Normal file
View File

@ -0,0 +1,7 @@
module Util
# A class that does not write, or swallows all incoming data
# Used in Arm to do a dry run (and in testing, where it was born)
class DevNull
def write_unsigned_int_32( _ );end
end
end

View File

@ -1,4 +1 @@
require_relative "../helper"
class DevNull
def write_unsigned_int_32( _ );end
end

View File

@ -57,7 +57,7 @@ module Risc
@machine.object_positions.each do | method , position|
next unless method.is_a? Parfait::TypedMethod
method.cpu_instructions.each do |ins|
ins.assemble(DevNull.new)
ins.assemble(Util::DevNull.new)
end
end
end

View File

@ -33,7 +33,7 @@ module Risc
@machine.object_positions.keys.each do |method|
next unless method.is_a? Parfait::TypedMethod
method.cpu_instructions.each do |ins|
ins.assemble(DevNull.new)
ins.assemble(Util::DevNull.new)
end
end
end