GCC, Cortex-M3 (LPC1768) und Fließkommazahlen

#1692756
Lesenswert?

Hallo,

bei meinem LPC1768 Cortex-M3 in Kombination mit meiner GCC 4.4.1 
Toolchain (Linux) habe ich heute ein komisches Verhalten entdeckt, wenn 
Fließkommazahlen in Modulen auftauchen. Es geht dabei um folgende 
Beispielfunktion:
1
void demo_fail(unsigned long p1, unsigned long p2) {
2
  log("STEP 1");
3
  double f = 0.0, d = 1.0;
4

5
  log("STEP 2");
6
  f = (double)p1/(16.0*(double)p2*d);
7

8
  log("STEP 3");
9
  if (f <= 1.1 || f >= 1.9) {
10

11
    log("STEP 4");
12
    for (f = 1.1; f <= 1.9; f += 0.1)
13
      d++;
14
  }
15

16
  log("STEP 5");
17
}

Ist diese Funktion innerhalb meiner main.c, funktioniert deren Aufruf 
"demo_fail(1,1)" komplett. Ist sie hingegen in ein Modul ausgelagert, 
ist "STEP 2" die letzte Ausgabe, die ich sehe (also hängt die 
double-Berechnung).

Übersetzt wird das Ganze fehlerfrei mit:
1
arm-none-eabi-gcc -marm -mcpu=cortex-m3 -mthumb -msoft-float 
2
   -ffreestanding -Wall -std=gnu99 -Wno-parentheses
3
   -fomit-frame-pointer -fshort-wchar -O3 -g -c -o mod.o mod.c
4
arm-none-eabi-gcc -marm -mcpu=cortex-m3 -mthumb -msoft-float 
5
   -ffreestanding -Wall -std=gnu99 -Wno-parentheses
6
   -fomit-frame-pointer -fshort-wchar -O3 -g -c -o main.o main.c
7
arm-none-eabi-ld --no-wchar-size-warning -T lpc1768.x -o main.elf
8
   main.o mod.o

Die folgenden beiden Varianten der Funktion (1 ohne Funktionsparameter, 
2 ohne Fließkommazahlen) funktionieren auch in einem Modul einwandfrei:
1
void demo_ok1() {
2
  log("STEP 1");
3
  unsigned long p1 = 1, p2 = 1;
4
  double f = 0.0, d = 1.0;
5

6
  log("STEP 2");
7
  f = (double)p1/(16.0*(double)p2*d);
8

9
  log("STEP 3");
10
  if (f <= 1.1 || f >= 1.9) {
11

12
    log("STEP 4");
13
    for (f = 1.1; f <= 1.9; f += 0.1)
14
      d++;
15
  }
16

17
  log("STEP 5");
18
}
19

20
void demo_ok2(unsigned long p1, unsigned long p2) {
21
  log("STEP 1");
22
  int f = 0, d = 1;
23

24
  log("STEP 2");
25
  f = p1/(16*p2*d);
26

27
  log("STEP 3");
28
  if (f <= 1 || f >= 2) {
29

30
    log("STEP 4");
31
    for (f = 1; f <= 2; f += 1)
32
      d++;
33
  }
34

35
  log("STEP 5");
36
}

Hat jemand eine Idee, woran das liegen könnte?! Danke vorab.
#1697436
Lesenswert?

Das kommt mir bekannt vor, ich kann mich ebenso dunkel an einen Fall 
erinnern, bei dem das Funktionieren von der Position der libgcc in der 
Parameterliste abhing.

Leider scheint das hier nicht der Fall zu sein, ich habe es gerade mit 
der Codesourcery Toolchain gemäß deinem Vorschlag versucht, das Ergebnis 
ist aber leider dasselbe. Trotzdem danke für die Idee.
(Firma: EleLa - www.elela.de) #1697678
Lesenswert?

Ich habe meine Formel wegen der Geschwindigkeit umgebaut. Du könntest 
vielleicht eine Float-Zahl wandeln in eine s32, dann berechnen, dann 
wiederzurück in Float. Ich weiß ja nicht wie komplex Deine Formeln sind, 
bzw. ob Du cos/sin Funktionen brauchst.

PS: Versuche es doch mal mit dem Datentyp float un nicht mit double.
#1697716
Lesenswert?

Versteh mich bitte nicht falsch, aber mir geht's da eher ums Prinzip. 
Falls es tatsächlich ein Bug ist, ist er in den aktuellen Versionen auch 
noch vorhanden. Habe mittlerweile folgende Kombinationen durch:

gcc 4.4.1 / binutils 2.19.1
gcc 4.4.1 / binutils 2.19.51.20090709 (Sourcery)
gcc 4.5.0 / binutils 2.20

Mit "float" kommt er immerhin zu "STEP 3".
Persönliche Seite #1703034
Lesenswert?

Halte ich zwar für unwahrscheinlich dass es daran liegt, aber trotzdem: 
Prober mal statt -O3 lieber -O2 oder -O0 (zumindest testweise), evtl. 
ist das schlicht ein Compilerbug oder sowas in der Richtung.

Außerdem könnten die Optionen die du beim bauen der Toolchain verwendet 
hast eine Rolle spielen (also nicht nur die Optionen mit denen du den 
Compiler aufrufst), z.B. --with-float=soft u.ä.

Und/oder probier auch mal eine andere toolchain-Version um festzustellen 
ob es evtl. ein Compilerbug in dieser Version ist.

HTH, Uwe.
#1703051
Lesenswert?

Unterschiedliche Optimierungsstufen habe ich schon hinter mir und 
unterschiedliche Toolchains auch, siehe oben. Die Toolchains sind wie 
folgt konfiguriert:
1
Target: arm-none-eabi
2
Configured with: ../gcc-4.4.1/configure --target=arm-none-eabi --prefix=/usr/local/toolchain/arm-none-eabi-4.4.1 --enable-interwork --enable-multilib --enable-languages=c --disable-fpu --disable-nls --disable-shared --disable-libssp --without-headers
3
Thread model: single
4
gcc version 4.4.1 (GCC)
5

6
Target: arm-none-eabi
7
Configured with: ../gcc-4.5.0/configure --target=arm-none-eabi --prefix=/usr/local/toolchain/arm-none-eabi-4.5.0 --enable-interwork --enable-multilib --enable-languages=c --with-newlib --with-headers=../newlib-1.18.0/newlib/libc/include --with-float=soft
8
Thread model: single
9
gcc version 4.5.0 (GCC)
10

11
Target: arm-none-eabi
12
Configured with: /scratch/julian/2010q1-release-eabi-lite/src/gcc-4.4-2010q1/configure --build=i686-pc-linux-gnu --host=i686-pc-linux-gnu --target=arm-none-eabi --enable-threads --disable-libmudflap --disable-libssp --disable-libstdcxx-pch --enable-extra-sgxxlite-multilibs --with-gnu-as --with-gnu-ld --with-specs='%{O2:%{!fno-remove-local-statics: -fremove-local-statics}} %{O*:%{O|O0|O1|O2|Os:;:%{!fno-remove-local-statics: -fremove-local-statics}}}' --enable-languages=c,c++ --disable-shared --disable-lto --with-newlib --with-pkgversion='Sourcery G++ Lite 2010q1-188' --with-bugurl=https://support.codesourcery.com/GNUToolchain/ --disable-nls --prefix=/opt/codesourcery --with-headers=yes --with-sysroot=/opt/codesourcery/arm-none-eabi --with-build-sysroot=/scratch/julian/2010q1-release-eabi-lite/install/arm-none-eabi --with-gmp=/scratch/julian/2010q1-release-eabi-lite/obj/host-libs-2010q1-188-arm-none-eabi-i686-pc-linux-gnu/usr --with-mpfr=/scratch/julian/2010q1-release-eabi-lite/obj/host-libs-2010q1-188-arm-none-eabi-i686-pc-linux-gnu/usr --with-ppl=/scratch/julian/2010q1-release-eabi-lite/obj/host-libs-2010q1-188-arm-none-eabi-i686-pc-linux-gnu/usr --with-host-libstdcxx='-static-libgcc -Wl,-Bstatic,-lstdc++,-Bdynamic -lm' --with-cloog=/scratch/julian/2010q1-release-eabi-lite/obj/host-libs-2010q1-188-arm-none-eabi-i686-pc-linux-gnu/usr --disable-libgomp --enable-poison-system-directories --with-build-time-tools=/scratch/julian/2010q1-release-eabi-lite/install/arm-none-eabi/bin --with-build-time-tools=/scratch/julian/2010q1-release-eabi-lite/install/arm-none-eabi/bin
13
Thread model: single
14
gcc version 4.4.1 (Sourcery G++ Lite 2010q1-188)
#1707793
Lesenswert?

Ich hab's doch auch mit der Toolchain von CodeSourcery versucht, doch 
auch da muss man nun mal gegen die thumb2-libgcc linken... ;-) Zum Thema 
selbst übersetzen: ich habe da einfach die bessere Kontrolle über 
diverse Einstellungen (z.B. SMALLMEM bei der newlib).
Gast #1714672
Lesenswert?

Vieleicht eine division durch 0? Ja ich weiss, sollte es ned sein, 
berechne den Divident und Divisior vor und schau ob diese 0 sind...

Ansonsten wäre ein direkter vergleich der Disassemblies interessant (als 
Modul vs. in Main, mit dem gleichen Compiler...)

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren