working on registers, awip (a work in progress)

This commit is contained in:
Torsten Ruger
2014-05-25 08:43:07 +03:00
parent 1e326e00b9
commit 6ac92cac3a
9 changed files with 80 additions and 40 deletions

View File

@ -10,6 +10,10 @@ require_relative "constants"
module Arm
class ArmMachine < Vm::RegisterMachine
def integer_equals block , left , right
block << cmp( left , right )
Vm::BranchCondition.new :eq
end
def integer_less_or_equal block , left , right
block << cmp( left , right )
Vm::BranchCondition.new :le

View File

@ -12,6 +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 == from.register
end
# arm intrucions are pretty sensible, and always 4 bytes (thumb not supported)

View File

@ -35,12 +35,21 @@ module Ast
context.function = function
into = function.body
last_compiled = nil
body.each do |b|
compiled = b.compile(context , into)
function.return_type = compiled
puts "compiled in function #{compiled.inspect}"
raise "alarm #{compiled} \n #{b}" unless compiled.is_a? Vm::Word
last_compiled = b.compile(context , into)
puts "compiled in function #{last_compiled.inspect}"
raise "alarm #{last_compiled} \n #{b}" unless last_compiled.is_a? Vm::Word
end
return_reg = Vm::Integer.new(0)
if last_compiled.is_a?(Vm::IntegerConstant) or last_compiled.is_a?(Vm::StringConstant)
return_reg.load into , last_compiled if last_compiled.register != return_reg.register
else
return_reg.move( into, last_compiled ) if last_compiled.register != return_reg.register
end
function.set_return return_reg
context.locals = parent_locals
context.function = parent_function
function

View File

@ -23,7 +23,7 @@ module Ast
raise "Can only assign variables, not #{left}" unless left.is_a?(NameExpression)
l_val = context.locals[left.name]
if( l_val ) #variable existed, move data there
l_val = l_val.move( into , r_val)
l_val = l_val.move( into , r_val) if r_val.is_a?(Vm::Value) and l_val.register != r_val.register
else
l_val = context.function.new_local.move( into , r_val )
end
@ -39,10 +39,11 @@ module Ast
code = l_val.greater_than into , r_val
when "<"
code = l_val.less_than into , r_val
when "=="
code = l_val.equals into , r_val
when "+"
res = context.function.new_local
into.res = l_val + r_val
# code = res.plus into , l_val , r_val
code = res
when "-"
res = context.function.new_local

View File

@ -28,7 +28,7 @@ module Core
block = function.body
# should be another level of indirection, ie write(io,str)
ret = Vm::RegisterMachine.instance.write_stdout(block)
function.return_type = ret
function.set_return ret
function
end

View File

@ -39,23 +39,25 @@ module Vm
@args[i] = arg.new(i)
end
end
@return_type = return_type || Vm::Integer
if @return_type.is_a?(Value)
raise "return in non std register #{@return_type.inspect}" unless 0 == @return_type.register
else
@return_type = @return_type.new(0)
end
@exit = Core::Kernel::function_exit( Vm::Block.new("#{name}_exit" , self) , name )
@return = Block.new("#{name}_return", self , @exit)
@body = Block.new("#{name}_body", self , @return)
@entry = Core::Kernel::function_entry( Vm::Block.new("#{name}_entry" , self , @body) ,name )
@locals = []
@blocks = []
set_return return_type
@exit = Core::Kernel::function_exit( Vm::Block.new("#{name}_exit" , self) , name )
@return = Block.new("#{name}_return", self , @exit)
@body = Block.new("#{name}_body", self , @return)
@entry = Core::Kernel::function_entry( Vm::Block.new("#{name}_entry" , self , @body) ,name )
@locals = []
@blocks = []
end
attr_reader :args , :entry , :exit , :body , :name
attr_accessor :return_type
attr_reader :args , :entry , :exit , :body , :name , :return_type
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 0 == @return_type.register
else
@return_type = @return_type.new(0)
end
end
def arity
@args.length
end
@ -69,11 +71,14 @@ module Vm
def save_locals context , into
save = args.collect{|a| a.register } + @locals.collect{|l| l.register}
save.delete_at(0)
into.push save
end
def restore_locals context , into
#TODO assumes allocation in order, as the pop must be get regs in ascending order (also push)
restore = args.collect{|a| a.register } + @locals.collect{|l| l.register}
restore.delete_at(0)
into.pop restore
end

View File

@ -40,6 +40,8 @@ module Vm
:le
when :lt
:ge
when :eq
:ne
else
raise "no implemented #{@operator}"
end
@ -98,6 +100,9 @@ module Vm
def greater_than block , right
RegisterMachine.instance.integer_greater_than block , self , right
end
def equals block , right
RegisterMachine.instance.integer_equals block , self , right
end
def less_than block , right
RegisterMachine.instance.integer_less_than block , self , right
end