remove the old add_new_int and calls
last orrurences in syscalls replaced, 2 variants - exit does not actually need the int - all else, preallocate the int beforehand and in syscall assume the reg name (integer_tmp) test missing
This commit is contained in:
parent
a8d1f070f1
commit
e6615d0a6a
@ -58,7 +58,10 @@ module Mom
|
|||||||
branch while_start_label
|
branch while_start_label
|
||||||
|
|
||||||
add_code exit_label
|
add_code exit_label
|
||||||
Risc::Builtin::Object.emit_syscall( builder , :exit )
|
# temporary, need to raise really.
|
||||||
|
factory! << Parfait.object_space.get_factory_for(:Integer)
|
||||||
|
integer_tmp! << factory[:reserve]
|
||||||
|
Risc::Builtin::Object.emit_syscall( builder , :exit ) #uses integer_tmp
|
||||||
|
|
||||||
add_code ok_label
|
add_code ok_label
|
||||||
cache_entry[:cached_method] << callable_method
|
cache_entry[:cached_method] << callable_method
|
||||||
|
@ -38,7 +38,7 @@ module Risc
|
|||||||
if last_char == "!" or last_char == "?"
|
if last_char == "!" or last_char == "?"
|
||||||
if @names.has_key?(name)
|
if @names.has_key?(name)
|
||||||
return @names[name] if last_char == "?"
|
return @names[name] if last_char == "?"
|
||||||
raise "Name exists before creating it #{name}#{last_char}"
|
raise "Name exists (#{@names.keys})before creating it #{name}#{last_char}"
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
raise "Must create (with ! or ?) before using #{name}#{last_char}"
|
raise "Must create (with ! or ?) before using #{name}#{last_char}"
|
||||||
@ -50,7 +50,7 @@ module Risc
|
|||||||
reg
|
reg
|
||||||
end
|
end
|
||||||
|
|
||||||
# Infer the type from a symbol. In the simplest case the sybbol is the class name.
|
# Infer the type from a symbol. In the simplest case the symbol is the class name.
|
||||||
# But in building, sometimes variations are needed, so next_message or caller work
|
# But in building, sometimes variations are needed, so next_message or caller work
|
||||||
# too (and both return "Message")
|
# too (and both return "Message")
|
||||||
# A general "_reg"/"_obj"/"_const" or "_tmp" at the end of the name will be removed
|
# A general "_reg"/"_obj"/"_const" or "_tmp" at the end of the name will be removed
|
||||||
@ -114,8 +114,8 @@ module Risc
|
|||||||
compiler.reset_regs
|
compiler.reset_regs
|
||||||
end
|
end
|
||||||
|
|
||||||
# Build code using dsl (see __init__ or MessageSetup for examples)
|
# Build code using dsl (see __init__ or MessageSetup for examples).
|
||||||
# names (that ruby would resolve to a variable/method) are converted
|
# Names (that ruby would resolve to a variable/method) are converted
|
||||||
# to registers. << means assignment and [] is supported both on
|
# to registers. << means assignment and [] is supported both on
|
||||||
# L and R values (but only one at a time). R values may also be constants.
|
# L and R values (but only one at a time). R values may also be constants.
|
||||||
#
|
#
|
||||||
@ -123,7 +123,7 @@ module Risc
|
|||||||
# Transfer instructions with extremely readable code.
|
# Transfer instructions with extremely readable code.
|
||||||
# example:
|
# example:
|
||||||
# space << Parfait.object_space # load constant
|
# space << Parfait.object_space # load constant
|
||||||
# message[:receiver] << space #make current message (r0) receiver the space
|
# message[:receiver] << space #make current message's (r0) receiver the space
|
||||||
#
|
#
|
||||||
# build result is added to compiler directly
|
# build result is added to compiler directly
|
||||||
#
|
#
|
||||||
@ -137,22 +137,37 @@ module Risc
|
|||||||
return ins
|
return ins
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# for some methods that return an integer it is beneficial to pre allocate the
|
||||||
|
# integer and store it in the return value. That is what this function does.
|
||||||
|
#
|
||||||
|
# Those (builtin) methods, mostly syscall wrappers then go on to do this and that
|
||||||
|
# clobbering registers and so the allocate and even move would be difficult.
|
||||||
|
# We sidestep all that by pre-allocating.
|
||||||
|
def prepare_int_return
|
||||||
|
integer_tmp = allocate_int
|
||||||
|
build do
|
||||||
|
message[:return_value] << integer_tmp
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# allocate int fetches a new int, for sure. It is a builder method, rather than
|
# allocate int fetches a new int, for sure. It is a builder method, rather than
|
||||||
# an inbuilt one, to avoid call overhead for 99.9%
|
# an inbuilt one, to avoid call overhead for 99.9%
|
||||||
# The factories allocate in 1k, so only when that runs out do we really need a call.
|
# The factories allocate in 1k, so only when that runs out do we really need a call.
|
||||||
# Note:
|
# Note:
|
||||||
# Unfortunately (or so me thinks), this creates code bloat, as the calling is
|
# Unfortunately (or so me thinks), this creates code bloat, as the calling is
|
||||||
# included in 100%, but only needed in 0.1. Risc-levelBlocks or Macros may be needed.
|
# included in 100%, but only needed in 0.1. Risc-level Blocks or Macros may be needed.
|
||||||
# as the calling in (the same) 30-40 instructions for every basic int op.
|
# as the calling in (the same) 40-50 instructions for every basic int op.
|
||||||
#
|
#
|
||||||
# The method
|
# The method
|
||||||
# - grabs a Integer instance from the Integer factory
|
# - grabs a Integer instance from the Integer factory
|
||||||
# - checks for nil and calls (get_more) for more if needed
|
# - checks for nil and calls (get_more) for more if needed
|
||||||
# - returns the RiscValue (Regster) where the object is found
|
# - returns the RiscValue (Register) where the object is found
|
||||||
#
|
#
|
||||||
# The implicit condition is that the method is called at the entry of a method.
|
# The implicit condition is that the method is called at the entry of a method.
|
||||||
# It uses a fair few registers and resets all at the end. The returned object
|
# It uses a fair few registers and resets all at the end. The returned object
|
||||||
# will always be in r1, because the method resets, and all others will be clobbered
|
# will always be in r1, because the method resets, and all others will be clobbered.
|
||||||
|
#
|
||||||
|
# Return RegisterValue(:r1) that will be named integer_tmp
|
||||||
def allocate_int
|
def allocate_int
|
||||||
compiler.reset_regs
|
compiler.reset_regs
|
||||||
integer = self.integer!
|
integer = self.integer!
|
||||||
@ -194,17 +209,6 @@ module Risc
|
|||||||
Mom::SimpleCall.new(calling).to_risc(compiler)
|
Mom::SimpleCall.new(calling).to_risc(compiler)
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_new_int( source , from, to )
|
|
||||||
to.set_builder( self ) # esecially div10 comes in without having used builder
|
|
||||||
from.set_builder( self ) # not named regs, different regs ==> silent errors
|
|
||||||
build do
|
|
||||||
factory! << Parfait.object_space.get_factory_for(:Integer)
|
|
||||||
to << factory[:next_object]
|
|
||||||
integer_2! << to[:next_integer]
|
|
||||||
factory[:next_object] << integer_2
|
|
||||||
to[Parfait::Integer.integer_index] << from
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -41,7 +41,9 @@ module Risc
|
|||||||
# Even if it's just this one, sys_exit (later raise)
|
# Even if it's just this one, sys_exit (later raise)
|
||||||
def _method_missing( context )
|
def _method_missing( context )
|
||||||
compiler = compiler_for(:Object,:method_missing ,{})
|
compiler = compiler_for(:Object,:method_missing ,{})
|
||||||
emit_syscall( compiler.builder(compiler.source) , :exit )
|
builder = compiler.builder(compiler.source)
|
||||||
|
builder.prepare_int_return # makes integer_tmp variable as return
|
||||||
|
emit_syscall( builder , :exit )
|
||||||
return compiler
|
return compiler
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -83,6 +85,16 @@ module Risc
|
|||||||
return compiler
|
return compiler
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# the exit function
|
||||||
|
# mainly calls exit_sequence
|
||||||
|
def exit( context )
|
||||||
|
compiler = compiler_for(:Object,:exit ,{})
|
||||||
|
builder = compiler.builder(compiler.source)
|
||||||
|
builder.prepare_int_return # makes integer_tmp variable as return
|
||||||
|
exit_sequence(builder)
|
||||||
|
return compiler
|
||||||
|
end
|
||||||
|
|
||||||
# a sort of inline version of exit method.
|
# a sort of inline version of exit method.
|
||||||
# Used by exit and __init__ (so it doesn't have to call it)
|
# Used by exit and __init__ (so it doesn't have to call it)
|
||||||
# Assumes int return value and extracts the fixnum for process exit code
|
# Assumes int return value and extracts the fixnum for process exit code
|
||||||
@ -95,15 +107,6 @@ module Risc
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# the exit function
|
|
||||||
# mainly calls exit_sequence
|
|
||||||
def exit( context )
|
|
||||||
compiler = compiler_for(:Object,:exit ,{})
|
|
||||||
builder = compiler.builder(compiler.source)
|
|
||||||
exit_sequence(builder)
|
|
||||||
return compiler
|
|
||||||
end
|
|
||||||
|
|
||||||
# emit the syscall with given name
|
# emit the syscall with given name
|
||||||
# there is a Syscall instruction, but the message has to be saved and restored
|
# there is a Syscall instruction, but the message has to be saved and restored
|
||||||
def emit_syscall( builder , name )
|
def emit_syscall( builder , name )
|
||||||
@ -128,12 +131,10 @@ module Risc
|
|||||||
# the int gets retured, ie is the return_value of the message
|
# the int gets retured, ie is the return_value of the message
|
||||||
def restore_message(builder)
|
def restore_message(builder)
|
||||||
r8 = RegisterValue.new( :r8 , :Message)
|
r8 = RegisterValue.new( :r8 , :Message)
|
||||||
int = builder.compiler.use_reg(:Integer)
|
|
||||||
builder.build do
|
builder.build do
|
||||||
integer_reg! << message
|
integer_reg! << message
|
||||||
message << r8
|
message << r8
|
||||||
add_new_int( "_restore_message", integer_reg , int )
|
integer_tmp[Parfait::Integer.integer_index] << integer_reg
|
||||||
message[:return_value] << int
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ module Risc
|
|||||||
def putstring( context)
|
def putstring( context)
|
||||||
compiler = compiler_for(:Word , :putstring ,{})
|
compiler = compiler_for(:Word , :putstring ,{})
|
||||||
builder = compiler.builder(compiler.source)
|
builder = compiler.builder(compiler.source)
|
||||||
|
builder.prepare_int_return # makes integer_tmp variable as return
|
||||||
builder.build do
|
builder.build do
|
||||||
word! << message[:receiver]
|
word! << message[:receiver]
|
||||||
integer! << word[Parfait::Word.get_length_index]
|
integer! << word[Parfait::Word.get_length_index]
|
||||||
|
Loading…
Reference in New Issue
Block a user