* src/pic16/gen.c: fixed bug #1106975,
authorvrokas <vrokas@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sun, 23 Jan 2005 11:23:43 +0000 (11:23 +0000)
committervrokas <vrokas@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sun, 23 Jan 2005 11:23:43 +0000 (11:23 +0000)
* 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

12 files changed:
ChangeLog
device/lib/pic16/startup/Makefile
doc/sdccman.lyx
src/SDCC.lex
src/SDCC.y
src/SDCCsymt.c
src/SDCCsymt.h
src/pic16/gen.c
src/pic16/main.c
src/pic16/pcode.c
support/Util/SDCCerr.c
support/Util/SDCCerr.h

index 5fe897c46a95a6a645802e2901baa817bdf08457..8cd4d22e4ec8c8ed97a1e943834f82ca9e1f0c66 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2005-01-23 Vangelis Rokas <vrokas AT otenet.gr>
+
+       * 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 <vrokas AT otenet.gr>
 
        * .version: bumped version number to 2.4.8
index bd266eb52dcad92dbf89a72ea4ac46d04b22f4b6..4fdbd8b03c9f22385c556e1cfe62c96645a97135 100644 (file)
@@ -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))
index 2c211266192251a6999ab64d8248df7701c1c7db..a7748be022e02a48775452e46baeadf4007ab8db 100644 (file)
@@ -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*
 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
 \begin_inset Text
 
-\layout Standard
+\layout Standard
+
+
+\series bold 
+debug
+\end_inset 
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+link the debug library
+\end_inset 
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+
+\emph on 
+libdebug
+\emph default 
+.lib
+\end_inset 
+</cell>
+</row>
+</lyxtabular>
+
+\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 
-</cell>
-<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
-\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 
-</cell>
-<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
-\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 
-</cell>
-</row>
-</lyxtabular>
+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
+<lyxtabular version="3" rows="4" columns="3">
+<features>
+<column alignment="center" valignment="top" leftline="true" width="0">
+<column alignment="center" valignment="top" leftline="true" width="0">
+<column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
+<row topline="true" bottomline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+
+\emph on 
+n
+\end_inset 
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+Interrupt Vector
+\end_inset 
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+Interrupt Vector Address
+\end_inset 
+</cell>
+</row>
+<row topline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+0
+\end_inset 
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+RESET vector
+\end_inset 
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+0x000000
+\end_inset 
+</cell>
+</row>
+<row topline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+
+\family roman 
+\series medium 
+\shape up 
+\size normal 
+\emph off 
+\bar no 
+\noun off 
+\color none
+1
+\end_inset 
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\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 
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+0x000008
+\end_inset 
+</cell>
+</row>
+<row topline="true" bottomline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+2
+\end_inset 
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+LOW priority interrupts
+\end_inset 
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+0x000018
+\end_inset 
+</cell>
+</row>
+</lyxtabular>
+
+\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
 
 
index 098e36cddc148434f42363f130cf3d813b0b163f..60820b75b9c19702456f7bc31ae4ec534de81d2f 100644 (file)
@@ -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); }
index d2aaedc06d2a7bf541069f820b42ae72d16e8619..3e3c7b3eba875d405f0c2b20f98c77329d954d17 100644 (file)
@@ -89,6 +89,7 @@ bool uselessDecl = TRUE;
 %token <yyint> 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($$)) {
index 7ccca8c333cf0003ef27fba9cb77bc1bd523a630..dbcfd6630cdbf25ce093efed252442fc456aede3 100644 (file)
@@ -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);
index 5ed6048e84072d2a21ad2bda70f72b31612a76d7..1dced6d02702eb8f71290a862b20ee489a4e6154 100644 (file)
@@ -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)
index 70e132b96ee3affb997e8411f49ee48ac7b6e521..b61a5820ee936cbc1aa3087b02fc32f1c3fece65 100644 (file)
@@ -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 */
index a570358a684be58910c1f0cfe1c9ccf10b6ee5c5..7e51fb27680fcfb49e618420a9920cd0942d7b58 100644 (file)
@@ -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
 };
 
index 98854b6b725f2400d1fb6755bb18ef683ef383a0..802545e6310df1fa56c6d204b7ad15c1295ba475 100644 (file)
@@ -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;
                                        }
                                }
index e0674aebe74fb082e51175a9bb18fd82844585eb..6542a7ead5085cf3e3b59903c93da0aab02b3a72 100644 (file)
@@ -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'" },
 };
 
 /*
index 728c97539481db9813b402d0e4e4eb928e19ca5b..a08c84122bf491a9b65ca8bdd649fdad7c450180 100644 (file)
@@ -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 */