www.mikrocontroller.net

Forum: Compiler & IDEs WinAVR 20070525 Optimierung


Autor: m4444x (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Gibt's beim Upgrade von WinAVR irgendwas zu beachten? Ich hatte bis vor 
kurzem WinAVR 2006 installiert. Jetzt hab ich auf WinAVR 2007 upgedated 
und meinen Webserver neucompiliert. Leider funktioniert nun die 
Checksummenberechnung nicht mehr.
WORD checksum( BYTE * buffer, WORD count )
{
  WORD sum;
  asm volatile (
    "clr %A0               \n\t"
    "clr %B0               \n\t"
    
    "sbiw %A2, 1           \n\t"
    "brcs 2f               \n\t"
    
    "1:                    \n\t"
    
    "ld __tmp_reg__, %a1+  \n\t"
    "add %A0, __tmp_reg__  \n\t"
    "adc %B0, __zero_reg__ \n\t"
    "adc %A0, __zero_reg__ \n\t"
    
    "sbiw %A2, 1           \n\t"
    "brcs 2f               \n\t"
    
    "ld __tmp_reg__, %a1+  \n\t"
    "add %B0, __tmp_reg__  \n\t"
    "adc %A0, __zero_reg__ \n\t"
    "adc %B0, __zero_reg__ \n\t"
    
    "sbiw %A2, 1           \n\t"
    "brcc 1b               \n\t"
    
    "2:                    \n\t"
    : "=r" (sum) : "e" (buffer), "w" (count)
  );
  return sum;
}

Daraus macht der neue WinAVR (mit -Os):
    20c0:  fe 01         movw  r30, r28
    20c2:  39 96         adiw  r30, 0x09  ; 9
    20c4:  8c e0         ldi  r24, 0x0C  ; 12
    20c6:  90 e0         ldi  r25, 0x00  ; 0
    20c8:  ee 27         eor  r30, r30
    20ca:  ff 27         eor  r31, r31
    20cc:  01 97         sbiw  r24, 0x01  ; 1
    20ce:  60 f0         brcs  .+24       ; 0x20e8 <pushUDP+0xa2>
    20d0:  01 90         ld  r0, Z+
    20d2:  e0 0d         add  r30, r0
    20d4:  f1 1d         adc  r31, r1
    20d6:  e1 1d         adc  r30, r1
    20d8:  01 97         sbiw  r24, 0x01  ; 1
    20da:  30 f0         brcs  .+12       ; 0x20e8 <pushUDP+0xa2>
    20dc:  01 90         ld  r0, Z+
    20de:  f0 0d         add  r31, r0
    20e0:  e1 1d         adc  r30, r1
    20e2:  f1 1d         adc  r31, r1
    20e4:  01 97         sbiw  r24, 0x01  ; 1
    20e6:  a0 f7         brcc  .-24       ; 0x20d0 <pushUDP+0x8a>
    20e8:  f8 87         std  Y+8, r31  ; 0x08
    20ea:  ef 83         std  Y+7, r30  ; 0x07

Sieht so aus als ob die Funktion in 'inline' umgewandelt wird. Aber 
warum tut er R31:R30 doppelt belegen?!?

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

Bewertung
0 lesenswert
nicht lesenswert
m4444x wrote:

> Sieht so aus als ob die Funktion in 'inline' umgewandelt wird.

Ja.  Der Compiler hat keine Ahnung, dass dein inline asm statement
ziemlich länglich ist.  Für ihn ist es ein einzelnes statement (insn),
und das lohnt es sich allemal zu inlinen.

Du kannst das ggf. mit __attribute__((noinline)) verhindern.

> Aber warum tut er R31:R30 doppelt belegen?!?

Hast du mal ein aufs Minimum zusammengestrichenes Codeschnipsel, damit
man es selbst durch den Compiler schieben kann?

Autor: m4444x (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
int main(void)
{
  char data[123]
  return checksum( data, 123 );
}

Das scheint schon zu reichen, um den Fehler zu reproduzieren.

Danke für den Tip mit dem noinline. Aber ich werd' wohl erstmal wieder 
mit dem alten gcc compilieren.

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Den Regeln von GCC entsprechend dürfen Input- und Output-Operand im 
gleichen Register landen, sofern das nicht ausdrücklich verboten wurde. 
Das ist also nicht das Problem des Compilers, sondern wie üblich des 
Programmierers, der die Doku nicht genau genug gelesen hat:

"Unless an output operand has the `&' constraint modifier, GCC may 
allocate it in the same register as an unrelated input operand, on the 
assumption the inputs are consumed before the outputs are produced. This 
assumption may be false if the assembler code actually consists of more 
than one instruction. In such a case, use `&' for each output operand 
that may not overlap an input."

Autor: m4444x (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Achso, also doch bloß der gute alte "did you forget the & ?"

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.