#2191 RETURN and RETFIE not generated when using __naked modifier

closed-rejected
Maarten Brock
PIC16
5
2013-07-10
2013-07-09
Mauricio Martins
No

I started using SDCC to code my programs for PIC and looking the internals I found some items that I need clarification.

--> Processor PIC18F252, sdcc command line: --use-non-free --no-crt -mpic16 -p18f252

--> SDCC Version

SDCC : mcs51/gbz80/z80/z180/r2k/r3ka/ds390/pic16/pic14/TININative/ds400/hc08/s08/stm8 3.3.1 #8721 (Jun 26 2013) (MINGW64)

-->Here's the C code fragment

...
/ TIMER Section /
void timer_init() naked {
T1CONbits.T1CKPS1=0;

T1CONbits.T1CKPS0=1;
T1CONbits.T1OSCEN=1;
T1CONbits.T1SYNC=1;
T1CONbits.TMR1CS=0;
T1CONbits.TMR1ON=1;
TMR1H=248; //OVF@1ms FOSC@16MHz
TMR1L=48;
}
void timer_delayms(unsigned char c)
naked {
while(c>0){
if(PIR1bits.TMR1IF!=0) { c--; PIR1bits.TMR1IF=0; }
}

}
...

--> Now the equivalent generated .ASM code (verified in .LST)
...
; ; Starting pCode block
S_blinktimer_init code
_timer_init:
; .line 12; blink.c T1CONbits.T1CKPS1=0;
0000a6 9acd bcf 0xcd, 0x5, 0 BCF _T1CONbits, 5
; .line 13; blink.c T1CONbits.T1CKPS0=1;
0000a8 88cd bsf 0xcd, 0x4, 0 BSF _T1CONbits, 4
; .line 14; blink.c T1CONbits.T1OSCEN=1;
0000aa 86cd bsf 0xcd, 0x3, 0 BSF _T1CONbits, 3
; .line 15; blink.c T1CONbits.T1SYNC=1;
0000ac 84cd bsf 0xcd, 0x2, 0 BSF _T1CONbits, 2
; .line 16; blink.c T1CONbits.TMR1CS=0;
0000ae 92cd bcf 0xcd, 0x1, 0 BCF _T1CONbits, 1
; .line 17; blink.c T1CONbits.TMR1ON=1;
0000b0 80cd bsf 0xcd, 0, 0 BSF _T1CONbits, 0
; .line 18; blink.c TMR1H=248; //OVF@1ms FOSC@16MHz
0000b2 0ef8 movlw 0xf8 MOVLW 0xf8
0000b4 6ecf movwf 0xcf, 0 MOVWF _TMR1H
; .line 19; blink.c TMR1L=48;
0000b6 0e30 movlw 0x30 MOVLW 0x30
0000b8 6ece movwf 0xce, 0 MOVWF _TMR1L
; ; Starting pCode block
S_blink
isr_high code
...

See at last line, the compiler starts another method. but the timer_init() genereated in ASM never ends and executes the precedent code if any.

My claim is independently of having __naked or not, the RETURN (or RETFIE) must be generated.

When I remove the __naked, the RETURN (or RETFIE) is generated with the context saving code.

--> My workaround
Every __naked function declared, at end of if(before the last "}") I'm issuing a "return" via assembly (the "return" C statement does not generate the RETURN/RETFIE as I expected :( )

void func() __naked {
    ...
    __asm RETURN __endasm;
}

void isr() __naked __interrupt... {
    ...
    __asm RETFIE __endasm;
}

I'm assuming this behaviour is a bug. Please clarify!

Discussion

  • Maarten Brock
    Maarten Brock
    2013-07-10

    • status: open --> closed-rejected
    • assigned_to: Maarten Brock
     
  • Maarten Brock
    Maarten Brock
    2013-07-10

    This is no bug but intended behavior. A __naked function has no prologue, no epilogue and no return statement.