[pypy-commit] pypy emit-call-arm: start extracting an interface from x86/callbuilder.py
bivab
noreply at buildbot.pypy.org
Wed May 22 15:46:58 CEST 2013
Author: David Schneider <david.schneider at picle.org>
Branch: emit-call-arm
Changeset: r64451:1e10efb3ccd5
Date: 2013-05-22 08:12 -0500
http://bitbucket.org/pypy/pypy/changeset/1e10efb3ccd5/
Log: start extracting an interface from x86/callbuilder.py
diff --git a/rpython/jit/backend/llsupport/callbuilder.py b/rpython/jit/backend/llsupport/callbuilder.py
new file mode 100644
--- /dev/null
+++ b/rpython/jit/backend/llsupport/callbuilder.py
@@ -0,0 +1,75 @@
+from rpython.rlib.clibffi import FFI_DEFAULT_ABI
+
+class AbstractCallBuilder(object):
+
+ # this is the calling convention (can be FFI_STDCALL on Windows)
+ callconv = FFI_DEFAULT_ABI
+
+ # is it for the main CALL of a call_release_gil?
+ is_call_release_gil = False
+
+ # set by save_result_value()
+ tmpresloc = None
+
+ def __init__(self, assembler, fnloc, arglocs, resloc, restype, ressize):
+ # Avoid tons of issues with a non-immediate fnloc by sticking it
+ # as an extra argument if needed
+ self.fnloc = fnloc
+ self.arglocs = arglocs
+ self.asm = assembler
+ self.mc = assembler.mc
+ self.resloc = resloc
+ self.restype = restype
+ self.ressize = ressize
+ self.ressigned = False
+
+ def emit_no_collect(self):
+ """Emit a call that cannot collect."""
+ self.prepare_arguments()
+ self.emit_raw_call()
+ self.restore_stack_pointer()
+ self.load_result()
+
+ def emit(self):
+ """Emit a regular call; not for CALL_RELEASE_GIL."""
+ self.prepare_arguments()
+ self.push_gcmap()
+ self.emit_raw_call()
+ self.restore_stack_pointer()
+ self.pop_gcmap()
+ self.load_result()
+
+ def emit_call_release_gil(self):
+ """Emit a CALL_RELEASE_GIL, including calls to releasegil_addr
+ and reacqgil_addr."""
+ self.select_call_release_gil_mode()
+ self.prepare_arguments()
+ self.push_gcmap_for_call_release_gil()
+ self.call_releasegil_addr_and_move_real_arguments()
+ self.emit_raw_call()
+ self.restore_stack_pointer()
+ self.move_real_result_and_call_reacqgil_addr()
+ self.pop_gcmap()
+ self.load_result()
+
+ def select_call_release_gil_mode(self):
+ """Overridden in CallBuilder64"""
+ self.is_call_release_gil = True
+
+ def prepare_arguments(self):
+ raise NotImplementedError
+
+ def push_gcmap(self):
+ raise NotImplementedError
+
+ def pop_gcmap(self):
+ raise NotImplementedError
+
+ def emit_raw_call(self):
+ raise NotImplementedError
+
+ def restore_stack_pointer(self):
+ raise NotImplementedError
+
+ def load_result(self):
+ raise NotImplementedError
diff --git a/rpython/jit/backend/x86/callbuilder.py b/rpython/jit/backend/x86/callbuilder.py
--- a/rpython/jit/backend/x86/callbuilder.py
+++ b/rpython/jit/backend/x86/callbuilder.py
@@ -8,6 +8,7 @@
r12, r13, r14, r15, X86_64_SCRATCH_REG, X86_64_XMM_SCRATCH_REG,
RegLoc, RawEspLoc, RawEbpLoc, imm, ImmedLoc)
from rpython.jit.backend.x86.jump import remap_frame_layout
+from rpython.jit.backend.llsupport.callbuilder import AbstractCallBuilder
# darwin requires the stack to be 16 bytes aligned on calls.
@@ -19,7 +20,8 @@
-class AbstractCallBuilder(object):
+
+class CallBuilderX86(AbstractCallBuilder):
# max number of words we have room in esp; if we need more for
# arguments, we need to decrease esp temporarily
@@ -30,65 +32,19 @@
argtypes = ""
ressign = False
- # this is the calling convention (can be FFI_STDCALL on Windows)
- callconv = FFI_DEFAULT_ABI
-
- # is it for the main CALL of a call_release_gil?
- is_call_release_gil = False
-
- # set by save_result_value()
- tmpresloc = None
-
-
def __init__(self, assembler, fnloc, arglocs,
resloc=eax, restype=INT, ressize=WORD):
- # Avoid tons of issues with a non-immediate fnloc by sticking it
- # as an extra argument if needed
+ AbstractCallBuilder.__init__(self, assembler, fnloc, arglocs,
+ resloc, restype, ressize)
self.fnloc_is_immediate = isinstance(fnloc, ImmedLoc)
- if self.fnloc_is_immediate:
- self.fnloc = fnloc
- self.arglocs = arglocs
- else:
+ if not self.fnloc_is_immediate:
+ self.fnloc = None
self.arglocs = arglocs + [fnloc]
- self.asm = assembler
- self.mc = assembler.mc
- self.resloc = resloc
- self.restype = restype
- self.ressize = ressize
self.current_esp = 0 # 0 or (usually) negative, counted in bytes
- def emit_no_collect(self):
- """Emit a call that cannot collect."""
- self.prepare_arguments()
- self.emit_raw_call()
- self.restore_esp()
- self.load_result()
-
- def emit(self):
- """Emit a regular call; not for CALL_RELEASE_GIL."""
- self.prepare_arguments()
- self.push_gcmap()
- self.emit_raw_call()
- self.restore_esp()
- self.pop_gcmap()
- self.load_result()
-
- def emit_call_release_gil(self):
- """Emit a CALL_RELEASE_GIL, including calls to releasegil_addr
- and reacqgil_addr."""
- self.select_call_release_gil_mode()
- self.prepare_arguments()
- self.push_gcmap_for_call_release_gil()
- self.call_releasegil_addr_and_move_real_arguments()
- self.emit_raw_call()
- self.restore_esp()
- self.move_real_result_and_call_reacqgil_addr()
- self.pop_gcmap()
- self.load_result()
-
def select_call_release_gil_mode(self):
"""Overridden in CallBuilder64"""
- self.is_call_release_gil = True
+ AbstractCallBuilder.select_call_release_gil_mode(self)
if self.asm._is_asmgcc():
from rpython.memory.gctransform import asmgcroot
self.stack_max = PASS_ON_MY_FRAME - asmgcroot.JIT_USE_WORDS
@@ -105,7 +61,7 @@
self.current_esp -= align * WORD
self.mc.SUB_ri(esp.value, align * WORD)
- def restore_esp(self, target_esp=0):
+ def restore_stack_pointer(self, target_esp=0):
if self.current_esp != target_esp:
self.mc.ADD_ri(esp.value, target_esp - self.current_esp)
self.current_esp = target_esp
@@ -204,7 +160,7 @@
self.mc.ADD(ebp, imm(1)) # ebp any more
#
self.restore_register_arguments()
- self.restore_esp(initial_esp)
+ self.restore_stack_pointer(initial_esp)
def save_register_arguments(self):
"""Overridden in CallBuilder64"""
@@ -248,7 +204,7 @@
raise NotImplementedError
-class CallBuilder32(AbstractCallBuilder):
+class CallBuilder32(CallBuilderX86):
def prepare_arguments(self):
arglocs = self.arglocs
@@ -318,7 +274,7 @@
else:
self.mc.MOV(resloc, self.tmpresloc)
else:
- AbstractCallBuilder.load_result(self)
+ CallBuilderX86.load_result(self)
def save_result_value(self):
# Temporarily save the result value into [ESP+4]. We use "+4"
@@ -343,7 +299,7 @@
self.mc.MOV_sr(4, eax.value)
-class CallBuilder64(AbstractCallBuilder):
+class CallBuilder64(CallBuilderX86):
ARGUMENTS_GPR = [edi, esi, edx, ecx, r8, r9]
ARGUMENTS_XMM = [xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7]
@@ -389,7 +345,7 @@
i += 1
def select_call_release_gil_mode(self):
- AbstractCallBuilder.select_call_release_gil_mode(self)
+ CallBuilderX86.select_call_release_gil_mode(self)
# We have to copy the arguments around a bit more in this mode,
# but on the other hand we don't need prepare_arguments() moving
# them in precisely the final registers. Here we look around for
@@ -502,7 +458,7 @@
# from the lower 32 bits of XMM0
self.mc.MOVD(self.resloc, xmm0)
else:
- AbstractCallBuilder.load_result(self)
+ CallBuilderX86.load_result(self)
def save_result_value(self):
# Temporarily save the result value into [ESP].
More information about the pypy-commit
mailing list