【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 视图下使用
- 32 个 64 位双字寄存器 D0~D31,其中前 16 个也可以在 VFPv3 视图下使用
VFP 数据类型
条件代码
-
和 ARM 的含义略有不同:
-
注意:若要使用这些标记来控制条件指令,必须先使用 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 指令的常数进行合成
例:
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
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
VCMP
-
语法
VCMP{cond}.F32 Sd, Sm VCMP{cond}.F32 Sd, #0 VCMP{cond}.F64 Dd, Dm VCMP{cond}.F64 Dd, #0
参考资料
- RealView® 编译工具 3.1版 汇编程序指南
- ARM ASSEMBLY LANGUAGE Fundamentals and Techniques (SECOND EDITION)