From 7ca3207b3e75ad418c7f2575769a46dbc9ed9019 Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Tue, 10 Jun 2014 13:29:01 +0300 Subject: [PATCH] moved registers to machine, changed return to 0 (from 7) and erased all integer references to registers --- lib/arm/arm_machine.rb | 20 +++++++++++++++++--- lib/arm/move_instruction.rb | 8 ++++---- lib/ast/call_site_expression.rb | 2 +- lib/ast/function_expression.rb | 7 ++++--- lib/ast/return_expression.rb | 4 ++-- lib/vm/function.rb | 17 +++++++---------- lib/vm/values.rb | 16 ++++++++++------ 7 files changed, 45 insertions(+), 29 deletions(-) diff --git a/lib/arm/arm_machine.rb b/lib/arm/arm_machine.rb index b15f820c..f9d7e8bb 100644 --- a/lib/arm/arm_machine.rb +++ b/lib/arm/arm_machine.rb @@ -9,6 +9,20 @@ require_relative "constants" module Arm class ArmMachine < Vm::RegisterMachine + # The constants are here for readablility, the code uses access functions below + RETURN_REG = :r0 + TYPE_REG = :r1 + RECEIVER_REG = :r2 + + def return_register + RETURN_REG + end + def type_register + TYPE_REG + end + def receiver_register + RECEIVER_REG + end def integer_equals block , left , right block << cmp( left , right ) @@ -106,11 +120,11 @@ module Arm end def syscall block , num - sys_and_ret = Vm::Integer.new( Vm::Function::RETURN_REG ) + #small todo, is this actually correct for all (that they return int) + sys_and_ret = Vm::Integer.new( Vm::RegisterMachine.instance.return_register ) block << mov( sys_and_ret , num ) block << swi( 0 ) - #small todo, is this actually correct for all (that they return int) - block << mov( sys_and_ret , :r0 ) # syscall returns in r0, more to our return + block << mov( sys_and_ret , return_register ) # syscall returns in r0, more to our return #todo should write type into r0 according to syscall sys_and_ret end diff --git a/lib/arm/move_instruction.rb b/lib/arm/move_instruction.rb index 28677448..a31531f2 100644 --- a/lib/arm/move_instruction.rb +++ b/lib/arm/move_instruction.rb @@ -12,10 +12,10 @@ module Arm @immediate = 0 @rn = :r0 # register zero = zero bit pattern - raise inspect if to.is_a?(Vm::Value) and - from.is_a?(Vm::Value) and - !@attributes[:shift_lsr] and - to.register_symbol == from.register_symbol +# NO-OP -> pass raise inspect if to.is_a?(Vm::Value) and + # from.is_a?(Vm::Value) and + # !@attributes[:shift_lsr] and + # to.register_symbol == from.register_symbol raise "uups " if @to.register_symbol == :rr1 end diff --git a/lib/ast/call_site_expression.rb b/lib/ast/call_site_expression.rb index 19cb3a8a..9c2f5683 100644 --- a/lib/ast/call_site_expression.rb +++ b/lib/ast/call_site_expression.rb @@ -9,7 +9,7 @@ module Ast if receiver.is_a?(NameExpression) and (receiver.name == :self) function = context.current_class.get_or_create_function(name) - value_receiver = Vm::Integer.new(Vm::Function::RECEIVER_REG) + value_receiver = Vm::Integer.new(Vm::RegisterMachine.instance.receiver_register) else value_receiver = receiver.compile(context , into) function = context.current_class.get_or_create_function(name) diff --git a/lib/ast/function_expression.rb b/lib/ast/function_expression.rb index 837892f1..2d715bf0 100644 --- a/lib/ast/function_expression.rb +++ b/lib/ast/function_expression.rb @@ -7,12 +7,13 @@ module Ast locals = {} params.each_with_index do |param , index| arg = param.name - arg_value = Vm::Integer.new(index+2) + register = Vm::RegisterUse.new(Vm::RegisterMachine.instance.receiver_register).next_reg_use(index + 1) + arg_value = Vm::Integer.new(register) locals[arg] = arg_value args << arg_value end # class depends on receiver - me = Vm::Integer.new( Vm::Function::RECEIVER_REG ) + me = Vm::Integer.new( Vm::RegisterMachine.instance.receiver_register ) if receiver.nil? clazz = context.current_class else @@ -36,7 +37,7 @@ module Ast raise "alarm #{last_compiled} \n #{b}" unless last_compiled.is_a? Vm::Word end - return_reg = Vm::Integer.new(7) + return_reg = Vm::Integer.new(Vm::RegisterMachine.instance.return_register) if last_compiled.is_a?(Vm::IntegerConstant) or last_compiled.is_a?(Vm::ObjectConstant) return_reg.load into , last_compiled if last_compiled.register_symbol != return_reg.register_symbol else diff --git a/lib/ast/return_expression.rb b/lib/ast/return_expression.rb index 8c4afbff..5d6f7781 100644 --- a/lib/ast/return_expression.rb +++ b/lib/ast/return_expression.rb @@ -2,11 +2,11 @@ module Ast class ReturnExpression < Expression # attr_reader :expression def compile context , into - puts "compiling return expression #{expression}, now return in 7" + puts "compiling return expression #{expression}, now return in return_regsiter" expression_value = expression.compile(context , into) # copied from function expression: TODO make function - return_reg = Vm::Integer.new(7) + return_reg = Vm::Integer.new(Vm::RegisterMachine.instance.return_register) if expression_value.is_a?(Vm::IntegerConstant) or expression_value.is_a?(Vm::ObjectConstant) return_reg.load into , expression_value else diff --git a/lib/vm/function.rb b/lib/vm/function.rb index d4c835d2..ac90d488 100644 --- a/lib/vm/function.rb +++ b/lib/vm/function.rb @@ -27,27 +27,24 @@ module Vm class Function < Code - TYPE_REG = :r0 - RECEIVER_REG = :r1 - RETURN_REG = :r7 - def initialize(name , receiver = Vm::Integer , args = [] , return_type = Vm::Integer) super() @name = name.to_sym if receiver.is_a?(Value) @receiver = receiver - raise "arg in non std register #{arg.inspect}" unless RECEIVER_REG == receiver.register_symbol + raise "arg in non std register #{receiver.inspect}" unless RegisterMachine.instance.receiver_register == receiver.register_symbol else - @receiver = receiver.new(RECEIVER_REG) + @receiver = receiver.new(RegisterMachine.instance.receiver_register) end @args = Array.new(args.length) args.each_with_index do |arg , i| + shouldda = RegisterUse.new(RegisterMachine.instance.receiver_register).next_reg_use(i + 1) if arg.is_a?(Value) @args[i] = arg - raise "arg #{i}in non std register #{arg.inspect}" unless RECEIVER_REG == arg.used_register.next_reg(-1-i) + raise "arg #{i} in non std register #{arg.used_register}, expecting #{shouldda}" unless shouldda == arg.used_register else - @args[i] = arg.new(RegisterUse.new(RECEIVER_REG).next_reg(i + 1)) + @args[i] = arg.new(shouldda) end end set_return return_type @@ -64,9 +61,9 @@ module Vm def set_return type_or_value @return_type = type_or_value || Vm::Integer if @return_type.is_a?(Value) - raise "return in non std register #{@return_type.inspect}" unless RETURN_REG == @return_type.register_symbol + raise "return in non std register #{@return_type.inspect}" unless RegisterMachine.instance.return_register == @return_type.register_symbol else - @return_type = @return_type.new(RETURN_REG) + @return_type = @return_type.new(RegisterMachine.instance.return_register) end end def arity diff --git a/lib/vm/values.rb b/lib/vm/values.rb index 0ac3f998..9c3e5336 100644 --- a/lib/vm/values.rb +++ b/lib/vm/values.rb @@ -63,13 +63,17 @@ module Vm @symbol = r end - #helper methods to calculate with register symbols - def next_reg by = 1 - int = @symbol[1,3].to_i - "r#{int + by}".to_sym + def == other + return false if other.nil? + return false if other.class != RegisterUse + symbol == other.symbol end + + #helper method to calculate with register symbols def next_reg_use by = 1 - RegisterUse.new( next_reg(by) ) + int = @symbol[1,3].to_i + sym = "r#{int + by}".to_sym + RegisterUse.new( sym ) end end @@ -152,7 +156,7 @@ module Vm block.mov( self , right ) #move the value elsif right.is_a? StringConstant block.add( self , right , nil) #move the address, by "adding" to pc, ie pc relative - block.mov( Integer.new(self.used_register.next_reg) , right.length ) #and the length HACK TODO + block.mov( Integer.new(self.used_register.next_reg_use) , right.length ) #and the length HACK TODO elsif right.is_a?(BootClass) or right.is_a?(MetaClass) block.add( self , right , nil) #move the address, by "adding" to pc, ie pc relative else