diff --git a/lib/asm/arm/builder_d.rb b/lib/asm/arm/builder_d.rb index ff6ac4f0..6253b469 100644 --- a/lib/asm/arm/builder_d.rb +++ b/lib/asm/arm/builder_d.rb @@ -29,14 +29,16 @@ module Asm # Build representation for source value def build_operand(arg) - if (arg.is_a?(Asm::RegisterListArgNode)) + if (arg.is_a?(Array)) @operand = 0 - arg.registers.each do |reg_node| - reg = reg_ref(reg_node) + arg.each do |sym , reg | + #allow an array of reg (strings), or the [:reg , name] produced by the instruction functions + reg = sym == :reg ? reg : sym + reg = reg_ref(reg) @operand |= (1 << reg) end else - raise Asm::AssemblyError.new(Asm::ERRSTR_INVALID_ARG, arg) + raise Asm::AssemblyError.new(Asm::ERRSTR_INVALID_ARG + " " + arg.inspect , arg) end end diff --git a/lib/asm/arm/code_generator.rb b/lib/asm/arm/code_generator.rb index 792d0d0f..6208cb7c 100644 --- a/lib/asm/arm/code_generator.rb +++ b/lib/asm/arm/code_generator.rb @@ -49,7 +49,8 @@ class Asm::Arm::CodeGenerator @asm.add_object Asm::Arm::Instruction.new(node) end - %w(adc add and bic eor orr rsb rsc sbc sub mov mvn cmn cmp teq tst b bl bx swi str strb ldr ldrb + %w(adc add and bic eor orr rsb rsc sbc sub mov mvn cmn cmp teq tst b bl bx + push pop swi str strb ldr ldrb ).each { |inst| define_method(inst) { |*args| instruction inst.to_sym, *args diff --git a/lib/asm/arm/instruction.rb b/lib/asm/arm/instruction.rb index e5242a7d..5f27b239 100644 --- a/lib/asm/arm/instruction.rb +++ b/lib/asm/arm/instruction.rb @@ -122,7 +122,8 @@ module Asm end a.cond = COND_BITS[@cond] a.rn = 13 # sp - a.build_operand args[0] + puts "ARGS #{args.inspect}" + a.build_operand args a.write io, as when :b, :bl arg = args[0] diff --git a/lib/asm/nodes.rb b/lib/asm/nodes.rb index d34344b5..503a4a29 100644 --- a/lib/asm/nodes.rb +++ b/lib/asm/nodes.rb @@ -42,8 +42,13 @@ module Asm end end + #maybe not used at all as code_gen::instruction raises if used. + # instead now using Arrays class RegisterListArgNode < ArgNode attr_accessor :registers + def initialize regs + @registers = regs.collect{ |sym , reg| (sym == :reg) ? reg : "not a reg #{sym} , #{reg}" } + end end class NumLiteralArgNode < ArgNode diff --git a/test/helper.rb b/test/helper.rb index 8da54f85..a8fe5550 100644 --- a/test/helper.rb +++ b/test/helper.rb @@ -30,3 +30,4 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'test')) require 'crystal' require 'asm/object_writer' +require "asm/arm/code_generator" diff --git a/test/test_crystal.rb b/test/test_crystal.rb index daaf8783..54f4cb0d 100644 --- a/test/test_crystal.rb +++ b/test/test_crystal.rb @@ -76,6 +76,15 @@ class TestArmAsm < MiniTest::Test code = @generator.instance_eval { orr r2 , r2 , r3 }.first assert_code code , :orr , [0x03,0x20,0x82,0xe1] #e1 82 20 03 end + def test_push + code = @generator.instance_eval { push lr }.first + assert_code code , :push , [0x00,0x40,0x2d,0xe9] #e9 2d 40 00 + end + def test_pop + code = @generator.instance_eval { pop pc }.first + assert_code code , :pop , [0x00,0x80,0xbd,0xe8] #e8 bd 80 00 + end + def test_rsb code = @generator.instance_eval { rsb r1 , r2 , r3 }.first assert_code code , :rsb , [0x03,0x10,0x62,0xe0]#e0 62 10 03