AVR-GCC 16Bit-Lastigkeit nervt

OP #2830009
Lesenswert?

Warum hängt der AVR-GCC so an 16Bit bei 8Bit Berechnungen?
1
void test()
2
{
3
  if( PINB & (1<<PB0 | 1<<PB1) )
4
  80:   83 b1           in      r24, 0x03       ; 3
5
  82:   90 e0           ldi     r25, 0x00       ; 0
6
  84:   83 70           andi    r24, 0x03       ; 3
7
  86:   90 70           andi    r25, 0x00       ; 0
8
  88:   89 2b           or      r24, r25
9
  8a:   09 f0           breq    .+2             ; 0x8e <test+0xe>
10
    PORTB = 0;
11
  8c:   15 b8           out     0x05, r1        ; 5
12
  8e:   08 95           ret

Statt 6 Byte kostet der Vergleich 12 Byte (= 200%).
Aber nur, wenn der Test auch Bit 0 enthällt.
1
void test2()
2
{
3
  if( PINB & (1<<PB1 | 1<<PB2) )
4
  90:   83 b1           in      r24, 0x03       ; 3
5
  92:   86 70           andi    r24, 0x06       ; 6
6
  94:   09 f0           breq    .+2             ; 0x98 <test2+0x8>
7
    PORTB = 0;
8
  96:   15 b8           out     0x05, r1        ; 5
9
  98:   08 95           ret

Ich benutze WINAVR 2010.


Peter
OP #2830084
Lesenswert?

Das ist funktional völlig anderer Code, es müssen 2 Zugriffe 
nacheinander auf PINB gemacht werden. Und dazwischen könnte ein 
Interrupt kommen, d.h. dann sind viele µs Unterschied, statt 
gleichzeitig.

Das PINB ist nur als Beispiel gemeint. Es kann auch ein IO-Register im 
RAM-Space sein (>0x0100).



Peter
Moderator Persönliche Seite #2830116
Lesenswert?

Peter Dannegger schrieb:
> Statt 6 Byte kostet der Vergleich 12 Byte (= 200%).

Kann ich bei mir nachvollziehen.

> Aber nur, wenn der Test auch Bit 0 enthällt.

Stimmt nicht, benutze mal

    if( PINB & (1<<PB0 | 1<<PB2))

Hier wird wieder die kurze Variante vom Compiler gewählt.

> Ich benutze WINAVR 2010.

Ich normalerweise auch, konnte aber das Problem sogar mit 
WinAVR-20090313 nachstellen.

EDIT:
Das Problem scheint nur in der Kombination PB0 und PB1, also (PINB & 
3), aufzutreten. Ich habe keine andere hinbekommen.
OP #2830192
Lesenswert?

Frank M. schrieb:
> Das Problem scheint nur in der Kombination PB0 und PB1, also (PINB &
> 3), aufzutreten. Ich habe keine andere hinbekommen.

Also bei geht alles von Bit 0 aufsteigend, also Maske 3, 7, 15, 31, 63, 
127.
Mit Lücke oder ohne Bit 0 wirds kurz.

Hier mal die Funktion, wo es mir aufgefallen ist:
1
void sleep()
2
{
3
  cli();
4
  if( !(ASSR & (1<<TCN2UB | 1<<OCR2AUB | 1<<OCR2BUB | 1<<TCR2AUB | 1<<TCR2BUB)))
5
  {
6
    sei();
7
    sleep_cpu();
8
    return;
9
  }
10
  sei();
11
}

Frank M. schrieb:
> Vielleicht solltest Du doch mal auf einen neueren Compiler wechseln ;-)

Ist die zu empfehlen:

avr-gcc-4.7.1-rc1-mingw32.zip


Peter
OP #2830303
Lesenswert?

Jörg Wunsch schrieb:
> Peter Dannegger schrieb:
>> avr-gcc-4.7.1-rc1-mingw32.zip
>
> Da 4.7.1 bereits released ist, würde ich keinen RC ("release
> candidate") mehr nehmen.

Diesen Link habe ich in AVR Freaks "avr-gcc 4.7.0 for the brave" 
gefunden:

http://sourceforge.net/projects/mobilechessboar/files/avr-gcc%20snapshots%20%28Win32%29/

Hast Du nen Link ohne RC?

Irgendwie fehlt ja nach WINAVR 2010 ne offizielle Anlaufstelle für neue 
Versionen zum Downloaden.


Peter
Persönliche Seite #2830448
Lesenswert?

Jörg Wunsch schrieb:
> Peter Dannegger schrieb:
>> avr-gcc-4.7.1-rc1-mingw32.zip
>
> Da 4.7.1 bereits released ist, würde ich keinen RC ("release
> candidate") mehr nehmen.

Wobei diese RC1 Bugfixes anthält, die in der offiziellen 4.7.1 nicht 
enthalten sind  ;-)

Siehe die Patches in ./source

GCC:
 http://gcc.gnu.org/PR53595

Binutils:
 http://sourceware.org/PR13899
 http://sourceware.org/PR14058


Jörg Wunsch schrieb:

> Nein, ich bau' mir meine Compiler ohnehin immer selbst. ;-)
> 's ist ja keine Raketenwissenschaft, das zu tun.

>> "Come on, Rory. It's not rocket science. It's just quantum physics."
Moderator Persönliche Seite #2832632
Lesenswert?

Adib schrieb:
> dass bit operationen im C als int
> behandelt werden.

Der C-Standard ist ein "als wäre"-Standard: die Operationen müssen
sich so verhalten, als wären sie als "int" behandelt worden.  Wenn
aber das obere Byte zum Ergebnis nichts beiträgt, steht es dem
Compiler sehr wohl frei, nur das niederwertige Byte überhaupt
ausrechnen zu lassen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren