[pypy-commit] pypy release-pypy2.7-5.x: solved the big endian issue in the ppc backend
plan_rich
pypy.commits at gmail.com
Tue Nov 8 13:53:24 EST 2016
Author: Richard Plangger <planrichi at gmail.com>
Branch: release-pypy2.7-5.x
Changeset: r88232:d8b224b914e8
Date: 2016-11-08 18:51 +0100
http://bitbucket.org/pypy/pypy/changeset/d8b224b914e8/
Log: solved the big endian issue in the ppc backend
diff --git a/rpython/jit/backend/ppc/vector_ext.py b/rpython/jit/backend/ppc/vector_ext.py
--- a/rpython/jit/backend/ppc/vector_ext.py
+++ b/rpython/jit/backend/ppc/vector_ext.py
@@ -230,26 +230,19 @@
self.mc.stvx(src, r.SCRATCH2.value, r.SP.value)
self.mc.load_imm(r.SCRATCH2, PARAM_SAVE_AREA_OFFSET+16)
self.mc.stvx(res, r.SCRATCH2.value, r.SP.value)
- for i in range(2): # at most 2 operations
- if IS_BIG_ENDIAN:
- srcoff = (i * osize)
- resoff = (i * nsize)
- else:
- if osize == 4:
- srcoff = 8 + (i * osize)
- resoff = (i * nsize)
- else:
- srcoff = (i * osize)
- resoff = 8 + (i * nsize)
- if osize == 8:
- self.mc.load(r.SCRATCH.value, r.SP.value, srcoff + PARAM_SAVE_AREA_OFFSET)
- else:
- self.mc.lwa(r.SCRATCH.value, r.SP.value, srcoff + PARAM_SAVE_AREA_OFFSET)
- if nsize == 8:
- self.mc.store(r.SCRATCH.value, r.SP.value, resoff + PARAM_SAVE_AREA_OFFSET+16)
- else:
- self.mc.stw(r.SCRATCH.value, r.SP.value, resoff + PARAM_SAVE_AREA_OFFSET+16)
-
+ for j in range(2): # at most 2 operations
+ off = PARAM_SAVE_AREA_OFFSET
+ i = j
+ if not IS_BIG_ENDIAN:
+ i = (16 // osize) - 1 - i
+ off += osize * i
+ self._load_from_sp(r.SCRATCH.value, osize, off)
+ off = PARAM_SAVE_AREA_OFFSET
+ i = j
+ if not IS_BIG_ENDIAN:
+ i = (16 // nsize) - 1 - i
+ off += nsize * i
+ self._store_to_sp(r.SCRATCH.value, nsize, off+16)
self.mc.lvx(res, r.SCRATCH2.value, r.SP.value)
def emit_vec_float_abs(self, op, arglocs, regalloc):
@@ -531,6 +524,37 @@
self.mc.stb(src, r.SP.value, PARAM_SAVE_AREA_OFFSET+idx)
self.mc.lvx(res, r.SCRATCH2.value, r.SP.value)
+ def _load_from_sp(self, res, size, off):
+ if size == 8:
+ self.mc.load(res, r.SP.value, off)
+ return True
+ elif size == 4:
+ self.mc.lwa(res, r.SP.value, off)
+ return True
+ elif size == 2:
+ self.mc.lha(res, r.SP.value, off)
+ return True
+ elif size == 1:
+ self.mc.lbz(res, r.SP.value, off)
+ self.mc.extsb(res, res)
+ return True
+ return False
+
+ def _store_to_sp(self, res, size, off):
+ if size == 8:
+ self.mc.store(res, r.SP.value, off)
+ return True
+ elif size == 4:
+ self.mc.stw(res, r.SP.value, off)
+ return True
+ elif size == 2:
+ self.mc.sth(res, r.SP.value, off)
+ return True
+ elif size == 1:
+ self.mc.stz(res, r.SP.value, off)
+ return True
+ return False
+
def emit_vec_unpack_i(self, op, arglocs, regalloc):
assert isinstance(op, VectorOp)
resloc, srcloc, idxloc, countloc, sizeloc = arglocs
@@ -539,6 +563,7 @@
src = srcloc.value
size = sizeloc.value
count = countloc.value
+ newsize = op.bytesize
if count == 1:
assert srcloc.is_vector_reg()
assert not resloc.is_vector_reg()
@@ -548,18 +573,7 @@
if not IS_BIG_ENDIAN:
idx = (16 // size) - 1 - idx
off += size * idx
- if size == 8:
- self.mc.load(res, r.SP.value, off)
- return
- elif size == 4:
- self.mc.lwa(res, r.SP.value, off)
- return
- elif size == 2:
- self.mc.lha(res, r.SP.value, off)
- return
- elif size == 1:
- self.mc.lbz(res, r.SP.value, off)
- self.mc.extsb(res, res)
+ if self._load_from_sp(res, size, off):
return
else:
# count is not 1, but only 2 is supported for i32
@@ -571,16 +585,21 @@
self.mc.stvx(src, r.SCRATCH2.value, r.SP.value)
self.mc.load_imm(r.SCRATCH2, PARAM_SAVE_AREA_OFFSET+16)
self.mc.stvx(res, r.SCRATCH2.value, r.SP.value)
- if count * size == 8:
+ for j in range(count):
+ off = PARAM_SAVE_AREA_OFFSET
+ i = j+idx
if not IS_BIG_ENDIAN:
- endian_off = 8
+ i = (16 // size) - 1 - i
+ off += size * i
+ self._load_from_sp(r.SCRATCH.value, size, off)
off = PARAM_SAVE_AREA_OFFSET
- off = off + endian_off - (idx * size)
- assert idx * size + 8 <= 16
- self.mc.load(r.SCRATCH.value, r.SP.value, off)
- self.mc.store(r.SCRATCH.value, r.SP.value, PARAM_SAVE_AREA_OFFSET+16+endian_off)
- self.mc.lvx(res, r.SCRATCH2.value, r.SP.value)
- return
+ i = j
+ if not IS_BIG_ENDIAN:
+ i = (16 // size) - 1 - i
+ off += size * i
+ self._store_to_sp(r.SCRATCH.value, newsize, off+16)
+ self.mc.lvx(res, r.SCRATCH2.value, r.SP.value)
+ return
not_implemented("%d bit integer, count %d" % \
(size*8, count))
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_vecopt.py b/rpython/jit/metainterp/optimizeopt/test/test_vecopt.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_vecopt.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_vecopt.py
@@ -1397,5 +1397,6 @@
assert op not in dups
dups.add(op)
+
class TestLLtype(BaseTestVectorize, LLtypeMixin):
pass
diff --git a/rpython/jit/metainterp/resoperation.py b/rpython/jit/metainterp/resoperation.py
--- a/rpython/jit/metainterp/resoperation.py
+++ b/rpython/jit/metainterp/resoperation.py
@@ -1190,6 +1190,8 @@
# Uh, that should be moved to vector_ext really!
_cast_ops['CAST_FLOAT_TO_INT'] = ('f', 8, 'i', 8, 2)
_cast_ops['VEC_CAST_FLOAT_TO_INT'] = ('f', 8, 'i', 8, 2)
+ _cast_ops['CAST_INT_TO_FLOAT'] = ('i', 8, 'f', 8, 2)
+ _cast_ops['VEC_CAST_INT_TO_FLOAT'] = ('i', 8, 'f', 8, 2)
# ____________________________________________________________
diff --git a/rpython/jit/metainterp/test/test_vector.py b/rpython/jit/metainterp/test/test_vector.py
--- a/rpython/jit/metainterp/test/test_vector.py
+++ b/rpython/jit/metainterp/test/test_vector.py
@@ -845,17 +845,18 @@
j += 4
i += 8
- va = alloc_raw_storage(4*30, zero=True)
- vb = alloc_raw_storage(8*30, zero=True)
- for i,v in enumerate([1]*30):
+ count = 32
+ va = alloc_raw_storage(4*count, zero=True)
+ vb = alloc_raw_storage(8*count, zero=True)
+ for i,v in enumerate([1,2,3,4]*(count/4)):
raw_storage_setitem(va, i*4, rffi.cast(rffi.INT,v))
- for i,v in enumerate([-9.0]*30):
+ for i,v in enumerate([-1.0,-2.0,-3.0,-4.0]*(count/4)):
raw_storage_setitem(vb, i*8, rffi.cast(rffi.DOUBLE,v))
- vc = alloc_raw_storage(8*30, zero=True)
- self.meta_interp(f, [8*30, va, vb, vc], vec=True)
+ vc = alloc_raw_storage(8*count, zero=True)
+ self.meta_interp(f, [8*count, va, vb, vc], vec=True)
- for i in range(30):
- assert raw_storage_getitem(rffi.DOUBLE,vc,i*8) == -8.0
+ for i in range(count):
+ assert raw_storage_getitem(rffi.DOUBLE,vc,i*8) == 0.0
free_raw_storage(va)
free_raw_storage(vb)
More information about the pypy-commit
mailing list