[pypy-commit] pypy fast-slowpath: be clear about conditional_call limitations. Also try to support 32bit (untested
fijal
noreply at buildbot.pypy.org
Wed Jul 24 16:04:36 CEST 2013
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: fast-slowpath
Changeset: r65605:26be63cd3453
Date: 2013-07-24 16:03 +0200
http://bitbucket.org/pypy/pypy/changeset/26be63cd3453/
Log: be clear about conditional_call limitations. Also try to support
32bit (untested so far)
diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py
--- a/rpython/jit/backend/x86/assembler.py
+++ b/rpython/jit/backend/x86/assembler.py
@@ -155,11 +155,19 @@
"""
mc = codebuf.MachineCodeBlockWrapper()
self._push_all_regs_to_frame(mc, [], supports_floats, callee_only)
- mc.SUB(esp, imm(WORD))
+ if self.cpu.IS_X86_64:
+ mc.SUB(esp, imm(WORD))
+ else:
+ # we want space for 3 arguments + call + alignment
+ # the caller is responsible for putting arguments in the right spot
+ mc.SUB(esp, imm(WORD * 7))
self.set_extra_stack_depth(mc, 2 * WORD)
# args are in their respective positions
mc.CALL(eax)
- mc.ADD(esp, imm(WORD))
+ if self.cpu.IS_X86_64:
+ mc.ADD(esp, imm(WORD))
+ else:
+ mc.ADD(esp, imm(WORD * 7))
self.set_extra_stack_depth(mc, 0)
self._reload_frame_if_necessary(mc, align_stack=True)
self._pop_all_regs_from_frame(mc, [], supports_floats,
@@ -2144,7 +2152,7 @@
def label(self):
self._check_frame_depth_debug(self.mc)
- def cond_call(self, op, gcmap, cond_loc, call_loc):
+ def cond_call(self, op, gcmap, cond_loc, call_loc, arglocs):
self.mc.TEST(cond_loc, cond_loc)
self.mc.J_il8(rx86.Conditions['Z'], 0) # patched later
jmp_adr = self.mc.get_relative_pos()
@@ -2160,6 +2168,12 @@
if self._regalloc.xrm.reg_bindings:
floats = True
cond_call_adr = self.cond_call_slowpath[floats * 2 + callee_only]
+ if self.cpu.IS_X86_32:
+ p = -7 * WORD
+ for i in range(len(arglocs) - 1, -1, -1):
+ loc = arglocs[i]
+ self.mc.MOV(RawEspLoc(p), loc)
+ p += WORD
self.mc.CALL(imm(cond_call_adr))
self.pop_gcmap(self.mc)
# never any result value
diff --git a/rpython/jit/backend/x86/regalloc.py b/rpython/jit/backend/x86/regalloc.py
--- a/rpython/jit/backend/x86/regalloc.py
+++ b/rpython/jit/backend/x86/regalloc.py
@@ -809,12 +809,18 @@
imm = self.rm.convert_to_imm(v)
self.assembler.regalloc_mov(imm, eax)
args_so_far = [tmpbox]
+ locs = []
for i in range(2, len(args)):
- reg = self.rm.register_arguments[i - 2]
- self.make_sure_var_in_reg(args[i], args_so_far, selected_reg=reg)
+ if self.cpu.IS_X86_64:
+ reg = self.rm.register_arguments[i - 2]
+ self.make_sure_var_in_reg(args[i], args_so_far, selected_reg=reg)
+ else:
+ loc = self.make_sure_var_in_reg(args[i], args_so_far)
+ locs.append(loc)
args_so_far.append(args[i])
loc_cond = self.make_sure_var_in_reg(args[0], args)
- self.assembler.cond_call(op, self.get_gcmap([eax]), loc_cond, eax)
+ self.assembler.cond_call(op, self.get_gcmap([eax]), loc_cond, eax,
+ locs)
self.rm.possibly_free_var(tmpbox)
def consider_call_malloc_nursery(self, op):
diff --git a/rpython/jit/codewriter/jtransform.py b/rpython/jit/codewriter/jtransform.py
--- a/rpython/jit/codewriter/jtransform.py
+++ b/rpython/jit/codewriter/jtransform.py
@@ -1355,6 +1355,13 @@
return getattr(self, 'handle_jit_marker__%s' % key)(op, jitdriver)
def rewrite_op_jit_conditional_call(self, op):
+ have_floats = False
+ for arg in op.args:
+ if getkind(arg.concretetype) == 'float':
+ have_floats = True
+ break
+ if len(op.args) > 4 + 2 or have_floats:
+ raise Exception("Conditional call does not support floats or more than 4 arguments")
callop = SpaceOperation('direct_call', op.args[1:], op.result)
calldescr = self.callcontrol.getcalldescr(callop)
assert not calldescr.get_extra_info().check_forces_virtual_or_virtualizable()
diff --git a/rpython/rtyper/lltypesystem/lloperation.py b/rpython/rtyper/lltypesystem/lloperation.py
--- a/rpython/rtyper/lltypesystem/lloperation.py
+++ b/rpython/rtyper/lltypesystem/lloperation.py
@@ -350,7 +350,7 @@
'lllong_lshift': LLOp(canfold=True), # args (r_longlonglong, int)
'lllong_rshift': LLOp(canfold=True), # args (r_longlonglong, int)
'lllong_xor': LLOp(canfold=True),
-
+
'cast_primitive': LLOp(canfold=True),
'cast_bool_to_int': LLOp(canfold=True),
'cast_bool_to_uint': LLOp(canfold=True),
@@ -457,6 +457,7 @@
'jit_force_quasi_immutable': LLOp(canrun=True),
'jit_record_known_class' : LLOp(canrun=True),
'jit_ffi_save_result': LLOp(canrun=True),
+ 'jit_conditional_call': LLOp(),
'get_exception_addr': LLOp(),
'get_exc_value_addr': LLOp(),
'do_malloc_fixedsize_clear':LLOp(canmallocgc=True),
diff --git a/rpython/translator/c/funcgen.py b/rpython/translator/c/funcgen.py
--- a/rpython/translator/c/funcgen.py
+++ b/rpython/translator/c/funcgen.py
@@ -29,7 +29,7 @@
__slots__ = """graph db gcpolicy
exception_policy
more_ll_values
- vars all_cached_consts
+ vars all_cached_consts
illtypes
functionname
blocknum
@@ -59,7 +59,7 @@
if isinstance(T, Ptr) and T.TO.__class__ == ForwardReference:
continue
db.gettype(T) # force the type to be considered by the database
-
+
self.illtypes = None
def collect_var_and_types(self):
@@ -90,7 +90,7 @@
for cleanupop in exc_cleanup_ops:
mix.extend(cleanupop.args)
mix.append(cleanupop.result)
-
+
uniquemix = []
seen = identity_dict()
for v in mix:
@@ -454,6 +454,9 @@
fnexpr = '((%s)%s)' % (cdecl(typename, ''), self.expr(fnaddr))
return self.generic_call(FUNC, fnexpr, op.args[1:], op.result)
+ def OP_JIT_CONDITIONAL_CALL(self, op):
+ return ''
+
# low-level operations
def generic_get(self, op, sourceexpr):
T = self.lltypemap(op.result)
@@ -580,7 +583,7 @@
def OP_PTR_ISZERO(self, op):
return '%s = (%s == NULL);' % (self.expr(op.result),
self.expr(op.args[0]))
-
+
def OP_PTR_EQ(self, op):
return '%s = (%s == %s);' % (self.expr(op.result),
self.expr(op.args[0]),
@@ -627,7 +630,7 @@
ARRAY = self.lltypemap(op.args[0]).TO
if ARRAY._hints.get("render_as_void"):
return '%s = (char *)%s + %s;' % (
- self.expr(op.result),
+ self.expr(op.result),
self.expr(op.args[0]),
self.expr(op.args[1]))
else:
@@ -652,7 +655,7 @@
def OP_CAST_INT_TO_PTR(self, op):
TYPE = self.lltypemap(op.result)
typename = self.db.gettype(TYPE)
- return "%s = (%s)%s;" % (self.expr(op.result), cdecl(typename, ""),
+ return "%s = (%s)%s;" % (self.expr(op.result), cdecl(typename, ""),
self.expr(op.args[0]))
def OP_SAME_AS(self, op):
@@ -711,7 +714,7 @@
val = "(unsigned char)%s" % val
elif ORIG is UniChar:
val = "(unsigned long)%s" % val
- typename = cdecl(self.db.gettype(TYPE), '')
+ typename = cdecl(self.db.gettype(TYPE), '')
return "%(result)s = (%(typename)s)(%(val)s);" % locals()
OP_FORCE_CAST = OP_CAST_PRIMITIVE # xxx the same logic works
@@ -823,7 +826,7 @@
counter_label+1)
counter_label = self.expr(op.args[1])
return 'PYPY_INSTRUMENT_COUNT(%s);' % counter_label
-
+
def OP_IS_EARLY_CONSTANT(self, op):
return '%s = 0; /* IS_EARLY_CONSTANT */' % (self.expr(op.result),)
More information about the pypy-commit
mailing list