39#if defined(OJPH_ARCH_I386) || defined(OJPH_ARCH_X86_64)
60 __m256i avx2_mm256_srai_epi64(__m256i a,
int amt, __m256i m)
64 __m256i x = _mm256_srli_epi64(a, amt);
65 x = _mm256_xor_si256(x, m);
66 __m256i result = _mm256_sub_epi64(x, m);
72 void avx2_deinterleave32(
float* dpl,
float* dph,
float* sp,
int width)
74 for (; width > 0; width -= 16, sp += 16, dpl += 8, dph += 8)
76 __m256 a = _mm256_load_ps(sp);
77 __m256 b = _mm256_load_ps(sp + 8);
78 __m256 c = _mm256_permute2f128_ps(a, b, (2 << 4) | (0));
79 __m256 d = _mm256_permute2f128_ps(a, b, (3 << 4) | (1));
80 __m256 e = _mm256_shuffle_ps(c, d, _MM_SHUFFLE(2, 0, 2, 0));
81 __m256 f = _mm256_shuffle_ps(c, d, _MM_SHUFFLE(3, 1, 3, 1));
82 _mm256_store_ps(dpl, e);
83 _mm256_store_ps(dph, f);
89 void avx2_interleave32(
float* dp,
float* spl,
float* sph,
int width)
91 for (; width > 0; width -= 16, dp += 16, spl += 8, sph += 8)
93 __m256 a = _mm256_load_ps(spl);
94 __m256 b = _mm256_load_ps(sph);
95 __m256 c = _mm256_unpacklo_ps(a, b);
96 __m256 d = _mm256_unpackhi_ps(a, b);
97 __m256 e = _mm256_permute2f128_ps(c, d, (2 << 4) | (0));
98 __m256 f = _mm256_permute2f128_ps(c, d, (3 << 4) | (1));
99 _mm256_store_ps(dp, e);
100 _mm256_store_ps(dp + 8, f);
106 void avx2_deinterleave64(
void* dpl,
void* dph,
const void* sp,
int width)
108 for (; width > 0; width -= 8,
109 sp = (
const char*)sp + 64,
110 dpl = (
char*)dpl + 32,
111 dph = (
char*)dph + 32)
113 __m256i a = _mm256_load_si256((
const __m256i*)sp);
114 __m256i b = _mm256_load_si256((
const __m256i*)((
const char*)sp + 32));
115 __m256i c = _mm256_permute2f128_si256(a, b, (2 << 4) | (0));
116 __m256i d = _mm256_permute2f128_si256(a, b, (3 << 4) | (1));
117 __m256i e = _mm256_unpacklo_epi64(c, d);
118 __m256i f = _mm256_unpackhi_epi64(c, d);
119 _mm256_store_si256((__m256i*)dpl, e);
120 _mm256_store_si256((__m256i*)dph, f);
126 void avx2_interleave64(
void* dp,
const void* spl,
const void* sph,
129 for (; width > 0; width -= 8,
131 spl = (
const char*)spl + 32,
132 sph = (
const char*)sph + 32)
134 __m256i a = _mm256_load_si256((
const __m256i*)spl);
135 __m256i b = _mm256_load_si256((
const __m256i*)sph);
136 __m256i c = _mm256_unpacklo_epi64(a, b);
137 __m256i d = _mm256_unpackhi_epi64(a, b);
138 __m256i e = _mm256_permute2f128_si256(c, d, (2 << 4) | (0));
139 __m256i f = _mm256_permute2f128_si256(c, d, (3 << 4) | (1));
140 _mm256_store_si256((__m256i*)dp, e);
141 _mm256_store_si256((__m256i*)((
char*)dp + 32), f);
147 void avx2_rev_vert_step32(
const lifting_step* s,
const line_buf* sig,
148 const line_buf* other,
const line_buf* aug,
149 ui32 repeat,
bool synthesis)
151 const si32 a = s->rev.Aatk;
152 const si32 b = s->rev.Batk;
153 const ui8 e = s->rev.Eatk;
154 __m256i va = _mm256_set1_epi32(a);
155 __m256i vb = _mm256_set1_epi32(b);
157 si32* dst = aug->i32;
158 const si32* src1 = sig->i32, * src2 = other->i32;
166 for (; i > 0; i -= 8, dst += 8, src1 += 8, src2 += 8)
168 __m256i s1 = _mm256_load_si256((__m256i*)src1);
169 __m256i s2 = _mm256_load_si256((__m256i*)src2);
170 __m256i d = _mm256_load_si256((__m256i*)dst);
171 __m256i t = _mm256_add_epi32(s1, s2);
172 __m256i v = _mm256_add_epi32(vb, t);
173 __m256i w = _mm256_srai_epi32(v, e);
174 d = _mm256_sub_epi32(d, w);
175 _mm256_store_si256((__m256i*)dst, d);
178 for (; i > 0; i -= 8, dst += 8, src1 += 8, src2 += 8)
180 __m256i s1 = _mm256_load_si256((__m256i*)src1);
181 __m256i s2 = _mm256_load_si256((__m256i*)src2);
182 __m256i d = _mm256_load_si256((__m256i*)dst);
183 __m256i t = _mm256_add_epi32(s1, s2);
184 __m256i v = _mm256_add_epi32(vb, t);
185 __m256i w = _mm256_srai_epi32(v, e);
186 d = _mm256_add_epi32(d, w);
187 _mm256_store_si256((__m256i*)dst, d);
190 else if (a == -1 && b == 1 && e == 1)
194 for (; i > 0; i -= 8, dst += 8, src1 += 8, src2 += 8)
196 __m256i s1 = _mm256_load_si256((__m256i*)src1);
197 __m256i s2 = _mm256_load_si256((__m256i*)src2);
198 __m256i d = _mm256_load_si256((__m256i*)dst);
199 __m256i t = _mm256_add_epi32(s1, s2);
200 __m256i w = _mm256_srai_epi32(t, e);
201 d = _mm256_add_epi32(d, w);
202 _mm256_store_si256((__m256i*)dst, d);
205 for (; i > 0; i -= 8, dst += 8, src1 += 8, src2 += 8)
207 __m256i s1 = _mm256_load_si256((__m256i*)src1);
208 __m256i s2 = _mm256_load_si256((__m256i*)src2);
209 __m256i d = _mm256_load_si256((__m256i*)dst);
210 __m256i t = _mm256_add_epi32(s1, s2);
211 __m256i w = _mm256_srai_epi32(t, e);
212 d = _mm256_sub_epi32(d, w);
213 _mm256_store_si256((__m256i*)dst, d);
220 for (; i > 0; i -= 8, dst += 8, src1 += 8, src2 += 8)
222 __m256i s1 = _mm256_load_si256((__m256i*)src1);
223 __m256i s2 = _mm256_load_si256((__m256i*)src2);
224 __m256i d = _mm256_load_si256((__m256i*)dst);
225 __m256i t = _mm256_add_epi32(s1, s2);
226 __m256i v = _mm256_sub_epi32(vb, t);
227 __m256i w = _mm256_srai_epi32(v, e);
228 d = _mm256_sub_epi32(d, w);
229 _mm256_store_si256((__m256i*)dst, d);
232 for (; i > 0; i -= 8, dst += 8, src1 += 8, src2 += 8)
234 __m256i s1 = _mm256_load_si256((__m256i*)src1);
235 __m256i s2 = _mm256_load_si256((__m256i*)src2);
236 __m256i d = _mm256_load_si256((__m256i*)dst);
237 __m256i t = _mm256_add_epi32(s1, s2);
238 __m256i v = _mm256_sub_epi32(vb, t);
239 __m256i w = _mm256_srai_epi32(v, e);
240 d = _mm256_add_epi32(d, w);
241 _mm256_store_si256((__m256i*)dst, d);
247 for (; i > 0; i -= 8, dst += 8, src1 += 8, src2 += 8)
249 __m256i s1 = _mm256_load_si256((__m256i*)src1);
250 __m256i s2 = _mm256_load_si256((__m256i*)src2);
251 __m256i d = _mm256_load_si256((__m256i*)dst);
252 __m256i t = _mm256_add_epi32(s1, s2);
253 __m256i u = _mm256_mullo_epi32(va, t);
254 __m256i v = _mm256_add_epi32(vb, u);
255 __m256i w = _mm256_srai_epi32(v, e);
256 d = _mm256_sub_epi32(d, w);
257 _mm256_store_si256((__m256i*)dst, d);
260 for (; i > 0; i -= 8, dst += 8, src1 += 8, src2 += 8)
262 __m256i s1 = _mm256_load_si256((__m256i*)src1);
263 __m256i s2 = _mm256_load_si256((__m256i*)src2);
264 __m256i d = _mm256_load_si256((__m256i*)dst);
265 __m256i t = _mm256_add_epi32(s1, s2);
266 __m256i u = _mm256_mullo_epi32(va, t);
267 __m256i v = _mm256_add_epi32(vb, u);
268 __m256i w = _mm256_srai_epi32(v, e);
269 d = _mm256_add_epi32(d, w);
270 _mm256_store_si256((__m256i*)dst, d);
277 void avx2_rev_vert_step64(
const lifting_step* s,
const line_buf* sig,
278 const line_buf* other,
const line_buf* aug,
279 ui32 repeat,
bool synthesis)
281 const si32 a = s->rev.Aatk;
282 const si32 b = s->rev.Batk;
283 const ui8 e = s->rev.Eatk;
284 __m256i vb = _mm256_set1_epi64x(b);
285 __m256i ve = _mm256_set1_epi64x(1LL << (63 - e));
287 si64* dst = aug->i64;
288 const si64* src1 = sig->i64, * src2 = other->i64;
296 for (; i > 0; i -= 4, dst += 4, src1 += 4, src2 += 4)
298 __m256i s1 = _mm256_load_si256((__m256i*)src1);
299 __m256i s2 = _mm256_load_si256((__m256i*)src2);
300 __m256i d = _mm256_load_si256((__m256i*)dst);
301 __m256i t = _mm256_add_epi64(s1, s2);
302 __m256i v = _mm256_add_epi64(vb, t);
303 __m256i w = avx2_mm256_srai_epi64(v, e, ve);
304 d = _mm256_sub_epi64(d, w);
305 _mm256_store_si256((__m256i*)dst, d);
308 for (; i > 0; i -= 4, dst += 4, src1 += 4, src2 += 4)
310 __m256i s1 = _mm256_load_si256((__m256i*)src1);
311 __m256i s2 = _mm256_load_si256((__m256i*)src2);
312 __m256i d = _mm256_load_si256((__m256i*)dst);
313 __m256i t = _mm256_add_epi64(s1, s2);
314 __m256i v = _mm256_add_epi64(vb, t);
315 __m256i w = avx2_mm256_srai_epi64(v, e, ve);
316 d = _mm256_add_epi64(d, w);
317 _mm256_store_si256((__m256i*)dst, d);
320 else if (a == -1 && b == 1 && e == 1)
324 for (; i > 0; i -= 4, dst += 4, src1 += 4, src2 += 4)
326 __m256i s1 = _mm256_load_si256((__m256i*)src1);
327 __m256i s2 = _mm256_load_si256((__m256i*)src2);
328 __m256i d = _mm256_load_si256((__m256i*)dst);
329 __m256i t = _mm256_add_epi64(s1, s2);
330 __m256i w = avx2_mm256_srai_epi64(t, e, ve);
331 d = _mm256_add_epi64(d, w);
332 _mm256_store_si256((__m256i*)dst, d);
335 for (; i > 0; i -= 4, dst += 4, src1 += 4, src2 += 4)
337 __m256i s1 = _mm256_load_si256((__m256i*)src1);
338 __m256i s2 = _mm256_load_si256((__m256i*)src2);
339 __m256i d = _mm256_load_si256((__m256i*)dst);
340 __m256i t = _mm256_add_epi64(s1, s2);
341 __m256i w = avx2_mm256_srai_epi64(t, e, ve);
342 d = _mm256_sub_epi64(d, w);
343 _mm256_store_si256((__m256i*)dst, d);
350 for (; i > 0; i -= 4, dst += 4, src1 += 4, src2 += 4)
352 __m256i s1 = _mm256_load_si256((__m256i*)src1);
353 __m256i s2 = _mm256_load_si256((__m256i*)src2);
354 __m256i d = _mm256_load_si256((__m256i*)dst);
355 __m256i t = _mm256_add_epi64(s1, s2);
356 __m256i v = _mm256_sub_epi64(vb, t);
357 __m256i w = avx2_mm256_srai_epi64(v, e, ve);
358 d = _mm256_sub_epi64(d, w);
359 _mm256_store_si256((__m256i*)dst, d);
362 for (; i > 0; i -= 4, dst += 4, src1 += 4, src2 += 4)
364 __m256i s1 = _mm256_load_si256((__m256i*)src1);
365 __m256i s2 = _mm256_load_si256((__m256i*)src2);
366 __m256i d = _mm256_load_si256((__m256i*)dst);
367 __m256i t = _mm256_add_epi64(s1, s2);
368 __m256i v = _mm256_sub_epi64(vb, t);
369 __m256i w = avx2_mm256_srai_epi64(v, e, ve);
370 d = _mm256_add_epi64(d, w);
371 _mm256_store_si256((__m256i*)dst, d);
378 for (
ui32 i = repeat; i > 0; --i)
379 *dst++ -= (b + a * (*src1++ + *src2++)) >> e;
381 for (
ui32 i = repeat; i > 0; --i)
382 *dst++ += (b + a * (*src1++ + *src2++)) >> e;
388 const line_buf* other,
const line_buf* aug,
389 ui32 repeat,
bool synthesis)
398 avx2_rev_vert_step32(s, sig, other, aug, repeat, synthesis);
405 avx2_rev_vert_step64(s, sig, other, aug, repeat, synthesis);
411 void avx2_rev_horz_ana32(
const param_atk* atk,
const line_buf* ldst,
412 const line_buf* hdst,
const line_buf* src,
413 ui32 width,
bool even)
419 float* dpl = even ? ldst->f32 : hdst->f32;
420 float* dph = even ? hdst->f32 : ldst->f32;
421 float* sp = src->f32;
423 avx2_deinterleave32(dpl, dph, sp, w);
426 si32* hp = hdst->i32, * lp = ldst->i32;
427 ui32 l_width = (width + (even ? 1 : 0)) >> 1;
428 ui32 h_width = (width + (even ? 0 : 1)) >> 1;
429 ui32 num_steps = atk->get_num_steps();
430 for (
ui32 j = num_steps; j > 0; --j)
435 const si32 b = s->rev.Batk;
436 const ui8 e = s->rev.Eatk;
437 __m256i va = _mm256_set1_epi32(a);
438 __m256i vb = _mm256_set1_epi32(b);
442 lp[l_width] = lp[l_width - 1];
448 int i = (int)h_width;
451 for (; i > 0; i -= 8, sp += 8, dp += 8)
453 __m256i s1 = _mm256_load_si256((__m256i*)sp);
454 __m256i s2 = _mm256_loadu_si256((__m256i*)(sp + 1));
455 __m256i d = _mm256_load_si256((__m256i*)dp);
456 __m256i t = _mm256_add_epi32(s1, s2);
457 __m256i v = _mm256_add_epi32(vb, t);
458 __m256i w = _mm256_srai_epi32(v, e);
459 d = _mm256_add_epi32(d, w);
460 _mm256_store_si256((__m256i*)dp, d);
465 for (; i > 0; i -= 8, sp += 8, dp += 8)
467 __m256i s1 = _mm256_load_si256((__m256i*)sp);
468 __m256i s2 = _mm256_loadu_si256((__m256i*)(sp - 1));
469 __m256i d = _mm256_load_si256((__m256i*)dp);
470 __m256i t = _mm256_add_epi32(s1, s2);
471 __m256i v = _mm256_add_epi32(vb, t);
472 __m256i w = _mm256_srai_epi32(v, e);
473 d = _mm256_add_epi32(d, w);
474 _mm256_store_si256((__m256i*)dp, d);
478 else if (a == -1 && b == 1 && e == 1)
480 int i = (int)h_width;
482 for (; i > 0; i -= 8, sp += 8, dp += 8)
484 __m256i s1 = _mm256_load_si256((__m256i*)sp);
485 __m256i s2 = _mm256_loadu_si256((__m256i*)(sp + 1));
486 __m256i d = _mm256_load_si256((__m256i*)dp);
487 __m256i t = _mm256_add_epi32(s1, s2);
488 __m256i w = _mm256_srai_epi32(t, e);
489 d = _mm256_sub_epi32(d, w);
490 _mm256_store_si256((__m256i*)dp, d);
493 for (; i > 0; i -= 8, sp += 8, dp += 8)
495 __m256i s1 = _mm256_load_si256((__m256i*)sp);
496 __m256i s2 = _mm256_loadu_si256((__m256i*)(sp - 1));
497 __m256i d = _mm256_load_si256((__m256i*)dp);
498 __m256i t = _mm256_add_epi32(s1, s2);
499 __m256i w = _mm256_srai_epi32(t, e);
500 d = _mm256_sub_epi32(d, w);
501 _mm256_store_si256((__m256i*)dp, d);
506 int i = (int)h_width;
508 for (; i > 0; i -= 8, sp += 8, dp += 8)
510 __m256i s1 = _mm256_load_si256((__m256i*)sp);
511 __m256i s2 = _mm256_loadu_si256((__m256i*)(sp + 1));
512 __m256i d = _mm256_load_si256((__m256i*)dp);
513 __m256i t = _mm256_add_epi32(s1, s2);
514 __m256i v = _mm256_sub_epi32(vb, t);
515 __m256i w = _mm256_srai_epi32(v, e);
516 d = _mm256_add_epi32(d, w);
517 _mm256_store_si256((__m256i*)dp, d);
520 for (; i > 0; i -= 8, sp += 8, dp += 8)
522 __m256i s1 = _mm256_load_si256((__m256i*)sp);
523 __m256i s2 = _mm256_loadu_si256((__m256i*)(sp - 1));
524 __m256i d = _mm256_load_si256((__m256i*)dp);
525 __m256i t = _mm256_add_epi32(s1, s2);
526 __m256i v = _mm256_sub_epi32(vb, t);
527 __m256i w = _mm256_srai_epi32(v, e);
528 d = _mm256_add_epi32(d, w);
529 _mm256_store_si256((__m256i*)dp, d);
534 int i = (int)h_width;
536 for (; i > 0; i -= 8, sp += 8, dp += 8)
538 __m256i s1 = _mm256_load_si256((__m256i*)sp);
539 __m256i s2 = _mm256_loadu_si256((__m256i*)(sp + 1));
540 __m256i d = _mm256_load_si256((__m256i*)dp);
541 __m256i t = _mm256_add_epi32(s1, s2);
542 __m256i u = _mm256_mullo_epi32(va, t);
543 __m256i v = _mm256_add_epi32(vb, u);
544 __m256i w = _mm256_srai_epi32(v, e);
545 d = _mm256_add_epi32(d, w);
546 _mm256_store_si256((__m256i*)dp, d);
549 for (; i > 0; i -= 8, sp += 8, dp += 8)
551 __m256i s1 = _mm256_load_si256((__m256i*)sp);
552 __m256i s2 = _mm256_loadu_si256((__m256i*)(sp - 1));
553 __m256i d = _mm256_load_si256((__m256i*)dp);
554 __m256i t = _mm256_add_epi32(s1, s2);
555 __m256i u = _mm256_mullo_epi32(va, t);
556 __m256i v = _mm256_add_epi32(vb, u);
557 __m256i w = _mm256_srai_epi32(v, e);
558 d = _mm256_add_epi32(d, w);
559 _mm256_store_si256((__m256i*)dp, d);
564 si32* t = lp; lp = hp; hp = t;
566 ui32 w = l_width; l_width = h_width; h_width = w;
571 ldst->i32[0] = src->i32[0];
573 hdst->i32[0] = src->i32[0] << 1;
579 void avx2_rev_horz_ana64(
const param_atk* atk,
const line_buf* ldst,
580 const line_buf* hdst,
const line_buf* src,
581 ui32 width,
bool even)
587 void* dpl = even ? ldst->p : hdst->p;
588 void* dph = even ? hdst->p : ldst->p;
589 const void* sp = src->p;
591 avx2_deinterleave64(dpl, dph, sp, w);
594 si64* hp = hdst->i64, * lp = ldst->i64;
595 ui32 l_width = (width + (even ? 1 : 0)) >> 1;
596 ui32 h_width = (width + (even ? 0 : 1)) >> 1;
597 ui32 num_steps = atk->get_num_steps();
598 for (
ui32 j = num_steps; j > 0; --j)
603 const si32 b = s->rev.Batk;
604 const ui8 e = s->rev.Eatk;
605 __m256i vb = _mm256_set1_epi64x(b);
606 __m256i ve = _mm256_set1_epi64x(1LL << (63 - e));
610 lp[l_width] = lp[l_width - 1];
616 int i = (int)h_width;
619 for (; i > 0; i -= 4, sp += 4, dp += 4)
621 __m256i s1 = _mm256_load_si256((__m256i*)sp);
622 __m256i s2 = _mm256_loadu_si256((__m256i*)(sp + 1));
623 __m256i d = _mm256_load_si256((__m256i*)dp);
624 __m256i t = _mm256_add_epi64(s1, s2);
625 __m256i v = _mm256_add_epi64(vb, t);
626 __m256i w = avx2_mm256_srai_epi64(v, e, ve);
627 d = _mm256_add_epi64(d, w);
628 _mm256_store_si256((__m256i*)dp, d);
633 for (; i > 0; i -= 4, sp += 4, dp += 4)
635 __m256i s1 = _mm256_load_si256((__m256i*)sp);
636 __m256i s2 = _mm256_loadu_si256((__m256i*)(sp - 1));
637 __m256i d = _mm256_load_si256((__m256i*)dp);
638 __m256i t = _mm256_add_epi64(s1, s2);
639 __m256i v = _mm256_add_epi64(vb, t);
640 __m256i w = avx2_mm256_srai_epi64(v, e, ve);
641 d = _mm256_add_epi64(d, w);
642 _mm256_store_si256((__m256i*)dp, d);
646 else if (a == -1 && b == 1 && e == 1)
648 int i = (int)h_width;
650 for (; i > 0; i -= 4, sp += 4, dp += 4)
652 __m256i s1 = _mm256_load_si256((__m256i*)sp);
653 __m256i s2 = _mm256_loadu_si256((__m256i*)(sp + 1));
654 __m256i d = _mm256_load_si256((__m256i*)dp);
655 __m256i t = _mm256_add_epi64(s1, s2);
656 __m256i w = avx2_mm256_srai_epi64(t, e, ve);
657 d = _mm256_sub_epi64(d, w);
658 _mm256_store_si256((__m256i*)dp, d);
661 for (; i > 0; i -= 4, sp += 4, dp += 4)
663 __m256i s1 = _mm256_load_si256((__m256i*)sp);
664 __m256i s2 = _mm256_loadu_si256((__m256i*)(sp - 1));
665 __m256i d = _mm256_load_si256((__m256i*)dp);
666 __m256i t = _mm256_add_epi64(s1, s2);
667 __m256i w = avx2_mm256_srai_epi64(t, e, ve);
668 d = _mm256_sub_epi64(d, w);
669 _mm256_store_si256((__m256i*)dp, d);
674 int i = (int)h_width;
676 for (; i > 0; i -= 4, sp += 4, dp += 4)
678 __m256i s1 = _mm256_load_si256((__m256i*)sp);
679 __m256i s2 = _mm256_loadu_si256((__m256i*)(sp + 1));
680 __m256i d = _mm256_load_si256((__m256i*)dp);
681 __m256i t = _mm256_add_epi64(s1, s2);
682 __m256i v = _mm256_sub_epi64(vb, t);
683 __m256i w = avx2_mm256_srai_epi64(v, e, ve);
684 d = _mm256_add_epi64(d, w);
685 _mm256_store_si256((__m256i*)dp, d);
688 for (; i > 0; i -= 4, sp += 4, dp += 4)
690 __m256i s1 = _mm256_load_si256((__m256i*)sp);
691 __m256i s2 = _mm256_loadu_si256((__m256i*)(sp - 1));
692 __m256i d = _mm256_load_si256((__m256i*)dp);
693 __m256i t = _mm256_add_epi64(s1, s2);
694 __m256i v = _mm256_sub_epi64(vb, t);
695 __m256i w = avx2_mm256_srai_epi64(v, e, ve);
696 d = _mm256_add_epi64(d, w);
697 _mm256_store_si256((__m256i*)dp, d);
705 for (
ui32 i = h_width; i > 0; --i, sp++, dp++)
706 *dp += (b + a * (sp[0] + sp[1])) >> e;
708 for (
ui32 i = h_width; i > 0; --i, sp++, dp++)
709 *dp += (b + a * (sp[-1] + sp[0])) >> e;
713 si64* t = lp; lp = hp; hp = t;
715 ui32 w = l_width; l_width = h_width; h_width = w;
720 ldst->i64[0] = src->i64[0];
722 hdst->i64[0] = src->i64[0] << 1;
728 const line_buf* hdst,
const line_buf* src,
729 ui32 width,
bool even)
735 avx2_rev_horz_ana32(atk, ldst, hdst, src, width, even);
742 avx2_rev_horz_ana64(atk, ldst, hdst, src, width, even);
748 void avx2_rev_horz_syn32(
const param_atk* atk,
const line_buf* dst,
749 const line_buf* lsrc,
const line_buf* hsrc,
750 ui32 width,
bool even)
755 si32* oth = hsrc->i32, * aug = lsrc->i32;
756 ui32 aug_width = (width + (even ? 1 : 0)) >> 1;
757 ui32 oth_width = (width + (even ? 0 : 1)) >> 1;
758 ui32 num_steps = atk->get_num_steps();
759 for (
ui32 j = 0; j < num_steps; ++j)
763 const si32 b = s->rev.Batk;
764 const ui8 e = s->rev.Eatk;
765 __m256i va = _mm256_set1_epi32(a);
766 __m256i vb = _mm256_set1_epi32(b);
770 oth[oth_width] = oth[oth_width - 1];
772 const si32* sp = oth;
776 int i = (int)aug_width;
779 for (; i > 0; i -= 8, sp += 8, dp += 8)
781 __m256i s1 = _mm256_load_si256((__m256i*)sp);
782 __m256i s2 = _mm256_loadu_si256((__m256i*)(sp - 1));
783 __m256i d = _mm256_load_si256((__m256i*)dp);
784 __m256i t = _mm256_add_epi32(s1, s2);
785 __m256i v = _mm256_add_epi32(vb, t);
786 __m256i w = _mm256_srai_epi32(v, e);
787 d = _mm256_sub_epi32(d, w);
788 _mm256_store_si256((__m256i*)dp, d);
793 for (; i > 0; i -= 8, sp += 8, dp += 8)
795 __m256i s1 = _mm256_load_si256((__m256i*)sp);
796 __m256i s2 = _mm256_loadu_si256((__m256i*)(sp + 1));
797 __m256i d = _mm256_load_si256((__m256i*)dp);
798 __m256i t = _mm256_add_epi32(s1, s2);
799 __m256i v = _mm256_add_epi32(vb, t);
800 __m256i w = _mm256_srai_epi32(v, e);
801 d = _mm256_sub_epi32(d, w);
802 _mm256_store_si256((__m256i*)dp, d);
806 else if (a == -1 && b == 1 && e == 1)
808 int i = (int)aug_width;
810 for (; i > 0; i -= 8, sp += 8, dp += 8)
812 __m256i s1 = _mm256_load_si256((__m256i*)sp);
813 __m256i s2 = _mm256_loadu_si256((__m256i*)(sp - 1));
814 __m256i d = _mm256_load_si256((__m256i*)dp);
815 __m256i t = _mm256_add_epi32(s1, s2);
816 __m256i w = _mm256_srai_epi32(t, e);
817 d = _mm256_add_epi32(d, w);
818 _mm256_store_si256((__m256i*)dp, d);
821 for (; i > 0; i -= 8, sp += 8, dp += 8)
823 __m256i s1 = _mm256_load_si256((__m256i*)sp);
824 __m256i s2 = _mm256_loadu_si256((__m256i*)(sp + 1));
825 __m256i d = _mm256_load_si256((__m256i*)dp);
826 __m256i t = _mm256_add_epi32(s1, s2);
827 __m256i w = _mm256_srai_epi32(t, e);
828 d = _mm256_add_epi32(d, w);
829 _mm256_store_si256((__m256i*)dp, d);
834 int i = (int)aug_width;
836 for (; i > 0; i -= 8, sp += 8, dp += 8)
838 __m256i s1 = _mm256_load_si256((__m256i*)sp);
839 __m256i s2 = _mm256_loadu_si256((__m256i*)(sp - 1));
840 __m256i d = _mm256_load_si256((__m256i*)dp);
841 __m256i t = _mm256_add_epi32(s1, s2);
842 __m256i v = _mm256_sub_epi32(vb, t);
843 __m256i w = _mm256_srai_epi32(v, e);
844 d = _mm256_sub_epi32(d, w);
845 _mm256_store_si256((__m256i*)dp, d);
848 for (; i > 0; i -= 8, sp += 8, dp += 8)
850 __m256i s1 = _mm256_load_si256((__m256i*)sp);
851 __m256i s2 = _mm256_loadu_si256((__m256i*)(sp + 1));
852 __m256i d = _mm256_load_si256((__m256i*)dp);
853 __m256i t = _mm256_add_epi32(s1, s2);
854 __m256i v = _mm256_sub_epi32(vb, t);
855 __m256i w = _mm256_srai_epi32(v, e);
856 d = _mm256_sub_epi32(d, w);
857 _mm256_store_si256((__m256i*)dp, d);
862 int i = (int)aug_width;
864 for (; i > 0; i -= 8, sp += 8, dp += 8)
866 __m256i s1 = _mm256_load_si256((__m256i*)sp);
867 __m256i s2 = _mm256_loadu_si256((__m256i*)(sp - 1));
868 __m256i d = _mm256_load_si256((__m256i*)dp);
869 __m256i t = _mm256_add_epi32(s1, s2);
870 __m256i u = _mm256_mullo_epi32(va, t);
871 __m256i v = _mm256_add_epi32(vb, u);
872 __m256i w = _mm256_srai_epi32(v, e);
873 d = _mm256_sub_epi32(d, w);
874 _mm256_store_si256((__m256i*)dp, d);
877 for (; i > 0; i -= 8, sp += 8, dp += 8)
879 __m256i s1 = _mm256_load_si256((__m256i*)sp);
880 __m256i s2 = _mm256_loadu_si256((__m256i*)(sp + 1));
881 __m256i d = _mm256_load_si256((__m256i*)dp);
882 __m256i t = _mm256_add_epi32(s1, s2);
883 __m256i u = _mm256_mullo_epi32(va, t);
884 __m256i v = _mm256_add_epi32(vb, u);
885 __m256i w = _mm256_srai_epi32(v, e);
886 d = _mm256_sub_epi32(d, w);
887 _mm256_store_si256((__m256i*)dp, d);
892 si32* t = aug; aug = oth; oth = t;
894 ui32 w = aug_width; aug_width = oth_width; oth_width = w;
899 float* dp = dst->f32;
900 float* spl = even ? lsrc->f32 : hsrc->f32;
901 float* sph = even ? hsrc->f32 : lsrc->f32;
903 avx2_interleave32(dp, spl, sph, w);
908 dst->i32[0] = lsrc->i32[0];
910 dst->i32[0] = hsrc->i32[0] >> 1;
916 void avx2_rev_horz_syn64(
const param_atk* atk,
const line_buf* dst,
917 const line_buf* lsrc,
const line_buf* hsrc,
918 ui32 width,
bool even)
923 si64* oth = hsrc->i64, * aug = lsrc->i64;
924 ui32 aug_width = (width + (even ? 1 : 0)) >> 1;
925 ui32 oth_width = (width + (even ? 0 : 1)) >> 1;
926 ui32 num_steps = atk->get_num_steps();
927 for (
ui32 j = 0; j < num_steps; ++j)
931 const si32 b = s->rev.Batk;
932 const ui8 e = s->rev.Eatk;
933 __m256i vb = _mm256_set1_epi64x(b);
934 __m256i ve = _mm256_set1_epi64x(1LL << (63 - e));
938 oth[oth_width] = oth[oth_width - 1];
940 const si64* sp = oth;
944 int i = (int)aug_width;
947 for (; i > 0; i -= 4, sp += 4, dp += 4)
949 __m256i s1 = _mm256_load_si256((__m256i*)sp);
950 __m256i s2 = _mm256_loadu_si256((__m256i*)(sp - 1));
951 __m256i d = _mm256_load_si256((__m256i*)dp);
952 __m256i t = _mm256_add_epi64(s1, s2);
953 __m256i v = _mm256_add_epi64(vb, t);
954 __m256i w = avx2_mm256_srai_epi64(v, e, ve);
955 d = _mm256_sub_epi64(d, w);
956 _mm256_store_si256((__m256i*)dp, d);
961 for (; i > 0; i -= 4, sp += 4, dp += 4)
963 __m256i s1 = _mm256_load_si256((__m256i*)sp);
964 __m256i s2 = _mm256_loadu_si256((__m256i*)(sp + 1));
965 __m256i d = _mm256_load_si256((__m256i*)dp);
966 __m256i t = _mm256_add_epi64(s1, s2);
967 __m256i v = _mm256_add_epi64(vb, t);
968 __m256i w = avx2_mm256_srai_epi64(v, e, ve);
969 d = _mm256_sub_epi64(d, w);
970 _mm256_store_si256((__m256i*)dp, d);
974 else if (a == -1 && b == 1 && e == 1)
976 int i = (int)aug_width;
978 for (; i > 0; i -= 4, sp += 4, dp += 4)
980 __m256i s1 = _mm256_load_si256((__m256i*)sp);
981 __m256i s2 = _mm256_loadu_si256((__m256i*)(sp - 1));
982 __m256i d = _mm256_load_si256((__m256i*)dp);
983 __m256i t = _mm256_add_epi64(s1, s2);
984 __m256i w = avx2_mm256_srai_epi64(t, e, ve);
985 d = _mm256_add_epi64(d, w);
986 _mm256_store_si256((__m256i*)dp, d);
989 for (; i > 0; i -= 4, sp += 4, dp += 4)
991 __m256i s1 = _mm256_load_si256((__m256i*)sp);
992 __m256i s2 = _mm256_loadu_si256((__m256i*)(sp + 1));
993 __m256i d = _mm256_load_si256((__m256i*)dp);
994 __m256i t = _mm256_add_epi64(s1, s2);
995 __m256i w = avx2_mm256_srai_epi64(t, e, ve);
996 d = _mm256_add_epi64(d, w);
997 _mm256_store_si256((__m256i*)dp, d);
1002 int i = (int)aug_width;
1004 for (; i > 0; i -= 4, sp += 4, dp += 4)
1006 __m256i s1 = _mm256_load_si256((__m256i*)sp);
1007 __m256i s2 = _mm256_loadu_si256((__m256i*)(sp - 1));
1008 __m256i d = _mm256_load_si256((__m256i*)dp);
1009 __m256i t = _mm256_add_epi64(s1, s2);
1010 __m256i v = _mm256_sub_epi64(vb, t);
1011 __m256i w = avx2_mm256_srai_epi64(v, e, ve);
1012 d = _mm256_sub_epi64(d, w);
1013 _mm256_store_si256((__m256i*)dp, d);
1016 for (; i > 0; i -= 4, sp += 4, dp += 4)
1018 __m256i s1 = _mm256_load_si256((__m256i*)sp);
1019 __m256i s2 = _mm256_loadu_si256((__m256i*)(sp + 1));
1020 __m256i d = _mm256_load_si256((__m256i*)dp);
1021 __m256i t = _mm256_add_epi64(s1, s2);
1022 __m256i v = _mm256_sub_epi64(vb, t);
1023 __m256i w = avx2_mm256_srai_epi64(v, e, ve);
1024 d = _mm256_sub_epi64(d, w);
1025 _mm256_store_si256((__m256i*)dp, d);
1033 for (
ui32 i = aug_width; i > 0; --i, sp++, dp++)
1034 *dp -= (b + a * (sp[-1] + sp[0])) >> e;
1036 for (
ui32 i = aug_width; i > 0; --i, sp++, dp++)
1037 *dp -= (b + a * (sp[0] + sp[1])) >> e;
1041 si64* t = aug; aug = oth; oth = t;
1043 ui32 w = aug_width; aug_width = oth_width; oth_width = w;
1049 const void* spl = even ? lsrc->p : hsrc->p;
1050 const void* sph = even ? hsrc->p : lsrc->p;
1052 avx2_interleave64(dp, spl, sph, w);
1057 dst->i64[0] = lsrc->i64[0];
1059 dst->i64[0] = hsrc->i64[0] >> 1;
1065 const line_buf* lsrc,
const line_buf* hsrc,
1066 ui32 width,
bool even)
1072 avx2_rev_horz_syn32(atk, dst, lsrc, hsrc, width, even);
1079 avx2_rev_horz_syn64(atk, dst, lsrc, hsrc, width, even);
void avx2_rev_horz_syn(const param_atk *atk, const line_buf *dst, const line_buf *lsrc, const line_buf *hsrc, ui32 width, bool even)
void avx2_rev_vert_step(const lifting_step *s, const line_buf *sig, const line_buf *other, const line_buf *aug, ui32 repeat, bool synthesis)
void avx2_rev_horz_ana(const param_atk *atk, const line_buf *ldst, const line_buf *hdst, const line_buf *src, ui32 width, bool even)