Forum: Compiler & IDEs Optimierung bei AVR-GCC 3.3


von Hermann Kraus (Gast)


Lesenswert?

Hallo!

Ich habe mal ne Frage zur Optimierung von AVR-GCC 3.3 20021209:
Es geht dabei um eine Funktion zur Ansteuerung eines LCDs. Dabei wurde 
immer nur ein Befehl umgeschrieben, die Funktion blieb aber gleich und 
trotzdem gab's große Codeunterschiede.
Der Code der Funktion(am besten optimiert):
#define DB_SHIFT=2
void lcd_send(unsigned char data, unsigned char ormask)
{
  unsigned char tmp;   ////////////////////
  tmp=data&0xF0;           // Um diese vier  //
  tmp>>=4-DB_SHIFT;   // Zeilen geht es //
  LCD_PORT=tmp | ormask;   ////////////////////
  lcd_enable();
  LCD_PORT=((data & 0x0F)<<DB_SHIFT) | ormask;
  lcd_enable();
  lcd_wait_20us(10);
}
und das zugehörige Assemblerlisting:
 216 0050 0F93          push r16
 217 0052 1F93          push r17
 219 0054 082F          mov r16,r24
 220 0056 162F          mov r17,r22
  41:lcd.c         ****   unsigned char tmp;
  42:lcd.c         ****   tmp=data&0xF0;
 224 0058 807F          andi r24,lo8(-16)
  43:lcd.c         ****   tmp>>=4-DB_SHIFT;
 227 005a 8695          lsr r24
 228 005c 8695          lsr r24
  44:lcd.c         ****   LCD_PORT=tmp     | ormask;
 231 005e 862B          or r24,r22
 232 0060 85BB          out 53-0x20,r24
Besser hätte ich es auch nicht machen gekonnt.


Aber wenn ich den Befehl verkürze:
tmp=(data&0xF0)>>(4-DB_SHIFT);
Bekomm ich aber einen um 8Byte großeren Code:
 216 0050 FF92          push r15
 217 0052 0F93          push r16
 218 0054 1F93          push r17
 220 0056 F62E          mov r15,r22
  41:lcd.c         ****   unsigned char tmp;
  42:lcd.c         ****   tmp=(data&0xF0)>>(4-DB_SHIFT);
 224 0058 082F          mov r16,r24
 225 005a 1127          clr r17
 226 005c C801          movw r24,r16
 227 005e 9695          lsr r25
 228 0060 8795          ror r24
 229 0062 9695          lsr r25
 230 0064 8795          ror r24
 231 0066 8C73          andi r24,lo8(60)
  43:lcd.c         ****   LCD_PORT=tmp     | ormask;
 234 0068 862B          or r24,r22
 235 006a 85BB          out 53-0x20,r24

Genausoschlimm ist folgender Befehl:
LCD_PORT=((data>>4)<<DB_SHIFT)     | ormask;
 216 0050 0F93          push r16
 217 0052 1F93          push r17
 219 0054 082F          mov r16,r24
 220 0056 162F          mov r17,r22
  46:lcd.c         ****   LCD_PORT=((data>>4)<<DB_SHIFT)     | ormask;
 223 0058 8295          swap r24
 224 005a 8F70          andi r24,0x0f
 225 005c 9927          clr r25
 226 005e 880F          lsl r24
 227 0060 991F          rol r25
 228 0062 880F          lsl r24
 229 0064 991F          rol r25
 230 0066 862B          or r24,r22
 231 0068 85BB          out 53-0x20,r24
  47:lcd.c         ****   lcd_enable();
 234 006a 0E94 0000     call lcd_enable
  48:lcd.c         ****   LCD_PORT=((data & 0x0F)<<DB_SHIFT) | ormask;
 237 006e 802F          mov r24,r16
 238 0070 9927          clr r25
Was mir hier besonders negativ auffällt ist die Tatsache das immer 
wieder(225,227,229) mir r25 gearbeitet wird, dieses Register aber in 238 
gelöscht wird ohne das der darin stehende Wert jemals benutzt worden 
wäre.

Kann mir vielleicht mal jemand erklären an welche Regeln ich mich halten 
muss, damit der Compiler effektiven Code produziert.

von Joerg Wunsch (Gast)


Lesenswert?


von Joerg Wunsch (Gast)


Lesenswert?

OK, nicht exakt, aber den Weg hast Du ja schon gefunden.
Alternativ müßte es auch mit passenden typecasts gehen.

von Hermann Kraus (Gast)


Lesenswert?

Das in der FAQ hatte ich schon gelesen. Aber das kann ja wohl kaum der 
Grund sein. Wenn ich den Befehl auf mehrere Zeilen aufteile bekomme ich 
ja einen kleinen Code. Nur wenn ich alles in eine Zeile schreibe ist das 
Problem da.

Herman

von Joerg Wunsch (Gast)


Lesenswert?

Du bekommst den Code mit entsprechenden Casts auch in einer
Zeile gebacken.  Die Zwischenvariable (die vom Typ unsigned char
ist) spart Dir allerdings den Cast.  Da sie ansonsten sowieso
wegoptimiert wird und der Code durch diese übersichtlicher
wird als mit all der andernfalls notwendigen Casterei, warum
läßt Du es dann nicht einfach so?

Du kannst den Compiler ja mal spaßeshalber mit -mint8 aufrufen,
dann sollte er das auch alles nicht brauchen.  Allerdings ist
die Library damit nicht kompatibel.

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.