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