diff --git a/test/arm/helper.rb b/test/arm/helper.rb new file mode 100644 index 00000000..dc0a5482 --- /dev/null +++ b/test/arm/helper.rb @@ -0,0 +1,29 @@ +require_relative '../helper' + +# try to test that the generation of basic instructions works +# one instruction at a time, reverse testing from objdump --demangle -Sfghxp +# tests are named as per assembler code, ie test_mov testing mov instruction +# adc add and bic eor orr rsb rsc sbc sub mov mvn cmn cmp teq tst b call bx swi strb + +module ArmHelper + # need Assembler and a block (see those classes) + def setup + @machine = Arm::ArmMachine.new + end + + # code is what the generator spits out, at least one instruction worth (.first) + # the op code is wat was witten as assembler in the first place and the binary result + # is reversed and in 4 bytes as ruby can only do 31 bits and so we can't test with just one int (?) + def assert_code code , op , should + assert_equal op , code.opcode + io = StringIO.new + code.assemble(io) + binary = io.string + assert_equal 4 , binary.length , "code length wrong for #{code.inspect}" + index = 0 + binary.each_byte do |byte | + assert_equal should[index] , byte , "byte #{index} 0x#{should[index].to_s(16)} != 0x#{byte.to_s(16)}" + index += 1 + end + end +end diff --git a/test/arm/test_all.rb b/test/arm/test_all.rb new file mode 100644 index 00000000..220aaf19 --- /dev/null +++ b/test/arm/test_all.rb @@ -0,0 +1,2 @@ +require_relative "test_arm" +require_relative "test_logic" diff --git a/test/test_arm.rb b/test/arm/test_arm.rb similarity index 82% rename from test/test_arm.rb rename to test/arm/test_arm.rb index 0001787a..53e54817 100644 --- a/test/test_arm.rb +++ b/test/arm/test_arm.rb @@ -26,18 +26,6 @@ class TestArmAsm < MiniTest::Test index += 1 end end - def test_adc - code = @machine.adc :r1, left: :r3, right: :r5 - assert_code code , :adc , [0x05,0x10,0xa3,0xe0] #e0 a3 10 05 - end - def test_add - code = @machine.add :r1 , left: :r1, right: :r3 - assert_code code , :add , [0x03,0x10,0x81,0xe0] #e0 81 10 03 - end - def test_and # inst eval doesn't really work with and - code = @machine.and( :r1 , left: :r2 , right: :r3) - assert_code code , :and , [0x03,0x10,0x02,0xe0] #e0 01 10 03 - end def test_b # the address is what an assembler calculates (a signed number for the amount of instructions), # ie the relative (to pc) address -8 (pipeline) /4 so save space @@ -61,10 +49,6 @@ class TestArmAsm < MiniTest::Test code = @machine.cmp :r1 , right: :r2 assert_code code , :cmp , [0x02,0x00,0x51,0xe1] #e1 51 00 02 end - def test_eor - code = @machine.eor :r2 , left: :r2 , right: :r3 - assert_code code , :eor , [0x03,0x20,0x22,0xe0] #e0 22 20 03 - end def test_ldr code = @machine.ldr :r0, right: :r0 assert_code code, :ldr , [0x00,0x00,0x90,0xe5] #e5 90 00 00 @@ -77,10 +61,6 @@ class TestArmAsm < MiniTest::Test code = @machine.ldrb :r0, right: :r0 assert_code code, :ldrb , [0x00,0x00,0xd0,0xe5] #e5 d0 00 00 end - def test_orr - code = @machine.orr :r2 , left: :r2 , right: :r3 - assert_code code , :orr , [0x03,0x20,0x82,0xe1] #e1 82 20 03 - end def test_push code = @machine.push [:lr] , {} assert_code code , :push , [0x00,0x40,0x2d,0xe9] #e9 2d 40 00 @@ -109,10 +89,6 @@ class TestArmAsm < MiniTest::Test code = @machine.strb :r0, right: :r0 assert_code code, :strb , [0x00,0x00,0xc0,0xe5] #e5 c0 00 00 end - def test_sub - code = @machine.sub :r2, left: :r0, right: 1 - assert_code code, :sub , [0x01,0x20,0x40,0xe2] #e2 40 20 01 - end def test_swi code = @machine.swi 0x05 , {} assert_code code , :swi , [0x05,0x00,0x00,0xef]#ef 00 00 05 diff --git a/test/arm/test_logic.rb b/test/arm/test_logic.rb new file mode 100644 index 00000000..e65f443c --- /dev/null +++ b/test/arm/test_logic.rb @@ -0,0 +1,30 @@ +require_relative 'helper' + +class TestArmAsm < MiniTest::Test + include ArmHelper + + def test_adc + code = @machine.adc :r1, left: :r3, right: :r5 + assert_code code , :adc , [0x05,0x10,0xa3,0xe0] #e0 a3 10 05 + end + def test_add + code = @machine.add :r1 , left: :r1, right: :r3 + assert_code code , :add , [0x03,0x10,0x81,0xe0] #e0 81 10 03 + end + def test_and # inst eval doesn't really work with and + code = @machine.and( :r1 , left: :r2 , right: :r3) + assert_code code , :and , [0x03,0x10,0x02,0xe0] #e0 01 10 03 + end + def test_eor + code = @machine.eor :r2 , left: :r2 , right: :r3 + assert_code code , :eor , [0x03,0x20,0x22,0xe0] #e0 22 20 03 + end + def test_sub + code = @machine.sub :r2, left: :r0, right: 1 + assert_code code, :sub , [0x01,0x20,0x40,0xe2] #e2 40 20 01 + end + def test_orr + code = @machine.orr :r2 , left: :r2 , right: :r3 + assert_code code , :orr , [0x03,0x20,0x82,0xe1] #e1 82 20 03 + end +end diff --git a/test/test_all.rb b/test/test_all.rb index b7632165..2d53d83c 100644 --- a/test/test_all.rb +++ b/test/test_all.rb @@ -1,4 +1,4 @@ -require_relative "test_arm" +require_relative "arm/test_all" require_relative "test_small_program" #require_relative "test_runner" require_relative "parser/test_all"