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 的含义略有不同:
- 注意:若要使用这些标记来控制条件指令,必须先使用 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)