introduce load_data instruction

which just loads data to a register (used internally)
as opposed to integers, which are objects
This commit is contained in:
Torsten Ruger
2018-03-31 12:38:30 +03:00
parent ee8b9469af
commit 6e941ebcb7
10 changed files with 56 additions and 26 deletions

View File

@ -20,8 +20,8 @@ module Risc
compiler = compiler_for(:Integer,:+ ,{other: :int})
me , other = self_and_int_arg(compiler,source + "1")
# reduce me and other to integers
compiler.add_slot_to_reg( source + "2" , me , 1 , me)
compiler.add_slot_to_reg( source + "3", other , 1 , other)
compiler.add_slot_to_reg( source + "2" , me , 2 , me)
compiler.add_slot_to_reg( source + "3", other , 2 , other)
compiler.add_code Risc.op( source + "4", :+ , me , other)
#TODO must get an Integer and put the value there then return the integer (object not value)
# and put it back into the return value
@ -36,47 +36,47 @@ module Risc
tmp = compiler.add_known( :receiver )
q = compiler.add_known( :receiver )
const = compiler.use_reg :Integer , 1
compiler.add_load_constant( s, 1 , const )
compiler.add_load_data( s, 1 , const )
# int tmp = self >> 1
compiler.add_code Risc.op( s , :>> , tmp , const)
# int q = self >> 2
compiler.add_load_constant( s , 2 , const)
compiler.add_load_data( s , 2 , const)
compiler.add_code Risc.op( s , :>> , q , const)
# q = q + tmp
compiler.add_code Risc.op( s , :+ , q , tmp )
# tmp = q >> 4
compiler.add_load_constant( s , 4 , const)
compiler.add_load_data( s , 4 , const)
compiler.add_transfer( s, q , tmp)
compiler.add_code Risc.op( s , :>> , tmp , const)
# q = q + tmp
compiler.add_code Risc.op( s , :+ , q , tmp )
# tmp = q >> 8
compiler.add_load_constant( s , 8 , const)
compiler.add_load_data( s , 8 , const)
compiler.add_transfer( s, q , tmp)
compiler.add_code Risc.op( s , :>> , tmp , const)
# q = q + tmp
compiler.add_code Risc.op( s , :+ , q , tmp )
# tmp = q >> 16
compiler.add_load_constant( s , 16 , const)
compiler.add_load_data( s , 16 , const)
compiler.add_transfer( s, q , tmp)
compiler.add_code Risc.op( s , :>> , tmp , const)
# q = q + tmp
compiler.add_code Risc.op( s , :+ , q , tmp )
# q = q >> 3
compiler.add_load_constant( s , 3 , const)
compiler.add_load_data( s , 3 , const)
compiler.add_code Risc.op( s , :>> , q , const)
# tmp = q * 10
compiler.add_load_constant( s , 10 , const)
compiler.add_load_data( s , 10 , const)
compiler.add_transfer( s, q , tmp)
compiler.add_code Risc.op( s , :* , tmp , const)
# tmp = self - tmp
compiler.add_code Risc.op( s , :- , me , tmp )
compiler.add_transfer( s , me , tmp)
# tmp = tmp + 6
compiler.add_load_constant( s , 6 , const)
compiler.add_load_data( s , 6 , const)
compiler.add_code Risc.op( s , :+ , tmp , const )
# tmp = tmp >> 4
compiler.add_load_constant( s , 4 , const)
compiler.add_load_data( s , 4 , const)
compiler.add_code Risc.op( s , :>> , tmp , const )
# return q + tmp
compiler.add_code Risc.op( s , :+ , q , tmp )

View File

@ -59,6 +59,7 @@ require_relative "instructions/slot_to_reg"
require_relative "instructions/reg_to_byte"
require_relative "instructions/byte_to_reg"
require_relative "instructions/load_constant"
require_relative "instructions/load_data"
require_relative "instructions/syscall"
require_relative "instructions/function_call"
require_relative "instructions/function_return"

View File

@ -20,7 +20,7 @@ module Risc
private
def constant_str
case @constant
when String , Symbol , Fixnum , Integer
when String , Symbol
@constant.to_s
else
if( @constant.respond_to? :sof_reference_name )

View File

@ -0,0 +1,27 @@
module Risc
# load raw data into a register
#
# This is not really used by the compiler, or to be more precise: not used during the
# compilation of ruby code. Ruby code works on Objects only
#
# But for Builtin methods, methods that are created programatically and form the runtime,
# it can be handy to load an integer directly withou the object overhead.
#
class LoadData < Instruction
def initialize( source , constant , register)
super(source)
@register = register
@constant = constant
raise "Not Integer #{constant}" unless constant.is_a?(Integer)
end
attr_accessor :register , :constant
def to_s
class_source "#{register} <- #{constant}"
end
end
def self.load_data( source , constant , register )
LoadData.new( source , constant , register)
end
end

View File

@ -125,6 +125,7 @@ module Risc
set_register( to , value )
true
end
alias :execute_LoadData :execute_LoadConstant
def execute_SlotToReg
object = get_register( @instruction.array )

View File

@ -92,7 +92,8 @@ module Risc
# for computationally building code (ie writing assembler) these short cuts
# help to instantiate risc instructions and add them immediately
[:label, :reg_to_slot , :slot_to_reg , :load_constant, :function_return , :function_call,
[:label, :reg_to_slot , :slot_to_reg , :load_constant, :load_data,
:function_return , :function_call,
:transfer , :reg_to_slot , :byte_to_reg , :reg_to_byte].each do |method|
define_method("add_#{method}".to_sym) do |*args|
add_code Risc.send( method , *args )