Vergleich wird 16-bittig ausgeführt (avr-gcc)

Gast #4761224
Lesenswert?

Professor: ATtiny2313
avr-gcc: (AVR_8_bit_GNU_Toolchain_3.4.2_939) 4.7.2

Ich habe eine Frage an die C-Gurus, und zwar habe ich folgendes 
"Problem".
Wie man im Assembler-Listing sehen kann, übersetzt avr-gcc diesen 
Vergleich 16-bittig.
Warum ist das so und kann man es abstellen?
1
if( statusbyte.rc5_bit ^ ((RC5_INP & RC5_PIN) ? 1 : 0) ) {
2
  ...
3
}
4

5
IN        R19,0x13       In from I/O location
6
IN        R18,0x10       In from I/O location
7
BST       R19,2          Bit store from register to T
8
CLR       R22            Clear Register
9
BLD       R22,0          Bit load from T to register
10
LDI       R23,0x00       Load immediate
11
BST       R18,4          Bit store from register to T
12
CLR       R20            Clear Register
13
BLD       R20,0          Bit load from T to register
14
LDI       R21,0x00       Load immediate
15
CP        R22,R20        Compare
16
CPC       R23,R21        Compare with carry
17
BREQ      PC+0x20        Branch if equal
Moderator #4761343
Lesenswert?

Was die Symbole statusbyte, RC5_INP und RC5_PIN bedeuten, ist wohl dein
Geheimnis, also kann man nur raten. Ich habe versucht, die fehlende
Information aus dem generierten Assemblercode zu rekonstruieren.

Wenn ich damit richtig liege, tut folgender C-Code dasselbe:

1
  uint8_t rc5inp = RC5_INP;
2
  if(statusbyte.rc5_bit)
3
    rc5inp = ~rc5inp;
4
  if(rc5inp & RC5_PIN) {
5
    ...
6
  }


GCC 6.2.0 macht daraus

1
  in r24,0x13
2
  sbic 0x10,4
3
  com r24
4
  sbrs r24,2
5
  rjmp ...

was IMHO nicht weiter optimiert werden kann.


Übrigens:

Statt

1
(ausdruck) ? 1 : 0

kann man auch schreiben

1
(bool)(ausdruck)
Gast #4762411
Lesenswert?

Danke, der Cast hats gebracht. Jetzt siehts schon viel besser aus.
1
IN        R18,0x13       In from I/O location
2
IN        R19,0x10       In from I/O location
3
SWAP      R19            Swap nibbles
4
ANDI      R19,0x01       Logical AND with immediate
5
BST       R18,2          Bit store from register to T
6
CLR       R18            Clear Register
7
BLD       R18,0          Bit load from T to register
8
CP        R19,R18        Compare
9
BREQ      PC+0x20        Branch if equal
Gruß Olaf
#4771019
Lesenswert?

Adib schrieb:
> Ps: im C sind alle Bit-operationen mit int-operanden definiert.

Nein.

In C sind alle Operationen auf "schmaleren" Datentypen als int als 
Operationen auf int definiert (integer promotion).

Ein optimierender Compiler darf das abkürzen, solange das Ergebnis 
dasselbe bleibt, wie wenn er integer promotion durchgeführt hätte.

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