diff --git a/lib/risc/platform.rb b/lib/risc/platform.rb index 5b4db22e..6469ea39 100644 --- a/lib/risc/platform.rb +++ b/lib/risc/platform.rb @@ -8,17 +8,19 @@ module Risc # return the translator instance that traslates risc intructions into # platform specific ones def translator - raise "not implemented" + raise "not implemented in #{self.class}" end # return an integer where the binary is loaded def loaded_at - raise "not implemented" + raise "not implemented in #{self.class}" end - # return the number of registers the platform supports - def num_registers - raise "not implemented" + # return an array of register names that should be used by the allocator + # does not include :message + # could be in interpreter and arm, but here for now + def register_names + (1 ... 16).collect{|i| "r#{i}".to_sym } end # return the Allocator for the platform @@ -30,6 +32,19 @@ module Risc StandardAllocator.new(compiler , self ) 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 # string given. # Currently only "Arm" and "Interpreter" diff --git a/lib/risc/standard_allocator.rb b/lib/risc/standard_allocator.rb index cb8f931f..f3272015 100644 --- a/lib/risc/standard_allocator.rb +++ b/lib/risc/standard_allocator.rb @@ -14,7 +14,7 @@ module Risc @platform = platform @used_regs = {} @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 attr_reader :used_regs , :compiler , :platform , :reg_names @@ -49,9 +49,11 @@ module Risc def assign(instruction) names = instruction.register_names - names.each do |for_name| - new_reg = get_reg(for_name) + #puts "AT #{instruction}" + names.each do |ssa_name| + new_reg = get_reg(ssa_name) # swap name out + #puts "Assign #{new_reg} for #{ssa_name}" end names end @@ -76,10 +78,6 @@ module Risc released end - def used_regs_empty? - @used_regs.empty? - end - # use the given reg (first) parameter and mark it as assigned to # it's ssa form, the second parameter. # 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) #puts "Using #{reg} for #{ssa_name}" @used_regs[reg] = ssa_name + reg end # Check whether a register has been assigned to the given ssa form given. @@ -104,6 +103,12 @@ module Risc def get_reg(ssa_name) name = reverse_used( ssa_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| return use_reg(name , ssa_name) unless @used_regs.has_key?(name) end diff --git a/test/risc/test_platform.rb b/test/risc/test_platform.rb index eee5291f..6071eb1f 100644 --- a/test/risc/test_platform.rb +++ b/test/risc/test_platform.rb @@ -13,8 +13,24 @@ module Risc assert_raises{ Platform.for("NotArm")} end def test_allocate - allocator = Platform.new.allocator(FakeCompiler.new) + allocator = Platform.for("Interpreter").allocator(FakeCompiler.new) assert_equal FakeCompiler , allocator.compiler.class 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 diff --git a/test/risc/test_standard_allocator.rb b/test/risc/test_standard_allocator.rb index 615821f4..8afeeb05 100644 --- a/test/risc/test_standard_allocator.rb +++ b/test/risc/test_standard_allocator.rb @@ -13,11 +13,8 @@ module Risc def test_regs assert_equal Hash , @allocator.used_regs.class end - def test_empty - assert @allocator.used_regs_empty? - end def test_reg_names - assert_equal 16 , @allocator.reg_names.length + assert_equal 15 , @allocator.reg_names.length end def test_compiler assert_equal CallableCompiler , @allocator.compiler.class