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

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

[avr-gcc-list] __builtin_constant_p for inline func args with -Os


From: Paul Stoffregen
Subject: [avr-gcc-list] __builtin_constant_p for inline func args with -Os
Date: Sun, 08 Nov 2009 12:14:10 -0800
User-agent: Thunderbird 2.0.0.23 (X11/20090817)

I'm trying to create an inline function (instead of a preprocessor macro) which uses __builtin_constant_p to test if its args are compile time constants. According to the manual, this is supposed to work with optimization enabled.

  You may use this built-in function in either a macro or an inline
  function. However, if you use it in an inlined function and pass an
  argument of the function as the argument to the built-in, GCC ....
  will not return 1 when you pass a constant numeric value to the
  inline function unless you specify the -O option.

Indeed it works great with -O2. But with -Os, __builtin_constant_p never returns 1.

Is this a bug? Or is __builtin_constant_p just not supported with -Os? Or did I do something stupidly wrong?

My test code is attached.

Thanks,

-Paul




// compile with:
//
//   avr-gcc -mmcu=atmega168 -g -Os -c test2.c
//
// disassemble with:
//
//   avr-objdump -d -S test2.o

#include <avr/io.h>

extern void _digitalWrite(uint8_t pin, uint8_t val);


// With -Os  __builtin_constant_p never returns true
// With -O2  __builtin_constant_p works properly

static inline void digitalWrite(uint8_t pin, uint8_t val)
{
        if (__builtin_constant_p(pin) && __builtin_constant_p(val)) {
                if (val) {
                        if (pin == 0) {
                                PORTD |= _BV(0);
                        } else if (pin == 1) {
                                PORTD |= _BV(1);
                        } else if (pin == 2) {
                                PORTD |= _BV(2);
                        } else {
                        }
                } else {
                        if (pin == 0) {
                                PORTD &= ~_BV(0);
                        } else if (pin == 1) {
                                PORTD &= ~_BV(1);
                        } else if (pin == 2) {
                                PORTD &= ~_BV(2);
                        } else {
                        }
                }
        } else {
                _digitalWrite(pin, val);
        }
}


volatile uint8_t num=2;

int main(void)
{
        PORTD |= 0x04;          // should optimize to single instruction
        digitalWrite(num, 1);   // should call function
        digitalWrite(2, 1);     // should optimize to single instruction
        while (1) ;
}


reply via email to

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