[llvm-commits] [vector_llvm] CVS: llvm/examples/SIMD/DCT/Makefile dct.altivec.handwritten.c dct.sse.handwritten.c dct.vectorc.c main.c

Robert L. Bocchino Jr. bocchino at persephone.cs.uiuc.edu
Sun Oct 23 15:50:20 PDT 2005



Changes in directory llvm/examples/SIMD/DCT:

Makefile added (r1.1.2.1)
dct.altivec.handwritten.c added (r1.1.2.1)
dct.sse.handwritten.c added (r1.1.2.1)
dct.vectorc.c added (r1.1.2.1)
main.c added (r1.1.2.1)
---
Log message:

Examples to illustrate Vector LLVM's SIMD support.


---
Diffs of the changes:  (+646 -0)

 Makefile                  |    4 
 dct.altivec.handwritten.c |  198 ++++++++++++++++++++++++++++++++++++++++++++++
 dct.sse.handwritten.c     |  129 +++++++++++++++++++++++++++++
 dct.vectorc.c             |  140 ++++++++++++++++++++++++++++++++
 main.c                    |  175 ++++++++++++++++++++++++++++++++++++++++
 5 files changed, 646 insertions


Index: llvm/examples/SIMD/DCT/Makefile
diff -c /dev/null llvm/examples/SIMD/DCT/Makefile:1.1.2.1
*** /dev/null	Sun Oct 23 17:49:50 2005
--- llvm/examples/SIMD/DCT/Makefile	Sun Oct 23 17:49:39 2005
***************
*** 0 ****
--- 1,4 ----
+ NAME= dct
+ 
+ include ../Makefile.common
+ 


Index: llvm/examples/SIMD/DCT/dct.altivec.handwritten.c
diff -c /dev/null llvm/examples/SIMD/DCT/dct.altivec.handwritten.c:1.1.2.1
*** /dev/null	Sun Oct 23 17:50:17 2005
--- llvm/examples/SIMD/DCT/dct.altivec.handwritten.c	Sun Oct 23 17:49:39 2005
***************
*** 0 ****
--- 1,198 ----
+ static inline void Matrix_Transpose ( vector signed short *input, vector signed short *output)
+ {
+   vector signed short a0, a1, a2, a3, a4, a5, a6, a7;
+   vector signed short b0, b1, b2, b3, b4, b5, b6, b7;
+ 
+   b0 = vec_mergeh( input[0], input[4] );     /* [ 00 40 01 41 02 42 03 43 ]*/
+   b1 = vec_mergel( input[0], input[4] );     /* [ 04 44 05 45 06 46 07 47 ]*/
+   b2 = vec_mergeh( input[1], input[5] );     /* [ 10 50 11 51 12 52 13 53 ]*/
+   b3 = vec_mergel( input[1], input[5] );     /* [ 14 54 15 55 16 56 17 57 ]*/
+   b4 = vec_mergeh( input[2], input[6] );     /* [ 20 60 21 61 22 62 23 63 ]*/
+   b5 = vec_mergel( input[2], input[6] );     /* [ 24 64 25 65 26 66 27 67 ]*/
+   b6 = vec_mergeh( input[3], input[7] );     /* [ 30 70 31 71 32 72 33 73 ]*/
+   b7 = vec_mergel( input[3], input[7] );     /* [ 34 74 35 75 36 76 37 77 ]*/
+ 
+   a0 = vec_mergeh( b0, b4 );                 /* [ 00 20 40 60 01 21 41 61 ]*/
+   a1 = vec_mergel( b0, b4 );                 /* [ 02 22 42 62 03 23 43 63 ]*/
+   a2 = vec_mergeh( b1, b5 );                 /* [ 04 24 44 64 05 25 45 65 ]*/
+   a3 = vec_mergel( b1, b5 );                 /* [ 06 26 46 66 07 27 47 67 ]*/
+   a4 = vec_mergeh( b2, b6 );                 /* [ 10 30 50 70 11 31 51 71 ]*/
+   a5 = vec_mergel( b2, b6 );                 /* [ 12 32 52 72 13 33 53 73 ]*/
+   a6 = vec_mergeh( b3, b7 );                 /* [ 14 34 54 74 15 35 55 75 ]*/
+   a7 = vec_mergel( b3, b7 );                 /* [ 16 36 56 76 17 37 57 77 ]*/
+ 
+   output[0] = vec_mergeh( a0, a4 );          /* [ 00 10 20 30 40 50 60 70 ]*/
+   output[1] = vec_mergel( a0, a4 );          /* [ 01 11 21 31 41 51 61 71 ]*/
+   output[2] = vec_mergeh( a1, a5 );          /* [ 02 12 22 32 42 52 62 72 ]*/
+   output[3] = vec_mergel( a1, a5 );          /* [ 03 13 23 33 43 53 63 73 ]*/
+   output[4] = vec_mergeh( a2, a6 );          /* [ 04 14 24 34 44 54 64 74 ]*/
+   output[5] = vec_mergel( a2, a6 );          /* [ 05 15 25 35 45 55 65 75 ]*/
+   output[6] = vec_mergeh( a3, a7 );          /* [ 06 16 26 36 46 56 66 76 ]*/
+   output[7] = vec_mergel( a3, a7 );          /* [ 07 17 27 37 47 57 67 77 ]*/
+ 
+ }
+ 
+ /***************************************************************
+  *
+  * Copyright:   (c) Copyright Motorola Inc. 1998
+  *
+  * Date:        April 15, 1998
+  *
+  * Macro:       DCT_Transform
+  *
+  * Description: Discrete Cosign Transform implemented by the
+  *              Scaled Chen (II) Algorithm developed by Haifa
+  *              Research Lab.  The major differnce between this
+  *              algorithm and the Scaled Chen (I) is that
+  *              certain multiply-subtracts are replaced by
+  *              multiply adds.  A full description of the
+  *              Scaled Chen (I) algorithm can be found in:
+  *              W.C.Chen, C.H.Smith and S.C.Fralick, "A Fast
+  *              Computational Algorithm for the Discrete Cosine
+  *              Transform", IEEE Transactions on Cummnuications,
+  *              Vol. COM-25, No. 9, pp 1004-1009, Sept. 1997.
+  *
+  * Inputs:      vx     : array of vector short
+  *              t1-t10 : temporary vector variables set up by caller
+  *              c4     : cos(4*pi/16)
+  *              mc4    : -c4
+  *              a0     : c6/c2
+  *              a1     : c7/c1
+  *              a2     : c5/c3
+  *              ma2    : -a2
+  *              zero   : an array of zero elements
+  *
+  * Outputs:     vy     : array of vector short
+  *
+  **************************************************************/
+ 
+ #define DCT_Transform(vx,vy) \
+                                                                    \
+   /* 1st stage. */                                                 \
+   t8 = vec_adds( vx[0], vx[7] );     /* t0 + t7 */                 \
+   t9 = vec_subs( vx[0], vx[7] );     /* t0 - t7 */                 \
+   t0 = vec_adds( vx[1], vx[6] );     /* t1 + t6 */                 \
+   t7 = vec_subs( vx[1], vx[6] );     /* t1 - t6 */                 \
+   t1 = vec_adds( vx[2], vx[5] );     /* t2 + t6 */                 \
+   t6 = vec_subs( vx[2], vx[5] );     /* t2 - t6 */                 \
+   t2 = vec_adds( vx[3], vx[4] );     /* t3 + t4 */                 \
+   t5 = vec_subs( vx[3], vx[4] );     /* t3 - t4 */                 \
+                                                                    \
+   /* 2nd stage. */                                                 \
+   t3 = vec_adds( t8, t2 );           /* (t0+t7) + (t3+t4) */       \
+   t4 = vec_subs( t8, t2 );           /* (t0+t7) - (t3+t4) */       \
+   t2 = vec_adds( t0, t1 );           /* (t1+t6) + (t2+t5) */       \
+   t8 = vec_subs( t0, t1 );           /* (t1+t6) - (t2+t5) */       \
+                                                                    \
+   t1 = vec_adds( t7, t6 );           /* (t1-t6) + (t2-t5) */       \
+   t0 = vec_subs( t7, t6 );           /* (t1-t6) - (t2-t5) */       \
+                                                                    \
+   /* 3rd stage */                                                  \
+   vy[0] = vec_adds( t3, t2 );        /* y0 = t3 + t2 */            \
+   vy[4] = vec_subs( t3, t2 );        /* y4 = t3 + t2 */            \
+   vy[2] = vec_mradds( t8, a0, t4 );  /* y2 = t8 * (a0) + t4 */     \
+   t10 = vec_mradds( t4, a0, zero );                                \
+   vy[6]  = vec_subs( t10, t8 );       /* y6 = t4 * (a0) - t8 */    \
+                                                                    \
+   t6 = vec_mradds( t0, c4, t5 );     /* t6 = t0 * (c4) + t5  */    \
+   t7 = vec_mradds( t0, mc4, t5 );    /* t7 = t0 * (-c4) + t5 */    \
+   t2 = vec_mradds( t1, mc4, t9 );    /* t2 = t1 * (-c4) + t9 */    \
+   t3 = vec_mradds( t1, c4, t9 );     /* t3 = t1 * (c4) + t9  */    \
+                                                                    \
+   /* 4th stage. */                                                 \
+   vy[1] = vec_mradds( t6, a1, t3 );    /* y1 = t6 * (a1) + t3  */  \
+   t9 = vec_mradds( t3, a1, zero );                                 \
+   vy[7] = vec_subs( t9, t6 ) ;         /* y7 = t3 * (a1) - t6  */  \
+   vy[5] = vec_mradds( t2, a2, t7 );    /* y5 = t2 + (a2) + t7  */  \
+   vy[3] = vec_mradds( t7, ma2, t2 );   /* y3 = t7 * (-a2) + t2 */
+ 
+ /* Post-scaling matrix -- scaled by 1 */
+ vector signed short PostScale[8] = {
+     (vector signed short)( 4095, 5681, 5351, 4816, 4095, 4816, 5351, 5681 ),
+     (vector signed short)( 5681, 7880, 7422, 6680, 5681, 6680, 7422, 7880 ),
+     (vector signed short)( 5351, 7422, 6992, 6292, 5351, 6292, 6992, 7422 ),
+     (vector signed short)( 4816, 6680, 6292, 5663, 4816, 5663, 6292, 6680 ),
+     (vector signed short)( 4095, 5681, 5351, 4816, 4095, 4816, 5351, 5681 ),
+     (vector signed short)( 4816, 6680, 6292, 5663, 4816, 5663, 6292, 6680 ),
+     (vector signed short)( 5351, 7422, 6992, 6292, 5351, 6292, 6992, 7422 ),
+     (vector signed short)( 5681, 7880, 7422, 6680, 5681, 6680, 7422, 7880 )
+ };
+ 
+ /***************************************************************
+  *
+  * Copyright:   (c) Copyright Motorola Inc. 1998
+  *
+  * Date:        April 17, 1998
+  *
+  * Function:    DCT
+  *
+  * Description: Scaled Chen (II) algorithm for DCT
+  *              Arithmetic is 16-bit fixed point.
+  *
+  * Inputs:      input - Pointer to input data (short), which
+  *                      must be between -255 to +255.
+  *                      It is assumed that the allocated array
+  *                      has been 128-bit aligned and contains
+  *                      8x8 short elements.
+  *
+  * Outputs:     output - Pointer to output area for the transfored
+  *                       data. The output values are between -2040
+  *                       and 2040. It is assumed that a 128-bit
+  *                       aligned 8x8 array of short has been
+  *                       pre-allocated.
+  *
+  * Return:      None
+  *
+  ***************************************************************/
+ 
+ void dct_vector(short *input, short *output) {
+ 
+   vector signed short t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10;
+   vector signed short a0, a1, a2, ma2, c4, mc4, zero;
+   vector signed short vx[8], vy[8];
+   vector signed short *vec_ptr;  /* used for conversion between
+                                     arrays of short and vector
+                                     signed short array.  */
+ 
+   /* load the multiplication constants */
+   c4   = (vector signed short)(23170);   /* c4 = cos(4*pi/16)  */
+   a0   = (vector signed short)(13573);   /* a0 = c6/c2         */
+   a1   = (vector signed short)(6518);    /* a1 = c7/c1         */
+   a2   = (vector signed short)(21895);   /* a2 = c5/c3         */
+   mc4   = (vector signed short)(-23170); /* -c4                */
+   ma2   = (vector signed short)(-21895); /* -a2                */
+   zero = (vector signed short)(0);       /* 0                  */
+ 
+   /* copy the rows of input data */
+   vec_ptr = ( vector signed short * ) input;
+   vx[0] = vec_ptr[0];
+   vx[1] = vec_ptr[1];
+   vx[2] = vec_ptr[2];
+   vx[3] = vec_ptr[3];
+   vx[4] = vec_ptr[4];
+   vx[5] = vec_ptr[5];
+   vx[6] = vec_ptr[6];
+   vx[7] = vec_ptr[7];
+ 
+   /* Perform DCT first on the 8 columns */
+   DCT_Transform( vx, vy );
+ 
+   /* Transpose matrix to work on rows */
+   Matrix_Transpose( vy, vx );
+ 
+   /* Perform DCT first on the 8 rows */
+   DCT_Transform( vx, vy );
+ 
+   /* Post-scale and store result. */
+   vec_ptr = (vector signed short *) output;
+ 
+   vec_ptr[0] = vec_mradds( PostScale[0], vy[0], zero );
+   vec_ptr[1] = vec_mradds( PostScale[1], vy[1], zero );
+   vec_ptr[2] = vec_mradds( PostScale[2], vy[2], zero );
+   vec_ptr[3] = vec_mradds( PostScale[3], vy[3], zero );
+   vec_ptr[4] = vec_mradds( PostScale[4], vy[4], zero );
+   vec_ptr[5] = vec_mradds( PostScale[5], vy[5], zero );
+   vec_ptr[6] = vec_mradds( PostScale[6], vy[6], zero );
+   vec_ptr[7] = vec_mradds( PostScale[7], vy[7], zero );
+ 
+ }


Index: llvm/examples/SIMD/DCT/dct.sse.handwritten.c
diff -c /dev/null llvm/examples/SIMD/DCT/dct.sse.handwritten.c:1.1.2.1
*** /dev/null	Sun Oct 23 17:50:18 2005
--- llvm/examples/SIMD/DCT/dct.sse.handwritten.c	Sun Oct 23 17:49:39 2005
***************
*** 0 ****
--- 1,129 ----
+ #include "Scalar.h"
+ #include "SSE.h"
+ 
+ extern short *PostScalePtr;
+ 
+ static inline void Matrix_Transpose ( short *input_scalar, short *output_scalar)
+ {
+   __m128i *input = (__m128i*) input_scalar;
+   __m128i *output = (__m128i*) output_scalar;
+ 
+   __m128i a0, a1, a2, a3, a4, a5, a6, a7;
+   __m128i b0, b1, b2, b3, b4, b5, b6, b7;
+ 
+   b0 = _mm_unpacklo_epi16( input[0], input[4] );     /* [ 00 40 01 41 02 42 03 43 ]*/
+   b1 = _mm_unpackhi_epi16( input[0], input[4] );     /* [ 04 44 05 45 06 46 07 47 ]*/
+   b2 = _mm_unpacklo_epi16( input[1], input[5] );     /* [ 10 50 11 51 12 52 13 53 ]*/
+   b3 = _mm_unpackhi_epi16( input[1], input[5] );     /* [ 14 54 15 55 16 56 17 57 ]*/
+   b4 = _mm_unpacklo_epi16( input[2], input[6] );     /* [ 20 60 21 61 22 62 23 63 ]*/
+   b5 = _mm_unpackhi_epi16( input[2], input[6] );     /* [ 24 64 25 65 26 66 27 67 ]*/
+   b6 = _mm_unpacklo_epi16( input[3], input[7] );     /* [ 30 70 31 71 32 72 33 73 ]*/
+   b7 = _mm_unpackhi_epi16( input[3], input[7] );     /* [ 34 74 35 75 36 76 37 77 ]*/
+ 
+   a0 = _mm_unpacklo_epi16( b0, b4 );                 /* [ 00 20 40 60 01 21 41 61 ]*/
+   a1 = _mm_unpackhi_epi16( b0, b4 );                 /* [ 02 22 42 62 03 23 43 63 ]*/
+   a2 = _mm_unpacklo_epi16( b1, b5 );                 /* [ 04 24 44 64 05 25 45 65 ]*/
+   a3 = _mm_unpackhi_epi16( b1, b5 );                 /* [ 06 26 46 66 07 27 47 67 ]*/
+   a4 = _mm_unpacklo_epi16( b2, b6 );                 /* [ 10 30 50 70 11 31 51 71 ]*/
+   a5 = _mm_unpackhi_epi16( b2, b6 );                 /* [ 12 32 52 72 13 33 53 73 ]*/
+   a6 = _mm_unpacklo_epi16( b3, b7 );                 /* [ 14 34 54 74 15 35 55 75 ]*/
+   a7 = _mm_unpackhi_epi16( b3, b7 );                 /* [ 16 36 56 76 17 37 57 77 ]*/
+ 
+   output[0] = _mm_unpacklo_epi16( a0, a4 );          /* [ 00 10 20 30 40 50 60 70 ]*/
+   output[1] = _mm_unpackhi_epi16( a0, a4 );          /* [ 01 11 21 31 41 51 61 71 ]*/
+   output[2] = _mm_unpacklo_epi16( a1, a5 );          /* [ 02 12 22 32 42 52 62 72 ]*/
+   output[3] = _mm_unpackhi_epi16( a1, a5 );          /* [ 03 13 23 33 43 53 63 73 ]*/
+   output[4] = _mm_unpacklo_epi16( a2, a6 );          /* [ 04 14 24 34 44 54 64 74 ]*/
+   output[5] = _mm_unpackhi_epi16( a2, a6 );          /* [ 05 15 25 35 45 55 65 75 ]*/
+   output[6] = _mm_unpacklo_epi16( a3, a7 );          /* [ 06 16 26 36 46 56 66 76 ]*/
+   output[7] = _mm_unpackhi_epi16( a3, a7 );          /* [ 07 17 27 37 47 57 67 77 ]*/
+ 
+ }
+ 
+ static inline void DCT_Transform ( short *x, short *y) {
+   __m128i *vx = (__m128i*) x;
+   __m128i *vy = (__m128i*) y;
+ 
+   __m128i t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10;
+ 
+   __m128i c13573 = _mm_splat_epi16(13573);
+   __m128i c21895 = _mm_splat_epi16(21895);
+   __m128i cNeg21895 = _mm_splat_epi16(-21895);
+   __m128i c23170 = _mm_splat_epi16(23170);
+   __m128i cNeg23170 = _mm_splat_epi16(-23170);
+   __m128i c6518 = _mm_splat_epi16(6518);
+ 
+   t8 = _mm_adds_epi16(vx[0], vx[7]);
+   t9 = _mm_subs_epi16(vx[0], vx[7]);
+   t0 = _mm_adds_epi16(vx[1], vx[6]);
+   t7 = _mm_subs_epi16(vx[1], vx[6]);
+   t1 = _mm_adds_epi16(vx[2], vx[5]);
+   t6 = _mm_subs_epi16(vx[2], vx[5]);
+   t2 = _mm_adds_epi16(vx[3], vx[4]);
+   t5 = _mm_subs_epi16(vx[3], vx[4]);
+ 
+   t3 = _mm_adds_epi16(t8, t2);
+   t4 = _mm_subs_epi16(t8, t2);
+   t2 = _mm_adds_epi16(t0, t1);
+   t8 = _mm_subs_epi16(t0, t1);
+ 
+   t1 = _mm_adds_epi16(t7, t6);
+   t0 = _mm_subs_epi16(t7, t6);
+ 
+   vy[0] = _mm_adds_epi16(t3, t2);
+   vy[4] = _mm_subs_epi16(t3, t2);
+ 
+   vy[2] = _mm_mradds_epi16(t8, c13573, t4);
+   t10 = _mm_mr_epi16(t4, c13573);
+ 
+   vy[6] = _mm_subs_epi16(t10, t8);
+ 
+   t6 = _mm_mradds_epi16(t0, c23170, t5);
+   t7 = _mm_mradds_epi16(t0, cNeg23170, t5);
+   t2 = _mm_mradds_epi16(t1, cNeg23170, t9);
+   t3 = _mm_mradds_epi16(t1, c23170, t9);
+ 
+   vy[1] = _mm_mradds_epi16(t6, c6518, t3);
+   t9 = _mm_mr_epi16(t3, c6518);
+ 
+   vy[7] = _mm_subs_epi16(t9, t6);
+   vy[5] = _mm_mradds_epi16(t2, c21895, t7);
+   vy[3] = _mm_mradds_epi16(t7, cNeg21895, t2);
+ 
+ }
+ 
+ #define STORE(i) \
+      outputv[i] = _mm_mradds_epi16(PostScalev[i], yv[i], _mm_splat_epi16(0));
+ 
+ void dct_vector(short *input, short *output, short *x, short *y) {
+ 
+   __m128i *xv = (__m128i*) x;
+   __m128i *yv = (__m128i*) y;
+   __m128i *inputv = (__m128i*) input;
+   __m128i *outputv = (__m128i*) output;
+   __m128i *PostScalev = (__m128i*) PostScalePtr;
+ 
+   xv[0] = inputv[0];
+   xv[1] = inputv[1];
+   xv[2] = inputv[2];
+   xv[3] = inputv[3];
+   xv[4] = inputv[4];
+   xv[5] = inputv[5];
+   xv[6] = inputv[6];
+   xv[7] = inputv[7];
+ 
+   DCT_Transform( x, y );
+   Matrix_Transpose( y, x );
+   DCT_Transform( x, y );
+ 
+   STORE(0);
+   STORE(1);
+   STORE(2);
+   STORE(3);
+   STORE(4);
+   STORE(5);
+   STORE(6);
+   STORE(7);
+ 
+ }
+ 


Index: llvm/examples/SIMD/DCT/dct.vectorc.c
diff -c /dev/null llvm/examples/SIMD/DCT/dct.vectorc.c:1.1.2.1
*** /dev/null	Sun Oct 23 17:50:18 2005
--- llvm/examples/SIMD/DCT/dct.vectorc.c	Sun Oct 23 17:49:39 2005
***************
*** 0 ****
--- 1,140 ----
+ #include "Scalar.h"
+ #include "VectorC.h"
+ #include "Intrinsics.h"
+ 
+ // See the rgb2yuv benchmark for a description of USE_C0.  For some
+ // reason, USE_C0 1 seems to be slightly *faster* on SSE!  I'm
+ // investigating why this is.
+ //
+ #define USE_C0 1
+ 
+ short vllvm_adds_short(short,short);
+ 
+ #define MERGE(out01, out0, out1, in0, in1) \
+   short out01 = vllvm_fixed_vimm_short(0, 16); \
+   out01 = _fixed_combine_short(out01, 16, in0, 8, 0, 1); \
+   out01 = _fixed_combine_short(out01, 16, in1, 8, 8, 1); \
+   short out0 = _extract_short(out01, 0, 2, 8); \
+   short out1 = _extract_short(out01, 1, 2, 8)
+ 
+ #define IN(x) \
+   vllvm_load_short(input_scalar, 8, x)
+ 
+ #define STORE(out, idx) \
+   vllvm_store_short(out, output_scalar, idx)
+ 
+ static inline void Matrix_Transpose_VectorC (short *input_scalar, short *output_scalar) {
+   MERGE(b01, b0, b1, IN(0), IN(4));
+   MERGE(b23, b2, b3, IN(1), IN(5));
+   MERGE(b45, b4, b5, IN(2), IN(6));
+   MERGE(b67, b6, b7, IN(3), IN(7));
+ 
+   MERGE(a01, a0, a1, b0, b4);
+   MERGE(a23, a2, a3, b1, b5);
+   MERGE(a45, a4, a5, b2, b6);
+   MERGE(a67, a6, a7, b3, b7);
+ 
+   MERGE(out01, out0, out1, a0, a4);
+   MERGE(out23, out2, out3, a1, a5);
+   MERGE(out45, out4, out5, a2, a6);
+   MERGE(out67, out6, out7, a3, a7);
+ 
+   STORE(out0, 0);
+   STORE(out1, 1);
+   STORE(out2, 2);
+   STORE(out3, 3);
+   STORE(out4, 4);
+   STORE(out5, 5);
+   STORE(out6, 6);
+   STORE(out7, 7);
+ }
+ 
+ static inline void DCT_Transform_VectorC ( short *x, short *y) {
+   signed short t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10;
+ 
+   t8 = vllvm_adds_short(vllvm_load_short(x, 8, 0), vllvm_load_short(x, 8, 7));
+   t9 = vllvm_subs_short(vllvm_load_short(x, 8, 0), vllvm_load_short(x, 8, 7));
+   t0 = vllvm_adds_short(vllvm_load_short(x, 8, 1), vllvm_load_short(x, 8, 6));
+   t7 = vllvm_subs_short(vllvm_load_short(x, 8, 1), vllvm_load_short(x, 8, 6));
+   t1 = vllvm_adds_short(vllvm_load_short(x, 8, 2), vllvm_load_short(x, 8, 5));
+   t6 = vllvm_subs_short(vllvm_load_short(x, 8, 2), vllvm_load_short(x, 8, 5));
+   t2 = vllvm_adds_short(vllvm_load_short(x, 8, 3), vllvm_load_short(x, 8, 4));
+   t5 = vllvm_subs_short(vllvm_load_short(x, 8, 3), vllvm_load_short(x, 8, 4));
+ 
+   t3 = vllvm_adds_short(t8, t2);
+   t4 = vllvm_subs_short(t8, t2);
+   t2 = vllvm_adds_short(t0, t1);
+   t8 = vllvm_subs_short(t0, t1);
+ 
+   t1 = vllvm_adds_short(t7, t6);
+   t0 = vllvm_subs_short(t7, t6);
+ 
+   vllvm_store_short(vllvm_adds_short(t3, t2), y, 0);
+   vllvm_store_short(vllvm_subs_short(t3, t2), y, 4);
+ 
+   short c13573 = vllvm_fixed_vimm_short(13573, 8);
+ #if USE_C0
+   short c0 = vllvm_fixed_vimm_short(0, 8);
+ #endif
+   short c23170 = vllvm_fixed_vimm_short(23170, 8);
+   short cneg23170 = vllvm_fixed_vimm_short(-23170, 8);
+   short c6518 = vllvm_fixed_vimm_short(6518, 8);
+ 
+   vllvm_store_short(vllvm_mradds_short(t8, c13573, t4), y, 2);
+ #if USE_C0
+   t10 = vllvm_mradds_short(t4, c13573, c0);
+ #else
+   t10 = vllvm_mr_short(t4, c13573);
+ #endif
+   vllvm_store_short(vllvm_subs_short(t10, t8), y, 6);
+ 
+   t6 = vllvm_mradds_short(t0, c23170, t5);
+   t7 = vllvm_mradds_short(t0, cneg23170, t5);
+   t2 = vllvm_mradds_short(t1, cneg23170, t9);
+   t3 = vllvm_mradds_short(t1, c23170, t9);
+ 
+   vllvm_store_short(vllvm_mradds_short(t6, c6518, t3), y, 1);
+ #if USE_C0
+   t9 = vllvm_mradds_short(t3, c6518, c0);
+ #else
+   t9 = vllvm_mr_short(t3, c6518);
+ #endif
+   vllvm_store_short(vllvm_subs_short(t9, t6), y, 7);
+   vllvm_store_short(vllvm_mradds_short(t2, vllvm_fixed_vimm_short(21895, 8), t7), y, 5);
+   vllvm_store_short(vllvm_mradds_short(t7, vllvm_fixed_vimm_short(-21895, 8), t2), y, 3);
+ 
+ }
+ 
+ extern short *PostScalePtr;
+ 
+ #define STORE2(i) \
+     vllvm_store_short(vllvm_mradds_short(vllvm_load_short(PostScalePtr, 8, i), \
+ 					   vllvm_load_short(y, 8, i), \
+ 					   vllvm_fixed_vimm_short(0, 8)), \
+ 			output, i);
+ 
+ void dct_vector(short *input, short *output, short *x, short *y) {
+ 
+   vllvm_store_short(vllvm_load_short(input, 8, 0), x, 0);
+   vllvm_store_short(vllvm_load_short(input, 8, 1), x, 1);
+   vllvm_store_short(vllvm_load_short(input, 8, 2), x, 2);
+   vllvm_store_short(vllvm_load_short(input, 8, 3), x, 3);
+   vllvm_store_short(vllvm_load_short(input, 8, 4), x, 4);
+   vllvm_store_short(vllvm_load_short(input, 8, 5), x, 5);
+   vllvm_store_short(vllvm_load_short(input, 8, 6), x, 6);
+   vllvm_store_short(vllvm_load_short(input, 8, 7), x, 7);
+   DCT_Transform_VectorC( x, y );
+   Matrix_Transpose_VectorC( y, x );
+   DCT_Transform_VectorC( x, y );
+ 
+   STORE2(0);
+   STORE2(1);
+   STORE2(2);
+   STORE2(3);
+   STORE2(4);
+   STORE2(5);
+   STORE2(6);
+   STORE2(7);
+ 
+ }
+ 


Index: llvm/examples/SIMD/DCT/main.c
diff -c /dev/null llvm/examples/SIMD/DCT/main.c:1.1.2.1
*** /dev/null	Sun Oct 23 17:50:18 2005
--- llvm/examples/SIMD/DCT/main.c	Sun Oct 23 17:49:39 2005
***************
*** 0 ****
--- 1,175 ----
+ #define N 1024
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <sys/time.h>
+ #include <sys/times.h>
+ #include "../_malloc.h"
+ #include "Scalar.h"
+ 
+ inline void dct_scalar(short*, short*);
+ void dct_vector(short*, short*, short*, short*);
+ 
+ short *in;
+ short *out_vector;
+ short *out_scalar;
+ 
+ static short PostScaleArray[64] = {
+     4095, 5681, 5351, 4816, 4095, 4816, 5351, 5681,
+     5681, 7880, 7422, 6680, 5681, 6680, 7422, 7880,
+     5351, 7422, 6992, 6292, 5351, 6292, 6992, 7422,
+     4816, 6680, 6292, 5663, 4816, 5663, 6292, 6680,
+     4095, 5681, 5351, 4816, 4095, 4816, 5351, 5681,
+     4816, 6680, 6292, 5663, 4816, 5663, 6292, 6680,
+     5351, 7422, 6992, 6292, 5351, 6292, 6992, 7422,
+     5681, 7880, 7422, 6680, 5681, 6680, 7422, 7880
+ };
+ 
+ short *PostScalePtr;
+ 
+ void init() {
+   int i;
+ 
+   // Force 16-byte alignment
+   //
+   in = (short*) _malloc(N*sizeof(short));
+   out_vector = (short*) _malloc(N*sizeof(short));
+   out_scalar = (short*) _malloc(N*sizeof(short));
+   PostScalePtr = (short*) _malloc(64*sizeof(short));
+   memcpy(PostScalePtr, PostScaleArray, 64*sizeof(short));
+   
+   // Populate in with a range of values
+   //
+   for (i = 0; i < N; ++i) {
+     in[i] = N/2-i;
+   }
+   
+ }
+ 
+ float run() {
+   long t0, t1, t2;
+   int i,j;
+   struct tms buf_s, buf_e;
+   long scalar_time = 0, vector_time = 0;
+ 
+   times(&buf_s);
+   for (i = 0; i < 100000; ++i)
+     for (j = 0; j < N; j +=64)
+       dct_scalar(in+j, out_scalar+j);
+   times(&buf_e);
+   scalar_time = buf_e.tms_utime - buf_s.tms_utime;
+   printf("scalar time=%d, ", scalar_time);
+   
+   short *x = (short*) _malloc(64*sizeof(short));
+   short *y = (short*) _malloc(64*sizeof(short));
+   times(&buf_s);
+   for (i = 0; i < 100000; ++i)
+     for (j = 0; j < N; j +=64)
+       dct_vector(in+j, out_vector+j, x, y);
+   times(&buf_e);
+   vector_time = buf_e.tms_utime - buf_s.tms_utime;
+   printf("vector time=%d, ", vector_time);
+   
+   float speedup = ((float) scalar_time)/vector_time;
+   printf("speedup=%f\n", speedup);
+   
+   for (i = 0; i < N; i++) {
+     if (out_vector[i] != out_scalar[i]) {
+       printf("FAILED\n");
+       exit(1);
+     }
+   }
+   
+   return speedup;
+ }
+ 
+ int main (void) {
+   unsigned i;
+ 
+   init();
+ 
+   float best = 0;
+   for (i = 0; i < NRUNS; ++i) {
+     float speedup = run();
+     if (speedup > best)
+       best = speedup;
+   }
+   printf("best speedup=%f\n", best);
+ 
+   printf ("PASSED\n");
+   return 0;
+ 
+ }
+ 
+ static inline void Matrix_Transpose ( short *input, short *output) {
+   unsigned i;
+   for (i = 0; i < 8; ++i) {
+     output[i] = input[8*i];
+     output[8+i] = input[8*i+1];
+     output[16+i] = input[8*i+2];
+     output[24+i] = input[8*i+3];
+     output[32+i] = input[8*i+4];
+     output[40+i] = input[8*i+5];
+     output[48+i] = input[8*i+6];
+     output[56+i] = input[8*i+7];
+   }
+ }
+ 
+ static inline void DCT_Transform ( short *x, short *y) {
+   signed short t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10;
+ 
+   unsigned i;
+   for (i = 0; i < 8; ++i) {
+     t8 = adds_short(x[i], x[56+i]);
+     t9 = subs_short(x[i], x[56+i]);
+     t0 = adds_short(x[8+i], x[48+i]);
+     t7 = subs_short(x[8+i], x[48+i]);
+     t1 = adds_short(x[16+i], x[40+i]);
+     t6 = subs_short(x[16+i], x[40+i]);
+     t2 = adds_short(x[24+i], x[32+i]);
+     t5 = subs_short(x[24+i], x[32+i]);
+ 
+     t3 = adds_short(t8, t2);
+     t4 = subs_short(t8, t2);
+     t2 = adds_short(t0, t1);
+     t8 = subs_short(t0, t1);
+     
+     t1 = adds_short(t7, t6);
+     t0 = subs_short(t7, t6);
+ 
+     y[i] = adds_short(t3, t2);
+     y[32+i] = subs_short(t3, t2);
+     y[16+i] = mradds_short(t8, 13573, t4);
+     t10 = mradds_short(t4, 13573, 0);
+     y[48+i] = subs_short(t10, t8);
+ 
+     t6 = mradds_short(t0, 23170, t5);
+     t7 = mradds_short(t0, -23170, t5);
+     t2 = mradds_short(t1, -23170, t9);
+     t3 = mradds_short(t1, 23170, t9);
+ 
+     y[8+i] = mradds_short(t6, 6518, t3);
+     t9 = mradds_short(t3, 6518, 0);
+     y[56+i] = subs_short(t9, t6);
+     y[40+i] = mradds_short(t2, 21895, t7);
+     y[24+i] = mradds_short(t7, -21895, t2);
+   }
+ 
+ }
+ 
+ void dct_scalar(short *input, short *output) {
+ 
+   short x[64], y[64];
+   unsigned i, j;
+ 
+   memcpy(x, input, 64*sizeof(short));
+   DCT_Transform( x, y );
+   Matrix_Transpose( y, x );
+   DCT_Transform( x, y );
+ 
+   for (i = 0; i < 8; ++i)
+     for (j = 0; j < 8; ++j)
+       output[8*i+j] = mradds_short(PostScaleArray[8*i+j], y[8*i+j], 0);
+ }
+ 






More information about the llvm-commits mailing list