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

OP #1692756
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.
Gast
eine Funktion log zu benennen halte ich nicht für gut, denn in math.h 
gibt es ja: double log(double x)  natürlicher Logarithmus ln(x), x > 0
vielleicht liegt da der Fehler.!?
OP
Das kannst du mir ruhig glauben, ich habe eine eigens übersetzte 
Toolchain und absichtlich keine libc und libmath... wieso glaubst du, 
dass es damit funktioniert? Das sieht mir irgendwie eher nach einem Bug 
aus.
OP
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)
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.
OP
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
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.
OP
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)
OP
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
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

Eine eigene Frage? Dieser Thread ist über 16 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.