function now returns locals, not free registers
This commit is contained in:
parent
e1f889fd10
commit
2df2dcc528
@ -82,7 +82,7 @@ module Arm
|
||||
add( number , number , number , shift_lsr: 8)
|
||||
add( number , number , number , shift_lsr: 16)
|
||||
mov( number , number , shift_lsr: 3)
|
||||
tmp = Vm::Integer.new( remainder.register + 1)
|
||||
tmp = function.new_local
|
||||
add( tmp , number , number , shift_lsl: 2)
|
||||
sub( remainder , remainder , tmp , shift_lsl: 1 , update_status: 1)
|
||||
add( number , number, 1 , condition_code: :pl )
|
||||
|
@ -25,8 +25,7 @@ module Ast
|
||||
if( l_val ) #variable existed, move data there
|
||||
l_val = l_val.move( into , r_val)
|
||||
else
|
||||
next_register = context.function.next_register
|
||||
l_val = Vm::Integer.new(next_register).load( into , r_val )
|
||||
l_val = context.function.new_local.load( into , r_val )
|
||||
end
|
||||
context.locals[left.name] = l_val
|
||||
return l_val
|
||||
@ -38,12 +37,12 @@ module Ast
|
||||
when ">"
|
||||
code = l_val.less_or_equal into , r_val
|
||||
when "+"
|
||||
res = Vm::Integer.new(context.function.next_register)
|
||||
res = context.function.new_local
|
||||
into.add_code res.is l_val + r_val
|
||||
# code = res.plus into , l_val , r_val
|
||||
code = res
|
||||
when "-"
|
||||
res = Vm::Integer.new(context.function.next_register)
|
||||
res = context.function.new_local
|
||||
code = res.minus into , l_val , r_val
|
||||
else
|
||||
raise "unimplemented operator #{operator} #{self}"
|
||||
|
@ -83,7 +83,7 @@ module Core
|
||||
result = fibo_function.args[0]
|
||||
int = fibo_function.args[1]
|
||||
count = Vm::Integer.new(2)
|
||||
loop_block = Vm::Block.new("loop")
|
||||
loop_block = Vm::Block.new("loop", nil)
|
||||
f1 = Vm::Integer.new(3)
|
||||
f2 = Vm::Integer.new(4)
|
||||
b = fibo_function.body.scope binding
|
||||
|
@ -20,14 +20,15 @@ module Vm
|
||||
|
||||
class Block < Code
|
||||
|
||||
def initialize(name)
|
||||
def initialize(name , function)
|
||||
super()
|
||||
@function = function
|
||||
@name = name.to_sym
|
||||
@next = nil
|
||||
@codes = []
|
||||
end
|
||||
|
||||
attr_reader :name , :next , :codes
|
||||
attr_reader :name , :next , :codes , :function
|
||||
|
||||
def length
|
||||
@codes.inject(0) {| sum , item | sum + item.length}
|
||||
|
@ -37,15 +37,10 @@ module Vm
|
||||
else
|
||||
@return_type = @return_type.new(0)
|
||||
end
|
||||
@entry = Core::Kernel::function_entry( Vm::Block.new("#{name}_entry") ,name )
|
||||
@exit = Core::Kernel::function_exit( Vm::Block.new("#{name}_exit") , name )
|
||||
@body = Block.new("#{name}_body")
|
||||
@reg_count = 0
|
||||
branch_body
|
||||
@entry = Core::Kernel::function_entry( Vm::Block.new("#{name}_entry") ,name )
|
||||
@exit = Core::Kernel::function_exit( Vm::Block.new("#{name}_exit") , name )
|
||||
@body = Block.new("#{name}_body")
|
||||
@reg_count = 0
|
||||
@entry = Core::Kernel::function_entry( Vm::Block.new("#{name}_entry" , self) ,name )
|
||||
@exit = Core::Kernel::function_exit( Vm::Block.new("#{name}_exit", self) , name )
|
||||
@body = Block.new("#{name}_body", self)
|
||||
@locals = []
|
||||
branch_body
|
||||
end
|
||||
attr_reader :args , :entry , :exit , :body , :name
|
||||
@ -55,10 +50,11 @@ module Vm
|
||||
@args.length
|
||||
end
|
||||
|
||||
def next_register
|
||||
next_free = @reg_count
|
||||
@reg_count += 1
|
||||
next_free + args.length
|
||||
def new_local type = Vm::Integer
|
||||
register = args.length + @locals.length
|
||||
l = type.new(register)
|
||||
@locals << l
|
||||
l
|
||||
end
|
||||
|
||||
def link_at address , context
|
||||
|
@ -23,7 +23,7 @@ module Vm
|
||||
# Initialize with a string for cpu. Naming conventions are: for Machine XXX there exists a module XXX
|
||||
# with a XXXMachine in it that derives from Vm::CMachine
|
||||
def initialize machine = nil
|
||||
super("start")
|
||||
super("start" , nil)
|
||||
machine = RbConfig::CONFIG["host_cpu"] unless machine
|
||||
machine = "intel" if machine == "x86_64"
|
||||
machine = machine.capitalize
|
||||
@ -33,10 +33,10 @@ module Vm
|
||||
@objects = []
|
||||
# global functions
|
||||
@functions = []
|
||||
@entry = Core::Kernel::main_start Vm::Block.new("main_entry")
|
||||
@entry = Core::Kernel::main_start Vm::Block.new("main_entry",nil)
|
||||
#main gets executed between entry and exit
|
||||
@main = Block.new("main")
|
||||
@exit = Core::Kernel::main_exit Vm::Block.new("main_exit")
|
||||
@main = Block.new("main",nil)
|
||||
@exit = Core::Kernel::main_exit Vm::Block.new("main_exit",nil)
|
||||
end
|
||||
attr_reader :context , :main , :functions , :entry , :exit
|
||||
|
||||
|
@ -13,7 +13,7 @@ class TestSmallProg < MiniTest::Test
|
||||
end
|
||||
|
||||
def test_loop
|
||||
s = Vm::Block.new("start").scope binding
|
||||
s = Vm::Block.new("start",nil).scope binding
|
||||
m = @program.main.scope binding
|
||||
r0 = Vm::Integer.new(0)
|
||||
m.r0 = 5 #1
|
||||
|
Loading…
Reference in New Issue
Block a user