Hallo,
ich habe ein Olimex STM32F4 Board und verwende eine GCC 4.6q2 Toolchain
mit newlib
(https://launchpad.net/gcc-arm-embedded/+milestone/4.6-2012-q2-update).
Ich möchte die Verwendung der FPU zu testen; mein main besteht im
wesentlichen aus:
1 | for(int i=0;i<10;i++) {
|
2 | float fi = i;
|
3 | float f = sqrtf(fi);
|
4 | }
|
Beim kompilieren habe ich noch die beiden Flags -mfloat-abi=hard
-mfpu=fpv4-sp-d16 dazugegeben. Der Compiler macht daraus:
for(int i=0;i<10;i++) {
800018e: f04f 0300 mov.w r3, #0
8000192: 60fb str r3, [r7, #12]
8000194: e01b b.n 80001ce <main+0x46>
float fi = i;
8000196: 68fb ldr r3, [r7, #12]
8000198: ee07 3a10 vmov s14, r3
800019c: eef8 7ac7 vcvt.f32.s32 s15, s14
80001a0: edc7 7a02 vstr s15, [r7, #8]
float f = sqrtf(fi);
80001a4: edd7 7a02 vldr s15, [r7, #8]
80001a8: eef1 7ae7 vsqrt.f32 s15, s15
80001ac: eef4 7a67 vcmp.f32 s15, s15
80001b0: eef1 fa10 vmrs APSR_nzcv, fpscr
80001b4: d005 beq.n 80001c2 <main+0x3a>
80001b6: ed97 0a02 vldr s0, [r7, #8]
80001ba: f000 fabf bl 800073c <sqrtf>
80001be: eef0 7a40 vmov.f32 s15, s0
80001c2: edc7 7a01 vstr s15, [r7, #4]
80001c6: 68fb ldr r3, [r7, #12]
80001c8: f103 0301 add.w r3, r3, #1
80001cc: 60fb str r3, [r7, #12]
80001ce: 68fb ldr r3, [r7, #12]
80001d0: 2b09 cmp r3, #9
80001d2: dde0 ble.n 8000196 <main+0xe>
Offensichtlich verwendet der Code die FPU Befehle des Cortex-M4. Das
Merkwürdige ist aber, dass in 80001b0 der "return" wert von vsqrt.f32
überprüft wird. Wenn ein Flag gesetzt ist, dann wird die "soft-fpu"
Funktion sqrtf aus der newlib aufgerufen - quasi als Fallback?!
Hat irgendwer eine Ahnung, warum das passiert (bzw ob irgendwelche
Compiler/Linker flags falsch eingestellt sind)? Ich hätte erwartet, dass
eine FPU verwendet wird, wenn eine da ist & nicht noch zusätzlich die
FPU Emulation der newlib verwendet wird...
Danke - Clemens
P.S.: Das komplette Projekt ist hier
https://github.com/ClemensFMN/STM32F4XStart zu finden