diff --git a/lib/risc/callable_compiler.rb b/lib/risc/callable_compiler.rb index 551172bc..a256b56d 100644 --- a/lib/risc/callable_compiler.rb +++ b/lib/risc/callable_compiler.rb @@ -151,7 +151,8 @@ module Risc # The Platform specifies how many registers there are, and the # Allocator changes SSA names to allocated names def allocate_regs(platform) - allocator = Allocator.new(self , platform) + allocator = platform.allocator(self) + allocator.allocate_regs end end end diff --git a/lib/risc/platform.rb b/lib/risc/platform.rb index 53517ba5..5b4db22e 100644 --- a/lib/risc/platform.rb +++ b/lib/risc/platform.rb @@ -8,14 +8,26 @@ module Risc # return the translator instance that traslates risc intructions into # platform specific ones def translator + raise "not implemented" end # return an integer where the binary is loaded def loaded_at + raise "not implemented" end # return the number of registers the platform supports def num_registers + raise "not implemented" + end + + # return the Allocator for the platform + # stanrard implementation return StandardAllocator, which uses + # num_registers and assumes rXX naming (ie arm + interpreter) + # + # Possibility to override and implemented different schemes + def allocator(compiler) + StandardAllocator.new(compiler , self ) end # Factory method to create a Platform object according to the platform diff --git a/lib/risc/standard_allocator.rb b/lib/risc/standard_allocator.rb index 156508f2..01f4f218 100644 --- a/lib/risc/standard_allocator.rb +++ b/lib/risc/standard_allocator.rb @@ -13,9 +13,18 @@ module Risc @compiler = compiler @platform = platform @used_regs = {} - reset_used_regs + @reg_names = (0 ... platform.num_registers).collect{|i| "r#{i-1}".to_sym } + end + attr_reader :used_regs , :compiler , :platform , :reg_names + + # main entry point and the whole reason for the class. + # Allocate regs by changing the names of compiler instructions to + # register names according to platform. + # Ie on arm register names are r0 .. . r15 , so it keeps a list of unused + # regs and frees regs according to live ranges + def allocate_regs + end - attr_reader :used_regs , :compiler , :platform def used_regs_empty? @used_regs.empty? @@ -43,12 +52,6 @@ module Risc RegisterValue.new( sym , type, extra) end - def copy( reg , source ) - copied = use_reg reg.type - add_code Register.transfer( source , reg , copied ) - copied - end - # releasing a register (accuired by use_reg) makes it available for use again # thus avoiding possibly using too many registers def release_reg( reg ) @@ -57,12 +60,5 @@ module Risc @used_regs.delete(reg) end - # reset the registers to be used. Start at r4 for next usage. - # Every statement starts with this, meaning each statement may use all registers, but none - # get saved. Statements have affect on objects. - def reset_used_regs - @used_regs.clear - end - end end diff --git a/test/risc/test_platform.rb b/test/risc/test_platform.rb index 6a1c722b..eee5291f 100644 --- a/test/risc/test_platform.rb +++ b/test/risc/test_platform.rb @@ -12,5 +12,9 @@ module Risc def test_factory_raise assert_raises{ Platform.for("NotArm")} end + def test_allocate + allocator = Platform.new.allocator(FakeCompiler.new) + assert_equal FakeCompiler , allocator.compiler.class + end end end diff --git a/test/risc/test_standard_allocator.rb b/test/risc/test_standard_allocator.rb index abcf0861..76dd5906 100644 --- a/test/risc/test_standard_allocator.rb +++ b/test/risc/test_standard_allocator.rb @@ -16,6 +16,9 @@ module Risc def test_empty assert @allocator.used_regs_empty? end + def test_reg_names + assert_equal 16 , @allocator.reg_names.length + end def test_compiler assert_equal CallableCompiler , @allocator.compiler.class assert_equal :fake_name , @allocator.compiler.callable.name