10. Gleitkommabefehle

Diese Befehle unterstützen die Nutzung des ARM-Gleitkomma-Koprozessors (auf Plattformen wie den OpenMV Cams, die mit einem solchen ausgestattet sind). Die FPU verfügt über 32 Register, bekannt als s0-s31, von denen jedes einen einfach genauen Float aufnehmen kann. Daten können mit dem Befehl vmov zwischen den FPU-Registern und den ARM-Kernregistern übertragen werden.

Beachten Sie, dass MicroPython das Übergeben von Floats an Assembler-Funktionen nicht unterstützt und Sie auch keinen Float in r0 legen und ein sinnvolles Ergebnis erwarten können. Es gibt zwei Möglichkeiten, dies zu umgehen. Die erste ist die Verwendung von Arrays, und die zweite ist das Übergeben und/oder Zurückgeben von Ganzzahlen und das Umwandeln von und zu Floats im Code.

10.1. Dokumentkonventionen

Notation: Sd, Sm, Sn bezeichnen FPU-Register, Rd, Rm, Rn bezeichnen ARM-Kernregister. Letztere können beliebige ARM-Kernregister sein, obwohl die Register R13-R15 in diesem Kontext wahrscheinlich nicht geeignet sind.

10.2. Arithmetik

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

Register dürfen identisch sein: vmul(S0, S0, S0) führt S0 = S0*S0 aus

10.3. Zwischen ARM-Kern- und FPU-Registern verschieben

  • vmov(Sd, Rm) Sd = Rm

  • vmov(Rd, Sm) Rd = Sm

Die FPU verfügt über ein Register namens FPSCR, ähnlich dem APSR des ARM-Kerns, das Bedingungscodes sowie weitere Daten speichert. Die folgenden Befehle ermöglichen den Zugriff darauf.

  • vmrs(APSR_nzcv, FPSCR)

Verschiebt die Gleitkomma-Flags N, Z, C und V in die APSR-Flags N, Z, C und V.

Dies geschieht nach einem Befehl wie etwa einem FPU-Vergleich, um zu ermöglichen, dass die Bedingungscodes vom Assembler-Code geprüft werden können. Das Folgende ist eine allgemeinere Form des Befehls.

  • vmrs(Rd, FPSCR) Rd = FPSCR

10.4. Zwischen FPU-Register und Speicher verschieben

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

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

Wobei [Rn + offset] die Speicheradresse bezeichnet, die durch Addition von Rn zum Offset erhalten wird. Dieser wird in Bytes angegeben. Da jeder Float-Wert ein 32-Bit-Wort belegt, muss der Offset beim Zugriff auf Arrays von Floats stets ein Vielfaches von vier Bytes sein.

10.5. Datenvergleich

  • vcmp(Sd, Sm)

Vergleicht die Werte in Sd und Sm und setzt die FPU-Flags N, Z, C und V. Darauf würde normalerweise vmrs(APSR_nzcv, FPSCR) folgen, um die Ergebnisse prüfbar zu machen.

10.6. Zwischen Ganzzahl und Float umwandeln

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

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