------- Comment #6 from j at uriah dot heep dot sax dot de  2007-11-15 21:21 
-------
I'm not sure whether this is related or not... but from the description, it
looks so.

avr-libc contains a macro that helps the users declaring a flash-ROM string,
lacking any real support in GCC for different memory sections (as proposed
by the Embedded C draft).  This works by using the GCC extension that a
block can return a value: a block is openened, and a block-scope static
variable is allocated, using the string literal passed in by the user.  Then,
that block returns the address of this variable to the caller.  By giving
the block-scope variable the "progmem" attribute, it will eventually be
allocated in ROM rather than RAM.

Now, if that macro is called with identical string literals within one
translation unit, the strings are allocated separately rather than merged
into a single location.

This behaviour is reproducable as well on the i386 target, so it looks like
not really related to the avr backend.

Here's a simple test case.  For simplicity, the original PSTR() macro is
just reproduced in the file rather than including the entire original
header(s).

#if defined(__AVR__)
#  define PROGMEM __attribute__((__progmem__))
#else
#  define PROGMEM /* nothing */
#endif

#define PSTR(x) \
(__extension__({static const char __c[] PROGMEM = (x); &__c[0];}))

extern void puts_P(const char *);

void
dosomething(void)
{
        puts_P(PSTR("Hello world!"));
        puts_P(PSTR("Hello world!"));
}

Compiling for the avr target yields:

        .file   "foo.c"
__SREG__ = 0x3f
__SP_H__ = 0x3e
__SP_L__ = 0x3d
__tmp_reg__ = 0
__zero_reg__ = 1
        .global __do_copy_data
        .global __do_clear_bss
        .text
.global dosomething
        .type   dosomething, @function
dosomething:
/* prologue: frame size=0 */
/* prologue end (size=0) */
        ldi r24,lo8(__c.1471)
        ldi r25,hi8(__c.1471)
        rcall puts_P
        ldi r24,lo8(__c.1473)
        ldi r25,hi8(__c.1473)
        rcall puts_P
/* epilogue: frame size=0 */
        ret
/* epilogue end (size=1) */
/* function dosomething size 7 (6) */
        .size   dosomething, .-dosomething
        .section        .progmem.data,"a",@progbits
        .type   __c.1473, @object
        .size   __c.1473, 13
__c.1473:
        .string "Hello world!"
        .type   __c.1471, @object
        .size   __c.1471, 13
__c.1471:
        .string "Hello world!"
/* File "foo.c": code    7 = 0x0007 (   6), prologues   0, epilogues   1 */

Compiling the same file for the i386 target also shows two copies of the
string literal:

        .file   "foo.c"
        .section        .rodata
        .type   __c.0, @object
        .size   __c.0, 13
__c.0:
        .string "Hello world!"
        .type   __c.1, @object
        .size   __c.1, 13
__c.1:
        .string "Hello world!"
        .text
.globl dosomething
        .type   dosomething, @function
dosomething:
        pushl   %ebp
        movl    %esp, %ebp
        pushl   $__c.0
        call    puts_P
        movl    $__c.1, (%esp)
        call    puts_P
        leave
        ret
        .size   dosomething, .-dosomething
        .ident  "GCC: (GNU) 3.4.4 [FreeBSD] 20050518"


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21018

Reply via email to