]> git.sesse.net Git - x264/blobdiff - common/ppc/ppccommon.h
Add missing x264util.asm
[x264] / common / ppc / ppccommon.h
index 35f773f18c8e6950ae6f64a0ab6c6b5cc8779137..2756e3851fc6aedfd02eb9be60705963f6ed4e59 100644 (file)
@@ -1,10 +1,7 @@
 /*****************************************************************************
  * ppccommon.h: h264 encoder
  *****************************************************************************
- * Copyright (C) 2003 Laurent Aimar
- * $Id: ppccommon.h,v 1.1 2004/06/03 19:27:07 fenrir Exp $
- *
- * Authors: Eric Petit <titer@m0k.org>
+ * Copyright (C) 2003 Eric Petit <eric.petit@lapsus.org>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -18,7 +15,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
  *****************************************************************************/
 
 /***********************************************************************
 #define vec_u32_t vector unsigned int
 #define vec_s32_t vector signed int
 
+typedef union {
+  unsigned int s[4];
+  vector unsigned int v;
+} vect_int_u;
+
+typedef union {
+  unsigned short s[8];
+  vector unsigned short v;
+} vect_ushort_u;
+
+typedef union {
+  signed short s[8];
+  vector signed short v;
+} vect_sshort_u;
+
 /***********************************************************************
  * Null vector
  **********************************************************************/
@@ -64,7 +76,7 @@
 #define vec_u8_to_s16(v) vec_u8_to_s16_h(v)
 
 #define vec_u16_to_u8(v) vec_pack( v, zero_u16v )
-#define vec_s16_to_u8(v) vec_pack( v, zero_u16v )
+#define vec_s16_to_u8(v) vec_packsu( v, zero_s16v )
 
 /***********************************************************************
  * PREP_LOAD: declares two vectors required to perform unaligned loads
     _lv    = vec_ld( 15, p ); \
     _tmp1v = vec_perm( _lv, _hv, _tmp2v ); \
     _tmp2v = vec_lvsr( 0, p ); \
-    _lv    = vec_perm( v, _tmp1v, _tmp2v ); \
-    vec_st( _lv, 15, p ); \
-    _hv    = vec_perm( _tmp1v, v, _tmp2v ); \
-    vec_st( _hv, 0, p )
+    _lv    = vec_perm( (vec_u8_t) v, _tmp1v, _tmp2v ); \
+    vec_st( _lv, 15, (uint8_t *) p ); \
+    _hv    = vec_perm( _tmp1v, (vec_u8_t) v, _tmp2v ); \
+    vec_st( _hv, 0, (uint8_t *) p )
 
 #define PREP_STORE8 \
     PREP_STORE16; \
-    vec_u8_t _tmp3v; \
-    const vec_u8_t sel = \
+    vec_u8_t _tmp3v, _tmp4v; \
+    const vec_u8_t sel_h = \
         (vec_u8_t) CV(-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0)
 
-#define VEC_STORE8( v, p ) \
-    _tmp3v = vec_lvsr( 0, p ); \
-    v      = vec_perm( v, v, _tmp3v ); \
-    _lv    = vec_ld( 7, p ); \
-    _tmp1v = vec_perm( sel, zero_u8v, _tmp3v ); \
-    _lv    = vec_sel( _lv, v, _tmp1v ); \
-    vec_st( _lv, 7, p ); \
-    _hv    = vec_ld( 0, p ); \
-    _tmp2v = vec_perm( zero_u8v, sel, _tmp3v ); \
-    _hv    = vec_sel( _hv, v, _tmp2v ); \
-    vec_st( _hv, 0, p )
+#define PREP_STORE8_HL \
+    PREP_STORE8; \
+    const vec_u8_t sel_l = \
+        (vec_u8_t) CV(0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1)
+
+#define VEC_STORE8 VEC_STORE8_H
+
+#define VEC_STORE8_H( v, p ) \
+    _tmp3v = vec_lvsr( 0, (uint8_t *) p ); \
+    _tmp4v = vec_perm( (vec_u8_t) v, (vec_u8_t) v, _tmp3v ); \
+    _lv    = vec_ld( 7, (uint8_t *) p ); \
+    _tmp1v = vec_perm( sel_h, zero_u8v, _tmp3v ); \
+    _lv    = vec_sel( _lv, _tmp4v, _tmp1v ); \
+    vec_st( _lv, 7, (uint8_t *) p ); \
+    _hv    = vec_ld( 0, (uint8_t *) p ); \
+    _tmp2v = vec_perm( zero_u8v, sel_h, _tmp3v ); \
+    _hv    = vec_sel( _hv, _tmp4v, _tmp2v ); \
+    vec_st( _hv, 0, (uint8_t *) p )
+
+#define VEC_STORE8_L( v, p ) \
+    _tmp3v = vec_lvsr( 8, (uint8_t *) p ); \
+    _tmp4v = vec_perm( (vec_u8_t) v, (vec_u8_t) v, _tmp3v ); \
+    _lv    = vec_ld( 7, (uint8_t *) p ); \
+    _tmp1v = vec_perm( sel_l, zero_u8v, _tmp3v ); \
+    _lv    = vec_sel( _lv, _tmp4v, _tmp1v ); \
+    vec_st( _lv, 7, (uint8_t *) p ); \
+    _hv    = vec_ld( 0, (uint8_t *) p ); \
+    _tmp2v = vec_perm( zero_u8v, sel_l, _tmp3v ); \
+    _hv    = vec_sel( _hv, _tmp4v, _tmp2v ); \
+    vec_st( _hv, 0, (uint8_t *) p )
 
 #define PREP_STORE4 \
     PREP_STORE16; \
     _hv    = vec_sel( _hv, v, _tmp2v ); \
     vec_st( _hv, 0, p )
 
+/***********************************************************************
+ * VEC_TRANSPOSE_8
+ ***********************************************************************
+ * Transposes a 8x8 matrix of s16 vectors
+ **********************************************************************/
+#define VEC_TRANSPOSE_8(a0,a1,a2,a3,a4,a5,a6,a7,b0,b1,b2,b3,b4,b5,b6,b7) \
+    b0 = vec_mergeh( a0, a4 ); \
+    b1 = vec_mergel( a0, a4 ); \
+    b2 = vec_mergeh( a1, a5 ); \
+    b3 = vec_mergel( a1, a5 ); \
+    b4 = vec_mergeh( a2, a6 ); \
+    b5 = vec_mergel( a2, a6 ); \
+    b6 = vec_mergeh( a3, a7 ); \
+    b7 = vec_mergel( a3, a7 ); \
+    a0 = vec_mergeh( b0, b4 ); \
+    a1 = vec_mergel( b0, b4 ); \
+    a2 = vec_mergeh( b1, b5 ); \
+    a3 = vec_mergel( b1, b5 ); \
+    a4 = vec_mergeh( b2, b6 ); \
+    a5 = vec_mergel( b2, b6 ); \
+    a6 = vec_mergeh( b3, b7 ); \
+    a7 = vec_mergel( b3, b7 ); \
+    b0 = vec_mergeh( a0, a4 ); \
+    b1 = vec_mergel( a0, a4 ); \
+    b2 = vec_mergeh( a1, a5 ); \
+    b3 = vec_mergel( a1, a5 ); \
+    b4 = vec_mergeh( a2, a6 ); \
+    b5 = vec_mergel( a2, a6 ); \
+    b6 = vec_mergeh( a3, a7 ); \
+    b7 = vec_mergel( a3, a7 )
+
+/***********************************************************************
+ * VEC_TRANSPOSE_4
+ ***********************************************************************
+ * Transposes a 4x4 matrix of s16 vectors.
+ * Actually source and destination are 8x4. The low elements of the
+ * source are discarded and the low elements of the destination mustn't
+ * be used.
+ **********************************************************************/
+#define VEC_TRANSPOSE_4(a0,a1,a2,a3,b0,b1,b2,b3) \
+    b0 = vec_mergeh( a0, a0 ); \
+    b1 = vec_mergeh( a1, a0 ); \
+    b2 = vec_mergeh( a2, a0 ); \
+    b3 = vec_mergeh( a3, a0 ); \
+    a0 = vec_mergeh( b0, b2 ); \
+    a1 = vec_mergel( b0, b2 ); \
+    a2 = vec_mergeh( b1, b3 ); \
+    a3 = vec_mergel( b1, b3 ); \
+    b0 = vec_mergeh( a0, a2 ); \
+    b1 = vec_mergel( a0, a2 ); \
+    b2 = vec_mergeh( a1, a3 ); \
+    b3 = vec_mergel( a1, a3 )
+
+/***********************************************************************
+ * VEC_DIFF_H
+ ***********************************************************************
+ * p1, p2:    u8 *
+ * i1, i2, n: int
+ * d:         s16v
+ *
+ * Loads n bytes from p1 and p2, do the diff of the high elements into
+ * d, increments p1 and p2 by i1 and i2
+ **********************************************************************/
+#define PREP_DIFF           \
+    LOAD_ZERO;              \
+    PREP_LOAD;              \
+    vec_s16_t pix1v, pix2v;
+
+#define VEC_DIFF_H(p1,i1,p2,i2,n,d)      \
+    VEC_LOAD( p1, pix1v, n, vec_s16_t ); \
+    pix1v = vec_u8_to_s16( pix1v );      \
+    VEC_LOAD( p2, pix2v, n, vec_s16_t ); \
+    pix2v = vec_u8_to_s16( pix2v );      \
+    d     = vec_sub( pix1v, pix2v );     \
+    p1   += i1;                          \
+    p2   += i2
+
+/***********************************************************************
+ * VEC_DIFF_HL
+ ***********************************************************************
+ * p1, p2: u8 *
+ * i1, i2: int
+ * dh, dl: s16v
+ *
+ * Loads 16 bytes from p1 and p2, do the diff of the high elements into
+ * dh, the diff of the low elements into dl, increments p1 and p2 by i1
+ * and i2
+ **********************************************************************/
+#define VEC_DIFF_HL(p1,i1,p2,i2,dh,dl)    \
+    VEC_LOAD( p1, pix1v, 16, vec_s16_t ); \
+    temp0v = vec_u8_to_s16_h( pix1v );    \
+    temp1v = vec_u8_to_s16_l( pix1v );    \
+    VEC_LOAD( p2, pix2v, 16, vec_s16_t ); \
+    temp2v = vec_u8_to_s16_h( pix2v );    \
+    temp3v = vec_u8_to_s16_l( pix2v );    \
+    dh     = vec_sub( temp0v, temp2v );   \
+    dl     = vec_sub( temp1v, temp3v );   \
+    p1    += i1;                          \
+    p2    += i2
+
+/***********************************************************************
+* VEC_DIFF_H_8BYTE_ALIGNED
+***********************************************************************
+* p1, p2:    u8 *
+* i1, i2, n: int
+* d:         s16v
+*
+* Loads n bytes from p1 and p2, do the diff of the high elements into
+* d, increments p1 and p2 by i1 and i2
+* Slightly faster when we know we are loading/diffing 8bytes which
+* are 8 byte aligned. Reduces need for two loads and two vec_lvsl()'s
+**********************************************************************/
+#define PREP_DIFF_8BYTEALIGNED \
+LOAD_ZERO;                     \
+vec_s16_t pix1v, pix2v;        \
+vec_u8_t pix1v8, pix2v8;       \
+vec_u8_t permPix1, permPix2;   \
+permPix1 = vec_lvsl(0, pix1);  \
+permPix2 = vec_lvsl(0, pix2);  \
+
+#define VEC_DIFF_H_8BYTE_ALIGNED(p1,i1,p2,i2,n,d)     \
+pix1v8 = vec_perm(vec_ld(0,p1), zero_u8v, permPix1);  \
+pix2v8 = vec_perm(vec_ld(0, p2), zero_u8v, permPix2); \
+pix1v = vec_u8_to_s16( pix1v8 );                      \
+pix2v = vec_u8_to_s16( pix2v8 );                      \
+d = vec_sub( pix1v, pix2v);                           \
+p1 += i1;                                             \
+p2 += i2;