59 __asm__(
"xvrspi %x0,%x1" :
"=wa"(w) :
"wa"((
vsx_v_f32)a));
60 return (
v128_t)vec_cts(w, 0);
65 const ui32 src_line_offset,
67 const ui32 dst_line_offset,
74 const si32 *sp = src_line->i32 + src_line_offset;
75 si32 *dp = dst_line->i32 + dst_line_offset;
77 for (
int i = (width + 3) >> 2; i > 0; --i, sp+=4, dp+=4)
79 v128_t s = vsx_v128_load(sp);
80 s = vsx_i32x4_add(s, sh);
81 vsx_v128_store(dp, s);
86 const si32 *sp = src_line->i32 + src_line_offset;
87 si64 *dp = dst_line->i64 + dst_line_offset;
88 v128_t sh = vsx_i64x2_splat(shift);
89 for (
int i = (width + 3) >> 2; i > 0; --i, sp+=4, dp+=4)
92 s = vsx_v128_load(sp);
94 t = vsx_i64x2_extend_low_i32x4(s);
95 t = vsx_i64x2_add(t, sh);
96 vsx_v128_store(dp, t);
98 t = vsx_i64x2_extend_high_i32x4(s);
99 t = vsx_i64x2_add(t, sh);
100 vsx_v128_store(dp + 2, t);
108 const si64 *sp = src_line->i64 + src_line_offset;
109 si32 *dp = dst_line->i32 + dst_line_offset;
110 v128_t sh = vsx_i64x2_splat(shift);
111 for (
int i = (width + 3) >> 2; i > 0; --i, sp+=4, dp+=4)
114 s0 = vsx_v128_load(sp);
115 s0 = vsx_i64x2_add(s0, sh);
116 s1 = vsx_v128_load(sp + 2);
117 s1 = vsx_i64x2_add(s1, sh);
119 vsx_v128_store(dp, s0);
126 const ui32 src_line_offset,
128 const ui32 dst_line_offset,
135 const si32 *sp = src_line->i32 + src_line_offset;
136 si32 *dp = dst_line->i32 + dst_line_offset;
138 v128_t zero = vsx_i32x4_splat(0);
139 for (
int i = (width + 3) >> 2; i > 0; --i, sp += 4, dp += 4)
141 v128_t s = vsx_v128_load(sp);
142 v128_t c = vsx_i32x4_lt(s, zero);
143 v128_t v_m_sh = vsx_i32x4_sub(sh, s);
144 v_m_sh = vsx_v128_and(c, v_m_sh);
145 s = vsx_v128_andnot(s, c);
146 s = vsx_v128_or(s, v_m_sh);
147 vsx_v128_store(dp, s);
152 const si32 *sp = src_line->i32 + src_line_offset;
153 si64 *dp = dst_line->i64 + dst_line_offset;
154 v128_t sh = vsx_i64x2_splat(-shift);
155 v128_t zero = vsx_i32x4_splat(0);
156 for (
int i = (width + 3) >> 2; i > 0; --i, sp += 4, dp += 4)
159 s = vsx_v128_load(sp);
161 u = vsx_i64x2_extend_low_i32x4(s);
162 c = vsx_i64x2_lt(u, zero);
163 v_m_sh = vsx_i64x2_sub(sh, u);
164 v_m_sh = vsx_v128_and(c, v_m_sh);
165 u = vsx_v128_andnot(u, c);
166 u = vsx_v128_or(u, v_m_sh);
168 vsx_v128_store(dp, u);
170 u = vsx_i64x2_extend_high_i32x4(s);
171 c = vsx_i64x2_lt(u, zero);
172 v_m_sh = vsx_i64x2_sub(sh, u);
173 v_m_sh = vsx_v128_and(c, v_m_sh);
174 u = vsx_v128_andnot(u, c);
175 u = vsx_v128_or(u, v_m_sh);
177 vsx_v128_store(dp + 2, u);
185 const si64 *sp = src_line->i64 + src_line_offset;
186 si32 *dp = dst_line->i32 + dst_line_offset;
187 v128_t sh = vsx_i64x2_splat(-shift);
188 v128_t zero = vsx_i32x4_splat(0);
189 for (
int i = (width + 3) >> 2; i > 0; --i, sp += 4, dp += 4)
193 v128_t s, t0, t1, p, n, m, tm;
194 s = vsx_v128_load(sp);
195 m = vsx_i64x2_lt(s, zero);
196 tm = vsx_i64x2_sub(sh, s);
197 n = vsx_v128_and(m, tm);
198 p = vsx_v128_andnot(s, m);
199 t0 = vsx_v128_or(n, p);
201 s = vsx_v128_load(sp + 2);
202 m = vsx_i64x2_lt(s, zero);
203 tm = vsx_i64x2_sub(sh, s);
204 n = vsx_v128_and(m, tm);
205 p = vsx_v128_andnot(s, m);
206 t1 = vsx_v128_or(n, p);
209 vsx_v128_store(dp, t0);
218 v128_t shift = vsx_f32x4_splat(0.5f);
219 v128_t m = vsx_f32x4_splat(mul);
220 for (
ui32 i = (width + 3) >> 2; i > 0; --i, sp+=4, dp+=4)
222 v128_t t = vsx_v128_load(sp);
223 v128_t s = vsx_f32x4_convert_i32x4(t);
224 s = vsx_f32x4_mul(s, m);
225 s = vsx_f32x4_sub(s, shift);
226 vsx_v128_store(dp, s);
234 v128_t m = vsx_f32x4_splat(mul);
235 for (
ui32 i = (width + 3) >> 2; i > 0; --i, sp+=4, dp+=4)
237 v128_t t = vsx_v128_load(sp);
238 v128_t s = vsx_f32x4_convert_i32x4(t);
239 s = vsx_f32x4_mul(s, m);
240 vsx_v128_store(dp, s);
248 const v128_t half = vsx_f32x4_splat(0.5f);
249 v128_t m = vsx_f32x4_splat(mul);
250 for (
int i = (width + 3) >> 2; i > 0; --i, sp+=4, dp+=4)
252 v128_t t = vsx_v128_load(sp);
253 v128_t s = vsx_f32x4_add(t, half);
254 s = vsx_f32x4_mul(s, m);
255 s = vsx_f32x4_add(s, half);
264 const v128_t half = vsx_f32x4_splat(0.5f);
265 v128_t m = vsx_f32x4_splat(mul);
266 for (
int i = (width + 3) >> 2; i > 0; --i, sp+=4, dp+=4)
268 v128_t t = vsx_v128_load(sp);
269 v128_t s = vsx_f32x4_mul(t, m);
270 s = vsx_f32x4_add(s, half);
279 v128_t c = vsx_f32x4_ge(x, y);
287 v128_t c = vsx_f32x4_lt(x, y);
292 template <
bool NLT_TYPE3>
296 ui32 bit_depth,
bool is_signed,
ui32 width)
303 assert(bit_depth <= 32);
304 const float* sp = src_line->f32;
305 si32* dp = dst_line->i32 + dst_line_offset;
312 si32 neg_limit = (
si32)INT_MIN >> (32 - bit_depth);
313 v128_t mul = vsx_f32x4_splat((
float)(1ull << bit_depth));
314 v128_t fl_up_lim = vsx_f32x4_splat(-(
float)neg_limit);
315 v128_t fl_low_lim = vsx_f32x4_splat((
float)neg_limit);
316 v128_t s32_up_lim = vsx_i32x4_splat(INT_MAX >> (32 - bit_depth));
317 v128_t s32_low_lim = vsx_i32x4_splat(INT_MIN >> (32 - bit_depth));
321 const v128_t zero = vsx_f32x4_splat(0.0f);
322 v128_t bias = vsx_i32x4_splat(-(
si32)((1ULL << (bit_depth - 1)) + 1));
323 for (
int i = (
int)width; i > 0; i -= 4, sp += 4, dp += 4) {
324 v128_t t = vsx_v128_load(sp);
325 t = vsx_f32x4_mul(t, mul);
331 v128_t c = vsx_i32x4_gt(zero, u);
332 v128_t neg = vsx_i32x4_sub(bias, u);
333 neg = vsx_v128_and(c, neg);
334 u = vsx_v128_andnot(u, c);
335 u = vsx_v128_or(neg, u);
337 vsx_v128_store(dp, u);
342 v128_t ihalf = vsx_i32x4_splat((
si32)(1ULL << (bit_depth - 1)));
343 for (
int i = (
int)width; i > 0; i -= 4, sp += 4, dp += 4) {
344 v128_t t = vsx_v128_load(sp);
345 t = vsx_f32x4_mul(t, mul);
349 u = vsx_i32x4_add(u, ihalf);
350 vsx_v128_store(dp, u);
358 ui32 bit_depth,
bool is_signed,
ui32 width)
361 dst_line_offset, bit_depth, is_signed, width);
367 ui32 bit_depth,
bool is_signed,
ui32 width)
370 dst_line_offset, bit_depth, is_signed, width);
374 template <
bool NLT_TYPE3>
378 ui32 bit_depth,
bool is_signed,
ui32 width)
385 assert(bit_depth <= 32);
386 v128_t mul = vsx_f32x4_splat((
float)(1.0 / (
double)(1ULL << bit_depth)));
388 const si32* sp = src_line->i32 + src_line_offset;
389 float* dp = dst_line->f32;
392 v128_t zero = vsx_i32x4_splat(0);
393 v128_t bias = vsx_i32x4_splat(-(
si32)((1ULL << (bit_depth - 1)) + 1));
394 for (
int i = (
int)width; i > 0; i -= 4, sp += 4, dp += 4) {
395 v128_t t = vsx_v128_load(sp);
398 v128_t c = vsx_i32x4_lt(t, zero);
399 v128_t neg = vsx_i32x4_sub(bias, t);
400 neg = vsx_v128_and(c, neg);
401 c = vsx_v128_andnot(t, c);
402 t = vsx_v128_or(neg, c);
404 v128_t v = vsx_f32x4_convert_i32x4(t);
405 v = vsx_f32x4_mul(v, mul);
406 vsx_v128_store(dp, v);
411 v128_t half = vsx_i32x4_splat((
si32)(1ULL << (bit_depth - 1)));
412 for (
int i = (
int)width; i > 0; i -= 4, sp += 4, dp += 4) {
413 v128_t t = vsx_v128_load(sp);
414 t = vsx_i32x4_sub(t, half);
415 v128_t v = vsx_f32x4_convert_i32x4(t);
416 v = vsx_f32x4_mul(v, mul);
417 vsx_v128_store(dp, v);
425 ui32 bit_depth,
bool is_signed,
ui32 width)
428 dst_line, bit_depth, is_signed, width);
434 ui32 bit_depth,
bool is_signed,
ui32 width)
437 dst_line, bit_depth, is_signed, width);
462 const si32 *rp = r->i32, * gp = g->i32, * bp = b->i32;
463 si32 *yp = y->i32, * cbp = cb->i32, * crp = cr->i32;
465 for (
int i = (repeat + 3) >> 2; i > 0; --i)
467 v128_t mr = vsx_v128_load(rp);
468 v128_t mg = vsx_v128_load(gp);
469 v128_t mb = vsx_v128_load(bp);
470 v128_t t = vsx_i32x4_add(mr, mb);
471 t = vsx_i32x4_add(t, vsx_i32x4_shl(mg, 1));
472 vsx_v128_store(yp, vsx_i32x4_shr(t, 2));
473 t = vsx_i32x4_sub(mb, mg);
474 vsx_v128_store(cbp, t);
475 t = vsx_i32x4_sub(mr, mg);
476 vsx_v128_store(crp, t);
478 rp += 4; gp += 4; bp += 4;
479 yp += 4; cbp += 4; crp += 4;
490 const si32 *rp = r->i32, *gp = g->i32, *bp = b->i32;
491 si64 *yp = y->i64, *cbp = cb->i64, *crp = cr->i64;
492 for (
int i = (repeat + 3) >> 2; i > 0; --i)
494 v128_t mr32 = vsx_v128_load(rp);
495 v128_t mg32 = vsx_v128_load(gp);
496 v128_t mb32 = vsx_v128_load(bp);
498 mr = vsx_i64x2_extend_low_i32x4(mr32);
499 mg = vsx_i64x2_extend_low_i32x4(mg32);
500 mb = vsx_i64x2_extend_low_i32x4(mb32);
502 t = vsx_i64x2_add(mr, mb);
503 t = vsx_i64x2_add(t, vsx_i64x2_shl(mg, 1));
504 vsx_v128_store(yp, vsx_i64x2_shr(t, 2));
505 t = vsx_i64x2_sub(mb, mg);
506 vsx_v128_store(cbp, t);
507 t = vsx_i64x2_sub(mr, mg);
508 vsx_v128_store(crp, t);
510 yp += 2; cbp += 2; crp += 2;
512 mr = vsx_i64x2_extend_high_i32x4(mr32);
513 mg = vsx_i64x2_extend_high_i32x4(mg32);
514 mb = vsx_i64x2_extend_high_i32x4(mb32);
516 t = vsx_i64x2_add(mr, mb);
517 t = vsx_i64x2_add(t, vsx_i64x2_shl(mg, 1));
518 vsx_v128_store(yp, vsx_i64x2_shr(t, 2));
519 t = vsx_i64x2_sub(mb, mg);
520 vsx_v128_store(cbp, t);
521 t = vsx_i64x2_sub(mr, mg);
522 vsx_v128_store(crp, t);
524 rp += 4; gp += 4; bp += 4;
525 yp += 2; cbp += 2; crp += 2;
552 const si32 *yp = y->i32, *cbp = cb->i32, *crp = cr->i32;
553 si32 *rp = r->i32, *gp = g->i32, *bp = b->i32;
554 for (
int i = (repeat + 3) >> 2; i > 0; --i)
556 v128_t my = vsx_v128_load(yp);
557 v128_t mcb = vsx_v128_load(cbp);
558 v128_t mcr = vsx_v128_load(crp);
560 v128_t t = vsx_i32x4_add(mcb, mcr);
561 t = vsx_i32x4_sub(my, vsx_i32x4_shr(t, 2));
562 vsx_v128_store(gp, t);
563 v128_t u = vsx_i32x4_add(mcb, t);
564 vsx_v128_store(bp, u);
565 u = vsx_i32x4_add(mcr, t);
566 vsx_v128_store(rp, u);
568 yp += 4; cbp += 4; crp += 4;
569 rp += 4; gp += 4; bp += 4;
580 const si64 *yp = y->i64, *cbp = cb->i64, *crp = cr->i64;
581 si32 *rp = r->i32, *gp = g->i32, *bp = b->i32;
582 for (
int i = (repeat + 3) >> 2; i > 0; --i)
584 v128_t my, mcb, mcr, tr0, tg0, tb0, tr1, tg1, tb1;
585 my = vsx_v128_load(yp);
586 mcb = vsx_v128_load(cbp);
587 mcr = vsx_v128_load(crp);
589 tg0 = vsx_i64x2_add(mcb, mcr);
590 tg0 = vsx_i64x2_sub(my, vsx_i64x2_shr(tg0, 2));
591 tb0 = vsx_i64x2_add(mcb, tg0);
592 tr0 = vsx_i64x2_add(mcr, tg0);
594 yp += 2; cbp += 2; crp += 2;
596 my = vsx_v128_load(yp);
597 mcb = vsx_v128_load(cbp);
598 mcr = vsx_v128_load(crp);
600 tg1 = vsx_i64x2_add(mcb, mcr);
601 tg1 = vsx_i64x2_sub(my, vsx_i64x2_shr(tg1, 2));
602 tb1 = vsx_i64x2_add(mcb, tg1);
603 tr1 = vsx_i64x2_add(mcr, tg1);
609 vsx_v128_store(rp, tr0);
610 vsx_v128_store(gp, tg0);
611 vsx_v128_store(bp, tb0);
613 yp += 2; cbp += 2; crp += 2;
614 rp += 4; gp += 4; bp += 4;
621 float *y,
float *cb,
float *cr,
ui32 repeat)
628 for (
ui32 i = (repeat + 3) >> 2; i > 0; --i)
630 v128_t mr = vsx_v128_load(r);
631 v128_t mb = vsx_v128_load(b);
632 v128_t my = vsx_f32x4_mul(alpha_rf, mr);
633 my = vsx_f32x4_add(my, vsx_f32x4_mul(alpha_gf, vsx_v128_load(g)));
634 my = vsx_f32x4_add(my, vsx_f32x4_mul(alpha_bf, mb));
635 vsx_v128_store(y, my);
636 vsx_v128_store(cb, vsx_f32x4_mul(beta_cbf, vsx_f32x4_sub(mb, my)));
637 vsx_v128_store(cr, vsx_f32x4_mul(beta_crf, vsx_f32x4_sub(mr, my)));
639 r += 4; g += 4; b += 4;
640 y += 4; cb += 4; cr += 4;
646 float *r,
float *g,
float *b,
ui32 repeat)
652 for (
ui32 i = (repeat + 3) >> 2; i > 0; --i)
654 v128_t my = vsx_v128_load(y);
655 v128_t mcr = vsx_v128_load(cr);
656 v128_t mcb = vsx_v128_load(cb);
657 v128_t mg = vsx_f32x4_sub(my, vsx_f32x4_mul(gamma_cr2g, mcr));
658 vsx_v128_store(g, vsx_f32x4_sub(mg, vsx_f32x4_mul(gamma_cb2g, mcb)));
659 vsx_v128_store(r, vsx_f32x4_add(my, vsx_f32x4_mul(gamma_cr2r, mcr)));
660 vsx_v128_store(b, vsx_f32x4_add(my, vsx_f32x4_mul(gamma_cb2b, mcb)));
662 y += 4; cb += 4; cr += 4;
663 r += 4; g += 4; b += 4;
static v128_t ojph_vsx_i32x4_min_lt(v128_t a, v128_t b, v128_t x, v128_t y)
void vsx_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)
static void local_vsx_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 vsx_ict_backward(const float *y, const float *cb, const float *cr, float *r, float *g, float *b, ui32 repeat)
void vsx_cnvrt_float_to_si32(const float *sp, si32 *dp, float mul, ui32 width)
void vsx_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 vsx_ict_forward(const float *r, const float *g, const float *b, float *y, float *cb, float *cr, ui32 repeat)
void vsx_cnvrt_float_to_si32_shftd(const float *sp, si32 *dp, float mul, ui32 width)
void vsx_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)
static v128_t ojph_convert_float_to_i32(v128_t a)
void vsx_cnvrt_si32_to_float_shftd(const si32 *sp, float *dp, float mul, ui32 width)
void vsx_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)
static void local_vsx_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)
void vsx_cnvrt_si32_to_float(const si32 *sp, float *dp, float mul, ui32 width)
void vsx_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 vsx_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)
void vsx_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 vsx_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)
static v128_t ojph_vsx_i32x4_max_ge(v128_t a, v128_t b, v128_t x, v128_t y)
__vector unsigned int vsx_v_u32
__vector unsigned char v128_t
#define vsx_i32x4_shuffle(a, b, c0, c1, c2, c3)
static const float GAMMA_CR2R
static const float BETA_CbF
static const float GAMMA_CB2B
static const float ALPHA_RF
static const float GAMMA_CB2G
static const float GAMMA_CR2G
static const float ALPHA_BF
static const float BETA_CrF
static const float ALPHA_GF