2004-11-04 Vangelis Rokas <vrokas AT otenet.gr>
authorvrokas <vrokas@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Thu, 4 Nov 2004 12:34:49 +0000 (12:34 +0000)
committervrokas <vrokas@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Thu, 4 Nov 2004 12:34:49 +0000 (12:34 +0000)
* src/pic16/main.c (options): added command line --gstack, to trace
stack over/under flows,
* added pragma 'wparam' to allow passing first byte of function
parameters via WREG, syntax is #pragma wparam my_function[, func2...]
* src/pic16/gen.c (pic16_testStackOverflow): function which emits a
call to __gstack_test function and sets up the symbol as extern,
* (pic16_pushpCodeOp, pic16_poppCodeOp, pushw, pushaop, popaopidx,
* popaop): added call to pic16_testStackOverflow,
* (wParamCmp, inWparamList): NEW, test existence of a symbol in
wparamList list,
* (genCall, genPcall): now all parameters are passed via stack
except in functions that are pass to wparam pragma in which WREG is
used too,
* (genPcall): REENTRANT flag is checked to see if variable prototype
contains reentrant keyword, don't call a non-reentrant function, via
a reentrant function pointer or vice versa, functions are never
passed via WREG,
* (genJumpTab): applied patch from bug #1057478 by R.Neider and
D.Winkler,
* src/pic16/glue.c (pic16emitRegularMap): fixed bug which caused a
SIGSEGV when accessing a NULL register stucture,
* (pic16_printGPointerType): modified to handle UPPER modifier for
function initializers, changed prototype of function to simpler one,
* (pic16_printIvalFuncPtr): check to see if function is already
added in externs list,
* src/pic16/pcoderegs.c (pCodeOptime2pCodes): fixed bug which
optimized a move from W to SFR with a move to the same register
later after a CALL,
* device/lib/pic16/debug: NEW directory, contains debug features
which are enabled when linking with libdebug.lib, currently command
line option --gstack enables stack pointer tracing for over/under
flow, corresponding sources are in debug/gstack

git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3564 4a8a32a2-be11-0410-ad9d-d568d2c75423

15 files changed:
ChangeLog
device/lib/pic16/Makefile
device/lib/pic16/Makefile.common.in
device/lib/pic16/debug/Makefile [new file with mode: 0644]
device/lib/pic16/debug/Makefile.rules [new file with mode: 0644]
device/lib/pic16/debug/gstack/Makefile [new file with mode: 0644]
device/lib/pic16/debug/gstack/gstack.c [new file with mode: 0644]
src/pic16/gen.c
src/pic16/genutils.c
src/pic16/genutils.h
src/pic16/glue.c
src/pic16/main.c
src/pic16/main.h
src/pic16/pcode.h
src/pic16/pcoderegs.c

index d545400f233cb4b461ecb58079e6389b12686f2d..2a4a258e443e1d1e8bd7fe0e4e746ec88e32170c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,38 @@
+2004-11-04 Vangelis Rokas <vrokas AT otenet.gr>
+
+       * src/pic16/main.c (options): added command line --gstack, to trace
+       stack over/under flows,
+       * added pragma 'wparam' to allow passing first byte of function
+       parameters via WREG, syntax is #pragma wparam my_function[, func2...]
+       * src/pic16/gen.c (pic16_testStackOverflow): function which emits a
+       call to __gstack_test function and sets up the symbol as extern,
+       * (pic16_pushpCodeOp, pic16_poppCodeOp, pushw, pushaop, popaopidx,
+       * popaop): added call to pic16_testStackOverflow,
+       * (wParamCmp, inWparamList): NEW, test existence of a symbol in
+       wparamList list,
+       * (genCall, genPcall): now all parameters are passed via stack
+       except in functions that are pass to wparam pragma in which WREG is
+       used too,
+       * (genPcall): REENTRANT flag is checked to see if variable prototype
+       contains reentrant keyword, don't call a non-reentrant function, via
+       a reentrant function pointer or vice versa, functions are never
+       passed via WREG,
+       * (genJumpTab): applied patch from bug #1057478 by R.Neider and
+       D.Winkler,
+       * src/pic16/glue.c (pic16emitRegularMap): fixed bug which caused a
+       SIGSEGV when accessing a NULL register stucture,
+       * (pic16_printGPointerType): modified to handle UPPER modifier for
+       function initializers, changed prototype of function to simpler one,
+       * (pic16_printIvalFuncPtr): check to see if function is already
+       added in externs list,
+       * src/pic16/pcoderegs.c (pCodeOptime2pCodes): fixed bug which
+       optimized a move from W to SFR with a move to the same register
+       later after a CALL,
+       * device/lib/pic16/debug: NEW directory, contains debug features
+       which are enabled when linking with libdebug.lib, currently command
+       line option --gstack enables stack pointer tracing for over/under
+       flow, corresponding sources are in debug/gstack
+
 2004-10-30 Vangelis Rokas <vrokas AT otenet.gr>
 
        * doc/sdccman.lyx: updated SDCC version,
index 35ecb4dea23e78c4226e13665bbddf3e03f15708..1592f5803c908734acfc148642775b2cd57bab0c 100644 (file)
@@ -17,7 +17,8 @@ include ./Makefile.common
 
 DIRS   =       libdev  \
                libsdcc \
-               startup
+               startup \
+               debug
 
 
 all: build-all-libraries
index 7ca93e249adc72463cfd9d076a75aec74f6ab5c8..13e1e2eccd8afe9029fa57c3ef8e0ab8bbc35062 100644 (file)
@@ -28,4 +28,4 @@ SED   = @SED@
 # but it's needed for `make clean`; Bernhard
 MM = -MM
 
-MODELFLAGS      = -mpic16
\ No newline at end of file
+MODELFLAGS      = -mpic16
diff --git a/device/lib/pic16/debug/Makefile b/device/lib/pic16/debug/Makefile
new file mode 100644 (file)
index 0000000..231e9d7
--- /dev/null
@@ -0,0 +1,54 @@
+#
+# Makefile - Makefile to build pic16 debug library
+#
+# This file is part of the GNU PIC Library.
+#
+# January, 2004
+# The GNU PIC Library is maintained by,
+#      Vangelis Rokas <vrokas@otenet.gr>
+#
+# $Id$
+#
+#
+
+
+DIRS   =       gstack
+
+
+LIB    = libdebug.lib
+
+all: build-libraries
+
+make-target: build-libraries
+
+build-libraries:
+       for dir in $(DIRS) ; do  \
+               $(MAKE) -C $$dir ; \
+       done;
+       gplib -c $(LIB) gstack/*.o
+       mv -v $(LIB) ../bin
+       
+
+clean-intermediate:
+       @for dir in $(DIRS) ; do \
+               $(MAKE) -C $$dir clean-intermediate ; \
+       done ;
+       
+clean:
+       for dir in $(DIRS) ; do \
+               $(MAKE) -C $$dir clean; \
+       done ;
+       rm -fv $(LIB)
+
+
+real-clean: clean
+       find -name *.adb -print | xargs -- rm -fv ;
+       find -name *.p -print | xargs -- rm -fv ;
+       find -name *.d -print | xargs -- rm -fv ;
+       find -name *.dump* -print | xargs -- rm -fv ;
+       
+
+dep:
+       for dir in $(DIRS) ; do \
+               $(MAKE) -C $$dir dep; \
+       done
diff --git a/device/lib/pic16/debug/Makefile.rules b/device/lib/pic16/debug/Makefile.rules
new file mode 100644 (file)
index 0000000..3faf727
--- /dev/null
@@ -0,0 +1,49 @@
+#
+# Makefile.rules - Common Makefile rules to build pic16
+#                  debug library
+#
+# This file is part of the GNU PIC Library.
+#
+# January, 2004
+# The GNU PIC Library is maintained by,
+#      Vangelis Rokas <vrokas@otenet.gr>
+#
+# $Id$
+#
+#
+
+
+include ../../Makefile.common
+
+PRJDIR = ../../../../..
+
+LIBC_INC_DIR   = $(PRJDIR)/device/include/pic16
+
+COMPILE_FLAGS  += $(MODELFLAGS) --pomit-config-words --pomit-ivt --no-peep --i-code-in-asm
+CFLAGS = --nostdinc -I$(LIBC_INC_DIR)
+
+CFILES = $(patsubst %,%.c,$(SRCS))
+OFILES = $(patsubst %.c,%.o,$(CFILES))
+
+%.o: %.c
+       $(CC) $(CFLAGS) $(COMPILE_FLAGS) -c $<
+
+
+all: build-library
+
+clean-intermediate:
+       $(RM) -f *.lst *.asm *.dump* *.p *.d *.adb
+
+
+clean: clean-intermediate
+       $(RM) -f $(LIB) *.o
+
+dep .depend:
+       rm -f .depend
+       for temp in $(CFILES); do \
+               $(CPP) $(MM) $(CFLAGS) $$temp > .tmpdepend; \
+               $(SED) s/.rel/.o/g .tmpdepend >> .depend; \
+               $(RM) -f .tmpdepend; \
+       done;
+
+include .depend
diff --git a/device/lib/pic16/debug/gstack/Makefile b/device/lib/pic16/debug/gstack/Makefile
new file mode 100644 (file)
index 0000000..3925e4b
--- /dev/null
@@ -0,0 +1,23 @@
+#
+# Makefile - Makefile to build pic16 stack tracing support function
+#
+# This file is part of the GNU PIC Library.
+#
+# January, 2004
+# The GNU PIC Library is maintained by,
+#      Vangelis Rokas <vrokas@otenet.gr>
+#
+# $Id$
+#
+#
+
+
+SRCS   =       gstack
+
+
+include ../Makefile.rules
+
+
+all: build-library
+
+build-library: $(OFILES)
diff --git a/device/lib/pic16/debug/gstack/gstack.c b/device/lib/pic16/debug/gstack/gstack.c
new file mode 100644 (file)
index 0000000..9cd8b16
--- /dev/null
@@ -0,0 +1,199 @@
+/*-------------------------------------------------------------------------
+
+   gstack.c :- debug stack tracing support function
+
+   Written for pic16 port by Vangelis Rokas, 2004 (vrokas@otenet.gr)
+
+   This library is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Library General Public License as published by the
+   Free Software Foundation; either version 2, or (at your option) any
+   later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+   In other words, you are welcome to use, share and improve this program.
+   You are forbidden to forbid anyone else to use, share and improve
+   what you give them.   Help stamp out software-hoarding!
+-------------------------------------------------------------------------*/
+/*
+** $Id$
+*/
+
+extern WREG;
+extern FSR1L;
+extern FSR1H;
+extern FSR0L;
+extern FSR0H;
+extern STATUS;
+extern POSTINC0;
+extern POSTDEC1;
+extern PREINC1;
+extern TOSL;
+extern TOSH;
+extern TOSU;
+extern PCL;
+extern PCLATH;
+extern PCLATU;
+extern stack;
+extern stack_end;
+
+#pragma udata access _wreg_store _status_store _fsr0_store
+#pragma udata access _gstack_begin _gstack_end _init_ok
+
+static char _init_ok=0;
+static char _wreg_store;
+static char _status_store;
+static unsigned int _fsr0_store;
+static unsigned int _gstack_begin;
+static unsigned int _gstack_end;
+
+char _gstack_fail_str[]="Stack overflow\n";
+char _gstack_succ_str[]="Stack ok\n";
+
+
+static
+void _gstack_overflow_default(void) _naked
+{
+  _asm
+    lfsr       0, __gstack_fail_str
+;    incf      _FSR0L, f
+
+@0:
+    movf       _POSTINC0, w
+    movff      _WREG, 0xf7f
+    bnz                @0
+    
+;    sleep
+@00:
+    goto       @00
+    
+  _endasm ;
+}
+
+void (* _gstack_overflow)(void)=_gstack_overflow_default;
+
+    
+void _gstack_init(void) _naked
+{
+  _asm
+    
+    movlw      LOW(_stack)
+    movwf      __gstack_begin
+    
+    movlw      HIGH(_stack)
+    movwf      __gstack_begin+1
+
+    movlw      LOW(_stack_end)
+    movwf      __gstack_end
+    
+    movlw      HIGH(_stack_end)
+    movwf      __gstack_end+1
+
+    ; load default handler
+;    movlw     LOW(__gstack_overflow_default)
+;    movwf     __gstack_overflow
+    
+;    movlw     HIGH(__gstack_overflow_default)
+;    movwf     __gstack_overflow+1
+    
+;    movlw     UPPER(__gstack_overflow_default)
+;    movwf     __gstack_overflow+2
+    
+
+    movlw      1
+    movwf      __init_ok
+    
+    return;    
+  _endasm ;
+}
+
+
+void _gstack_test(void) _naked
+{
+  _asm
+    movff      _WREG, __wreg_store
+    movff      _STATUS, __status_store
+
+    ; if first time, initialize boundary variables
+    movf       __init_ok, w
+    bnz                @1
+    call       __gstack_init
+    
+@1:
+    movf       __gstack_begin, w
+    cpfslt     _FSR1L
+    bra                @2
+    bra                @3
+
+@2:
+    movf       __gstack_begin+1, w
+    cpfslt     _FSR1H
+    bra                @4
+    bra                @3
+
+@4:
+    movf       __gstack_end, w
+    cpfsgt     _FSR1L
+    bra                @5
+    bra                @3
+
+@5:
+    movf       __gstack_end+1, w
+    cpfsgt     _FSR1H
+    bra                @6
+
+    ; fail
+
+@3:
+
+    push
+    movlw      LOW(ret_lab)
+    movwf      _TOSL
+
+    movlw      HIGH(ret_lab)
+    movwf      _TOSH
+
+    movlw      UPPER(ret_lab)
+    movwf      _TOSU
+
+    movff      __gstack_overflow+2, _PCLATU
+    movff      __gstack_overflow+1, _PCLATH
+    movf       __gstack_overflow, w
+    
+    ; execute 
+    movwf      _PCL
+    
+ret_lab:
+    bra                @10
+
+    ; success
+@6:
+    movff      _FSR0L, __fsr0_store
+    movff      _FSR0H, __fsr0_store+1
+    lfsr       0, __gstack_succ_str
+
+    ; print corresponding string
+@8:
+    movf       _POSTINC0, w
+    movff      _WREG, 0xf7f
+    bnz                @8
+
+@9:
+    movff      __fsr0_store+1, _FSR0H
+    movff      __fsr0_store, _FSR0L
+
+@10:
+    movff      __status_store, _STATUS
+    movff      __wreg_store, _WREG
+    
+    return
+    
+    _endasm ;
+}
index ee1c04d439f2c33beffd3f8aa16733aba7db1ab6..668eccf2f42fe3a180d381e89ae2e249279d9b59 100644 (file)
@@ -72,6 +72,8 @@ static int optimized_for_speed = 0;
 
 */
 
+extern set *externs;
+
 /* max_key keeps track of the largest label number used in 
    a function. This is then used to adjust the label offset
    for the next function.
@@ -2235,18 +2237,38 @@ static void mov2fp(pCodeOp *dst, asmop *src, int offset)
   }
 }
 
+void pic16_testStackOverflow(void)
+{
+#define        GSTACK_TEST_NAME        "__gstack_test"
+
+  pic16_emitpcode(POC_CALL, pic16_popGetWithString( GSTACK_TEST_NAME ));
+  
+  {
+    symbol *sym;
+
+      sym = newSymbol( GSTACK_TEST_NAME , 0 );
+      strcpy(sym->rname, GSTACK_TEST_NAME);
+      checkAddSym(&externs, sym);
+  }
+
+}
 
 /* push pcop into stack */
 void pic16_pushpCodeOp(pCodeOp *pcop)
 {
 //     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-       pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pcop, pic16_popCopyReg(&pic16_pc_postdec1)));
+  pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pcop, pic16_popCopyReg(&pic16_pc_postdec1)));
+  if(pic16_options.gstack)
+    pic16_testStackOverflow();
+    
 }
 
 /* pop pcop from stack */
 void pic16_poppCodeOp(pCodeOp *pcop)
 {
-       pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_preinc1), pcop));
+  pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_preinc1), pcop));
+  if(pic16_options.gstack)
+    pic16_testStackOverflow();
 }
 
 
@@ -2255,8 +2277,10 @@ void pic16_poppCodeOp(pCodeOp *pcop)
 /*-----------------------------------------------------------------*/
 void pushw(void)
 {
-        DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-       pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postdec1));
+  DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+  pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postdec1));
+  if(pic16_options.gstack)
+    pic16_testStackOverflow();
 }
 
                 
@@ -2265,8 +2289,19 @@ void pushw(void)
 /*-----------------------------------------------------------------*/
 void pushaop(asmop *aop, int offset)
 {
-        DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-        pic16_emitpcode(POC_MOVFF, pic16_popCombine2(PCOR(pic16_popGet(aop, offset)), &pic16_pc_postdec1, 0));
+  DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+
+  if(is_LitAOp(aop)) {
+    pic16_emitpcode(POC_MOVLW, pic16_popGet(aop, offset));
+    pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postdec1));
+  } else {
+    pic16_emitpcode(POC_MOVFF,
+      pic16_popGet2p(pic16_popGet(aop, offset), pic16_popCopyReg(&pic16_pc_postdec1)));
+  }
+
+//  pic16_emitpcode(POC_MOVFF, pic16_popCombine2(PCOR(pic16_popGet(aop, offset)), &pic16_pc_postdec1, 0));
+  if(pic16_options.gstack)
+    pic16_testStackOverflow();
 }
 
 /*-----------------------------------------------------------------*/
@@ -2274,20 +2309,24 @@ void pushaop(asmop *aop, int offset)
 /*-----------------------------------------------------------------*/
 void popaop(asmop *aop, int offset)
 {
-       DEBUGpic16_emitcode("; ***", "%s  %d", __FUNCTION__, __LINE__);
-       pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_preinc1, PCOR(pic16_popGet(aop, offset)), 0));
+  DEBUGpic16_emitcode("; ***", "%s  %d", __FUNCTION__, __LINE__);
+  pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_preinc1, PCOR(pic16_popGet(aop, offset)), 0));
+  if(pic16_options.gstack)
+    pic16_testStackOverflow();
 }
 
 void popaopidx(asmop *aop, int offset, int index)
 {
   int ofs=1;
 
-        DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-       if(STACK_MODEL_LARGE)ofs++;
+    if(STACK_MODEL_LARGE)ofs++;
 
-       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(index + ofs));
-        pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_plusw2, PCOR(pic16_popGet(aop, offset)), 0));
+    pic16_emitpcode(POC_MOVLW, pic16_popGetLit(index + ofs));
+    pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_plusw2, PCOR(pic16_popGet(aop, offset)), 0));
+    if(pic16_options.gstack)
+      pic16_testStackOverflow();
 }
 
 /*-----------------------------------------------------------------*/
@@ -2814,6 +2853,7 @@ static void assignResultValue(operand * oper, int rescall)
         /* >32-bits, result on stack, and FSR0 points to beginning.
         * Fix stack when done */
        /* FIXME FIXME */
+//     debugf("WARNING: Possible bug when returning more than 4-bytes\n");
        while (size--) {
 //         DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
 //          DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
@@ -2833,7 +2873,7 @@ static void assignResultValue(operand * oper, int rescall)
     } else {
       int areg = 0;            /* matching argument register */
       
-      debugf("_G.useWreg = %d\n", _G.useWreg);
+//      debugf("_G.useWreg = %d\tGpsuedoStkPtr = %d\n", _G.useWreg, GpsuedoStkPtr);
       areg = SPEC_ARGREG( OP_SYM_ETYPE( oper ) ) - 1;
 
 
@@ -2846,6 +2886,7 @@ static void assignResultValue(operand * oper, int rescall)
           size--;
           pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper), offset /*size*/));
           offset++;
+//          debugf("receive from WREG\n", 0);
         }
       }
 //      GpsuedoStkPtr++;
@@ -2855,6 +2896,7 @@ static void assignResultValue(operand * oper, int rescall)
         size--;
         GpsuedoStkPtr++;
         popaopidx(AOP(oper), offset, GpsuedoStkPtr);
+//        debugf("receive from STACK\n", 0);
         offset++;
       }
     }
@@ -2870,7 +2912,6 @@ static void genIpush (iCode *ic)
 
   DEBUGpic16_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
 
-
   if(ic->parmPush) {
     pic16_aopOp(IC_LEFT(ic), ic, FALSE );
 
@@ -3036,6 +3077,17 @@ static void saverbank (int bank, iCode *ic, bool pushPsw)
 #endif /* 0 */
 
 
+static int wparamCmp(void *p1, void *p2)
+{
+  return (!strcmp((char *)p1, (char *)p2));
+}
+
+int inWparamList(char *s)
+{
+  return isinSetWith(wparamList, s, wparamCmp);
+} 
+
+
 /*-----------------------------------------------------------------*/
 /* genCall - generates a call statement                            */
 /*-----------------------------------------------------------------*/
@@ -3044,6 +3096,7 @@ static void genCall (iCode *ic)
   sym_link *ftype;   
   int stackParms=0;
   int use_wreg=0;
+  int inwparam=0;
   char *fname;
   
     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
@@ -3057,6 +3110,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);
 
 #if 0
     gpsimDebug_StackDump(__FILE__, __LINE__, fname );
@@ -3066,85 +3120,76 @@ static void genCall (iCode *ic)
     if (_G.sendSet) {
       iCode *sic;
       int psuedoStkPtr=-1; 
-#if USE_WREG_IN_FUNC_PARAMS
       int firstTimeThruLoop = 1;
-#endif
 
-#if 1
+
         /* reverse sendSet if function is not reentrant */
         if(!IFFUNC_ISREENT(ftype))
           _G.sendSet = reverseSet(_G.sendSet);
-#endif
 
        /* First figure how many parameters are getting passed */
-
-/*     do we really need to know this ? -- VR 
-       for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
-         pic16_aopOp(IC_LEFT(sic),sic,FALSE);
-          psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
-          pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
-        }
-*/
-
-
-//        stackParms = psuedoStkPtr;
         stackParms = 0;
         use_wreg = 0;
         
         for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
           int size;
-#if USE_WREG_IN_FUNC_PARAMS
-          int offset = 0;
-#endif
+//          int offset = 0;
+
             pic16_aopOp(IC_LEFT(sic),sic,FALSE);
             size = AOP_SIZE(IC_LEFT(sic));
 
             stackParms += size;
 
-            /* set the following to 1 to enable passing arguments via WREG */
-#if USE_WREG_IN_FUNC_PARAMS
-            while (size--) {
-              DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
-                    pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
-              DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
+            /* pass the last byte through WREG */
+            if(inwparam) {
 
-              if(!firstTimeThruLoop) {
-                /* If this is not the first time we've been through the loop
-                 * then we need to save the parameter in a temporary
-                 * register. The last byte of the last parameter is
-                 * passed in W. */
+              while (size--) {
+                DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
+                      pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
+                DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
 
-                pushw();
-//                --psuedoStkPtr;              // sanity check
-                use_wreg = 1;
-              }
+                if(!firstTimeThruLoop) {
+                  /* If this is not the first time we've been through the loop
+                   * then we need to save the parameter in a temporary
+                   * register. The last byte of the last parameter is
+                   * passed in W. */
+
+                  pushw();
+//                  --psuedoStkPtr;            // sanity check
+                  use_wreg = 1;
+                }
                 
-              firstTimeThruLoop=0;
+                firstTimeThruLoop=0;
 
-              mov2w (AOP(IC_LEFT(sic)), size);
+                mov2w (AOP(IC_LEFT(sic)), size);
 
-              offset++;
-            }
-#else
-            /* all arguments are passed via stack */
-            while (size--) {
-              DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
-                    pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
-              DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
-
-              mov2w (AOP(IC_LEFT(sic)), size);
-              pushw();
+//                offset++;
+              }
+            } else {
+              /* all arguments are passed via stack */
+              use_wreg = 0;
+
+              while (size--) {
+                DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
+                      pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
+                DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
+
+//                pushaop(AOP(IC_LEFT(sic)), size);
+                mov2w (AOP(IC_LEFT(sic)), size);
+                pushw();
+              }
             }
-#endif
 
             pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
           }
 
-#if USE_WREG_IN_FUNC_PARAMS
-          /* save last parameter to stack if functions has varargs */
-          if(IFFUNC_HASVARARGS(ftype) || IFFUNC_ISREENT(ftype))pushw();
-          else use_wreg = 1;           /* last parameter in WREG */
-#endif
+          if(inwparam) {
+            if(IFFUNC_HASVARARGS(ftype) || IFFUNC_ISREENT(ftype)) {
+              pushw(); /* save last parameter to stack if functions has varargs */
+              use_wreg = 0;
+            } else
+              use_wreg = 1;
+          } else use_wreg = 0;
 
           _G.stackRegSet = _G.sendSet;
           _G.sendSet = NULL;
@@ -3154,6 +3199,7 @@ static void genCall (iCode *ic)
     pic16_emitpcode(POC_CALL,pic16_popGetWithString(fname));
 
     GpsuedoStkPtr=0;
+    
     /* if we need to assign a result value */
     if ((IS_ITEMP(IC_RESULT(ic))
           && (OP_SYMBOL(IC_RESULT(ic))->nRegs
@@ -3217,82 +3263,36 @@ static void genCall (iCode *ic)
 /*-----------------------------------------------------------------*/
 static void genPcall (iCode *ic)
 {
-  sym_link *ftype;
+  sym_link *ftype, *fntype;
   int stackParms=0;
-  int use_wreg=0;
   symbol *retlbl = newiTempLabel(NULL);
   pCodeOp *pcop_lbl = pic16_popGetLabel(retlbl->key);
   
     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
     ftype = OP_SYM_TYPE(IC_LEFT(ic));
-    
+    fntype = operandType( IC_LEFT(ic) )->next;
+
     /* if send set is not empty the assign */
     if (_G.sendSet) {
       iCode *sic;
       int psuedoStkPtr=-1; 
-#if USE_WREG_IN_FUNC_PARAMS
-      int firstTimeThruLoop = 1;
-#endif
-
-      /* For the Pic port, there is no data stack.
-       * So parameters passed to functions are stored
-       * in registers. (The pCode optimizer will get
-       * rid of most of these :). */
-
 
-#if 1
       /* reverse sendSet if function is not reentrant */
-      if(!IFFUNC_ISREENT(ftype))
+      if(!IFFUNC_ISREENT(fntype))
         _G.sendSet = reverseSet(_G.sendSet);
-#endif
-
-      /* First figure how many parameters are getting passed */
-#if 0
-      for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
-        pic16_aopOp(IC_LEFT(sic),sic,FALSE);
-        psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
-        pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
-      }
-#endif
 
-//      stackParms = psuedoStkPtr;
       stackParms = 0;
-
+      
       for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
         int size;
-#if USE_WREG_IN_FUNC_PARAMS
-        int offset = 0;
-#endif
 
           pic16_aopOp(IC_LEFT(sic),sic,FALSE);
           size = AOP_SIZE(IC_LEFT(sic));
           stackParms += size;
 
-#if USE_WREG_IN_FUNC_PARAMS
-          while (size--) {
-            DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
-            pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
-            DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
-
-            if(!firstTimeThruLoop) {
-              /* If this is not the first time we've been through the loop
-               * then we need to save the parameter in a temporary
-               * register. The last byte of the last parameter is
-               * passed in W. */
-
-              pushw();
-              --psuedoStkPtr;          // sanity check
-            }
-                       
-            firstTimeThruLoop=0;
-
-            mov2w (AOP(IC_LEFT(sic)), size);
-            use_wreg = 1;
-
-            offset++;
-          }
-#else
+          /* all parameters are passed via stack, since WREG is clobbered
+           * by the calling sequence */
           while (size--) {
             DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
             pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
@@ -3301,16 +3301,10 @@ static void genPcall (iCode *ic)
             mov2w (AOP(IC_LEFT(sic)), size);
             pushw();
           }
-#endif
 
           pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
       }
 
-#if USE_WREG_IN_FUNC_PARAMS
-      if(IFFUNC_HASVARARGS(ftype) || IFFUNC_ISREENT(ftype))pushw();
-      else use_wreg = 1;               /* last parameter in WREG */
-#endif
-
       _G.stackRegSet = _G.sendSet;
       _G.sendSet = NULL;
     }
@@ -3362,7 +3356,7 @@ static void genPcall (iCode *ic)
       pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
     }
 
-    stackParms -= use_wreg;
+//    stackParms -= use_wreg;
     
     if(stackParms>0) {
       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms));
@@ -3565,7 +3559,10 @@ static void genFunction (iCode *ic)
     if(strcmp(sym->name, "main")) {
       if(1  /*!options.ommitFramePtr || sym->regsUsed*/) {
         /* setup the stack frame */
-        pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr2l, &pic16_pc_postdec1, 0));
+        if(STACK_MODEL_LARGE)
+          pic16_pushpCodeOp(pic16_popCopyReg(&pic16_pc_fsr2h));
+        pic16_pushpCodeOp(pic16_popCopyReg(&pic16_pc_fsr2l));
+//        pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr2l, &pic16_pc_postdec1, 0));
         pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1l, &pic16_pc_fsr2l, 0));
         if(STACK_MODEL_LARGE)
           pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1h, &pic16_pc_fsr2h, 0));
@@ -3583,13 +3580,13 @@ static void genFunction (iCode *ic)
       pic16_emitpcode(POC_DECF, pic16_popCopyReg(&pic16_pc_fsr1h));
     }
           
-#if USE_WREG_IN_FUNC_PARAMS
-    if(IFFUNC_HASVARARGS(sym->type) || IFFUNC_ISREENT(sym->type))
+    if(inWparamList(sym->name)) {
+      if(IFFUNC_HASVARARGS(sym->type) || IFFUNC_ISREENT(sym->type))
+        _G.useWreg = 0;
+      else
+        _G.useWreg = 1;
+    } else
       _G.useWreg = 0;
-    else _G.useWreg = 1;
-#else
-    _G.useWreg = 0;
-#endif
 
     /* if callee-save to be used for this function
      * then save the registers being used in this function */
@@ -3675,8 +3672,10 @@ static void genEndFunction (iCode *ic)
       if(1/*!options.ommitFramePtr ||*/ /*sym->regsUsed*/) {
         /* restore stack frame */
         if(STACK_MODEL_LARGE)
-          pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2h, 0));
-        pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2l, 0));
+          pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr2h ));
+//          pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2h, 0));
+        pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr2l ));
+//        pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2l, 0));
       }
     }
 
@@ -10427,7 +10426,6 @@ static void genGenPointerGet (operand *left,
 }
 #endif
 
-extern set *externs;
 
 /*-----------------------------------------------------------------*/
 /* genGenPointerGet - gget value from generic pointer space        */
@@ -11347,7 +11345,8 @@ static void genGenPointerSet (operand *right,
      * by the support function this restoring the stack. The important
      * thing is that there is no need to manually restore stack pointer
      * here */
-    mov2fp(pic16_popCopyReg(&pic16_pc_postdec1), AOP(right), 0);
+    pushaop(AOP(right), 0);
+//    mov2fp(pic16_popCopyReg(&pic16_pc_postdec1), AOP(right), 0);
     if(size>1)mov2fp(pic16_popCopyReg(&pic16_pc_prodh), AOP(right), 1);
     if(size>2)mov2fp(pic16_popCopyReg(&pic16_pc_tblptrl), AOP(right), 2);
     if(size>3)mov2fp(pic16_popCopyReg(&pic16_pc_tblptrh), AOP(right), 3);
@@ -11789,7 +11788,7 @@ static void genAssign (iCode *ic)
     } else if (AOP_TYPE(right) == AOP_CRY) {
       pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
       if(offset == 0) {
-        debugf("%s: BTFSS offset == 0\n", __FUNCTION__);
+//        debugf("%s: BTFSS offset == 0\n", __FUNCTION__);
        pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
        pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
       }
@@ -11834,6 +11833,7 @@ static void genJumpTab (iCode *ic)
     pic16_emitcode("jmp","@a+dptr");
     pic16_emitcode("","%05d_DS_:",jtab->key+100);
 
+#if 0
     pic16_emitpcode(POC_MOVLW, pic16_popGetLabel(jtab->key));
     pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_JTCOND(ic)),0));
     emitSKPNC;
@@ -11841,6 +11841,49 @@ static void genJumpTab (iCode *ic)
     pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
     pic16_emitpLabel(jtab->key);
 
+#else
+
+    pCodeOp *jt_offs = pic16_popGetTempReg(0);
+    pCodeOp *jt_offs_hi = pic16_popGetTempReg(1);
+    pCodeOp *jt_label = pic16_popGetLabel (jtab->key);
+    //fprintf (stderr, "Creating jump table...\n");
+
+    // calculate offset into jump table (idx * sizeof (GOTO))
+    pic16_emitpcode(POC_CLRF  , jt_offs_hi);
+    pic16_emitpcode(POC_RLCFW , pic16_popGet(AOP(IC_JTCOND(ic)),0));
+    pic16_emitpcode(POC_RLCF  , jt_offs_hi);
+    pic16_emitpcode(POC_RLCFW , pic16_popCopyReg(&pic16_pc_wreg));
+    pic16_emitpcode(POC_RLCF  , jt_offs_hi);
+    pic16_emitpcode(POC_ANDLW , pic16_popGetLit (0xFC));
+    pic16_emitpcode(POC_MOVWF , jt_offs);
+
+    // prepare PCLATx (set to first entry in jump table)
+    pic16_emitpcode(POC_MOVLW , pic16_popGetImmd(jt_label->name, 2, 0));
+    pic16_emitpcode(POC_MOVWF , pic16_popCopyReg(&pic16_pc_pclatu));
+    pic16_emitpcode(POC_MOVLW , pic16_popGetImmd(jt_label->name, 1, 0));
+    pic16_emitpcode(POC_MOVWF , pic16_popCopyReg(&pic16_pc_pclath));
+    pic16_emitpcode(POC_MOVLW , pic16_popGetImmd(jt_label->name, 0, 0));
+
+    // set PCLATx to selected entry (new PCL is stored in jt_offs)
+    pic16_emitpcode(POC_ADDWF , jt_offs);
+    pic16_emitpcode(POC_MOVFW , jt_offs_hi);
+    pic16_emitpcode(POC_ADDWFC, pic16_popCopyReg(&pic16_pc_pclath));
+    emitSKPNC;
+    pic16_emitpcode(POC_INCF  , pic16_popCopyReg(&pic16_pc_pclatu));
+
+    // release temporaries and prepare jump into table (new PCL --> WREG)
+    pic16_emitpcode(POC_MOVFW , jt_offs);
+    pic16_popReleaseTempReg (jt_offs_hi, 1);
+    pic16_popReleaseTempReg (jt_offs, 0);
+
+    // jump into the table
+    pic16_emitpcode(POC_MOVWF , pic16_popCopyReg(&pic16_pc_pcl));
+
+    // this goto prevents the next label from being removed...
+    pic16_emitpcode(POC_GOTO, jt_label);
+    pic16_emitpLabel(jtab->key);
+
+#endif
     pic16_freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
 
     /* now generate the jump labels */
index ace571cf4ece2ebc253e5f72bc333e3ccc143f60..16dfc1a1aac8fae8e5bf500909da0730f5707a44 100644 (file)
@@ -418,8 +418,6 @@ void pic16_DumpOp(char *prefix, operand *op)
 
 }
 
-//#define      debugf(frm, rest)       _debugf(__FILE__, __LINE__, frm, rest)
-
 void _debugf(char *f, int l, char *frm, ...)
 {
   va_list ap;
index 2f18180133bcbb2b115ec5c2ed3fec2dea7e3576..2c81d09a7255e237cebd2f33eb4f31d6bbc9914e 100644 (file)
@@ -38,7 +38,9 @@ void gpsimio2_lit(unsigned char lit);
 
 void gpsimDebug_StackDump(char *fname, int line, char *info);
 
+#ifndef debugf
 #define debugf(frm, rest)       _debugf(__FILE__, __LINE__, frm, rest)
+#endif
 void _debugf(char *f, int l, char *frm, ...);
 
 #endif /* __GENUTILS_H__ */
index f4087a6f3744b50eb66a496cf3f206fda7be4bf3..b19127f73b5365814c79786079b49a6c48ef17f2 100644 (file)
@@ -80,8 +80,6 @@ void  pic16_pCodeInitRegisters(void);
 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc);
 extern void pic16_pCodeConstString(char *name, char *value);
 
-#define debugf(frm, rest)       _debugf(__FILE__, __LINE__, frm, rest)
-extern void _debugf(char *f, int l, char *frm, ...);
 
 /*-----------------------------------------------------------------*/
 /* aopLiteral - string from a literal value                        */
@@ -180,12 +178,8 @@ pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag)
                                && !(sym->ival && !sym->level)
                        ) {
                          regs *reg;
-                               /* add it to udata list */
-
-//                             fprintf(stderr, "%s:%d adding %s (%s) remat=%d\n", __FILE__, __LINE__,
-//                                     sym->name, sym->rname, sym->remat);
-                                       
-                                               //, OP_SYMBOL(operandFromSymbol(sym))->name);
+                          sectSym *ssym;
+                          int found=0;
 #define SET_IMPLICIT   1
 
 #if SET_IMPLICIT
@@ -195,22 +189,18 @@ pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag)
 
                                reg = pic16_allocDirReg( operandFromSymbol( sym ));
                                
-                               {
-                                 sectSym *ssym;
-                                 int found=0;
-                                 
+                               if(reg) {
 #if 1
-                                       for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) {
-                                               if(!strcmp(ssym->name, reg->name))found=1;
-                                       }
+                                  for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) {
+                                   if(!strcmp(ssym->name, reg->name))found=1;
+                                  }
 #endif
+                                  if(!found)
+                                    checkAddReg(&pic16_rel_udata, reg);
+                                  else
+                                   checkAddSym(&publics, sym);
 
-                                       if(!found)
-                                               checkAddReg(&pic16_rel_udata, reg);
-                                       else
-                                               checkAddSym(&publics, sym);
-
-                               }
+                                }
                        }
 
                /* if extern then do nothing or is a function
@@ -309,17 +299,16 @@ pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag)
                                                        sym->rname, reg, (reg?reg->name:"<<NULL>>"));
 #endif
 
-#if 1
-                                               for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) {
-                                                       if(!strcmp(ssym->name, reg->name))found=1;
-                                               }
-#endif
-
-                                               if(!found)
-                                                       if(checkAddReg(&pic16_rel_udata, reg)) {
-                                                               addSetHead(&publics, sym);
-                                                       }
+                                                if(reg) {
+                                                 for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) {
+                                                   if(!strcmp(ssym->name, reg->name))found=1;
+                                                  }
 
+                                                  if(!found)
+                                                    if(checkAddReg(&pic16_rel_udata, reg)) {
+                                                      addSetHead(&publics, sym);
+                                                    }
+                                                }
                                        }
 
 
@@ -566,8 +555,8 @@ void pic16_printPointerType (const char *name, char ptype, void *p)
 /*-----------------------------------------------------------------*/
 /* printGPointerType - generates ival for generic pointer type     */
 /*-----------------------------------------------------------------*/
-void pic16_printGPointerType (const char *iname, const char *oname, const unsigned int itype,
-  const unsigned int type, char ptype, void *p)
+void pic16_printGPointerType (const char *iname, const unsigned int itype,
+  char ptype, void *p)
 {
   char buf[256];
   
@@ -576,6 +565,7 @@ void pic16_printGPointerType (const char *iname, const char *oname, const unsign
     switch( itype ) {
       case FPOINTER:
       case CPOINTER:
+      case FUNCTION:
         {
           sprintf(buf, "UPPER(%s)", iname);
           pic16_emitDS(buf, ptype, p);
@@ -585,6 +575,9 @@ void pic16_printGPointerType (const char *iname, const char *oname, const unsign
         sprintf(buf, "0x80");
         pic16_emitDS(buf, ptype, p);
         break;
+      default:
+//        debugf("itype = %d\n", itype );
+        assert( 0 );
     }
 
     pic16_flushDB(ptype, p);
@@ -906,7 +899,7 @@ int pic16_printIvalCharPtr (symbol * sym, sym_link * type, value * val, char pty
             // this is a literal string
             type=CPOINTER;
           }
-          pic16_printGPointerType(val->name, sym->name, type, type, ptype, p);
+          pic16_printGPointerType(val->name, type, ptype, p);
         }
       else
         {
@@ -987,22 +980,20 @@ void pic16_printIvalFuncPtr (sym_link * type, initList * ilist, char ptype, void
 
   /* now generate the name */
   if (!val->sym) {
-      pic16_printPointerType (val->name, ptype, p);
+      pic16_printGPointerType (val->name, DCL_TYPE(val->type), ptype, p);
   } else {
-      pic16_printPointerType (val->sym->rname, ptype, p);
+      pic16_printGPointerType (val->sym->rname, DCL_TYPE(val->type), ptype, p);
 
-      if(IS_FUNC(val->sym->type) && !val->sym->used) {
+      if(IS_FUNC(val->sym->type) && !val->sym->used && !IS_STATIC(val->sym->etype)) {
         
         if(!checkSym(publics, val->sym))
-         checkAddSym(&externs, val->sym);
-        
-       /* this has not been declared as extern
-        * so declare it as a 'late extern' just after the symbol */
-       if(ptype == 'f') {
-               fprintf((FILE *)p, "declare symbol as extern");
-               fprintf((FILE *)p, "\textern\t%s\n", val->sym->rname);
-               fprintf((FILE *)p, "continue variable declaration");
-       }
+         if(checkAddSym(&externs, val->sym) && (ptype == 'f')) {
+           /* this has not been declared as extern
+            * so declare it as a 'late extern' just after the symbol */
+           fprintf((FILE *)p, ";\tdeclare symbol as extern\n");
+           fprintf((FILE *)p, "\textern\t%s\n", val->sym->rname);
+           fprintf((FILE *)p, ";\tcontinue variable declaration\n");
+          }
       }
   }
 
@@ -1085,9 +1076,8 @@ void pic16_printIvalPtr (symbol * sym, sym_link * type, initList * ilist, char p
     }
   else if (size == 3)
     {
-      pic16_printGPointerType (val->name, sym->name, (IS_PTR(type)?DCL_TYPE(type):PTR_TYPE(SPEC_OCLS(sym->etype))),
-                         (IS_PTR (val->type) ? DCL_TYPE (val->type) :
-                          PTR_TYPE (SPEC_OCLS (val->etype))), ptype, p);
+      pic16_printGPointerType (val->name, (IS_PTR(type)?DCL_TYPE(type):PTR_TYPE(SPEC_OCLS(sym->etype))),
+                          ptype, p);
     } else
        assert(0);
   return;
index 4667a303cfdae19956ea305c24c9e340ef7258c4..e28d4caa55acf3c1c8a20296dae2522b3e1820f1 100644 (file)
@@ -135,12 +135,13 @@ set *absSymSet;
 
 set *sectNames=NULL;                   /* list of section listed in pragma directives */
 set *sectSyms=NULL;                    /* list of symbols set in a specific section */
-
+set *wparamList=NULL;
 
 static int
 _process_pragma(const char *sz)
 {
   static const char *WHITE = " \t\n";
+  static const char *WHITECOMMA = " \t\n,";
   
   char *ptr = strtok((char *)sz, WHITE);
 
@@ -278,6 +279,19 @@ _process_pragma(const char *sz)
          return 0;
        }
        
+       if(startsWith(ptr, "wparam")) {
+         char *fname = strtok((char *)NULL, WHITECOMMA);
+         
+            while(fname) {
+              addSet(&wparamList, Safe_strdup(fname));
+              
+//              debugf("passing with WREG to %s\n", fname);
+              fname = strtok((char *)NULL, WHITECOMMA);
+            }
+            
+          return 0;
+        }
+       
   return 1;
 }
 
index 813eead64efc3e7ef71b38c0836c689f2f4d179d..9825b3c73863a99b4e420e8d21ede876feec9a0a 100644 (file)
@@ -31,6 +31,7 @@ typedef struct sectSym {
 extern set *absSymSet;
 extern set *sectNames;
 extern set *sectSyms;
+extern set *wparamList;
 
 extern int pic16_mplab_comp;
 extern int pic16_fstack;
index b169350e84e1b71ac8883b099f11f3b1ed67dc7d..2a547d76c4f06c6c70a4308584cdce50dccd8361 100644 (file)
@@ -1023,6 +1023,14 @@ extern void pic16_pcode_test(void);
 extern int pic16_debug_verbose;
 extern int pic16_pcode_verbose;
 
+#ifndef debugf
+//#define debugf(frm, rest...)       _debugf(__FILE__, __LINE__, frm, rest)
+#define debugf(frm, rest)      _debug(__FILE__, __LINE__, frm, rest)
+#endif
+
+extern void _debugf(char *f, int l, char *frm, ...);
+
+
 /*-----------------------------------------------------------------*
  * pCode objects.
  *-----------------------------------------------------------------*/
index ba0098a9c4a2105d16b7427704ed43654b1db8e1..c17a9d02b0dc0f61a68cf3a2305363ccdc72b79c 100644 (file)
@@ -527,13 +527,18 @@ static int pCodeOptime2pCodes(pCode *pc1, pCode *pc2, pCode *pcfl_used, regs *re
 
   }  else if(PCI(pc1)->op == POC_MOVWF) {
 
+    reg1 = pic16_getRegFromInstruction(pc1);
+
+    if(reg1->type == REG_SFR)return (total_registers_saved != t);
+
     pct2 = pic16_findNextInstruction(pc2->next);
 
     if(PCI(pc2)->op == POC_MOVFW) {
-      /*
+
+#if 0
        fprintf(stderr, "   MOVWF/MOVFW. instruction after MOVFW is:\n");
        pct2->print(stderr,pct2);
-      */
+#endif
 
       if(PCI(pct2)->op == POC_MOVWF) {
        /*
@@ -551,8 +556,8 @@ static int pCodeOptime2pCodes(pCode *pc1, pCode *pc2, pCode *pcfl_used, regs *re
            
        */
        reg2 = pic16_getRegFromInstruction(pct2);
-       //if(reg2 && !regUsedinRange(pc1,pc2,reg2) && (reg2->type != REG_SFR)) {
-       if(reg2 && !regUsedinRange(pc1,pc2,reg2)) {
+       if(reg2 && !regUsedinRange(pc1,pc2,reg2) && (reg2->type != REG_SFR)) {
+//     if(reg2 && !regUsedinRange(pc1,pc2,reg2)) 
 
          if(pic16_pCodeSearchCondition(pct2, PCC_Z) < 1) {
            pCode *pct3 = pic16_findNextInstruction(pct2->next);
@@ -573,13 +578,13 @@ static int pCodeOptime2pCodes(pCode *pc1, pCode *pc2, pCode *pcfl_used, regs *re
              //fprintf(stderr,"didn't optimize because Z bit is used\n");
            }
        }
-/*
+#if 0
        fprintf(stderr, " couldn't optimize\n");
        if(reg2)
          fprintf(stderr, " %s is used in range\n",reg2->name);
        else
          fprintf(stderr, " reg2 is NULL\n");
-*/
+#endif
       }
     }
 
@@ -642,7 +647,9 @@ static int pCodeOptime2pCodes(pCode *pc1, pCode *pc2, pCode *pcfl_used, regs *re
        }
       } else if ( (PCI(pct1)->op == POC_MOVWF) &&
           (PCI(pc2)->op == POC_MOVFW)) {
-       //fprintf(stderr,"movwf MOVWF/MOVFW\n");
+
+//        fprintf(stderr,"movwf MOVWF/MOVFW\n");
+
        if(optimize_level > 1 && can_free) {
          pct2 = pic16_newpCode(POC_MOVFW, PCI(pc1)->pcop);
          pic16_pCodeInsertAfter(pc2, pct2);