keep track of used and assigned registers for each block
This commit is contained in:
parent
fbcfa844de
commit
b66c4157d5
@ -106,7 +106,7 @@ module Arm
|
||||
end
|
||||
|
||||
def syscall block , num
|
||||
sys_and_ret = Vm::Integer.new(7)
|
||||
sys_and_ret = Vm::Integer.new( Vm::Function::RETURN_REG )
|
||||
block << mov( sys_and_ret , num )
|
||||
block << swi( 0 )
|
||||
#small todo, is this actually correct for all (that they return int)
|
||||
|
@ -27,13 +27,18 @@ module Vm
|
||||
@next = next_block
|
||||
@codes = []
|
||||
@insert_at = self
|
||||
# keeping track of register usage, left (assigns) or right (uses)
|
||||
@assigns = []
|
||||
@uses = []
|
||||
end
|
||||
|
||||
attr_reader :name , :next , :codes , :function
|
||||
attr_reader :name , :next , :codes , :function , :assigns , :uses
|
||||
|
||||
def add_code(kode)
|
||||
raise "alarm #{kode}" if kode.is_a? Word
|
||||
raise "alarm #{kode.class} #{kode}" unless kode.is_a? Code
|
||||
@assigns += kode.assigns
|
||||
@uses += kode.uses
|
||||
@insert_at.codes << kode
|
||||
self
|
||||
end
|
||||
|
@ -27,7 +27,23 @@ module Vm
|
||||
def opcode
|
||||
@attributes[:opcode]
|
||||
end
|
||||
|
||||
|
||||
# returns an array of registers (RegisterUses) that this instruction uses.
|
||||
# ie for r1 = r2 + r3
|
||||
# which in assembler is add r1 , r2 , r3
|
||||
# it would return [r2,r3]
|
||||
# for pushes the list may be longer, whereas for a jump empty
|
||||
def uses
|
||||
raise "abstract called for #{self.class}"
|
||||
end
|
||||
# returns an array of registers (RegisterUses) that this instruction assigns to.
|
||||
# ie for r1 = r2 + r3
|
||||
# which in assembler is add r1 , r2 , r3
|
||||
# it would return [r1]
|
||||
# for most instruction this is one, but comparisons and jumps 0 , and pop's as long as 16
|
||||
def assigns
|
||||
raise "abstract called for #{self.class}"
|
||||
end
|
||||
def method_missing name , *args , &block
|
||||
return super unless (args.length <= 1) or block_given?
|
||||
set , attribute = name.to_s.split("set_")
|
||||
@ -46,6 +62,21 @@ module Vm
|
||||
@first = first
|
||||
super(options)
|
||||
end
|
||||
def is_push?
|
||||
opcode == :push
|
||||
end
|
||||
def is_pop?
|
||||
!is_push?
|
||||
end
|
||||
def uses
|
||||
is_push? ? regs : []
|
||||
end
|
||||
def assigns
|
||||
is_pop? ? regs : []
|
||||
end
|
||||
def regs
|
||||
@first
|
||||
end
|
||||
end
|
||||
class MemoryInstruction < Instruction
|
||||
def initialize result , left , right = nil , options = {}
|
||||
@ -54,6 +85,14 @@ module Vm
|
||||
@right = right
|
||||
super(options)
|
||||
end
|
||||
def uses
|
||||
ret = [@left.used_register ]
|
||||
ret << @right.used_register unless @right.nil?
|
||||
ret
|
||||
end
|
||||
def assigns
|
||||
[@result.used_register]
|
||||
end
|
||||
end
|
||||
class LogicInstruction < Instruction
|
||||
# result = left op right
|
||||
@ -64,30 +103,47 @@ module Vm
|
||||
def initialize result , left , right , options = {}
|
||||
@result = result
|
||||
@left = left
|
||||
@right = right
|
||||
@right = right.is_a?(Fixnum) ? IntegerConstant.new(right) : right
|
||||
super(options)
|
||||
end
|
||||
end
|
||||
class MathInstruction < Instruction
|
||||
def initialize first , options = {}
|
||||
@first = first
|
||||
super(options)
|
||||
def uses
|
||||
ret = []
|
||||
ret << @left.used_register if @left and not @left.is_a? Constant
|
||||
ret << @right.used_register if @right and not @right.is_a?(Constant)
|
||||
ret
|
||||
end
|
||||
def assigns
|
||||
[@result.used_register]
|
||||
end
|
||||
end
|
||||
class CompareInstruction < Instruction
|
||||
def initialize left , right , options = {}
|
||||
@left = left
|
||||
@right = right
|
||||
@right = right.is_a?(Fixnum) ? IntegerConstant.new(right) : right
|
||||
super(options)
|
||||
end
|
||||
def uses
|
||||
ret = [@left.used_register ]
|
||||
ret << @right.used_register unless @right.is_a? Constant
|
||||
ret
|
||||
end
|
||||
def assigns
|
||||
[]
|
||||
end
|
||||
end
|
||||
class MoveInstruction < Instruction
|
||||
def initialize to , from , options = {}
|
||||
@to = to
|
||||
@from = from
|
||||
@from = from.is_a?(Fixnum) ? IntegerConstant.new(from) : from
|
||||
raise "move must have from set #{inspect}" unless from
|
||||
super(options)
|
||||
end
|
||||
def uses
|
||||
@from.is_a?(Constant) ? [] : [@from.used_register]
|
||||
end
|
||||
def assigns
|
||||
[@to.used_register]
|
||||
end
|
||||
end
|
||||
class CallInstruction < Instruction
|
||||
def initialize first , options = {}
|
||||
@ -103,5 +159,11 @@ module Vm
|
||||
@attributes[:opcode] = :call
|
||||
end
|
||||
end
|
||||
def uses
|
||||
[]
|
||||
end
|
||||
def assigns
|
||||
[]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -11,7 +11,6 @@ def fibonaccir( n )
|
||||
else
|
||||
a = fibonaccir( n - 1 )
|
||||
b = fibonaccir( n - 2 )
|
||||
c = fibonaccir( n - 3 )
|
||||
return a + b
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user