This is the mail archive of the crossgcc@sources.redhat.com mailing list for the crossgcc project.

See the CrossGCC FAQ for lots more information.


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

Re: Return from Interrupts for ARM-ELF


> Hi folks,
> 
> Just a quick question with regards to the interrupt attribute for functions.
> 
> 
> For example 
> 
> void	ADI_IRQ_Interrupt_Setup(void) __attribute__ ((interrupt ("IRQ")));
> 
> void	ADI_IRQ_Interrupt_Setup(void) 
> {
> 	IRQ();
> 	return ;
> }
> 
> Generates the following code
> 
> 
>    0:   e52dc004        str     ip, [sp, -#4]!
>    4:   e1a0c00d        mov     ip, sp
>    8:   e24ee004        sub     lr, lr, #4      ; 0x4
>    c:   e92dd80f        stmdb   sp!, {r0, r1, r2, r3, fp, ip, lr, pc}
>   10:   e24cb004        sub     fp, ip, #4      ; 0x4
>         IRQ();
>   14:   e59f3014        ldr     r3, [pc, #20]   ; 30 <ADI_IRQ_Interrupt_Setup+0x
> 
> 30>
>   18:   e5933000        ldr     r3, [r3]
>   1c:   e1a0e00f        mov     lr, pc
>   20:   e12fff13        bx      r3
>         return 0 ;
>   24:   e3a03000        mov     r3, #0  ; 0x0
> }
>   28:   e1a00003        mov     r0, r3
>   2c:   e95b580f        ldmdb   fp, {r0, r1, r2, r3, fp, ip, lr}^
>   30:   000001c0        andeq   r0, r0, r0, asr #3

This disassembly cannot possibly come from the example code you cite above.

1) It calls a pointer to a function
2) It tries to return a value (interrupt functions must be void).

> 
> How does GCC return to the code that calls this as it does not directly affect
> the PC?
> 
> Should the following liner be replaced:
> 
> ldmdb   fp, {r0, r1, r2, r3, fp, ip, lr}^
> 
> with:
> 
> ldmdb   fp, {r0, r1, r2, r3, fp, ip, PC}^

Nope, it needs to play more games after that to restore the stack 
correctly:

> 
> To switch back to the previous user mode and jump back to the Link Register
> location.
> 
> Any ideas?
> 

Yes, use gcc-3.3.1.  There have been a large number of problems with 
generating code that returns from interrupts.  Hopefully these are now all 
fixed.

Putting your *source* code into gcc 3.3.1 gives:

        str     ip, [sp, #-4]!
        mov     ip, sp
        stmfd   sp!, {r0, r1, r2, r3, fp, ip, lr, pc}
        sub     fp, ip, #4
        bl      IRQ
        ldmea   fp, {r0, r1, r2, r3, fp, sp, lr}
        ldmfd   sp!, {ip}
        subs    pc, lr, #4

Which I believe is correct, if not the world's most efficient interrupt 
handler.

R.


------
Want more information?  See the CrossGCC FAQ, http://www.objsw.com/CrossGCC/
Want to unsubscribe? Send a note to crossgcc-unsubscribe@sources.redhat.com


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