change platform to return register names
not just the number of them also adds protocol to map registers (like message to r0 , or syscalls)
This commit is contained in:
parent
f13e6dcf57
commit
0137056b89
@ -8,17 +8,19 @@ module Risc
|
|||||||
# return the translator instance that traslates risc intructions into
|
# return the translator instance that traslates risc intructions into
|
||||||
# platform specific ones
|
# platform specific ones
|
||||||
def translator
|
def translator
|
||||||
raise "not implemented"
|
raise "not implemented in #{self.class}"
|
||||||
end
|
end
|
||||||
|
|
||||||
# return an integer where the binary is loaded
|
# return an integer where the binary is loaded
|
||||||
def loaded_at
|
def loaded_at
|
||||||
raise "not implemented"
|
raise "not implemented in #{self.class}"
|
||||||
end
|
end
|
||||||
|
|
||||||
# return the number of registers the platform supports
|
# return an array of register names that should be used by the allocator
|
||||||
def num_registers
|
# does not include :message
|
||||||
raise "not implemented"
|
# could be in interpreter and arm, but here for now
|
||||||
|
def register_names
|
||||||
|
(1 ... 16).collect{|i| "r#{i}".to_sym }
|
||||||
end
|
end
|
||||||
|
|
||||||
# return the Allocator for the platform
|
# return the Allocator for the platform
|
||||||
@ -30,6 +32,19 @@ module Risc
|
|||||||
StandardAllocator.new(compiler , self )
|
StandardAllocator.new(compiler , self )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def assign_reg?(name)
|
||||||
|
case name
|
||||||
|
when :message
|
||||||
|
:r0
|
||||||
|
when :syscall_1
|
||||||
|
:r0
|
||||||
|
when :syscall_2
|
||||||
|
:r1
|
||||||
|
else
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# Factory method to create a Platform object according to the platform
|
# Factory method to create a Platform object according to the platform
|
||||||
# string given.
|
# string given.
|
||||||
# Currently only "Arm" and "Interpreter"
|
# Currently only "Arm" and "Interpreter"
|
||||||
|
@ -14,7 +14,7 @@ module Risc
|
|||||||
@platform = platform
|
@platform = platform
|
||||||
@used_regs = {}
|
@used_regs = {}
|
||||||
@release_points = Hash.new {|hash , key | hash[key] = [] }
|
@release_points = Hash.new {|hash , key | hash[key] = [] }
|
||||||
@reg_names = (0 ... platform.num_registers).collect{|i| "r#{i}".to_sym }
|
@reg_names = platform.register_names
|
||||||
end
|
end
|
||||||
attr_reader :used_regs , :compiler , :platform , :reg_names
|
attr_reader :used_regs , :compiler , :platform , :reg_names
|
||||||
|
|
||||||
@ -49,9 +49,11 @@ module Risc
|
|||||||
|
|
||||||
def assign(instruction)
|
def assign(instruction)
|
||||||
names = instruction.register_names
|
names = instruction.register_names
|
||||||
names.each do |for_name|
|
#puts "AT #{instruction}"
|
||||||
new_reg = get_reg(for_name)
|
names.each do |ssa_name|
|
||||||
|
new_reg = get_reg(ssa_name)
|
||||||
# swap name out
|
# swap name out
|
||||||
|
#puts "Assign #{new_reg} for #{ssa_name}"
|
||||||
end
|
end
|
||||||
names
|
names
|
||||||
end
|
end
|
||||||
@ -76,10 +78,6 @@ module Risc
|
|||||||
released
|
released
|
||||||
end
|
end
|
||||||
|
|
||||||
def used_regs_empty?
|
|
||||||
@used_regs.empty?
|
|
||||||
end
|
|
||||||
|
|
||||||
# use the given reg (first) parameter and mark it as assigned to
|
# use the given reg (first) parameter and mark it as assigned to
|
||||||
# it's ssa form, the second parameter.
|
# it's ssa form, the second parameter.
|
||||||
# forward check is trivial, and reverse_used provides reverse check
|
# forward check is trivial, and reverse_used provides reverse check
|
||||||
@ -88,6 +86,7 @@ module Risc
|
|||||||
raise "Stupid error #{reg}" unless reg.is_a?(Symbol)
|
raise "Stupid error #{reg}" unless reg.is_a?(Symbol)
|
||||||
#puts "Using #{reg} for #{ssa_name}"
|
#puts "Using #{reg} for #{ssa_name}"
|
||||||
@used_regs[reg] = ssa_name
|
@used_regs[reg] = ssa_name
|
||||||
|
reg
|
||||||
end
|
end
|
||||||
|
|
||||||
# Check whether a register has been assigned to the given ssa form given.
|
# Check whether a register has been assigned to the given ssa form given.
|
||||||
@ -104,6 +103,12 @@ module Risc
|
|||||||
def get_reg(ssa_name)
|
def get_reg(ssa_name)
|
||||||
name = reverse_used( ssa_name )
|
name = reverse_used( ssa_name )
|
||||||
return name if name
|
return name if name
|
||||||
|
get_next_free(ssa_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_next_free(ssa_name)
|
||||||
|
reg = platform.assign_reg?( ssa_name )
|
||||||
|
return use_reg(reg , ssa_name) if reg
|
||||||
@reg_names.each do |name|
|
@reg_names.each do |name|
|
||||||
return use_reg(name , ssa_name) unless @used_regs.has_key?(name)
|
return use_reg(name , ssa_name) unless @used_regs.has_key?(name)
|
||||||
end
|
end
|
||||||
|
@ -13,8 +13,24 @@ module Risc
|
|||||||
assert_raises{ Platform.for("NotArm")}
|
assert_raises{ Platform.for("NotArm")}
|
||||||
end
|
end
|
||||||
def test_allocate
|
def test_allocate
|
||||||
allocator = Platform.new.allocator(FakeCompiler.new)
|
allocator = Platform.for("Interpreter").allocator(FakeCompiler.new)
|
||||||
assert_equal FakeCompiler , allocator.compiler.class
|
assert_equal FakeCompiler , allocator.compiler.class
|
||||||
end
|
end
|
||||||
|
def test_map_message
|
||||||
|
assert_equal :r0 , Platform.new.assign_reg?(:message)
|
||||||
|
end
|
||||||
|
def test_map_sys
|
||||||
|
assert_equal :r0 , Platform.new.assign_reg?(:syscall_1)
|
||||||
|
end
|
||||||
|
def test_map_id
|
||||||
|
assert_nil Platform.new.assign_reg?(:id_some_id)
|
||||||
|
end
|
||||||
|
def test_names_len
|
||||||
|
assert_equal 15 , Platform.new.register_names.length
|
||||||
|
end
|
||||||
|
def test_names_r
|
||||||
|
assert_equal "r" , Platform.new.register_names.first.to_s[0]
|
||||||
|
assert_equal "r" , Platform.new.register_names.last.to_s[0]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -13,11 +13,8 @@ module Risc
|
|||||||
def test_regs
|
def test_regs
|
||||||
assert_equal Hash , @allocator.used_regs.class
|
assert_equal Hash , @allocator.used_regs.class
|
||||||
end
|
end
|
||||||
def test_empty
|
|
||||||
assert @allocator.used_regs_empty?
|
|
||||||
end
|
|
||||||
def test_reg_names
|
def test_reg_names
|
||||||
assert_equal 16 , @allocator.reg_names.length
|
assert_equal 15 , @allocator.reg_names.length
|
||||||
end
|
end
|
||||||
def test_compiler
|
def test_compiler
|
||||||
assert_equal CallableCompiler , @allocator.compiler.class
|
assert_equal CallableCompiler , @allocator.compiler.class
|
||||||
|
Loading…
Reference in New Issue
Block a user