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

             Bug #: 52565
           Summary: __builtin_va_arg(va, double); may fall on cortex-m3
    Classification: Unclassified
           Product: gcc
           Version: 4.6.2
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassig...@gcc.gnu.org
        ReportedBy: ramon.zambe...@bluewin.ch


Created attachment 26880
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=26880
source and full outputs

Compiling this:

extern double vargTest(const char* format, ...);

#include <stdarg.h>



int main(void) {
    vargTest("%f", (double) 1.23456);

    while (1)
        ;
}

double vargTest(const char* format, ...) {
    __gnuc_va_list vaList;

    __builtin_va_start(vaList, format);

    double value = __builtin_va_arg(vaList, double);

    return value;
}


void _exit(){

}

Produces:

000080d8 <main>:
    80d8:    b580          push    {r7, lr}
    80da:    af00          add    r7, sp, #0
    80dc:    f248 4008     movw    r0, #33800    ; 0x8408
    80e0:    f2c0 0000     movt    r0, #0
    80e4:    a302          add    r3, pc, #8    ; (adr r3, 80f0 <main+0x18>)
    80e6:    e9d3 2300     ldrd    r2, r3, [r3]
    80ea:    f000 f805     bl    80f8 <vargTest>
    80ee:    e7fe          b.n    80ee <main+0x16>
    80f0:    fc8f3238     .word    0xfc8f3238
    80f4:    3ff3c0c1     .word    0x3ff3c0c1

000080f8 <vargTest>:
    80f8:    b40f          push    {r0, r1, r2, r3}
    80fa:    b480          push    {r7}
    80fc:    b085          sub    sp, #20
    80fe:    af00          add    r7, sp, #0
    8100:    f107 031c     add.w    r3, r7, #28
    8104:    607b          str    r3, [r7, #4]
    8106:    687b          ldr    r3, [r7, #4]
    8108:    f103 0307     add.w    r3, r3, #7
    810c:    f023 0307     bic.w    r3, r3, #7
    8110:    f103 0208     add.w    r2, r3, #8
    8114:    607a          str    r2, [r7, #4]
    8116:    e9d3 2300     ldrd    r2, r3, [r3]
    811a:    e9c7 2302     strd    r2, r3, [r7, #8]
    811e:    e9d7 2302     ldrd    r2, r3, [r7, #8]
    8122:    4610          mov    r0, r2
    8124:    4619          mov    r1, r3
    8126:    f107 0714     add.w    r7, r7, #20
    812a:    46bd          mov    sp, r7
    812c:    bc80          pop    {r7}
    812e:    b004          add    sp, #16
    8130:    4770          bx    lr
    8132:    bf00          nop


The instruction at 0x810c forces the address used for the ldrd to be alligned
to an 8 bytes boundary. The problem is that the double parameter is passed on
register r2-r3 and pushed on the stack at the entry point of  vargTest
function. Since the stack is aligned on 4 bytes boundary only the double value
may be misaligned and as a consequence the __builtin_va_arg(vaList, double)
function fails to retrive the correct value. 

Is this a bug?

Reply via email to