R1 has no valid value in ISR routine
Original Reporter info from Mantis: Timm Thaler
-
Reporter name: Timm Thaler
Original Reporter info from Mantis: Timm Thaler
- Reporter name: Timm Thaler
Description:
While calling a ISR in AVR controller register R1 is not pushed. R1 is taken to be ZERO, but sometimes it is not.
This code
[code=laz]procedure timer0_interrupt; alias: 'TIMER0_COMPA_ISR'; interrupt; public;
begin
inc(sseccnt);
if sseccnt >= 25000 then begin // 1 second
sseccnt := 0;[/code]
will be compiled to
[code=asm]TIMER0_COMPA_ISR:
push r26
push r20
push r19
push r18
push r0
in r0,63
push r0
# [25] inc(sseccnt);
lds r20,(U_sEM_INT_ss_SSECCNT)
lds r19,(U_sEM_INT_ss_SSECCNT+1)
ldi r18,1
add r20,r18
adc r19,r1 <= here R1 = 0 is assumed
sts (U_sEM_INT_ss_SSECCNT),r20
sts (U_sEM_INT_ss_SSECCNT+1),r19[/code]
R1 is assumed to be zero, but if the ISR is called within a multiply part R1:R0 holds the results of the multiplication.
A word multiply somewhere in the main program gives
[code=asm]# [50] mean := (15 * mean + vval) div 16;
lds r18,(U_sEM_DEFINE_ss_MEAN)
lds r19,(U_sEM_DEFINE_ss_MEAN+1)
ldi r22,15
mov r21,r1
movw r2,r18
mul r2,r22
movw r18,r0 <= from here R1:R0 holds the return of the mul
mul r3,r22
add r19,r0
mul r2,r21
add r19,r0
clr r1 <= here R1 is ZERO again
mov r2,r19
mov r21,r1
[/code]
So of the ISR is called within mul and clr R1, R1 may have any other value than ZERO.
Steps to reproduce:
doing a word calculation in an ISR that uses R1, or zeroing a variable
doing a lot of word multiplies in main program which uses mul instruction
=> the word calculation in the ISR will went wrong
Additional information:
FPC 3.1.1
Compiler options -O2 or -O3, others I didn't try
Bugfix: If R1 is used in ISR, push R1, clr R1 at entry, pop R1 at return of ISR.
Mantis conversion info:
- Mantis ID: 33165
- OS: AVR
- OS Build: AVR5
- Build: 57250
- Platform: Embedded
- Version: 3.1.1
- Fixed in version: 3.1.1
- Fixed in revision: 38233 (#291ee4b5)