10. Instructions à virgule flottante

Ces instructions prennent en charge l’utilisation du coprocesseur à virgule flottante ARM (sur des plateformes telles que les OpenMV Cam qui en sont équipées). La FPU possède 32 registres appelés s0-s31, chacun pouvant contenir un flottant en simple précision. Les données peuvent être transférées entre les registres de la FPU et les registres du cœur ARM grâce à l’instruction vmov.

Notez que MicroPython ne prend pas en charge le passage de flottants aux fonctions assembleur, et vous ne pouvez pas non plus placer un flottant dans r0 en espérant un résultat cohérent. Il existe deux façons de contourner cela. La première consiste à utiliser des tableaux, et la seconde à passer et/ou renvoyer des entiers et à les convertir vers et depuis des flottants dans le code.

10.1. Conventions du document

Notation : Sd, Sm, Sn désignent les registres de la FPU, Rd, Rm, Rn désignent les registres du cœur ARM. Ces derniers peuvent être n’importe quel registre du cœur ARM, bien que les registres R13-R15 soient peu susceptibles d’être appropriés dans ce contexte.

10.2. Arithmétique

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

Les registres peuvent être identiques : vmul(S0, S0, S0) exécutera S0 = S0*S0

10.3. Transfert entre les registres du cœur ARM et de la FPU

  • vmov(Sd, Rm) Sd = Rm

  • vmov(Rd, Sm) Rd = Sm

La FPU possède un registre appelé FPSCR, similaire à l’APSR du cœur ARM, qui stocke des codes de condition ainsi que d’autres données. Les instructions suivantes en fournissent l’accès.

  • vmrs(APSR_nzcv, FPSCR)

Transfère les indicateurs à virgule flottante N, Z, C et V vers les indicateurs N, Z, C et V de l’APSR.

Ceci est effectué après une instruction telle qu’une comparaison FPU afin de permettre aux codes de condition d’être testés par le code assembleur. Ce qui suit est une forme plus générale de l’instruction.

  • vmrs(Rd, FPSCR) Rd = FPSCR

10.4. Transfert entre un registre de la FPU et la mémoire

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

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

[Rn + offset] désigne l’adresse mémoire obtenue en ajoutant Rn à l’offset. Celui-ci est spécifié en octets. Comme chaque valeur flottante occupe un mot de 32 bits, lors de l’accès à des tableaux de flottants l’offset doit toujours être un multiple de quatre octets.

10.5. Comparaison de données

  • vcmp(Sd, Sm)

Compare les valeurs dans Sd et Sm et positionne les indicateurs N, Z, C et V de la FPU. Ceci serait normalement suivi de vmrs(APSR_nzcv, FPSCR) pour permettre de tester les résultats.

10.6. Conversion entre entier et flottant

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

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