www.mikrocontroller.net

Forum: Compiler & IDEs Achtung, Codeverschwendung bei 64Bit !


Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Für ne Berechnung auf nem ATtiny26 benötige ich ne große Dynamik, aber 
float paßt ja nicht rein.

Da dachte ich, nimmste einfach long long (64Bit), dürfte ja nur doppelt 
soviel Code sein, wie long (32Bit).

Aber Pustekuchen, das ist total verschwenderisch programmiert (noch viel 
teurer als float).

Ne Division kostet etwa 5kB !!!

Also Finger weg von long long, wenns unter nem ATmega16 ist !


Nun wollte ich mir ne Divisionsfunktion in Assembler schreiben (35 Words 
= 70Byte), also 2 Parameter übergeben (r25..r18, r17..10 -> r25..18).

Aber wieder Pustekuchen, die Parameter werden gepusht, dann mein 
Assembler ausgeführt und dann die Parameter gepopt, also meine 
Berechnung weggeschmissen, schöne Scheiße.
Obendrein wird noch gemeckert, daß kein Returnwert da ist.

Ich bin mit meinem Latein am Ende :-(

Hat überhaupt schonmal jemand erfolgreich Assembler mit Parameter und 
Returnwert in ne Funktion integrieren können ?


Peter

Autor: Günter R. (galileo14)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, Peter,

bei einem anderen Prozessor (Toshiba TLCS-900-Umgebung) habe ich es so 
gemacht: ich habe einen Funktionsrumpf in C geschrieben (gleiche 
Parameter und Rückgabe wie bei meiner späteren Assembler-Funktion, 
minimale Funktionalität in der Funktion), habe mir dann den 
Assembler-Code angeschaut, den der Compiler daraus macht (quasi 
abkopiert), und dann meine Funktionalität in die Assembler-Funktion 
eingebaut.

Bei den AVR's habe ich keine Erfahrung mit Assembler, aber es könnte 
hier ja genauso gehen?

Günter

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Dannegger wrote:

> Ne Division kostet etwa 5kB !!!

Das ist mehr oder weniger ein known issue.  Da werden nur die
generischen (in C geschriebenen) Funktionen der libgcc.a benutzt, für
64 bit gibt's keine handoptimierten Varianten.

Du kannst ja gern mithelfen, in Assembler kennst du dich aus, warum
schlägst du nicht mal einen Patch für die libgcc.a vor?  Einziger
Wermutstropfen: damit er von GNU akzeptiert wird, musst du deren
Lizenzabkommen unterschreiben (Abtretung der Rechte aus dem Copyright
an die FSF), ohne das akzeptieren sie keine Patches für den GCC, die
mehr als `trivial patches' sind.

(Bitte keine weitere Baustelle wie bei floating point schaffen, bei
der die avr-libc die Funktionen aus der libgcc.a ersetzt.  Das ist
Sch***e und führt dazu, dass entsprechende Bugreports bei GCC nicht
ernst genommen werden, auch dann, wenn sie eigentlich echte Bugs
sind.)

> Aber wieder Pustekuchen, die Parameter werden gepusht, dann mein
> Assembler ausgeführt und dann die Parameter gepopt, also meine
> Berechnung weggeschmissen, schöne Scheiße.
> Obendrein wird noch gemeckert, daß kein Returnwert da ist.

Dann hast du wohl irgendwas flasch deklariert, die Warnung passt ja
wohl gut zum Verhalten des Compilers, den Rückkehrwert dann auch zu
ignorieren.

> Hat überhaupt schonmal jemand erfolgreich Assembler mit Parameter
> und Returnwert in ne Funktion integrieren können ?

Na klar, macht die avr-libc haufenweise:

% find ~/src/avr-libc/lib* -name \*.c | wc -l
     61
% find ~/src/avr-libc/lib* -name \*.S | wc -l
    126

Doppelt so viele Assemblerquellen wie in C geschriebene.  Ich mag
jetzt nicht zählen, wie viele davon Werte zurückgeben, ist mir zu
müßig.
#include <stdint.h>

extern uint64_t myfunc(uint64_t, uint64_t);

uint64_t x, y, z;

void
dosomething(void)
{
        z = myfunc(x, y);
}
Daraus wird generiert:
.global dosomething
        .type   dosomething, @function
dosomething:
/* prologue: frame size=0 */
        push r2
        push r3
        push r4
        push r5
        push r6
        push r7
        push r8
        push r9
        push r10
        push r11
        push r12
        push r13
        push r14
        push r15
        push r16
        push r17
/* prologue end (size=16) */
        lds r18,y
        lds r19,y+1
        lds r20,y+2
        lds r21,y+3
        lds r22,y+4
        lds r23,y+5
        lds r24,y+6
        lds r25,y+7
        lds r2,x
        lds r3,x+1
        lds r4,x+2
        lds r5,x+3
        lds r6,x+4
        lds r7,x+5
        lds r8,x+6
        lds r9,x+7
        mov r10,r18
        mov r11,r19
        mov r12,r20
        mov r13,r21
        mov r14,r22
        mov r15,r23
        mov r16,r24
        mov r17,r25
        mov r18,r2
        mov r19,r3
        mov r20,r4
        mov r21,r5
        mov r22,r6
        mov r23,r7
        mov r24,r8
        mov r25,r9
        rcall myfunc
        sts z,r18
        sts z+1,r19
        sts z+2,r20
        sts z+3,r21
        sts z+4,r22
        sts z+5,r23
        sts z+6,r24
        sts z+7,r25
/* epilogue: frame size=0 */
        pop r17
        pop r16
        pop r15
        pop r14
        pop r13
        pop r12
        pop r11
        pop r10
        pop r9
        pop r8
        pop r7
        pop r6
        pop r5
        pop r4
        pop r3
        pop r2
        ret
/* epilogue end (size=17) */
/* function dosomething size 98 (65) */
Zugegebenermaßen ist das Umspeichern von x über r2...r9 nach r18...r25
alles andere als optimal, aber das Ergebnis wird ordentlich nach z
abgespeichert.

Bitte nicht mehr als 2 uint64_t übergeben: da gibt's einen offenen
GCC-Bug dafür, für den noch keiner eine richtige Lösung parat hat.
Der Fehler scheint im generischen GCC-Teil zu liegen, tritt aber nur
bei nicht-mainstream-CPUs wie dem AVR zu Tage, da die anderen ihre
eigenen Parameterübergaberoutinen haben.  Das führt leider dazu, dass
bei GCC daraus eine recht geringe Priorität resultiert. :-(

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mit dem Qualifier naked kann man ja beim GCC für ARM und AVR den 
Prolog und Epilog von Funktionen unterdrücken.
http://www.delorie.com/gnu/docs/gcc/gcc_55.html

Hilft dir das vielleicht bei deinem Push/Pop Problem weiter?

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.