[pypy-commit] pypy r15-for-exception: Fix the x86 backend to not touch r15 for normal usage, but handle
arigo
noreply at buildbot.pypy.org
Sat Jul 9 12:07:27 CEST 2011
Author: Armin Rigo <arigo at tunes.org>
Branch: r15-for-exception
Changeset: r45434:83b783be61f3
Date: 2011-07-09 12:16 +0200
http://bitbucket.org/pypy/pypy/changeset/83b783be61f3/
Log: Fix the x86 backend to not touch r15 for normal usage, but handle it
as the exception marker.
diff --git a/pypy/jit/backend/llsupport/llmodel.py b/pypy/jit/backend/llsupport/llmodel.py
--- a/pypy/jit/backend/llsupport/llmodel.py
+++ b/pypy/jit/backend/llsupport/llmodel.py
@@ -116,9 +116,12 @@
self.pos_exc_value = pos_exc_value
self.save_exception = save_exception
self.insert_stack_check = lambda: (0, 0, 0)
+ self.special_register = None
def _setup_exception_handling_translated(self):
+ from pypy.rlib import register
+ from pypy.rlib.register import register_number
def pos_exception():
addr = llop.get_exception_addr(llmemory.Address)
@@ -129,6 +132,8 @@
return heaptracker.adr2int(addr)
def save_exception():
+ if register_number is not None:
+ register.store_into_reg(register.nonnull)
addr = llop.get_exception_addr(llmemory.Address)
addr.address[0] = llmemory.NULL
addr = llop.get_exc_value_addr(llmemory.Address)
@@ -153,6 +158,9 @@
self.pos_exc_value = pos_exc_value
self.save_exception = save_exception
self.insert_stack_check = insert_stack_check
+ self.special_register = register_number
+ self.special_register_nonnull = llmemory.cast_adr_to_int(
+ register.nonnull)
def _setup_on_leave_jitted_untranslated(self):
# assume we don't need a backend leave in this case
diff --git a/pypy/jit/backend/x86/arch.py b/pypy/jit/backend/x86/arch.py
--- a/pypy/jit/backend/x86/arch.py
+++ b/pypy/jit/backend/x86/arch.py
@@ -6,6 +6,8 @@
# during a malloc that needs to go via its slow path.
import sys
+from pypy.rlib.register import register_number as special_register
+
if sys.maxint == (2**31 - 1):
WORD = 4
# ebp + ebx + esi + edi + 4 extra words + force_index = 9 words
@@ -14,16 +16,23 @@
MY_COPY_OF_REGS = -7*WORD
IS_X86_32 = True
IS_X86_64 = False
+ assert special_register is None
else:
WORD = 8
- # rbp + rbx + r12 + r13 + r14 + r15 + 11 extra words + force_index = 18
+ # rbp + rbx + r12 + r13 + r14 + r15? + 11 extra words + force_index = 18
FRAME_FIXED_SIZE = 18
FORCE_INDEX_OFS = -17*WORD
MY_COPY_OF_REGS = -16*WORD
IS_X86_32 = False
IS_X86_64 = True
+ if special_register is not None:
+ assert special_register == 15
+ # remove r15 from the saved registers and from the extra words
+ FRAME_FIXED_SIZE = 16
+ FORCE_INDEX_OFS = -15*WORD
+ MY_COPY_OF_REGS = -14*WORD
# The extra space has room for almost all registers, apart from eax and edx
# which are used in the malloc itself. They are:
# ecx, ebx, esi, edi [32 and 64 bits]
-# r8, r9, r10, r12, r13, r14, r15 [64 bits only]
+# r8, r9, r10, r12, r13, r14, r15? [64 bits only]
diff --git a/pypy/jit/backend/x86/assembler.py b/pypy/jit/backend/x86/assembler.py
--- a/pypy/jit/backend/x86/assembler.py
+++ b/pypy/jit/backend/x86/assembler.py
@@ -263,9 +263,14 @@
# esp is now aligned to a multiple of 16 again
mc.CALL(imm(slowpathaddr))
#
- mc.MOV(eax, heap(self.cpu.pos_exception()))
- mc.TEST_rr(eax.value, eax.value)
- mc.J_il8(rx86.Conditions['NZ'], 0)
+ if self.cpu.special_register is None:
+ mc.MOV(eax, heap(self.cpu.pos_exception()))
+ mc.TEST_rr(eax.value, eax.value)
+ mc.J_il8(rx86.Conditions['NZ'], 0)
+ else:
+ rnum = self.cpu.special_register
+ mc.TEST_rr(rnum, rnum)
+ mc.J_il8(rx86.Conditions['Z'], 0)
jnz_location = mc.get_relative_pos()
#
if IS_X86_32:
@@ -286,8 +291,7 @@
mc.overwrite(jnz_location-1, chr(offset))
# clear the exception from the global position
mc.MOV(eax, heap(self.cpu.pos_exc_value()))
- mc.MOV(heap(self.cpu.pos_exception()), imm0)
- mc.MOV(heap(self.cpu.pos_exc_value()), imm0)
+ self.clear_current_exception(mc)
# save the current exception instance into fail_boxes_ptr[0]
adr = self.fail_boxes_ptr.get_addr_for_num(0)
mc.MOV(heap(adr), eax)
@@ -308,6 +312,13 @@
rawstart = mc.materialize(self.cpu.asmmemmgr, [])
self.stack_check_slowpath = rawstart
+ def clear_current_exception(self, mc):
+ if self.cpu.special_register is not None:
+ mc.MOV_ri(self.cpu.special_register,
+ self.cpu.special_register_nonnull)
+ mc.MOV(heap(self.cpu.pos_exception()), imm0)
+ mc.MOV(heap(self.cpu.pos_exc_value()), imm0)
+
@staticmethod
def _release_gil_asmgcc(css):
# similar to trackgcroot.py:pypy_asm_stackwalk, first part
@@ -1563,8 +1574,13 @@
def genop_guard_guard_no_exception(self, ign_1, guard_op, guard_token,
locs, ign_2):
- self.mc.CMP(heap(self.cpu.pos_exception()), imm0)
- self.implement_guard(guard_token, 'NZ')
+ if self.cpu.special_register is None:
+ self.mc.CMP(heap(self.cpu.pos_exception()), imm0)
+ self.implement_guard(guard_token, 'NZ')
+ else:
+ rnum = self.cpu.special_register
+ self.mc.TEST_rr(rnum, rnum)
+ self.implement_guard(guard_token, 'Z')
def genop_guard_guard_not_invalidated(self, ign_1, guard_op, guard_token,
locs, ign_2):
@@ -1575,14 +1591,11 @@
def genop_guard_guard_exception(self, ign_1, guard_op, guard_token,
locs, resloc):
loc = locs[0]
- loc1 = locs[1]
- self.mc.MOV(loc1, heap(self.cpu.pos_exception()))
- self.mc.CMP(loc1, loc)
+ self.mc.CMP(heap(self.cpu.pos_exception()), loc)
self.implement_guard(guard_token, 'NE')
if resloc is not None:
self.mc.MOV(resloc, heap(self.cpu.pos_exc_value()))
- self.mc.MOV(heap(self.cpu.pos_exception()), imm0)
- self.mc.MOV(heap(self.cpu.pos_exc_value()), imm0)
+ self.clear_current_exception(self.mc)
def _gen_guard_overflow(self, guard_op, guard_token):
guard_opnum = guard_op.getopnum()
diff --git a/pypy/jit/backend/x86/regalloc.py b/pypy/jit/backend/x86/regalloc.py
--- a/pypy/jit/backend/x86/regalloc.py
+++ b/pypy/jit/backend/x86/regalloc.py
@@ -19,7 +19,7 @@
from pypy.jit.backend.llsupport.descr import BaseCallDescr, BaseSizeDescr
from pypy.jit.backend.llsupport.regalloc import FrameManager, RegisterManager,\
TempBox
-from pypy.jit.backend.x86.arch import WORD, FRAME_FIXED_SIZE
+from pypy.jit.backend.x86.arch import WORD, FRAME_FIXED_SIZE, special_register
from pypy.jit.backend.x86.arch import IS_X86_32, IS_X86_64, MY_COPY_OF_REGS
from pypy.rlib.rarithmetic import r_longlong, r_uint
@@ -56,8 +56,11 @@
not_implemented("convert_to_imm: got a %s" % c)
class X86_64_RegisterManager(X86RegisterManager):
- # r11 omitted because it's used as scratch
- all_regs = [eax, ecx, edx, ebx, esi, edi, r8, r9, r10, r12, r13, r14, r15]
+ # r11 omitted because it's used as scratch; r15 is omitted if used
+ # as a special register
+ all_regs = [eax, ecx, edx, ebx, esi, edi, r8, r9, r10, r12, r13, r14]
+ if special_register is None:
+ all_regs.append(r15)
no_lower_byte_regs = []
save_around_call_regs = [eax, ecx, edx, esi, edi, r8, r9, r10]
@@ -79,8 +82,9 @@
r12: MY_COPY_OF_REGS + 7 * WORD,
r13: MY_COPY_OF_REGS + 8 * WORD,
r14: MY_COPY_OF_REGS + 9 * WORD,
- r15: MY_COPY_OF_REGS + 10 * WORD,
}
+ if special_register is None:
+ REGLOC_TO_COPY_AREA_OFS[r15] = MY_COPY_OF_REGS + 10 * WORD
class X86XMMRegisterManager(RegisterManager):
@@ -518,17 +522,13 @@
def consider_guard_exception(self, op):
loc = self.rm.make_sure_var_in_reg(op.getarg(0))
- box = TempBox()
- args = op.getarglist()
- loc1 = self.rm.force_allocate_reg(box, args)
if op.result in self.longevity:
# this means, is it ever used
- resloc = self.rm.force_allocate_reg(op.result, args + [box])
+ resloc = self.rm.force_allocate_reg(op.result)
else:
resloc = None
- self.perform_guard(op, [loc, loc1], resloc)
+ self.perform_guard(op, [loc], resloc)
self.rm.possibly_free_vars_for_op(op)
- self.rm.possibly_free_var(box)
consider_guard_no_overflow = consider_guard_no_exception
consider_guard_overflow = consider_guard_no_exception
diff --git a/pypy/jit/backend/x86/runner.py b/pypy/jit/backend/x86/runner.py
--- a/pypy/jit/backend/x86/runner.py
+++ b/pypy/jit/backend/x86/runner.py
@@ -5,7 +5,7 @@
from pypy.rlib.objectmodel import we_are_translated
from pypy.jit.metainterp import history, compile
from pypy.jit.backend.x86.assembler import Assembler386
-from pypy.jit.backend.x86.arch import FORCE_INDEX_OFS
+from pypy.jit.backend.x86.arch import FORCE_INDEX_OFS, special_register
from pypy.jit.backend.x86.profagent import ProfileAgent
from pypy.jit.backend.llsupport.llmodel import AbstractLLCPU
from pypy.jit.backend.x86 import regloc
@@ -205,7 +205,9 @@
backend_name = 'x86_64'
WORD = 8
NUM_REGS = 16
- CALLEE_SAVE_REGISTERS = [regloc.ebx, regloc.r12, regloc.r13, regloc.r14, regloc.r15]
+ CALLEE_SAVE_REGISTERS = [regloc.ebx, regloc.r12, regloc.r13, regloc.r14]
+ if special_register is None:
+ CALLEE_SAVE_REGISTERS.append(regloc.r15)
def __init__(self, *args, **kwargs):
assert sys.maxint == (2**63 - 1)
More information about the pypy-commit
mailing list