Version: WinAVR-20081205
Target: -mmcu=atmega32
#include <avr/io.h>
uint8_t foo()
{
uint8_t val = 0;
if (bit_is_set(PINA,PA5)) val |=1;
if (bit_is_set(PINA,PA0)) val |=2;
return val;
}
I would expect something like that:
foo:
clr r24
sbic 0x19,5
ori r24,1
sbic 0x19,0
ori r24,2
ret
Compiling with -Os -mmcu=atmega32
00000000 <foo>:
0: 89 b3 in r24, 0x19 ; 25
2: 90 e0 ldi r25, 0x00 ; 0
4: 25 e0 ldi r18, 0x05 ; 5
6: 96 95 lsr r25
8: 87 95 ror r24
a: 2a 95 dec r18
c: 01 f4 brne .+0 ; 0xe <foo+0xe>
c: R_AVR_7_PCREL .text+0x6
e: 81 70 andi r24, 0x01 ; 1
10: c8 99 sbic 0x19, 0 ; 25
12: 82 60 ori r24, 0x02 ; 2
14: 08 95 ret
Funnily enough it uses sbic for the second if() but not for the first.
Copmiled with -O3 -mmcu=atmega32
00000000 <foo>:
0: 89 b3 in r24, 0x19 ; 25
2: 90 e0 ldi r25, 0x00 ; 0
4: 96 95 lsr r25
6: 87 95 ror r24
8: 92 95 swap r25
a: 82 95 swap r24
c: 8f 70 andi r24, 0x0F ; 15
e: 89 27 eor r24, r25
10: 9f 70 andi r25, 0x0F ; 15
12: 89 27 eor r24, r25
14: 81 70 andi r24, 0x01 ; 1
16: c8 99 sbic 0x19, 0 ; 25
18: 82 60 ori r24, 0x02 ; 2
1a: 08 95 ret
If I swap the order of the 2 "if"s around it gets even more bizzare:
With -Os:
00000000 <foo>:
0: c8 9b sbis 0x19, 0 ; 25
2: 00 c0 rjmp .+0 ; 0x4 <foo+0x4>
2: R_AVR_13_PCREL .text+0x8
4: 82 e0 ldi r24, 0x02 ; 2
6: 00 c0 rjmp .+0 ; 0x8 <foo+0x8>
6: R_AVR_13_PCREL .text+0xa
8: 80 e0 ldi r24, 0x00 ; 0
a: cd 99 sbic 0x19, 5 ; 25
c: 81 60 ori r24, 0x01 ; 1
e: 08 95 ret
With -03:
00000000 <foo>:
0: c8 9b sbis 0x19, 0 ; 25
2: 00 c0 rjmp .+0 ; 0x4 <foo+0x4>
2: R_AVR_13_PCREL .text+0xe
4: 82 e0 ldi r24, 0x02 ; 2
6: 93 e0 ldi r25, 0x03 ; 3
8: cd 99 sbic 0x19, 5 ; 25
a: 89 2f mov r24, r25
c: 08 95 ret
e: 80 e0 ldi r24, 0x00 ; 0
10: 91 e0 ldi r25, 0x01 ; 1
12: 00 c0 rjmp .+0 ; 0x14 <__zero_reg__+0x13>
12: R_AVR_13_PCREL .text+0x8
Nobody/Anonymous
GCC
v1.0 (example)
Public
Copyright © 2009 Geeknet, Inc. All rights reserved. Terms of Use