Witam!
Niby prosta rzecz:
void test1(void) { while( bit_is_clear (PIND, 4 ) ); }
void test2(void) { while( true ) { if(bit_is_set (PIND, 4 )) break; } }
void test3(void) { for(;;) { if(bit_is_set (PIND, 4 )) break; } }
A efekty co najmniej tragiczne:
00000084 <_Z5test1v>: 84: 21 e0 ldi r18, 0x01 ; 1 86: 30 e0 ldi r19, 0x00 ; 0 88: 80 b3 in r24, 0x10 ; 16 8a: 99 27 eor r25, r25 8c: 92 95 swap r25 8e: 82 95 swap r24 90: 8f 70 andi r24, 0x0F ; 15 92: 89 27 eor r24, r25 94: 9f 70 andi r25, 0x0F ; 15 96: 89 27 eor r24, r25 98: 82 27 eor r24, r18 9a: 93 27 eor r25, r19 9c: 80 fd sbrc r24, 0 9e: f4 cf rjmp .-24 ; 0x88 a0: 08 95 ret000000a2 <_Z5test2v>: a2: 80 b3 in r24, 0x10 ; 16 a4: 99 27 eor r25, r25 a6: 92 95 swap r25 a8: 82 95 swap r24 aa: 8f 70 andi r24, 0x0F ; 15 ac: 89 27 eor r24, r25 ae: 9f 70 andi r25, 0x0F ; 15 b0: 89 27 eor r24, r25 b2: 81 70 andi r24, 0x01 ; 1 b4: 90 70 andi r25, 0x00 ; 0 b6: 88 23 and r24, r24 b8: a1 f3 breq .-24 ; 0xa2 ba: 08 95 ret
000000bc <_Z5test3v>: bc: 80 b3 in r24, 0x10 ; 16 be: 99 27 eor r25, r25 c0: 92 95 swap r25 c2: 82 95 swap r24 c4: 8f 70 andi r24, 0x0F ; 15 c6: 89 27 eor r24, r25 c8: 9f 70 andi r25, 0x0F ; 15 ca: 89 27 eor r24, r25 cc: 81 70 andi r24, 0x01 ; 1 ce: 90 70 andi r25, 0x00 ; 0 d0: 88 23 and r24, r24 d2: a1 f3 breq .-24 ; 0xbc d4: 08 95 retPo co te wszystkie swapy/etc ?
Spodziewałbym się prymitywnej pętli z testowaniem bitu. A dostaje stertę kodu, który nic sensownego nie wnosi ...
gcc 3.4.3, kompilacja z -O2 i -O3 daje takie same efekty.
Zaznaczam, że samo testowanie bitów kompiluje się do pojedynczej instrukcji. Sama pętla while(true); kompiluje sie do prostackiego rjmp .-2. Dopiero zbitek z warunkiem opuszczenia produkuje takie nieoptymale fukcje.
Czy to wina GCC czy może moja ?