RoboterNetz.de Foren-Übersicht Werbung
 Home  •  Forum  •  Suchen •  Mitgliederliste  •  RN-Landkarte  •  Ränge  •  Statistik  •  Download •  Album  •  Links  •  Kalender  •  Letzte Themen
 RN-Wissen Artikelbereich  •  Mitarbeiter  •  Benutzergruppen  •  Chat  •  Registrieren  •  FAQ  •  Profil  •  log in, Nachrichten zu lesen  •  Login
Kalender 
Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Neues Thema eröffnenNeue Antwort erstellen
Vorheriges Thema anzeigen Dieses Thema einem Freund schickenZeige Benutzer, die dieses Thema gesehen habenDieses Thema als Textdatei speichernPrintable versionlog in, Nachrichten zu lesen Nächstes Thema anzeigen
Autor Nachricht
s.o.

Roboter Experte
Roboter Experte




Anmeldungsdatum: 08.07.2006
Beiträge: 442
Wohnort: Karlsruhe
Alter: 19

germany.gif
Beitrag Verfasst am: 21.07.2007, 18:40 Antworten mit ZitatNach oben

Hallo,

ich frage mich schon seit längerem, wieso Gcc die unteren Register nie anfässt.(Ich verwende avr-gcc 4.1.2.) Im Wiki finde ich folgendes: R1 – R17, R28, R29 allgemeine Register, die durch einen Funktionsaufruf nicht verändert bzw wieder auf den ursprünglichen Wert restauriert werden. Wenn man jetzt aber globale Variablen hat, legt dieser sie in den SRAM. Wieso diese dann nicht in die unteren Register? Wann (außgenommen Funktionsparameterübergabe) werden diese jemals verwendet. Wie bekomme ich den Gcc dazu, diese zu verwenden. Ich verliere ungern unnötig 16 Register.

Ich hoffe Ihr könnt mir helfen.
Offline Benutzer-Profile anzeigen ICQ-Nummer
uwegw

Robotik Einstein
Robotik Einstein




Anmeldungsdatum: 06.02.2005
Beiträge: 4318
Wohnort: OWL
Alter: 23

germany.gif
Beitrag Verfasst am: 21.07.2007, 21:21 Antworten mit ZitatNach oben

Könnte damit zusammenhängen, dass die unteren Register nicht alles können, was die oberen können. Für diverse Operationen müsste man daher die Daten aus diesen Registern in eins der oberen Register kopieren und danach wieder zurück. Wahrscheinlich hat man auf die unteren Register verzichtet, um sich diesen Sonderfall zu sparen.
Offline Benutzer-Profile anzeigen
SprinterSB

Robotik Einstein
Robotik Einstein




Anmeldungsdatum: 09.06.2005
Beiträge: 2847
Wohnort: An der Saar

germany.gif
Beitrag Verfasst am: 21.07.2007, 22:53 Antworten mit ZitatNach oben

Was sich im GCC an der Registerallokierung von 3.x nach 4.x geändert hat, kann ich nicht sagen. jedenfalls hat sich das ABI geändert, d.h. die Register werden in der 4.x so verwendet wie in der 3.x.

Globale/Statische Variablen werden nie in Register allokiert, es sei denn, man definiert sich globale Registervariablen à la

int register var asm ("r2");

void foo (void)
{
    var >>= 1;
}


foo:
   asr r3    ;  var
   ror r2    ;  var
   ret    ;


Davon ist jedoch tunlichst abzuraten: Nehmen wir an, du verwendest so eine Variable in einer ISR und die IRQ trat in einer LIB-Funktion auf, die so ein Register verwendet. Dann hast du ein Problem...

Ich glaube nicht, daß du die LIBs komplett neu generieren willst und zwar so, daß GCC nirgends die o.g. regs verwendet (abgesehen davon, das Y den Framepionter hält).

Und selbst wenn du keine LIBs verwendest oder sie mit -ffixed= generiert bekommst, ist die Verwendung globaler Registervariablen anders als die globaler Variablen. Es gibt einige Nebeneffekte, die dir ruckzuck das Programm um die Ohren hauen.

GCC verwendet die unteren Register deshalb ungerne, weil die Register nicht alle gleichwertig sind. Es gibt für diese GPRs zB kein LDI und eine konstante in so ein GPR laden geht nur aufwändig über einen sekundären Reload (also über ein oberes GPR).

Die unteren Register werden verwendet, wenn deine Funktionen komplexer werden und wenn du Funktionen hast, die kein Blatt sind:
long long bar (long long a, long long b)
{
    return a+b;
}


bar:
/* 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) */
   mov r2,r18    ;  a, a
   mov r3,r19    ;  a, a
   mov r4,r20    ;  a, a
   mov r5,r21    ;  a, a
   mov r6,r22    ;  a, a
   mov r7,r23    ;  a, a
   mov r8,r24    ;  a, a
   mov r9,r25    ;  a, a
   mov r18,r10    ;  b, b
   mov r19,r11    ;  b, b
   mov r20,r12    ;  b, b
   mov r21,r13    ;  b, b
   mov r22,r14    ;  b, b
   mov r23,r15    ;  b, b
   mov r24,r16    ;  b, b
   mov r25,r17    ;  b, b
   mov r10,r2    ; ,
   add r10,r18    ; , b
   ldi r30,lo8(1)    ;  tmp46,
   cp r10,r2    ;  tmp45, a
   brlo .L3    ; ,
   ldi r30,lo8(0)    ;  tmp46,
.L3:
   mov r11,r3    ; ,
   add r11,r19    ; , b
   ldi r26,lo8(1)    ;  tmp47,
   cp r11,r3    ; , a
   brlo .L4    ; ,
   ldi r26,lo8(0)    ;  tmp47,
.L4:
   add r30,r11    ;  tmp48,
   ldi r31,lo8(1)    ;  tmp49,
   cp r30,r11    ;  tmp48,
   brlo .L5    ; ,
   ldi r31,lo8(0)    ;  tmp49,
.L5:
   or r26,r31    ;  tmp47, tmp49
   mov r11,r30    ; , tmp48
   mov r12,r4    ; ,
   add r12,r20    ; , b
   ldi r27,lo8(1)    ;  tmp50,
   cp r12,r4    ; , a
   brlo .L6    ; ,
   ldi r27,lo8(0)    ;  tmp50,
.L6:
   mov r30,r26    ;  tmp51, tmp47
   add r30,r12    ;  tmp51,
   ldi r31,lo8(1)    ;  tmp52,
   cp r30,r12    ;  tmp51,
   brlo .L7    ; ,
   ldi r31,lo8(0)    ;  tmp52,
.L7:
   or r27,r31    ;  tmp50, tmp52
   mov r12,r30    ; , tmp51
   mov r13,r5    ; ,
   add r13,r21    ; , b
   ldi r26,lo8(1)    ;  tmp53,
   cp r13,r5    ; , a
   brlo .L8    ; ,
   ldi r26,lo8(0)    ;  tmp53,
.L8:
   mov r30,r27    ;  tmp54, tmp50
   add r30,r13    ;  tmp54,
   ldi r31,lo8(1)    ;  tmp55,
   cp r30,r13    ;  tmp54,
   brlo .L9    ; ,
   ldi r31,lo8(0)    ;  tmp55,
.L9:
   or r26,r31    ;  tmp53, tmp55
   mov r13,r30    ; , tmp54
   mov r14,r6    ; ,
   add r14,r22    ; , b
   ldi r27,lo8(1)    ;  tmp56,
   cp r14,r6    ; , a
   brlo .L10    ; ,
   ldi r27,lo8(0)    ;  tmp56,
.L10:
   mov r30,r26    ;  tmp57, tmp53
   add r30,r14    ;  tmp57,
   ldi r31,lo8(1)    ;  tmp58,
   cp r30,r14    ;  tmp57,
   brlo .L11    ; ,
   ldi r31,lo8(0)    ;  tmp58,
.L11:
   or r27,r31    ;  tmp56, tmp58
   mov r14,r30    ; , tmp57
   mov r15,r7    ; ,
   add r15,r23    ; , b
   ldi r26,lo8(1)    ;  tmp59,
   cp r15,r7    ; , a
   brlo .L12    ; ,
   ldi r26,lo8(0)    ;  tmp59,
.L12:
   mov r30,r27    ;  tmp60, tmp56
   add r30,r15    ;  tmp60,
   ldi r31,lo8(1)    ;  tmp61,
   cp r30,r15    ;  tmp60,
   brlo .L13    ; ,
   ldi r31,lo8(0)    ;  tmp61,
.L13:
   or r26,r31    ;  tmp59, tmp61
   mov r15,r30    ; , tmp60
   mov r16,r8    ; ,
   add r16,r24    ; , b
   ldi r27,lo8(1)    ;  tmp62,
   cp r16,r8    ; , a
   brlo .L14    ; ,
   ldi r27,lo8(0)    ;  tmp62,
.L14:
   mov r31,r26    ;  tmp63, tmp59
   add r31,r16    ;  tmp63,
   ldi r30,lo8(1)    ;  tmp64,
   cp r31,r16    ;  tmp63,
   brlo .L15    ; ,
   ldi r30,lo8(0)    ;  tmp64,
.L15:
   or r30,r27    ;  tmp65, tmp62
   mov r17,r9    ; ,
   add r17,r25    ; , b
   add r30,r17    ;  tmp65,
   mov r18,r10    ;  <result>, <result>
   mov r19,r11    ; , <result>
   mov r20,r12    ; , <result>
   mov r21,r13    ; , <result>
   mov r22,r14    ; , <result>
   mov r23,r15    ; , <result>
   mov r24,r31    ; , <result>
   mov r25,r30    ; , tmp65
/* 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


Anm: Der Code ist trotz -Os nicht optimal, weil wenig AUfwand in 64-Bit-Typen gesteckt wurde und GCC die Addition algebraisch austextet.

Das Beispiel zeigt aber, daß GCC durchaus diese Register verwendet.

ZU R1: GCC geht davon aus, daß da die 0 drin steht.

_________________
Gruß, Georg-Johann

Computer sind Maschinen, mit denen man Probleme lösen kann, die es ohne sie nicht gäbe.

http://www.gjlay.de
Offline Benutzer-Profile anzeigen Website dieses Benutzers besuchen
SprinterSB

Robotik Einstein
Robotik Einstein




Anmeldungsdatum: 09.06.2005
Beiträge: 2847
Wohnort: An der Saar

germany.gif
Beitrag Verfasst am: 21.07.2007, 22:54 Antworten mit ZitatNach oben

typo: das ABI hat sich natürlich *nicht* geändert!

_________________
Gruß, Georg-Johann

Computer sind Maschinen, mit denen man Probleme lösen kann, die es ohne sie nicht gäbe.

http://www.gjlay.de
Offline Benutzer-Profile anzeigen Website dieses Benutzers besuchen
s.o.

Roboter Experte
Roboter Experte




Anmeldungsdatum: 08.07.2006
Beiträge: 442
Wohnort: Karlsruhe
Alter: 19

germany.gif
Beitrag Verfasst am: 22.07.2007, 20:15 Antworten mit ZitatNach oben

Vielen Dank Sprinter für deine ausfürliche Antwort.

Ich habe noch eine Frage: Da der Gcc4 die unteren Register R2-R17 ja nicht zum Variablenspeichern verwendet, wieso Pushed und Popped(nicht falsch verstehen Zwinkern ) er das dann? Das ist doch Zeit und Resourcenverschwendung?

Grüße
Offline Benutzer-Profile anzeigen ICQ-Nummer
SprinterSB

Robotik Einstein
Robotik Einstein




Anmeldungsdatum: 09.06.2005
Beiträge: 2847
Wohnort: An der Saar

germany.gif
Beitrag Verfasst am: 22.07.2007, 21:13 Antworten mit ZitatNach oben

Ich glaub, da herrscht etwas Verwirrung...

Variablen (d.gh allgemeiner Objekte im Sinne von C) haben einen Speicherort. Globale und statische Variablen leben zB üblicherweise im SRAM (auch möglich sind Flash und EEPROM).

Zur Verarbeitung muss ein Compiler einen Werte von dem Ort, wo er "lebt", in ein Register (GPR) laden, um die gewünschten Operationen damit anzustellen. Das ist notwendig, weil kaum eine Architektur Verarbeitung direkt im RAM erlaubt. AVR zB erlaubt nur Lesen/Schreiben von Werten und das Testen von Bits im bit-adressierbaren SFR-Bereich.

Wird nun eine solche Variable gebraucht, dann muss sie also geladen werden, zB nach R25:R24 für eine 16-Bit-Variable.

Wird nach dem Laden eine Funktion ausgeführt, dann muss avr-gcc den Wert in ein Register sichern, das nicht von der Funktion verändert wird, zB R17:R16. Braucht die aufgerufene Funktion ihrerseits zB R17, muss es gesichert werden, weil der Aufrufer davon ausgeht.

Diese Variablen werden nicht in GPRs angelegt (leben also nicht dort), werden aber evtl durchaus dort hinkopiert.

Lokale Variablen (genauer: automatische Variablen) werden von GCC in GPRs oder im Frame der Funktion angelegt, falls sie nicht wegoptimiert werden.

long foo (long i)
{
    if (i)
        return foo (i)+i;
       
    return i;
}

foo:
/* prologue: frame size=0 */
   push r14
   push r15
   push r16
   push r17
/* prologue end (size=4) */
   movw r14,r22    ;  i, i
   movw r16,r24    ;  i, i
   cp r22,__zero_reg__    ;  i
   cpc r23,__zero_reg__    ;  i
   cpc r24,__zero_reg__    ;  i
   cpc r25,__zero_reg__    ;  i
   breq .L2    ; ,
   rcall foo    ;
   add r22,r14    ;  <result>, i
   adc r23,r15    ;  <result>, i
   adc r24,r16    ;  <result>, i
   adc r25,r17    ;  <result>, i
   rjmp .L1    ;
.L2:
.L1:
/* epilogue: frame size=0 */
   pop r17
   pop r16
   pop r15
   pop r14
   ret


Mal abgesehen davon, daß das Beispielprogramm recht sinnlos ist: GCC macht hier guten Code und das Sichern der Register (i in R22-R25 nach R14-R17) um den Aufruf von foo ist nicht überflüssig.

Hast du ein konkretes, überschaubares Beispiel da, von dem du denkst, daß GCC schlecht arbeitet? Vielleicht kann man daran diskutieren, was abgeht.

Übersetzen am besten mit -O2 oder -Os zusammen mit -S und -fverbose-asm.

_________________
Gruß, Georg-Johann

Computer sind Maschinen, mit denen man Probleme lösen kann, die es ohne sie nicht gäbe.

http://www.gjlay.de
Offline Benutzer-Profile anzeigen Website dieses Benutzers besuchen
s.o.

Roboter Experte
Roboter Experte




Anmeldungsdatum: 08.07.2006
Beiträge: 442
Wohnort: Karlsruhe
Alter: 19

germany.gif
Beitrag Verfasst am: 23.07.2007, 06:42 Antworten mit ZitatNach oben

Hallo Sprinter.

Danke für die ausfürliche Antwort.

Zu deinem Bsp.
Wieso muss Gcc diese sichern? Das ganze geht ja auch ohne das sichern. Es geht doch auch add R22,R22 ?

Ich habe mal ein Beispiel, bei dem der Gcc (für mich) unverständlich viel Pushed.

long foo(long a, long b, long c, uint8_t d){
  if(d){
    return a+b;
  }else{
    return a-c;
  }
}

Nun das Listing:

long foo(long a, long b, long c, uint8_t d){
  4e:   cf 92          push   r12 ;Alle unteren Register werden gepushed
  50:   ef 92          push   r14 ;obwohl sie nicht verändert werden
  52:   ff 92          push   r15 ;
  54:   0f 93          push   r16
  56:   1f 93          push   r17
  if(d){
  58:   cc 20          and   r12, r12
  5a:   29 f0          breq   .+10        ; 0x66 <foo+0x18>
    return a+b;
  5c:   62 0f          add   r22, r18
  5e:   73 1f          adc   r23, r19
  60:   84 1f          adc   r24, r20
  62:   95 1f          adc   r25, r21
  64:   04 c0          rjmp   .+8         ; 0x6e <foo+0x20>
  }else{
    return a-c;
  66:   6e 19          sub   r22, r14
  68:   7f 09          sbc   r23, r15
  6a:   80 0b          sbc   r24, r16
  6c:   91 0b          sbc   r25, r17
  6e:   1f 91          pop   r17 ;und wieder restaurieren, obwohl sie
  70:   0f 91          pop   r16 ;unberührt sind...
  72:   ff 90          pop   r15
  74:   ef 90          pop   r14
  76:   cf 90          pop   r12
  78:   08 95          ret


Gcc ist jedoch, obwohl er diese Eigenheit hat. einer der besten Compiler. Recursive funktionen macht er z.T. auch ohne Pushen. Sofern halt wieder die unteren Register nicht berührt werden.

Mir ist bewust, dass Gcc die unteren Register nur zum Teil verwenden kann. Das ist doch aber kein Grund, diese zu Pushen, obwohl die nicht verändert werden. Kann man das dem Gcc irgendwie abgewöhnen?

Grüße
Offline Benutzer-Profile anzeigen ICQ-Nummer
SprinterSB

Robotik Einstein
Robotik Einstein




Anmeldungsdatum: 09.06.2005
Beiträge: 2847
Wohnort: An der Saar

germany.gif
Beitrag Verfasst am: 23.07.2007, 08:48 Antworten mit ZitatNach oben

Ja, hier werden die Register unnötigerweise gesichert, weil sie nicht verändert werden.

IMHO ist das eine Unzulänglichkeit in GCC (also nicht nur in avr-gcc).

Ich kann die erläutern, wo das Problem herkommt, und wo du es fixen kannst:

Du übersetzt mit -da -dp -save-temps. Das erzeugt dir zig RTL (register transfer language) dumps.
Einer der komplexesten Teile von GCC (und vieler anderer optimierender Compiler) ist die Register-Allokierung. In diesen Passes werden die unendlich vielen Pseudo-Register, in denen die Werte gehalten werden, auf die endlich vielen Hard-Register der Maschine abgebildet. Falls die Hard-Register nicht ausreichen, landen die Werte in Stack-Slots und müssen zur Verabreitung vom Stack geladen werden, wofür dann wieder andere Hard-Register frei geschaufelt werden müssen, etc.

In Pass lreg (local register allocation = reg-alloc innerhalb von basic blocks) ist noch alles ok, zB
(insn 5 4 6 0 (set (reg/v:SI 44 [ c ])
        (reg:SI 14 r14 [ c ])) 14 {*movsi} (nil)
    (expr_list:REG_DEAD (reg:SI 14 r14 [ c ])
        (nil)))


(reg 44) ist ein SI-Pseudo (also 32-Bit) und wird geladen vom SI-Hard-Reg 14, einem incoming arg (=c) von foo. In dieser insn stirbt R14 (also R14...R17), weil es jetzt ja in R44 steht. Ich vereinfache mal das insn-Pattern auf das Wesentliche:

(set (reg:SI 44)
     (reg:SI 14))


In Pass greg+postreload (global register allocation) wird daraus
(set (reg:SI 14)
     (reg:SI 14))

d.h. GCC allokiert R44 nach R14 (eine gute Wahl) und in flow2 wird erkannt, daß insn 5 trivial ist und weggeworfen. Allerdings lebt R14 weiterhin, weil es ja verwendet wird (wenn auch nirgends explizit gesetzt wird).

In ./gcc/config/avr/avr.c:function_prologue() und :function_epilogue() wird der asm-Code für Funktions-Prolog und -Epilog ausgegeben, der sich u.a. darum kümmert, Regs die leben *und* call save sind (als nach einer Funktion unverändert vorliegen) zu sichern, d.h. dort werden die überflüssigen push/pop emittiert.

Die Info, ob ein (pseudo oder hard) Reg lebt, wird in regs_ever_live[] gemerkt. Und dort steht eben nur, ob ein Reg lebt, aber nicht, ob es verändert wird oder nicht.

Idea Um den Code zu verbessern, müsste man also an dieser Stelle nicht auf regs_ever_live[] testen, sondern eine neue live analysis durchführen und testen, ob für diese Register REG_N_SETS() gleich Null ist und einen neuen avr-gcc generieren (bzw ein neuer cc1, das reicht schon). Möglicherweise sieht GCC bzw. die zu REG_N_SETS() betragenden Funktionen in ./gcc/regclass.c, daß R14 zu den virtual-incoming-args Registern gehört, und zählen es zu den gesetzten Registern hinzu.

Falls du an GCC nicht selbst Hand anlegen willst, kannst du bei http://gcc.gnu.org eine feature-request machen und bei der GCC 4.3 hast du schon besseren Code. (AFAIK ist momentan jedoch Konsolidierung und ein feature freeze).

_________________
Gruß, Georg-Johann

Computer sind Maschinen, mit denen man Probleme lösen kann, die es ohne sie nicht gäbe.

http://www.gjlay.de
Offline Benutzer-Profile anzeigen Website dieses Benutzers besuchen
s.o.

Roboter Experte
Roboter Experte




Anmeldungsdatum: 08.07.2006
Beiträge: 442
Wohnort: Karlsruhe
Alter: 19

germany.gif
Beitrag Verfasst am: 23.07.2007, 20:07 Antworten mit ZitatNach oben

Hallo Sprinter.

Ich traue es mir nicht zu, im Gcc zumzufummeln. Da habe ich zu wenig Erfahrung dazu. Ich mag mich zwar etwas auszennen, aber das ist doch dann zu kompliziert.

Ich werde wohl bei Gcc einen features-request einreichen, und hoffen das die Verstehen, was ich meine.^^

Vielen Dank für deine Hilfe.
Offline Benutzer-Profile anzeigen ICQ-Nummer
SprinterSB

Robotik Einstein
Robotik Einstein




Anmeldungsdatum: 09.06.2005
Beiträge: 2847
Wohnort: An der Saar

germany.gif
Beitrag Verfasst am: 28.07.2007, 18:12 Antworten mit ZitatNach oben

Falls es nur wenige, zeitkritische Funktionen sind, um die es geht, bleiben noch folgende Möglichkeiten, ohne GCC anzufassen:

-- Funktion(en) unter Beachtung des avr-ABI in Assembler / Inline Assembler formulieren. Ob ne Stub zusammen mit Inline Asm hilft, müsste man testen (da besteht uU das Problem weiterhin).
-- Funktion(en) inlinen, zb mit "inline" oder "__attribute__((always_inline))"

_________________
Gruß, Georg-Johann

Computer sind Maschinen, mit denen man Probleme lösen kann, die es ohne sie nicht gäbe.

http://www.gjlay.de
Offline Benutzer-Profile anzeigen Website dieses Benutzers besuchen
s.o.

Roboter Experte
Roboter Experte




Anmeldungsdatum: 08.07.2006
Beiträge: 442
Wohnort: Karlsruhe
Alter: 19

germany.gif
Beitrag Verfasst am: 29.07.2007, 05:45 Antworten mit ZitatNach oben

Hallo Sprinter,

das mit dem I-ASM ist eine gute Idee für zeitkritische Funktionen.

Der Gcc Bug Report:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32871

Wo Du gerade das Attribute always_inline ansprichst. Angenommen, man hat eie Funktion, die immer geinlined wird. Dann ist aber immer noch die Funktion im Listing an sich da, wieso löscht der Avr-Gcc die dann nicht?

Grüße
Offline Benutzer-Profile anzeigen ICQ-Nummer
SprinterSB

Robotik Einstein
Robotik Einstein




Anmeldungsdatum: 09.06.2005
Beiträge: 2847
Wohnort: An der Saar

germany.gif
Beitrag Verfasst am: 29.07.2007, 10:25 Antworten mit ZitatNach oben

Die Funktion muss ja da bleiben, weil es vielleicht eine externe Referenz auf die Funktion gibt. Hier hilft's, die Funktion als static zu geklarieren. Aber selbst dann kann die Funktion noch gebraucht werden, zB wenn ihre Adresse genommen wird.

Dann gibt's noch die hilfreichen Schalter -Winline -fno-keep-inline-functions (für -fxxx gibt's immer auch -fno-xxx)

Weitere Rädchen zum Feinjustieren siehst du mit

avr-gcc -v --help | grep inline


Aber aufpassen: grep filtert nur nach "inline". Evtl sind die Options nur für C++. Dann das komplette avr-gcc -v --help lesen...

_________________
Gruß, Georg-Johann

Computer sind Maschinen, mit denen man Probleme lösen kann, die es ohne sie nicht gäbe.

http://www.gjlay.de
Offline Benutzer-Profile anzeigen Website dieses Benutzers besuchen
SprinterSB

Robotik Einstein
Robotik Einstein




Anmeldungsdatum: 09.06.2005
Beiträge: 2847
Wohnort: An der Saar

germany.gif
Beitrag Verfasst am: 29.07.2007, 10:34 Antworten mit ZitatNach oben

Zum bugreport bei gcc.gnu.org:

Häng da noch die Precompilierte Quelle (also wo alle #includes etc aufgelöst sind) dran, und wie du die Datei erhalten hast!

Sonst kann man das niemals nachvollziehen!


long foo (long a, long b, long c, unsigned char d){
  if(d){
    return a+b;
  }else{
    return a-c;
  }
}



d:\avr\test>avr-gcc blah.c -Os -S -v -fverbose-asm
Reading specs from E:/WinAVR_20060421/lib/gcc/avr/3.4.6/specs
Configured with: ../gcc-3.4.6/configure --prefix=/c/WinAVR --target=avr --enable
=c,c++ --with-dwarf2 --enable-win32-registry=WinAVR --disable-nls
Thread model: single
gcc version 3.4.6
 E:/WinAVR_20060421/libexec/gcc/avr/3.4.6/cc1.exe -quiet -v -iprefix e:\WinAVR_2
n/../lib/gcc/avr/3.4.6/ blah.c -quiet -dumpbase blah.c -auxbase blah -Os -versio
e-asm -o blah.s
ignoring nonexistent directory "E:/WinAVR_20060421/avr/sys-include"
#include "..." search starts here:
#include <...> search starts here:
 e:\WinAVR_20060421\bin/../lib/gcc/avr/3.4.6/include
 E:/WinAVR_20060421/lib/gcc/avr/3.4.6/include
 E:/WinAVR_20060421/avr/include
End of search list.
GNU C version 3.4.6 (avr)
        compiled by GNU C version 3.4.2 (mingw-special).
GGC heuristics: --param ggc-min-expand=47 --param ggc-min-heapsize=32702


blah.s:
   .file   "blah.c"
   .arch avr2
__SREG__ = 0x3f
__SP_H__ = 0x3e
__SP_L__ = 0x3d
__tmp_reg__ = 0
__zero_reg__ = 1
   .global __do_copy_data
   .global __do_clear_bss
 ;  GNU C version 3.4.6 (avr)
 ;    compiled by GNU C version 3.4.2 (mingw-special).
 ;  GGC heuristics: --param ggc-min-expand=47 --param ggc-min-heapsize=32702
 ;  options passed:  -v -iprefix -auxbase -Os -fverbose-asm
 ;  options enabled:  -feliminate-unused-debug-types -fdefer-pop
 ;  -fomit-frame-pointer -foptimize-sibling-calls -funit-at-a-time
 ;  -fcse-follow-jumps -fcse-skip-blocks -fexpensive-optimizations
 ;  -fthread-jumps -fstrength-reduce -fpeephole -fforce-mem -ffunction-cse
 ;  -fkeep-static-consts -fcaller-saves -freg-struct-return -fgcse
 ;  -fgcse-lm -fgcse-sm -fgcse-las -floop-optimize -fcrossjumping
 ;  -fif-conversion -fif-conversion2 -frerun-cse-after-loop
 ;  -frerun-loop-opt -fdelete-null-pointer-checks -fsched-interblock
 ;  -fsched-spec -fsched-stalled-insns -fsched-stalled-insns-dep
 ;  -fbranch-count-reg -freorder-functions -fcprop-registers -fcommon
 ;  -fverbose-asm -fregmove -foptimize-register-move -fargument-alias
 ;  -fstrict-aliasing -fmerge-constants -fzero-initialized-in-bss -fident
 ;  -fpeephole2 -fguess-branch-probability -fmath-errno -ftrapping-math
 ;  -minit-stack=__stack -mmcu=avr2

   .text
.global   foo
   .type   foo, @function
foo:
/* prologue: frame size=0 */
   push r12
   push r14
   push r15
   push r16
   push r17
   push r28
   push r29
/* prologue end (size=7) */
   mov r29,r25    ;  a, a
   mov r28,r24    ;  a, a
   mov r27,r23    ;  a, a
   mov r26,r22    ;  a, a
   tst r12    ;  d
   breq .L2    ; ,
   mov r22,r26    ;  <result>, a
   mov r23,r27    ;  <result>, a
   mov r24,r28    ;  <result>, a
   mov r25,r29    ;  <result>, a
   add r22,r18    ;  <result>, b
   adc r23,r19    ;  <result>, b
   adc r24,r20    ;  <result>, b
   adc r25,r21    ;  <result>, b
   rjmp .L1    ;
.L2:
   mov r22,r26    ;  <result>, a
   mov r23,r27    ;  <result>, a
   mov r24,r28    ;  <result>, a
   mov r25,r29    ;  <result>, a
   sub r22,r14    ;  <result>, c
   sbc r23,r15    ;  <result>, c
   sbc r24,r16    ;  <result>, c
   sbc r25,r17    ;  <result>, c
.L1:
/* epilogue: frame size=0 */
   pop r29
   pop r28
   pop r17
   pop r16
   pop r15
   pop r14
   pop r12
   ret
/* epilogue end (size=8) */
/* function foo size 38 (23) */
   .size   foo, .-foo
/* File "blah.c": code   38 = 0x0026 (  23), prologues   7, epilogues   8 */

_________________
Gruß, Georg-Johann

Computer sind Maschinen, mit denen man Probleme lösen kann, die es ohne sie nicht gäbe.

http://www.gjlay.de
Offline Benutzer-Profile anzeigen Website dieses Benutzers besuchen
s.o.

Roboter Experte
Roboter Experte




Anmeldungsdatum: 08.07.2006
Beiträge: 442
Wohnort: Karlsruhe
Alter: 19

germany.gif
Beitrag Verfasst am: 29.07.2007, 17:13 Antworten mit ZitatNach oben

Hallo Sprinter,

ich habe den Bugreport erweitert. Vielen Dank für Deinen Hinweis!

Michael
Offline Benutzer-Profile anzeigen ICQ-Nummer
Beiträge vom vorherigen Thema anzeigen:      
Neues Thema eröffnenNeue Antwort erstellen
Vorheriges Thema anzeigen Dieses Thema einem Freund schickenZeige Benutzer, die dieses Thema gesehen habenDieses Thema als Textdatei speichernPrintable versionlog in, Nachrichten zu lesen Nächstes Thema anzeigen



 Gehe zu:   



Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.
Du kannst Dateien in diesem Forum nicht posten
Du kannst Dateien in diesem Forum nicht herunterladen




Die große Community für Robotik-, Mikrocontroller- und Elektronik Bastler als auch Experten
 Roboternetz RSS2.0 News Feed
Alle Zeiten sind GMT + 1 Stunde