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

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

Re: [avr-gcc-list] avr-gcc 3.4.3 confused about function pointers


From: Ned Konz
Subject: Re: [avr-gcc-list] avr-gcc 3.4.3 confused about function pointers
Date: Sun, 16 Apr 2006 16:01:44 -0700


On Apr 16, 2006, at 2:55 PM, John Regehr wrote:

Compiling like this:

  avr-gcc -Wall -mmcu=atmega128 -Os foo.c

gives a program that icalls to a bad address.

On the other hand, compiling the same program with -O instead of -Os
results in correct code.

The problem occurs when the Z register is loaded with the address of
foo().  In the buggy (-Os) version, the literal address of foo() is
loaded, rather than the address shifted right by one bit position. With -O the compiler gets it right.

I'd appreciate hearing about it if there's a patch for this or if the bug is known to be fixed in later versions.

Under avr-gcc 4.1.0 both foo and stuff get optimized out (well, they both end up empty):

  32                    .global foo
  34                    foo:
  41 0000 0895                  ret
  43                    /* function foo size 1 (0) */
  45                    .Lscope0:
  49                    .global stuff
  51                    stuff:
  58 0002 0895                  ret
  60                    /* function stuff size 1 (0) */
  62                    .Lscope1:
  66                    .global main
  68                    main:
  73 0004 C0E0                  ldi r28,lo8(__stack - 0)
  74 0006 D0E0                  ldi r29,hi8(__stack - 0)
  75 0008 DEBF                  out __SP_H__,r29
  76 000a CDBF                  out __SP_L__,r28
  80 000c 0E94 0000             call stuff
  83 0010 80E0                  ldi r24,lo8(0)
  84 0012 90E0                  ldi r25,hi8(0)
  86 0014 0C94 0000             jmp exit
  88                    /* function main size 10 (4) */

If you force foo to be called (for instance, passing a pointer to back [0], after declaring back as volatile) then the compiler is clever enough just to call foo(), rather than using a pointer.

You'll have to come up with a test program that's cleverer than that.

I did notice that for the expression (&foo + 1) it used a byte increment, rather than a word increment (which seems wrong to me).

void
foo(volatile struct bar *b)
{
  ca:   fc 01           movw    r30, r24
    b->yyy = (void*)0;
  cc:   11 82           std     Z+1, r1 ; 0x01
  ce:   10 82           st      Z, r1
  d0:   08 95           ret

000000d2 <stuff>:
}

void
stuff(void)
{
  d2:   cf 93           push    r28
  d4:   df 93           push    r29
  d6:   cd b7           in      r28, 0x3d       ; 61
  d8:   de b7           in      r29, 0x3e       ; 62
  da:   28 97           sbiw    r28, 0x08       ; 8
  dc:   0f b6           in      r0, 0x3f        ; 63
  de:   f8 94           cli
  e0:   de bf           out     0x3e, r29       ; 62
  e2:   0f be           out     0x3f, r0        ; 63
  e4:   cd bf           out     0x3d, r28       ; 61
    volatile struct bar back[2];

    void (*p) (volatile struct bar *) = foo;

    back[0].aaa = (void *) (&foo + 1);
  e6:   8b ec           ldi     r24, 0xCB       ; 203    <<<< questionable!
  e8:   90 e0           ldi     r25, 0x00       ; 0
  ea:   9c 83           std     Y+4, r25        ; 0x04
  ec:   8b 83           std     Y+3, r24        ; 0x03

    int i;

    for (i = 0; i < 6; i++)
    {
        back[0].aaa = back[0].yyy;
  ee:   89 81           ldd     r24, Y+1        ; 0x01
  f0:   9a 81           ldd     r25, Y+2        ; 0x02
  f2:   9c 83           std     Y+4, r25        ; 0x04
  f4:   8b 83           std     Y+3, r24        ; 0x03
.. etc ..
    }

    (*p) (&back[0]);
11e:    ce 01           movw    r24, r28
120:    01 96           adiw    r24, 0x01       ; 1
122:    0e 94 65 00     call    0xca <foo>
126:    28 96           adiw    r28, 0x08       ; 8
128:    0f b6           in      r0, 0x3f        ; 63
12a:    f8 94           cli
12c:    de bf           out     0x3e, r29       ; 62
12e:    0f be           out     0x3f, r0        ; 63
130:    cd bf           out     0x3d, r28       ; 61
132:    df 91           pop     r29
134:    cf 91           pop     r28
136:    08 95           ret

--
Ned Konz
address@hidden






reply via email to

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