]> git.sesse.net Git - x264/blobdiff - common/ppc/ppccommon.h
Bump dates to 2016
[x264] / common / ppc / ppccommon.h
index a4cb9e36a1f018e9b694912942ea04ab404fa5a5..4c91cd2a80a4f43e71d1dcc8e29f5934bd576e26 100644 (file)
@@ -1,10 +1,9 @@
 /*****************************************************************************
- * ppccommon.h: h264 encoder
+ * ppccommon.h: ppc utility macros
  *****************************************************************************
- * Copyright (C) 2003 Laurent Aimar
- * $Id: ppccommon.h,v 1.1 2004/06/03 19:27:07 fenrir Exp $
+ * Copyright (C) 2003-2016 x264 project
  *
- * Authors: Eric Petit <titer@m0k.org>
+ * Authors: 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
  *
  * 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.
+ *
+ * This program is also available under a commercial proprietary license.
+ * For more information, contact us at licensing@x264.com.
  *****************************************************************************/
 
+#if HAVE_ALTIVEC_H
+#include <altivec.h>
+#endif
+
 /***********************************************************************
  * For constant vectors, use parentheses on OS X and braces on Linux
  **********************************************************************/
-#ifdef SYS_MACOSX
+#if defined(__APPLE__) && __GNUC__ < 4
 #define CV(a...) (a)
 #else
 #define CV(a...) {a}
 #define vec_s32_t vector signed int
 
 typedef union {
-  unsigned int s[4];
-  vector unsigned int v;
-} vect_int_u;
+  uint32_t s[4];
+  vec_u32_t v;
+} vec_u32_u;
+
+typedef union {
+  uint16_t s[8];
+  vec_u16_t v;
+} vec_u16_u;
 
 typedef union {
-  unsigned short s[8];
-  vector unsigned short v;
-} vect_ushort_u;
+  int16_t s[8];
+  vec_s16_t v;
+} vec_s16_u;
+
+typedef union {
+  uint8_t s[16];
+  vec_u8_t v;
+} vec_u8_u;
 
 /***********************************************************************
  * Null vector
@@ -65,10 +81,17 @@ typedef union {
 /***********************************************************************
  * 8 <-> 16 bits conversions
  **********************************************************************/
+#ifdef WORDS_BIGENDIAN
 #define vec_u8_to_u16_h(v) (vec_u16_t) vec_mergeh( zero_u8v, (vec_u8_t) v )
 #define vec_u8_to_u16_l(v) (vec_u16_t) vec_mergel( zero_u8v, (vec_u8_t) v )
 #define vec_u8_to_s16_h(v) (vec_s16_t) vec_mergeh( zero_u8v, (vec_u8_t) v )
 #define vec_u8_to_s16_l(v) (vec_s16_t) vec_mergel( zero_u8v, (vec_u8_t) v )
+#else
+#define vec_u8_to_u16_h(v) (vec_u16_t) vec_mergeh( (vec_u8_t) v, zero_u8v )
+#define vec_u8_to_u16_l(v) (vec_u16_t) vec_mergel( (vec_u8_t) v, zero_u8v )
+#define vec_u8_to_s16_h(v) (vec_s16_t) vec_mergeh( (vec_u8_t) v, zero_u8v )
+#define vec_u8_to_s16_l(v) (vec_s16_t) vec_mergel( (vec_u8_t) v, zero_u8v )
+#endif
 
 #define vec_u8_to_u16(v) vec_u8_to_u16_h(v)
 #define vec_u8_to_s16(v) vec_u8_to_s16_h(v)
@@ -76,91 +99,110 @@ typedef union {
 #define vec_u16_to_u8(v) vec_pack( v, zero_u16v )
 #define vec_s16_to_u8(v) vec_packsu( v, zero_s16v )
 
+
+/***********************************************************************
+ * 16 <-> 32 bits conversions
+ **********************************************************************/
+#ifdef WORDS_BIGENDIAN
+#define vec_u16_to_u32_h(v) (vec_u32_t) vec_mergeh( zero_u16v, (vec_u16_t) v )
+#define vec_u16_to_u32_l(v) (vec_u32_t) vec_mergel( zero_u16v, (vec_u16_t) v )
+#define vec_u16_to_s32_h(v) (vec_s32_t) vec_mergeh( zero_u16v, (vec_u16_t) v )
+#define vec_u16_to_s32_l(v) (vec_s32_t) vec_mergel( zero_u16v, (vec_u16_t) v )
+#else
+#define vec_u16_to_u32_h(v) (vec_u32_t) vec_mergeh( (vec_u16_t) v, zero_u16v )
+#define vec_u16_to_u32_l(v) (vec_u32_t) vec_mergel( (vec_u16_t) v, zero_u16v )
+#define vec_u16_to_s32_h(v) (vec_s32_t) vec_mergeh( (vec_u16_t) v, zero_u16v )
+#define vec_u16_to_s32_l(v) (vec_s32_t) vec_mergel( (vec_u16_t) v, zero_u16v )
+#endif
+
+#define vec_u16_to_u32(v) vec_u16_to_u32_h(v)
+#define vec_u16_to_s32(v) vec_u16_to_s32_h(v)
+
+#define vec_u32_to_u16(v) vec_pack( v, zero_u32v )
+#define vec_s32_to_u16(v) vec_packsu( v, zero_s32v )
+
+
 /***********************************************************************
  * PREP_LOAD: declares two vectors required to perform unaligned loads
- * VEC_LOAD:  loads n bytes from u8 * p into vector v of type t
+ * VEC_LOAD:  loads n bytes from u8 * p into vector v of type t where o is from original src offset
+ * VEC_LOAD:_G: loads n bytes from u8 * p into vectory v of type t - use when offset is not known
+ * VEC_LOAD_OFFSET: as above, but with offset vector known in advance
  **********************************************************************/
-#define PREP_LOAD \
+#define PREP_LOAD     \
     vec_u8_t _hv, _lv
 
-#define VEC_LOAD( p, v, n, t )                  \
-    _hv = vec_ld( 0, p );                       \
-    v   = (t) vec_lvsl( 0, p );                 \
-    _lv = vec_ld( n - 1, p );                   \
+#define PREP_LOAD_SRC( src )              \
+    vec_u8_t _##src##_ = vec_lvsl(0, src)
+
+#define VEC_LOAD_G( p, v, n, t )                 \
+    _hv = vec_ld( 0, p );                        \
+    v   = (t) vec_lvsl( 0, p );                  \
+    _lv = vec_ld( n - 1, p );                    \
     v   = (t) vec_perm( _hv, _lv, (vec_u8_t) v )
 
+#define VEC_LOAD( p, v, n, t, g )                   \
+    _hv = vec_ld( 0, p );                           \
+    _lv = vec_ld( n - 1, p );                       \
+    v = (t) vec_perm( _hv, _lv, (vec_u8_t) _##g##_ )
+
+#define VEC_LOAD_OFFSET( p, v, n, t, o )         \
+    _hv = vec_ld( 0, p);                         \
+    _lv = vec_ld( n - 1, p );                    \
+    v   = (t) vec_perm( _hv, _lv, (vec_u8_t) o )
+
+#define VEC_LOAD_PARTIAL( p, v, n, t, g)               \
+    _hv = vec_ld( 0, p);                               \
+    v   = (t) vec_perm( _hv, _hv, (vec_u8_t) _##g##_ )
+
+
 /***********************************************************************
  * PREP_STORE##n: declares required vectors to store n bytes to a
  *                potentially unaligned address
  * VEC_STORE##n:  stores n bytes from vector v to address p
  **********************************************************************/
 #define PREP_STORE16 \
-    vec_u8_t _tmp1v, _tmp2v \
-
-#define VEC_STORE16( v, p ) \
-    _hv    = vec_ld( 0, p ); \
-    _tmp2v = vec_lvsl( 0, p ); \
-    _lv    = vec_ld( 15, p ); \
-    _tmp1v = vec_perm( _lv, _hv, _tmp2v ); \
-    _tmp2v = vec_lvsr( 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_u8_t _tmp1v  \
+
+#define PREP_STORE16_DST( dst )             \
+    vec_u8_t _##dst##l_ = vec_lvsl(0, dst); \
+    vec_u8_t _##dst##r_ = vec_lvsr(0, dst);
+
+#define VEC_STORE16( v, p, o )                           \
+    _hv    = vec_ld( 0, p );                             \
+    _lv    = vec_ld( 15, p );                            \
+    _tmp1v = vec_perm( _lv, _hv, _##o##l_ );             \
+    _lv    = vec_perm( (vec_u8_t) v, _tmp1v, _##o##r_ ); \
+    vec_st( _lv, 15, (uint8_t *) p );                    \
+    _hv    = vec_perm( _tmp1v, (vec_u8_t) v, _##o##r_ ); \
     vec_st( _hv, 0, (uint8_t *) p )
 
+
 #define PREP_STORE8 \
-    PREP_STORE16; \
-    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 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 )
+    vec_u8_t _tmp3v \
+
+#define VEC_STORE8( v, p )                \
+    _tmp3v = vec_lvsl(0, p);              \
+    v = vec_perm(v, v, _tmp3v);           \
+    vec_ste((vec_u32_t)v,0,(uint32_t*)p); \
+    vec_ste((vec_u32_t)v,4,(uint32_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; \
-    vec_u8_t _tmp3v; \
-    const vec_u8_t sel = \
+#define PREP_STORE4                                        \
+    PREP_STORE16;                                          \
+    vec_u8_t _tmp2v, _tmp3v;                               \
+    const vec_u8_t sel =                                   \
         (vec_u8_t) CV(-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0)
 
-#define VEC_STORE4( v, p ) \
-    _tmp3v = vec_lvsr( 0, p ); \
-    v      = vec_perm( v, v, _tmp3v ); \
-    _lv    = vec_ld( 3, p ); \
+#define VEC_STORE4( v, p )                      \
+    _tmp3v = vec_lvsr( 0, p );                  \
+    v      = vec_perm( v, v, _tmp3v );          \
+    _lv    = vec_ld( 3, p );                    \
     _tmp1v = vec_perm( sel, zero_u8v, _tmp3v ); \
-    _lv    = vec_sel( _lv, v, _tmp1v ); \
-    vec_st( _lv, 3, p ); \
-    _hv    = vec_ld( 0, p ); \
+    _lv    = vec_sel( _lv, v, _tmp1v );         \
+    vec_st( _lv, 3, p );                        \
+    _hv    = vec_ld( 0, p );                    \
     _tmp2v = vec_perm( zero_u8v, sel, _tmp3v ); \
-    _hv    = vec_sel( _hv, v, _tmp2v ); \
+    _hv    = vec_sel( _hv, v, _tmp2v );         \
     vec_st( _hv, 0, p )
 
 /***********************************************************************
@@ -224,22 +266,33 @@ typedef union {
  * 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
+ * d, increments p1 and p2 by i1 and i2 into known offset g
  **********************************************************************/
 #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;                          \
+
+#define VEC_DIFF_H(p1,i1,p2,i2,n,d,g)               \
+    VEC_LOAD_PARTIAL( p1, pix1v, n, vec_s16_t, p1); \
+    pix1v = vec_u8_to_s16( pix1v );                 \
+    VEC_LOAD( p2, pix2v, n, vec_s16_t, g);          \
+    pix2v = vec_u8_to_s16( pix2v );                 \
+    d     = vec_sub( pix1v, pix2v );                \
+    p1   += i1;                                     \
+    p2   += i2
+
+#define VEC_DIFF_H_OFFSET(p1,i1,p2,i2,n,d,g1,g2)    \
+    pix1v = (vec_s16_t)vec_perm( vec_ld( 0, p1 ), zero_u8v, _##g1##_ );\
+    pix1v = vec_u8_to_s16( pix1v );                 \
+    VEC_LOAD( p2, pix2v, n, vec_s16_t, g2);         \
+    pix2v = vec_u8_to_s16( pix2v );                 \
+    d     = vec_sub( pix1v, pix2v );                \
+    p1   += i1;                                     \
     p2   += i2
 
+
 /***********************************************************************
  * VEC_DIFF_HL
  ***********************************************************************
@@ -251,16 +304,16 @@ typedef union {
  * 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;                          \
+#define VEC_DIFF_HL(p1,i1,p2,i2,dh,dl)       \
+    pix1v = (vec_s16_t)vec_ld(0, p1);        \
+    temp0v = vec_u8_to_s16_h( pix1v );       \
+    temp1v = vec_u8_to_s16_l( pix1v );       \
+    VEC_LOAD( p2, pix2v, 16, vec_s16_t, p2); \
+    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
 
 /***********************************************************************