10. Instrukcje zmiennoprzecinkowe

Instrukcje te obsługują użycie koprocesora zmiennoprzecinkowego ARM (na platformach takich jak OpenMV Cam, które są w niego wyposażone). FPU ma 32 rejestry znane jako s0-s31, z których każdy może przechowywać liczbę zmiennoprzecinkową pojedynczej precyzji. Dane można przekazywać między rejestrami FPU a rejestrami rdzenia ARM za pomocą instrukcji vmov.

Zauważ, że MicroPython nie obsługuje przekazywania liczb zmiennoprzecinkowych do funkcji asemblerowych, ani nie możesz umieścić liczby zmiennoprzecinkowej w r0 i oczekiwać sensownego wyniku. Istnieją dwa sposoby na obejście tego. Pierwszy to użycie tablic, a drugi to przekazywanie i/lub zwracanie liczb całkowitych oraz konwertowanie do i z liczb zmiennoprzecinkowych w kodzie.

10.1. Konwencje dokumentu

Notacja: Sd, Sm, Sn oznaczają rejestry FPU, Rd, Rm, Rn oznaczają rejestry rdzenia ARM. Te ostatnie mogą być dowolnym rejestrem rdzenia ARM, choć rejestry R13-R15 raczej nie będą odpowiednie w tym kontekście.

10.2. Arytmetyka

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

Rejestry mogą być identyczne: vmul(S0, S0, S0) wykona S0 = S0*S0

10.3. Przenoszenie między rejestrami rdzenia ARM a rejestrami FPU

  • vmov(Sd, Rm) Sd = Rm

  • vmov(Rd, Sm) Rd = Sm

FPU ma rejestr znany jako FPSCR, podobny do rejestru APSR rdzenia ARM, który przechowuje kody warunków oraz inne dane. Poniższe instrukcje zapewniają dostęp do niego.

  • vmrs(APSR_nzcv, FPSCR)

Przenosi flagi zmiennoprzecinkowe N, Z, C i V do flag N, Z, C i V rejestru APSR.

Wykonuje się to po instrukcji takiej jak porównanie FPU, aby umożliwić testowanie kodów warunków przez kod asemblera. Poniżej znajduje się bardziej ogólna forma tej instrukcji.

  • vmrs(Rd, FPSCR) Rd = FPSCR

10.4. Przenoszenie między rejestrem FPU a pamięcią

  • vldr(Sd, [Rn, offset]) Sd = [Rn + offset]

  • vstr(Sd, [Rn, offset]) [Rn + offset] = Sd

Gdzie [Rn + offset] oznacza adres pamięci uzyskany przez dodanie Rn do przesunięcia. Jest ono podawane w bajtach. Ponieważ każda wartość zmiennoprzecinkowa zajmuje słowo 32-bitowe, przy dostępie do tablic liczb zmiennoprzecinkowych przesunięcie musi zawsze być wielokrotnością czterech bajtów.

10.5. Porównanie danych

  • vcmp(Sd, Sm)

Porównuje wartości w Sd i Sm oraz ustawia flagi N, Z, C i V FPU. Po tym zwykle następuje vmrs(APSR_nzcv, FPSCR), aby umożliwić testowanie wyników.

10.6. Konwersja między liczbą całkowitą a zmiennoprzecinkową

  • vcvt_f32_s32(Sd, Sm) Sd = float(Sm)

  • vcvt_s32_f32(Sd, Sm) Sd = int(Sm)