Author: Armin Rigo <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit