avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[avr-gcc-list] Optimization opportunities with I/O and bool?


From: larry barello
Subject: [avr-gcc-list] Optimization opportunities with I/O and bool?
Date: Thu, 11 Jun 2009 12:34:45 -0700

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? 

Attachment: bool-test.c
Description: Text document


reply via email to

[Prev in Thread] Current Thread [Next in Thread]