10. 浮点指令

这些指令支持使用 ARM 浮点协处理器(在配备有一个的 Pyboard 等平台上)。FPU 有 32 个寄存器,s0-s31 每个寄存器都可以保存一个单精度浮点数。数据可以通过vmov指令在 FPU 寄存器和 ARM 内核寄存器之间传递。

请注意,MicroPython 不支持将浮点数传递给汇编函数,您也不能将浮点数放入r0 并期望得到合理的结果。有两种方法可以克服这一点。第一个是使用数组,第二个是传递和/或返回整数,并在代码中与浮点数相互转换。

10.1. 文档约定

符号:表示FPU寄存器,表示ARM内核寄存器。后者可以是任何 ARM 核心寄存器,尽管寄存器 不太可能适用于这种情况。Sd, Sm, SnRd, Rm, Rn R13-R15

10.2. 算术

  • vadd(Sd, Sn, Sm) Sd = Sn + Sm

  • vsub(Sd, Sn, Sm) Sd = Sn - Sm

  • vneg(Sd, Sm) Sd = -Sm

  • vmul(Sd, Sn, Sm) Sd = Sn * Sm

  • vdiv(Sd, Sn, Sm) Sd = Sn / Sm

  • vsqrt(Sd, Sm) Sd = sqrt(Sm)

寄存器可能相同:将执行vmul(S0, S0, S0) will execute S0 = S0*S0

10.3. 在 ARM 内核和 FPU 寄存器之间移动

  • vmov(Sd, Rm) Sd = Rm

  • vmov(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得到的内存地址。这是以字节为单位指定的。由于每个浮点值占用一个 32 位字,因此在访问浮点数组时,偏移量必须始终是四个字节的倍数。 [Rn + offset]

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)