interrupt handlers the way god intended

interrupt handlers the way god intended

Postby notzed » Mon Mar 24, 2014 4:34 am

Interrupt handlers in C just feels wrong to me but for some reason adapteva decided not to describe the process apart from saying to use the C interface. The information is scattered around tho.

  • If using the sdk loader a set of somewhat inconsistent section names can be used to define the single 32-bit instruction allowed in the interrupt vector table starting at location 0. See one of the linker scripts.
  • unfortunately only the PC is saved automatically, so the status register needs to be saved explicitly.
  • rti clears the pending bit of the current interrupt automatically.

e.g. define the ivt entry for wand:
Code: Select all
  .section ivt_entry_wand
  b isr_wand

isr_wand must be on-core.

An example that doesn't allow other interrupts:
Code: Select all
 .section .text
isr_wand:
  strd r0,[sp,-1]

 ; clear bit 3 of status = WAND bit
  movfs r0,status
 ; of course if it's guaranteed to be set could use: sub r0,r0,8
  mov r1,#~(1<<3)
  movt r1,#~0
  and r0,r0,r1
  movts status,r0

  ldrd r0,[sp,-1]
  rti

Since this saves the status register as part of the calculation it doesn't need to save status or iret. While interrupts are disabled it is safe to have data outside sp (i'm sure adapteva would disagree but that's what they do).

An example that allows nested higher level interrupts:
Code: Select all
 .section .text
isr_wand:
  strd r4,[sp, -1]
  movfs r4,status
  movfs r5,iret
  add sp,sp,-8   ; adjust for other saved regs as necessary (before gie)
  gie

  ; do stuff

  gid
  add sp,sp,8
  movts status,r4
  movts iret,r5
  ldrd r4,[sp,-1]
  rti


This is basically what the compiler does when you use __attribute__((interrupt)) anyway (i used objdump to find out what needed saving).
notzed
 
Posts: 331
Joined: Mon Dec 17, 2012 12:28 am
Location: Australia

Re: interrupt handlers the way god intended

Postby timpart » Tue Mar 25, 2014 5:57 pm

I fully agree assembler is currently best for writing interrupt handlers, since C has overheads.

One irritation, even with assembler, is that the chip doesn't have any registers reserved for ISR use. (Some chips have a shadow set which come into play.) I've been mulling over making a request for a compiler option to tell the compiler not to use registers R24 to R27. (There is already one to tell it not to use R32 to R63 for use with future versions of the chip with only 32 registers.) If we had some registers we knew the compiler wouldn't touch in ordinary routines we could use them as scratch registers in an ISR without having to save and restore them first, speeding things up a little.

I'd turn off the option by default, since not everyone would need it. (The standard libraries would have to be compiled with the option on though.) Any thoughts on this suggestion?

Tim
timpart
 
Posts: 302
Joined: Mon Dec 17, 2012 3:25 am
Location: UK

Re: interrupt handlers the way god intended

Postby notzed » Tue Mar 25, 2014 11:55 pm

It's a bit of a bummer that even status isn't shadowed although you'd have to save any shadowed registers for nested interrupts anyway.

Do you have a case where the 4 extra instructions to save/restore 4 regs by writing to/reading from local memory will make a practical impact? Compared to the mesh latency?

You could borrow the 4 'constant' registers 28-31 to test whether it makes enough of a difference to matter. Only r28 has a reserved use at the moment as a PIC base pointer which probably isn't used by anyone yet, pity r15 isn't PC for that tho.

Slightly related: last year I tried adjusting the abi in a custom build of the compiler by changing r0-r7 to arg/scratch, r8-15 saved. But i didn't really have enough code to test to determine if it improved anything by being able to use short instructions more often in leaf functions and with argument construction. And sp forced everything to 32-bits anyway (maybe r7=sp would help).
notzed
 
Posts: 331
Joined: Mon Dec 17, 2012 12:28 am
Location: Australia

Re: interrupt handlers the way god intended

Postby timpart » Wed Mar 26, 2014 7:52 am

notzed wrote:It's a bit of a bummer that even status isn't shadowed although you'd have to save any shadowed registers for nested interrupts anyway.

Do you have a case where the 4 extra instructions to save/restore 4 regs by writing to/reading from local memory will make a practical impact? Compared to the mesh latency?


Agreed nested interrupts need saving of registers.

Personally I don't see anything wrong your writing to outside the stack pointed area in the ISR, since that rule must be there because of interrupts. Not sure about you use of
Code: Select all
strd r0,[sp,-1]

sp might not be at a double word address. The EABI only says "(SP mod 4) = 0". Perhaps it would be better if the EAPI was changed so it was aligned to a double word, as I'd expect the opportunities to use double word save and restore would reduce code size more than the possible extra word of stack space used. (Unless there's heavy use of recursive functions.)

I have no practical applications for interrupts at all apart from perhaps WAND. Was just thinking that saving a few cycles could be useful in some applications.

Regards,

Tim
timpart
 
Posts: 302
Joined: Mon Dec 17, 2012 3:25 am
Location: UK

Re: interrupt handlers the way god intended

Postby notzed » Wed Mar 26, 2014 12:05 pm

timpart wrote:
Code: Select all
strd r0,[sp,-1]

sp might not be at a double word address. The EABI only says "(SP mod 4) = 0". Perhaps it would be better if the EAPI was changed so it was aligned to a double word, as I'd expect the opportunities to use double word save and restore would reduce code size more than the possible extra word of stack space used. (Unless there's heavy use of recursive functions.)


Hmm, you're right, I read the wrong bit, well I read both bits but went with the stack frame bullet point.

However I suspect the EABI appendix is wrong or just unclear here because this is what the compiler produces for interrupt routines too. Due to the lack of pre-decrement the stack isn't build incrementally but in whole chunks, and since those have to be 8-byte aligned it probably always is too.

I'll ask.
notzed
 
Posts: 331
Joined: Mon Dec 17, 2012 12:28 am
Location: Australia

Re: interrupt handlers the way god intended

Postby notzed » Wed Mar 26, 2014 12:31 pm

BTW if you want to play with the abi, perhaps these options will suffice. Came across them tonight.

`-ffixed-REG'
Treat the register named REG as a fixed register; generated code
should never refer to it (except perhaps as a stack pointer, frame
pointer or in some other fixed role).

REG must be the name of a register. The register names accepted
are machine-specific and are defined in the `REGISTER_NAMES' macro
in the machine description macro file.

`-fcall-used-REG'
Treat the register named REG as an allocable register that is
clobbered by function calls. It may be allocated for temporaries
or variables that do not live across a call. Functions compiled
this way do not save and restore the register REG.

It is an error to use this flag with the frame pointer or stack
pointer. Use of this flag for other registers that have fixed
pervasive roles in the machine's execution model produces
disastrous results.

`-fcall-saved-REG'
Treat the register named REG as an allocable register saved by
functions. It may be allocated even for temporaries or variables
that live across a call. Functions compiled this way save and
restore the register REG if they use it.

It is an error to use this flag with the frame pointer or stack
pointer. Use of this flag for other registers that have fixed
pervasive roles in the machine's execution model produces
disastrous results.

A different sort of disaster results from the use of this flag for
a register in which function values may be returned.
notzed
 
Posts: 331
Joined: Mon Dec 17, 2012 12:28 am
Location: Australia

Re: interrupt handlers the way god intended

Postby notzed » Fri Mar 28, 2014 7:30 am

Confirmed it should be 8-byte aligned:

viewtopic.php?f=23&t=1064&p=6740#p6722
notzed
 
Posts: 331
Joined: Mon Dec 17, 2012 12:28 am
Location: Australia


Return to Assembly

Who is online

Users browsing this forum: No registered users and 1 guest

cron