[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