Beispiel #1
0
class TestRunningAssembler(object):
    def setup_method(self, method):
        cpu = CPU(None, None)
        self.a = AssemblerARM(cpu)
        self.a.setup_once()
        token = JitCellToken()
        clt = CompiledLoopToken(cpu, 0)
        clt.allgcrefs = []
        token.compiled_loop_token = clt
        self.a.setup(token)

    def test_make_operation_list(self):
        i = rop.INT_ADD
        from rpython.jit.backend.arm import assembler
        assert assembler.asm_operations[i] \
            is AssemblerARM.emit_op_int_add.im_func

    def test_load_small_int_to_reg(self):
        self.a.gen_func_prolog()
        self.a.mc.gen_load_int(r.r0.value, 123)
        self.a.gen_func_epilog()
        assert run_asm(self.a) == 123

    def test_load_medium_int_to_reg(self):
        self.a.gen_func_prolog()
        self.a.mc.gen_load_int(r.r0.value, 0xBBD7)
        self.a.gen_func_epilog()
        assert run_asm(self.a) == 48087

    def test_load_int_to_reg(self):
        self.a.gen_func_prolog()
        self.a.mc.gen_load_int(r.r0.value, 0xFFFFFF85)
        self.a.gen_func_epilog()
        assert run_asm(self.a) == -123

    def test_load_neg_int_to_reg(self):
        self.a.gen_func_prolog()
        self.a.mc.gen_load_int(r.r0.value, -110)
        self.a.gen_func_epilog()
        assert run_asm(self.a) == -110

    def test_load_neg_int_to_reg2(self):
        self.a.gen_func_prolog()
        self.a.mc.gen_load_int(r.r0.value, -3)
        self.a.gen_func_epilog()
        assert run_asm(self.a) == -3

    def test_load_int1(self):
        self.a.gen_func_prolog()
        self.a.mc.gen_load_int(r.r0.value, 440)
        self.a.gen_func_epilog()
        assert run_asm(self.a) == 440

    def test_load_int2(self):
        self.a.gen_func_prolog()
        self.a.mc.gen_load_int(r.r0.value, 464)
        self.a.gen_func_epilog()
        assert run_asm(self.a) == 464

    def test_or(self):
        self.a.gen_func_prolog()
        self.a.mc.MOV_ri(r.r1.value, 8)
        self.a.mc.MOV_ri(r.r2.value, 8)
        self.a.mc.ORR_rr(r.r0.value, r.r1.value, r.r2.value, 4)
        self.a.gen_func_epilog()
        assert run_asm(self.a) == 0x88

    def test_sub(self):
        self.a.gen_func_prolog()
        self.a.mc.gen_load_int(r.r1.value, 123456)
        self.a.mc.SUB_ri(r.r0.value, r.r1.value, 123)
        self.a.gen_func_epilog()
        assert run_asm(self.a) == 123333

    def test_cmp(self):
        self.a.gen_func_prolog()
        self.a.mc.gen_load_int(r.r1.value, 22)
        self.a.mc.CMP_ri(r.r1.value, 123)
        self.a.mc.MOV_ri(r.r0.value, 1, c.LE)
        self.a.mc.MOV_ri(r.r0.value, 0, c.GT)
        self.a.gen_func_epilog()
        assert run_asm(self.a) == 1

    def test_int_le_false(self):
        self.a.gen_func_prolog()
        self.a.mc.gen_load_int(r.r1.value, 2222)
        self.a.mc.CMP_ri(r.r1.value, 123)
        self.a.mc.MOV_ri(r.r0.value, 1, c.LE)
        self.a.mc.MOV_ri(r.r0.value, 0, c.GT)
        self.a.gen_func_epilog()
        assert run_asm(self.a) == 0

    def test_simple_jump(self):
        self.a.gen_func_prolog()
        self.a.mc.MOV_ri(r.r1.value, 1)
        loop_head = self.a.mc.currpos()
        self.a.mc.CMP_ri(r.r1.value, 0)  # z=0, z=1
        self.a.mc.MOV_ri(r.r1.value, 0, cond=c.NE)
        self.a.mc.MOV_ri(r.r1.value, 7, cond=c.EQ)
        self.a.mc.B_offs(loop_head, c.NE)
        self.a.mc.MOV_rr(r.r0.value, r.r1.value)
        self.a.gen_func_epilog()
        assert run_asm(self.a) == 7

    def test_jump(self):
        self.a.gen_func_prolog()
        self.a.mc.MOV_ri(r.r1.value, 1)
        loop_head = self.a.mc.currpos()
        self.a.mc.ADD_ri(r.r1.value, r.r1.value, 1)
        self.a.mc.CMP_ri(r.r1.value, 9)
        self.a.mc.B_offs(loop_head, c.NE)
        self.a.mc.MOV_rr(r.r0.value, r.r1.value)
        self.a.gen_func_epilog()
        assert run_asm(self.a) == 9

    def test_B_offs_imm(self):
        self.a.mc.PUSH([reg.value for reg in r.callee_saved_registers])
        self.a.mc.MOV_ri(r.r0.value, 0)
        self.a.mc.MOV_ri(r.r1.value, 0)
        self.a.mc.CMP_rr(r.r0.value, r.r1.value)
        pos = self.a.mc.currpos()
        self.a.mc.MOV_ri(r.r0.value, 123, cond=c.NE)

        for x in range(15):
            self.a.mc.POP(
                [reg.value for reg in r.callee_restored_registers], cond=c.NE)

        self.a.mc.MOV_ri(r.r1.value, 33)
        self.a.mc.MOV_ri(r.r0.value, 23)
        self.a.mc.CMP_rr(r.r0.value, r.r1.value)
        self.a.mc.B_offs(pos)
        assert run_asm(self.a) == 123

    def test_B_offs_reg(self):
        self.a.mc.PUSH([reg.value for reg in r.callee_saved_registers])
        self.a.mc.MOV_ri(r.r0.value, 0)
        self.a.mc.MOV_ri(r.r1.value, 0)
        self.a.mc.CMP_rr(r.r0.value, r.r1.value)
        pos = self.a.mc.currpos()
        self.a.mc.MOV_ri(r.r0.value, 123, cond=c.NE)

        for x in range(100):
            self.a.mc.POP(
                [reg.value for reg in r.callee_restored_registers], cond=c.NE)

        self.a.mc.MOV_ri(r.r1.value, 33)
        self.a.mc.MOV_ri(r.r0.value, 23)
        self.a.mc.CMP_rr(r.r0.value, r.r1.value)
        self.a.mc.B_offs(pos)
        assert run_asm(self.a) == 123

    def test_call_python_func(self):
        functype = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Signed))
        call_addr = rffi.cast(lltype.Signed, llhelper(functype, callme))
        self.a.gen_func_prolog()
        self.a.mc.MOV_ri(r.r0.value, 123)
        self.a.mc.BL(call_addr)
        self.a.gen_func_epilog()
        assert run_asm(self.a) == 133

    def test_division(self):
        self.a.gen_func_prolog()
        self.a.mc.MOV_ri(r.r0.value, 123)
        self.a.mc.MOV_ri(r.r1.value, 2)

        # call to div
        self.a.mc.PUSH(range(2, 12))
        div_addr = rffi.cast(lltype.Signed, arm_int_div)
        self.a.mc.BL(div_addr)
        self.a.mc.POP(range(2, 12))
        self.a.gen_func_epilog()
        assert run_asm(self.a) == 61

    def test_DIV(self):
        self.a.gen_func_prolog()
        self.a.mc.MOV_ri(r.r0.value, 123)
        self.a.mc.MOV_ri(r.r1.value, 2)
        self.a.mc.DIV()
        self.a.gen_func_epilog()
        assert run_asm(self.a) == 61

    def test_DIV2(self):
        self.a.gen_func_prolog()
        self.a.mc.gen_load_int(r.r0.value, -110)
        self.a.mc.gen_load_int(r.r1.value, 3)
        self.a.mc.DIV()
        self.a.gen_func_epilog()
        assert run_asm(self.a) == -36

    def test_DIV3(self):
        self.a.gen_func_prolog()
        self.a.mc.gen_load_int(r.r8.value, 110)
        self.a.mc.gen_load_int(r.r9.value, -3)
        self.a.mc.MOV_rr(r.r0.value, r.r8.value)
        self.a.mc.MOV_rr(r.r1.value, r.r9.value)
        self.a.mc.DIV()
        self.a.gen_func_epilog()
        assert run_asm(self.a) == -36

    def test_bl_with_conditional_exec(self):
        functype = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Signed))
        call_addr = rffi.cast(lltype.Signed, llhelper(functype, callme))
        self.a.gen_func_prolog()
        self.a.mc.MOV_ri(r.r0.value, 123)
        self.a.mc.CMP_ri(r.r0.value, 1)
        self.a.mc.BL(call_addr, c.NE)
        self.a.gen_func_epilog()
        assert run_asm(self.a) == 133

    def test_mov_small_imm_loc_to_loc(self):
        self.a.gen_func_prolog()
        self.a.mov_loc_loc(imm(12), r.r0)
        self.a.gen_func_epilog()
        assert run_asm(self.a) == 12

    def test_mov_large_imm_loc_to_loc(self):
        self.a.gen_func_prolog()
        self.a.mov_loc_loc(imm(2478), r.r0)
        self.a.gen_func_epilog()
        assert run_asm(self.a) == 2478

    def test_load_store(self):
        x = 0x60002224
        self.a.gen_func_prolog()
        self.a.mc.gen_load_int(r.r1.value, x)
        self.a.mc.SUB_ri(r.sp.value, r.sp.value, 8)
        self.a.mc.MOV_ri(r.r3.value, 8)
        self.a.mc.STR_rr(r.r1.value, r.sp.value, r.r3.value)
        self.a.mc.LDR_ri(r.r0.value, r.sp.value, 8)
        self.a.mc.ADD_ri(r.sp.value, r.sp.value, 8)
        self.a.gen_func_epilog()
        assert run_asm(self.a) == x
    
    def test_stm(self):
        container = lltype.malloc(lltype.Array(lltype.Signed, hints={'nolength': True}), 10, flavor='raw')
        self.a.gen_func_prolog()
        self.a.mc.gen_load_int(r.ip.value, rffi.cast(lltype.Signed, container))
        for x in range(10):
            self.a.mc.gen_load_int(x, x)
        self.a.mc.STM(r.ip.value, [x for x in range(10)])
        self.a.gen_func_epilog()
        run_asm(self.a)
        for x in range(10):
            assert container[x] == x
        lltype.free(container, flavor='raw')

    def test_ldm(self):
        container = lltype.malloc(lltype.Array(lltype.Signed, hints={'nolength': True}), 10, flavor='raw')
        for x in range(10):
            container[x] = x
        self.a.gen_func_prolog()
        self.a.mc.gen_load_int(r.ip.value, rffi.cast(lltype.Signed, container))
        self.a.mc.LDM(r.ip.value, [x for x in range(10)])
        for x in range(1, 10):
            self.a.mc.ADD_rr(0, 0, x)
        self.a.gen_func_epilog()
        res = run_asm(self.a)
        assert res == sum(range(10))
        lltype.free(container, flavor='raw')

    def test_vstm(self):
        n = 14
        source_container = lltype.malloc(lltype.Array(longlong.FLOATSTORAGE,
            hints={'nolength': True}), n, flavor='raw')
        target_container = lltype.malloc(lltype.Array(longlong.FLOATSTORAGE,
            hints={'nolength': True}), n, flavor='raw')
        for x in range(n):
            source_container[x] = longlong.getfloatstorage(float("%d.%d" % (x,x)))
        self.a.gen_func_prolog()
        for x in range(n):
            self.a.mc.ADD_ri(r.ip.value, r.ip.value, 8)
            self.a.mc.VLDR(n, r.ip.value)
        self.a.mc.gen_load_int(r.ip.value, rffi.cast(lltype.Signed, target_container))
        self.a.mc.VSTM(r.ip.value, [x for x in range(n)])
        self.a.gen_func_epilog()
        run_asm(self.a)
        for d in range(n):
            res = longlong.getrealfloat(target_container[0]) == float("%d.%d" % (d,d))
        lltype.free(source_container, flavor='raw')
        lltype.free(target_container, flavor='raw')

    def test_vldm(self):
        n = 14
        container = lltype.malloc(lltype.Array(longlong.FLOATSTORAGE,
                                hints={'nolength': True}), n, flavor='raw')
        for x in range(n):
            container[x] = longlong.getfloatstorage(float("%d.%d" % (x,x)))
        self.a.gen_func_prolog()
        self.a.mc.gen_load_int(r.ip.value, rffi.cast(lltype.Signed, container))
        self.a.mc.VLDM(r.ip.value, [x for x in range(n)])
        for x in range(1, n):
            self.a.mc.VADD(0, 0, x)
        self.a.mc.VSTR(r.d0.value, r.ip.value)
        self.a.gen_func_epilog()
        res = run_asm(self.a)
        assert longlong.getrealfloat(container[0]) == sum([float("%d.%d" % (d,d)) for d in range(n)])
        lltype.free(container, flavor='raw')

    def test_vstm_vldm_combined(self):
        n = 14
        source_container = lltype.malloc(lltype.Array(longlong.FLOATSTORAGE,
            hints={'nolength': True}), n, flavor='raw')
        target_container = lltype.malloc(lltype.Array(longlong.FLOATSTORAGE,
            hints={'nolength': True}), n, flavor='raw')
        for x in range(n):
            source_container[x] = longlong.getfloatstorage(float("%d.%d" % (x,x)))
        self.a.gen_func_prolog()
        self.a.mc.gen_load_int(r.ip.value, rffi.cast(lltype.Signed, source_container))
        self.a.mc.VLDM(r.ip.value, [x for x in range(n)])
        self.a.mc.gen_load_int(r.ip.value, rffi.cast(lltype.Signed, target_container))
        self.a.mc.VSTM(r.ip.value, [x for x in range(n)])
        self.a.gen_func_epilog()
        run_asm(self.a)
        for d in range(n):
            res = longlong.getrealfloat(target_container[0]) == float("%d.%d" % (d,d))
        lltype.free(source_container, flavor='raw')
        lltype.free(target_container, flavor='raw')