fix passes, add noop reduction, remove the wretched value operators

This commit is contained in:
Torsten Ruger 2014-06-11 21:36:22 +03:00
parent 4e6319b753
commit b125a7c5c7
6 changed files with 42 additions and 26 deletions

View File

@ -128,7 +128,6 @@ module Arm
sys_and_ret = Vm::Integer.new( Vm::RegisterMachine.instance.return_register )
block.do_add mov( sys_and_ret , num )
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
sys_and_ret
end

View File

@ -39,7 +39,7 @@ module Vm
#main gets executed between entry and exit
@exit = RegisterMachine.instance.main_exit @context
boot_classes
@passes = [ MoveMoveReduction.new, LogicMoveReduction.new, SaveLocals.new ]
@passes = [ MoveMoveReduction.new , LogicMoveReduction.new, NoopReduction.new, SaveLocals.new ]
end
attr_reader :context , :main , :classes , :entry , :exit
@ -55,6 +55,10 @@ module Vm
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
# 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
@ -69,12 +73,16 @@ module Vm
obj.add_function Boot::String.send(f , @context)
end
end
# Objects are data and get assembled after functions
def add_object o
return if @objects.include? o
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)
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
raise "uups #{name}.#{name.class}" unless name.is_a? Symbol
c = @classes[name]
@ -85,15 +93,15 @@ module Vm
c
end
# linking entry , main , exit , classes , objects
# linking entry , exit , main , classes , objects
def link_at( start , context)
super
@entry.link_at( start , context )
start += @entry.length
@main.link_at( start , context )
start += @main.length
@exit.link_at( start , context)
start += @exit.length
@main.link_at( start , context )
start += @main.length
@classes.values.each do |clazz|
clazz.link_at(start , context)
start += clazz.length
@ -108,8 +116,8 @@ module Vm
def assemble( io )
link_at( @position , nil) #second link in case of forward declarations
@entry.assemble( io )
@main.assemble( io )
@exit.assemble( io )
@main.assemble( io )
@classes.values.each do |clazz|
clazz.assemble(io)
end
@ -118,10 +126,5 @@ module Vm
end
io
end
def main= code
@main = code
end
end
end

View File

@ -130,7 +130,7 @@ module Vm
# This does _not_ change the insertion point, that has do be done with insert_at(block)
def new_block 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
return new_b
end

View File

@ -10,7 +10,7 @@ module Vm
def run block
block.codes.dup.each_with_index do |kode , index|
next unless kode.is_a? StackInstruction
if kode.regiters.empty?
if kode.registers.empty?
block.codes.delete(kode)
puts "deleted stack instruction in #{b.name}"
end
@ -31,6 +31,8 @@ module Vm
next unless kode.is_a? LogicInstruction
next unless n.is_a? MoveInstruction
if kode.result == n.from
puts "KODE #{kode.result.inspect}"
puts "N #{n.from.inspect}"
kode.result = n.to
block.codes.delete(n)
end
@ -56,6 +58,19 @@ module Vm
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
# 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
@ -64,11 +79,9 @@ module Vm
# Or sometimes just remove the push/pops, when no locals needed saving
class SaveLocals
def run block
unless block.function
puts "No function for #{block.name}"
end
push = block.call_block?
return unless push
return unless block.function
locals = block.function.locals_at block
pop = block.next.codes.first
if(locals.empty?)

View File

@ -126,15 +126,15 @@ module Vm
def less_than block , right
RegisterMachine.instance.integer_less_than block , self , right
end
def == other
code = class_for(CompareInstruction).new(self , other , opcode: :cmp)
end
def + other
class_for(LogicInstruction).new(nil , self , other , opcode: :add)
end
def - other
class_for(LogicInstruction).new(nil , self , other , opcode: :sub )#, update_status: 1 )
end
# def == other
# code = class_for(CompareInstruction).new(self , other , opcode: :cmp)
# end
# def + other
# class_for(LogicInstruction).new(nil , self , other , opcode: :add)
# end
# def - other
# class_for(LogicInstruction).new(nil , self , other , opcode: :sub )#, update_status: 1 )
# end
def at_index block , left , right
RegisterMachine.instance.integer_at_index block , self , left , right
end

View File

@ -32,6 +32,7 @@ HERE
def test_kernel_fibo
int = Vm::Integer.new(1)
fibo = @object_space.get_or_create_class(:Object).get_or_create_function(:fibo)
#HACk this with send
main = @object_space.main
main.mov int , 10
ret = main.call( fibo )