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 + 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)
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 = Rmvmov(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)