This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Does anyone know how to use the FPU in the FRDM-K64F with uVision 5?

I've been trying to get Keil uVision5 to compile code for the FRDM-K64F so it uses the FPU with instructions such as VADD and VMUL.

The code I'm using is the one for the Blinky standalone sample code found in Keil's software pack: MDK5 - FreescaleFRDM-K64F

I've tried changing the "Floating point hardware" option in Keil from "Not Used" to "Use Single Precision", but all I get it to do is use VMOV but still calling __aeabi_dadd and __aeabi_dmul

Any help is welcome!

Parents
  • I answered myself! Hoping to help anyone, here it goes:

    The Cortex-M4 FPU does single precision arithmetic, not double. So if your code uses doubles, all of the related expressions get extended to double. Since the FPU can't take care of doubles, all of the double operations are done by software routines by means of the integer ALU :/

    In my code I had the following function:

    This...Translates to...




    float CircleArea(float r){

      return 3.14159 * r * r;

    }

    VMOV r0,s16

    BL.W __aeabi_f2d ; float-to-double routine

    VMOV dl0,r0,rl

    VMOV r0,s16

    BL.W __aeabi_f2d ; float-to-double routine

    VMOV d12,r0,r1

    VLDR d0,[pc,#0x110]

    VMOV r2,r3,d0

    BL.W __aeabi_dmul ; double-multiply routine

    VMOV d11,r0,r1

    VMOV r2,r3,d10

    BL.W __aeabi_dmul ; double-multiply routine

    VMOV d9,r0,r1

    BL.W __aeabi_d2f ; double-to-float routine

    VMOV s0,r0

    ...which has a double constant! So it calls routines to convert the existing floats to double, and then operate on doubles, which is done by integer software.... NOT what I wanted.

    A subtle change made wonders:

    This...Translates to...

    float CircleArea(float r){

      return 3.14159f * r * r;

    }

    VLDR     s0,[pc,#0xF4]

    VMUL.F32 s0,s1,s0

    VMUL.F32 s0,s0,s1

    ... which does exactly what's expected from an FPU.

    So there you have it! Avoid using doubles. Maybe there's a compiler option or preprocessor directive for this. Anyone?

Reply
  • I answered myself! Hoping to help anyone, here it goes:

    The Cortex-M4 FPU does single precision arithmetic, not double. So if your code uses doubles, all of the related expressions get extended to double. Since the FPU can't take care of doubles, all of the double operations are done by software routines by means of the integer ALU :/

    In my code I had the following function:

    This...Translates to...




    float CircleArea(float r){

      return 3.14159 * r * r;

    }

    VMOV r0,s16

    BL.W __aeabi_f2d ; float-to-double routine

    VMOV dl0,r0,rl

    VMOV r0,s16

    BL.W __aeabi_f2d ; float-to-double routine

    VMOV d12,r0,r1

    VLDR d0,[pc,#0x110]

    VMOV r2,r3,d0

    BL.W __aeabi_dmul ; double-multiply routine

    VMOV d11,r0,r1

    VMOV r2,r3,d10

    BL.W __aeabi_dmul ; double-multiply routine

    VMOV d9,r0,r1

    BL.W __aeabi_d2f ; double-to-float routine

    VMOV s0,r0

    ...which has a double constant! So it calls routines to convert the existing floats to double, and then operate on doubles, which is done by integer software.... NOT what I wanted.

    A subtle change made wonders:

    This...Translates to...

    float CircleArea(float r){

      return 3.14159f * r * r;

    }

    VLDR     s0,[pc,#0xF4]

    VMUL.F32 s0,s1,s0

    VMUL.F32 s0,s0,s1

    ... which does exactly what's expected from an FPU.

    So there you have it! Avoid using doubles. Maybe there's a compiler option or preprocessor directive for this. Anyone?

Children
No data