It appears GCC and <stdbool.h> treats bool's as ints with the expected code hit. Using "uint8_t" instead of bool gives better code.
Also illustrated is poor Boolean handling of i/o registers. maybe that is something inherent in GCC, but wouldn't it be much more straightforward to code (((~PINE)&_BV(6)) != 0) as ldi Rx, lo8(1) sbic PINE, 6 ldi Rx, lo8(0) I have become fond of using bools, but now might consider moving back to uint8_t and explicit tests. The following example generates very tight code if I change to uint8_t and get rid of the test for != 0 (i.e. just bit masks), with <stdbool.h> the != 0 is implied and the same code results whether it is there or not. I am no guru, so what problems will I run into using uint8_t vs. stdbool? Can handling of bools be improved? avr-gcc -c -mmcu=atmega128 -I. -gdwarf-2 - -I../.. -I../. -Os -funsigned-bitfields -fpack-struct -fshort-enums -fno-inline -Wall -Wstrict-prototypes -Wa,-adhlns=bool-test.lst -std=gnu99 -Wp,-M,-MP,-MT,bool-test.o,-MF,.dep/bool-test.o.d bool-test.c -o bool-test.o #include <avr/io.h> #if 1 #include <stdbool.h> #else typedef unsigned char bool; #endif bool bPower; bool bLanyard; bool bPowerSwitch; bool test(void) { bLanyard = ((~PINE) & _BV(PE7)); bPowerSwitch = ((~PINE) & _BV(PE6)); bPower = bPowerSwitch | bLanyard; return bPower; } Code generated with <stdbool.h> 18 test: 19 .LFB2: 20 .LM1: 21 /* prologue: function */ 22 /* frame size = 0 */ 23 .LM2: 24 0000 21B1 in r18,33-32 25 0002 2095 com r18 26 0004 221F rol r18 27 0006 2227 clr r18 28 0008 221F rol r18 29 000a 2093 0000 sts bLanyard,r18 30 .LM3: 31 000e 81B1 in r24,33-32 32 0010 8295 swap r24 33 0012 8695 lsr r24 34 0014 8695 lsr r24 35 0016 8370 andi r24,lo8(3) 36 0018 8095 com r24 37 001a 8170 andi r24,lo8(1) 38 001c 8093 0000 sts bPowerSwitch,r24 39 .LM4: 40 0020 40E0 ldi r20,lo8(0) 41 0022 90E0 ldi r25,lo8(0) 42 0024 30E0 ldi r19,lo8(0) 43 0026 822B or r24,r18 44 0028 932B or r25,r19 45 002a 892B or r24,r25 46 002c 01F0 breq .L3 47 002e 41E0 ldi r20,lo8(1) 48 .L3: 49 0030 4093 0000 sts bPower,r20 50 .LM5: 51 0034 842F mov r24,r20 52 /* epilogue start */ 53 0036 0895 ret Code generated with uint8_t 18 test: 19 .LFB2: 20 .LM1: 21 /* prologue: function */ 22 /* frame size = 0 */ 23 .LM2: 24 0000 91B1 in r25,33-32 25 0002 9095 com r25 26 0004 9078 andi r25,lo8(-128) 27 0006 9093 0000 sts bLanyard,r25 28 .LM3: 29 000a 81B1 in r24,33-32 30 000c 8095 com r24 31 000e 8074 andi r24,lo8(64) 32 0010 8093 0000 sts bPowerSwitch,r24 33 .LM4: 34 0014 892B or r24,r25 35 0016 8093 0000 sts bPower,r24 36 /* epilogue start */ 37 .LM5: 38 001a 0895 ret Granted using uint8_t doesn't generate strictly bool results (0x00 & 0x01) but afaict GCC never tests the values: it always tests != 0 so good enough, right?
#include <avr/io.h> #if 1 #include <stdbool.h> #else typedef unsigned char bool; #endif bool bPower; bool bLanyard; bool bPowerSwitch; bool test(void) { bLanyard = ((~PINE) & _BV(PE7)); bPowerSwitch = ((~PINE) & _BV(PE6)); bPower = bPowerSwitch | bLanyard; return bPower; }
_______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list