10. 浮点数指令¶
这些指令支持使用ARM浮点协同处理器(在诸如Python的平台上,此平台即配备了此处理器)。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 + 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)
将执行 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)
Move the floating-point N, Z, C, and V flags to the APSR N, Z, C, and V flags.
其中 [Rn + offset] 表示通过将Rn添加到偏移量获得的存储器地址。其单位为字节。由于每个浮点值占用一个32位字,因此在访问浮点数组时,偏移量须始终为4字节的倍数。
vmrs(Rd, FPSCR)
Rd = FPSCR
10.4. Move between FPU register and memory¶
vldr(Sd, [Rn, offset])
Sd = [Rn + offset]
vstr(Sd, [Rn, offset])
[Rn + offset] = Sd
Where [Rn + offset]
denotes the memory address obtained by adding Rn to the offset. This
is specified in bytes. Since each float value occupies a 32 bit word, when accessing arrays of
floats the offset must always be a multiple of four bytes.
10.5. 数据比对¶
vcmp(Sd, Sm)
比对Sd和Sm中的值,并设定FPU N、C、Z、V标志。这之后通常有 vmrs(APSR_nzcv, FPSCR)
来启用待检测的结果。
10.6. 整数和浮点间的转换¶
vcvt_f32_s32(Sd, Sm)
Sd = float(Sm)
vcvt_s32_f32(Sd, Sm)
Sd = int(Sm)