Forum: Compiler & IDEs Präprozessor Optionen WinARM GCC


von Lokko (Gast)


Lesenswert?

Ich hab immer gedacht der Präprozessor würde so Geschichten wie diese
"brechnen"

Wenn ich diese defines

#define FLASH_AT91C_MC_CORRECT_KEY  ((unsigned int) 0x5A << 24)
#define AT91C_MC_FCMD_UNLOCK        ((unsigned int) 0x4)

in dieser Funktion benutzte

char RAMFUNC flash_UnlockPage(unsigned int pagenum){
  if(pagenum >= FLASH_PAGE_NB) return FLASH_PROGE;
  flash_ReadyWait();
--->>>>flash_AT91F_MC_EFC_PerformCmd(AT91C_BASE_MC,((pagenum)<<8)|(FLASH 
_AT91C_MC_CORRECT_KEY|AT91C_MC_FCMD_UNLOCK));
  flash_ReadyWait();
  return flash_GetError();
}

gehe ich davon aus, dass er mir FLASH_AT91C_MC_CORRECT_KEY und
AT91C_MC_FCMD_UNLOCK zusammenfasst... oder liege ich da falsch!??!

Der erzeugt Assembler code an der stelle sieht aber so aus

 293        mov  r3, r0, asl #8
 294        orr  r3, r3, #1509949440
 295        orr  r3, r3, #4

#1509949440 ist übrigends 0x5A << 24

In der gcc hilfe hab ich nix dazugefunden.

Achja diesen COde macht er mir bei Optimierungsstufe 2,3 und s

Bei Stufe 1 macht er jenes

 160 mov  r3, #1509949440
 161 add  r3, r3, #4
 162 orr  r3, r3, r0, asl #8

Mach ich da was falsch oder besteht da Optimierungsbedarf am gcc ?? Ist
ja eigentlich Standard solche Konstrukte zu verwenden.

hier noch die version

arm-elf-gcc (GCC) 4.0.2 (WinARM)

und die Parameter

Compiling C: flash.c
arm-elf-gcc -c  -mcpu=arm7tdmi  -I. -gstabs -DROM_RUN  -Os -Wall
-Wcast-align -Wimplicit  -Wpointer-arith -Wswitch -Wredundant-decls
-Wreturn-type -Wshadow -Wunused -Wa,-adhlns=flash.lst   -MD -MP -MF
.dep/flash.o.d -Wnested-externs  -std=gnu99 flash.c -o flash.o

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Nein, der Präprozessor ersetzt nur, stur.

Es wäre der Compiler, der solcher Art Ausdrücke zusammenfassen
sollte. Keine Ahnung, wie gut der ARM-Port des GCC in Schuss
ist.  Vielleicht kann ja Martin hier was dazu sagen.

von Μαtthias W. (matthias) Benutzerseite


Lesenswert?

Hi

darf ich auch was dazu sagen? ;-)
Das dürfte eher daran liegen das der ARM keine beliebigen 32 Bit
Konstanten mit einem Befehl laden kann. Es sind nur 8 Bit-Konstanten
möglich die allerdings noch zusätzlich durch den Barrel-Shifter gehen
also um eine beliebige Anzahl Stellen rotiert werden können.

Alternativ kann man 32 Bit Konstanten über den Literal Pool laden was
aber in dieser Sitution unklug wäre da es keinen Code einspart aber
einen Zugriff außerhalb des aktuellen Code-Pfads benötigen würde was
bei einem Prozessor mit Pipeline und/oder Cache nicht wirklich optimal
ist.

Matthias

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Sowas in der Art hatte ich mir schon fast gedacht. ;-)

von Lokko (Gast)


Lesenswert?

MOMENT... :) ich möchte das verstehen

wenn ich dich richtig verstanden habe, dann läd der ARM im Prinzip bei
0x5A000000 nur 0x5A und shiftet die beim Laden.

bei 0x5A020000 würde er 0x5A laden und shiften und dann 0x02 und
shiften?

Ok das mit dem Pipelining hört sich auch logisch an.

von Μαtthias W. (matthias) Benutzerseite


Lesenswert?

Hi

So in etwa. Im Opcode wird die Konstante 0x5A codiert. Zusätzlich steht
im Opcode "um 24 Bits nach links shiften". Er lädt also die Konstante,
shiftet sie um 24 Bits nach links und schreibt das Ergebnis in das
angegebene Register. Und das alles in einem Takt.

Ob die Konstanten aber wirklich 8 Bit haben, da bin ich mir nicht
absolut sicher. Könnten auch 10 Bit sein.

Matthias

von Lokko (Gast)


Lesenswert?

Hi

DANK DIR!

Habs verstanden :)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.