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 + 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)

把浮點的 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)