Hi.
Eine AES-Funktion, die ich einsetze, nutzt .balign 256, um Segmente im
Flash anzuordnen. Das ist ja auch von Vorteil, wenn man einmal mit ldi
ZH nur den High-Pointer einladen muss und dann nur noch ZL ändern muss,
bevor man dann mit lpm das Byte einlädt. Und das passiert sehr oft im
Loop, deshalb ist diese Optimierung durchaus legitim.
Nun ist mir aufgefallen, dass diese Funktion mit -mrelax nicht mehr
funktioniert.
Im Code wird via .balign 256 der Block angeordnet. Dies ist auch so im
Binary richtig platziert. Steht so im .lss-File. Allerdings wird jetzt
der Pointer nicht mehr richtig eingeladen. Das (Pseudocode) ldi Z,0x3000
wurde zu ldi Z,0x297F.
Kann mir da jemand helfen?
Jan schrieb:> Eine AES-Funktion, die ich einsetze, nutzt .balign 256, um Segmente im> Flash anzuordnen. Das ist ja auch von Vorteil, wenn man einmal mit ldi> ZH nur den High-Pointer einladen muss und dann nur noch ZL ändern muss,> bevor man dann mit lpm das Byte einlädt.
Mikro-Optimierung? Hast du mal gemessen, ob das überhaupt Einfluß auf
die Laufzeit des Codes hat?
> Nun ist mir aufgefallen, dass diese Funktion mit -mrelax nicht mehr> funktioniert.
Das ist auch unklar. Hier beschreibst du den generierten Code:
> Im Code wird via .balign 256 der Block angeordnet. Dies ist auch so im> Binary richtig platziert. Steht so im .lss-File. Allerdings wird jetzt> der Pointer nicht mehr richtig eingeladen. Das (Pseudocode) ldi Z,0x3000> wurde zu ldi Z,0x297F.
Aber du sagst nicht, ob der Code noch das richtige tut. Ist das nicht
eigentlich das entscheidende?
Wenn du gültigen C-Code hast, der ohne -mrelax das korrekte Verhalten,
mit -mrelax jedoch inkorrektes Verhalten erzeugt, dann hast du einen Bug
in der AVR Toolchain gefunden. Reporte ihn.
Aber aus deinem Post werde ich nicht schlau. Und die Dokumentation von
avr-gcc [1] zu -mrelax läßt den Zusammenhang mit dem gesagten zumindest
unwahrscheinlich erscheinen.
[1] https://gcc.gnu.org/onlinedocs/gcc/AVR-Options.html
Axel S. schrieb:> Jan schrieb:>>> Eine AES-Funktion, die ich einsetze, nutzt .balign 256, um Segmente im>> Flash anzuordnen. Das ist ja auch von Vorteil, wenn man einmal mit ldi>> ZH nur den High-Pointer einladen muss und dann nur noch ZL ändern muss,>> bevor man dann mit lpm das Byte einlädt.>> Mikro-Optimierung? Hast du mal gemessen, ob das überhaupt Einfluß auf> die Laufzeit des Codes hat?
Ja, macht gut 30% aus. Es handelt sich um diese Funktion:
http://point-at-infinity.org/avraes/rijndaelfurious.asm.html>> Nun ist mir aufgefallen, dass diese Funktion mit -mrelax nicht mehr>> funktioniert.>> Das ist auch unklar. Hier beschreibst du den generierten Code:>>> Im Code wird via .balign 256 der Block angeordnet. Dies ist auch so im>> Binary richtig platziert. Steht so im .lss-File. Allerdings wird jetzt>> der Pointer nicht mehr richtig eingeladen. Das (Pseudocode) ldi Z,0x3000>> wurde zu ldi Z,0x297F.>> Aber du sagst nicht, ob der Code noch das richtige tut. Ist das nicht> eigentlich das entscheidende?
Der Code tut nur das richtige, wenn man -mrelax weglässt. Sobald man es
aktiviert, wird im ldi ZH, high(sbox<<1) die falsche Adresse eingeladen.
> Wenn du gültigen C-Code hast, der ohne -mrelax das korrekte Verhalten,> mit -mrelax jedoch inkorrektes Verhalten erzeugt, dann hast du einen Bug> in der AVR Toolchain gefunden. Reporte ihn.
Wo? Habe sowas noch nie gemacht. Wird die avr toolchain überhaupt noch
gepflegt?
> Aber aus deinem Post werde ich nicht schlau. Und die Dokumentation von> avr-gcc [1] zu -mrelax läßt den Zusammenhang mit dem gesagten zumindest> unwahrscheinlich erscheinen.>> [1] https://gcc.gnu.org/onlinedocs/gcc/AVR-Options.html
Ich liefere gerne Infos nach.
-mrelax veranlasst den Linker dazu "CALL n \ RET" durch "JMP n"
ersetzt. Dabei reduziert er natürlich die Code-Größe und damit auch die
Position von "hand-alignden" Adressen. Die Tabelle müßte in einem
eigenen Segment stehen, daß Attribut "Alignment 256" hat. Dann würde der
Linker das auch entsprechend ausrichten. Wahrscheinlich muß man das über
ein passendes Linkerscript machen.
Gcc schrieb:> -mrelax veranlasst den Linker dazu "CALL n \ RET" durch "JMP n"> ersetzt. Dabei reduziert er natürlich die Code-Größe und damit auch die> Position von "hand-alignden" Adressen. Die Tabelle müßte in einem> eigenen Segment stehen, daß Attribut "Alignment 256" hat. Dann würde der> Linker das auch entsprechend ausrichten. Wahrscheinlich muß man das über> ein passendes Linkerscript machen.
Ja, wenn es konsistent wäre, wäre das auch nachvollziehbar. Aber im .lss
File sieht man, dass die Matrix weiterhin korrekt aligned wurde. Nur der
ldi zeigt auf die optimierte (also falsche, da zu niedrige) Adresse.
Jan schrieb:>> Aber du sagst nicht, ob der Code noch das richtige tut. Ist das nicht>> eigentlich das entscheidende?>> Der Code tut nur das richtige, wenn man -mrelax weglässt. Sobald man es> aktiviert, wird im ldi ZH, high(sbox<<1) die falsche Adresse eingeladen.
Das ist keine Antwort auf die Frage. Deswegen nochmal:
"Tut der erzeugte Code, was er soll?"
Sprich chiffriert und dechiffriert er ordungsgemäß? Wenn ja, dann ist
die Toolchain nicht "buggy". Die Geschwindigkeit, mit der das Compilat
läuft ist nicht entscheidend für Korrektheit.
Natürlich kann es sein, das für dich die Geschwindigkeit auch wichtig
ist (nach der Korrektheit natürlich). Aber dann muß ich erstmal die
Frage stellen: warum -mrelax? Die Option nutzt nur RCALL/RJMP statt
CALL/JMP, spart also gerade mal einen Cycle (und ein Byte) pro
Funktionsaufruf. Der Riesen-Burner wird das also nicht sein. Zumal der
Compiler, wenn man mit -O2 compiliert, Funktionen eher inlinen wird als
sie aufzurufen.
Axel S. schrieb:> "Tut der erzeugte Code, was er soll?">> Sprich chiffriert und dechiffriert er ordungsgemäß?
Die Antwort sollte eigentlich selbstverständlich sein. Nein, tut er
nicht. Was meinst du, wie ich sonst hätte dieses Problem mitbekommen
sollen?
Also nochmal deutlich: Mit -mrelax kommt nur noch Datenmüll raus,
schalte ich -mrelax ab, funktioniert es.
Axel S. schrieb:> warum -mrelax?
Weil ich ausschliesslich in Assembler programmiere und bei grossen
Projekten switche ich dann alles auf call/jmp. Da soll der Compiler dann
bitte selbst optimieren. Die Codegrösse (mit oder ohne mrelax)
unterscheidet sich dabei gerne mal um 500 Bytes. Ich würde schon sagen,
dass ich das gerne hätte, wenn es schonmal da ist. Bei den 8-Bittern
sind 500 Bytes ja schon noch erwähnenswert.
Gut, dann hast du zumindest einen Testcase, damit kannst du bei den GNU
Binutils einen Bugreport aufmachen.
Den ganzen Zirkus
-Wall -Wextra -std=gnu99
kannst du gern weglassen, wenn du eh keinen C-Code compilierst. Der
interessiert nur den eigentlichen Compiler.
Jan schrieb:> Bei den 8-Bittern> sind 500 Bytes ja schon noch erwähnenswert.
Nö.
Call bedeutet, Du nimmst mindestens einen Mega16, d.h. die Einsparung
ist bestenfalls nur 3%.
Peter D. schrieb:> Jan schrieb:>> Bei den 8-Bittern>> sind 500 Bytes ja schon noch erwähnenswert.>> Nö.> Call bedeutet, Du nimmst mindestens einen Mega16, d.h. die Einsparung> ist bestenfalls nur 3%.
Und 3% findest du nicht erwähnenswert? Wow... Nope. Kann ich nicht
nachvollziehen.
Jörg W. schrieb:> Gut, dann hast du zumindest einen Testcase, damit kannst du bei den GNU> Binutils einen Bugreport aufmachen.
Wie gesagt, habe sowas noch nie gemacht. Wohin gehe ich da genau?
Jan schrieb:> Jörg W. schrieb:>> Gut, dann hast du zumindest einen Testcase, damit kannst du bei den GNU>> Binutils einen Bugreport aufmachen.>> Wie gesagt, habe sowas noch nie gemacht. Wohin gehe ich da genau?
Mit nochmaligem drüber Nachdenken, vielleicht doch besser beim Compiler
selbst:
https://gcc.gnu.org/bugzilla/
statt bei den Binutils:
https://www.sourceware.org/bugzilla/
Bin mir gerade nicht 100%ig sicher, wer genau was bei -mrelax macht.
Jan schrieb:> War offensichtlich das falsche Forum für sowas.
Na, du bist gut. Du brauchst einen Tag für dein Beispiel, und dann soll
jeder hier springen und dir in 2 Stunden eine Antwort geliefert haben?
Jörg W. schrieb:> Mit nochmaligem drüber Nachdenken, vielleicht doch besser beim Compiler> selbst:>> https://gcc.gnu.org/bugzilla/>> statt bei den Binutils:>> https://www.sourceware.org/bugzilla/>> Bin mir gerade nicht 100%ig sicher, wer genau was bei -mrelax macht.
Ich habe es erst anscheinend irrtümlich bei gcc eingereicht:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103673
Dort wurde er geschlossen. Eine Anmeldung bei binutils wurde geblockt.
Anscheinend nehmen die grade einfach keine Anmeldungen an. Das wird mir
jetzt auch alles zu viel. Ich persönlich habe schon seit gestern einen
work-around zur Laufzeit, aber ich dachte, ich reiche den Bug mal ein,
falls noch jemand drüber stoplert. Den zu finden alleine hat mich 2
Stunden gekostet.
Jörg W. schrieb:> Jan schrieb:>> War offensichtlich das falsche Forum für sowas.>> Na, du bist gut. Du brauchst einen Tag für dein Beispiel, und dann soll> jeder hier springen und dir in 2 Stunden eine Antwort geliefert haben?
Es kam generell seit Eröffnung eher wenig Feedback. War keine Kritik,
eher ne Feststellung.
Jan schrieb:> Eine Anmeldung bei binutils wurde geblockt.
Gab's eine Begründung?
Ansonsten kann ich das da für dich einreichen, aber ich brauche dazu
deine Binutils-Version ("avr-ld -V").
Jan schrieb:> Es kam generell seit Eröffnung eher wenig Feedback.
Ist ja auch ein reichlich spezieller Anwendungsfall.
Wie ich schon schrieb, der wesentliche Grund, warum die Linker
relaxations seinerzeit (durch Björn Haase, wenn ich mich recht entsinne)
vorangetrieben worden sind für den AVR waren die jump trampolines /
linker stubs für AVRs mit mehr als 128 KiB Flash. Alles jenseits dessen
ist sicher eher sehr wenig getestetes Gelände. Kommt noch hinzu, die
meisten, die einen AVR (ausgiebiger) in Assembler programmieren, werden
das vermutlich mit Atmel/Microchips eigenem Assembler im Atmel/Microchip
Studio tun. Der hat gleich gar keinen Linker. :-)
Jörg W. schrieb:> Mit nochmaligem drüber Nachdenken, vielleicht doch besser beim Compiler> selbst:> statt bei den Binutils:> Bin mir gerade nicht 100%ig sicher, wer genau was bei -mrelax macht.
Wenn ich das richtig überblicke, dann macht auch der Assembler eher
wenig dafür. Eigentlich ist das beim Linker angesiedelt, denn der macht
ja die Relokation (und bei -relax noch ein paar Opcode-Ersetzungen
zusätzlich). Andererseits ist Code (bzw. hier Daten) mit festem
Placement (im Original) oder doch zumindest ungewöhnlichem Alignment
(der Code des TE) in einer extra Flash-Sektion besser aufgehoben.
Beim Mixen von Assembler und C-Code stößt man halt schneller an die
Grenzen der Toolchain. Besonders, wenn es um Sachen geht, die über alle
Phasen der Compilierung gehen. Für -flto erwarte ich auch spannende
Effekte, wenn Assembler mit an Bord ist.
Axel S. schrieb:> Für -flto erwarte ich auch spannende Effekte, wenn Assembler mit an Bord> ist.
Ist die Frage, ob das dann überhaupt aktiviert wird.
So wie ich das verstanden habe, wird da ja der Compiler nochmal
angeworfen.
Jörg W. schrieb:> Jan schrieb:>> Eine Anmeldung bei binutils wurde geblockt.>> Gab's eine Begründung?
Zitat, nach Eingabe der verlangten e-mail Adresse: "User account
creation has been restricted. Contact your administrator or the
maintainer (overseers@sourceware.org) for information about creating an
account."
> Ansonsten kann ich das da für dich einreichen, aber ich brauche dazu> deine Binutils-Version ("avr-ld -V").
Das wäre nett. Ich kenne mich mit der Toolchain gar nicht aus. Ich nutze
nur den gas. Aber da ich das ja mit avr-gcc aufrufe, dachte ich halt, es
gehört dazu... Naja ist alles ziermlich gross da.
@Jörg: Wenn du der Meinung bist, dass das Problem doch im gcc liegen
könnte, könntest du ja hier mal ein deinen Kommentar hinzufügen. Der Bug
ist jetzt halt "RESOLVED MOVED". Und ich kann da wirklich nicht
mitdiskutieren.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103673
https://www.sourceware.org/bugzilla/show_bug.cgi?id=28686
Beim Eingeben tauchte Bug 20545 auf, der meiner Meinung nach etwas
Ähnliches beschreibt. Da der aber als repariert markiert ist, habe ich
einen neuen aufgemacht statt den alten wiederzubeleben.
Deine Binutils-Version scheint ja recht aktuell zu sein, und damit
ausreichend, dass Bug 20545 darin repariert ist.
ps: Achso, wenn du mir deine Mailadresse zusendest (meine wirst du
herausfinden können ;-), dann trage ich dich dort auf die Cc-Liste ein.
pps: Ich habe mal den recht populären (u.a. durch Arduino) ATmega328 als
Beispiel eingegeben statt deines eher exotischen Xmegas. Der Fehler
tritt dafür genauso auf.
Jan schrieb:> Und 3% findest du nicht erwähnenswert? Wow... Nope. Kann ich nicht> nachvollziehen.
Bei Deinem ATxmega384C3 sind es nur noch winzige 0,1%.
Jan schrieb:> Ja, macht gut 30% aus.
Es wäre mal interessant, ob der Anwender die 30% überhaupt bemerken
würde.
Bei allen meinen Programmen würde der Benutzer nicht merken, wenn ich
einen um 30% langsameren Quarz einsetze.
Jörg W. schrieb:> https://www.sourceware.org/bugzilla/show_bug.cgi?id=28686
Danke. Behalte ich im Auge.
> ps: Achso, wenn du mir deine Mailadresse zusendest (meine wirst du> herausfinden können ;-), dann trage ich dich dort auf die Cc-Liste ein.
Ja, steht ja alles auf sax.de ;) Man sieht, dass die Seite noch aus
jungen Internetjahren stammt, wo die Leute noch nett zueinander waren.
Aber du brauchst mich da nicht adden, ich habe den Bug auf der Watchlist
und bekomme das mit, wenn sich da was tut. Die Aktivitäten dort scheinen
aber generell eher zu ruhen. So ein bissl wie bei avrdude ;)
Danke für deine Mithilfe.
Das ging ja schnell.
Nick Clifton <nickc at redhat dot com> changed:
What |Removed |Added
------------------------------------------------------------------------
----
Resolution|--- |FIXED
Status|ASSIGNED |RESOLVED
--- Comment #3 from Nick Clifton <nickc at redhat dot com> ---
Patch applied.
Oha.... gut, jetzt bin ich positiv überrascht. Ich weiss zwar nicht, wie
lange es dauert, bis die gefixte Version es letztendlich in mein FreeBSD
13 schafft, aber immerhin fixed.
Aber nagut, sowas ist ja auch einfacher zu fixen als ein double rjmp
Hardware-bug in einem xmega E, der es damals bei Microchip nichtmal
durch den 1st Level Support geschafft hat.
Jan schrieb:> Aber nagut, sowas ist ja auch einfacher zu fixen als ein double rjmp> Hardware-bug in einem xmega E, der es damals bei Microchip nichtmal> durch den 1st Level Support geschafft hat.
Bei sowas musst du beim Firstlevel-Support hartnäckig bleiben. Sowie
diese Leute zu der Überzeugung gekommen sind, dass es wirklich Hardware
ist, dann können sie das ja an die Entwickler weiterreichen und der Fall
ist für sie erledigt. Diese Leute werden mehr oder weniger nach
"Durchsatz" evaluiert, und was sie folglich nicht an der Backe haben
wollen, sind Bugs, die auf ihrer Liste ewig als offen herum lungern.
Bezüglich FreeBSD: dafür braucht's natürlich erstmal einen
binutils-Release. Aber bei FreeBSD hast du es einfach: installier dir
den Ports-Tree, lege den Diff aus dem genannten commit in
devel/binutils/files/bug28686.patch ab und bau dir die avr-binutils aus
dem Port selbst.
Jörg W. schrieb:> Aber bei FreeBSD hast du es einfach: installier dir> den Ports-Tree, lege den Diff aus dem genannten commit in> devel/binutils/files/bug28686.patch ab und bau dir die avr-binutils aus> dem Port selbst.
Danke für den Input. Das probiere ich dann mal aus. Derzeit läuft ein
Offset-Hotfix beim Init auf dem µC. Ich dachte nicht, dass der Bug so
schnell gefixt wird.
Jörg W. schrieb:> Bei sowas musst du beim Firstlevel-Support hartnäckig bleiben. Sowie> diese Leute zu der Überzeugung gekommen sind, dass es wirklich Hardware> ist, dann können sie das ja an die Entwickler weiterreichen und der Fall> ist für sie erledigt. Diese Leute werden mehr oder weniger nach> "Durchsatz" evaluiert, und was sie folglich nicht an der Backe haben> wollen, sind Bugs, die auf ihrer Liste ewig als offen herum lungern.
Ja, mag sein, aber als Hobbybastler wird man nicht bezahlt. Wenn man
angestellter Entwickler ist und der Chef sagt "Meld mal den Bug", dann
investiert man halt die 20 Stunden dafür. So funktioniert ja Arbeit. Und
für mich ist es da wesentlich schneller, das Problem einfach in meine
Errata zu notieren. Ist vielleicht ein wenig egoistisch, aber deshalb
habe ich den Bug ja wenigstens hier mal gemeldet, wenn auch vielleicht
der Nickname etwas provokant gewählt war und es deshalb länger als nötig
gedauert hat, bis hier die wenigen Leute, die wirklich was auf dem
Kasten haben. die Sache ernst genommen haben.
Das Thema wurde übrigens (leider, aber ehrlich gesagt wie erwartet) ohne
Ergebnis geschlossen: Beitrag "XMEGA Hardware-Bug (Kritisch)"