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:
guxiwei
2024-06-25 19:26:39 +08:00
committed by Hecai Yuan
parent 2154425f70
commit 02309b9f60
3 changed files with 247 additions and 0 deletions
+241
View File
@@ -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
+4
View File
@@ -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 */
+2
View File
@@ -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) {