Enabling FPU results in erroneous assembly (Cortex-M4F)

Asked by Thargon

Hi,
I guess I encountered a bug that exists since version 4.9, but so far I am having issues to create a minimal example that reproduces the error. Maybe one of you guys is better with compiler debugging than me and can give me some advice ;)

What I want to to:
I am developing code for an STM32F405 (Cortex-M4F) using ChibiOS (kernel 3.1.x of branch stable_16.1.x) and want to make use of the hardware floating point unit (-mfloat-abi=hard -mfpu=fpv4-sp-d16). When compiling my code with arm-none-eabi-gcc-4.8.3 (2014q1) it works fine, but with newer versions of GCC (4.9.3 and 5.x.x tested) the system would not start.

What the assembly says:
I had a brief look at the generated assembly code and found an interesting difference at the very beginning. Here are four examples of the first assembly lines:
GCC 4.8.3 no FPU:
   0: e92d 43f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, lr}
   4: b083 sub sp, #12
GCC 4.8.3 with FPU:
   0: e92d 43f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, lr}
   4: ed2d 8b02 vpush {d8}
   8: b083 sub sp, #12
GCC 5.4.1 no FPU
   0: e92d 43f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, lr}
   4: b083 sub sp, #12
GCC 5.4.1 with FPU:
   0: b5f0 push {r4, r5, r6, r7, lr}
   2: ed2d 8b02 vpush {d8}
   6: b085 sub sp, #20
Seems to me as if GCC 5.4.1 generated a false 'push' instead of the 'stmdb' as the very first command. Unfortunately I can not reproduce the issue with the ChibiOS demos (no 'stmdb' is generated at all).

Since I am no expert in assembly and did never debug GCC before, I appreciate any help in this. Actually it is even possible that I messed up the compiler arguments (arm-none-eabi-g++ -c -mcpu=cortex-m4 -g -O2 -fomit-frame-pointer -falign-functions=16 -fstack-usage -ffunction-sections -fdata-sections -fno-common -mfloat-abi=hard -mfpu=fpv4-sp-d16 -fsingle-precision-constant -fno-rtti -std=c++11 -Wall -Wextra -Wundef -Wa,-alms=build/lst/main.lst -DCORTEX_USE_FPU=TRUE -DTHUMB_PRESENT -mno-thumb-interwork -DTHUMB_NO_INTERWORKING -MD -MP -MF .dep/main.o.d -mthumb -DTHUMB -I<many/many/folders> main.cpp -o build/obj/main.o), but then again I have no idea where to start =(

Maybe someone can give me some advice?

Question information

Language:
English Edit question
Status:
Answered
For:
GNU Arm Embedded Toolchain Edit question
Assignee:
No assignee Edit question
Last query:
Last reply:
Revision history for this message
Andre Vieira (andre-simoesdiasvieira) said :
#1

Hi Thargon,

I dont see what is wrong with the push, why do you call it a 'false' push? It seems the FPU version with GCC 5.4.1 saves and restores less callee save registers (r4-r7 and lr), but thats fine, I'm assuming its because it doesn't need r8 and r9, possibly due to code improvements. If you take a look at the ARMv7-M Reference Manual, see http://infocenter.arm.com/help/topic/com.arm.doc.ddi0403e.b/index.html, you can see that STMDB SP!, <registers> is equivalent to PUSH <registers> (See section A.7.7.99).

As for your command line, I see you are using -mno-thumb-interwork which I don't think is necessary since cortex-m4 doesn't have an ARM mode anyway, though it shouldn't hurt. Otherwise the only thing that comes to mind is that the command line you give does not link (-c), but I'm assuming you link it later.

Have you tried to debug it? Do you know at what point in your program it goes wrong? Anyhow I don't think it has anything to do with the push you showed.

Good luck!

Andre

Can you help with this problem?

Provide an answer of your own, or ask Thargon for more information if necessary.

To post a message you must log in.