msac: Add msac_decode_bool_equia_lsx and msac_decode_hi_tok_lsx
The performance data is as follows: msac_decode_bool_equi_c: 0.4 ( 1.00x) msac_decode_bool_equi_lsx: 0.3 ( 1.07x) msac_decode_hi_tok_c: 1.8 ( 1.00x) msac_decode_hi_tok_lsx: 1.4 ( 1.27x) Change-Id: Ic2f2678cf699bb22c579424af71ae2603e228482
This commit is contained in:
@@ -31,6 +31,12 @@ const min_prob
|
||||
.short 60, 56, 52, 48, 44, 40, 36, 32, 28, 24, 20, 16, 12, 8, 4, 0
|
||||
endconst
|
||||
|
||||
const ph_0xff00
|
||||
.rept 8
|
||||
.short 0xff00
|
||||
.endr
|
||||
endconst
|
||||
|
||||
.macro decode_symbol_adapt w
|
||||
addi.d sp, sp, -48
|
||||
addi.d a4, a0, 24
|
||||
@@ -281,6 +287,82 @@ function msac_decode_bool_lsx
|
||||
move a0, t8
|
||||
endfunc
|
||||
|
||||
function msac_decode_bool_equi_lsx
|
||||
ld.w t0, a0, 24 // rng
|
||||
ld.d t1, a0, 16 // dif
|
||||
ld.w a5, a0, 28 // cnt
|
||||
srli.w t2, t0, 8 // r >> 8
|
||||
slli.w t2, t2, 7
|
||||
addi.w t2, t2, 4 // v
|
||||
|
||||
slli.d t3, t2, 48 // vw
|
||||
sltu t4, t1, t3
|
||||
move t8, t4 // ret
|
||||
xori t4, t4, 1
|
||||
maskeqz t6, t3, t4 // if (ret) vw
|
||||
sub.d t6, t1, t6 // dif
|
||||
slli.w t5, t2, 1
|
||||
sub.w t5, t0, t5 // r - 2v
|
||||
maskeqz t7, t5, t4 // if (ret) r - 2v
|
||||
add.w t5, t2, t7 // v(rng)
|
||||
|
||||
// renorm
|
||||
clz.w t4, t5 // d
|
||||
xori t4, t4, 16 // d
|
||||
sll.d t6, t6, t4
|
||||
sll.w t5, t5, t4
|
||||
sub.w t7, a5, t4 // cnt-d
|
||||
st.w t5, a0, 24 // store rng
|
||||
bgeu a5, t4, 9f
|
||||
|
||||
// refill
|
||||
ld.d t0, a0, 0 // buf_pos
|
||||
ld.d t1, a0, 8 // buf_end
|
||||
addi.d t2, t0, 8
|
||||
bltu t1, t2, 2f
|
||||
|
||||
ld.d t3, t0, 0 // next_bits
|
||||
addi.w t1, t7, -48 // shift_bits = cnt + 16 (- 64)
|
||||
nor t3, t3, t3
|
||||
sub.w t2, zero, t1
|
||||
revb.d t3, t3 // next_bits = bswap(next_bits)
|
||||
srli.w t2, t2, 3 // num_bytes_read
|
||||
srl.d t3, t3, t1 // next_bits >>= (shift_bits & 63)
|
||||
b 3f
|
||||
1:
|
||||
addi.w t3, t7, -48
|
||||
srl.d t3, t3, t3 // pad with ones
|
||||
b 4f
|
||||
2:
|
||||
bgeu t0, t1, 1b
|
||||
ld.d t3, t1, -8 // next_bits
|
||||
sub.w t2, t2, t1
|
||||
sub.w t1, t1, t0 // num_bytes_left
|
||||
slli.w t2, t2, 3
|
||||
srl.d t3, t3, t2
|
||||
addi.w t2, t7, -48
|
||||
nor t3, t3, t3
|
||||
sub.w t4, zero, t2
|
||||
revb.d t3, t3
|
||||
srli.w t4, t4, 3
|
||||
srl.d t3, t3, t2
|
||||
sltu t2, t1, t4
|
||||
maskeqz t1, t1, t2
|
||||
masknez t2, t4, t2
|
||||
or t2, t2, t1 // num_bytes_read
|
||||
3:
|
||||
slli.w t1, t2, 3
|
||||
add.d t0, t0, t2
|
||||
add.w t7, t7, t1 // cnt += num_bits_read
|
||||
st.d t0, a0, 0
|
||||
4:
|
||||
or t6, t6, t3 // dif |= next_bits
|
||||
9:
|
||||
st.w t7, a0, 28 // store cnt
|
||||
st.d t6, a0, 16 // store dif
|
||||
move a0, t8
|
||||
endfunc
|
||||
|
||||
function msac_decode_bool_adapt_lsx
|
||||
ld.hu a3, a1, 0 // cdf[0] /f
|
||||
ld.w t0, a0, 24 // rng
|
||||
@@ -374,3 +456,162 @@ function msac_decode_bool_adapt_lsx
|
||||
st.d t6, a0, 16 // store dif
|
||||
move a0, t8
|
||||
endfunc
|
||||
|
||||
.macro HI_TOK allow_update_cdf
|
||||
.\allow_update_cdf\()_hi_tok_lsx_start:
|
||||
.if \allow_update_cdf == 1
|
||||
ld.hu a4, a1, 0x06 // cdf[3]
|
||||
.endif
|
||||
vor.v vr1, vr0, vr0
|
||||
vsrli.h vr1, vr1, 0x06 // cdf[val] >> EC_PROB_SHIFT
|
||||
vstelm.h vr2, sp, 0, 0 // -0x1a
|
||||
vand.v vr2, vr2, vr4 // (8 x rng) & 0xff00
|
||||
vslli.h vr1, vr1, 0x07
|
||||
vmuh.hu vr1, vr1, vr2
|
||||
vadd.h vr1, vr1, vr5 // v += EC_MIN_PROB/* 4 */ * ((unsigned)n_symbols/* 3 */ - val);
|
||||
vst vr1, sp, 0x02 // -0x18
|
||||
vssub.hu vr1, vr1, vr3 // v - c
|
||||
vseqi.h vr1, vr1, 0
|
||||
.if \allow_update_cdf == 1
|
||||
addi.d t4, a4, 0x50
|
||||
srli.d t4, t4, 0x04
|
||||
sltui t7, a4, 32
|
||||
add.w a4, a4, t7
|
||||
|
||||
vreplgr2vr.h vr7, t4
|
||||
vavgr.hu vr9, vr8, vr1
|
||||
vsub.h vr9, vr9, vr0
|
||||
vsub.h vr0, vr0, vr1
|
||||
vsra.h vr9, vr9, vr7
|
||||
vadd.h vr0, vr0, vr9
|
||||
vstelm.d vr0, a1, 0, 0
|
||||
st.h a4, a1, 0x06
|
||||
.endif
|
||||
vmsknz.b vr7, vr1
|
||||
movfr2gr.s t4, f7
|
||||
ctz.w t4, t4 // loop_times * 2
|
||||
addi.d t7, t4, 2
|
||||
ldx.hu t6, sp, t4 // u
|
||||
ldx.hu t5, sp, t7 // v
|
||||
addi.w t3, t3, 0x05
|
||||
addi.w t4, t4, -0x05 // if t4 == 3, continue
|
||||
sub.w t6, t6, t5 // u - v , rng for ctx_norm
|
||||
slli.d t5, t5, 0x30 // (ec_win)v << (EC_WIN_SIZE - 16)
|
||||
sub.d t1, t1, t5 // s->dif - ((ec_win)v << (EC_WIN_SIZE - 16))
|
||||
// Init ctx_norm param
|
||||
clz.w t7, t6
|
||||
xori t7, t7, 0x1f
|
||||
xori t7, t7, 0x0f // d = 15 ^ (31 ^ clz(rng));
|
||||
sll.d t1, t1, t7 // dif << d
|
||||
sll.d t6, t6, t7 // rng << d
|
||||
// update vr2 8 x rng
|
||||
vreplgr2vr.h vr2, t6
|
||||
vreplvei.h vr2, vr2, 0
|
||||
st.w t6, a0, 0x18 // store rng
|
||||
move t0, t2
|
||||
sub.w t2, t2, t7 // cnt - d
|
||||
bgeu t0, t7, .\allow_update_cdf\()_hi_tok_lsx_ctx_norm_end // if ((unsigned)cnt < (unsigned)d) goto ctx_norm_end
|
||||
// Step into ctx_fill
|
||||
ld.d t5, a0, 0x00 // buf_pos
|
||||
ld.d t6, a0, 0x08 // end_pos
|
||||
addi.d t7, t5, 0x08 // buf_pos + 8
|
||||
sub.d t7, t7, t6 // (buf_pos + 8) - end_pos
|
||||
blt zero, t7, .\allow_update_cdf\()_hi_tok_lsx_ctx_refill_eob
|
||||
// (end_pos - buf_pos) >= 8
|
||||
ld.d t6, t5, 0x00 // load buf_pos[0]~buf_pos[7]
|
||||
addi.w t7, t2, -0x30 // cnt - 0x30
|
||||
nor t6, t6, t6 // not buf data
|
||||
revb.d t6, t6 // Byte reversal
|
||||
srl.d t6, t6, t7 // Replace left shift with right shift
|
||||
sub.w t7, zero, t7 // neg
|
||||
srli.w t7, t7, 0x03 // Loop times
|
||||
or t1, t1, t6 // dif |= (ec_win)(*buf_pos++ ^ 0xff) << c
|
||||
b .\allow_update_cdf\()_hi_tok_lsx_ctx_refill_end
|
||||
.\allow_update_cdf\()_hi_tok_lsx_ctx_refill_eob:
|
||||
bge t5, t6, .\allow_update_cdf\()_hi_tok_lsx_ctx_refill_one
|
||||
// end_pos - buf_pos < 8 && buf_pos < end_pos
|
||||
ld.d t0, t6, -0x08
|
||||
slli.d t7, t7, 0x03
|
||||
srl.d t6, t0, t7 // Retrieve the buf data and remove the excess data
|
||||
addi.w t7, t2, -0x30 // cnt - 0x30
|
||||
nor t6, t6, t6 // not
|
||||
revb.d t6, t6 // Byte reversal
|
||||
srl.d t6, t6, t7 // Replace left shift with right shift
|
||||
sub.w t7, zero, t7 // neg
|
||||
or t1, t1, t6 // dif |= (ec_win)(*buf_pos++ ^ 0xff) << c
|
||||
ld.d t6, a0, 0x08 // end_pos
|
||||
srli.w t7, t7, 0x03 // Loop times
|
||||
sub.d t6, t6, t5 // end_pos - buf_pos
|
||||
slt t0, t6, t7
|
||||
maskeqz a3, t6, t0 // min(loop_times, end_pos - buf_pos)
|
||||
masknez t0, t7, t0
|
||||
or t7, a3, t0
|
||||
b .\allow_update_cdf\()_hi_tok_lsx_ctx_refill_end
|
||||
.\allow_update_cdf\()_hi_tok_lsx_ctx_refill_one:
|
||||
// buf_pos >= end_pos
|
||||
addi.w t7, t2, -0x10
|
||||
andi t7, t7, 0xf
|
||||
nor t0, zero, zero
|
||||
srl.d t0, t0, t7
|
||||
or t1, t1, t0 // dif |= ~(~(ec_win)0xff << c);
|
||||
b .\allow_update_cdf\()_hi_tok_lsx_ctx_norm_end
|
||||
.\allow_update_cdf\()_hi_tok_lsx_ctx_refill_end:
|
||||
add.d t5, t5, t7 // buf_pos + Loop_times
|
||||
st.d t5, a0, 0x00 // Store buf_pos
|
||||
alsl.w t2, t7, t2, 0x03 // update cnt
|
||||
.\allow_update_cdf\()_hi_tok_lsx_ctx_norm_end:
|
||||
srli.d t7, t1, 0x30
|
||||
vreplgr2vr.h vr3, t7 // broadcast the high 16 bits of dif
|
||||
add.w t3, t4, t3 // update control parameter
|
||||
beqz t3, .\allow_update_cdf\()_hi_tok_lsx_end // control loop for at most 4 times.
|
||||
blt zero, t4, .\allow_update_cdf\()_hi_tok_lsx_start // tok_br == 3
|
||||
.\allow_update_cdf\()_hi_tok_lsx_end:
|
||||
addi.d t3, t3, 0x1e
|
||||
st.d t1, a0, 0x10 // store dif
|
||||
st.w t2, a0, 0x1c // store cnt
|
||||
srli.w a0, t3, 0x01 // tok
|
||||
addi.d sp, sp, 0x1a
|
||||
.endm
|
||||
|
||||
/**
|
||||
* @param unsigned dav1d_msac_decode_hi_tok_c(MsacContext *const s, uint16_t *const cdf)
|
||||
* * Reg Alloction
|
||||
* * vr0: cdf;
|
||||
* * vr1: temp;
|
||||
* * vr2: rng;
|
||||
* * vr3: dif;
|
||||
* * vr4: const 0xff00ff00...ff00ff00;
|
||||
* * vr5: const 0x0004080c;
|
||||
* * vr6: const 0;
|
||||
* * t0: allow_update_cdf, tmp;
|
||||
* * t1: dif;
|
||||
* * t2: cnt;
|
||||
* * t3: 0xffffffe8, outermost control parameter;
|
||||
* * t4: loop time
|
||||
* * t5: v, buf_pos, temp;
|
||||
* * t6: u, rng, end_pos, buf, temp;
|
||||
* * t7: temp;
|
||||
*/
|
||||
function msac_decode_hi_tok_lsx
|
||||
fld.d f0, a1, 0 // Load cdf[0]~cdf[3]
|
||||
vldrepl.h vr2, a0, 0x18 // 8 x rng, assert(rng <= 65535U), only the lower 16 bits are valid
|
||||
vldrepl.h vr3, a0, 0x16 // broadcast the high 16 bits of dif, c = s->dif >> (EC_WIN_SIZE - 16)
|
||||
ld.w t0, a0, 0x20 // allow_update_cdf
|
||||
la.local t7, ph_0xff00
|
||||
vld vr4, t7, 0x00 // 0xff00ff00...ff00ff00
|
||||
la.local t7, min_prob
|
||||
vld vr5, t7, 12 * 2 // 0x0004080c
|
||||
vxor.v vr6, vr6, vr6 // const 0
|
||||
ld.d t1, a0, 0x10 // dif
|
||||
ld.w t2, a0, 0x1c // cnt
|
||||
orn t3, t3, t3
|
||||
srli.d t3, t3, 32
|
||||
addi.d t3, t3, -0x17 // 0xffffffe8
|
||||
vseq.h vr8, vr8, vr8
|
||||
addi.d sp, sp, -0x1a // alloc stack
|
||||
beqz t0, .hi_tok_lsx_no_update_cdf
|
||||
HI_TOK 1
|
||||
jirl zero, ra, 0x0
|
||||
.hi_tok_lsx_no_update_cdf:
|
||||
HI_TOK 0
|
||||
endfunc
|
||||
|
||||
@@ -36,11 +36,15 @@ unsigned dav1d_msac_decode_symbol_adapt16_lsx(MsacContext *s, uint16_t *cdf,
|
||||
size_t n_symbols);
|
||||
unsigned dav1d_msac_decode_bool_adapt_lsx(MsacContext *s, uint16_t *cdf);
|
||||
unsigned dav1d_msac_decode_bool_lsx(MsacContext *s, unsigned f);
|
||||
unsigned dav1d_msac_decode_bool_equi_lsx(MsacContext *s);
|
||||
unsigned dav1d_msac_decode_hi_tok_lsx(MsacContext *s, uint16_t *cdf);
|
||||
|
||||
#define dav1d_msac_decode_symbol_adapt4 dav1d_msac_decode_symbol_adapt4_lsx
|
||||
#define dav1d_msac_decode_symbol_adapt8 dav1d_msac_decode_symbol_adapt8_lsx
|
||||
#define dav1d_msac_decode_symbol_adapt16 dav1d_msac_decode_symbol_adapt16_lsx
|
||||
#define dav1d_msac_decode_bool_adapt dav1d_msac_decode_bool_adapt_lsx
|
||||
#define dav1d_msac_decode_bool dav1d_msac_decode_bool_lsx
|
||||
#define dav1d_msac_decode_bool_equi dav1d_msac_decode_bool_equi_lsx
|
||||
#define dav1d_msac_decode_hi_tok dav1d_msac_decode_hi_tok_lsx
|
||||
|
||||
#endif /* DAV1D_SRC_LOONGARCH_MSAC_H */
|
||||
|
||||
@@ -280,6 +280,8 @@ void checkasm_check_msac(void) {
|
||||
c.decode_symbol_adapt16 = dav1d_msac_decode_symbol_adapt16_lsx;
|
||||
c.decode_bool_adapt = dav1d_msac_decode_bool_adapt_lsx;
|
||||
c.decode_bool = dav1d_msac_decode_bool_lsx;
|
||||
c.decode_bool_equi = dav1d_msac_decode_bool_equi_lsx;
|
||||
c.decode_hi_tok = dav1d_msac_decode_hi_tok_lsx;
|
||||
}
|
||||
#elif ARCH_X86 && HAVE_ASM
|
||||
if (dav1d_get_cpu_flags() & DAV1D_X86_CPU_FLAG_SSE2) {
|
||||
|
||||
Reference in New Issue
Block a user