From e551732f18ba78ee0bda0a298c91fc271d1be20f Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Wed, 28 Dec 2016 20:37:54 +0200 Subject: [PATCH] tighter integration with factory methods for adding code define methods to collapse the code Register. in add_code Register.factory_method most instructions done, except op and branch that are rare --- lib/register/builtin/compile_helper.rb | 4 +-- lib/register/builtin/integer.rb | 28 +++++++++--------- lib/register/builtin/kernel.rb | 20 ++++++------- lib/register/builtin/object.rb | 6 ++-- lib/register/builtin/word.rb | 10 +++---- lib/register/instructions/function_call.rb | 10 +++---- lib/typed/method_compiler.rb | 11 +++++-- lib/typed/method_compiler/assignment.rb | 4 +-- lib/typed/method_compiler/basic_values.rb | 12 ++++---- lib/typed/method_compiler/call_site.rb | 29 +++++++++---------- lib/typed/method_compiler/field_access.rb | 2 +- lib/typed/method_compiler/name_expression.rb | 14 ++++----- lib/typed/method_compiler/return_statement.rb | 2 +- 13 files changed, 79 insertions(+), 73 deletions(-) diff --git a/lib/register/builtin/compile_helper.rb b/lib/register/builtin/compile_helper.rb index ef35733b..bbd67680 100644 --- a/lib/register/builtin/compile_helper.rb +++ b/lib/register/builtin/compile_helper.rb @@ -17,8 +17,8 @@ module Register # Load the value def load_int_arg_at(compiler, source , at) int_arg = compiler.use_reg :Integer - compiler.add_code Register.slot_to_reg(source , :message , :arguments , int_arg ) - compiler.add_code Register.slot_to_reg(source , int_arg , at + 1, int_arg ) #1 for type + compiler.add_slot_to_reg(source , :message , :arguments , int_arg ) + compiler.add_slot_to_reg(source , int_arg , at + 1, int_arg ) #1 for type return int_arg end diff --git a/lib/register/builtin/integer.rb b/lib/register/builtin/integer.rb index 74a0363b..ed9b5c8e 100644 --- a/lib/register/builtin/integer.rb +++ b/lib/register/builtin/integer.rb @@ -25,47 +25,47 @@ module Register # int tmp = self >> 1 compiler.add_code Register.op( s , ">>" , tmp , const) # int q = self >> 2 - compiler.add_code Register.load_constant( s , 2 , const) + compiler.add_load_constant( s , 2 , const) compiler.add_code Register.op( s , ">>" , q , const) # q = q + tmp compiler.add_code Register.op( s , "+" , q , tmp ) # tmp = q >> 4 - compiler.add_code Register.load_constant( s , 4 , const) - compiler.add_code Register.transfer( s, q , tmp) + compiler.add_load_constant( s , 4 , const) + compiler.add_transfer( s, q , tmp) compiler.add_code Register.op( s , ">>" , tmp , const) # q = q + tmp compiler.add_code Register.op( s , "+" , q , tmp ) # tmp = q >> 8 - compiler.add_code Register.load_constant( s , 8 , const) - compiler.add_code Register.transfer( s, q , tmp) + compiler.add_load_constant( s , 8 , const) + compiler.add_transfer( s, q , tmp) compiler.add_code Register.op( s , ">>" , tmp , const) # q = q + tmp compiler.add_code Register.op( s , "+" , q , tmp ) # tmp = q >> 16 - compiler.add_code Register.load_constant( s , 16 , const) - compiler.add_code Register.transfer( s, q , tmp) + compiler.add_load_constant( s , 16 , const) + compiler.add_transfer( s, q , tmp) compiler.add_code Register.op( s , ">>" , tmp , const) # q = q + tmp compiler.add_code Register.op( s , "+" , q , tmp ) # q = q >> 3 - compiler.add_code Register.load_constant( s , 3 , const) + compiler.add_load_constant( s , 3 , const) compiler.add_code Register.op( s , ">>" , q , const) # tmp = q * 10 - compiler.add_code Register.load_constant( s , 10 , const) - compiler.add_code Register.transfer( s, q , tmp) + compiler.add_load_constant( s , 10 , const) + compiler.add_transfer( s, q , tmp) compiler.add_code Register.op( s , "*" , tmp , const) # tmp = self - tmp compiler.add_code Register.op( s , "-" , me , tmp ) - compiler.add_code Register.transfer( s , me , tmp) + compiler.add_transfer( s , me , tmp) # tmp = tmp + 6 - compiler.add_code Register.load_constant( s , 6 , const) + compiler.add_load_constant( s , 6 , const) compiler.add_code Register.op( s , "+" , tmp , const ) # tmp = tmp >> 4 - compiler.add_code Register.load_constant( s , 4 , const) + compiler.add_load_constant( s , 4 , const) compiler.add_code Register.op( s , ">>" , tmp , const ) # return q + tmp compiler.add_code Register.op( s , "+" , q , tmp ) - compiler.add_code Register.reg_to_slot( s , q , :message , :return_value) + compiler.add_reg_to_slot( s , q , :message , :return_value) return compiler.method end end diff --git a/lib/register/builtin/kernel.rb b/lib/register/builtin/kernel.rb index 273d37d9..ac7c729b 100644 --- a/lib/register/builtin/kernel.rb +++ b/lib/register/builtin/kernel.rb @@ -13,14 +13,14 @@ module Register space = Parfait::Space.object_space space_reg = compiler.use_reg(:Space) #Set up the Space as self upon init - compiler.add_code Register.load_constant("__init__ load Space", space , space_reg) + compiler.add_load_constant("__init__ load Space", space , space_reg) 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.reg_to_slot( "__init__ store Space in message", space_reg , :message , :receiver) + compiler.add_slot_to_reg( "__init__ load 1st message" , space_reg , message_ind , :message) + compiler.add_reg_to_slot( "__init__ store Space in message", space_reg , :message , :receiver) exit_label = Register.label("_exit_label for __init__" , "#{compiler.type.object_class.name}.#{compiler.method.name}" ) ret_tmp = compiler.use_reg(:Label) - 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_load_constant("__init__ load return", exit_label , ret_tmp) + compiler.add_reg_to_slot("__init__ store return", ret_tmp , :message , :return_address) compiler.add_code Register.function_call( "__init__ issue call" , Register.machine.space.get_main ) compiler.add_code exit_label emit_syscall( compiler , :exit ) @@ -38,7 +38,7 @@ module Register compiler.add_code Syscall.new("emit_syscall(#{name})", name ) restore_message(compiler) return unless (@clazz and @method) - compiler.add_code Register.label( "#{@clazz.name}.#{@message.name}" , "return_syscall" ) + compiler.add_label( "#{@clazz.name}.#{@message.name}" , "return_syscall" ) end # save the current message, as the syscall destroys all context @@ -47,7 +47,7 @@ module Register # def save_message(compiler) r8 = RegisterValue.new( :r8 , :Message) - compiler.add_code Register.transfer("save_message", Register.message_reg , r8 ) + compiler.add_transfer("save_message", Register.message_reg , r8 ) end def restore_message(compiler) @@ -55,11 +55,11 @@ module Register return_tmp = Register.tmp_reg :Integer source = "_restore_message" # get the sys return out of the way - compiler.add_code Register.transfer(source, Register.message_reg , return_tmp ) + compiler.add_transfer(source, Register.message_reg , return_tmp ) # load the stored message into the base RegisterMachine - compiler.add_code Register.transfer(source, r8 , Register.message_reg ) + compiler.add_transfer(source, r8 , Register.message_reg ) # save the return value into the message - compiler.add_code Register.reg_to_slot( source , return_tmp , :message , :return_value ) + compiler.add_reg_to_slot( source , return_tmp , :message , :return_value ) end end extend ClassMethods diff --git a/lib/register/builtin/object.rb b/lib/register/builtin/object.rb index d8b1116e..a67132f0 100644 --- a/lib/register/builtin/object.rb +++ b/lib/register/builtin/object.rb @@ -14,9 +14,9 @@ module Register source = "get_internal_word" me , index = self_and_int_arg(compiler,source) # reduce me to me[index] - compiler.add_code Register.slot_to_reg( source , me , index , me) + compiler.add_slot_to_reg( source , me , index , me) # and put it back into the return value - compiler.add_code Register.reg_to_slot( source , me , :message , :return_value) + compiler.add_reg_to_slot( source , me , :message , :return_value) return compiler.method end @@ -29,7 +29,7 @@ module Register value = load_int_arg_at(compiler,source , 2) # do the set - compiler.add_code Register.reg_to_slot( source , value , me , index) + compiler.add_reg_to_slot( source , value , me , index) return compiler.method end diff --git a/lib/register/builtin/word.rb b/lib/register/builtin/word.rb index 7a7e90b8..536c2326 100644 --- a/lib/register/builtin/word.rb +++ b/lib/register/builtin/word.rb @@ -8,10 +8,10 @@ module Register def putstring context compiler = Typed::MethodCompiler.new.create_method(:Word , :putstring ).init_method - compiler.add_code Register.slot_to_reg( "putstring" , :message , :receiver , :new_message ) + compiler.add_slot_to_reg( "putstring" , :message , :receiver , :new_message ) index = Parfait::Word.get_length_index reg = RegisterValue.new(:r2 , :Integer) - compiler.add_code Register.slot_to_reg( "putstring" , :new_message , index , reg ) + compiler.add_slot_to_reg( "putstring" , :new_message , index , reg ) Kernel.emit_syscall( compiler , :putstring ) compiler.method end @@ -23,9 +23,9 @@ module Register source = "get_internal_byte" me , index = self_and_int_arg(compiler,source) # reduce me to me[index] - compiler.add_code Register.byte_to_reg( source , me , index , me) + compiler.add_byte_to_reg( source , me , index , me) # and put it back into the return value - compiler.add_code Register.reg_to_slot( source , me , :message , :return_value) + compiler.add_reg_to_slot( source , me , :message , :return_value) return compiler.method end @@ -41,7 +41,7 @@ module Register me , index = self_and_int_arg(compiler,source) value = load_int_arg_at(compiler , source , 2 ) # do the set - compiler.add_code Register.reg_to_byte( source , value , me , index) + compiler.add_reg_to_byte( source , value , me , index) return compiler.method end diff --git a/lib/register/instructions/function_call.rb b/lib/register/instructions/function_call.rb index 3c86a952..f9d6ea07 100644 --- a/lib/register/instructions/function_call.rb +++ b/lib/register/instructions/function_call.rb @@ -22,12 +22,12 @@ module Register def self.issue_call( compiler , callee ) return_label = Register.label("_return_label #{callee.name}" , "#{compiler.type.object_class.name}.#{compiler.method.name}" ) ret_tmp = compiler.use_reg(:Label) - 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.transfer("#{callee.name} move new message", Register.new_message_reg , Register.message_reg ) + compiler.add_load_constant("#{callee.name} load ret", return_label , ret_tmp) + compiler.add_reg_to_slot("#{callee.name} store ret", ret_tmp , :new_message , :return_address) + compiler.add_transfer("#{callee.name} move new message", Register.new_message_reg , Register.message_reg ) compiler.add_code Register.function_call( "#{callee.name} call" , callee ) 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.slot_to_reg("#{callee.name} restore message" , :new_message , :caller , :message ) + compiler.add_transfer("#{callee.name} remove new message", Register.message_reg , Register.new_message_reg ) + compiler.add_slot_to_reg("#{callee.name} restore message" , :new_message , :caller , :message ) end end diff --git a/lib/typed/method_compiler.rb b/lib/typed/method_compiler.rb index 1c94486f..17eaea87 100644 --- a/lib/typed/method_compiler.rb +++ b/lib/typed/method_compiler.rb @@ -135,9 +135,9 @@ module Typed name = "#{method.for_type.name}.#{method.name}" @method.instructions = Register.label(source, name) @current = enter = method.instructions - add_code Register.label( source, "return #{name}") + add_label( source, "return #{name}") #load the return address into pc, affecting return. (other cpus have commands for this, but not arm) - add_code Register.function_return( source , Register.message_reg , Register.resolve_to_index(:message , :return_address) ) + add_function_return( source , Register.message_reg , Register.resolve_to_index(:message , :return_address) ) @current = enter self end @@ -157,6 +157,13 @@ module Typed self end + [:label, :reg_to_slot , :slot_to_reg , :load_constant, :function_return , + :transfer , :reg_to_slot , :byte_to_reg , :reg_to_byte].each do |method| + define_method("add_#{method}".to_sym) do |*args| + add_code Register.send( method , *args ) + end + end + # require a (temporary) register. code must give this back with release_reg def use_reg( type , value = nil ) raise "Not type #{type.inspect}" unless type.is_a?(Symbol) or type.is_a?(Parfait::Type) diff --git a/lib/typed/method_compiler/assignment.rb b/lib/typed/method_compiler/assignment.rb index 3ffa5da2..eabc7a18 100644 --- a/lib/typed/method_compiler/assignment.rb +++ b/lib/typed/method_compiler/assignment.rb @@ -17,8 +17,8 @@ module Typed value_type = @method.locals_type( index ) end raise "Type mismatch for #{type} access #{value.type}!=#{value_type}" unless value.type == value_type - add_code Register.slot_to_reg(statement , :message , type , named_list ) - add_code Register.reg_to_slot(statement , value , named_list , index + 1 ) # one for type + add_slot_to_reg(statement , :message , type , named_list ) + add_reg_to_slot(statement , value , named_list , index + 1 ) # one for type end # ensure the name given is not space and raise exception otherwise diff --git a/lib/typed/method_compiler/basic_values.rb b/lib/typed/method_compiler/basic_values.rb index b7551538..8b23ad3a 100644 --- a/lib/typed/method_compiler/basic_values.rb +++ b/lib/typed/method_compiler/basic_values.rb @@ -13,25 +13,25 @@ module Typed def on_IntegerExpression expression int = expression.value reg = use_reg :Integer , int - add_code Register.load_constant( expression, int , reg ) + add_load_constant( expression, int , reg ) return reg end def on_TrueExpression expression reg = use_reg :Boolean - add_code Register.load_constant( expression, true , reg ) + add_load_constant( expression, true , reg ) return reg end def on_FalseExpression expression reg = use_reg :Boolean - add_code Register.load_constant( expression, false , reg ) + add_load_constant( expression, false , reg ) return reg end def on_NilExpression expression reg = use_reg :NilClass - add_code Register.load_constant( expression, nil , reg ) + add_load_constant( expression, nil , reg ) return reg end @@ -39,7 +39,7 @@ module Typed value = Parfait.new_word expression.value.to_sym reg = use_reg :Word Register.machine.constants << value - add_code Register.load_constant( expression, value , reg ) + add_load_constant( expression, value , reg ) return reg end @@ -48,7 +48,7 @@ module Typed clazz = Parfait::Space.object_space.get_class_by_name! name raise "No such class #{name}" unless clazz reg = use_reg :MetaClass , clazz - add_code Register.load_constant( expression, clazz , reg ) + add_load_constant( expression, clazz , reg ) return reg end diff --git a/lib/typed/method_compiler/call_site.rb b/lib/typed/method_compiler/call_site.rb index 8c1dc7e7..6997dfb1 100644 --- a/lib/typed/method_compiler/call_site.rb +++ b/lib/typed/method_compiler/call_site.rb @@ -7,7 +7,7 @@ module Typed reset_regs #move the new message (that we need to populate to make a call) to std register new_message = Register.resolve_to_register(:new_message) - add_code Register.slot_to_reg(statement, :message , :next_message , new_message ) + add_slot_to_reg(statement, :message , :next_message , new_message ) me = get_me( statement ) type = get_my_type(me) @@ -15,7 +15,7 @@ module Typed raise "Method not implemented #{type.inspect}.#{statement.name}" unless method # move our receiver there - add_code Register.reg_to_slot( statement , me , :new_message , :receiver) + add_reg_to_slot( statement , me , :new_message , :receiver) set_message_details(method , statement , statement.arguments) set_arguments(method , statement.arguments) @@ -25,7 +25,7 @@ module Typed # the effect of the method is that the NewMessage Return slot will be filled, return it # but move it into a register too - add_code Register.slot_to_reg(statement, :new_message , :return_value , ret ) + add_slot_to_reg(statement, :new_message , :return_value , ret ) ret end @@ -36,7 +36,7 @@ module Typed me = process( statement.receiver ) else me = use_reg @method.for_type - add_code Register.slot_to_reg(statement, :message , :receiver , me ) + add_slot_to_reg(statement, :message , :receiver , me ) end me end @@ -58,22 +58,22 @@ module Typed def set_message_details( method , name_s , arguments ) name = name_s.name name_tmp = use_reg(:Word) - add_code Register.load_constant("#{name} load method name", name , name_tmp) - add_code Register.reg_to_slot( "#{name} store method name" , name_tmp , :new_message , :name) + add_load_constant("#{name} load method name", name , name_tmp) + add_reg_to_slot( "#{name} store method name" , name_tmp , :new_message , :name) # next arg and local types args_reg = use_reg(:Type , method.arguments ) list_reg = use_reg(:NamedList , arguments ) - add_code Register.load_constant("#{name} load methods", method , args_reg) + add_load_constant("#{name} load methods", method , args_reg) args_type_index = method.get_type().variable_index(:arguments) raise args_type_index.to_s unless args_type_index == 6 - add_code Register.slot_to_reg( "#{name} get args type from method" , args_reg , args_type_index , args_reg ) - add_code Register.slot_to_reg( "#{name} get args from method" , :new_message , :arguments , list_reg ) - add_code Register.reg_to_slot( "#{name} store args type in args" , args_reg , list_reg , 1 ) + add_slot_to_reg( "#{name} get args type from method" , args_reg , args_type_index , args_reg ) + add_slot_to_reg( "#{name} get args from method" , :new_message , :arguments , list_reg ) + add_reg_to_slot( "#{name} store args type in args" , args_reg , list_reg , 1 ) #FIXME need to set type of locals too. sama sama # len_tmp = use_reg(:Integer , arguments.to_a.length ) -# add_code Register.load_constant(name_s, arguments.to_a.length , len_tmp) -# add_code Register.reg_to_slot( name_s , len_tmp , :new_message , :indexed_length) +# add_load_constant(name_s, arguments.to_a.length , len_tmp) +# add_reg_to_slot( name_s , len_tmp , :new_message , :indexed_length) end def set_arguments( method , arguments ) @@ -89,10 +89,9 @@ module Typed #FIXME definately needs some tests raise "TypeMismatch calling with #{val.type} , instead of #{arg_type.type_at(i + 2)}" if val.type != arg_type.type_at(i + 2) list_reg = use_reg(:NamedList , arguments ) - add_code Register.slot_to_reg( "Set arg #{i}:#{arg}" , :new_message , :arguments , list_reg ) + add_slot_to_reg( "Set arg #{i}:#{arg}" , :new_message , :arguments , list_reg ) # which we load int the new_message at the argument's index - set = Register.reg_to_slot( arg , val , list_reg , i + 2 ) #one for type and one for ruby - add_code set + add_reg_to_slot( arg , val , list_reg , i + 2 ) #one for type and one for ruby end end end diff --git a/lib/typed/method_compiler/field_access.rb b/lib/typed/method_compiler/field_access.rb index 8aec8cbe..84569f20 100644 --- a/lib/typed/method_compiler/field_access.rb +++ b/lib/typed/method_compiler/field_access.rb @@ -15,7 +15,7 @@ module Typed raise "no such field:#{field_name} for class #{type.inspect}" unless index value = use_reg(type.type_at(index)) - add_code Register.slot_to_reg(statement , receiver , index, value) + add_slot_to_reg(statement , receiver , index, value) value end diff --git a/lib/typed/method_compiler/name_expression.rb b/lib/typed/method_compiler/name_expression.rb index 2f9ad6f2..c3f452f7 100644 --- a/lib/typed/method_compiler/name_expression.rb +++ b/lib/typed/method_compiler/name_expression.rb @@ -15,8 +15,8 @@ module Typed named_list = use_reg :NamedList ret = use_reg @method.argument_type(index) #puts "For #{name} at #{index} got #{@method.arguments.inspect}" - add_code Register.slot_to_reg("#{statement} load args" , :message , :arguments, named_list ) - add_code Register.slot_to_reg("#{statement} load #{name}" , named_list , index + 1, ret ) + add_slot_to_reg("#{statement} load args" , :message , :arguments, named_list ) + add_slot_to_reg("#{statement} load #{name}" , named_list , index + 1, ret ) return ret end # or a local so it is in the named_list @@ -30,28 +30,28 @@ module Typed index = @method.has_local( name ) raise "must define variable '#{name}' before using it" unless index named_list = use_reg :NamedList - add_code Register.slot_to_reg("#{name} load locals" , :message , :locals , named_list ) + add_slot_to_reg("#{name} load locals" , :message , :locals , named_list ) ret = use_reg @method.locals_type( index ) - add_code Register.slot_to_reg("#{name} load from locals" , named_list , index + 1, ret ) + add_slot_to_reg("#{name} load from locals" , named_list , index + 1, ret ) return ret end def handle_special_self(statement) ret = use_reg @type - add_code Register.slot_to_reg("#{statement} load self" , :message , :receiver , ret ) + add_slot_to_reg("#{statement} load self" , :message , :receiver , ret ) return ret end def handle_special_space(statement) space = Parfait::Space.object_space reg = use_reg :Space , space - add_code Register.load_constant( "#{statement} load space", space , reg ) + add_load_constant( "#{statement} load space", space , reg ) return reg end def handle_special_message(statement) reg = use_reg :Message - add_code Register.transfer( "#{statement} load message", Register.message_reg , reg ) + add_transfer( "#{statement} load message", Register.message_reg , reg ) return reg end end #module diff --git a/lib/typed/method_compiler/return_statement.rb b/lib/typed/method_compiler/return_statement.rb index d91b6120..18a8ae19 100644 --- a/lib/typed/method_compiler/return_statement.rb +++ b/lib/typed/method_compiler/return_statement.rb @@ -3,7 +3,7 @@ module Typed def on_ReturnStatement statement reg = process(statement.return_value) - add_code Register.reg_to_slot( statement, reg , :message , :return_value) + add_reg_to_slot( statement, reg , :message , :return_value) nil # statements don't return end end