www.mikrocontroller.net

Forum: Compiler & IDEs Riesencode im List.


Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Huhu,

hab mal folgendes übersetzen lassen:
ISR(TIMER2_COMP_vect) {
  /* Turn off display */
  PORTD = 255;
}

Hab mich gewundert, warum die ISR so lahm ist (bin bissi knapp bei 
Resourcen). Im List kam dann raus:
 128:  1f 92         push  r1
 12a:  0f 92         push  r0
 12c:  0f b6         in  r0, 0x3f  ; 63
 12e:  0f 92         push  r0
 130:  11 24         eor  r1, r1
 132:  8f 93         push  r24
  /* Turn off display */
  PORTD = 255;
 134:  8f ef         ldi  r24, 0xFF  ; 255
 136:  82 bb         out  0x12, r24  ; 18
 138:  8f 91         pop  r24
 13a:  0f 90         pop  r0
 13c:  0f be         out  0x3f, r0  ; 63
 13e:  0f 90         pop  r0
 140:  1f 90         pop  r1
 142:  18 95         reti

Und da dacht ich mir, das kann doch wohl nicht wahr sein?! Übersetzt 
wurde mit -Os.

Der Schnipsel hier hätte doch genau dieselben Wirkungen und 
Nebenwirkungen:
push r16
ldi r16, 255
out 0x12, r16
pop r16
Vorallen Dingen, was zum Geier hat "eor r1, r1" oben zu suchen?

Kann man dem GCC das irgendwie verständlich machen? Ich mein, dass der 
mir ab drei Variablen sowieso fast das ganze Registerfile pusht, daran 
hab ich mich ja gewöhnt, aber sowas?

Vielen Dank und viele Grüße,
Sven

Autor: Μαtthias W. (matthias) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Wenn die ISR wirklich so extrem zeitkritisch und simpel ist implementier 
sie doch in einer .s Datei in Assembler und link sie deinem Projekt 
dazu.

Matthias

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oder die ISR als Naked darstellen und dann inline-ASM, schon klar. Aber 
was baut der GCC denn da überhaupt fürn "Müll" zusammen?

Autor: Μαtthias W. (matthias) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

das muss er halt machen da er über den Code in der ISR recht wenig weiß 
bzw. noch niemand den Compiler in diese Richtung optimiert hat.

eor r1, r1 setzt dabei das Zero-Register auf 0 da der Compiler ja nicht 
wissen kann ob eben jenes irgendwo mal nicht 0 war.

Auch der restliche Code hat durchaus seine Bedeutung. Wenn dir das also 
zu viel ist -> .s oder Inline-ASM.

Matthias

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich weiß ja, wozu der Code ist:
 ; Zero-Register retten (könnte ja vom MUL benutzt sein
 128:  1f 92         push  r1

 ; Unsinnigerweise r0 retten; retten, weils ja vom LPM benutzt
 ; sein könnte. Aber man hätte auch r1 benutzen können.
 12a:  0f 92         push  r0

 ; SREG retten. Warum auch immer hier r0 benutzt wird;
 ; r1 hätte es genauso gut getan
 12c:  0f b6         in  r0, 0x3f  ; 63
 12e:  0f 92         push  r0

 ; GCC weiß scheinbar net, dass überhaupt keine "0" hier
 ; gebraucht wird.
 130:  11 24         eor  r1, r1

 ; ein direktes Register retten
 132:  8f 93         push  r24
  /* Turn off display */
  PORTD = 255;
 134:  8f ef         ldi  r24, 0xFF  ; 255
 136:  82 bb         out  0x12, r24  ; 18
 138:  8f 91         pop  r24

 ; SREG wieder herstellen
 13a:  0f 90         pop  r0
 13c:  0f be         out  0x3f, r0  ; 63

 13e:  0f 90         pop  r0
 140:  1f 90         pop  r1
 142:  18 95         reti

Hier ist also reichlich gefahrloses Optimierungspotential vorhanden ;-)

Autor: Der Albi (der-albi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich denke in r0 wird das Status-Register gesichert (keine Ahnung, ob das 
stimmt - loisch wärs aber - man müsste mal das Datenblatt ansehen, was 
der da reinholt) r1 wird auf 0 gesetzt, weil er das Statusregister als 
16-Bit int verwaltet (auch nur Vermutung). Dann nutzt er r24 für das 
ldi.
Alles in allem unschön, aber dennoch nachvollziehbar.

Dein Schnipsel hätte halt wesentlich mehr Nebenwirkungen, wie du es 
nennst, weil du das Statusregister nicht sicherst. Gefährlich!! ;-)

MFG

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Albi: Joa, soweit warn wir schon, schätze mal, wir ham gleichzeitig 
getippselt...:-)

Der Albi wrote:
> Ich denke in r0 wird das Status-Register gesichert (keine Ahnung, ob das
> stimmt - loisch wärs aber - man müsste mal das Datenblatt ansehen, was
> der da reinholt)
Er benutzt r0 als temporäres Register, um damit das Statusregister aufn 
Stack zu pushen, jo.

> r1 wird auf 0 gesetzt, weil er das Statusregister als
> 16-Bit int verwaltet (auch nur Vermutung).
Nö; r1 ist per Definition immer als "Nullregister" gedacht. Deshalb 
setzt er es auf Null-.

> Dann nutzt er r24 für das ldi.
> Alles in allem unschön, aber dennoch nachvollziehbar.
Jubb.

> Dein Schnipsel hätte halt wesentlich mehr Nebenwirkungen, wie du es
> nennst, weil du das Statusregister nicht sicherst. Gefährlich!! ;-)
Hätte er nicht. Weder LDI noch OUT noch PUSH noch POP verändern das 
Statusregister. Daran habe ich schon gedacht...

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, schön und gut. Das "Problem" ist bekannt und wie gesagt hat in der 
Hinsicht noch keiner Hand angelegt am AVR-GCC. Sprich: Es gibt einfach 
keine Optimierungsroutine an dieser Stelle, die überprüft ob das 
Nullregister überhaupt gebraucht wird oder ob das SREG überhaupt 
verändert wird.

Und für die 10 (über den Daumen gepeilt) Takte wird sich da so leicht 
wahrscheinlich auch niemand für begeistern lassen.

Man sollte auch nicht ausschließen, dass vielleicht irgendwelche Normen 
im C-Compilerbau bestimmte Sachen einfach verbieten. Dazu müsste sich 
aber einer der Compiler-Freaks hier mal zu Wort melden ;)

PS: Was spricht gegen eine naked-ISR und einem kleinen C-Kommentar an 
der Stelle, dass es legitim ist?

Autor: G. L. (sprintersb)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Simon K. wrote:
> Sprich: Es gibt einfach keine Optimierungsroutine an dieser Stelle,
> die überprüft ob das Nullregister überhaupt gebraucht wird oder ob
> das SREG überhaupt verändert wird.

Der Haken ist, dass die Änderungen im avr-gcc weit über "diese Stelle" 
hinausgingen.

In r1 steht in avr-gcc immer die 0. Dies geschieht jedoch komplett 
implizit, d.h. gcc hat keine Vorstellung davon. Das ist auch der Grund, 
warum Instruktionen (insns), welche r1 verändern (zB mul) r1 immer 
wieder von Hand herstellen müssen und r1 nicht in der 
Register-Allokierung teilnimmt.

Ich wüsst auch garnicht, wie das gcc beizubringen wäre, d.h welches RTL 
das ausdrücken könnte. Dazu müsste man nämlich sagen können, dass in 
einem bestimmten GPR ein bestimmter Wert vorhanden sein muss. Evrl 
könnte man in jedem Prolog ein (set (reg) (const_int 0)) emittieren und 
mit (use (reg)) die Verwendung anzeigen. Allerdings führt das an anderen 
Stellen zu Problemen, die ohne weiteres nicht zu beheben sind.

Mit SREG sieht's da schon einfacher aus, weil avr-gcc den CC (Condition 
Code) implementiert und jede Insn enstprechend attribuiert.

Also los Jungs, wenn ne hausbackene naked-ISR zu viel Arbeit ist, ihr 
wisst wo die Quelle ist ... feel free to improve and contribute to 
GCC...

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hihi, ne, dass das so tief verstrickt ist, dass wusst ich auch noch 
nich. Najo, irgendwann vielleicht mal^

Danke!

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.