def test_cycle_2(): assembler = MockAssembler() s8 = frame_pos(8, INT) s12 = frame_pos(12, INT) s20 = frame_pos(19, INT) s24 = frame_pos(1, INT) s2 = frame_pos(2, INT) s3 = frame_pos(3, INT) remap_frame_layout(assembler, [eax, s8, edi, s20, eax, s20, s24, esi, s2, s3], [s8, s20, edi, eax, edx, s24, ebx, s12, s3, s2], ecx) assert assembler.got([('mov', eax, edx), ('mov', s24, ebx), ('mov', esi, s12), ('mov', s20, ecx), ('mov', ecx, s24), ('push', s8), ('mov', eax, s8), ('mov', s20, eax), ('pop', s20), ('push', s3), ('mov', s2, ecx), ('mov', ecx, s3), ('pop', s2)])
def test_constants(): assembler = MockAssembler() c3 = imm(3) remap_frame_layout(assembler, [c3], [eax], '?') assert assembler.ops == [('mov', c3, eax)] assembler = MockAssembler() s12 = frame_pos(12, INT) remap_frame_layout(assembler, [c3], [s12], '?') assert assembler.ops == [('mov', c3, s12)]
def test_constants_and_cycle(): assembler = MockAssembler() c3 = imm(3) s12 = frame_pos(13, INT) remap_frame_layout(assembler, [ebx, c3, s12], [s12, eax, ebx], edi) assert assembler.ops == [('mov', c3, eax), ('push', s12), ('mov', ebx, s12), ('pop', ebx)]
def fake_allocate(self, loop): from rpython.jit.backend.x86.jump import remap_frame_layout def emit(*args): self.assembler.emitted.append(args) for i, op in enumerate(loop.operations): self.rm.position = i opnum = op.getopnum() opname = op.getopname() if rop.is_comparison(opnum): locs = [self.loc(x) for x in op.getarglist()] loc = self.force_allocate_reg_or_cc(op) emit(opname, loc, locs) elif opname.startswith("int_"): locs = [self.loc(x) for x in op.getarglist()] loc = self.rm.force_result_in_reg( op, op.getarg(0), op.getarglist()) emit(opname, loc, locs[1:]) elif op.is_guard(): fail_locs = [self.loc(x) for x in op.getfailargs()] emit(opname, self.loc(op.getarg(0)), fail_locs) elif rop.is_call(opnum): # calling convention! src_locs = [self.loc(x) for x in op.getarglist()[1:]] self.rm.before_call() loc = self.rm.after_call(op) dst_locs = [r1, r2, r3][:len(src_locs)] remap_frame_layout(self.assembler, src_locs, dst_locs, r8) emit(opname, loc, dst_locs) elif opname == "label": descr = op.getdescr() locs = [self.loc(x) for x in op.getarglist()] emit(opname, locs) descr._fake_arglocs = locs lastop = loop.operations[-1] if lastop.getopname() == "jump" and lastop.getdescr() is descr: # now we know the places, add hints for i, r in enumerate(locs): if isinstance(r, FakeReg): self.longevity.fixed_register( len(loop.operations) - 1, r, lastop.getarg(i)) elif opname == "jump": src_locs = [self.loc(x) for x in op.getarglist()] dst_locs = op.getdescr()._fake_arglocs remap_frame_layout(self.assembler, src_locs, dst_locs, r8) emit("jump", dst_locs) else: locs = [self.loc(x) for x in op.getarglist()] if op.type != "v": loc = self.rm.force_allocate_reg(op) emit(opname, loc, locs) else: emit(opname, locs) self.possibly_free_vars_for_op(op) return self.assembler.emitted
def test_no_tmp_reg(): assembler = MockAssembler() s8 = frame_pos(0, INT) s12 = frame_pos(13, INT) s20 = frame_pos(20, INT) s24 = frame_pos(221, INT) remap_frame_layout(assembler, [s8, eax, s12], [s20, s24, edi], None) assert assembler.ops == [('push', s8), ('pop', s20), ('mov', eax, s24), ('mov', s12, edi)]
def test_simple_framelocs(): assembler = MockAssembler() s8 = frame_pos(0, INT) s12 = frame_pos(13, INT) s20 = frame_pos(20, INT) s24 = frame_pos(221, INT) remap_frame_layout(assembler, [s8, eax, s12], [s20, s24, edi], edx) assert assembler.ops == [('mov', s8, edx), ('mov', edx, s20), ('mov', eax, s24), ('mov', s12, edi)]
def test_reordering(): assembler = MockAssembler() s8 = frame_pos(8, INT) s12 = frame_pos(12, INT) s20 = frame_pos(19, INT) s24 = frame_pos(1, INT) remap_frame_layout(assembler, [eax, s8, s20, ebx], [s8, ebx, eax, edi], '?') assert assembler.got([('mov', ebx, edi), ('mov', s8, ebx), ('mov', eax, s8), ('mov', s20, eax)])
def test_cycle(): assembler = MockAssembler() s8 = frame_pos(8, INT) s12 = frame_pos(12, INT) s20 = frame_pos(19, INT) s24 = frame_pos(1, INT) remap_frame_layout(assembler, [eax, s8, s20, ebx], [s8, ebx, eax, s20], '?') assert assembler.got([('push', s8), ('mov', eax, s8), ('mov', s20, eax), ('mov', ebx, s20), ('pop', ebx)])
def test_trivial(): assembler = MockAssembler() remap_frame_layout(assembler, [], [], '?') assert assembler.ops == [] remap_frame_layout(assembler, [eax, ebx, ecx, edx, esi, edi], [eax, ebx, ecx, edx, esi, edi], '?') assert assembler.ops == [] s8 = frame_pos(1, INT) s12 = frame_pos(31, INT) s20 = frame_pos(6, INT) remap_frame_layout(assembler, [eax, ebx, ecx, s20, s8, edx, s12, esi, edi], [eax, ebx, ecx, s20, s8, edx, s12, esi, edi], '?') assert assembler.ops == []
def prepare_arguments(self): src_locs = [] dst_locs = [] xmm_src_locs = [] xmm_dst_locs = [] singlefloats = None arglocs = self.arglocs argtypes = self.argtypes on_stack = 0 for i in range(len(arglocs)): loc = arglocs[i] if loc.is_float(): tgt = self._unused_xmm() if tgt is None: tgt = RawEspLoc(on_stack * WORD, FLOAT) on_stack += 1 xmm_src_locs.append(loc) xmm_dst_locs.append(tgt) elif i < len(argtypes) and argtypes[i] == 'S': # Singlefloat argument if singlefloats is None: singlefloats = [] tgt = self._unused_xmm() if tgt is None: tgt = RawEspLoc(on_stack * WORD, INT) on_stack += 1 singlefloats.append((loc, tgt)) else: tgt = self._unused_gpr(hint=loc) if tgt is None: tgt = RawEspLoc(on_stack * WORD, INT) on_stack += 1 src_locs.append(loc) dst_locs.append(tgt) if not self.fnloc_is_immediate: self.fnloc = dst_locs[-1] # the last "argument" prepared above if not we_are_translated(): # assert that we got the right stack depth floats = 0 for i in range(len(arglocs)): arg = arglocs[i] if arg.is_float() or (i < len(argtypes) and argtypes[i] == 'S'): floats += 1 all_args = len(arglocs) stack_depth = ( max(all_args - floats - len(self.ARGUMENTS_GPR), 0) + max(floats - len(self.ARGUMENTS_XMM), 0)) assert stack_depth == on_stack self.subtract_esp_aligned(on_stack - self.stack_max) # Handle register arguments: first remap the xmm arguments remap_frame_layout(self.asm, xmm_src_locs, xmm_dst_locs, X86_64_XMM_SCRATCH_REG) # Load the singlefloat arguments from main regs or stack to xmm regs if singlefloats is not None: for src, dst in singlefloats: if isinstance(dst, RawEspLoc): # XXX too much special logic if isinstance(src, RawEbpLoc): self.mc.MOV32(X86_64_SCRATCH_REG, src) self.mc.MOV32(dst, X86_64_SCRATCH_REG) else: self.mc.MOV32(dst, src) continue if isinstance(src, ImmedLoc): self.mc.MOV(X86_64_SCRATCH_REG, src) src = X86_64_SCRATCH_REG self.mc.MOVD32(dst, src) # Finally remap the arguments in the main regs remap_frame_layout(self.asm, src_locs, dst_locs, X86_64_SCRATCH_REG)
def prepare_arguments(self): src_locs = [] dst_locs = [] xmm_src_locs = [] xmm_dst_locs = [] singlefloats = None arglocs = self.arglocs argtypes = self.argtypes on_stack = 0 for i in range(len(arglocs)): loc = arglocs[i] if loc.is_float(): tgt = self._unused_xmm() if tgt is None: tgt = RawEspLoc(on_stack * WORD, FLOAT) on_stack += 1 xmm_src_locs.append(loc) xmm_dst_locs.append(tgt) elif i < len(argtypes) and argtypes[i] == 'S': # Singlefloat argument if singlefloats is None: singlefloats = [] tgt = self._unused_xmm() if tgt is None: tgt = RawEspLoc(on_stack * WORD, INT) on_stack += 1 singlefloats.append((loc, tgt)) else: tgt = self._unused_gpr(hint=loc) if tgt is None: tgt = RawEspLoc(on_stack * WORD, INT) on_stack += 1 src_locs.append(loc) dst_locs.append(tgt) if not self.fnloc_is_immediate: self.fnloc = dst_locs[-1] # the last "argument" prepared above if not we_are_translated(): # assert that we got the right stack depth floats = 0 for i in range(len(arglocs)): arg = arglocs[i] if arg.is_float() or (i < len(argtypes) and argtypes[i]=='S'): floats += 1 all_args = len(arglocs) stack_depth = (max(all_args - floats - len(self.ARGUMENTS_GPR), 0) + max(floats - len(self.ARGUMENTS_XMM), 0)) assert stack_depth == on_stack self.subtract_esp_aligned(on_stack - self.stack_max) # Handle register arguments: first remap the xmm arguments remap_frame_layout(self.asm, xmm_src_locs, xmm_dst_locs, X86_64_XMM_SCRATCH_REG) # Load the singlefloat arguments from main regs or stack to xmm regs if singlefloats is not None: for src, dst in singlefloats: if isinstance(dst, RawEspLoc): # XXX too much special logic if isinstance(src, RawEbpLoc): self.mc.MOV32(X86_64_SCRATCH_REG, src) self.mc.MOV32(dst, X86_64_SCRATCH_REG) else: self.mc.MOV32(dst, src) continue if isinstance(src, ImmedLoc): self.mc.MOV(X86_64_SCRATCH_REG, src) src = X86_64_SCRATCH_REG self.mc.MOVD32(dst, src) # Finally remap the arguments in the main regs remap_frame_layout(self.asm, src_locs, dst_locs, X86_64_SCRATCH_REG)
def test_simple_registers(): assembler = MockAssembler() remap_frame_layout(assembler, [eax, ebx, ecx], [edx, esi, edi], '?') assert assembler.ops == [('mov', eax, edx), ('mov', ebx, esi), ('mov', ecx, edi)]
def main(): srclocs = [FrameLoc(9999, x, 'i') for x,y in CASE] dstlocs = [FrameLoc(9999, y, 'i') for x,y in CASE] remap_frame_layout(FakeAssembler(), srclocs, dstlocs, eax)