Author: Maciej Fijalkowski <[email protected]>
Branch: jitframe-on-heap
Changeset: r60017:d6934bbf2a8a
Date: 2013-01-13 12:03 +0200
http://bitbucket.org/pypy/pypy/changeset/d6934bbf2a8a/
Log: fight with calls, not finished
diff --git a/pypy/jit/backend/test/runner_test.py
b/pypy/jit/backend/test/runner_test.py
--- a/pypy/jit/backend/test/runner_test.py
+++ b/pypy/jit/backend/test/runner_test.py
@@ -565,10 +565,11 @@
[funcbox, ConstInt(num), BoxInt(num)],
'int', descr=calldescr)
assert res.value == 2 * num
-
if cpu.supports_floats:
def func(f0, f1, f2, f3, f4, f5, f6, i0, f7, i1, f8, f9):
+ import pdb
+ pdb.set_trace()
return f0 + f1 + f2 + f3 + f4 + f5 + f6 + float(i0 + i1) + f7
+ f8 + f9
F = lltype.Float
I = lltype.Signed
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
@@ -43,8 +43,9 @@
# XXX FORCE_INDEX might need to go to GC frame
if WORD == 4:
+ # XXX rethink the fixed size
# ebp + ebx + esi + edi + 4 extra words + force_index = 9 words
- FRAME_FIXED_SIZE = 12 # 9 aligned to 16 bytes = 4 * WORD
+ FRAME_FIXED_SIZE = 6
FORCE_INDEX_OFS = 0
SAVED_REGISTERS = 1 # range(1, 5)
MY_COPY_OF_REGS = 5 # range(5, 9)
@@ -53,7 +54,7 @@
# reg, we don't save it
else:
# rbp + rbx + r12 + r13 + r14 + r15 + 11 extra words + force_index = 18
- FRAME_FIXED_SIZE = 18 # 18 aligned to 16 bytes = 2 * WORD
+ FRAME_FIXED_SIZE = 6
FORCE_INDEX_OFS = 0
SAVED_REGISTERS = 1 # range(1, 7)
MY_COPY_OF_REGS = 7 # range(7, 18)
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
@@ -18,7 +18,7 @@
xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, r8, r9, r10, r11,
r12, r13, r14, r15, X86_64_SCRATCH_REG, X86_64_XMM_SCRATCH_REG,
RegLoc, StackLoc, ConstFloatLoc, ImmedLoc, AddressLoc, imm,
- imm0, imm1, FloatImmedLoc, RawStackLoc)
+ imm0, imm1, FloatImmedLoc, RawStackLoc, RawEspLoc)
from pypy.rlib.objectmodel import we_are_translated, specialize
from pypy.jit.backend.x86 import rx86, codebuf
from pypy.jit.metainterp.resoperation import rop, ResOperation
@@ -749,9 +749,9 @@
def _call_header(self):
# NB. the shape of the frame is hard-coded in get_basic_shape() too.
# Also, make sure this is consistent with FRAME_FIXED_SIZE.
- self.mc.PUSH_r(ebp.value)
# XXX should be LEA?
- self.mc.ADD_ri(esp.value, FRAME_FIXED_SIZE * WORD)
+ self.mc.SUB_ri(esp.value, FRAME_FIXED_SIZE * WORD)
+ self.mc.MOV_sr(0, ebp.value)
if IS_X86_64:
descrs = self.cpu.gc_ll_descr.getframedescrs(self.cpu)
_, ofs, _ = unpack_arraydescr(descrs.arraydescr)
@@ -759,8 +759,8 @@
else:
xxx
- for loc in self.cpu.CALLEE_SAVE_REGISTERS:
- self.mc.PUSH_r(loc.value)
+ for i, loc in enumerate(self.cpu.CALLEE_SAVE_REGISTERS):
+ self.mc.MOV_sr((i + 1) * WORD, loc.value)
gcrootmap = self.cpu.gc_ll_descr.gcrootmap
if gcrootmap and gcrootmap.is_shadow_stack:
@@ -785,16 +785,16 @@
self._call_header()
def _call_footer(self):
- self.mc.SUB_ri(esp.value, FRAME_FIXED_SIZE * WORD)
-
gcrootmap = self.cpu.gc_ll_descr.gcrootmap
if gcrootmap and gcrootmap.is_shadow_stack:
self._call_footer_shadowstack(gcrootmap)
for i in range(len(self.cpu.CALLEE_SAVE_REGISTERS)-1, -1, -1):
- self.mc.POP_r(self.cpu.CALLEE_SAVE_REGISTERS[i].value)
+ self.mc.MOV_rs(self.cpu.CALLEE_SAVE_REGISTERS[i].value,
+ (i + 1) * WORD)
- self.mc.POP_r(ebp.value)
+ self.mc.MOV_rs(ebp.value, 0)
+ self.mc.ADD_ri(esp.value, FRAME_FIXED_SIZE * WORD)
self.mc.RET()
def _call_header_shadowstack(self, gcrootmap):
@@ -1056,7 +1056,7 @@
argtypes=None, callconv=FFI_DEFAULT_ABI):
if IS_X86_64:
return self._emit_call_64(force_index, x, arglocs, start, argtypes)
-
+ XXX
p = 0
n = len(arglocs)
for i in range(start, n):
@@ -1099,60 +1099,42 @@
dst_locs = []
xmm_src_locs = []
xmm_dst_locs = []
- pass_on_stack = []
singlefloats = None
# In reverse order for use with pop()
unused_gpr = [r9, r8, ecx, edx, esi, edi]
unused_xmm = [xmm7, xmm6, xmm5, xmm4, xmm3, xmm2, xmm1, xmm0]
+ on_stack = 0
for i in range(start, len(arglocs)):
loc = arglocs[i]
- # XXX: Should be much simplier to tell whether a location is a
- # float! It's so ugly because we have to "guard" the access to
- # .type with isinstance, since not all AssemblerLocation classes
- # are "typed"
- if ((isinstance(loc, RegLoc) and loc.is_xmm) or
- (isinstance(loc, StackLoc) and loc.type == FLOAT) or
- (isinstance(loc, ConstFloatLoc))):
+ if loc.is_float():
+ xmm_src_locs.append(loc)
if len(unused_xmm) > 0:
- xmm_src_locs.append(loc)
xmm_dst_locs.append(unused_xmm.pop())
else:
- pass_on_stack.append(loc)
+ xmm_dst_locs.append(RawEspLoc(on_stack * WORD, FLOAT))
+ on_stack += 1
elif argtypes is not None and argtypes[i-start] == 'S':
# Singlefloat argument
if len(unused_xmm) > 0:
- if singlefloats is None: singlefloats = []
+ if singlefloats is None:
+ singlefloats = []
singlefloats.append((loc, unused_xmm.pop()))
else:
- pass_on_stack.append(loc)
+ singlefloats.append((loc, RawEspLoc(on_stack * WORD, INT)))
+ on_stack += 1
else:
+ src_locs.append(loc)
if len(unused_gpr) > 0:
- src_locs.append(loc)
dst_locs.append(unused_gpr.pop())
else:
- pass_on_stack.append(loc)
+ dst_locs.append(RawEspLoc(on_stack * WORD, INT))
+ on_stack += 1
- # Emit instructions to pass the stack arguments
- # XXX: Would be nice to let remap_frame_layout take care of this, but
- # we'd need to create something like StackLoc, but relative to esp,
- # and I don't know if it's worth it.
- for i in range(len(pass_on_stack)):
- loc = pass_on_stack[i]
- if not isinstance(loc, RegLoc):
- if isinstance(loc, StackLoc) and loc.type == FLOAT:
- self.mc.MOVSD(X86_64_XMM_SCRATCH_REG, loc)
- self.mc.MOVSD_sx(i*WORD, X86_64_XMM_SCRATCH_REG.value)
- else:
- self.mc.MOV(X86_64_SCRATCH_REG, loc)
- self.mc.MOV_sr(i*WORD, X86_64_SCRATCH_REG.value)
- else:
- # It's a register
- if loc.is_xmm:
- self.mc.MOVSD_sx(i*WORD, loc.value)
- else:
- self.mc.MOV_sr(i*WORD, loc.value)
+ align = align_stack_words(on_stack)
+ if align:
+ self.mc.SUB_ri(esp.value, align * WORD)
# Handle register arguments: first remap the xmm arguments
remap_frame_layout(self, xmm_src_locs, xmm_dst_locs,
@@ -1172,10 +1154,11 @@
dst_locs.append(r10)
x = r10
remap_frame_layout(self, src_locs, dst_locs, X86_64_SCRATCH_REG)
-
+ # align
self.mc.CALL(x)
+ if align:
+ self.mc.ADD_ri(esp.value, align * WORD)
self.mark_gc_roots(force_index)
- self._regalloc.needed_extra_stack_locations(len(pass_on_stack))
def call(self, addr, args, res):
force_index = self.write_new_force_index()
diff --git a/pypy/jit/backend/x86/regloc.py b/pypy/jit/backend/x86/regloc.py
--- a/pypy/jit/backend/x86/regloc.py
+++ b/pypy/jit/backend/x86/regloc.py
@@ -53,7 +53,7 @@
self.type = type
def _getregkey(self):
- return -(self.value + 1)
+ return -(self.value * 2 + 2)
def get_width(self):
if self.type == FLOAT:
@@ -66,6 +66,36 @@
def assembler(self):
return repr(self)
+ def is_float(self):
+ return self.type == FLOAT
+
+class RawEspLoc(AssemblerLocation):
+ """ Esp-based location
+ """
+ _immutable_ = True
+ _location_code = 's'
+
+ def __init__(self, value, type):
+ self.value = value
+ self.type = type
+
+ def _getregkey(self):
+ return -(self.value * 2 + 1)
+
+ def get_width(self):
+ if self.type == FLOAT:
+ return 8
+ return WORD
+
+ def __repr__(self):
+ return '%d(%%esp)' % (self.value,)
+
+ def assembler(self):
+ return repr(self)
+
+ def is_float(self):
+ return self.type == FLOAT
+
class StackLoc(RawStackLoc):
def __init__(self, position, ebp_offset, type):
# _getregkey() returns self.value; the value returned must not
@@ -116,6 +146,9 @@
else:
return eax
+ def is_float(self):
+ return self.is_xmm
+
class ImmediateAssemblerLocation(AssemblerLocation):
_immutable_ = True
@@ -123,10 +156,11 @@
_immutable_ = True
_location_code = 'i'
- def __init__(self, value):
+ def __init__(self, value, is_float=False):
from pypy.rpython.lltypesystem import rffi, lltype
# force as a real int
self.value = rffi.cast(lltype.Signed, value)
+ self._is_float = is_float
def getint(self):
return self.value
@@ -143,6 +177,9 @@
val -= 0x100
return ImmedLoc(val)
+ def is_float(self):
+ return self._is_float
+
class AddressLoc(AssemblerLocation):
_immutable_ = True
@@ -177,6 +214,10 @@
def get_width(self):
return WORD
+ def is_float(self):
+ return False # not 100% true, but we don't use AddressLoc for locations
+ # really, so it's ok
+
def value_a(self):
return self.loc_a
@@ -224,6 +265,9 @@
def __repr__(self):
return '<ConstFloatLoc @%s>' % (self.value,)
+ def is_float(self):
+ return True
+
if IS_X86_32:
class FloatImmedLoc(ImmediateAssemblerLocation):
# This stands for an immediate float. It cannot be directly used in
@@ -255,11 +299,14 @@
floatvalue = longlong.getrealfloat(self.aslonglong)
return '<FloatImmedLoc(%s)>' % (floatvalue,)
+ def is_float(self):
+ return True
+
if IS_X86_64:
def FloatImmedLoc(floatstorage):
from pypy.rlib.longlong2float import float2longlong
value = intmask(float2longlong(floatstorage))
- return ImmedLoc(value)
+ return ImmedLoc(value, True)
REGLOCS = [RegLoc(i, is_xmm=False) for i in range(16)]
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit