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) |