Hi, Sten. Thanks for your answer. Since this function was calling
other functions (and could not possibly know what other registers
might the other functions alter), I was wondering if this code
shouldn't have saved the r4-r12 registers. I wasn't aware of APCS (r0-
r3 being scratch registers, as David just explained to me), but I
deeply suspected there was one.
Guille
--- In lpc2000@yahoogroups.com, "bdmlpc" <list@n...> wrote:
>
> Hello Guille,
>
> which registers do you expect to save/restore when calling a
> sub-routine? In generell you are only saving registers you need. In
> your IRQ all used registers (r0..r3) are saved and restored.
> CPSR (current program status register) must not be saved if you are
> not using nested interrupts on your IRQ. CPSR is automatically saved
> to SPSR_mode (saved program status register of certain mode) when
ARM
> switches from user/system/supervisor mode to IRQ mode. IRQ is
disabled
> when switich to IRQ to disable interrupt nesting. SPSR is shadow
> register. It is restored when you return from IRQ mode to your
> previously used mode. Therfore don't touch CPSR in interrupt
services
> routines. It is not a x86 architecture! ARM does everything for you.
>
> Sten
>
> --- In lpc2000@yahoogroups.com, "Guillermo Prandi"
> <yahoo.messenger@m...> wrote:
> >
> > Hi, all!
> >
> > First of all I want to thank everybody in this group. The amount
and
> > quality of help I'm receiving from you guys is extraordinary. I
> > sincerely hope I can contribute helping others in due time.
> >
> > I am doing some IRQ compilation tests with GCC and the
__attribute__
> > ((interrupt("IRQ")) syntax. Apparently the code doesn't seem to
> > save/restore all the registers I expected. In particular, it
doesn't
> > seem to save spsr. Also, only general registers r1-r4 are saved
> > before calling an external function. I have the following
questions:
> >
> > * Saving spsr is only needed for reentrant IRQs?
> > * Perhaps saving only r1-r4 is a convention, and functions should
> > always save by themselves any other general registers they may
use?
> > * Should I worry or this is perfectly normal and *safe*?
> >
> > Thanks in advance.
> >
> > Guille
> >
> > void Uart0Service(void) __attribute__ ((interrupt("IRQ"));
> >
> > void Uart0Service(void)
> > {
> > 18f0: e24ee004 sub lr, lr, #4 ; 0x4
> > 18f4: e92d500f stmdb sp!, {r0, r1, r2, r3, ip, lr}
> > unsigned char temp_id;
> > temp_id = U0IIR;
> > 18f8: e3a03903 mov r3, #49152 ; 0xc000
> > 18fc: e283328e add r3, r3, #-536870904 ; 0xe0000008
> > 1900: e5d32000 ldrb r2, [r3]
> > switch(temp_id & IDENT_MASK) {
> > 1904: e202200e and r2, r2, #14 ; 0xe
> > case DATA_AVAILABLE:
> > case DATA_TIMEOUT:
> > receive();
> > break;
> > case TRANSMIT_AVAILABLE:
> > transmit();
> > default:
> > break;
> > }
> > /* case DATA_AVAILABLE */
> > 1908: e3520004 cmp r2, #4 ; 0x4
> > 190c: 0a000005 beq 1928 <Uart0Service+0x38>
> >
> > /* case DATA_TIMEOUT */
> > 1910: e352000c cmp r2, #12 ; 0xc
> > 1914: 0a000003 beq 1928 <Uart0Service+0x38>
> >
> > /* case [not] TRANSMIT_AVAILABLE */
> > 1918: e3520002 cmp r2, #2 ; 0x2
> > 191c: 18fd900f ldmneia sp!, {r0, r1, r2, r3, ip, pc}^
> >
> > 1920: ebfffa69 bl 2cc <transmit>
> > 1924: e8fd900f ldmia sp!, {r0, r1, r2, r3, ip, pc}^
> >
> > 1928: ebfffa75 bl 304 <receive>
> > 192c: e8fd900f ldmia sp!, {r0, r1, r2, r3, ip, pc}^
> > }
> >
> > Shouldn't this code also save spsr? Or perhaps this is only
needed
> > for reentrant IRQs?
> >
> > Guille
> >
>Message
Re: Save/restore IRQ registers in GNU C
2005-10-25 by Guillermo Prandi
Attachments
- No local attachments were found for this message.