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

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

[avr-gcc-list] Inline vs. ? : operator


From: Szikra Istvan
Subject: [avr-gcc-list] Inline vs. ? : operator
Date: Sat, 27 Mar 2010 00:16:41 +0100

/**
Category: optimization miss
affects: avr-gcc 4.x.x
'?:' operator bit write generates unnecessary 'in' instruction in
inline functions.

I had a problem with my bit set macro and inline functions (among
other things). Though I found a workaround, I thought I'll share my
experience.

I have this 2 macros:
#define bit_write(p,b,c)        (c ? bit_set(p,b) : bit_clear(p,b))
#define bit_write_fix(p,b,c)    if (c) { bit_set(p,b);}else bit_clear(p,b)

The first works fine with constant parameters, but produces an extra
'in' instruction if called from static inline function.
The second works fine in both cases. Of course the inline functions
are called with constants.

My question is why is that?
It seems to be a bug to me. (It only affects gcc 4.x, good old gcc
3.4.6 works perfectly. )

I'm not a C expert, maybe I'm just missing something.
Any suggestions on the code, or maybe compiler parameters?

--Details:
-environment: WinAVR-20070525, 20080610,20081205,20090313,20100110
(avr-gcc 4.3.x )
(WinAVR-20060421 3.4.6 works)

-build command:
avr-gcc -mmcu=atmega16 -save-temps -Os test.c
or WinAVR Makefile Template

Here is the test code:
*/

#include <avr/io.h>

#define BIT(x) (0x01 << (x))
#define bit_set(p,b) ((p) |= BIT(b))
#define bit_clear(p,b) ((p) &= ~BIT(b))
#define bit_write(p,b,c) (c ? bit_set(p,b) : bit_clear(p,b))
#define bit_write_fix(p,b,c) if (c) { bit_set(p,b);}else bit_clear(p,b)

static inline void t_sw(char bit, char enable)
{
  enable ? bit_set(PORTA,bit) : bit_clear(PORTA,bit);
}
static inline void t_ie(char bit, char enable)
{
  if (enable) {
    bit_set(PORTA,bit);
  }else{
    bit_clear(PORTA,bit);
  }
}

static inline void t_BW(char bit, char enable)
{
  bit_write(PORTA,bit,enable);
}
static inline void t_BWF(char bit, char enable)
{
  bit_write_fix(PORTA,bit,enable);
}

int main (void)
{
  bit_write(PORTA,0,0);         /// cbi 59-32,0
  t_sw(2,0);                    /// cbi 59-32,2
                                /// in r24,59-32
  t_ie(3,0);                    /// cbi 59-32,3
  t_BW(1,0);                    /// cbi 59-32,1
                                /// in r24,59-32
  t_BWF(4,0);                   /// cbi 59-32,4
  bit_write_fix(PORTA,5,0);     /// cbi 59-32,5

  for (;;)  {
  }
}
/*
avr-gcc (WinAVR 20100110) 4.3.3
Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

avr-gcc -c -mmcu=atmega16 -I. -gdwarf-2 -DF_CPU=16000000UL
-DBOOTSIZE=1024  -Os -funsigned-char -funsigned-bitfields
-fpack-struct -fshort-enums -fno-strict-aliasing
-fno-inline-small-functions  -save-temps  -Wall -Winline
-Wstrict-prototypes -Wa,-adhlns=test.lst -ID:/Lib/ -std=gnu99 -MD -MP
-MF .dep/test.o.d test.c -o test.o
avr-gcc -mmcu=atmega16 -I. -gdwarf-2 -DF_CPU=16000000UL
-DBOOTSIZE=1024  -Os -funsigned-char -funsigned-bitfields
-fpack-struct -fshort-enums -fno-strict-aliasing
-fno-inline-small-functions  -save-temps  -Wall -Winline
-Wstrict-prototypes -Wa,-adhlns=test.o -ID:/Lib/ -std=gnu99 -MD -MP
-MF .dep/test.elf.d test.o --output test.elf -Wl,-Map=test.map,--cref
-lm -Wl,--section-start=.bootloader=0x3800
*/
/*
avr-gcc (GCC) 3.4.6
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

avr-gcc -mmcu=atmega16 -I. -gdwarf-2 -DF_CPU=8000000UL -Os
-funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall
-Wstrict-prototypes -Wundef -Wa,-adhlns=obj/test.lst -std=gnu99
-Wundef -MD -MP -MF .dep/test.elf.d test.c --output test.elf
-Wl,-Map=test.map,--cref -lm
*/
///(I get "../../../../../avr-libc-1.4.4/crt1/gcrt1.S:51: undefined
reference to `main'" error when use -save-temps option with gcc 3.4.6,
anyone has an idea why is that?)


-- 
Szikra Istvan




reply via email to

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