This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c++/37386] New: Interrupt service routine for arm target corrupts program counter


Trying to compile this code:

#define U0THR          (*((volatile unsigned char *) 0xE000C000))

template <typename T, unsigned int len>
class Queue
{
        public:
        /**
        Constructor, create a new queue.
        */
        Queue()
        {
                put_pos=get_pos=num_elem=0;
        }

        bool IRQget(T& elem)
        {
                if((put_pos==get_pos)&&(num_elem==0))//If queue empty
                {
                        return false;
                }
                num_elem--;
                elem=buffer[get_pos];
                if(++get_pos==len) get_pos=0;
                return true;
        }

        bool IRQput(T elem)
        {
                if((put_pos==get_pos)&&(num_elem!=0))//If queue full
                {
                        return false;
                }
                num_elem++;
                buffer[put_pos]=elem;
                if(++put_pos==len) put_pos=0;
                return true;
        }

        private:
        //Queue data
        T buffer[len];
        volatile unsigned int num_elem;
        volatile unsigned int put_pos;
        volatile unsigned int get_pos;
};

Queue<char,32> tx_queue;

void serial_IRQ_Routine()   __attribute__ ((interrupt("IRQ")));
void serial_IRQ_Routine()
{
        char c;
        int i;
        for(i=0;i<16;i++)
        {
                //If software queue empty, stop
                if(tx_queue.IRQget(c)==false) break;
                U0THR=c;
        }
}

with gcc 4.2.4, command line "arm-elf-g++ -mcpu=arm7tdmi -fno-exceptions
-fno-rtti -Os -Wall -S bug.cpp"
corrupts the program counter when returning from the ISR.
It happens only with -Os optimization flag. -O0 -O1 -O2 -O3 optimization flags
cause no bug.

Here's a piece of assembler code:

_Z18serial_IRQ_Routinev:
        @ Interrupt Service Routine.
        @ args = 0, pretend = 0, frame = 4
        @ frame_needed = 0, uses_anonymous_args = 0
        sub     lr, lr, #4
        stmfd   sp!, {r0, r1, r2, r3, r4, r5, r6, r7, ip, lr}
        ldr     r7, .L15
        sub     sp, sp, #4
        ldr     r6, .L15+4
        mov     r4, #0
        add     r5, sp, #3
.L10:
        ldr     r0, .L15+8
        mov     r1, r5
        mov     lr, pc
        bx      r7
        cmp     r0, #0
        add     r4, r4, #1
        beq     .L13
        ldrb    r3, [sp, #3]    @ zero_extendqisi2
        cmp     r4, #16
        strb    r3, [r6, #0]
        bne     .L10
.L13:
        add     sp, sp, #4
        ldmfd   sp!, {r0, r1, r2, r3, r4, r5, r6, r7, ip, lr}
        subs    pc, lr, #4

at the beginning there's
"       sub     lr, lr, #4"
and at the end
"       subs    pc, lr, #4"
so the program counter is decremented by 8 instead of 4.

Here's the output of arm-elf-gcc -v:

arm-elf-g++ -v
Using built-in specs.
Target: arm-elf
Configured with: ../gcc-4.2.4/configure --target=arm-elf
--prefix=/usr/local/arm-elf --enable-interwork --enable-multilib
--with-float=soft --enable-languages=c,c++ --with-newlib
--with-headers=../newlib-1.16.0/newlib/libc/include
Thread model: single
gcc version 4.2.4


-- 
           Summary: Interrupt service routine for arm target corrupts
                    program counter
           Product: gcc
           Version: 4.2.4
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: fede dot tft at hotmail dot it


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]