Compiler generates additional wrong fp instructions which converts from float to integer.

Asked by Vladislav Cebotari

Hello, I'm compiling for ARM cortex M4 with the following arguments:

arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=soft -O0 -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -fno-inline-functions -Wall -Wextra -g3

And there is a very strange behavior I observed.
I have 2 sources, main.c, test.c/test.h

in main.c:

float E = getE();
printf("%f", E); /* through serial terminal */

test.c/test.h
float getE(void) {
    float e = 2.71;
    return e;
}

The problem is that when I'll print on the terminal, I get the value: 1076719780 == 0x4e805ae1 , which is basically decimal representation of the memory location where the floating point is stored ( https://www.h-schmidt.net/FloatConverter/IEEE754.html ). That's strange, because the function should return a float,
looking into dissasembly of main.c:

-mfloat-abi=soft
 414 002e FFF7FEFF bl getE
 415 0032 0346 mov r3, r0
 416 0034 1846 mov r0, r3
 417 0036 FFF7FEFF bl __aeabi_i2f <------------------ why the hell this is generated?
 418 003a 0346 mov r3, r0
 419 003c 7B60 str r3, [r7, #4] @ float

-mfloat-abi=softpf
002e FFF7FEFF bl getE
0032 07EE900A vmov s15, r0 @ int
0036 F8EEE77A vcvt.f32.s32 s15, s15 <------------------ why the hell this is generated?
003a C7ED017A vstr.32 s15, [r7, #4]

You see that additional instructions are generated. Now, if move the function getE() from test.c directly to main.c:
-mfloat-abi=softpf/soft (in both case same listing)
002e FFF7FEFF bl getE2
0032 0346 mov r3, r0 @ float <---- all good, the value is returned through r0
0034 7B60 str r3, [r7, #4] @ float

Do somebody has a idea what is going on rly?
Thank You!!!

Question information

Language:
English Edit question
Status:
Solved
For:
GNU Arm Embedded Toolchain Edit question
Assignee:
No assignee Edit question
Solved by:
Vladislav Cebotari
Solved:
Last query:
Last reply:
Revision history for this message
Tejas Belagod (belagod-tejas) said :
#1

How do you declare getE() in main.c? In the absence of a prototype in main.c for getE() it assumes the return type is int and hence the conversions. The conversions are done in various ways depending on the float-abi used (https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html).

Revision history for this message
Vladislav Cebotari (darkwishmaster) said :
#2

Hey, thank you, indeed that was the problem. Had no idea that implicit references can have such consequences.