Why use of sqrtf function from libgcc.a causes link double precision function?

842 views Asked by At

I have problem with linking libgcc.a in my project. I need to use sqrtf and log10f, so I have added libgcc.a in makefile by add linker flag "-lm", math.h as include in module and everything compile great but something went wrong in my opinion. When I looked more deeply into mapfile, simply use of sqrtf causes linking also function for double precision floating point handling, for example:

__aeabi_dadd, __aeabi_d2f, __aeabi_ddiv

and many more. I really don't know why single precision implementation of sqrtf or log10f, especially when FPU is on, links double precision functions. I looked into disassembly and I did not find uses of this function in my code. Only in library I found occurrences.

My toolchain is: arm-none-eabi version 6-2017-q2 Core: Cortex-M4F, FPU hardware enabled in linker

Does anyone have any idea why it is happening like this? Code size is really important for me in this case. Thanks for help in advance.

2

There are 2 answers

5
R.. GitHub STOP HELPING ICE On

You need a version of the standard library (libc+libm) built for an ARM hardfloat (normally "armhf"/"arm-*-eabihf" ABI, although you could use the plain eabi still but with use of VFP instructions, i.e. gcc's "softfp" mode, enabled) target. Otherwise the simple fact that you're configuring hard float support at compile time is not going to change the fact that your libc/libm contain code that was compiled to reference soft-float libgcc functions.

3
0___________ On

Use the gcc multitarget - most known for me gcc toolchains do that. You need to specify the correct command line options both for the compiler & linker

example for stm32f303

arm-none-eabi-gcc  -fno-math-errno -mcpu=cortex-m4 -mthumb -mfloat-abi=hard  -fsingle-precision-constant -mfpu=fpv4-sp-d16  -specs=nosys.specs -specs=nano.specs 

-fno-math-errno - does not do the checks, errno is not set, sqrtf is compiled to the single fpu instruction -fsingle-precision-constant - when I mostly use floats I prefer this option to not write the f at the end of the float constants. -mfpu=fpv4-sp-d16 your FPU (actually my F303 one)

the rest is obvious I think. The toolchain should come with the libraries for the many fpus & cores, and linker will choose the correct one. It is lazy but efficient way.

float f;
...
printf("%f", sqrtf(f));

compiles to

 80028fa:   eddd 7a05   vldr    s15, [sp, #20]
 80028fe:   eeb1 7ae7   vsqrt.f32   s14, s15

if you want to benefit from the (almost sometimes) most recent gcc version visit my friends website and build/download his toolchain http://www.freddiechopin.info/en/articles/34-news/98-rewolucja-w-bleeding-edge-toolchain