Mercurial > vec
comparison src/impl/x86/avx2.c @ 28:c6c99ab1088a
*: add min/max functions and a big big refactor (again)
agh, this time I added a few more implementations (and generally
made the code just a little faster...)
| author | Paper <paper@tflc.us> |
|---|---|
| date | Thu, 24 Apr 2025 00:54:02 -0400 |
| parents | e49e70f7012f |
| children | bf6ad516f1e6 |
comparison
equal
deleted
inserted
replaced
| 27:d00b95f95dd1 | 28:c6c99ab1088a |
|---|---|
| 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| 22 * SOFTWARE. | 22 * SOFTWARE. |
| 23 **/ | 23 **/ |
| 24 | 24 |
| 25 #include "vec/impl/x86/avx2.h" | 25 #include "vec/impl/x86/avx2.h" |
| 26 #include "vec/impl/generic.h" | |
| 27 | 26 |
| 28 #include <immintrin.h> | 27 #include <immintrin.h> |
| 29 | 28 |
| 30 // this does NOT handle sign bits properly, use with caution | 29 /* ------------------------------------------------------------------------ */ |
| 31 #define VEC_AVX2_OPERATION_8x32_16x16(op, sign) \ | 30 /* min/max */ |
| 32 do { \ | 31 |
| 33 union v##sign##int8x32_impl_data *vec1d = (union v##sign##int8x32_impl_data *)&vec1; \ | 32 #define VEC_AVX2_MINMAX_TEMPLATE(SIGN, BITS, SIZE, INTLSIGN, OP) \ |
| 34 union v##sign##int8x32_impl_data *vec2d = (union v##sign##int8x32_impl_data *)&vec2; \ | 33 VEC_FUNC_IMPL v##SIGN##int##BITS##x##SIZE v##SIGN##int##BITS##x##SIZE##_avx2_##OP(v##SIGN##int##BITS##x##SIZE vec1, v##SIGN##int##BITS##x##SIZE vec2) \ |
| 35 \ | 34 { \ |
| 36 /* unpack and multiply */ \ | 35 union v##SIGN##int##BITS##x##SIZE##_impl_data *vec1d = (union v##SIGN##int##BITS##x##SIZE##_impl_data *)&vec1; \ |
| 37 __m256i dst_even = _mm256_##op##_epi16(vec1d->avx2, vec2d->avx2); \ | 36 union v##SIGN##int##BITS##x##SIZE##_impl_data *vec2d = (union v##SIGN##int##BITS##x##SIZE##_impl_data *)&vec2; \ |
| 38 __m256i dst_odd = _mm256_##op##_epi16(_mm256_srli_epi16(vec1d->avx2, 8), _mm256_srli_epi16(vec2d->avx2, 8)); \ | 37 \ |
| 39 \ | 38 vec1d->avx2 = _mm256_##OP##_ep##INTLSIGN##BITS(vec1d->avx2, vec2d->avx2); \ |
| 40 /* repack */ \ | 39 \ |
| 41 vec1d->avx2 = _mm256_or_si256( \ | 40 return vec1d->vec; \ |
| 42 _mm256_slli_epi16(dst_odd, 8), \ | 41 } |
| 43 _mm256_srli_epi16(_mm256_slli_epi16(dst_even, 8), 8) \ | 42 |
| 44 ); \ | 43 #define VEC_AVX2_MINMAX_8x32(OP) VEC_AVX2_MINMAX_TEMPLATE( , 8, 32, i, OP) |
| 45 return vec1d->vec; \ | 44 #define VEC_AVX2_MINMAX_u8x32(OP) VEC_AVX2_MINMAX_TEMPLATE(u, 8, 32, u, OP) |
| 46 } while (0) | 45 #define VEC_AVX2_MINMAX_16x16(OP) VEC_AVX2_MINMAX_TEMPLATE( , 16, 16, i, OP) |
| 47 | 46 #define VEC_AVX2_MINMAX_u16x16(OP) VEC_AVX2_MINMAX_TEMPLATE(u, 16, 16, u, OP) |
| 48 #define VEC_AVX2_OPERATION_16x16(op, sign) \ | 47 #define VEC_AVX2_MINMAX_32x8(OP) VEC_AVX2_MINMAX_TEMPLATE( , 32, 8, i, OP) |
| 49 do { \ | 48 #define VEC_AVX2_MINMAX_u32x8(OP) VEC_AVX2_MINMAX_TEMPLATE(u, 32, 8, u, OP) |
| 49 #define VEC_AVX2_MINMAX_64x4(OP) /* nothing */ | |
| 50 #define VEC_AVX2_MINMAX_u64x4(OP) /* nothing */ | |
| 51 | |
| 52 #define VEC_AVX2_STRUCT_MINMAX_8x32(OP, SIGN) v##SIGN##int8x32_avx2_##OP | |
| 53 #define VEC_AVX2_STRUCT_MINMAX_16x16(OP, SIGN) v##SIGN##int16x16_avx2_##OP | |
| 54 #define VEC_AVX2_STRUCT_MINMAX_32x8(OP, SIGN) v##SIGN##int32x8_avx2_##OP | |
| 55 #define VEC_AVX2_STRUCT_MINMAX_64x4(OP, SIGN) NULL | |
| 56 | |
| 57 /* reused this for avg */ | |
| 58 | |
| 59 #define VEC_AVX2_AVG_8x32 /* nothing */ | |
| 60 #define VEC_AVX2_AVG_16x16 /* nothing */ | |
| 61 #define VEC_AVX2_AVG_32x8 /* nothing */ | |
| 62 #define VEC_AVX2_AVG_64x4 /* nothing */ | |
| 63 | |
| 64 #define VEC_AVX2_AVG_u8x32 VEC_AVX2_MINMAX_TEMPLATE(u, 8, 32, u, avg) | |
| 65 #define VEC_AVX2_AVG_u16x16 VEC_AVX2_MINMAX_TEMPLATE(u, 16, 16, u, avg) | |
| 66 #define VEC_AVX2_AVG_u32x8 /* nothing */ | |
| 67 #define VEC_AVX2_AVG_u64x4 /* nothing */ | |
| 68 | |
| 69 #define VEC_AVX2_STRUCT_AVG_8x32 NULL | |
| 70 #define VEC_AVX2_STRUCT_AVG_16x16 NULL | |
| 71 #define VEC_AVX2_STRUCT_AVG_32x8 NULL | |
| 72 #define VEC_AVX2_STRUCT_AVG_64x4 NULL | |
| 73 | |
| 74 #define VEC_AVX2_STRUCT_AVG_u8x32 vuint8x32_avx2_avg | |
| 75 #define VEC_AVX2_STRUCT_AVG_u16x16 vuint16x16_avx2_avg | |
| 76 #define VEC_AVX2_STRUCT_AVG_u32x8 NULL | |
| 77 #define VEC_AVX2_STRUCT_AVG_u64x4 NULL | |
| 78 | |
| 79 /* ------------------------------------------------------------------------ */ | |
| 80 | |
| 81 // multiplication | |
| 82 | |
| 83 #define VEC_AVX2_MUL_8x32(sign) /* nothing */ | |
| 84 | |
| 85 #define VEC_AVX2_MUL_16x16(sign) \ | |
| 86 VEC_FUNC_IMPL v##sign##int16x16 v##sign##int16x16_avx2_mul(v##sign##int16x16 vec1, v##sign##int16x16 vec2) \ | |
| 87 { \ | |
| 50 union v##sign##int16x16_impl_data *vec1d = (union v##sign##int16x16_impl_data *)&vec1; \ | 88 union v##sign##int16x16_impl_data *vec1d = (union v##sign##int16x16_impl_data *)&vec1; \ |
| 51 union v##sign##int16x16_impl_data *vec2d = (union v##sign##int16x16_impl_data *)&vec2; \ | 89 union v##sign##int16x16_impl_data *vec2d = (union v##sign##int16x16_impl_data *)&vec2; \ |
| 52 \ | 90 \ |
| 53 /* unpack and multiply */ \ | |
| 54 __m256i dst_even = _mm256_##op##_epi32(vec1d->avx2, vec2d->avx2); \ | |
| 55 __m256i dst_odd = _mm256_##op##_epi32(_mm256_srli_epi32(vec1d->avx2, 16), _mm256_srli_epi32(vec2d->avx2, 16)); \ | |
| 56 \ | |
| 57 /* repack */ \ | |
| 58 vec1d->avx2 = _mm256_or_si256( \ | |
| 59 _mm256_slli_epi32(dst_odd, 16), \ | |
| 60 _mm256_srli_epi32(_mm256_slli_epi16(dst_even, 16), 16) \ | |
| 61 ); \ | |
| 62 return vec1d->vec; \ | |
| 63 } while (0) | |
| 64 | |
| 65 // multiplication | |
| 66 | |
| 67 #define VEC_AVX2_MUL_8x32(sign) \ | |
| 68 VEC_AVX2_OPERATION_8x32_16x16(mullo, sign) | |
| 69 | |
| 70 #define VEC_AVX2_MUL_16x16(sign) \ | |
| 71 do { \ | |
| 72 union v##sign##int16x16_impl_data *vec1d = (union v##sign##int16x16_impl_data *)&vec1; \ | |
| 73 union v##sign##int16x16_impl_data *vec2d = (union v##sign##int16x16_impl_data *)&vec2; \ | |
| 74 \ | |
| 75 vec1d->avx2 = _mm256_mullo_epi16(vec1d->avx2, vec2d->avx2); \ | 91 vec1d->avx2 = _mm256_mullo_epi16(vec1d->avx2, vec2d->avx2); \ |
| 76 return vec1d->vec; \ | 92 return vec1d->vec; \ |
| 77 } while (0) | 93 } |
| 78 | 94 |
| 79 #define VEC_AVX2_MUL_32x8(sign) \ | 95 #define VEC_AVX2_MUL_32x8(sign) \ |
| 80 do { \ | 96 VEC_FUNC_IMPL v##sign##int32x8 v##sign##int32x8_avx2_mul(v##sign##int32x8 vec1, v##sign##int32x8 vec2) \ |
| 97 { \ | |
| 81 union v##sign##int32x8_impl_data *vec1d = (union v##sign##int32x8_impl_data *)&vec1; \ | 98 union v##sign##int32x8_impl_data *vec1d = (union v##sign##int32x8_impl_data *)&vec1; \ |
| 82 union v##sign##int32x8_impl_data *vec2d = (union v##sign##int32x8_impl_data *)&vec2; \ | 99 union v##sign##int32x8_impl_data *vec2d = (union v##sign##int32x8_impl_data *)&vec2; \ |
| 83 \ | 100 \ |
| 84 vec1d->avx2 = _mm256_mullo_epi32(vec1d->avx2, vec2d->avx2); \ | 101 vec1d->avx2 = _mm256_mullo_epi32(vec1d->avx2, vec2d->avx2); \ |
| 85 return vec1d->vec; \ | 102 return vec1d->vec; \ |
| 86 } while (0) | 103 } |
| 87 | 104 |
| 88 #define VEC_AVX2_MUL_64x4(sign) \ | 105 #define VEC_AVX2_MUL_64x4(sign) \ |
| 89 do { \ | 106 VEC_FUNC_IMPL v##sign##int64x4 v##sign##int64x4_avx2_mul(v##sign##int64x4 vec1, v##sign##int64x4 vec2) \ |
| 107 { \ | |
| 90 union v##sign##int64x4_impl_data *vec1d = (union v##sign##int64x4_impl_data *)&vec1; \ | 108 union v##sign##int64x4_impl_data *vec1d = (union v##sign##int64x4_impl_data *)&vec1; \ |
| 91 union v##sign##int64x4_impl_data *vec2d = (union v##sign##int64x4_impl_data *)&vec2; \ | 109 union v##sign##int64x4_impl_data *vec2d = (union v##sign##int64x4_impl_data *)&vec2; \ |
| 92 \ | 110 \ |
| 93 __m256i ac = _mm256_mul_epu32(vec1d->avx2, vec2d->avx2); \ | 111 __m256i ac = _mm256_mul_epu32(vec1d->avx2, vec2d->avx2); \ |
| 94 __m256i b = _mm256_srli_epi64(vec1d->avx2, 32); \ | 112 __m256i b = _mm256_srli_epi64(vec1d->avx2, 32); \ |
| 98 __m256i hi = _mm256_add_epi64(bc, ad); \ | 116 __m256i hi = _mm256_add_epi64(bc, ad); \ |
| 99 hi = _mm256_slli_epi64(hi, 32); \ | 117 hi = _mm256_slli_epi64(hi, 32); \ |
| 100 \ | 118 \ |
| 101 vec1d->avx2 = _mm256_add_epi64(hi, ac); \ | 119 vec1d->avx2 = _mm256_add_epi64(hi, ac); \ |
| 102 return vec1d->vec; \ | 120 return vec1d->vec; \ |
| 103 } while (0) | 121 } |
| 122 | |
| 123 #define VEC_AVX2_STRUCT_MUL_8x32(SIGN) NULL | |
| 124 #define VEC_AVX2_STRUCT_MUL_16x16(SIGN) v##SIGN##int16x16_avx2_mul | |
| 125 #define VEC_AVX2_STRUCT_MUL_32x8(SIGN) v##SIGN##int32x8_avx2_mul | |
| 126 #define VEC_AVX2_STRUCT_MUL_64x4(SIGN) v##SIGN##int64x4_avx2_mul | |
| 104 | 127 |
| 105 // operations | 128 // operations |
| 106 | 129 |
| 107 #define VEC_AVX2_DEFINE_OPERATIONS_SIGN(sign, bits, size) \ | 130 #define VEC_AVX2_DEFINE_OPERATIONS_SIGN(sign, bits, size) \ |
| 108 union v##sign##int##bits##x##size##_impl_data { \ | 131 union v##sign##int##bits##x##size##_impl_data { \ |
| 111 }; \ | 134 }; \ |
| 112 \ | 135 \ |
| 113 VEC_STATIC_ASSERT(VEC_ALIGNOF(__m256i) <= VEC_ALIGNOF(v##sign##int##bits##x##size), "vec: v" #sign "int" #bits "x" #size " alignment needs to be expanded to fit intrinsic type size"); \ | 136 VEC_STATIC_ASSERT(VEC_ALIGNOF(__m256i) <= VEC_ALIGNOF(v##sign##int##bits##x##size), "vec: v" #sign "int" #bits "x" #size " alignment needs to be expanded to fit intrinsic type size"); \ |
| 114 VEC_STATIC_ASSERT(sizeof(__m256i) <= sizeof(v##sign##int##bits##x##size), "vec: v" #sign "int" #bits "x" #size " needs to be expanded to fit intrinsic type size"); \ | 137 VEC_STATIC_ASSERT(sizeof(__m256i) <= sizeof(v##sign##int##bits##x##size), "vec: v" #sign "int" #bits "x" #size " needs to be expanded to fit intrinsic type size"); \ |
| 115 \ | 138 \ |
| 116 static v##sign##int##bits##x##size v##sign##int##bits##x##size##_avx2_load_aligned(const vec_##sign##int##bits in[size]) \ | 139 VEC_FUNC_IMPL v##sign##int##bits##x##size v##sign##int##bits##x##size##_avx2_load_aligned(const vec_##sign##int##bits in[size]) \ |
| 117 { \ | 140 { \ |
| 118 union v##sign##int##bits##x##size##_impl_data vec; \ | 141 union v##sign##int##bits##x##size##_impl_data vec; \ |
| 119 vec.avx2 = _mm256_load_si256((const __m256i *)in); \ | 142 vec.avx2 = _mm256_load_si256((const __m256i *)in); \ |
| 120 return vec.vec; \ | 143 return vec.vec; \ |
| 121 } \ | 144 } \ |
| 122 \ | 145 \ |
| 123 static v##sign##int##bits##x##size v##sign##int##bits##x##size##_avx2_load(const vec_##sign##int##bits in[size]) \ | 146 VEC_FUNC_IMPL v##sign##int##bits##x##size v##sign##int##bits##x##size##_avx2_load(const vec_##sign##int##bits in[size]) \ |
| 124 { \ | 147 { \ |
| 125 union v##sign##int##bits##x##size##_impl_data vec; \ | 148 union v##sign##int##bits##x##size##_impl_data vec; \ |
| 126 vec.avx2 = _mm256_loadu_si256((const __m256i *)in); \ | 149 vec.avx2 = _mm256_loadu_si256((const __m256i *)in); \ |
| 127 return vec.vec; \ | 150 return vec.vec; \ |
| 128 } \ | 151 } \ |
| 129 \ | 152 \ |
| 130 static void v##sign##int##bits##x##size##_avx2_store_aligned(v##sign##int##bits##x##size vec, vec_##sign##int##bits out[size]) \ | 153 VEC_FUNC_IMPL void v##sign##int##bits##x##size##_avx2_store_aligned(v##sign##int##bits##x##size vec, vec_##sign##int##bits out[size]) \ |
| 131 { \ | 154 { \ |
| 132 _mm256_store_si256((__m256i *)out, ((union v##sign##int##bits##x##size##_impl_data*)&vec)->avx2); \ | 155 _mm256_store_si256((__m256i *)out, ((union v##sign##int##bits##x##size##_impl_data*)&vec)->avx2); \ |
| 133 } \ | 156 } \ |
| 134 \ | 157 \ |
| 135 static void v##sign##int##bits##x##size##_avx2_store(v##sign##int##bits##x##size vec, vec_##sign##int##bits out[size]) \ | 158 VEC_FUNC_IMPL void v##sign##int##bits##x##size##_avx2_store(v##sign##int##bits##x##size vec, vec_##sign##int##bits out[size]) \ |
| 136 { \ | 159 { \ |
| 137 _mm256_storeu_si256((__m256i *)out, ((union v##sign##int##bits##x##size##_impl_data*)&vec)->avx2); \ | 160 _mm256_storeu_si256((__m256i *)out, ((union v##sign##int##bits##x##size##_impl_data*)&vec)->avx2); \ |
| 138 } \ | 161 } \ |
| 139 \ | 162 \ |
| 140 static v##sign##int##bits##x##size v##sign##int##bits##x##size##_avx2_add(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \ | 163 VEC_FUNC_IMPL v##sign##int##bits##x##size v##sign##int##bits##x##size##_avx2_add(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \ |
| 141 { \ | 164 { \ |
| 142 union v##sign##int##bits##x##size##_impl_data *vec1d = (union v##sign##int##bits##x##size##_impl_data *)&vec1; \ | 165 union v##sign##int##bits##x##size##_impl_data *vec1d = (union v##sign##int##bits##x##size##_impl_data *)&vec1; \ |
| 143 union v##sign##int##bits##x##size##_impl_data *vec2d = (union v##sign##int##bits##x##size##_impl_data *)&vec2; \ | 166 union v##sign##int##bits##x##size##_impl_data *vec2d = (union v##sign##int##bits##x##size##_impl_data *)&vec2; \ |
| 144 \ | 167 \ |
| 145 vec1d->avx2 = _mm256_add_epi##bits(vec1d->avx2, vec2d->avx2); \ | 168 vec1d->avx2 = _mm256_add_epi##bits(vec1d->avx2, vec2d->avx2); \ |
| 146 return vec1d->vec; \ | 169 return vec1d->vec; \ |
| 147 } \ | 170 } \ |
| 148 \ | 171 \ |
| 149 static v##sign##int##bits##x##size v##sign##int##bits##x##size##_avx2_sub(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \ | 172 VEC_FUNC_IMPL v##sign##int##bits##x##size v##sign##int##bits##x##size##_avx2_sub(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \ |
| 150 { \ | 173 { \ |
| 151 union v##sign##int##bits##x##size##_impl_data *vec1d = (union v##sign##int##bits##x##size##_impl_data *)&vec1; \ | 174 union v##sign##int##bits##x##size##_impl_data *vec1d = (union v##sign##int##bits##x##size##_impl_data *)&vec1; \ |
| 152 union v##sign##int##bits##x##size##_impl_data *vec2d = (union v##sign##int##bits##x##size##_impl_data *)&vec2; \ | 175 union v##sign##int##bits##x##size##_impl_data *vec2d = (union v##sign##int##bits##x##size##_impl_data *)&vec2; \ |
| 153 \ | 176 \ |
| 154 vec1d->avx2 = _mm256_sub_epi##bits(vec1d->avx2, vec2d->avx2); \ | 177 vec1d->avx2 = _mm256_sub_epi##bits(vec1d->avx2, vec2d->avx2); \ |
| 155 return vec1d->vec; \ | 178 return vec1d->vec; \ |
| 156 } \ | 179 } \ |
| 157 \ | 180 \ |
| 158 static v##sign##int##bits##x##size v##sign##int##bits##x##size##_avx2_mul(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \ | 181 VEC_AVX2_MUL_##bits##x##size(sign) \ |
| 159 { \ | 182 \ |
| 160 VEC_AVX2_MUL_##bits##x##size(sign); \ | 183 VEC_FUNC_IMPL v##sign##int##bits##x##size v##sign##int##bits##x##size##_avx2_and(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \ |
| 161 } \ | |
| 162 \ | |
| 163 static v##sign##int##bits##x##size v##sign##int##bits##x##size##_avx2_and(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \ | |
| 164 { \ | 184 { \ |
| 165 union v##sign##int##bits##x##size##_impl_data *vec1d = (union v##sign##int##bits##x##size##_impl_data *)&vec1; \ | 185 union v##sign##int##bits##x##size##_impl_data *vec1d = (union v##sign##int##bits##x##size##_impl_data *)&vec1; \ |
| 166 union v##sign##int##bits##x##size##_impl_data *vec2d = (union v##sign##int##bits##x##size##_impl_data *)&vec2; \ | 186 union v##sign##int##bits##x##size##_impl_data *vec2d = (union v##sign##int##bits##x##size##_impl_data *)&vec2; \ |
| 167 \ | 187 \ |
| 168 vec1d->avx2 = _mm256_and_si256(vec1d->avx2, vec2d->avx2); \ | 188 vec1d->avx2 = _mm256_and_si256(vec1d->avx2, vec2d->avx2); \ |
| 169 return vec1d->vec; \ | 189 return vec1d->vec; \ |
| 170 } \ | 190 } \ |
| 171 \ | 191 \ |
| 172 static v##sign##int##bits##x##size v##sign##int##bits##x##size##_avx2_or(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \ | 192 VEC_FUNC_IMPL v##sign##int##bits##x##size v##sign##int##bits##x##size##_avx2_or(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \ |
| 173 { \ | 193 { \ |
| 174 union v##sign##int##bits##x##size##_impl_data *vec1d = (union v##sign##int##bits##x##size##_impl_data *)&vec1; \ | 194 union v##sign##int##bits##x##size##_impl_data *vec1d = (union v##sign##int##bits##x##size##_impl_data *)&vec1; \ |
| 175 union v##sign##int##bits##x##size##_impl_data *vec2d = (union v##sign##int##bits##x##size##_impl_data *)&vec2; \ | 195 union v##sign##int##bits##x##size##_impl_data *vec2d = (union v##sign##int##bits##x##size##_impl_data *)&vec2; \ |
| 176 \ | 196 \ |
| 177 vec1d->avx2 = _mm256_or_si256(vec1d->avx2, vec2d->avx2); \ | 197 vec1d->avx2 = _mm256_or_si256(vec1d->avx2, vec2d->avx2); \ |
| 178 return vec1d->vec; \ | 198 return vec1d->vec; \ |
| 179 } \ | 199 } \ |
| 180 \ | 200 \ |
| 181 static v##sign##int##bits##x##size v##sign##int##bits##x##size##_avx2_xor(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \ | 201 VEC_FUNC_IMPL v##sign##int##bits##x##size v##sign##int##bits##x##size##_avx2_xor(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \ |
| 182 { \ | 202 { \ |
| 183 union v##sign##int##bits##x##size##_impl_data *vec1d = (union v##sign##int##bits##x##size##_impl_data *)&vec1; \ | 203 union v##sign##int##bits##x##size##_impl_data *vec1d = (union v##sign##int##bits##x##size##_impl_data *)&vec1; \ |
| 184 union v##sign##int##bits##x##size##_impl_data *vec2d = (union v##sign##int##bits##x##size##_impl_data *)&vec2; \ | 204 union v##sign##int##bits##x##size##_impl_data *vec2d = (union v##sign##int##bits##x##size##_impl_data *)&vec2; \ |
| 185 \ | 205 \ |
| 186 vec1d->avx2 = _mm256_xor_si256(vec1d->avx2, vec2d->avx2); \ | 206 vec1d->avx2 = _mm256_xor_si256(vec1d->avx2, vec2d->avx2); \ |
| 187 return vec1d->vec; \ | 207 return vec1d->vec; \ |
| 188 } \ | 208 } \ |
| 189 \ | 209 \ |
| 210 VEC_AVX2_AVG_##sign##bits##x##size \ | |
| 211 \ | |
| 212 VEC_AVX2_MINMAX_##sign##bits##x##size(min) \ | |
| 213 VEC_AVX2_MINMAX_##sign##bits##x##size(max) \ | |
| 214 \ | |
| 190 const v##sign##int##bits##x##size##_impl v##sign##int##bits##x##size##_impl_avx2 = { \ | 215 const v##sign##int##bits##x##size##_impl v##sign##int##bits##x##size##_impl_avx2 = { \ |
| 191 v##sign##int##bits##x##size##_generic_splat, \ | 216 .load_aligned = v##sign##int##bits##x##size##_avx2_load_aligned, \ |
| 192 v##sign##int##bits##x##size##_avx2_load_aligned, \ | 217 .load = v##sign##int##bits##x##size##_avx2_load, \ |
| 193 v##sign##int##bits##x##size##_avx2_load, \ | 218 .store_aligned = v##sign##int##bits##x##size##_avx2_store_aligned, \ |
| 194 v##sign##int##bits##x##size##_avx2_store_aligned, \ | 219 .store = v##sign##int##bits##x##size##_avx2_store, \ |
| 195 v##sign##int##bits##x##size##_avx2_store, \ | 220 .add = v##sign##int##bits##x##size##_avx2_add, \ |
| 196 v##sign##int##bits##x##size##_avx2_add, \ | 221 .sub = v##sign##int##bits##x##size##_avx2_sub, \ |
| 197 v##sign##int##bits##x##size##_avx2_sub, \ | 222 .mul = VEC_AVX2_STRUCT_MUL_##bits##x##size(sign), \ |
| 198 v##sign##int##bits##x##size##_avx2_mul, \ | 223 .band = v##sign##int##bits##x##size##_avx2_and, \ |
| 199 v##sign##int##bits##x##size##_generic_div, \ | 224 .bor = v##sign##int##bits##x##size##_avx2_or, \ |
| 200 v##sign##int##bits##x##size##_generic_avg, \ | 225 .bxor = v##sign##int##bits##x##size##_avx2_xor, \ |
| 201 v##sign##int##bits##x##size##_avx2_and, \ | 226 .min = VEC_AVX2_STRUCT_MINMAX_##bits##x##size(min, sign), \ |
| 202 v##sign##int##bits##x##size##_avx2_or, \ | 227 .max = VEC_AVX2_STRUCT_MINMAX_##bits##x##size(max, sign), \ |
| 203 v##sign##int##bits##x##size##_avx2_xor, \ | 228 .avg = VEC_AVX2_STRUCT_AVG_##sign##bits##x##size, \ |
| 204 v##sign##int##bits##x##size##_generic_not, \ | |
| 205 v##sign##int##bits##x##size##_generic_lshift, \ | |
| 206 v##sign##int##bits##x##size##_generic_rshift, \ | |
| 207 v##sign##int##bits##x##size##_generic_lrshift, \ | |
| 208 v##sign##int##bits##x##size##_generic_cmplt, \ | |
| 209 v##sign##int##bits##x##size##_generic_cmple, \ | |
| 210 v##sign##int##bits##x##size##_generic_cmpeq, \ | |
| 211 v##sign##int##bits##x##size##_generic_cmpge, \ | |
| 212 v##sign##int##bits##x##size##_generic_cmpgt, \ | |
| 213 }; | 229 }; |
| 214 | 230 |
| 215 #define VEC_AVX2_DEFINE_OPERATIONS(bits, size) \ | 231 #define VEC_AVX2_DEFINE_OPERATIONS(bits, size) \ |
| 216 VEC_AVX2_DEFINE_OPERATIONS_SIGN( , bits, size) \ | 232 VEC_AVX2_DEFINE_OPERATIONS_SIGN( , bits, size) \ |
| 217 VEC_AVX2_DEFINE_OPERATIONS_SIGN(u, bits, size) | 233 VEC_AVX2_DEFINE_OPERATIONS_SIGN(u, bits, size) |
