【ARM汇编学习】VFP 和 NEON


VFP/NEON 指令相关知识

-mfpu=vfpv3-d16 编译选项可以开启 VFP/NEON 指令

浮点常量的表示

  • 非 VFP 指令环境:以 IEEE 754 浮点编码的形式出现

    例如:

    • 全局变量 tst:image

扩展寄存器组

  • NEON 和 VFPv3 使用相同的扩展寄存器组

  • VFPv3 视图:

    • 32 个 32 位单精度寄存器 s0~s31
  • NEON 视图:

    • 32 个 64 位双字寄存器 D0~D31,其中前 16 个也可以在 VFPv3 视图下使用
      image-20220731200427177

VFP 数据类型

image-20220731154254225

条件代码

  • 和 ARM 的含义略有不同:
    image-20220731205727203

  • 注意:若要使用这些标记来控制条件指令,必须先使用 VMSR 指令将其赋值到 APSR

VMRS 和 VMSR 指令

在一个 ARM 寄存器和一个 NEON 和 VFP 系统寄存器之间传送内容

  • 指令

        VMRS{cond} Rd, extsysreg
        VMSR{cond} extsysreg, Rd
    

    image-20220731210055681

  • 举例

    /*
    	float tst2 = ...;
        float tst = ...;
        if (tst <= tst2) {
            ...
        }
    */
            vldr    s0, [sp, #4]
            vldr    s6, [sp, #8]
            vcmpe.f32       s0, s6
            vmrs    APSR_nzcv, fpscr	; 需要将fpscr载入apsr
            bhi     .LBB1_2
            b       .LBB1_1
    

VFP/NEON 指令

VLDR 和 VSTR

  • 语法

     VLDR{cond}{.size} Fd, [Rn{, #offset}] 
     VSTR{cond}{.size} Fd, [Rn{, #offset}] 
     VLDR{cond}{.size} Fd, label 
     VSTR{cond}{.size} Fd, label
    

    image-20220731155625294

  • 功能

    • VLDR:从内存加载一个扩展寄存器
    • VSTR:将一个扩展寄存器的内容保存到内存中
  • 举例

            ldr     r0, .LCPI1_0
            vldr    s0, [r0]
            ......
    .LCPI1_0:
            .long   tst
    tst:
            .long   1082130432              @ float 4
    

VPOP 和 VPUSH

  • 语法

    VPOP{cond} Registers
    VPUSH{cond} Registers
    

    image-20220731155810777
    image-20220731155832505

VMOV

从浮点常数或同类寄存器复制到另一个寄存器

  • 语法

     VMOV{cond}.F32 Sd, #imm 
     VMOV{cond}.F64 Dd, #imm 
     VMOV{cond}.F32 Sd, Sm 
     VMOV{cond}.F64 Dd, Dm
    

    image-20220731203015350

    可用常数范围:image-20220731201756539

  • 大常数(或一般形式)的解决策略:

    • 使用 ARM 指令的常数进行合成

      例:

              mov     r0, #1851392			; 0x1C4000,符合灵活的第二操作数的形式
              orr     r0, r0, #1258291200		; 0x4B000000,符合灵活的第二操作数的形式
              str     r0, [sp]
      
    • 使用 VLDR 和全局变量代替

      例:

              ldr     r0, .LCPI1_0
              vldr    s0, [r0]
              ......
      .LCPI1_0:
              .long   tst
      tst:
              .long   1082130432              @ float 4
      

VCVT 类型转换指令

在单精度和双精度之间转换

  • 语法

    VCVT{cond}.F64.F32 Dd, Sm
    VCVT{cond}.F32.F64 Sd, Dm
    

    image-20220731203536172

  • 举例

    /*
        float tst2 = 4.0;
        float tst = tst2 * 3.0;
    */
            mov     r0, #8388608			; 0x800000
            orr     r0, r0, #1073741824		; 0x40000000
            str     r0, [sp, #8]
            vldr    s0, [sp, #8]
            vcvt.f64.f32    d1, s0
            vmov.f64        d2, #3.000000e+00
            vmul.f64        d1, d1, d2
            vcvt.f32.f64    s0, d1
            vstr    s0, [sp, #4]
    

在浮点数和整数之间

  • 语法

        VCVT{R}{cond}.type.F64 Sd, Dm
        VCVT{R}{cond}.type.F32 Sd, Sm
        VCVT{cond}.F64.type Dd, Sm
        VCVT{cond}.F32.type Sd, Sm
    

    image-20220731204009752

浮点运算指令

VADD/VSUB/VDIV

    Vop{cond}.F32 {Sd}, Sn, Sm    Vop{cond}.F64 {Dd}, Dn, Dm

image-20220731204740940

VABS/VNEG/VSQRT

浮点绝对值、求反、平方根

  • 语法:

        Vop{cond}.F32 Sd, Sm
        Vop{cond}.F64 Dd, Dm
    

    image-20220731204945035

VMUL/VMLA/VMLS

浮点数的乘法、乘加、乘减

    V{N}op{cond}.F32 Sd, Sn, Sm
    V{N}op{cond}.F64 Dd, Dn, Dm

image-20220731205051495

VCMP

  • 语法

        VCMP{cond}.F32 Sd, Sm
        VCMP{cond}.F32 Sd, #0
        VCMP{cond}.F64 Dd, Dm
        VCMP{cond}.F64 Dd, #0
    

    image-20220731205246477

参考资料

  1. RealView® 编译工具 3.1版 汇编程序指南
  2. ARM ASSEMBLY LANGUAGE Fundamentals and Techniques (SECOND EDITION)

原创文章,作者:carmelaweatherly,如若转载,请注明出处:https://blog.ytso.com/278151.html

(0)
上一篇 2022年8月1日
下一篇 2022年8月1日

相关推荐

发表回复

登录后才能评论