39#if defined(OJPH_ARCH_I386) || defined(OJPH_ARCH_X86_64)
57 void sse2_cnvrt_float_to_si32_shftd(
const float *sp,
si32 *dp,
float mul,
60 uint32_t rounding_mode = _MM_GET_ROUNDING_MODE();
61 _MM_SET_ROUNDING_MODE(_MM_ROUND_NEAREST);
62 __m128 shift = _mm_set1_ps(0.5f);
63 __m128 m = _mm_set1_ps(mul);
64 for (
int i = (width + 3) >> 2; i > 0; --i, sp+=4, dp+=4)
66 __m128 t = _mm_loadu_ps(sp);
67 __m128 s = _mm_add_ps(t, shift);
69 _mm_storeu_si128((__m128i*)dp, _mm_cvtps_epi32(s));
71 _MM_SET_ROUNDING_MODE(rounding_mode);
75 void sse2_cnvrt_float_to_si32(
const float *sp,
si32 *dp,
float mul,
78 uint32_t rounding_mode = _MM_GET_ROUNDING_MODE();
79 _MM_SET_ROUNDING_MODE(_MM_ROUND_NEAREST);
80 __m128 m = _mm_set1_ps(mul);
81 for (
int i = (width + 3) >> 2; i > 0; --i, sp+=4, dp+=4)
83 __m128 t = _mm_loadu_ps(sp);
84 __m128 s = _mm_mul_ps(t, m);
85 _mm_storeu_si128((__m128i*)dp, _mm_cvtps_epi32(s));
87 _MM_SET_ROUNDING_MODE(rounding_mode);
92 __m128i ojph_mm_max_ge_epi32(__m128i a, __m128i b, __m128 x, __m128 y)
94 __m128 ct = _mm_cmpge_ps(x, y);
95 __m128i c = _mm_castps_si128(ct);
96 __m128i d = _mm_and_si128(c, a);
97 __m128i e = _mm_andnot_si128(c, b);
98 return _mm_or_si128(d, e);
103 __m128i ojph_mm_min_lt_epi32(__m128i a, __m128i b, __m128 x, __m128 y)
105 __m128 ct = _mm_cmplt_ps(x, y);
106 __m128i c = _mm_castps_si128(ct);
107 __m128i d = _mm_and_si128(c, a);
108 __m128i e = _mm_andnot_si128(c, b);
109 return _mm_or_si128(d, e);
113 template <
bool NLT_TYPE3>
115 void local_sse2_irv_convert_to_integer(
const line_buf *src_line,
116 line_buf *dst_line,
ui32 dst_line_offset,
117 ui32 bit_depth,
bool is_signed,
ui32 width)
124 assert(bit_depth <= 32);
125 uint32_t rounding_mode = _MM_GET_ROUNDING_MODE();
126 _MM_SET_ROUNDING_MODE(_MM_ROUND_NEAREST);
128 const float* sp = src_line->f32;
129 si32* dp = dst_line->i32 + dst_line_offset;
136 si32 neg_limit = (
si32)INT_MIN >> (32 - bit_depth);
137 __m128 mul = _mm_set1_ps((
float)(1ull << bit_depth));
138 __m128 fl_up_lim = _mm_set1_ps(-(
float)neg_limit);
139 __m128 fl_low_lim = _mm_set1_ps((
float)neg_limit);
140 __m128i s32_up_lim = _mm_set1_epi32(INT_MAX >> (32 - bit_depth));
141 __m128i s32_low_lim = _mm_set1_epi32(INT_MIN >> (32 - bit_depth));
145 __m128i zero = _mm_setzero_si128();
146 __m128i bias = _mm_set1_epi32(-(
si32)((1ULL << (bit_depth - 1)) + 1));
147 for (
int i = (
int)width; i > 0; i -= 4, sp += 4, dp += 4) {
148 __m128 t = _mm_loadu_ps(sp);
149 t = _mm_mul_ps(t, mul);
150 __m128i u = _mm_cvtps_epi32(t);
151 u = ojph_mm_max_ge_epi32(u, s32_low_lim, t, fl_low_lim);
152 u = ojph_mm_min_lt_epi32(u, s32_up_lim, t, fl_up_lim);
155 __m128i c = _mm_cmpgt_epi32(zero, u);
156 __m128i neg = _mm_sub_epi32(bias, u);
157 neg = _mm_and_si128(c, neg);
158 u = _mm_andnot_si128(c, u);
159 u = _mm_or_si128(neg, u);
161 _mm_storeu_si128((__m128i*)dp, u);
166 __m128i half = _mm_set1_epi32((
si32)(1ULL << (bit_depth - 1)));
167 for (
int i = (
int)width; i > 0; i -= 4, sp += 4, dp += 4) {
168 __m128 t = _mm_loadu_ps(sp);
169 t = _mm_mul_ps(t, mul);
170 __m128i u = _mm_cvtps_epi32(t);
171 u = ojph_mm_max_ge_epi32(u, s32_low_lim, t, fl_low_lim);
172 u = ojph_mm_min_lt_epi32(u, s32_up_lim, t, fl_up_lim);
173 u = _mm_add_epi32(u, half);
174 _mm_storeu_si128((__m128i*)dp, u);
178 _MM_SET_ROUNDING_MODE(rounding_mode);
183 line_buf *dst_line,
ui32 dst_line_offset,
184 ui32 bit_depth,
bool is_signed,
ui32 width)
186 local_sse2_irv_convert_to_integer<false>(src_line, dst_line,
187 dst_line_offset, bit_depth, is_signed, width);
192 line_buf *dst_line,
ui32 dst_line_offset,
193 ui32 bit_depth,
bool is_signed,
ui32 width)
195 local_sse2_irv_convert_to_integer<true>(src_line, dst_line,
196 dst_line_offset, bit_depth, is_signed, width);
200 template<
int NLT_TYPE>
202 void local_sse2_irv_convert_to_integer_nlt2or4(
const line_buf *src_line,
203 line_buf *dst_line,
ui32 dst_line_offset,
214 assert(bit_depth <= 32);
215 uint32_t rounding_mode = _MM_GET_ROUNDING_MODE();
216 _MM_SET_ROUNDING_MODE(_MM_ROUND_NEAREST);
218 const float* sp = src_line->f32;
219 si32* dp = dst_line->i32 + dst_line_offset;
221 __m128 mul = _mm_set1_ps(rec->multiplier);
222 __m128 d_min = _mm_set1_ps(rec->fd_min);
223 __m128 d_max = _mm_set1_ps(rec->fd_max);
224 __m128 delta = _mm_set1_ps(rec->delta);
225 __m128 inv_delta = _mm_set1_ps(rec->inv_delta);
226 const float* lut = rec->dec_points;
228 __m128 half_ps = _mm_set1_ps(0.5f);
230 if (rec->is_signed())
232 __m128 half = _mm_set1_ps((
float)(1ULL << (rec->get_bit_depth() - 1)));
234 _mm_set1_epi32(-(
si32)((1ULL << (rec->get_bit_depth() - 1)) + 1));
235 __m128i zero = _mm_setzero_si128();
236 for (
int i = (
int)width; i > 0; i -= 4, sp += 4, dp += 4) {
237 __m128 t = _mm_loadu_ps(sp);
238 t = _mm_add_ps(t, half_ps);
239 t = _mm_max_ps(t, d_min);
240 t = _mm_min_ps(t, d_max);
241 __m128i k = _mm_cvttps_epi32(
242 _mm_mul_ps(_mm_sub_ps(t, d_min), inv_delta));
243 __m128 d_k = _mm_add_ps(d_min,
244 _mm_mul_ps(_mm_cvtepi32_ps(k), delta));
248 _mm_storeu_si128((__m128i*)kk, k);
249 __m128 t_k = _mm_set_ps(lut[kk[3]], lut[kk[2]],
250 lut[kk[1]], lut[kk[0]]);
251 __m128 t_kp1 = _mm_set_ps(lut[kk[3] + 1], lut[kk[2] + 1],
252 lut[kk[1] + 1], lut[kk[0] + 1]);
253 __m128 z = _mm_add_ps(t_k,
254 _mm_mul_ps(_mm_mul_ps(_mm_sub_ps(t, d_k), inv_delta),
255 _mm_sub_ps(t_kp1, t_k)));
257 _mm_cvtps_epi32(_mm_sub_ps(_mm_mul_ps(z, mul), half));
260 __m128i c = _mm_cmpgt_epi32(zero, v);
261 __m128i neg = _mm_sub_epi32(bias, v);
262 neg = _mm_and_si128(c, neg);
263 v = _mm_andnot_si128(c, v);
264 v = _mm_or_si128(neg, v);
266 _mm_storeu_si128((__m128i*)dp, v);
271 for (
int i = (
int)width; i > 0; i -= 4, sp += 4, dp += 4) {
272 __m128 t = _mm_loadu_ps(sp);
273 t = _mm_add_ps(t, half_ps);
274 t = _mm_max_ps(t, d_min);
275 t = _mm_min_ps(t, d_max);
276 __m128i k = _mm_cvttps_epi32(
277 _mm_mul_ps(_mm_sub_ps(t, d_min), inv_delta));
278 __m128 d_k = _mm_add_ps(d_min,
279 _mm_mul_ps(_mm_cvtepi32_ps(k), delta));
283 _mm_storeu_si128((__m128i*)kk, k);
284 __m128 t_k = _mm_set_ps(lut[kk[3]], lut[kk[2]],
285 lut[kk[1]], lut[kk[0]]);
286 __m128 t_kp1 = _mm_set_ps(lut[kk[3] + 1], lut[kk[2] + 1],
287 lut[kk[1] + 1], lut[kk[0] + 1]);
288 __m128 z = _mm_add_ps(t_k,
289 _mm_mul_ps(_mm_mul_ps(_mm_sub_ps(t, d_k), inv_delta),
290 _mm_sub_ps(t_kp1, t_k)));
291 __m128i v = _mm_cvtps_epi32(_mm_mul_ps(z, mul));
292 _mm_storeu_si128((__m128i*)dp, v);
296 _MM_SET_ROUNDING_MODE(rounding_mode);
301 line_buf *dst_line,
ui32 dst_line_offset,
305 if (rec->get_type() == nl::OJPH_NLT_LUT_STYLE_NLT)
306 local_sse2_irv_convert_to_integer_nlt2or4<2>(src_line, dst_line,
307 dst_line_offset, bit_depth, is_signed, width, rec);
308 else if (rec->get_type() == nl::OJPH_NLT_BINARY_COMPLEMENT_PLUS_LUT)
309 local_sse2_irv_convert_to_integer_nlt2or4<4>(src_line, dst_line,
310 dst_line_offset, bit_depth, is_signed, width, rec);
317 static inline __m128i sse2_mm_srai_epi64(__m128i a,
int amt, __m128i m)
321 __m128i x = _mm_srli_epi64(a, amt);
322 x = _mm_xor_si128(x, m);
323 __m128i result = _mm_sub_epi64(x, m);
328 static inline __m128i sse2_cvtlo_epi32_epi64(__m128i a, __m128i zero)
331 t = _mm_cmplt_epi32(a, zero);
332 t = _mm_unpacklo_epi32(a, t);
337 static inline __m128i sse2_cvthi_epi32_epi64(__m128i a, __m128i zero)
340 t = _mm_cmplt_epi32(a, zero);
341 t = _mm_unpackhi_epi32(a, t);
347 const ui32 src_line_offset,
349 const ui32 dst_line_offset,
356 const si32 *sp = src_line->i32 + src_line_offset;
357 si32 *dp = dst_line->i32 + dst_line_offset;
358 __m128i sh = _mm_set1_epi32((
si32)shift);
359 for (
int i = (width + 3) >> 2; i > 0; --i, sp+=4, dp+=4)
361 __m128i s = _mm_loadu_si128((__m128i*)sp);
362 s = _mm_add_epi32(s, sh);
363 _mm_storeu_si128((__m128i*)dp, s);
368 const si32 *sp = src_line->i32 + src_line_offset;
369 si64 *dp = dst_line->i64 + dst_line_offset;
370 __m128i zero = _mm_setzero_si128();
371 __m128i sh = _mm_set1_epi64x(shift);
372 for (
int i = (width + 3) >> 2; i > 0; --i, sp+=4, dp+=4)
375 s = _mm_loadu_si128((__m128i*)sp);
377 t = sse2_cvtlo_epi32_epi64(s, zero);
378 t = _mm_add_epi64(t, sh);
379 _mm_storeu_si128((__m128i*)dp, t);
381 t = sse2_cvthi_epi32_epi64(s, zero);
382 t = _mm_add_epi64(t, sh);
383 _mm_storeu_si128((__m128i*)dp + 1, t);
391 const si64 *sp = src_line->i64 + src_line_offset;
392 si32 *dp = dst_line->i32 + dst_line_offset;
393 __m128i low_bits = _mm_set_epi64x(0, (
si64)ULLONG_MAX);
394 __m128i sh = _mm_set1_epi64x(shift);
395 for (
int i = (width + 3) >> 2; i > 0; --i, sp+=4, dp+=4)
398 s = _mm_loadu_si128((__m128i*)sp);
399 s = _mm_add_epi64(s, sh);
401 t = _mm_shuffle_epi32(s, _MM_SHUFFLE(0, 0, 2, 0));
402 t = _mm_and_si128(low_bits, t);
404 s = _mm_loadu_si128((__m128i*)sp + 1);
405 s = _mm_add_epi64(s, sh);
407 s = _mm_shuffle_epi32(s, _MM_SHUFFLE(2, 0, 0, 0));
408 s = _mm_andnot_si128(low_bits, s);
410 t = _mm_or_si128(s, t);
411 _mm_storeu_si128((__m128i*)dp, t);
418 const ui32 src_line_offset,
420 const ui32 dst_line_offset,
427 const si32 *sp = src_line->i32 + src_line_offset;
428 si32 *dp = dst_line->i32 + dst_line_offset;
429 __m128i sh = _mm_set1_epi32((
si32)(-shift));
430 __m128i zero = _mm_setzero_si128();
431 for (
int i = (width + 3) >> 2; i > 0; --i, sp += 4, dp += 4)
433 __m128i s = _mm_loadu_si128((__m128i*)sp);
434 __m128i c = _mm_cmplt_epi32(s, zero);
435 __m128i v_m_sh = _mm_sub_epi32(sh, s);
436 v_m_sh = _mm_and_si128(c, v_m_sh);
437 s = _mm_andnot_si128(c, s);
438 s = _mm_or_si128(s, v_m_sh);
439 _mm_storeu_si128((__m128i*)dp, s);
444 const si32 *sp = src_line->i32 + src_line_offset;
445 si64 *dp = dst_line->i64 + dst_line_offset;
446 __m128i sh = _mm_set1_epi64x(-shift);
447 __m128i zero = _mm_setzero_si128();
448 for (
int i = (width + 3) >> 2; i > 0; --i, sp += 4, dp += 4)
450 __m128i s, t, u, c, v_m_sh;
451 s = _mm_loadu_si128((__m128i*)sp);
453 t = _mm_cmplt_epi32(s, zero);
454 u = _mm_unpacklo_epi32(s, t);
455 c = _mm_unpacklo_epi32(t, t);
457 v_m_sh = _mm_sub_epi64(sh, u);
458 v_m_sh = _mm_and_si128(c, v_m_sh);
459 u = _mm_andnot_si128(c, u);
460 u = _mm_or_si128(u, v_m_sh);
462 _mm_storeu_si128((__m128i*)dp, u);
463 u = _mm_unpackhi_epi32(s, t);
464 c = _mm_unpackhi_epi32(t, t);
466 v_m_sh = _mm_sub_epi64(sh, u);
467 v_m_sh = _mm_and_si128(c, v_m_sh);
468 u = _mm_andnot_si128(c, u);
469 u = _mm_or_si128(u, v_m_sh);
471 _mm_storeu_si128((__m128i*)dp + 1, u);
479 const si64 *sp = src_line->i64 + src_line_offset;
480 si32 *dp = dst_line->i32 + dst_line_offset;
481 __m128i sh = _mm_set1_epi64x(-shift);
482 __m128i zero = _mm_setzero_si128();
483 __m128i half_mask = _mm_set_epi64x(0, (
si64)ULLONG_MAX);
484 for (
int i = (width + 3) >> 2; i > 0; --i, sp += 4, dp += 4)
488 __m128i s, t, p, n, m, tm;
489 s = _mm_loadu_si128((__m128i*)sp);
491 tm = _mm_cmplt_epi32(s, zero);
492 m = _mm_shuffle_epi32(tm, _MM_SHUFFLE(3, 3, 1, 1));
493 tm = _mm_sub_epi64(sh, s);
494 n = _mm_and_si128(m, tm);
495 p = _mm_andnot_si128(m, s);
496 tm = _mm_or_si128(n, p);
497 tm = _mm_shuffle_epi32(tm, _MM_SHUFFLE(0, 0, 2, 0));
498 t = _mm_and_si128(half_mask, tm);
500 s = _mm_loadu_si128((__m128i*)sp + 1);
501 tm = _mm_cmplt_epi32(s, zero);
502 m = _mm_shuffle_epi32(tm, _MM_SHUFFLE(3, 3, 1, 1));
503 tm = _mm_sub_epi64(sh, s);
504 n = _mm_and_si128(m, tm);
505 p = _mm_andnot_si128(m, s);
506 tm = _mm_or_si128(n, p);
507 tm = _mm_shuffle_epi32(tm, _MM_SHUFFLE(2, 0, 0, 0));
508 tm = _mm_andnot_si128(half_mask, tm);
510 t = _mm_or_si128(t, tm);
511 _mm_storeu_si128((__m128i*)dp, t);
517 template<
bool NLT_TYPE3>
519 void local_sse2_irv_convert_to_float(
const line_buf *src_line,
520 ui32 src_line_offset, line_buf *dst_line,
521 ui32 bit_depth,
bool is_signed,
ui32 width)
528 assert(bit_depth <= 32);
529 __m128 mul = _mm_set1_ps((
float)(1.0 / (
double)(1ULL << bit_depth)));
531 const si32* sp = src_line->i32 + src_line_offset;
532 float* dp = dst_line->f32;
535 __m128i zero = _mm_setzero_si128();
536 __m128i bias = _mm_set1_epi32(-(
si32)((1ULL << (bit_depth - 1)) + 1));
537 for (
int i = (
int)width; i > 0; i -= 4, sp += 4, dp += 4) {
538 __m128i t = _mm_loadu_si128((__m128i*)sp);
541 __m128i c = _mm_cmplt_epi32(t, zero);
542 __m128i neg = _mm_sub_epi32(bias, t);
543 neg = _mm_and_si128(c, neg);
544 c = _mm_andnot_si128(c, t);
545 t = _mm_or_si128(neg, c);
547 __m128 v = _mm_cvtepi32_ps(t);
548 v = _mm_mul_ps(v, mul);
549 _mm_storeu_ps(dp, v);
554 __m128i half = _mm_set1_epi32((
si32)(1ULL << (bit_depth - 1)));
555 for (
int i = (
int)width; i > 0; i -= 4, sp += 4, dp += 4) {
556 __m128i t = _mm_loadu_si128((__m128i*)sp);
557 t = _mm_sub_epi32(t, half);
558 __m128 v = _mm_cvtepi32_ps(t);
559 v = _mm_mul_ps(v, mul);
560 _mm_storeu_ps(dp, v);
567 ui32 src_line_offset, line_buf *dst_line,
568 ui32 bit_depth,
bool is_signed,
ui32 width)
570 local_sse2_irv_convert_to_float<false>(src_line, src_line_offset,
571 dst_line, bit_depth, is_signed, width);
576 ui32 src_line_offset, line_buf *dst_line,
577 ui32 bit_depth,
bool is_signed,
ui32 width)
579 local_sse2_irv_convert_to_float<true>(src_line, src_line_offset,
580 dst_line, bit_depth, is_signed, width);
584 template<
int NLT_TYPE>
586 void local_sse2_irv_convert_to_float_nlt2or4(
const line_buf *src_line,
587 ui32 src_line_offset, line_buf *dst_line,
597 assert(bit_depth <= 32);
598 __m128 mul = _mm_set1_ps((
float)(1.0 / (
double)(1ULL << bit_depth)));
599 __m128 d_min = _mm_set1_ps(rec->ft_min);
600 __m128 d_max = _mm_set1_ps(rec->ft_max);
601 __m128 delta = _mm_set1_ps(rec->delta);
602 __m128 inv_delta = _mm_set1_ps(rec->inv_delta);
603 const float* lut = rec->enc_points;
605 __m128 half_ps = _mm_set1_ps(0.5f);
607 const si32* sp = src_line->i32 + src_line_offset;
608 float* dp = dst_line->f32;
609 if (rec->is_signed())
612 _mm_set1_epi32(-(
si32)((1ULL << (rec->get_bit_depth() - 1)) + 1));
613 __m128i zero = _mm_setzero_si128();
614 for (
int i = (
int)width; i > 0; i -= 4, sp += 4, dp += 4) {
615 __m128i v = _mm_loadu_si128((__m128i*)sp);
618 __m128i c = _mm_cmpgt_epi32(zero, v);
619 __m128i neg = _mm_sub_epi32(bias, v);
620 neg = _mm_and_si128(c, neg);
621 v = _mm_andnot_si128(c, v);
622 v = _mm_or_si128(neg, v);
624 __m128 t = _mm_add_ps(
625 _mm_mul_ps(_mm_cvtepi32_ps(v), mul), half_ps);
626 t = _mm_max_ps(t, d_min);
627 t = _mm_min_ps(t, d_max);
628 __m128i k = _mm_cvttps_epi32(
629 _mm_mul_ps(_mm_sub_ps(t, d_min), inv_delta));
630 __m128 d_k = _mm_add_ps(d_min,
631 _mm_mul_ps(_mm_cvtepi32_ps(k), delta));
635 _mm_storeu_si128((__m128i*)kk, k);
636 __m128 t_k = _mm_set_ps(lut[kk[3]], lut[kk[2]],
637 lut[kk[1]], lut[kk[0]]);
638 __m128 t_kp1 = _mm_set_ps(lut[kk[3] + 1], lut[kk[2] + 1],
639 lut[kk[1] + 1], lut[kk[0] + 1]);
640 __m128 y = _mm_add_ps(t_k,
641 _mm_mul_ps(_mm_mul_ps(_mm_sub_ps(t, d_k), inv_delta),
642 _mm_sub_ps(t_kp1, t_k)));
643 _mm_storeu_ps(dp, _mm_sub_ps(y, half_ps));
648 for (
int i = (
int)width; i > 0; i -= 4, sp += 4, dp += 4) {
649 __m128i v = _mm_loadu_si128((__m128i*)sp);
650 __m128 t = _mm_mul_ps(_mm_cvtepi32_ps(v), mul);
651 t = _mm_max_ps(t, d_min);
652 t = _mm_min_ps(t, d_max);
653 __m128i k = _mm_cvttps_epi32(
654 _mm_mul_ps(_mm_sub_ps(t, d_min), inv_delta));
655 __m128 d_k = _mm_add_ps(d_min,
656 _mm_mul_ps(_mm_cvtepi32_ps(k), delta));
660 _mm_storeu_si128((__m128i*)kk, k);
661 __m128 t_k = _mm_set_ps(lut[kk[3]], lut[kk[2]],
662 lut[kk[1]], lut[kk[0]]);
663 __m128 t_kp1 = _mm_set_ps(lut[kk[3] + 1], lut[kk[2] + 1],
664 lut[kk[1] + 1], lut[kk[0] + 1]);
665 __m128 y = _mm_add_ps(t_k,
666 _mm_mul_ps(_mm_mul_ps(_mm_sub_ps(t, d_k), inv_delta),
667 _mm_sub_ps(t_kp1, t_k)));
668 _mm_storeu_ps(dp, _mm_sub_ps(y, half_ps));
675 ui32 src_line_offset, line_buf *dst_line,
679 if (rec->get_type() == nl::OJPH_NLT_LUT_STYLE_NLT)
680 local_sse2_irv_convert_to_float_nlt2or4<2>(src_line,
681 src_line_offset, dst_line, bit_depth, is_signed, width, rec);
682 else if (rec->get_type() == nl::OJPH_NLT_BINARY_COMPLEMENT_PLUS_LUT)
683 local_sse2_irv_convert_to_float_nlt2or4<4>(src_line,
684 src_line_offset, dst_line, bit_depth, is_signed, width, rec);
693 line_buf *y, line_buf *cb, line_buf *cr,
711 const si32 *rp = r->i32, * gp = g->i32, * bp = b->i32;
712 si32 *yp = y->i32, * cbp = cb->i32, * crp = cr->i32;
713 for (
int i = (repeat + 3) >> 2; i > 0; --i)
715 __m128i mr = _mm_load_si128((__m128i*)rp);
716 __m128i mg = _mm_load_si128((__m128i*)gp);
717 __m128i mb = _mm_load_si128((__m128i*)bp);
718 __m128i t = _mm_add_epi32(mr, mb);
719 t = _mm_add_epi32(t, _mm_slli_epi32(mg, 1));
720 _mm_store_si128((__m128i*)yp, _mm_srai_epi32(t, 2));
721 t = _mm_sub_epi32(mb, mg);
722 _mm_store_si128((__m128i*)cbp, t);
723 t = _mm_sub_epi32(mr, mg);
724 _mm_store_si128((__m128i*)crp, t);
726 rp += 4; gp += 4; bp += 4;
727 yp += 4; cbp += 4; crp += 4;
738 __m128i zero = _mm_setzero_si128();
739 __m128i v2 = _mm_set1_epi64x(1ULL << (63 - 2));
740 const si32 *rp = r->i32, *gp = g->i32, *bp = b->i32;
741 si64 *yp = y->i64, *cbp = cb->i64, *crp = cr->i64;
742 for (
int i = (repeat + 3) >> 2; i > 0; --i)
744 __m128i mr32 = _mm_load_si128((__m128i*)rp);
745 __m128i mg32 = _mm_load_si128((__m128i*)gp);
746 __m128i mb32 = _mm_load_si128((__m128i*)bp);
747 __m128i mr, mg, mb, t;
748 mr = sse2_cvtlo_epi32_epi64(mr32, zero);
749 mg = sse2_cvtlo_epi32_epi64(mg32, zero);
750 mb = sse2_cvtlo_epi32_epi64(mb32, zero);
752 t = _mm_add_epi64(mr, mb);
753 t = _mm_add_epi64(t, _mm_slli_epi64(mg, 1));
754 _mm_store_si128((__m128i*)yp, sse2_mm_srai_epi64(t, 2, v2));
755 t = _mm_sub_epi64(mb, mg);
756 _mm_store_si128((__m128i*)cbp, t);
757 t = _mm_sub_epi64(mr, mg);
758 _mm_store_si128((__m128i*)crp, t);
760 yp += 2; cbp += 2; crp += 2;
762 mr = sse2_cvthi_epi32_epi64(mr32, zero);
763 mg = sse2_cvthi_epi32_epi64(mg32, zero);
764 mb = sse2_cvthi_epi32_epi64(mb32, zero);
766 t = _mm_add_epi64(mr, mb);
767 t = _mm_add_epi64(t, _mm_slli_epi64(mg, 1));
768 _mm_store_si128((__m128i*)yp, sse2_mm_srai_epi64(t, 2, v2));
769 t = _mm_sub_epi64(mb, mg);
770 _mm_store_si128((__m128i*)cbp, t);
771 t = _mm_sub_epi64(mr, mg);
772 _mm_store_si128((__m128i*)crp, t);
774 rp += 4; gp += 4; bp += 4;
775 yp += 2; cbp += 2; crp += 2;
784 line_buf *r, line_buf *g, line_buf *b,
802 const si32 *yp = y->i32, *cbp = cb->i32, *crp = cr->i32;
803 si32 *rp = r->i32, *gp = g->i32, *bp = b->i32;
804 for (
int i = (repeat + 3) >> 2; i > 0; --i)
806 __m128i my = _mm_load_si128((__m128i*)yp);
807 __m128i mcb = _mm_load_si128((__m128i*)cbp);
808 __m128i mcr = _mm_load_si128((__m128i*)crp);
810 __m128i t = _mm_add_epi32(mcb, mcr);
811 t = _mm_sub_epi32(my, _mm_srai_epi32(t, 2));
812 _mm_store_si128((__m128i*)gp, t);
813 __m128i u = _mm_add_epi32(mcb, t);
814 _mm_store_si128((__m128i*)bp, u);
815 u = _mm_add_epi32(mcr, t);
816 _mm_store_si128((__m128i*)rp, u);
818 yp += 4; cbp += 4; crp += 4;
819 rp += 4; gp += 4; bp += 4;
830 __m128i v2 = _mm_set1_epi64x(1ULL << (63 - 2));
831 __m128i low_bits = _mm_set_epi64x(0, (
si64)ULLONG_MAX);
832 const si64 *yp = y->i64, *cbp = cb->i64, *crp = cr->i64;
833 si32 *rp = r->i32, *gp = g->i32, *bp = b->i32;
834 for (
int i = (repeat + 3) >> 2; i > 0; --i)
836 __m128i my, mcb, mcr, tr, tg, tb;
837 my = _mm_load_si128((__m128i*)yp);
838 mcb = _mm_load_si128((__m128i*)cbp);
839 mcr = _mm_load_si128((__m128i*)crp);
841 tg = _mm_add_epi64(mcb, mcr);
842 tg = _mm_sub_epi64(my, sse2_mm_srai_epi64(tg, 2, v2));
843 tb = _mm_add_epi64(mcb, tg);
844 tr = _mm_add_epi64(mcr, tg);
847 mr = _mm_shuffle_epi32(tr, _MM_SHUFFLE(0, 0, 2, 0));
848 mr = _mm_and_si128(low_bits, mr);
849 mg = _mm_shuffle_epi32(tg, _MM_SHUFFLE(0, 0, 2, 0));
850 mg = _mm_and_si128(low_bits, mg);
851 mb = _mm_shuffle_epi32(tb, _MM_SHUFFLE(0, 0, 2, 0));
852 mb = _mm_and_si128(low_bits, mb);
854 yp += 2; cbp += 2; crp += 2;
856 my = _mm_load_si128((__m128i*)yp);
857 mcb = _mm_load_si128((__m128i*)cbp);
858 mcr = _mm_load_si128((__m128i*)crp);
860 tg = _mm_add_epi64(mcb, mcr);
861 tg = _mm_sub_epi64(my, sse2_mm_srai_epi64(tg, 2, v2));
862 tb = _mm_add_epi64(mcb, tg);
863 tr = _mm_add_epi64(mcr, tg);
865 tr = _mm_shuffle_epi32(tr, _MM_SHUFFLE(2, 0, 0, 0));
866 tr = _mm_andnot_si128(low_bits, tr);
867 mr = _mm_or_si128(mr, tr);
868 tg = _mm_shuffle_epi32(tg, _MM_SHUFFLE(2, 0, 0, 0));
869 tg = _mm_andnot_si128(low_bits, tg);
870 mg = _mm_or_si128(mg, tg);
871 tb = _mm_shuffle_epi32(tb, _MM_SHUFFLE(2, 0, 0, 0));
872 tb = _mm_andnot_si128(low_bits, tb);
873 mb = _mm_or_si128(mb, tb);
875 _mm_store_si128((__m128i*)rp, mr);
876 _mm_store_si128((__m128i*)gp, mg);
877 _mm_store_si128((__m128i*)bp, mb);
879 yp += 2; cbp += 2; crp += 2;
880 rp += 4; gp += 4; bp += 4;
void sse2_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 sse2_irv_convert_to_integer(const line_buf *src_line, line_buf *dst_line, ui32 dst_line_offset, ui32 bit_depth, bool is_signed, ui32 width)
void sse2_irv_convert_to_float_nlt_type3(const line_buf *src_line, ui32 src_line_offset, line_buf *dst_line, ui32 bit_depth, bool is_signed, ui32 width)
void sse2_irv_convert_to_integer_nlt_type3(const line_buf *src_line, line_buf *dst_line, ui32 dst_line_offset, ui32 bit_depth, bool is_signed, ui32 width)
void sse2_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 sse2_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)
void sse2_irv_convert_to_integer_nlt(const line_buf *src_line, line_buf *dst_line, ui32 dst_line_offset, ui32 bit_depth, bool is_signed, ui32 width, const nlt_rec *rec)
void sse2_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 sse2_irv_convert_to_float_nlt(const line_buf *src_line, ui32 src_line_offset, line_buf *dst_line, ui32 bit_depth, bool is_signed, ui32 width, const nlt_rec *rec)
void sse2_irv_convert_to_float(const line_buf *src_line, ui32 src_line_offset, line_buf *dst_line, ui32 bit_depth, bool is_signed, ui32 width)
ojph::param_nlt::nonlinearity nonlinearity