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 )
|
||||
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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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?)
|
||||
|
@ -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
|
||||
|
@ -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 )
|
||||
|
Loading…
Reference in New Issue
Block a user