This commit is contained in:
Jay D Dee
2023-02-08 22:11:05 -05:00
parent da7030faa8
commit 520d4d5384
19 changed files with 260 additions and 798 deletions

View File

@@ -65,10 +65,6 @@ typedef union
#define u64_mov256_64( v ) u64_mov128_64( _mm256_castsi256_si128( v ) )
#define u32_mov256_32( v ) u32_mov128_32( _mm256_castsi256_si128( v ) )
// deprecated
//#define mm256_mov256_64 u64_mov256_64
//#define mm256_mov256_32 u32_mov256_32
// concatenate two 128 bit vectors into one 256 bit vector: { hi, lo }
#define mm256_concat_128( hi, lo ) \
_mm256_inserti128_si256( _mm256_castsi128_si256( lo ), hi, 1 )
@@ -151,10 +147,12 @@ static inline __m256i mm256_not( const __m256i v )
#endif
/*
// Unary negation of each element ( -v )
#define mm256_negate_64( v ) _mm256_sub_epi64( m256_zero, v )
#define mm256_negate_32( v ) _mm256_sub_epi32( m256_zero, v )
#define mm256_negate_16( v ) _mm256_sub_epi16( m256_zero, v )
*/
// Add 4 values, fewer dependencies than sequential addition.
@@ -176,44 +174,34 @@ static inline __m256i mm256_not( const __m256i v )
// AVX512 has ternary logic that supports any 3 input boolean expression.
// a ^ b ^ c
#define mm256_xor3( a, b, c ) \
_mm256_ternarylogic_epi64( a, b, c, 0x96 )
#define mm256_xor3( a, b, c ) _mm256_ternarylogic_epi64( a, b, c, 0x96 )
// legacy convenience only
#define mm256_xor4( a, b, c, d ) \
_mm256_xor_si256( a, mm256_xor3( b, c, d ) )
#define mm256_xor4( a, b, c, d ) _mm256_xor_si256( a, mm256_xor3( b, c, d ) )
// a & b & c
#define mm256_and3( a, b, c ) \
_mm256_ternarylogic_epi64( a, b, c, 0x80 )
#define mm256_and3( a, b, c ) _mm256_ternarylogic_epi64( a, b, c, 0x80 )
// a | b | c
#define mm256_or3( a, b, c ) \
_mm256_ternarylogic_epi64( a, b, c, 0xfe )
#define mm256_or3( a, b, c ) _mm256_ternarylogic_epi64( a, b, c, 0xfe )
// a ^ ( b & c )
#define mm256_xorand( a, b, c ) \
_mm256_ternarylogic_epi64( a, b, c, 0x78 )
#define mm256_xorand( a, b, c ) _mm256_ternarylogic_epi64( a, b, c, 0x78 )
// a & ( b ^ c )
#define mm256_andxor( a, b, c ) \
_mm256_ternarylogic_epi64( a, b, c, 0x60 )
#define mm256_andxor( a, b, c ) _mm256_ternarylogic_epi64( a, b, c, 0x60 )
// a ^ ( b | c )
#define mm256_xoror( a, b, c ) \
_mm256_ternarylogic_epi64( a, b, c, 0x1e )
#define mm256_xoror( a, b, c ) _mm256_ternarylogic_epi64( a, b, c, 0x1e )
// a ^ ( ~b & c )
#define mm256_xorandnot( a, b, c ) \
_mm256_ternarylogic_epi64( a, b, c, 0xd2 )
#define mm256_xorandnot( a, b, c ) _mm256_ternarylogic_epi64( a, b, c, 0xd2 )
// a | ( b & c )
#define mm256_orand( a, b, c ) \
_mm256_ternarylogic_epi64( a, b, c, 0xf8 )
#define mm256_orand( a, b, c ) _mm256_ternarylogic_epi64( a, b, c, 0xf8 )
// ~( a ^ b ), same as (~a) ^ b
#define mm256_xnor( a, b ) \
_mm256_ternarylogic_epi64( a, b, b, 0x81 )
#define mm256_xnor( a, b ) _mm256_ternarylogic_epi64( a, b, b, 0x81 )
#else
@@ -260,76 +248,6 @@ static inline __m256i mm256_not( const __m256i v )
#define mm256_movmask_32( v ) \
_mm256_castps_si256( _mm256_movmask_ps( _mm256_castsi256_ps( v ) ) )
// Diagonal blending
// Blend 4 64 bit elements from 4 vectors
#define mm256_diagonal_64( v3, v2, v1, v0 ) \
mm256_blend_epi32( _mm256_blend_epi32( v3, v2, 0x30 ), \
_mm256_blend_epi32( v1, v0, 0x03 ), 0x0f )
// Blend 8 32 bit elements from 8 vectors
#define mm256_diagonal_32( v7, v6, v5, v4, v3, v2, v1, v0 ) \
_mm256_blend_epi32( \
_mm256_blend_epi32( \
_mm256_blend_epi32( v7, v6, 0x40 ), \
_mm256_blend_epi32( v5, v4, 0x10 ) 0x30 ), \
_mm256_blend_epi32( \
_mm256_blend_epi32( v3, v2, 0x04) \
_mm256_blend_epi32( v1, v0, 0x01 ), 0x03 ), 0x0f )
// Blend 4 32 bit elements from each 128 bit lane.
#define mm256_diagonal128_32( v3, v2, v1, v0 ) \
_mm256_blend_epi32( \
_mm256_blend_epi32( v3, v2, 0x44) \
_mm256_blend_epi32( v1, v0, 0x11 ) )
/*
//
// Extended bit shift for concatenated packed elements from 2 vectors.
// Shift right returns low half, shift left return high half.
#if defined(__AVX512VBMI2__) && defined(__AVX512VL__)
#define mm256_shl2_64( v1, v2, c ) _mm256_shldi_epi64( v1, v2, c )
#define mm256_shr2_64( v1, v2, c ) _mm256_shrdi_epi64( v1, v2, c )
#define mm256_shl2_32( v1, v2, c ) _mm256_shldi_epi32( v1, v2, c )
#define mm256_shr2_32( v1, v2, c ) _mm256_shrdi_epi32( v1, v2, c )
#define mm256_shl2_16( v1, v2, c ) _mm256_shldi_epi16( v1, v2, c )
#define mm256_shr2_16( v1, v2, c ) _mm256_shrdi_epi16( v1, v2, c )
#else
#define mm256_shl2i_64( v1, v2, c ) \
_mm256_or_si256( _mm256_slli_epi64( v1, c ), \
_mm256_srli_epi64( v2, 64 - (c) ) )
#define mm512_shr2_64( v1, v2, c ) \
_mm256_or_si256( _mm256_srli_epi64( v2, c ), \
_mm256_slli_epi64( v1, 64 - (c) ) )
#define mm256_shl2_32( v1, v2, c ) \
_mm256_or_si256( _mm256_slli_epi32( v1, c ), \
_mm256_srli_epi32( v2, 32 - (c) ) )
#define mm256_shr2_32( v1, v2, c ) \
_mm256_or_si256( _mm256_srli_epi32( v2, c ), \
_mm256_slli_epi32( v1, 32 - (c) ) )
#define mm256_shl2_16( v1, v2, c ) \
_mm256_or_si256( _mm256_slli_epi16( v1, c ), \
_mm256_srli_epi16( v2, 16 - (c) ) )
#define mm256_shr2_16( v1, v2, c ) \
_mm256_or_si256( _mm256_srli_epi16( v2, c ), \
_mm256_slli_epi16( v1, 16 - (c) ) )
#endif
*/
//
// Bit rotations.
//
@@ -448,6 +366,16 @@ static inline __m256i mm256_not( const __m256i v )
#define mm256_shufll_64( v ) _mm256_permute4x64_epi64( v, 0x93 )
// Rotate 256 bit vector by one 32 bit element.
#if defined(__AVX512VL__)
static inline __m256i mm256_shuflr_32( const __m256i v )
{ return _mm256_alignr_epi32( v, v, 1 ); }
static inline __m256i mm256_shufll_32( const __m256i v )
{ return _mm256_alignr_epi32( v, v, 15 ); }
#else
#define mm256_shuflr_32( v ) \
_mm256_permutevar8x32_epi32( v, \
m256_const_64( 0x0000000000000007, 0x0000000600000005, \
@@ -458,6 +386,8 @@ static inline __m256i mm256_not( const __m256i v )
m256_const_64( 0x0000000600000005, 0x0000000400000003, \
0x0000000200000001, 0x0000000000000007 ) )
#endif
//
// Rotate elements within each 128 bit lane of 256 bit vector.