Author: David Schneider <david.schnei...@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]. _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit