ARM汇编常用浮点相关指令(VFP)及部分 NEON 指令

VFP/NEON 指令相关知识

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

浮点常量的表示

  • 非 VFP 指令环境:以 IEEE 754 浮点编码的形式出现
    例如:
  • 全局变量 tst:

扩展寄存器组

  • NEON 和 VFPv3 使用相同的扩展寄存器组
  • VFPv3 视图:
  • 32 个 32 位单精度寄存器 s0~s31
  • NEON 视图:
  • 32 个 64 位双字寄存器 D0~D31,其中前 16 个也可以在 VFPv3 视图下使用

VFP 数据类型

如何在arm架构下打包vic模型 arm vfp_如何在arm架构下打包vic模型

条件代码

  • 和 ARM 的含义略有不同:
  • 如何在arm架构下打包vic模型 arm vfp_如何在arm架构下打包vic模型_02

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

VMRS 和 VMSR 指令

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

  • 指令
VMRS{cond} Rd, extsysreg
    VMSR{cond} extsysreg, Rd
  • 举例
/*
	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
  • 功能
  • 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

VMOV

ARM 寄存器和 VFP 寄存器之间

  • 语法
VMOV{cond} Rd, Sn 
 VMOV{cond} Sn, Rd

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

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

可用常数范围:

如何在arm架构下打包vic模型 arm vfp_浮点_03

  • 大常数(或一般形式)的解决策略:
  • 使用 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
  • 举例
/*
    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

浮点运算指令

VADD/VSUB/VDIV

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

如何在arm架构下打包vic模型 arm vfp_寄存器_04

VABS/VNEG/VSQRT

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

  • 语法:
Vop{cond}.F32 Sd, Sm
    Vop{cond}.F64 Dd, Dm

VMUL/VMLA/VMLS

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

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

如何在arm架构下打包vic模型 arm vfp_浮点_05

VCMP

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

参考资料

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