def test_random_mixed(): assembler = MockAssembler() registers1 = [eax, ebx, ecx] registers2 = [xmm0, xmm1, xmm2] if IS_X86_32: XMMWORDS = 2 elif IS_X86_64: XMMWORDS = 1 # def pick1(): n = random.randrange(-3, 10) if n < 0: return registers1[n] else: return frame_pos(n, INT) def pick2(): n = random.randrange(-3 , 10 // XMMWORDS) if n < 0: return registers2[n] else: return frame_pos(n * XMMWORDS, FLOAT) # def pick1c(): n = random.randrange(-2000, 500) if n >= 0: return imm(n) else: return pick1() # def pick_dst(fn, count, seen): result = [] while len(result) < count: x = fn() keys = [x._getregkey()] if isinstance(x, StackLoc) and x.width > WORD: keys.append(keys[0] + WORD) for key in keys: if key in seen: break else: for key in keys: seen[key] = True result.append(x) return result # def get_state(locations): regs1 = {} regs2 = {} stack = {} for i, loc in enumerate(locations): if isinstance(loc, RegLoc): if loc.is_xmm: if loc.width > WORD: newvalue = ('value-xmm-%d' % i, 'value-xmm-hiword-%d' % i) else: newvalue = 'value-xmm-%d' % i regs2[loc.value] = newvalue else: regs1[loc.value] = 'value-int-%d' % i elif isinstance(loc, StackLoc): stack[loc.value] = 'value-width%d-%d' % (loc.width, i) if loc.width > WORD: stack[loc.value+WORD] = 'value-hiword-%d' % i else: assert isinstance(loc, ImmedLoc) return regs1, regs2, stack # for i in range(500): seen = {} src_locations2 = [pick2() for i in range(4)] dst_locations2 = pick_dst(pick2, 4, seen) src_locations1 = [pick1c() for i in range(5)] dst_locations1 = pick_dst(pick1, 5, seen) assembler = MockAssembler() remap_frame_layout_mixed(assembler, src_locations1, dst_locations1, edi, src_locations2, dst_locations2, xmm7) # regs1, regs2, stack = get_state(src_locations1 + src_locations2) # def read(loc, expected_width=None): if expected_width is not None: assert loc.width == expected_width if isinstance(loc, RegLoc): if loc.is_xmm: return regs2[loc.value] else: return regs1[loc.value] if isinstance(loc, StackLoc): got = stack[loc.value] if loc.width > WORD: got = (got, stack[loc.value+WORD]) return got if isinstance(loc, ImmedLoc): return 'const-%d' % loc.value assert 0, loc # def write(loc, newvalue): if isinstance(loc, RegLoc): if loc.is_xmm: regs2[loc.value] = newvalue else: regs1[loc.value] = newvalue elif isinstance(loc, StackLoc): if loc.width > WORD: newval1, newval2 = newvalue stack[loc.value] = newval1 stack[loc.value+WORD] = newval2 else: stack[loc.value] = newvalue else: assert 0, loc # src_values1 = [read(loc, WORD) for loc in src_locations1] src_values2 = [read(loc, 8) for loc in src_locations2] # extrapushes = [] for op in assembler.ops: if op[0] == 'mov': src, dst = op[1:] assert isinstance(src, (RegLoc, StackLoc, ImmedLoc)) assert isinstance(dst, (RegLoc, StackLoc)) assert not (isinstance(src, StackLoc) and isinstance(dst, StackLoc)) write(dst, read(src)) elif op[0] == 'push': src, = op[1:] assert isinstance(src, (RegLoc, StackLoc)) extrapushes.append(read(src)) elif op[0] == 'pop': dst, = op[1:] assert isinstance(dst, (RegLoc, StackLoc)) write(dst, extrapushes.pop()) else: assert 0, "unknown op: %r" % (op,) assert not extrapushes # for i, loc in enumerate(dst_locations1): assert read(loc, WORD) == src_values1[i] for i, loc in enumerate(dst_locations2): assert read(loc, 8) == src_values2[i]
def test_random_mixed(): assembler = MockAssembler() registers1 = [eax, ebx, ecx] registers2 = [xmm0, xmm1, xmm2] if IS_X86_32: XMMWORDS = 2 elif IS_X86_64: XMMWORDS = 1 # def pick1(): n = random.randrange(-3, 10) if n < 0: return registers1[n] else: return frame_pos(n, INT) def pick2(): n = random.randrange(-3, 10 // XMMWORDS) if n < 0: return registers2[n] else: return frame_pos(n * XMMWORDS, FLOAT) # def pick1c(): n = random.randrange(-2000, 500) if n >= 0: return imm(n) else: return pick1() # def pick2c(): n = random.randrange(-2000, 500) if n >= 0: return ConstFloatLoc(n) # n is the address, not really used here else: return pick2() # def pick_dst(fn, count, seen): result = [] while len(result) < count: x = fn() keys = [x._getregkey()] if isinstance(x, StackLoc) and x.get_width() > WORD: keys.append(keys[0] + WORD) for key in keys: if key in seen: break else: for key in keys: seen[key] = True result.append(x) return result # def get_state(locations): regs1 = {} regs2 = {} stack = {} for i, loc in enumerate(locations): if isinstance(loc, RegLoc): if loc.is_xmm: if loc.get_width() > WORD: newvalue = ('value-xmm-%d' % i, 'value-xmm-hiword-%d' % i) else: newvalue = 'value-xmm-%d' % i regs2[loc.value] = newvalue else: regs1[loc.value] = 'value-int-%d' % i elif isinstance(loc, StackLoc): stack[loc.value] = 'value-width%d-%d' % (loc.get_width(), i) if loc.get_width() > WORD: stack[loc.value + WORD] = 'value-hiword-%d' % i else: assert isinstance(loc, (ImmedLoc, ConstFloatLoc)) return regs1, regs2, stack # for i in range(500): seen = {} src_locations2 = [pick2c() for i in range(4)] dst_locations2 = pick_dst(pick2, 4, seen) src_locations1 = [pick1c() for i in range(5)] dst_locations1 = pick_dst(pick1, 5, seen) assembler = MockAssembler() remap_frame_layout_mixed(assembler, src_locations1, dst_locations1, edi, src_locations2, dst_locations2, xmm7) # regs1, regs2, stack = get_state(src_locations1 + src_locations2) # def read(loc, expected_width=None): if expected_width is not None: assert loc.get_width() == expected_width if isinstance(loc, RegLoc): if loc.is_xmm: return regs2[loc.value] else: return regs1[loc.value] if isinstance(loc, StackLoc): got = stack[loc.value] if loc.get_width() > WORD: got = (got, stack[loc.value + WORD]) return got if isinstance(loc, ImmedLoc): return 'const-%d' % loc.value if isinstance(loc, ConstFloatLoc): got = 'constfloat-@%d' % loc.value if loc.get_width() > WORD: got = (got, 'constfloat-next-@%d' % loc.value) return got assert 0, loc # def write(loc, newvalue): assert (type(newvalue) is tuple) == (loc.get_width() > WORD) if isinstance(loc, RegLoc): if loc.is_xmm: regs2[loc.value] = newvalue else: regs1[loc.value] = newvalue elif isinstance(loc, StackLoc): if loc.get_width() > WORD: newval1, newval2 = newvalue stack[loc.value] = newval1 stack[loc.value + WORD] = newval2 else: stack[loc.value] = newvalue else: assert 0, loc # src_values1 = [read(loc, WORD) for loc in src_locations1] src_values2 = [read(loc, 8) for loc in src_locations2] # extrapushes = [] for op in assembler.ops: if op[0] == 'mov': src, dst = op[1:] if isinstance(src, ConstFloatLoc): assert isinstance(dst, RegLoc) assert dst.is_xmm else: assert isinstance(src, (RegLoc, StackLoc, ImmedLoc)) assert isinstance(dst, (RegLoc, StackLoc)) assert not (isinstance(src, StackLoc) and isinstance(dst, StackLoc)) write(dst, read(src)) elif op[0] == 'push': src, = op[1:] assert isinstance(src, (RegLoc, StackLoc)) extrapushes.append(read(src)) elif op[0] == 'pop': dst, = op[1:] assert isinstance(dst, (RegLoc, StackLoc)) write(dst, extrapushes.pop()) elif op[0] == 'immedmem2mem': src, dst = op[1:] assert isinstance(src, ConstFloatLoc) assert isinstance(dst, StackLoc) write(dst, read(src, 8)) else: assert 0, "unknown op: %r" % (op, ) assert not extrapushes # for i, loc in enumerate(dst_locations1): assert read(loc, WORD) == src_values1[i] for i, loc in enumerate(dst_locations2): assert read(loc, 8) == src_values2[i]
def test_mixed(): assembler = MockAssembler() s23 = frame_pos(2, FLOAT) # non-conflicting locations s4 = frame_pos(4, INT) remap_frame_layout_mixed(assembler, [ebx], [s4], 'tmp', [s23], [xmm5], 'xmmtmp') assert assembler.ops == [('mov', ebx, s4), ('mov', s23, xmm5)] # if IS_X86_32: assembler = MockAssembler() s23 = frame_pos(2, FLOAT) # gets stored in pos 2 and 3, with value==3 s3 = frame_pos(3, INT) remap_frame_layout_mixed(assembler, [ebx], [s3], 'tmp', [s23], [xmm5], 'xmmtmp') assert assembler.ops == [('push', s23), ('mov', ebx, s3), ('pop', xmm5)] # assembler = MockAssembler() s23 = frame_pos(2, FLOAT) s2 = frame_pos(2, INT) remap_frame_layout_mixed(assembler, [ebx], [s2], 'tmp', [s23], [xmm5], 'xmmtmp') assert assembler.ops == [('push', s23), ('mov', ebx, s2), ('pop', xmm5)] # assembler = MockAssembler() s4 = frame_pos(4, INT) s45 = frame_pos(4, FLOAT) s1 = frame_pos(1, INT) remap_frame_layout_mixed(assembler, [s4], [s1], edi, [s23], [s45], xmm3) assert assembler.ops == [('mov', s4, edi), ('mov', edi, s1), ('mov', s23, xmm3), ('mov', xmm3, s45)] # assembler = MockAssembler() s4 = frame_pos(4, INT) s45 = frame_pos(4, FLOAT) remap_frame_layout_mixed(assembler, [s4], [s2], edi, [s23], [s45], xmm3) assert assembler.ops == [('push', s23), ('mov', s4, edi), ('mov', edi, s2), ('pop', s45)] # if IS_X86_32: assembler = MockAssembler() remap_frame_layout_mixed(assembler, [s4], [s3], edi, [s23], [s45], xmm3) assert assembler.ops == [('push', s23), ('mov', s4, edi), ('mov', edi, s3), ('pop', s45)]