diff --git a/lib/arm/arm_machine.rb b/lib/arm/arm_machine.rb index fd76f532..7daa20df 100644 --- a/lib/arm/arm_machine.rb +++ b/lib/arm/arm_machine.rb @@ -31,15 +31,14 @@ module Arm end def word_load value , reg - e = Vm::Block.new("load_#{value}") - e.add_code( MoveInstruction.new( :left => reg , :right => value ) ) + mov( :left => reg , :right => value ) end def function_call call raise "Not FunctionCall #{call.inspect}" unless call.is_a? Vm::FunctionCall bl( :left => call.function ) end - def main_entry + def main_start entry = Vm::Block.new("main_entry") entry.add_code mov( :left => :fp , :right => 0 ) end @@ -47,6 +46,14 @@ module Arm entry = Vm::Block.new("main_exit") entry.add_code syscall(0) end + def function_entry f_name + entry = Vm::Block.new("#{f_name}_entry") + entry.add_code push( :left => :lr ) + end + def function_exit f_name + entry = Vm::Block.new("#{f_name}_exit") + entry.add_code pop( :left => :pc ) + end def syscall num [mov( :left => :r7 , :right => num ) , swi( :left => 0 )] end diff --git a/lib/arm/logic_instruction.rb b/lib/arm/logic_instruction.rb index b6c0884d..a815889f 100644 --- a/lib/arm/logic_instruction.rb +++ b/lib/arm/logic_instruction.rb @@ -71,7 +71,6 @@ module Arm def assemble(io) build instuction_class = 0b00 # OPC_DATA_PROCESSING - puts inspect val = @operand.is_a?(Symbol) ? reg_code(@operand) : @operand val |= (reg_code(@rd) << 12) val |= (reg_code(@rn) << 12+4) diff --git a/lib/arm/stack_instruction.rb b/lib/arm/stack_instruction.rb index 2441a85e..e2730c01 100644 --- a/lib/arm/stack_instruction.rb +++ b/lib/arm/stack_instruction.rb @@ -19,7 +19,7 @@ module Arm @operand = 0 @update_status_flag= 0 - @rn = reg "r0" # register zero = zero bit pattern + @rn = :r0 # register zero = zero bit pattern # downward growing, decrement before memory access # official ARM style stack as used by gas @write_base = 1 @@ -40,10 +40,10 @@ module Arm build instuction_class = 0b10 # OPC_STACK cond = @condition_code.is_a?(Symbol) ? COND_CODES[@condition_code] : @condition_code - rn = reg "sp" # sp register + @rn = :sp # sp register #assemble of old - val = operand - val |= (rn.bits << 16) + val = @operand + val |= (reg_code(@rn) << 16) val |= (is_pop << 16+4) #20 val |= (write_base << 16+4+ 1) val |= (update_status_flag << 16+4+ 1+1) @@ -57,13 +57,14 @@ module Arm private # Build representation for source value def build - if (args.is_a?(Array)) + if (@args.is_a?(Array)) @operand = 0 - args.each do |reg | - @operand |= (1 << reg.bits) + @args.each do |reg | + next unless reg + @operand |= (1 << reg_code(reg)) end else - raise "invalid operand argument #{args.inspect}" + raise "invalid operand argument #{@args.inspect} #{inspect}" end end end diff --git a/lib/vm/function.rb b/lib/vm/function.rb index 506ae359..dbf78919 100644 --- a/lib/vm/function.rb +++ b/lib/vm/function.rb @@ -15,8 +15,8 @@ module Vm def initialize(name , args = []) super(name) @args = args - @entry = Block.new("entry_#{name}") - @exit = Block.new("exit_#{name}") + @entry = Kernel::function_entry( name ) + @exit = Kernel::function_exit( name ) end attr_reader :args , :entry , :exit diff --git a/lib/vm/kernel.rb b/lib/vm/kernel.rb index 30587e74..4c3e9ad9 100644 --- a/lib/vm/kernel.rb +++ b/lib/vm/kernel.rb @@ -1,16 +1,29 @@ module Vm - module Kernel - def self.start - #TODO extract args into array of strings - Machine.instance.main_entry - end - def self.exit - # Machine.exit mov r7 , 0 + swi 0 - Machine.instance.main_exit - end - def self.puts string - # should unwrap from string to char* - Machine.instance.puts string + class Kernel + + #there are no Kernel instances, only class methods. + # We use this module syntax to avoid the (ugly) self. + module ClassMethods + def main_start + #TODO extract args into array of strings + Machine.instance.main_start + end + def main_exit + # Machine.exit mov r7 , 0 + swi 0 + Machine.instance.main_exit + end + def function_entry f_name + Machine.instance.function_entry f_name + end + def function_exit f_name + Machine.instance.function_exit f_name + end + def self.puts string + # should unwrap from string to char* + Machine.instance.puts string + end end + + extend ClassMethods end end \ No newline at end of file diff --git a/lib/vm/program.rb b/lib/vm/program.rb index 46cb01d9..32907173 100644 --- a/lib/vm/program.rb +++ b/lib/vm/program.rb @@ -28,10 +28,10 @@ module Vm @objects = [] # global functions @functions = [] - @entry = Vm::Kernel::start + @entry = Vm::Kernel::main_start #main gets executed between entry and exit @main = nil - @exit = Vm::Kernel::exit + @exit = Vm::Kernel::main_exit end attr_reader :context , :main , :functions