diff --git a/lib/arm/move_instruction.rb b/lib/arm/move_instruction.rb index d0392378..db268d67 100644 --- a/lib/arm/move_instruction.rb +++ b/lib/arm/move_instruction.rb @@ -65,7 +65,7 @@ module Arm io.write_uint32 val end def shift val , by - raise "Not integer #{val}:#{val.class}" unless val.is_a? Fixnum + raise "Not integer #{val}:#{val.class} in #{inspect}" unless val.is_a? Fixnum val << by end end diff --git a/lib/core/kernel.rb b/lib/core/kernel.rb index 948ce326..379ad1f1 100644 --- a/lib/core/kernel.rb +++ b/lib/core/kernel.rb @@ -73,6 +73,40 @@ module Core b.callne( utoa_function ) return utoa_function end + + # testing method, hand coded fibo, expects arg in 1 , so pass 2 in, first bogy + # result comes in 0 + # a hand coded version of the fibonachi numbers + # not my hand off course, found in the net from a basic introduction + def fibo context + fibo_function = Vm::Function.new(:fibo , [Vm::Integer , Vm::Integer] , Vm::Integer ) + result = fibo_function.args[0] + int =fibo_function.args[1] + i = Vm::Integer.new(2) + f1 = Vm::Integer.new(3) + f2 = Vm::Integer.new(4) + loop_block = Vm::Block.new("loop") + fibo_function.body.instance_eval do + cmp( int , 1) + mov( result, int , condition_code: :le) + mov( :pc , :lr , condition_code: :le) + push [ i , f1 , f2 , :lr] + mov( f1 , 1) + mov(f2 , 0) + sub( i , int , 2) + add_code loop_block + end + loop_block.instance_eval do + add( f1 , f1 , f2) + sub( f2 , f1 , f2) + sub( i , i , 1 , update_status: 1) + bpl( loop_block ) + mov( result , f1 ) + pop [ i , f1 , f2 , :pc] + end + fibo_function + end + end extend ClassMethods diff --git a/lib/elf/object_writer.rb b/lib/elf/object_writer.rb index 70182c91..8ed57d61 100644 --- a/lib/elf/object_writer.rb +++ b/lib/elf/object_writer.rb @@ -6,9 +6,9 @@ require 'elf/string_table_section' module Elf class ObjectWriter - def initialize(target) + def initialize(program , target) @object = Elf::ObjectFile.new(target) - + @program = program sym_strtab = Elf::StringTableSection.new(".strtab") @object.add_section sym_strtab @symbol_table = Elf::SymbolTableSection.new(".symtab", sym_strtab) @@ -16,6 +16,17 @@ module Elf @text = Elf::TextSection.new(".text") @object.add_section @text + + program.link_at( 0 , program.context ) + + binary = program.assemble(StringIO.new ) + + blocks = program.functions.collect{ |f| [f.entry , f.exit , f.body] } + blocks += [program.entry , program.exit , program.main] + blocks.flatten.each do |b| + add_symbol b.name.to_s , b.position + end + set_text binary.string end def set_text(text) diff --git a/test/arm/test_all.rb b/test/arm/test_all.rb index 31a27379..10f08b26 100644 --- a/test/arm/test_all.rb +++ b/test/arm/test_all.rb @@ -4,3 +4,4 @@ require_relative "test_logic" require_relative "test_move" require_relative "test_memory" require_relative "test_compare" +require_relative "test_small_program" diff --git a/test/arm/test_fibo.rb b/test/arm/test_fibo.rb new file mode 100644 index 00000000..86990622 --- /dev/null +++ b/test/arm/test_fibo.rb @@ -0,0 +1,26 @@ +require_relative 'helper' + +class TestFibo < MiniTest::Test + + def setup + @program = Vm::Program.new "Arm" + end + + # a hand coded version of the fibonachi numbers + # not my hand off course, found in the net from a basic introduction + def test_fibo + int = Vm::Integer.new(1) # the one is funny, but the fibo is _really_ tight code and reuses registers + fibo = utoa = @program.get_or_create_function(:fibo) + @program.main.mov( int , 10 ) + @program.main.call( fibo ) + #could put ... + write 20 , "fibo" + end + + #helper to write the file + def write len ,name + writer = Elf::ObjectWriter.new(@program , Elf::Constants::TARGET_ARM) + writer.save("#{name}_test.o") + end + +end \ No newline at end of file diff --git a/test/test_small_program.rb b/test/arm/test_small_program.rb similarity index 100% rename from test/test_small_program.rb rename to test/arm/test_small_program.rb diff --git a/test/test_all.rb b/test/test_all.rb index 2d53d83c..259bc17d 100644 --- a/test/test_all.rb +++ b/test/test_all.rb @@ -1,4 +1,3 @@ require_relative "arm/test_all" -require_relative "test_small_program" #require_relative "test_runner" require_relative "parser/test_all" diff --git a/test/test_runner.rb b/test/test_runner.rb index a687da02..e2267057 100644 --- a/test/test_runner.rb +++ b/test/test_runner.rb @@ -35,18 +35,8 @@ class TestRunner < MiniTest::Test end end - program.link_at( 0 , program.context ) - - binary = program.assemble(StringIO.new ) - assert binary - writer = Elf::ObjectWriter.new(Elf::Constants::TARGET_ARM) - blocks = program.functions.collect{ |f| [f.entry , f.exit , f.body] } - blocks += [program.entry , program.exit , program.main] - blocks.flatten.each do |b| - writer.add_symbol b.name.to_s , b.position - end + writer = Elf::ObjectWriter.new(program , Elf::Constants::TARGET_ARM) - writer.set_text binary.string writer.save(file.gsub(".rb" , ".o")) # puts program.to_yaml