10. Floating-point-instructies

Deze instructies ondersteunen het gebruik van de ARM floating-point-coprocessor (op platforms zoals de OpenMV Cams die er een hebben). De FPU heeft 32 registers bekend als s0-s31, die elk een float met enkele precisie kunnen bevatten. Data kan tussen de FPU-registers en de ARM-kernregisters worden doorgegeven met de vmov-instructie.

Merk op dat MicroPython het doorgeven van floats aan assemblerfuncties niet ondersteunt, en je kunt ook geen float in r0 plaatsen en een redelijk resultaat verwachten. Er zijn twee manieren om dit te ondervangen. De eerste is om arrays te gebruiken, en de tweede is om gehele getallen door te geven en/of terug te geven en deze in code naar en van floats te converteren.

10.1. Documentconventies

Notatie: Sd, Sm, Sn duiden FPU-registers aan, Rd, Rm, Rn duiden ARM-kernregisters aan. De laatste kunnen elk ARM-kernregister zijn, hoewel de registers R13-R15 in deze context waarschijnlijk niet geschikt zijn.

10.2. Rekenkunde

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

Registers mogen identiek zijn: vmul(S0, S0, S0) zal S0 = S0*S0 uitvoeren

10.3. Verplaatsen tussen ARM-kern- en FPU-registers

  • vmov(Sd, Rm) Sd = Rm

  • vmov(Rd, Sm) Rd = Sm

De FPU heeft een register bekend als FPSCR, vergelijkbaar met de APSR van de ARM-kern, dat conditiecodes plus andere data opslaat. De volgende instructies bieden toegang hiertoe.

  • vmrs(APSR_nzcv, FPSCR)

Verplaats de floating-point N-, Z-, C- en V-vlaggen naar de APSR N-, Z-, C- en V-vlaggen.

Dit wordt gedaan na een instructie zoals een FPU-vergelijking om de conditiecodes door de assemblercode te kunnen laten testen. Het volgende is een meer algemene vorm van de instructie.

  • vmrs(Rd, FPSCR) Rd = FPSCR

10.4. Verplaatsen tussen FPU-register en geheugen

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

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

Waarbij [Rn + offset] het geheugenadres aanduidt dat wordt verkregen door Rn bij de offset op te tellen. Dit wordt opgegeven in bytes. Aangezien elke float-waarde een 32-bits woord inneemt, moet de offset bij toegang tot arrays van floats altijd een veelvoud van vier bytes zijn.

10.5. Datavergelijking

  • vcmp(Sd, Sm)

Vergelijk de waarden in Sd en Sm en zet de FPU N-, Z-, C- en V-vlaggen. Dit zou normaal gesproken worden gevolgd door vmrs(APSR_nzcv, FPSCR) om de resultaten te kunnen testen.

10.6. Converteren tussen geheel getal en float

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

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