x264 编码器 AArch64汇编系列:16x16 块帧内预测函数

时间:2025-04-03 07:51:46
  • function 代表此段是一个函数;
  • export=1 表示这个函数需要被导出,以便在其他模块或程序中使用;
  • sub x3, x0, #FDEC_STRIDE:从x0中减去FDEC_STRIDE(一个常量,表示帧解码的步长)。
  • mov x1, #FDEC_STRIDE:将FDEC_STRIDE的值移动到x1寄存器。
  • add x2, x3, #8:将寄存器 x3 中的值加上数字 8,然后将结果存储在寄存器 x2 中。
  • sub x3, x3, #1:将寄存器 x3 中的值减去数字 1,然后将结果存储在寄存器 x3 中。
  • ld1 {v0.8b}, [x3]:从寄存器 x3 指向的内存地址开始,连续加载8个字节的数据到NEON寄存器 v0 中。
  • ld1 {v2.8b}, [x2], x1:从寄存器 x2 指向的内存地址开始,加载8个字节的数据到NEON寄存器 v2 中,加载完成后,x2 的值会增加 x1 的值,为下一次加载(如果有的话)准备新的基地址。
  • ldcol.8 v1, x3, x1:使用x3作为基地址,x1作为步长,加载8位列元素到v1。
  • add x3, x3, x1:将x1加到x3。
  • ldcol.8 v3, x3, x1:再次使用x3作为基地址,x1作为步长,加载8位列元素到v3。
  • rev64 v0.8b, v0.8b:将v0中的8个字节反转顺序。
  • rev64 v1.8b, v1.8b:将v1中的8个字节反转顺序。
  • movrel x4, p16weight:相对移动x4寄存器到p16weight的地址。
  • uaddl v4.8h, v2.8b, v3.8b:将v2和v3中的8位无符号字节相加,并将结果扩展为8位半字(16位)。
  • ld1 {v7.8h}, [x4]:从x4指向的地址加载8个半字到v7。
  • usubl v2.8h, v2.8b, v0.8b:将v0中的8位无符号字节从v2中减去,并将结果扩展为8位半字。
  • usubl v3.8h, v3.8b, v1.8b:将v1中的8位无符号字节从v3中减去,并将结果扩展为8位半字。
  • mul v2.8h, v2.8h, v7.8h:将v2和v7中的8位半字相乘。
  • mul v3.8h, v3.8h, v7.8h:将v3和v7中的8位半字相乘。
  • saddlp v2.4s, v2.8h:将v2中的8位半字水平求和,并将结果缩减为4个单精度浮点数。
  • saddlp v3.4s, v3.8h:将v3中的8位半字水平求和,并将结果缩减为4个单精度浮点数。
  • addp v2.4s, v2.4s, v3.4s:将v2和v3中的单精度浮点数求和。
  • addp v2.4s, v2.4s, v2.4s:将v2中的单精度浮点数再次求和。
  • shl v3.2s, v2.2s, #2:将v2中的单精度浮点数左移2位。
  • add v2.2s, v2.2s, v3.2s:将v2和v3中的单精度浮点数相加。
  • rshrn v5.4h, v2.4s, #6:将v2中的单精度浮点数右移6位,并将结果缩减为4个半字。
  • addp v2.4h, v5.4h, v5.4h:将v5中的半字求和。
  • shl v3.4h, v2.4h, #3:将v2中的半字左移3位。
  • sub v3.4h, v3.4h, v2.4h:将v2中的半字从v3中减去。
  • ext v4.16b, v4.16b, v4.16b, #14:将v4中的元素扩展,将第14个字节复制到所有16个字节中。
  • add v4.4h, v4.4h, v7.4h:将v4和v7中的半字相加。
  • shl v2.4h, v4.4h, #4:将v4中的半字左移4位。
  • sub v2.4h, v2.4h, v3.4h:将v3中的半字从v2中减去。
  • ext v7.16b, v7.16b, v7.16b, #14:将v7中的元素扩展,将最后一个字节复制到所有16个字节中。
  • mov [0], wzr:将v7中的第0个半字设置为零。
  • dup v3.8h, [0]:将v5中的第0个半字复制到v3的所有8个半字中。
  • mul v0.8h, v7.8h, [0]:将v7和v5中的半字相乘。
  • dup v1.8h, [0]:将v2中的第0个半字复制到v1的所有8个半字中。
  • dup v2.8h, [1]:将v5中的第1个半字复制到v2的所有8个半字中。
  • shl v3.8h, v3.8h, #3:将v3中的半字左移3位。
  • add v1.8h, v1.8h, v0.8h:将v0中的半字加到v1中。
  • add v3.8h, v3.8h, v1.8h:将v1中的半字加到v3中。
  • mov x3, #16:将16移动到x3。
  • 1:循环开始,
  • subs x3, x3, #1:将1从x3减去。
  • sqshrun v0.8b, v1.8h, #5:将v1中的8个半字向下舍入到8个字节。
  • add v1.8h, v1.8h, v2.8h:将v2中的半字加到v1中。
  • sqshrun2 v0.16b, v3.8h, #5:将v3中的8个半字向下舍入到16个字节。
  • add v3.8h, v3.8h, v2.8h:将v2中的半字加到v3中。
  • st1 {v0.16b}, [x0], x1:将v0中的16个字节存储到x0指向的地址,并根据x1的值更新x0。
  • 1b:如果x3不为零,则跳转到标签1继续循环。
    • b:代表分支(Branch)指令。
    • .ne:代表“不是相等”(Not Equal)的条件码。它与比较指令(如 subs)的结果相关联。如果 subs 指令的结果导致零标志(Z 标志)为零,则 .ne 条件成立。
    • 1b:是标签,指向代码中的特定位置。在这个例子中,它指向前面的标签 1:。·
  • ret:函数返回。
  • endfunc:函数定义结束。
  • 【plane 模式汇编实现也挺深奥的,没完全搞懂,继续研究????】