include/arithmetic/SSEPlus_arithmetic_SSE2.h

Go to the documentation of this file.
00001 //
00002 // Copyright (c) 2006-2008 Advanced Micro Devices, Inc. All Rights Reserved.
00003 // This software is subject to the Apache v2.0 License.
00004 //
00005 #ifndef __SSEPLUS_ARITHMETIC_SSE2_H__
00006 #define __SSEPLUS_ARITHMETIC_SSE2_H__
00007 
00008 #include "../native/SSEPlus_native_SSE2.h"
00009 #include "../emulation/SSEPlus_emulation_SSE2.h"
00010 
00016 SSP_FORCEINLINE
00017 __m128 ssp_arithmetic_hadd4_dup_ps_SSE2( __m128 a )      // [18 cycles]                 // Sum all 4 values
00018 {
00019     __m128 t;
00020     t = _mm_shuffle_ps( a, a, _MM_SHUFFLE(2, 3, 0, 1) );                //TODO shuflo, shuf hi
00021     a = _mm_add_ps( a, t );   
00022 
00023     t = _mm_shuffle_ps( a, a, _MM_SHUFFLE(1, 0, 3, 2) );                //TODO shuflo, shuf hi
00024     a = _mm_add_ps( a, t );
00025     return a;
00026 } 
00027 
00028 
00038 SSP_FORCEINLINE
00039 __m128i ssp_arithmetic_hadd4_epi16_SSE2( __m128i a, const unsigned int offset )      // Sum 2 sets of 4 values, dest in 0, and 4
00040 {
00041     ssp_m128 A,B;
00042     A.i = a;                                           //A = a, b, c, d | e, f, g, h
00043 
00044     if( offset >= 2 ) B.i = _mm_slli_si128( A.i, 4 );  //B = c, d, x, x | g, h, x, x
00045     else              B.i = _mm_srli_si128( A.i, 4 );  //B = x, x, a, b | x, x, e, f
00046 
00047     A.i = _mm_add_epi16 ( A.i, B.i );      
00048 
00049     if( offset & 1 )  B.i = _mm_slli_si128( A.i, 2 );  
00050     else              B.i = _mm_srli_si128( A.i, 2 ); 
00051   
00052     A.i = _mm_add_epi16 ( A.i, B.i );      
00053     return A.i;
00054 }  
00055 
00056 
00057 
00058 //__m128 ssp_arithmetic_hadd4_dup_ps_SSE2_a( __m128 a_ )      // [19 cycles]                 // Sum all 4 values
00059 //{
00060 //    ssp_m128 t, a; a.f = a_;
00061 //
00062 //    t.i  = _mm_shufflehi_epi16( a.i, _MM_SHUFFLE(1, 0, 3, 2) );
00063 //    t.i  = _mm_shufflelo_epi16( t.i, _MM_SHUFFLE(1, 0, 3, 2) );
00064 //    
00065 //    //t.f  = _mm_shuffle_ps( a, a, _MM_SHUFFLE(2, 3, 0, 1) );           //TODO shuflo, shuf hi   
00066 //
00067 //    a.f = _mm_add_ps    ( a.f, t.f );  
00068 //
00069 //    t.f = _mm_shuffle_ps( a.f, a.f, _MM_SHUFFLE(1, 0, 3, 2) );                //TODO shuflo, shuf hi
00070 //
00071 //
00072 //    a.f = _mm_add_ps    ( a.f, t.f );
00073 //    return a.f;
00074 //}  
00075 //
00076 //__m128 ssp_arithmetic_hadd4_dup_ps_SSE2_b( __m128 a )      // [18 cycles]                 // Sum all 4 values
00077 //{
00078 //    __m128 t;
00079 //    t = _mm_shuffle_ps( a, a, _MM_SHUFFLE(2, 3, 0, 1) );                //TODO shuflo, shuf hi
00080 //    a = _mm_add_ps( a, t );     
00081 //
00082 //    t = _mm_movelh_ps( t, a );
00083 //    t = _mm_movehl_ps( t, a );
00084 //   
00085 //    a = _mm_add_ps( a, t );
00086 //    return a;
00087 //}  
00088 
00090 SSP_FORCEINLINE
00091 __m128 ssp_round_ps_neg_zero_SSE2( __m128  a, int iRoundMode )
00092 {
00093     const static __m128i SIGN_BIT = SSP_CONST_SET_32I( 0x80000000, 0x80000000, 0x80000000,0x80000000 );
00094     ssp_m128 A, sign;
00095     A.f = a;
00096     
00097     sign.i = _mm_and_si128    ( A.i, SIGN_BIT );  // Store the sign bits
00098     A.f    = ssp_round_ps_SSE2( A.f, iRoundMode );   
00099     A.i    = _mm_or_si128     ( A.i, sign.i );    // Restore the sign bits (preserves -0)
00100    
00101     return A.f;
00102 }
00103 
00108 #endif // __SSEPLUS_ARITHMETIC_SSE2_H__

Generated on Wed May 21 13:44:11 2008 for "SSEPlus" by  doxygen 1.5.4