10. Istruzioni in virgola mobile

Queste istruzioni supportano l’uso del coprocessore in virgola mobile ARM (su piattaforme come le OpenMV Cam che ne sono dotate). La FPU ha 32 registri noti come s0-s31, ciascuno dei quali può contenere un float a precisione singola. I dati possono essere passati tra i registri della FPU e i registri del core ARM con l’istruzione vmov.

Nota che MicroPython non supporta il passaggio di float alle funzioni assembler, né puoi mettere un float in r0 e aspettarti un risultato ragionevole. Ci sono due modi per superare questo limite. Il primo è usare gli array, il secondo è passare e/o restituire interi e convertirli da e verso float nel codice.

10.1. Convenzioni del documento

Notazione: Sd, Sm, Sn indicano i registri della FPU, Rd, Rm, Rn indicano i registri del core ARM. Questi ultimi possono essere qualsiasi registro del core ARM, sebbene i registri R13-R15 difficilmente siano appropriati in questo contesto.

10.2. Aritmetica

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

I registri possono essere identici: vmul(S0, S0, S0) eseguirà S0 = S0*S0

10.3. Spostamento tra i registri del core ARM e della FPU

  • vmov(Sd, Rm) Sd = Rm

  • vmov(Rd, Sm) Rd = Sm

La FPU ha un registro noto come FPSCR, simile all’APSR del core ARM, che memorizza i codici di condizione più altri dati. Le seguenti istruzioni forniscono l’accesso a questo registro.

  • vmrs(APSR_nzcv, FPSCR)

Sposta i flag N, Z, C e V della virgola mobile nei flag N, Z, C e V dell’APSR.

Questo viene fatto dopo un’istruzione come un confronto della FPU per consentire che i codici di condizione siano testati dal codice assembler. Quella che segue è una forma più generale dell’istruzione.

  • vmrs(Rd, FPSCR) Rd = FPSCR

10.4. Spostamento tra registro della FPU e memoria

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

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

Dove [Rn + offset] indica l’indirizzo di memoria ottenuto sommando Rn all’offset. Questo è specificato in byte. Poiché ogni valore float occupa una parola da 32 bit, quando si accede ad array di float l’offset deve essere sempre un multiplo di quattro byte.

10.5. Confronto dei dati

  • vcmp(Sd, Sm)

Confronta i valori in Sd e Sm e imposta i flag N, Z, C e V della FPU. Questo normalmente sarebbe seguito da vmrs(APSR_nzcv, FPSCR) per consentire di testare i risultati.

10.6. Conversione tra intero e float

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

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