Does GCC use single-precision FP hardware on Cortex-M4 parts?

Hi - Can anybody tell me for what, if anything, does GCC use the single-precision hardware floating point units on some Cortex-M4 parts? At all? Single-precision float only? Presumably not double?

The PIC32MZ EF series parts have hardware double precision; presumably GCC uses this for double?

Thanks! Best Regards, Dave

Reply to
Dave Nadler
Loading thread data ...

Been there, done that, used correctly it works a charm:

GCC uses the single-precision floating point processor if you tell it to. And yes, it uses it for single-precision float only, so the usual math library stuff (sin, cos, etc.) is not, to my knowledge, supported.

(In C++ one _could_ have a smart math library that would see the type of the argument and call the correct library function -- I don't believe that's done, and I could see it causing all sorts of trouble when things get inadvertently up-cast to double as you maintain the code.)

At least on the Cortex M4 part that I used, you needed to turn on the math coprocessor -- it was not on by default. I'm not sure if this is par for the course, or if it's just an ST thing. If you don't turn on the math coprocessor then the first time you hit a coprocessor function you'll get a fault and the machine will hang.

--
Tim Wescott 
Control systems, embedded software and circuit design 
I'm looking for work!  See my website if you're interested 
http://www.wescottdesign.com
Reply to
Tim Wescott
< snip >

I would check. You may have to direct the compiler to do so. Check also to see if you need to do any special initialization on the chip to make the hardware double precision work. If you're using an RTOS, make sure that either there's no special care and feeding needed of the coprocessor, or that the RTOS does it, or that you only have one magic (and VERY well commented) task that's ever allowed to do floating point operations.

On RTOS and floating point: every processor that I've ever worked with that has hardware floating point, and even some floating point libraries that I've used, have required that the RTOS has knowledge of the floating point "stuff". In these cases, the floating point engine (HW or SW) needs to have it's state saved off independently of the rest of the processor and/or software. This means that task switches will be slower and the task control blocks bigger -- so you have to take that into account when you're choosing to use floating point. Note that most new software floating point libraries _don't_ require special attention from the RTOS -- but you never know. Caveat emptor. Speak softly, but carry a big stick. 'ware dragons. Etc.

--
Tim Wescott 
Control systems, embedded software and circuit design 
I'm looking for work!  See my website if you're interested 
http://www.wescottdesign.com
Reply to
Tim Wescott

FYI the latest M7 processors from ST have double-precision floating point e.g. STM32F769

gcc does have the appropriate flags to choose double precision floating point ARM hardware (fpv5-d16). How well it makes use of this I do not know, but ARM do contribute directly to gcc so I would hope it is there. One could try it and see.

--

John Devereux
Reply to
John Devereux

Yes, you need to tell gcc about the processor you are using:

-mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16

You may also want to add "-fsingle-precision-constant" which makes gcc treat floating point constants as single precision, so that "x * 2.5" is done as single precision rather than double precision (without having to write "x * 2.5f").

And you /definitely/ want to have "-Wdouble-promotion" to warn about any implicit promotions to double that might have occurred accidentally. (You can always cast to double, or assign values to double variables, if you really want slow but accurate doubles in the code.)

As for the maths library, "sinf", "cosf", and friends are standard functions for single-precision versions of the trigonometric functions. But remember that there is no such thing as the "gcc library" - gcc can come with a variety of libraries. Some of these will have good implementations of "sinf" and friends, done using only single-precision floating point in order to be fast on a the M4F and similar processors. Others simply convert their argument to double, call "sin", then convert the result back to single. If you need to use standard library maths functions, and you need the speed of single precision, then check the details for the libraries available in the particular toolchain you have.

Of course, when you need fast trig functions, it is usually best to have tables, interpolations, or other approximations that give you the required accuracy far faster than any IEEE-compliant standard library.

If you are going for C++, you can easily create a wrapper around "float" that does not have any implicit conversions to double so that you can be sure to avoid accidents.

Or you can use the gcc flags I mentioned above :-)

Reply to
David Brown

Thanks for your comments David -- -Wdouble-promotion was, specifically, flying under my radar. The next time that project is active I'll add it in, to the benefit of future-me.

--

Tim Wescott 
Wescott Design Services 
http://www.wescottdesign.com 

I'm looking for work -- see my website!
Reply to
Tim Wescott

By default Microchip's XC32 compiler uses 32-bit doubles. There is a compiler switch for 64-bit doubles, but there have been several reports on their forums about the wrong libraries being linked in or other such nonsense.

-a

Reply to
Anders.Montonen

Yes, this is lovely stuff:

formatting link

Thanks for the heads-up on -fno-short-double. I expected this for PIC24, but a bit surprising for PIC32? For some of our applications, 23 bits of precision doesn't do it...

Thanks Anders, Best Regards, Dave

Reply to
Dave Nadler

Thanks David for your (as usual) clear explanation, Best Regards, Dave

Reply to
Dave Nadler

Thanks John, we'll add the ST part to the list...

Reply to
Dave Nadler

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.