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

@ -79,11 +79,11 @@ module Arm
def translate_LoadConstant( code )
constant = code.constant
constant = constant.to_cpu(self) if constant.is_a?(Risc::Label)
if constant.is_a?(Parfait::Object) or constant.is_a?(Symbol) or constant.is_a?(Risc::Label)
return ArmMachine.add( code.register , constant )
else
return ArmMachine.mov( code.register , constant )
end
def translate_LoadData( code )
return ArmMachine.mov( code.register , code.constant )
end
def translate_OperatorInstruction( code )

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 )

View File

@ -1,7 +1,7 @@
require_relative "helper"
module Risc
class InterpreterAdd < MiniTest::Test
class InterpreterMod < MiniTest::Test
include Ticker
def setup

View File

@ -31,7 +31,7 @@ module Risc
assert_equal 9 , sl.index
assert_equal :r3 , sl.register.symbol
end
def test_slot2 #load arg from args
def est_slot2 #load arg from args
sl = ticks( 48 )
assert_equal SlotToReg , sl.class
assert_equal :r2 , sl.array.symbol #load from message

View File

@ -22,12 +22,12 @@ module Risc
SlotToReg, RegToSlot, LoadConstant, SlotToReg, RegToSlot,
LoadConstant, SlotToReg, RegToSlot, SlotToReg, LoadConstant,
FunctionCall, Label, SlotToReg, SlotToReg, SlotToReg,
LoadConstant, OperatorInstruction, LoadConstant, OperatorInstruction, OperatorInstruction,
LoadConstant, Transfer, OperatorInstruction, OperatorInstruction, LoadConstant,
Transfer, OperatorInstruction, OperatorInstruction, LoadConstant, Transfer,
OperatorInstruction, OperatorInstruction, LoadConstant, OperatorInstruction, LoadConstant,
Transfer, OperatorInstruction, OperatorInstruction, Transfer, LoadConstant,
OperatorInstruction, LoadConstant, OperatorInstruction, OperatorInstruction, RegToSlot,
LoadData, OperatorInstruction, LoadData, OperatorInstruction, OperatorInstruction,
LoadData, Transfer, OperatorInstruction, OperatorInstruction, LoadData,
Transfer, OperatorInstruction, OperatorInstruction, LoadData, Transfer,
OperatorInstruction, OperatorInstruction, LoadData, OperatorInstruction, LoadData,
Transfer, OperatorInstruction, OperatorInstruction, Transfer, LoadData,
OperatorInstruction, LoadData, OperatorInstruction, OperatorInstruction, RegToSlot,
SlotToReg, SlotToReg, RegToSlot, SlotToReg, SlotToReg,
FunctionReturn, SlotToReg, SlotToReg, RegToSlot, SlotToReg,
SlotToReg, RegToSlot, SlotToReg, SlotToReg, RegToSlot,