From f98f0bb012d04593bdeb00a0c18dc281bae1e9bb Mon Sep 17 00:00:00 2001 From: vrokas Date: Sun, 23 Jan 2005 11:23:43 +0000 Subject: [PATCH] * src/pic16/gen.c: fixed bug #1106975, * src/pic16/gen.c: fixed possible bug #1102572, now during TOS pointer update, INTCON is saved, global interrupts are disabled and restored after updateing TOS. * src/SDCC.y, src/SDCC.lex, src/SDCCsymt.c, src/SDCCsymt.h: * added function attribute 'shadowregs' to take advantage of shadow registers, * added function attribute 'wparam' as an alternative to the wparam pragma, * support/Utils/SDCCerr.[ch]: added error E_SHADOWREGS_NO_ISR when user declares a non-ISR function as 'shadowregs', * doc/sdccman.lyx: updated to reflect recent changes of pic16 port git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3650 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- ChangeLog | 15 + device/lib/pic16/startup/Makefile | 4 +- doc/sdccman.lyx | 694 +++++++++++++++++++----------- src/SDCC.lex | 2 + src/SDCC.y | 7 + src/SDCCsymt.c | 17 + src/SDCCsymt.h | 6 + src/pic16/gen.c | 41 +- src/pic16/main.c | 15 +- src/pic16/pcode.c | 3 +- support/Util/SDCCerr.c | 2 + support/Util/SDCCerr.h | 1 + 12 files changed, 547 insertions(+), 260 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5fe897c4..8cd4d22e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2005-01-23 Vangelis Rokas + + * src/pic16/gen.c: fixed bug #1106975, + * src/pic16/gen.c: fixed possible bug #1102572, now during TOS + pointer update, INTCON is saved, global interrupts are disabled and + restored after updateing TOS. + * src/SDCC.y, src/SDCC.lex, src/SDCCsymt.c, src/SDCCsymt.h: + * added function attribute 'shadowregs' to take advantage of shadow + registers, + * added function attribute 'wparam' as an alternative to the wparam + pragma, + * support/Utils/SDCCerr.[ch]: added error E_SHADOWREGS_NO_ISR when + user declares a non-ISR function as 'shadowregs', + * doc/sdccman.lyx: updated to reflect recent changes of pic16 port + 2005-01-22 Vangelis Rokas * .version: bumped version number to 2.4.8 diff --git a/device/lib/pic16/startup/Makefile b/device/lib/pic16/startup/Makefile index bd266eb5..4fdbd8b0 100644 --- a/device/lib/pic16/startup/Makefile +++ b/device/lib/pic16/startup/Makefile @@ -22,8 +22,8 @@ SRCS = crt0 \ # add nostdinc and nostdlib for this device libraries -COMPILE_FLAGS += --denable-peeps --optimize-goto --obanksel=2 --pomit-config-words --pomit-ivt -COMPILE_FLAGS += $(MODELFLAGS) --nostdinc --nostdlib +COMPILE_FLAGS += $(MODELFLAGS) $(OPT_FLAGS) +COMPILE_FLAGS += --nostdinc --nostdlib CFILES = $(patsubst %,%.c,$(SRCS)) OFILES = $(patsubst %.c,%.o,$(CFILES)) diff --git a/doc/sdccman.lyx b/doc/sdccman.lyx index 2c211266..a7748be0 100644 --- a/doc/sdccman.lyx +++ b/doc/sdccman.lyx @@ -83,7 +83,7 @@ SDCC Compiler User Guide \size normal -SDCC 2.4.7 +SDCC 2.4.8 \size footnotesize \newline @@ -15383,104 +15383,6 @@ status Collapsed / \end_inset --nodefaultlibs do not link default libraries when linking. -\layout List -\labelwidthstring 00.00.0000 - -- -\begin_inset ERT -status Collapsed - -\layout Standard - -\backslash -/ -\end_inset - --obanksel=# Set optimization level for inserting BANKSELs. -\begin_deeper -\layout List -\labelwidthstring 00.00.0000 - -0 is no optimization -\layout List -\labelwidthstring 00.00.0000 - -1 checks previous used register and if it is the same then does not emit - BANKSEL, accounts only for labels. -\layout List -\labelwidthstring 00.00.0000 - -2 tries to check the location of (even different) symbols and removes BANKSELs - if they are in the same bank. - Important: This will only work properly if the linker script does not have - sections across bank borders! -\end_deeper -\layout List -\labelwidthstring 00.00.0000 - -- -\begin_inset ERT -status Collapsed - -\layout Standard - -\backslash -/ -\end_inset - --pomit-config-words Omit the generation of the configuration words. -\layout List -\labelwidthstring 00.00.0000 - -- -\begin_inset ERT -status Collapsed - -\layout Standard - -\backslash -/ -\end_inset - --pomit-ivt Omit the generation of the interrupt vectors. -\layout List -\labelwidthstring 00.00.0000 - -- -\begin_inset ERT -status Collapsed - -\layout Standard - -\backslash -/ -\end_inset - --pleave-reset-vector Used in conjuction with - -\begin_inset ERT -status Collapsed - -\layout Standard - -\backslash -/ -\end_inset - --pomit-ivt, instructs the port NOT to omit the reset vector. -\layout List -\labelwidthstring 00.00.0000 - -- -\begin_inset ERT -status Collapsed - -\layout Standard - -\backslash -/ -\end_inset - -stack-model=[model] Used in conjuction with the command above. Defines the stack model to be used, valid stack models are : \begin_deeper @@ -15577,7 +15479,24 @@ status Collapsed / \end_inset --call-tree dump call tree in .calltree file +-mplab-comp MPLAB compatibility option. + Currently only suppresses special gpasm directives. +\layout Subsubsection + +Optimization Options +\layout Standard + +- +\begin_inset ERT +status Collapsed + +\layout Standard + +\backslash +/ +\end_inset + +-optimize-goto Try to use (conditional) BRA instead of GOTO \layout List \labelwidthstring 00.00.0000 @@ -15591,8 +15510,30 @@ status Collapsed / \end_inset --mplab-comp MPLAB compatibility option. - Currently only suppresses special gpasm directives. +-obanksel=nn Set optimization level for inserting BANKSELs. +\newline + +\begin_deeper +\layout List +\labelwidthstring 00.00.0000 + +0 is no optimization +\layout List +\labelwidthstring 00.00.0000 + +1 checks previous used register and if it is the same then does not emit + BANKSEL, accounts only for labels. +\layout List +\labelwidthstring 00.00.0000 + +2 tries to check the location of (even different) symbols and removes BANKSELs + if they are in the same bank. + Important: This will only work properly if the linker script does not have + sections across bank borders! +\end_deeper +\layout Subsubsection + +Linking Options \layout List \labelwidthstring 00.00.0000 @@ -15606,7 +15547,7 @@ status Collapsed / \end_inset --use-crt= Use a custom run-time module instead of the defaults. +-nodefaultlibs do not link default libraries when linking \layout List \labelwidthstring 00.00.0000 @@ -15620,7 +15561,7 @@ status Collapsed / \end_inset --no-crt Don't link the default run-time modules +-use-crt= Use a custom run-time module instead of the defaults. \layout List \labelwidthstring 00.00.0000 @@ -15634,7 +15575,7 @@ status Collapsed / \end_inset --optimize-goto Try to use (conditional) BRA instead of GOTO +-no-crt Don't link the default run-time modules \layout Subsubsection Debugging Options @@ -15729,6 +15670,20 @@ status Collapsed \end_inset -gstack Trace push/pops for stack pointer overflow +\layout List +\labelwidthstring 00.00.0000 + +- +\begin_inset ERT +status Collapsed + +\layout Standard + +\backslash +/ +\end_inset + +-call-tree dump call tree in .calltree file \layout Subsection Preprocessor Macros @@ -15992,26 +15947,37 @@ Example: \layout LyX-Code void foo(int x); -\layout List -\labelwidthstring 00.00.0000 +\layout Standard -code place a function symbol at static FLASH address +The same effect with +\emph on +wparam pragma +\emph default + can be achieved with the function attribute +\emph on +wparam +\emph default +. + Usage: \layout LyX-Code -Example: +void func_wparam(int a) wparam \layout LyX-Code +{ \layout LyX-Code -/* place function test_func at 0x4000 */ +... \layout LyX-Code -#pragma code test_func 0x4000 +} +\layout Standard + +Limitations of wparam pragma apply for wparam function attribute, too. \layout List \labelwidthstring 00.00.0000 -udata pragma udata instructs the compiler to emit code so that linker will - place a variable at a specific memory bank +code place a function symbol at static FLASH address \layout LyX-Code Example: @@ -16019,100 +15985,12 @@ Example: \layout LyX-Code -/* places variable foo at bank2 */ -\layout LyX-Code - -#pragma udata bank2 foo -\layout LyX-Code - -char foo; -\layout Standard - -In order for this pragma to work extra SECTION directives should be added - in the .lkr script. - In the following example a sample .lkr file is shown: -\layout LyX-Code - -\layout LyX-Code - -// Sample linker script for the PIC18F452 processor -\layout LyX-Code - -LIBPATH . -\layout LyX-Code - -CODEPAGE NAME=vectors START=0x0 END=0x29 PROTECTED -\layout LyX-Code - -CODEPAGE NAME=page START=0x2A END=0x7FFF -\layout LyX-Code - -CODEPAGE NAME=idlocs START=0x200000 END=0x200007 PROTECTED -\layout LyX-Code - -CODEPAGE NAME=config START=0x300000 END=0x30000D PROTECTED -\layout LyX-Code - -CODEPAGE NAME=devid START=0x3FFFFE END=0x3FFFFF PROTECTED -\layout LyX-Code - -CODEPAGE NAME=eedata START=0xF00000 END=0xF000FF PROTECTED -\layout LyX-Code - -ACCESSBANK NAME=accessram START=0x0 END=0x7F -\layout LyX-Code - -\layout LyX-Code - -DATABANK NAME=gpr0 START=0x80 END=0xFF -\layout LyX-Code - -DATABANK NAME=gpr1 START=0x100 END=0x1FF -\layout LyX-Code - -DATABANK NAME=gpr2 START=0x200 END=0x2FF -\layout LyX-Code - -DATABANK NAME=gpr3 START=0x300 END=0x3FF -\layout LyX-Code - -DATABANK NAME=gpr4 START=0x400 END=0x4FF -\layout LyX-Code - -DATABANK NAME=gpr5 START=0x500 END=0x5FF -\layout LyX-Code - -ACCESSBANK NAME=accesssfr START=0xF80 END=0xFFF PROTECTED -\layout LyX-Code - -\layout LyX-Code - -SECTION NAME=CONFIG ROM=config -\layout LyX-Code - -\layout LyX-Code - -SECTION NAME=bank0 RAM=gpr0 # these SECTION directives -\layout LyX-Code - -SECTION NAME=bank1 RAM=gpr1 # should be added to link -\layout LyX-Code - -SECTION NAME=bank2 RAM=gpr2 # section name 'bank?' with -\layout LyX-Code - -SECTION NAME=bank3 RAM=gpr3 # a specific DATABANK name +/* place function test_func at 0x4000 */ \layout LyX-Code -SECTION NAME=bank4 RAM=gpr4 +#pragma code test_func 0x4000 \layout LyX-Code -SECTION NAME=bank5 RAM=gpr5 -\layout Standard - -The linker will recognise the section name set in the pragma statement and - will position the variable at the memory bank set with the RAM field at - the SECTION line in the linker script file. \layout List \labelwidthstring 00.00.0000 @@ -16296,51 +16174,157 @@ libio18f* \begin_inset Text -\layout Standard +\layout Standard + + +\series bold +debug +\end_inset + + +\begin_inset Text + +\layout Standard + +link the debug library +\end_inset + + +\begin_inset Text + +\layout Standard + + +\emph on +libdebug +\emph default +.lib +\end_inset + + + + +\end_inset + + +\newline +* is the device number, i.e. + 452 for PIC18F452 MCU. +\layout Standard + +This feature allows for linking with specific libraries withoug having to + explicit name them in the command line. + Note that the +\noun on +ignore +\noun default + keyword will reject all modules specified by the library pragma. +\layout List +\labelwidthstring 00.00.0000 + +udata pragma udata instructs the compiler to emit code so that linker will + place a variable at a specific memory bank +\layout LyX-Code + +Example: +\layout LyX-Code + +\layout LyX-Code + +/* places variable foo at bank2 */ +\layout LyX-Code + +#pragma udata bank2 foo +\layout LyX-Code + +char foo; +\layout Standard + +In order for this pragma to work extra SECTION directives should be added + in the .lkr script. + In the following example a sample .lkr file is shown: +\layout LyX-Code + +\layout LyX-Code + +// Sample linker script for the PIC18F452 processor +\layout LyX-Code + +LIBPATH . +\layout LyX-Code + +CODEPAGE NAME=vectors START=0x0 END=0x29 PROTECTED +\layout LyX-Code + +CODEPAGE NAME=page START=0x2A END=0x7FFF +\layout LyX-Code + +CODEPAGE NAME=idlocs START=0x200000 END=0x200007 PROTECTED +\layout LyX-Code + +CODEPAGE NAME=config START=0x300000 END=0x30000D PROTECTED +\layout LyX-Code + +CODEPAGE NAME=devid START=0x3FFFFE END=0x3FFFFF PROTECTED +\layout LyX-Code + +CODEPAGE NAME=eedata START=0xF00000 END=0xF000FF PROTECTED +\layout LyX-Code + +ACCESSBANK NAME=accessram START=0x0 END=0x7F +\layout LyX-Code + +\layout LyX-Code + +DATABANK NAME=gpr0 START=0x80 END=0xFF +\layout LyX-Code + +DATABANK NAME=gpr1 START=0x100 END=0x1FF +\layout LyX-Code + +DATABANK NAME=gpr2 START=0x200 END=0x2FF +\layout LyX-Code + +DATABANK NAME=gpr3 START=0x300 END=0x3FF +\layout LyX-Code +DATABANK NAME=gpr4 START=0x400 END=0x4FF +\layout LyX-Code -\series bold -debug -\end_inset - - -\begin_inset Text +DATABANK NAME=gpr5 START=0x500 END=0x5FF +\layout LyX-Code -\layout Standard +ACCESSBANK NAME=accesssfr START=0xF80 END=0xFFF PROTECTED +\layout LyX-Code -link the debug library -\end_inset - - -\begin_inset Text +\layout LyX-Code -\layout Standard +SECTION NAME=CONFIG ROM=config +\layout LyX-Code +\layout LyX-Code -\emph on -libdebug -\emph default -.lib -\end_inset - - - +SECTION NAME=bank0 RAM=gpr0 # these SECTION directives +\layout LyX-Code -\end_inset +SECTION NAME=bank1 RAM=gpr1 # should be added to link +\layout LyX-Code +SECTION NAME=bank2 RAM=gpr2 # section name 'bank?' with +\layout LyX-Code -\newline -* is the device number, i.e. - 452 for PIC18F452 MCU. +SECTION NAME=bank3 RAM=gpr3 # a specific DATABANK name +\layout LyX-Code + +SECTION NAME=bank4 RAM=gpr4 +\layout LyX-Code + +SECTION NAME=bank5 RAM=gpr5 \layout Standard -This feature allows for linking with specific libraries withoug having to - explicit name them in the command line. - Note that the -\noun on -ignore -\noun default - keyword will reject all modules specified by the library pragma. +The linker will recognise the section name set in the pragma statement and + will position the variable at the memory bank set with the RAM field at + the SECTION line in the linker script file. \layout Subsection Header Files @@ -16435,8 +16419,21 @@ cd device/include \layout LyX-Code su -c 'make install' # install the headers, you need the root password +\layout Standard + +There exist a special target to build the I/O libraries. + This target is not automatically build because it will build the I/O library + for +\emph on +every +\emph default + supported device. + This way building will take quite a lot of time. + Users are advised to edit the device/lib/pic16/pics.build file and then + execute: \layout LyX-Code +make lib-io \layout Subsection Memory Models @@ -16868,6 +16865,192 @@ on stack, FSR0 points to the beginning Interrupts \layout Standard +An interrupt servive routine (ISR) is declared using the +\emph on +interrupt +\emph default + keyword. +\layout LyX-Code + +void isr(void) interrupt +\emph on +n +\layout LyX-Code + +{ +\layout LyX-Code + +... +\layout LyX-Code + +} +\layout Standard + + +\emph on +n +\emph default + is the interrupt number, which for PIC18F devices can be: +\layout Standard +\align center + +\begin_inset Tabular + + + + + + + +\begin_inset Text + +\layout Standard + + +\emph on +n +\end_inset + + +\begin_inset Text + +\layout Standard + +Interrupt Vector +\end_inset + + +\begin_inset Text + +\layout Standard + +Interrupt Vector Address +\end_inset + + + + +\begin_inset Text + +\layout Standard + +0 +\end_inset + + +\begin_inset Text + +\layout Standard + +RESET vector +\end_inset + + +\begin_inset Text + +\layout Standard + +0x000000 +\end_inset + + + + +\begin_inset Text + +\layout Standard + + +\family roman +\series medium +\shape up +\size normal +\emph off +\bar no +\noun off +\color none +1 +\end_inset + + +\begin_inset Text + +\layout Standard + + +\family roman +\series medium +\shape up +\size normal +\emph off +\bar no +\noun off +\color none +HIGH priority interrupts +\end_inset + + +\begin_inset Text + +\layout Standard + +0x000008 +\end_inset + + + + +\begin_inset Text + +\layout Standard + +2 +\end_inset + + +\begin_inset Text + +\layout Standard + +LOW priority interrupts +\end_inset + + +\begin_inset Text + +\layout Standard + +0x000018 +\end_inset + + + + +\end_inset + + +\layout Standard + +When generating assembly code for ISR the code generator places a +\noun on +goto +\noun default +instruction at the +\emph on +Interrupt Vector Address +\emph default + which points at the genetated ISR. +\layout Standard + + +\emph on +n +\emph default + is possible to be omitted. + This way a function is generated similar to an ISR, but it is not assigned + to any interrupt. +\layout Standard + When entering an interrupt, currently the PIC16 \begin_inset LatexCommand \index{PIC16} @@ -16892,13 +17075,42 @@ FSR0 (FSR0L and FSR0H) \layout Standard These registers are restored upon return from the interrupt routine. - +\layout Subsubsection + +Using Shadow Registers +\layout Standard + +When entering/exiting an ISR, it is possible to take advantage of the PIC18F + core shadow registers which hold the values of WREG, STATUS and BSR registers. + This can be done by adding the keyword +\emph on +shadowregs +\emph default + before the +\emph on +interrupt +\emph default + keyword in the function's header. +\layout LyX-Code + +void isr_shadow(void) shadowregs interrupt 1 +\layout LyX-Code + +{ +\layout LyX-Code + +... +\layout LyX-Code + +} \layout Standard -When entering a high priority interrupt WREG, STATUS and BSR are not explicit - saved by software. - The hardware shadow registers for WREG, STATUS and BSR are used in these - cases. + +\emph on +shadowregs +\emph default + instructs the code generator not to store/restore WREG, STATUS, BSR when + entering/exiting the ISR. \layout Standard diff --git a/src/SDCC.lex b/src/SDCC.lex index 098e36cd..60820b75 100644 --- a/src/SDCC.lex +++ b/src/SDCC.lex @@ -114,6 +114,8 @@ static int checkCurrFile(char *s); "near" { count(); TKEYWORD(DATA); } "pdata" { count(); TKEYWORD(PDATA); } "reentrant" { count(); TKEYWORD(REENTRANT); } +"shadowregs" { count(); TKEYWORD(SHADOWREGS); } +"wparam" { count(); TKEYWORD(WPARAM); } "register" { count(); return(REGISTER); } "return" { count(); return(RETURN); } "sfr" { count(); TKEYWORD(SFR); } diff --git a/src/SDCC.y b/src/SDCC.y index d2aaedc0..3e3c7b3e 100644 --- a/src/SDCC.y +++ b/src/SDCC.y @@ -89,6 +89,7 @@ bool uselessDecl = TRUE; %token XOR_ASSIGN OR_ASSIGN %token TYPEDEF EXTERN STATIC AUTO REGISTER CODE EEPROM INTERRUPT SFR AT SBIT %token REENTRANT USING XDATA DATA IDATA PDATA VAR_ARGS CRITICAL NONBANKED BANKED +%token SHADOWREGS WPARAM %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID BIT %token STRUCT UNION ENUM ELIPSIS RANGE FAR %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN @@ -210,6 +211,12 @@ function_attributes werror(W_BANKED_WITH_NONBANKED); } } + | SHADOWREGS {$$ = newLink (SPECIFIER); + FUNC_ISSHADOWREGS($$) = 1; + } + | WPARAM {$$ = newLink (SPECIFIER); + FUNC_ISWPARAM($$) = 1; + } | BANKED {$$ = newLink (SPECIFIER); FUNC_BANKED($$) = 1; if (FUNC_NONBANKED($$)) { diff --git a/src/SDCCsymt.c b/src/SDCCsymt.c index 7ccca8c3..dbcfd663 100644 --- a/src/SDCCsymt.c +++ b/src/SDCCsymt.c @@ -2293,6 +2293,12 @@ checkFunction (symbol * sym, symbol *csym) } } + if (IFFUNC_ISSHADOWREGS(sym->type) && !FUNC_ISISR (sym->type)) + { + werror (E_SHADOWREGS_NO_ISR, sym->name); + } + + for (argCnt=1, acargs = FUNC_ARGS(sym->type); acargs; acargs=acargs->next, argCnt++) { @@ -2361,6 +2367,17 @@ checkFunction (symbol * sym, symbol *csym) werror (E_PREV_DEF_CONFLICT, csym->name, "reentrant"); } + if (IFFUNC_ISWPARAM (csym->type) != IFFUNC_ISWPARAM (sym->type)) + { + werror (E_PREV_DEF_CONFLICT, csym->name, "wparam"); + } + + if (IFFUNC_ISSHADOWREGS (csym->type) != IFFUNC_ISSHADOWREGS (sym->type)) + { + werror (E_PREV_DEF_CONFLICT, csym->name, "shadowregs"); + } + + /* compare expected args with actual args */ exargs = FUNC_ARGS(csym->type); acargs = FUNC_ARGS(sym->type); diff --git a/src/SDCCsymt.h b/src/SDCCsymt.h index 5ed6048e..1dced6d0 100644 --- a/src/SDCCsymt.h +++ b/src/SDCCsymt.h @@ -218,6 +218,8 @@ typedef struct sym_link unsigned reent:1; /* function is reentrant */ unsigned naked:1; /* naked function */ + unsigned shadowregs:1; /* function uses shadow registers (pic16 port) */ + unsigned wparam:1; /* first byte of arguments is passed via WREG (pic16 port) */ unsigned nonbanked:1; /* function has the nonbanked attribute */ unsigned banked:1; /* function has the banked attribute */ unsigned critical:1; /* critical function */ @@ -360,6 +362,10 @@ extern sym_link *validateLink(sym_link *l, #define FUNC_ISREENT(x) (x->funcAttrs.reent) #define IFFUNC_ISREENT(x) (IS_FUNC(x) && FUNC_ISREENT(x)) +#define FUNC_ISSHADOWREGS(x) (x->funcAttrs.shadowregs) +#define IFFUNC_ISSHADOWREGS(x) (IS_FUNC(x) && FUNC_ISSHADOWREGS(x)) +#define FUNC_ISWPARAM(x) (x->funcAttrs.wparam) +#define IFFUNC_ISWPARAM(x) (IS_FUNC(x) && FUNC_ISWPARAM(x)) #define FUNC_ISNAKED(x) (x->funcAttrs.naked) #define IFFUNC_ISNAKED(x) (IS_FUNC(x) && FUNC_ISNAKED(x)) #define FUNC_NONBANKED(x) (x->funcAttrs.nonbanked) diff --git a/src/pic16/gen.c b/src/pic16/gen.c index 70e132b9..b61a5820 100644 --- a/src/pic16/gen.c +++ b/src/pic16/gen.c @@ -153,7 +153,6 @@ static struct { short ipushRegs; set *sendSet; set *stackRegSet; - int interruptvector; int usefastretfie; bitVect *fregsUsed; int stack_lat; /* stack offset latency */ @@ -3232,7 +3231,7 @@ static void genCall (iCode *ic) // stackParms = psuedoStkPtr; // fprintf(stderr, "%s:%d ic parmBytes = %d\n", __FILE__, __LINE__, ic->parmBytes); fname = OP_SYMBOL(IC_LEFT(ic))->rname[0]?OP_SYMBOL(IC_LEFT(ic))->rname:OP_SYMBOL(IC_LEFT(ic))->name; - inwparam = inWparamList(OP_SYMBOL(IC_LEFT(ic))->name); + inwparam = (inWparamList(OP_SYMBOL(IC_LEFT(ic))->name)) || (FUNC_ISWPARAM(OP_SYM_TYPE(IC_LEFT(ic)))); #if 0 gpsimDebug_StackDump(__FILE__, __LINE__, fname ); @@ -3436,6 +3435,11 @@ static void genPcall (iCode *ic) // push return address // push $ on return stack, then replace with retlbl + /* Thanks to Thorsten Klose for pointing out that the following + * snippet should be interrupt safe */ + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_intcon), pic16_popCopyReg(&pic16_pc_postdec1))); + pic16_emitpcode(POC_BCF, pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_intcon), 7)); + pic16_emitpcodeNULLop(POC_PUSH); pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 0, 0)); @@ -3445,6 +3449,11 @@ static void genPcall (iCode *ic) pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 2, 0)); pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosu)); + + /* restore interrupt control register */ + pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_preinc1)); + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_intcon)); + /* make the call by writing the pointer into pc */ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)),2), pic16_popCopyReg(&pic16_pc_pclatu))); pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)),1), pic16_popCopyReg(&pic16_pc_pclath))); @@ -3563,6 +3572,10 @@ static void genFunction (iCode *ic) char asymname[128]; pBlock *apb; + +// debugf("interrupt number: %hhi\n", FUNC_INTNO(sym->type)); + +#if 0 { int i, found=-1; @@ -3578,12 +3591,16 @@ static void genFunction (iCode *ic) if(found == -1) { fprintf(stderr, "PIC16 port: %s:%d: interrupt function but cannot locate symbol (%s)\n", __FILE__, __LINE__, sym->name); - assert( 0 ); +// assert( 0 ); } _G.interruptvector = found; } +#endif - sprintf(asymname, "ivec_%d_%s", _G.interruptvector, sym->name); + if(FUNC_INTNO(sym->type) == 256) + sprintf(asymname, "ivec_%s", sym->name); + else + sprintf(asymname, "ivec_0x%x_%s", FUNC_INTNO(sym->type), sym->name); asym = newSymbol(asymname, 0); apb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute section")); @@ -3602,14 +3619,18 @@ static void genFunction (iCode *ic) abSym = Safe_calloc(1, sizeof(absSym)); strcpy(abSym->name, asymname); - switch( _G.interruptvector ) { + switch( FUNC_INTNO(sym->type) ) { case 0: abSym->address = 0x000000; break; case 1: abSym->address = 0x000008; break; case 2: abSym->address = 0x000018; break; + + default: + abSym->address = -1; break; } /* relocate interrupt vectors if needed */ - abSym->address += pic16_options.ivt_loc; + if(abSym->address != -1) + abSym->address += pic16_options.ivt_loc; addSet(&absSymSet, abSym); } @@ -3654,7 +3675,7 @@ static void genFunction (iCode *ic) _G.usefastretfie = 1; /* use shadow registers by default */ /* an ISR should save: WREG, STATUS, BSR, PRODL, PRODH, FSR0L, FSR0H */ - if(!(_G.interruptvector == 1)) { + if(!FUNC_ISSHADOWREGS(sym->type)) { /* do not save WREG,STATUS,BSR for high priority interrupts * because they are stored in the hardware shadow registers already */ _G.usefastretfie = 0; @@ -3702,7 +3723,7 @@ static void genFunction (iCode *ic) pic16_emitpcode(POC_DECF, pic16_popCopyReg( pic16_stackpnt_hi )); //&pic16_pc_fsr1h)); } - if(inWparamList(sym->name)) { + if(inWparamList(sym->name) || FUNC_ISWPARAM(sym->type)) { if(IFFUNC_HASVARARGS(sym->type) || IFFUNC_ISREENT(sym->type)) _G.useWreg = 0; else @@ -3818,14 +3839,14 @@ static void genEndFunction (iCode *ic) pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodh )); pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodl )); - if(!(_G.interruptvector == 1)) { + if(!FUNC_ISSHADOWREGS(sym->type)) { /* do not restore interrupt vector for WREG,STATUS,BSR * for high priority interrupt, see genFunction */ pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_bsr )); pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_status )); pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_wreg )); } - _G.interruptvector = 0; /* sanity check */ +// _G.interruptvector = 0; /* sanity check */ /* if debug then send end of function */ diff --git a/src/pic16/main.c b/src/pic16/main.c index a570358a..7e51fb27 100644 --- a/src/pic16/main.c +++ b/src/pic16/main.c @@ -43,29 +43,32 @@ static char _defaultRules[] = static char *_pic16_keywords[] = { "at", -// "bit", "code", "critical", "register", "data", "far", -// "idata", "interrupt", "near", "pdata", "reentrant", "sfr", -// "sbit", "using", -// "xdata", "_data", "_code", "_generic", "_near", -// "_xdata", "_pdata", -// "_idata", "_naked", + "shadowregs", + "wparam", + +// "bit", +// "idata", +// "sbit", +// "xdata", +// "_xdata", +// "_idata", NULL }; diff --git a/src/pic16/pcode.c b/src/pic16/pcode.c index 98854b6b..802545e6 100644 --- a/src/pic16/pcode.c +++ b/src/pic16/pcode.c @@ -4602,7 +4602,8 @@ void pic16_printpBlock(FILE *of, pBlock *pb) // fprintf(stderr, "%s:%d testing %s <-> %s\n", __FILE__, __LINE__, PCF(pc)->fname, ab->name); if(!strcmp(ab->name, PCF(pc)->fname)) { // fprintf(stderr, "%s:%d address = %x\n", __FILE__, __LINE__, ab->address); - fprintf(of, "\t0X%06X", ab->address); + if(ab->address != -1) + fprintf(of, "\t0X%06X", ab->address); break; } } diff --git a/support/Util/SDCCerr.c b/support/Util/SDCCerr.c index e0674aeb..6542a7ea 100644 --- a/support/Util/SDCCerr.c +++ b/support/Util/SDCCerr.c @@ -419,6 +419,8 @@ struct " please report problem and send source code at SDCC-USER list on SF.Net"}, { W_COMPLEMENT, ERROR_LEVEL_WARNING, "using ~ on bit/bool/unsigned char variables can give unexpected results due to promotion to int" }, +{ E_SHADOWREGS_NO_ISR, ERROR_LEVEL_ERROR, + "ISR function attribute 'shadowregs' following non-ISR function `%s'" }, }; /* diff --git a/support/Util/SDCCerr.h b/support/Util/SDCCerr.h index 728c9753..a08c8412 100644 --- a/support/Util/SDCCerr.h +++ b/support/Util/SDCCerr.h @@ -196,6 +196,7 @@ SDCCERR - SDCC Standard error handler #define W_SIZEOF_VOID 178 /* size of void is zero */ #define W_POSSBUG2 179 /* possible bug, new format */ #define W_COMPLEMENT 180 /* ~bit can give unexpected results */ +#define E_SHADOWREGS_NO_ISR 181 /* shadowregs keyword following non-ISR function */ #define MAX_ERROR_WARNING 256 /* size of disable warnings array */ -- 2.47.2