not logged in | **[Login]**

back

These instructions allow the use of the ARM floating point coprocessor (on platforms such as the Pyboard which are equipped with one). The FPU has 32 registers known as s0-s31 each of which can hold a single precision float. Data can be passed between the FPU registers and the ARM core registers with the vMOV instruction.

It should be noted that MicroPython doesn't support passing floats to assembler functions, nor can you put a float into r0 and expect a reasonable result. There are two ways to communicate between Python code and an assembler function. The first is to use arrays, and the second is to pass and return integers doing the conversion to floats in code.

Notation: Sd, Sm, Sn denote FPU registers, Rd, Rm, Rn denote ARM core registers. The latter can be any ARM core register although registers R13-R15 make little sense in this context.

**vadd(Sd, Sn, Sm)** Add FPU register Sn to Sm and put the result in Sd

`Sd = Sn + Sm`

**vsub(Sd, Sn, Sm)** Subtract FPU register Sm from Sn and put the result in Sd

`Sd = Sn - Sm`

**vneg(Sd, Sm)** Negate the value in Sm and put in Sd

`Sd = -Sm`

**vmul(Sd, Sn, Sm)** Multiply FPU register Sm by Sn and put the result in Sd

`Sd = Sn * Sm`

**vdiv(Sd, Sn, Sm)** Divide FPU register Sn by Sm and put the result in Sd

`Sd = Sn / Sm`

**vsqrt(Sd, Sm)** Calculate the square root of Sm and put the result in Sd

`Sd = sqrt(Sm)`

**vmov(Sd, Rm)** Move a value from ARM core register Rm to FPU register Sd

**vmov(Rd, Sm)** Move a value from FPU register Sm to ARM core register Rd

**vmrs(APSR_nzcv, FPSCR)** Move the floating-point N, Z, C, and V flags to the APSR
N, Z, C, and V flags. This is done after an instruction such as an FPU comparison to enable the condition codes to be tested by the assembler code. The following is a more general form of the instruction.

**vmrs(Rd, FPSCR)** Move the floating-point Special Register into ARM core register Rd.

**vldr(Sd, [Rn, offset])** Load FPU register Sd from memory addressed by Rn + offset

**vstr(Sd, [Rn, offset])** Store FPU register Sd to memory addressed by Rn + offset

Note that offsets are in words not bytes.

**vcmp(Sd, Sm)** Compare the values in Sd and Sm and set the FPU N, Z, C, and V flags. This would normally be followed by a `vmrs`

instruction to enable the results to be tested.

**vcvt_f32_s32(Sd, Sm)** Convert the integer in Sm to a float and put in Sd

`Sd = (float)Sm`

**vcvt_s32_f32(Sd, Sm)** Convert the float in Sm to an integer and put in Sd

`Sd = (int)Sm`

Last edited by **Peter Hinch**, 2015-04-20 12:10:56