static void sub8x8_dct8( dctcoef dct[64], pixel *pix1, pixel *pix2 )
// 定义一个函数 sub8x8_dct8_neon,设置导出属性为 1
function sub8x8_dct8_neon, export=1
// 将 x3 寄存器设置为 FENC_STRIDE 的值 16
mov x3, #FENC_STRIDE
// 将 x4 寄存器设置为 FDEC_STRIDE 的值 32 因为涉及deblocking ,所以一般会pading到32x32
mov x4, #FDEC_STRIDE
// 从地址 x1 加载 8 个字节到 v16
ld1 {v16.8b}, [x1], x3
// 从地址 x2 加载 8 个字节到 v17
ld1 {v17.8b}, [x2], x4
// 从地址 x1 加载 8 个字节到 v18
ld1 {v18.8b}, [x1], x3
// 从地址 x2 加载 8 个字节到 v19
ld1 {v19.8b}, [x2], x4
// 执行无符号减法,将 v16 和 v17 相减的结果保存到 v0
usubl v0.8h, v16.8b, v17.8b
// 从地址 x1 加载 8 个字节到 v20
ld1 {v20.8b}, [x1], x3
// 从地址 x2 加载 8 个字节到 v21
ld1 {v21.8b}, [x2], x4
// 执行无符号减法,将 v18 和 v19 相减的结果保存到 v1
usubl v1.8h, v18.8b, v19.8b
// 从地址 x1 加载 8 个字节到 v22
ld1 {v22.8b}, [x1], x3
// 从地址 x2 加载 8 个字节到 v23
ld1 {v23.8b}, [x2], x4
// 执行无符号减法,将 v20 和 v21 相减的结果保存到 v2
usubl v2.8h, v20.8b, v21.8b
// 从地址 x1 加载 8 个字节到 v24
ld1 {v24.8b}, [x1], x3
// 从地址 x2 加载 8 个字节到 v25
ld1 {v25.8b}, [x2], x4
// 执行无符号减法,将 v22 和 v23 相减的结果保存到 v3
usubl v3.8h, v22.8b, v23.8b
// 从地址 x1 加载 8 个字节到 v26
ld1 {v26.8b}, [x1], x3
// 从地址 x2 加载 8 个字节到 v27
ld1 {v27.8b}, [x2], x4
// 执行无符号减法,将 v24 和 v25 相减的结果保存到 v4
usubl v4.8h, v24.8b, v25.8b
// 从地址 x1 加载 8 个字节到 v28
ld1 {v28.8b}, [x1], x3
// 从地址 x2 加载 8 个字节到 v29
ld1 {v29.8b}, [x2], x4
// 执行无符号减法,将 v26 和 v27 相减的结果保存到 v5
usubl v5.8h, v26.8b, v27.8b
// 从地址 x1 加载 8 个字节到 v30
ld1 {v30.8b}, [x1], x3
// 从地址 x2 加载 8 个字节到 v31
ld1 {v31.8b}, [x2], x4
// 执行无符号减法,将 v28 和 v29 相减的结果保存到 v6
usubl v6.8h, v28.8b, v29.8b
// 执行无符号减法,将 v30 和 v31 相减的结果保存到 v7
usubl v7.8h, v30.8b, v31.8b
DCT8_1D row //乘以正交矩阵
transpose8x8.h v0, v1, v2, v3, v4, v5, v6, v7, v30, v31 //矩阵转秩一下
DCT8_1D col //再乘以一次正交矩阵
st1 {v0.8h,v1.8h,v2.8h,v3.8h}, [x0], #64 //存入内存
st1 {v4.8h,v5.8h,v6.8h,v7.8h}, [x0], #64 //存入内存
ret
endfunc
//详细看看乘以矩阵的函数实现
.macro SUMSUB_AB sum, sub, a, b
add \sum, \a, \b
sub \sub, \a, \b
.endm
宏里面,相减和相加,参数需要\转义一下
.macro DCT8_1D type
// 对 v17.8h 和 v3.8h 进行 SUMSUB_AB 操作,结果存储在 v18.8h
SUMSUB_AB v18.8h, v17.8h, v3.8h, v4.8h
// 对 v16.8h 和 v2.8h 进行 SUMSUB_AB 操作,结果存储在 v19.8h
SUMSUB_AB v19.8h, v16.8h, v2.8h, v5.8h
// 对 v21.8h 和 v1.8h 进行 SUMSUB_AB 操作,结果存储在 v22.8h
SUMSUB_AB v22.8h, v21.8h, v1.8h, v6.8h
// 对 v20.8h 和 v0.8h 进行 SUMSUB_AB 操作,结果存储在 v23.8h
SUMSUB_AB v23.8h, v20.8h, v0.8h, v7.8h
// 对 v26.8h 和 v23.8h 进行 SUMSUB_AB 操作,结果存储在 v24.8h
SUMSUB_AB v24.8h, v26.8h, v23.8h, v18.8h
// 对 v27.8h 和 v22.8h 进行 SUMSUB_AB 操作,结果存储在 v25.8h
SUMSUB_AB v25.8h, v27.8h, v22.8h, v19.8h
// 对 v29.8h 和 v20.8h 进行 SUMSUB_AB 操作,结果存储在 v30.8h
SUMSUB_AB v30.8h, v29.8h, v20.8h, v17.8h
// 将 v21.8h 右移一位
sshr v23.8h, v21.8h, #1
// 将 v16.8h 右移一位
sshr v18.8h, v16.8h, #1
// 将 v23.8h 和 v21.8h 相加
add v23.8h, v23.8h, v21.8h
// 将 v18.8h 和 v16.8h 相加
add v18.8h, v18.8h, v16.8h
// 从 v30.8h 中减去 v23.8h
sub v30.8h, v30.8h, v23.8h
// 从 v29.8h 中减去 v18.8h
sub v29.8h, v29.8h, v18.8h
// 对 v31.8h 和 v21.8h 进行 SUMSUB_AB 操作,结果存储在 v28.8h
SUMSUB_AB v28.8h, v31.8h, v21.8h, v16.8h
// 将 v20.8h 右移一位
sshr v22.8h, v20.8h, #1
// 将 v17.8h 右移一位
sshr v19.8h, v17.8h, #1
// 将 v22.8h 和 v20.8h 相加
add v22.8h, v22.8h, v20.8h
// 将 v19.8h 和 v17.8h 相加
add v19.8h, v19.8h, v17.8h
// 将 v28.8h 和 v22.8h 相加
add v22.8h, v28.8h, v22.8h
// 将 v31.8h 和 v19.8h 相加
add v31.8h, v31.8h, v19.8h
// 对 v0.8h、v4.8h、v24.8h 和 v25.8h 进行 SUMSUB_AB 操作,结果存储在 v0.8h
SUMSUB_AB v0.8h, v4.8h, v24.8h, v25.8h
// 对 v1.8h、v7.8h、v22.8h、v31.8h、v16.8h 和 v17.8h 进行 SUMSUB_SHR 操作,结果存储在 v1.8h
SUMSUB_SHR 2, v1.8h, v7.8h, v22.8h, v31.8h, v16.8h, v17.8h
// 对 v2.8h、v6.8h、v26.8h、v27.8h、v18.8h 和 v19.8h 进行 SUMSUB_SHR 操作,结果存储在 v2.8h
SUMSUB_SHR 1, v2.8h, v6.8h, v26.8h, v27.8h, v18.8h, v19.8h
// 对 v3.8h、v5.8h、v30.8h、v29.8h、v20.8h 和 v21.8h 进行 SUMSUB_SHR2 操作,结果存储在 v3.8h
SUMSUB_SHR2 2, v3.8h, v5.8h, v30.8h, v29.8h, v20.8h, v21.8h
.endm
这段代码是一个宏定义,用于执行离散余弦变换(DCT)的 1D 版本。它包含了一系列算术操作,主要是加法(SUMSUB_AB)和右移(sshr)操作。
以下是对代码中各部分的详细解释:
- SUMSUB_AB 操作:这是一种二元运算,对两个操作数进行求和和减法操作。
- shsr 操作:右移操作,将操作数向右移动指定的位数。
- add 和 sub 操作:加法和减法操作,用于执行数值计算。
- 宏定义的参数 type:可能用于表示数据类型或其他特定的配置。
总体而言,这段代码的目的是通过一系列的算术操作来计算离散余弦变换的 1D 版本。这些操作可能用于图像、音频或其他数字信号处理任务中,以对数据进行频域分析或变换。具体的计算细节和用途可能取决于上下文和应用程序的需求。如果你需要更详细的解释,可能需要参考相关的文档、算法说明或代码的其他部分。
转置函数注释
宏展开之后
.macro transpose8x8.h r0, r1, r2, r3, r4, r5, r6, r7, r8, r9
trn1 v30().8H, v0().8H, v1().8H //
/*
trn1 v30().8H, v0().8H, v1().8H这句汇编指令可能是想表达trn1 v30.8H, v0.8H, v1.8H,如果是这样的话,它的含义为:将寄存器v30的高8位与寄存器v0、v1的高8位进行转置( Transpose )操作,并将结果存储在寄存器v30中。
具体来说,转置操作是一种将数据的行和列进行交换的操作,在这个例子中,就是将寄存器v0和v1的高8位进行交换,并将交换后的结果存储在寄存器v30的高8位中。
*/
trn2 v31().8H, v0().8H, v1().8H
trn1 v1().8H, v2().8H, v3().8H
trn2 v3().8H, v2().8H, v3().8H
trn1 v0().8H, v4().8H, v5().8H
trn2 v5().8H, v4().8H, v5().8H
trn1 v2().8H, v6().8H, v7().8H
trn2 v7().8H, v6().8H, v7().8H
trn1 v4().4S, v0().4S, v2().4S
trn2 v2().4S, v0().4S, v2().4S
trn1 v6().4S, v5().4S, v7().4S
trn2 v7().4S, v5().4S, v7().4S
trn1 v5().4S, v31().4S, v3().4S
trn2 v31().4S, v31().4S, v3().4S
trn1 v3().4S, v30().4S, v1().4S
trn2 v30().4S, v30().4S, v1().4S
trn1 v0().2D, v3().2D, v4().2D
trn2 v4().2D, v3().2D, v4().2D
trn1 v1().2D, v5().2D, v6().2D
trn2 v5().2D, v5().2D, v6().2D
trn2 v6().2D, v30().2D, v2().2D
trn1 v2().2D, v30().2D, v2().2D
trn1 v3().2D, v31().2D, v7().2D
trn2 v7().2D, v31().2D, v7().2D
.endm