diff --git a/lib/risc/builder.rb b/lib/risc/builder.rb index dd517e99..35c4e6d3 100644 --- a/lib/risc/builder.rb +++ b/lib/risc/builder.rb @@ -56,7 +56,7 @@ module Risc def infer_type( name ) as_string = name.to_s parts = as_string.split("_") - if(parts.last == "reg" or parts.last == "obj" or parts.last == "tmp") + if( ["reg" , "obj" , "tmp" , "self" , "const", "1" , "2"].include?( parts.last ) ) parts.pop as_string = parts.join("_") end diff --git a/lib/risc/builtin/integer.rb b/lib/risc/builtin/integer.rb index cab77655..15e1f5ea 100644 --- a/lib/risc/builtin/integer.rb +++ b/lib/risc/builtin/integer.rb @@ -102,24 +102,27 @@ module Risc return compiler end - # old helper function for div10 (which doesn't use builder yet) - def add_receiver(builder) - message = Risc.message_reg - ret_type = builder.compiler.receiver_type - ret = builder.compiler.use_reg( ret_type ).set_builder(builder) - builder.add_slot_to_reg(" load self" , message , :receiver , ret ) - builder.add_slot_to_reg( "int -> fix" , ret , Parfait::Integer.integer_index , ret) - return ret - end - + # as the name suggests, this devides the integer (self) by ten + # + # This version is lifted from some arm assembler tricks and is _much_ + # faster than the general div versions. I think it was about three + # times less instructions. Useful for itos + # + # In fact it is possible to generate specific div function for any given + # integer and some are even more faster (as eg div4). def div10( context ) s = "div_10 " compiler = compiler_for(:Integer,:div10 ,{}) builder = compiler.compiler_builder(compiler.source) - #FIX: this could load receiver once, reduce and then transfer twice - me = add_receiver( builder ) - tmp = add_receiver( builder ) - q = add_receiver( builder ) + builder.build do + integer_self! << message[:receiver] + integer_self.reduce_int + integer_tmp! << integer_self + integer_reg! << integer_self + end + me = builder.integer_self + tmp = builder.integer_tmp + q = builder.integer_reg const = compiler.use_reg :fixnum , value: 1 builder.add_load_data( s , 1 , const ) # int tmp = self >> 1 diff --git a/test/risc/interpreter/calling/test_div10.rb b/test/risc/interpreter/calling/test_div10.rb index 07c84ff7..ee3bbe80 100644 --- a/test/risc/interpreter/calling/test_div10.rb +++ b/test/risc/interpreter/calling/test_div10.rb @@ -14,32 +14,31 @@ module Risc check_main_chain [LoadConstant, LoadConstant, SlotToReg, SlotToReg, RegToSlot, RegToSlot, RegToSlot, RegToSlot, LoadConstant, SlotToReg, # 10 RegToSlot, LoadConstant, SlotToReg, Branch, RegToSlot, - SlotToReg, FunctionCall, SlotToReg, SlotToReg, SlotToReg, # 20 - SlotToReg, SlotToReg, SlotToReg, LoadData, OperatorInstruction, - LoadData, OperatorInstruction, OperatorInstruction, LoadData, Transfer, # 30 - Branch, OperatorInstruction, OperatorInstruction, LoadData, Transfer, - OperatorInstruction, OperatorInstruction, LoadData, Transfer, OperatorInstruction, # 40 - OperatorInstruction, LoadData, OperatorInstruction, LoadData, Branch, - Transfer, OperatorInstruction, OperatorInstruction, Transfer, LoadData, # 50 - OperatorInstruction, LoadData, OperatorInstruction, OperatorInstruction, LoadConstant, - SlotToReg, SlotToReg, RegToSlot, Branch, RegToSlot, # 60 - RegToSlot, SlotToReg, SlotToReg, RegToSlot, LoadConstant, - SlotToReg, RegToSlot, RegToSlot, SlotToReg, SlotToReg, # 70 - SlotToReg, FunctionReturn, SlotToReg, SlotToReg, RegToSlot, - SlotToReg, SlotToReg, RegToSlot, Branch, SlotToReg, # 80 - SlotToReg, RegToSlot, Branch, LoadConstant, SlotToReg, - RegToSlot, RegToSlot, SlotToReg, SlotToReg, SlotToReg, # 90 - FunctionReturn, Transfer, SlotToReg, SlotToReg, Syscall, - NilClass, ] + SlotToReg, FunctionCall, SlotToReg, SlotToReg, Transfer, # 20 + Transfer, LoadData, OperatorInstruction, LoadData, OperatorInstruction, + OperatorInstruction, LoadData, Transfer, OperatorInstruction, OperatorInstruction, # 30 + Branch, LoadData, Transfer, OperatorInstruction, OperatorInstruction, + LoadData, Transfer, OperatorInstruction, OperatorInstruction, LoadData, # 40 + OperatorInstruction, LoadData, Transfer, OperatorInstruction, Branch, + OperatorInstruction, Transfer, LoadData, OperatorInstruction, LoadData, # 50 + OperatorInstruction, OperatorInstruction, LoadConstant, SlotToReg, SlotToReg, + RegToSlot, RegToSlot, RegToSlot, Branch, SlotToReg, # 60 + SlotToReg, RegToSlot, LoadConstant, SlotToReg, RegToSlot, + RegToSlot, SlotToReg, SlotToReg, SlotToReg, FunctionReturn, # 70 + SlotToReg, SlotToReg, RegToSlot, SlotToReg, SlotToReg, + RegToSlot, Branch, SlotToReg, SlotToReg, RegToSlot, # 80 + Branch, LoadConstant, SlotToReg, RegToSlot, RegToSlot, + SlotToReg, SlotToReg, SlotToReg, FunctionReturn, Transfer, # 90 + SlotToReg, SlotToReg, Syscall, NilClass, ] assert_equal 2 , get_return end def test_load_space - load_ins = main_ticks 55 + load_ins = main_ticks 53 assert_load load_ins, Parfait::Space end def test_load_to - to = main_ticks 56 + to = main_ticks 54 assert_slot_to_reg to , :r5 , 5 ,:r2 end def test_load_25 @@ -48,7 +47,7 @@ module Risc assert_equal 25 , @interpreter.get_register(load_ins.register).value end def test_return_class - ret = main_ticks(72) + ret = main_ticks(70) assert_equal FunctionReturn , ret.class link = @interpreter.get_register( ret.register ) assert_equal Fixnum , link.class diff --git a/test/risc/test_builder2.rb b/test/risc/test_builder2.rb index 48326abe..6a919eeb 100644 --- a/test/risc/test_builder2.rb +++ b/test/risc/test_builder2.rb @@ -31,6 +31,15 @@ module Risc def test_caller_obj assert_equal :Message , @builder.infer_type(:caller_obj).class_name end + def test_caller_const + assert_equal :Message , @builder.infer_type(:caller_const).class_name + end + def test_caller_self + assert_equal :Message , @builder.infer_type(:caller_self).class_name + end + def test_caller_1 + assert_equal :Message , @builder.infer_type(:caller_1).class_name + end def test_message assert_equal :Message , @builder.infer_type(:message).class_name end