10. 浮点指令¶
这些指令支持使用 ARM 浮点协处理器(在诸如配备了协处理器的 OpenMV Cam 等平台上)。FPU 有 32 个名为 s0-s31 的寄存器,每个都可以保存一个单精度浮点数。可以用 vmov 指令在 FPU 寄存器和 ARM 内核寄存器之间传递数据。
请注意,MicroPython 不支持把浮点数传递给汇编函数,你也不能把一个浮点数放入 r0 并期望得到合理的结果。有两种方法可以克服这一点。第一种是使用数组,第二种是传递和/或返回整数,并在代码中进行浮点数与整数之间的转换。
10.1. 文档约定¶
记法:Sd, Sm, Sn 表示 FPU 寄存器,Rd, Rm, Rn 表示 ARM 内核寄存器。后者可以是任何 ARM 内核寄存器,不过寄存器 R13-R15 在此上下文中不太可能合适。
10.2. 算术¶
vadd(Sd, Sn, Sm)
Sd = Sn + Smvsub(Sd, Sn, Sm)
Sd = Sn - Smvneg(Sd, Sm)
Sd = -Smvmul(Sd, Sn, Sm)
Sd = Sn * Smvdiv(Sd, Sn, Sm)
Sd = Sn / Smvsqrt(Sd, Sm)
Sd = sqrt(Sm)
寄存器可以相同:vmul(S0, S0, S0) 会执行 S0 = S0*S0
10.3. 在 ARM 内核寄存器和 FPU 寄存器之间移动¶
vmov(Sd, Rm)
Sd = Rmvmov(Rd, Sm)
Rd = Sm
FPU 有一个名为 FPSCR 的寄存器,类似于 ARM 内核的 APSR,它存储条件码以及其他数据。以下指令提供对它的访问。
vmrs(APSR_nzcv, FPSCR)
将浮点的 N、Z、C 和 V 标志移动到 APSR 的 N、Z、C 和 V 标志。
这通常在诸如 FPU 比较之类的指令之后执行,以便能够由汇编代码测试条件码。下面是该指令的一种更通用的形式。
vmrs(Rd, FPSCR)
Rd = FPSCR
10.4. 在 FPU 寄存器和内存之间移动¶
vldr(Sd, [Rn, offset])
Sd = [Rn + offset]vstr(Sd, [Rn, offset])
[Rn + offset] = Sd
其中 [Rn + offset] 表示将 Rn 加上偏移量所得到的内存地址。偏移量以字节为单位指定。由于每个浮点值占用一个 32 位的字,因此在访问浮点数组时,偏移量必须始终是四字节的倍数。
10.5. 数据比较¶
vcmp(Sd, Sm)
比较 Sd 和 Sm 中的值,并设置 FPU 的 N、Z、C 和 V 标志。这之后通常会跟一条 vmrs(APSR_nzcv, FPSCR),以便能够测试结果。
10.6. 在整数和浮点数之间转换¶
vcvt_f32_s32(Sd, Sm)
Sd = float(Sm)vcvt_s32_f32(Sd, Sm)
Sd = int(Sm)