fix passes, add noop reduction, remove the wretched value operators
This commit is contained in:
parent
4e6319b753
commit
b125a7c5c7
@ -128,7 +128,6 @@ module Arm
|
|||||||
sys_and_ret = Vm::Integer.new( Vm::RegisterMachine.instance.return_register )
|
sys_and_ret = Vm::Integer.new( Vm::RegisterMachine.instance.return_register )
|
||||||
block.do_add mov( sys_and_ret , num )
|
block.do_add mov( sys_and_ret , num )
|
||||||
block.do_add swi( 0 )
|
block.do_add swi( 0 )
|
||||||
block.do_add mov( sys_and_ret , return_register ) # syscall returns in r0, more to our return
|
|
||||||
#todo should write type into r0 according to syscall
|
#todo should write type into r0 according to syscall
|
||||||
sys_and_ret
|
sys_and_ret
|
||||||
end
|
end
|
||||||
|
@ -39,7 +39,7 @@ module Vm
|
|||||||
#main gets executed between entry and exit
|
#main gets executed between entry and exit
|
||||||
@exit = RegisterMachine.instance.main_exit @context
|
@exit = RegisterMachine.instance.main_exit @context
|
||||||
boot_classes
|
boot_classes
|
||||||
@passes = [ MoveMoveReduction.new, LogicMoveReduction.new, SaveLocals.new ]
|
@passes = [ MoveMoveReduction.new , LogicMoveReduction.new, NoopReduction.new, SaveLocals.new ]
|
||||||
end
|
end
|
||||||
attr_reader :context , :main , :classes , :entry , :exit
|
attr_reader :context , :main , :classes , :entry , :exit
|
||||||
|
|
||||||
@ -55,6 +55,10 @@ module Vm
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# boot the classes, ie create a minimal set of classes with a minimal set of functions
|
||||||
|
# minimal means only that which can not be coded in ruby
|
||||||
|
# Functions are grabbed from respective modules by sending the sunction name. This should return the
|
||||||
|
# implementation of the function (ie a function object), not actually try to implement it (as that's impossible in ruby)
|
||||||
def boot_classes
|
def boot_classes
|
||||||
# very fiddly chicken 'n egg problem. Functions need to be in the right order, and in fact we have to define some
|
# very fiddly chicken 'n egg problem. Functions need to be in the right order, and in fact we have to define some
|
||||||
# dummies, just for the other to compile
|
# dummies, just for the other to compile
|
||||||
@ -69,12 +73,16 @@ module Vm
|
|||||||
obj.add_function Boot::String.send(f , @context)
|
obj.add_function Boot::String.send(f , @context)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Objects are data and get assembled after functions
|
||||||
def add_object o
|
def add_object o
|
||||||
return if @objects.include? o
|
return if @objects.include? o
|
||||||
raise "must be derived from Code #{o.inspect}" unless o.is_a? Code
|
raise "must be derived from Code #{o.inspect}" unless o.is_a? Code
|
||||||
@objects << o # TODO check type , no basic values allowed (must be wrapped)
|
@objects << o # TODO check type , no basic values allowed (must be wrapped)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# this is the way to instantiate classes (not BootBlass.new)
|
||||||
|
# so we get and keep exactly one per name
|
||||||
def get_or_create_class name
|
def get_or_create_class name
|
||||||
raise "uups #{name}.#{name.class}" unless name.is_a? Symbol
|
raise "uups #{name}.#{name.class}" unless name.is_a? Symbol
|
||||||
c = @classes[name]
|
c = @classes[name]
|
||||||
@ -85,15 +93,15 @@ module Vm
|
|||||||
c
|
c
|
||||||
end
|
end
|
||||||
|
|
||||||
# linking entry , main , exit , classes , objects
|
# linking entry , exit , main , classes , objects
|
||||||
def link_at( start , context)
|
def link_at( start , context)
|
||||||
super
|
super
|
||||||
@entry.link_at( start , context )
|
@entry.link_at( start , context )
|
||||||
start += @entry.length
|
start += @entry.length
|
||||||
@main.link_at( start , context )
|
|
||||||
start += @main.length
|
|
||||||
@exit.link_at( start , context)
|
@exit.link_at( start , context)
|
||||||
start += @exit.length
|
start += @exit.length
|
||||||
|
@main.link_at( start , context )
|
||||||
|
start += @main.length
|
||||||
@classes.values.each do |clazz|
|
@classes.values.each do |clazz|
|
||||||
clazz.link_at(start , context)
|
clazz.link_at(start , context)
|
||||||
start += clazz.length
|
start += clazz.length
|
||||||
@ -108,8 +116,8 @@ module Vm
|
|||||||
def assemble( io )
|
def assemble( io )
|
||||||
link_at( @position , nil) #second link in case of forward declarations
|
link_at( @position , nil) #second link in case of forward declarations
|
||||||
@entry.assemble( io )
|
@entry.assemble( io )
|
||||||
@main.assemble( io )
|
|
||||||
@exit.assemble( io )
|
@exit.assemble( io )
|
||||||
|
@main.assemble( io )
|
||||||
@classes.values.each do |clazz|
|
@classes.values.each do |clazz|
|
||||||
clazz.assemble(io)
|
clazz.assemble(io)
|
||||||
end
|
end
|
||||||
@ -118,10 +126,5 @@ module Vm
|
|||||||
end
|
end
|
||||||
io
|
io
|
||||||
end
|
end
|
||||||
|
|
||||||
def main= code
|
|
||||||
@main = code
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -130,7 +130,7 @@ module Vm
|
|||||||
# This does _not_ change the insertion point, that has do be done with insert_at(block)
|
# This does _not_ change the insertion point, that has do be done with insert_at(block)
|
||||||
def new_block new_name
|
def new_block new_name
|
||||||
block_name = "#{@insert_at.name}_#{new_name}"
|
block_name = "#{@insert_at.name}_#{new_name}"
|
||||||
new_b = Block.new( block_name , @function , @insert_at.next )
|
new_b = Block.new( block_name , self , @insert_at.next )
|
||||||
@insert_at.set_next new_b
|
@insert_at.set_next new_b
|
||||||
return new_b
|
return new_b
|
||||||
end
|
end
|
||||||
|
@ -10,7 +10,7 @@ module Vm
|
|||||||
def run block
|
def run block
|
||||||
block.codes.dup.each_with_index do |kode , index|
|
block.codes.dup.each_with_index do |kode , index|
|
||||||
next unless kode.is_a? StackInstruction
|
next unless kode.is_a? StackInstruction
|
||||||
if kode.regiters.empty?
|
if kode.registers.empty?
|
||||||
block.codes.delete(kode)
|
block.codes.delete(kode)
|
||||||
puts "deleted stack instruction in #{b.name}"
|
puts "deleted stack instruction in #{b.name}"
|
||||||
end
|
end
|
||||||
@ -31,6 +31,8 @@ module Vm
|
|||||||
next unless kode.is_a? LogicInstruction
|
next unless kode.is_a? LogicInstruction
|
||||||
next unless n.is_a? MoveInstruction
|
next unless n.is_a? MoveInstruction
|
||||||
if kode.result == n.from
|
if kode.result == n.from
|
||||||
|
puts "KODE #{kode.result.inspect}"
|
||||||
|
puts "N #{n.from.inspect}"
|
||||||
kode.result = n.to
|
kode.result = n.to
|
||||||
block.codes.delete(n)
|
block.codes.delete(n)
|
||||||
end
|
end
|
||||||
@ -56,6 +58,19 @@ module Vm
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#As the name says, remove no-ops. Currently mov x , x supported
|
||||||
|
class NoopReduction
|
||||||
|
def run block
|
||||||
|
block.codes.dup.each_with_index do |kode , index|
|
||||||
|
next unless kode.is_a? MoveInstruction
|
||||||
|
if kode.to == kode.from
|
||||||
|
block.codes.delete(kode)
|
||||||
|
puts "deleted noop move in #{block.name}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# We insert push/pops as dummies to fill them later in CallSaving
|
# We insert push/pops as dummies to fill them later in CallSaving
|
||||||
# as we can not know ahead of time which locals wil be live in the code to come
|
# as we can not know ahead of time which locals wil be live in the code to come
|
||||||
# and also we don't want to "guess" later where the push/pops should be
|
# and also we don't want to "guess" later where the push/pops should be
|
||||||
@ -64,11 +79,9 @@ module Vm
|
|||||||
# Or sometimes just remove the push/pops, when no locals needed saving
|
# Or sometimes just remove the push/pops, when no locals needed saving
|
||||||
class SaveLocals
|
class SaveLocals
|
||||||
def run block
|
def run block
|
||||||
unless block.function
|
|
||||||
puts "No function for #{block.name}"
|
|
||||||
end
|
|
||||||
push = block.call_block?
|
push = block.call_block?
|
||||||
return unless push
|
return unless push
|
||||||
|
return unless block.function
|
||||||
locals = block.function.locals_at block
|
locals = block.function.locals_at block
|
||||||
pop = block.next.codes.first
|
pop = block.next.codes.first
|
||||||
if(locals.empty?)
|
if(locals.empty?)
|
||||||
|
@ -126,15 +126,15 @@ module Vm
|
|||||||
def less_than block , right
|
def less_than block , right
|
||||||
RegisterMachine.instance.integer_less_than block , self , right
|
RegisterMachine.instance.integer_less_than block , self , right
|
||||||
end
|
end
|
||||||
def == other
|
# def == other
|
||||||
code = class_for(CompareInstruction).new(self , other , opcode: :cmp)
|
# code = class_for(CompareInstruction).new(self , other , opcode: :cmp)
|
||||||
end
|
# end
|
||||||
def + other
|
# def + other
|
||||||
class_for(LogicInstruction).new(nil , self , other , opcode: :add)
|
# class_for(LogicInstruction).new(nil , self , other , opcode: :add)
|
||||||
end
|
# end
|
||||||
def - other
|
# def - other
|
||||||
class_for(LogicInstruction).new(nil , self , other , opcode: :sub )#, update_status: 1 )
|
# class_for(LogicInstruction).new(nil , self , other , opcode: :sub )#, update_status: 1 )
|
||||||
end
|
# end
|
||||||
def at_index block , left , right
|
def at_index block , left , right
|
||||||
RegisterMachine.instance.integer_at_index block , self , left , right
|
RegisterMachine.instance.integer_at_index block , self , left , right
|
||||||
end
|
end
|
||||||
|
@ -32,6 +32,7 @@ HERE
|
|||||||
def test_kernel_fibo
|
def test_kernel_fibo
|
||||||
int = Vm::Integer.new(1)
|
int = Vm::Integer.new(1)
|
||||||
fibo = @object_space.get_or_create_class(:Object).get_or_create_function(:fibo)
|
fibo = @object_space.get_or_create_class(:Object).get_or_create_function(:fibo)
|
||||||
|
#HACk this with send
|
||||||
main = @object_space.main
|
main = @object_space.main
|
||||||
main.mov int , 10
|
main.mov int , 10
|
||||||
ret = main.call( fibo )
|
ret = main.call( fibo )
|
||||||
|
Loading…
x
Reference in New Issue
Block a user