use factory functions consistently to create instructions

This commit is contained in:
Torsten Ruger 2016-12-28 19:01:58 +02:00
parent 4cf732d395
commit 9cf56b3aa6
13 changed files with 44 additions and 33 deletions

View File

@ -7,7 +7,7 @@ module Register
# so it is responsible for initial setup # so it is responsible for initial setup
def __init__ context def __init__ context
compiler = Typed::MethodCompiler.new.create_method(:Kernel,:__init__ ) compiler = Typed::MethodCompiler.new.create_method(:Kernel,:__init__ )
new_start = Label.new("__init__ start" , "__init__" ) new_start = Register.label("__init__ start" , "__init__" )
compiler.method.instructions = new_start compiler.method.instructions = new_start
compiler.set_current new_start compiler.set_current new_start
@ -17,11 +17,11 @@ module Register
message_ind = Register.resolve_to_index( :space , :first_message ) message_ind = Register.resolve_to_index( :space , :first_message )
compiler.add_code Register.slot_to_reg( "__init__ load 1st message" , space_reg , message_ind , :message) compiler.add_code Register.slot_to_reg( "__init__ load 1st message" , space_reg , message_ind , :message)
compiler.add_code Register.reg_to_slot( "__init__ store Space in message", space_reg , :message , :receiver) compiler.add_code Register.reg_to_slot( "__init__ store Space in message", space_reg , :message , :receiver)
exit_label = Label.new("_exit_label for __init__" , "#{compiler.type.object_class.name}.#{compiler.method.name}" ) exit_label = Register.label("_exit_label for __init__" , "#{compiler.type.object_class.name}.#{compiler.method.name}" )
ret_tmp = compiler.use_reg(:Label) ret_tmp = compiler.use_reg(:Label)
compiler.add_code Register.load_constant("__init__ load return", exit_label , ret_tmp) compiler.add_code Register.load_constant("__init__ load return", exit_label , ret_tmp)
compiler.add_code Register.reg_to_slot("__init__ store return", ret_tmp , :message , :return_address) compiler.add_code Register.reg_to_slot("__init__ store return", ret_tmp , :message , :return_address)
compiler.add_code FunctionCall.new( "__init__ issue call" , Register.machine.space.get_main ) compiler.add_code Register.function_call( "__init__ issue call" , Register.machine.space.get_main )
compiler.add_code exit_label compiler.add_code exit_label
emit_syscall( compiler , :exit ) emit_syscall( compiler , :exit )
return compiler.method return compiler.method
@ -38,7 +38,7 @@ module Register
compiler.add_code Syscall.new("emit_syscall(#{name})", name ) compiler.add_code Syscall.new("emit_syscall(#{name})", name )
restore_message(compiler) restore_message(compiler)
return unless (@clazz and @method) return unless (@clazz and @method)
compiler.add_code Label.new( "#{@clazz.name}.#{@message.name}" , "return_syscall" ) compiler.add_code Register.label( "#{@clazz.name}.#{@message.name}" , "return_syscall" )
end end
# save the current message, as the syscall destroys all context # save the current message, as the syscall destroys all context

View File

@ -14,7 +14,7 @@ module Register
source = "get_internal_word" source = "get_internal_word"
me , index = self_and_int_arg(compiler,source) me , index = self_and_int_arg(compiler,source)
# reduce me to me[index] # reduce me to me[index]
compiler.add_code SlotToReg.new( source , me , index , me) compiler.add_code Register.slot_to_reg( source , me , index , me)
# and put it back into the return value # and put it back into the return value
compiler.add_code Register.reg_to_slot( source , me , :message , :return_value) compiler.add_code Register.reg_to_slot( source , me , :message , :return_value)
return compiler.method return compiler.method
@ -29,7 +29,7 @@ module Register
value = load_int_arg_at(compiler,source , 2) value = load_int_arg_at(compiler,source , 2)
# do the set # do the set
compiler.add_code RegToSlot.new( source , value , me , index) compiler.add_code Register.reg_to_slot( source , value , me , index)
return compiler.method return compiler.method
end end

View File

@ -23,7 +23,7 @@ module Register
source = "get_internal_byte" source = "get_internal_byte"
me , index = self_and_int_arg(compiler,source) me , index = self_and_int_arg(compiler,source)
# reduce me to me[index] # reduce me to me[index]
compiler.add_code ByteToReg.new( source , me , index , me) compiler.add_code Register.byte_to_reg( source , me , index , me)
# and put it back into the return value # and put it back into the return value
compiler.add_code Register.reg_to_slot( source , me , :message , :return_value) compiler.add_code Register.reg_to_slot( source , me , :message , :return_value)
return compiler.method return compiler.method
@ -41,7 +41,7 @@ module Register
me , index = self_and_int_arg(compiler,source) me , index = self_and_int_arg(compiler,source)
value = load_int_arg_at(compiler , source , 2 ) value = load_int_arg_at(compiler , source , 2 )
# do the set # do the set
compiler.add_code RegToByte.new( source , value , me , index) compiler.add_code Register.reg_to_byte( source , value , me , index)
return compiler.method return compiler.method
end end

View File

@ -12,9 +12,9 @@ module Register
# Produce a ByteToReg instruction. # Produce a ByteToReg instruction.
# from and to are translated (from symbol to register if neccessary) # from and to are translated (from symbol to register if neccessary)
# but index is left as is. # but index is left as is.
# def self.byte_to_reg source , array , index , to def self.byte_to_reg( source , array , index , to)
# from = resolve_to_register from array = resolve_to_register( array)
# to = resolve_to_register to to = resolve_to_register( to)
# ByteToReg.new( source , array , index , to) ByteToReg.new( source , array , index , to)
# end end
end end

View File

@ -4,7 +4,7 @@ module Register
# assembly takes care of the rest (ie getting the address) # assembly takes care of the rest (ie getting the address)
class FunctionCall < Instruction class FunctionCall < Instruction
def initialize source , method def initialize( source , method )
super(source) super(source)
@method = method @method = method
end end
@ -15,13 +15,17 @@ module Register
end end
end end
def self.function_call( source , method )
Register::FunctionCall.new( source , method )
end
def self.issue_call( compiler , callee ) def self.issue_call( compiler , callee )
return_label = Label.new("_return_label #{callee.name}" , "#{compiler.type.object_class.name}.#{compiler.method.name}" ) return_label = Register.label("_return_label #{callee.name}" , "#{compiler.type.object_class.name}.#{compiler.method.name}" )
ret_tmp = compiler.use_reg(:Label) ret_tmp = compiler.use_reg(:Label)
compiler.add_code Register.load_constant("#{callee.name} load ret", return_label , ret_tmp) compiler.add_code Register.load_constant("#{callee.name} load ret", return_label , ret_tmp)
compiler.add_code Register.reg_to_slot("#{callee.name} store ret", ret_tmp , :new_message , :return_address) compiler.add_code Register.reg_to_slot("#{callee.name} store ret", ret_tmp , :new_message , :return_address)
compiler.add_code Register.transfer("#{callee.name} move new message", Register.new_message_reg , Register.message_reg ) compiler.add_code Register.transfer("#{callee.name} move new message", Register.new_message_reg , Register.message_reg )
compiler.add_code FunctionCall.new( "#{callee.name} call" , callee ) compiler.add_code Register.function_call( "#{callee.name} call" , callee )
compiler.add_code return_label compiler.add_code return_label
compiler.add_code Register.transfer("#{callee.name} remove new message", Register.message_reg , Register.new_message_reg ) compiler.add_code Register.transfer("#{callee.name} remove new message", Register.message_reg , Register.new_message_reg )
compiler.add_code Register.slot_to_reg("#{callee.name} restore message" , :new_message , :caller , :message ) compiler.add_code Register.slot_to_reg("#{callee.name} restore message" , :new_message , :caller , :message )

View File

@ -4,7 +4,7 @@ module Register
# register and index specify where the return address is stored # register and index specify where the return address is stored
class FunctionReturn < Instruction class FunctionReturn < Instruction
def initialize source , register , index def initialize( source , register , index)
super(source) super(source)
@register = register @register = register
@index = index @index = index
@ -14,6 +14,9 @@ module Register
def to_s def to_s
"FunctionReturn: #{register} [#{index}]" "FunctionReturn: #{register} [#{index}]"
end end
end
def self.function_return( source , register , index)
FunctionReturn.new( source , register , index)
end end
end end

View File

@ -8,7 +8,7 @@ module Register
# #
class Label < Instruction class Label < Instruction
def initialize source , name , nekst = nil def initialize( source , name , nekst = nil)
super(source , nekst) super(source , nekst)
@name = name @name = name
end end
@ -77,4 +77,8 @@ module Register
super super
end end
end end
def self.label( source , name , nekst = nil)
Label.new( source , name , nekst = nil)
end
end end

View File

@ -11,11 +11,11 @@ module Register
# Produce a RegToByte instruction. # Produce a RegToByte instruction.
# from and to are translated (from symbol to register if neccessary) # from and to are translated (from symbol to register if neccessary)
# but index is left as is. # but index is left as is.
# def self.reg_to_byte source , from , to , index def self.reg_to_byte( source , from , to , index)
# from = resolve_to_register from from = resolve_to_register from
# index = resolve_to_index( to , index) index = resolve_to_index( to , index)
# to = resolve_to_register to to = resolve_to_register to
# RegToByte.new( source, from , to , index) RegToByte.new( source, from , to , index)
# end end
end end

View File

@ -105,7 +105,7 @@ module Register
when :new_message when :new_message
return new_message_reg return new_message_reg
else else
raise "not recognized register reference #{reference}" raise "not recognized register reference #{reference} #{reference.class}"
end end
end end

View File

@ -133,11 +133,11 @@ module Typed
def init_method def init_method
source = "_init_method" source = "_init_method"
name = "#{method.for_type.name}.#{method.name}" name = "#{method.for_type.name}.#{method.name}"
@method.instructions = Register::Label.new(source, name) @method.instructions = Register.label(source, name)
@current = enter = method.instructions @current = enter = method.instructions
add_code Register::Label.new( source, "return #{name}") add_code Register.label( source, "return #{name}")
#load the return address into pc, affecting return. (other cpus have commands for this, but not arm) #load the return address into pc, affecting return. (other cpus have commands for this, but not arm)
add_code Register::FunctionReturn.new( source , Register.message_reg , Register.resolve_to_index(:message , :return_address) ) add_code Register.function_return( source , Register.message_reg , Register.resolve_to_index(:message , :return_address) )
@current = enter @current = enter
self self
end end

View File

@ -21,7 +21,7 @@ module Typed
reset_regs reset_regs
process(statement.condition) process(statement.condition)
branch_class = Object.const_get "Register::Is#{statement.branch_type.capitalize}" branch_class = Object.const_get "Register::Is#{statement.branch_type.capitalize}"
true_block = Register::Label.new(statement, "if_true") true_block = Register.label(statement, "if_true")
add_code branch_class.new( statement.condition , true_block ) add_code branch_class.new( statement.condition , true_block )
return true_block return true_block
end end
@ -33,7 +33,7 @@ module Typed
def compile_if_false( statement ) def compile_if_false( statement )
reset_regs reset_regs
process(statement.if_false) if statement.if_false.statements process(statement.if_false) if statement.if_false.statements
merge = Register::Label.new(statement , "if_merge") merge = Register.label(statement , "if_merge")
add_code Register::Branch.new(statement.if_false, merge ) add_code Register::Branch.new(statement.if_false, merge )
merge merge
end end

View File

@ -22,13 +22,13 @@ module Typed
private private
def compile_while_preamble( statement ) def compile_while_preamble( statement )
condition_label = Register::Label.new(statement.condition , "condition_label") condition_label = Register.label(statement.condition , "condition_label")
# unconditionally branch to the condition upon entering the loop # unconditionally branch to the condition upon entering the loop
add_code Register::Branch.new(statement.condition , condition_label) add_code Register::Branch.new(statement.condition , condition_label)
condition_label condition_label
end end
def compile_while_body( statement ) def compile_while_body( statement )
start = Register::Label.new(statement , "while_start" ) start = Register.label(statement , "while_start" )
add_code start add_code start
reset_regs reset_regs
process(statement.statements) process(statement.statements)

View File

@ -81,7 +81,7 @@ class TestLogic < MiniTest::Test
end end
def label pos = 0x22 def label pos = 0x22
l = Register::Label.new("some" , "Label") l = Register.label("some" , "Label")
l.position = pos l.position = pos
l l
end end