58 __m256i x = _mm256_srli_epi64(a, amt);
59 x = _mm256_xor_si256(x, m);
60 __m256i result = _mm256_sub_epi64(x, m);
66 const ui32 src_line_offset,
68 const ui32 dst_line_offset,
75 const si32 *sp = src_line->
i32 + src_line_offset;
76 si32 *dp = dst_line->
i32 + dst_line_offset;
77 __m256i sh = _mm256_set1_epi32((
si32)shift);
78 for (
int i = (width + 7) >> 3; i > 0; --i, sp+=8, dp+=8)
80 __m256i s = _mm256_loadu_si256((__m256i*)sp);
81 s = _mm256_add_epi32(s, sh);
82 _mm256_storeu_si256((__m256i*)dp, s);
87 const si32 *sp = src_line->
i32 + src_line_offset;
88 si64 *dp = dst_line->
i64 + dst_line_offset;
89 __m256i sh = _mm256_set1_epi64x(shift);
90 for (
int i = (width + 7) >> 3; i > 0; --i, sp+=8, dp+=8)
93 s = _mm256_loadu_si256((__m256i*)sp);
95 t = _mm256_cvtepi32_epi64(_mm256_extracti128_si256(s, 0));
96 t = _mm256_add_epi64(t, sh);
97 _mm256_storeu_si256((__m256i*)dp, t);
99 t = _mm256_cvtepi32_epi64(_mm256_extracti128_si256(s, 1));
100 t = _mm256_add_epi64(t, sh);
101 _mm256_storeu_si256((__m256i*)dp + 1, t);
109 const si64 *sp = src_line->
i64 + src_line_offset;
110 si32 *dp = dst_line->
i32 + dst_line_offset;
111 __m256i low_bits = _mm256_set_epi64x(0, (
si64)ULLONG_MAX,
112 0, (
si64)ULLONG_MAX);
113 __m256i sh = _mm256_set1_epi64x(shift);
114 for (
int i = (width + 7) >> 3; i > 0; --i, sp+=8, dp+=8)
117 s = _mm256_loadu_si256((__m256i*)sp);
118 s = _mm256_add_epi64(s, sh);
120 t = _mm256_shuffle_epi32(s, _MM_SHUFFLE(0, 0, 2, 0));
121 t = _mm256_and_si256(low_bits, t);
123 s = _mm256_loadu_si256((__m256i*)sp + 1);
124 s = _mm256_add_epi64(s, sh);
126 s = _mm256_shuffle_epi32(s, _MM_SHUFFLE(2, 0, 0, 0));
127 s = _mm256_andnot_si256(low_bits, s);
129 t = _mm256_or_si256(s, t);
130 t = _mm256_permute4x64_epi64(t, _MM_SHUFFLE(3, 1, 2, 0));
131 _mm256_storeu_si256((__m256i*)dp, t);
138 const ui32 src_line_offset,
140 const ui32 dst_line_offset,
147 const si32 *sp = src_line->
i32 + src_line_offset;
148 si32 *dp = dst_line->
i32 + dst_line_offset;
149 __m256i sh = _mm256_set1_epi32((
si32)(-shift));
150 __m256i zero = _mm256_setzero_si256();
151 for (
int i = (width + 7) >> 3; i > 0; --i, sp += 8, dp += 8)
153 __m256i s = _mm256_loadu_si256((__m256i*)sp);
154 __m256i c = _mm256_cmpgt_epi32(zero, s);
155 __m256i v_m_sh = _mm256_sub_epi32(sh, s);
156 v_m_sh = _mm256_and_si256(c, v_m_sh);
157 s = _mm256_andnot_si256(c, s);
158 s = _mm256_or_si256(s, v_m_sh);
159 _mm256_storeu_si256((__m256i*)dp, s);
164 const si32 *sp = src_line->
i32 + src_line_offset;
165 si64 *dp = dst_line->
i64 + dst_line_offset;
166 __m256i sh = _mm256_set1_epi64x(-shift);
167 __m256i zero = _mm256_setzero_si256();
168 for (
int i = (width + 7) >> 3; i > 0; --i, sp += 8, dp += 8)
170 __m256i s, t, u0, u1, c, v_m_sh;
171 s = _mm256_loadu_si256((__m256i*)sp);
173 t = _mm256_cmpgt_epi32(zero, s);
174 u0 = _mm256_unpacklo_epi32(s, t);
175 c = _mm256_unpacklo_epi32(t, t);
177 v_m_sh = _mm256_sub_epi64(sh, u0);
178 v_m_sh = _mm256_and_si256(c, v_m_sh);
179 u0 = _mm256_andnot_si256(c, u0);
180 u0 = _mm256_or_si256(u0, v_m_sh);
182 u1 = _mm256_unpackhi_epi32(s, t);
183 c = _mm256_unpackhi_epi32(t, t);
185 v_m_sh = _mm256_sub_epi64(sh, u1);
186 v_m_sh = _mm256_and_si256(c, v_m_sh);
187 u1 = _mm256_andnot_si256(c, u1);
188 u1 = _mm256_or_si256(u1, v_m_sh);
190 t = _mm256_permute2x128_si256(u0, u1, (2 << 4) | 0);
191 _mm256_storeu_si256((__m256i*)dp, t);
193 t = _mm256_permute2x128_si256(u0, u1, (3 << 4) | 1);
194 _mm256_storeu_si256((__m256i*)dp + 1, t);
202 const si64 *sp = src_line->
i64 + src_line_offset;
203 si32 *dp = dst_line->
i32 + dst_line_offset;
204 __m256i sh = _mm256_set1_epi64x(-shift);
205 __m256i zero = _mm256_setzero_si256();
206 __m256i half_mask = _mm256_set_epi64x(0, (
si64)ULLONG_MAX,
207 0, (
si64)ULLONG_MAX);
208 for (
int i = (width + 7) >> 3; i > 0; --i, sp += 8, dp += 8)
212 __m256i s, t, p, n, m, tm;
213 s = _mm256_loadu_si256((__m256i*)sp);
215 m = _mm256_cmpgt_epi64(zero, s);
216 tm = _mm256_sub_epi64(sh, s);
217 n = _mm256_and_si256(m, tm);
218 p = _mm256_andnot_si256(m, s);
219 tm = _mm256_or_si256(n, p);
220 tm = _mm256_shuffle_epi32(tm, _MM_SHUFFLE(0, 0, 2, 0));
221 t = _mm256_and_si256(half_mask, tm);
223 s = _mm256_loadu_si256((__m256i*)sp + 1);
224 m = _mm256_cmpgt_epi64(zero, s);
225 tm = _mm256_sub_epi64(sh, s);
226 n = _mm256_and_si256(m, tm);
227 p = _mm256_andnot_si256(m, s);
228 tm = _mm256_or_si256(n, p);
229 tm = _mm256_shuffle_epi32(tm, _MM_SHUFFLE(2, 0, 0, 0));
230 tm = _mm256_andnot_si256(half_mask, tm);
232 t = _mm256_or_si256(t, tm);
233 t = _mm256_permute4x64_epi64(t, _MM_SHUFFLE(3, 1, 2, 0));
234 _mm256_storeu_si256((__m256i*)dp, t);
263 for (
int i = (repeat + 7) >> 3; i > 0; --i)
265 __m256i mr = _mm256_load_si256((__m256i*)rp);
266 __m256i mg = _mm256_load_si256((__m256i*)gp);
267 __m256i mb = _mm256_load_si256((__m256i*)bp);
268 __m256i t = _mm256_add_epi32(mr, mb);
269 t = _mm256_add_epi32(t, _mm256_slli_epi32(mg, 1));
270 _mm256_store_si256((__m256i*)yp, _mm256_srai_epi32(t, 2));
271 t = _mm256_sub_epi32(mb, mg);
272 _mm256_store_si256((__m256i*)cbp, t);
273 t = _mm256_sub_epi32(mr, mg);
274 _mm256_store_si256((__m256i*)crp, t);
276 rp += 8; gp += 8; bp += 8;
277 yp += 8; cbp += 8; crp += 8;
288 __m256i v2 = _mm256_set1_epi64x(1ULL << (63 - 2));
291 for (
int i = (repeat + 7) >> 3; i > 0; --i)
293 __m256i mr32 = _mm256_load_si256((__m256i*)rp);
294 __m256i mg32 = _mm256_load_si256((__m256i*)gp);
295 __m256i mb32 = _mm256_load_si256((__m256i*)bp);
296 __m256i mr, mg, mb, t;
297 mr = _mm256_cvtepi32_epi64(_mm256_extracti128_si256(mr32, 0));
298 mg = _mm256_cvtepi32_epi64(_mm256_extracti128_si256(mg32, 0));
299 mb = _mm256_cvtepi32_epi64(_mm256_extracti128_si256(mb32, 0));
301 t = _mm256_add_epi64(mr, mb);
302 t = _mm256_add_epi64(t, _mm256_slli_epi64(mg, 1));
304 t = _mm256_sub_epi64(mb, mg);
305 _mm256_store_si256((__m256i*)cbp, t);
306 t = _mm256_sub_epi64(mr, mg);
307 _mm256_store_si256((__m256i*)crp, t);
309 yp += 4; cbp += 4; crp += 4;
311 mr = _mm256_cvtepi32_epi64(_mm256_extracti128_si256(mr32, 1));
312 mg = _mm256_cvtepi32_epi64(_mm256_extracti128_si256(mg32, 1));
313 mb = _mm256_cvtepi32_epi64(_mm256_extracti128_si256(mb32, 1));
315 t = _mm256_add_epi64(mr, mb);
316 t = _mm256_add_epi64(t, _mm256_slli_epi64(mg, 1));
318 t = _mm256_sub_epi64(mb, mg);
319 _mm256_store_si256((__m256i*)cbp, t);
320 t = _mm256_sub_epi64(mr, mg);
321 _mm256_store_si256((__m256i*)crp, t);
323 rp += 8; gp += 8; bp += 8;
324 yp += 4; cbp += 4; crp += 4;
353 for (
int i = (repeat + 7) >> 3; i > 0; --i)
355 __m256i my = _mm256_load_si256((__m256i*)yp);
356 __m256i mcb = _mm256_load_si256((__m256i*)cbp);
357 __m256i mcr = _mm256_load_si256((__m256i*)crp);
359 __m256i t = _mm256_add_epi32(mcb, mcr);
360 t = _mm256_sub_epi32(my, _mm256_srai_epi32(t, 2));
361 _mm256_store_si256((__m256i*)gp, t);
362 __m256i u = _mm256_add_epi32(mcb, t);
363 _mm256_store_si256((__m256i*)bp, u);
364 u = _mm256_add_epi32(mcr, t);
365 _mm256_store_si256((__m256i*)rp, u);
367 yp += 8; cbp += 8; crp += 8;
368 rp += 8; gp += 8; bp += 8;
379 __m256i v2 = _mm256_set1_epi64x(1ULL << (63 - 2));
380 __m256i low_bits = _mm256_set_epi64x(0, (
si64)ULLONG_MAX,
381 0, (
si64)ULLONG_MAX);
384 for (
int i = (repeat + 7) >> 3; i > 0; --i)
386 __m256i my, mcb, mcr, tr, tg, tb;
387 my = _mm256_load_si256((__m256i*)yp);
388 mcb = _mm256_load_si256((__m256i*)cbp);
389 mcr = _mm256_load_si256((__m256i*)crp);
391 tg = _mm256_add_epi64(mcb, mcr);
393 tb = _mm256_add_epi64(mcb, tg);
394 tr = _mm256_add_epi64(mcr, tg);
397 mr = _mm256_shuffle_epi32(tr, _MM_SHUFFLE(0, 0, 2, 0));
398 mr = _mm256_and_si256(low_bits, mr);
399 mg = _mm256_shuffle_epi32(tg, _MM_SHUFFLE(0, 0, 2, 0));
400 mg = _mm256_and_si256(low_bits, mg);
401 mb = _mm256_shuffle_epi32(tb, _MM_SHUFFLE(0, 0, 2, 0));
402 mb = _mm256_and_si256(low_bits, mb);
404 yp += 4; cbp += 4; crp += 4;
406 my = _mm256_load_si256((__m256i*)yp);
407 mcb = _mm256_load_si256((__m256i*)cbp);
408 mcr = _mm256_load_si256((__m256i*)crp);
410 tg = _mm256_add_epi64(mcb, mcr);
412 tb = _mm256_add_epi64(mcb, tg);
413 tr = _mm256_add_epi64(mcr, tg);
415 tr = _mm256_shuffle_epi32(tr, _MM_SHUFFLE(2, 0, 0, 0));
416 tr = _mm256_andnot_si256(low_bits, tr);
417 mr = _mm256_or_si256(mr, tr);
418 mr = _mm256_permute4x64_epi64(mr, _MM_SHUFFLE(3, 1, 2, 0));
420 tg = _mm256_shuffle_epi32(tg, _MM_SHUFFLE(2, 0, 0, 0));
421 tg = _mm256_andnot_si256(low_bits, tg);
422 mg = _mm256_or_si256(mg, tg);
423 mg = _mm256_permute4x64_epi64(mg, _MM_SHUFFLE(3, 1, 2, 0));
425 tb = _mm256_shuffle_epi32(tb, _MM_SHUFFLE(2, 0, 0, 0));
426 tb = _mm256_andnot_si256(low_bits, tb);
427 mb = _mm256_or_si256(mb, tb);
428 mb = _mm256_permute4x64_epi64(mb, _MM_SHUFFLE(3, 1, 2, 0));
430 _mm256_store_si256((__m256i*)rp, mr);
431 _mm256_store_si256((__m256i*)gp, mg);
432 _mm256_store_si256((__m256i*)bp, mb);
434 yp += 4; cbp += 4; crp += 4;
435 rp += 8; gp += 8; bp += 8;
void avx2_rct_forward(const line_buf *r, const line_buf *g, const line_buf *b, line_buf *y, line_buf *cb, line_buf *cr, ui32 repeat)
void avx2_rct_backward(const line_buf *y, const line_buf *cb, const line_buf *cr, line_buf *r, line_buf *g, line_buf *b, ui32 repeat)
void avx2_rev_convert(const line_buf *src_line, const ui32 src_line_offset, line_buf *dst_line, const ui32 dst_line_offset, si64 shift, ui32 width)
void avx2_rev_convert_nlt_type3(const line_buf *src_line, const ui32 src_line_offset, line_buf *dst_line, const ui32 dst_line_offset, si64 shift, ui32 width)
static __m256i avx2_mm256_srai_epi64(__m256i a, int amt, __m256i m)