Author: Armin Rigo <ar...@tunes.org> Branch: guard-compatible Changeset: r84626:883cd4c3574e Date: 2016-05-23 16:56 +0200 http://bitbucket.org/pypy/pypy/changeset/883cd4c3574e/
Log: x86-32 support diff --git a/rpython/jit/backend/x86/guard_compat.py b/rpython/jit/backend/x86/guard_compat.py --- a/rpython/jit/backend/x86/guard_compat.py +++ b/rpython/jit/backend/x86/guard_compat.py @@ -10,7 +10,8 @@ from rpython.jit.backend.llsupport import jitframe from rpython.jit.backend.x86 import rx86, codebuf, regloc from rpython.jit.backend.x86.regalloc import gpr_reg_mgr_cls -from rpython.jit.backend.x86.arch import WORD, DEFAULT_FRAME_BYTES +from rpython.jit.backend.x86.arch import WORD, IS_X86_64, IS_X86_32 +from rpython.jit.backend.x86.arch import DEFAULT_FRAME_BYTES # @@ -383,6 +384,7 @@ mc.overwrite(jmp_location-1, chr(offset)) def setup_once(assembler): + """Generate the 'search_tree' block of code""" rax = regloc.eax.value rdx = regloc.edx.value rdi = regloc.edi.value @@ -394,40 +396,53 @@ mc = codebuf.MachineCodeBlockWrapper() mc.force_frame_size(frame_size) + if IS_X86_32: # save edi as an extra scratch register + mc.MOV_sr(3*WORD, rdi) + r11 = rdi # r11 doesn't exist on 32-bit, use "edi" instead ofs1 = _real_number(BCLIST + BCLISTLENGTHOFS) ofs2 = _real_number(BCLIST + BCLISTITEMSOFS) - mc.MOV_sr(16, rdx) # MOV [RSP+16], RDX + mc.MOV_sr(2*WORD, rdx) # MOV [RSP+16], RDX mc.MOV_rm(r11, (rdx, ofs1)) # MOV R11, [RDX + bc_list.length] mc.ADD_ri(rdx, ofs2) # ADD RDX, $bc_list.items mc.JMP_l8(0) # JMP loop jmp_location = mc.get_relative_pos() mc.force_frame_size(frame_size) + SH = 3 if IS_X86_64 else 2 + right_label = mc.get_relative_pos() - mc.LEA_ra(rdx, (rdx, r11, 3, 8)) # LEA RDX, [RDX + 8*R11 + 8] + mc.LEA_ra(rdx, (rdx, r11, SH, WORD)) # LEA RDX, [RDX + 8*R11 + 8] left_label = mc.get_relative_pos() mc.SHR_ri(r11, 1) # SHR R11, 1 mc.J_il8(rx86.Conditions['Z'], 0) # JZ not_found jz_location = mc.get_relative_pos() _fix_forward_label(mc, jmp_location) # loop: - mc.CMP_ra(rax, (rdx, r11, 3, -8)) # CMP RAX, [RDX + 8*R11 - 8] + mc.CMP_ra(rax, (rdx, r11, SH, -WORD)) # CMP RAX, [RDX + 8*R11 - 8] mc.J_il8(rx86.Conditions['A'], right_label - (mc.get_relative_pos() + 2)) mc.J_il8(rx86.Conditions['NE'], left_label - (mc.get_relative_pos() + 2)) - mc.MOV_ra(r11, (rdx, r11, 3, 0)) # MOV R11, [RDX + 8*R11] - mc.MOV_rs(rdx, 16) # MOV RDX, [RSP+16] + mc.MOV_ra(r11, (rdx, r11, SH, 0)) # MOV R11, [RDX + 8*R11] + mc.MOV_rs(rdx, 2*WORD) # MOV RDX, [RSP+16] ofs = _real_number(BCMOSTRECENT) mc.MOV_mr((rdx, ofs), rax) # MOV [RDX+bc_most_recent], RAX - mc.MOV_mr((rdx, ofs + 8), r11) # MOV [RDX+bc_most_recent+8], R11 + mc.MOV_mr((rdx, ofs+WORD), r11) # MOV [RDX+bc_most_recent+8], R11 mc.POP_r(rax) # POP RAX mc.POP_r(rdx) # POP RDX - mc.JMP_r(r11) # JMP *R11 + if IS_X86_64: + mc.JMP_r(r11) # JMP *R11 + elif IS_X86_32: + mc.MOV_sr(0, r11) # r11==rdi here + mc.MOV_rs(rdi, WORD) + mc.JMP_s(0) mc.force_frame_size(frame_size) _fix_forward_label(mc, jz_location) # not_found: + if IS_X86_32: + mc.MOV_rs(rdi, 3*WORD) + # read and pop the original RAX and RDX off the stack base_ofs = assembler.cpu.get_baseofs_of_frame_field() v = gpr_reg_mgr_cls.all_reg_indexes[rax] @@ -438,22 +453,34 @@ assembler._push_all_regs_to_frame(mc, [regloc.eax, regloc.edx], withfloats=True) - mc.MOV_rs(rdi, 0) # MOV RDI, [RSP] - mc.MOV_rr(regloc.esi.value, rax) # MOV RSI, RAX - mc.MOV_rr(regloc.edx.value, # MOV RDX, RBP - regloc.ebp.value) + if IS_X86_64: + mc.MOV_rs(rdi, 0) # MOV RDI, [RSP] + mc.MOV_rr(regloc.esi.value, rax) # MOV RSI, RAX + mc.MOV_rr(regloc.edx.value, # MOV RDX, RBP + regloc.ebp.value) + elif IS_X86_32: + # argument #1 is already in [ESP] + mc.MOV_sr(1 * WORD, rax) + mc.MOV_sr(2 * WORD, regloc.ebp.value) + invoke_find_compatible = make_invoke_find_compatible(assembler.cpu) llfunc = llhelper(INVOKE_FIND_COMPATIBLE_FUNC, invoke_find_compatible) llfunc = assembler.cpu.cast_ptr_to_int(llfunc) mc.CALL(regloc.imm(llfunc)) # CALL invoke_find_compatible assembler._reload_frame_if_necessary(mc) - mc.MOV_rr(r11, rax) # MOV R11, RAX + if IS_X86_64: + mc.MOV_rr(r11, rax) # MOV R11, RAX + elif IS_X86_32: + mc.MOV_sr(0, rax) # restore the registers that the CALL has clobbered, plus the ones # containing GC pointers that may have moved. That means we just - # restore them all. (We restore RAX and RDX too.) + # restore them all. (We restore RAX and RDX and RDI too.) assembler._pop_all_regs_from_frame(mc, [], withfloats=True) - mc.JMP_r(r11) # JMP *R11 + if IS_X86_64: + mc.JMP_r(r11) # JMP *R11 + elif IS_X86_32: + mc.JMP_s(0) assembler.guard_compat_search_tree = mc.materialize(assembler.cpu, []) diff --git a/rpython/jit/backend/x86/rx86.py b/rpython/jit/backend/x86/rx86.py --- a/rpython/jit/backend/x86/rx86.py +++ b/rpython/jit/backend/x86/rx86.py @@ -671,6 +671,7 @@ JM1_l = insn('\xE9', relative(1)) JM1_r = insn(rex_nw, '\xFF', orbyte(4<<3), register(1), '\xC0') JM1_m = insn(rex_nw, '\xFF', orbyte(4<<3), mem_reg_plus_const(1)) + JM1_s = insn(rex_nw, '\xFF', orbyte(4<<3), stack_sp(1)) # FIXME: J_il8 and JMP_l8 assume the caller will do the appropriate # calculation to find the displacement, but J_il does it for the caller. # We need to be consistent. @@ -693,6 +694,11 @@ if not we_are_translated(): self._frame_size = None + def JMP_s(self, ofs): + self.JM1_s(ofs) + if not we_are_translated(): + self._frame_size = None + def JMP_l8(self, rel): self.JM1_l8(rel) if not we_are_translated(): diff --git a/rpython/jit/backend/x86/test/test_compatible.py b/rpython/jit/backend/x86/test/test_compatible.py --- a/rpython/jit/backend/x86/test/test_compatible.py +++ b/rpython/jit/backend/x86/test/test_compatible.py @@ -77,14 +77,19 @@ for i in range(4 * WORD): mc.writechar('\x00') # 4 gctable entries; 'bchoices' will be #3 # + if IS_X86_64: + mc.MOV(regloc.edx, regloc.edi) + mc.MOV(regloc.eax, regloc.esi) + elif IS_X86_32: + mc.MOV_rs(regloc.edx.value, 4) + mc.MOV_rs(regloc.eax.value, 8) + # mc.PUSH(regloc.ebp) mc.SUB(regloc.esp, regloc.imm(448 - 2*WORD)) # make a frame, and align stack mc.LEA_rs(regloc.ebp.value, 48) # mc.PUSH(regloc.imm(0xdddd)) mc.PUSH(regloc.imm(0xaaaa)) - mc.MOV(regloc.edx, regloc.edi) - mc.MOV(regloc.eax, regloc.esi) mc.JMP(regloc.imm(cpu.assembler.guard_compat_search_tree)) sequel = mc.get_relative_pos() # _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit