* device/lib/pic16/libsdcc/Makefile: added lregs directory in
authorvrokas <vrokas@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Wed, 20 Oct 2004 14:02:16 +0000 (14:02 +0000)
committervrokas <vrokas@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Wed, 20 Oct 2004 14:02:16 +0000 (14:02 +0000)
makefile targets,
* device/lib/pic16/libsdcc/lregs/{Makefile,lrst.c,lrrest.c}: NEW
support functions to replace long sequences of MOVFF's from access
bank registers to stack and vice versa,
* src/pic16/device.h: added new field opt_flags, where optimization
flags can be set to enable certain features,
* src/pic16/gen.c (pic16_emitpinfo): NEW to add PC_INFO pCode in
* pBlock, (genFunction, genEndFunction): surroung loop for
saving/loading used registers in stack with PC_INFO pCodes,
INF_LREGS. Code in between can then be optimized by pCode optimizer
to support function calls,
* (genDataPointerSet): fixed bug which loaded float fields in
structures with corrupt data,
* src/pic16/genutils.c (debugf, _debugf): macro/function which emits
in a standard way debug info on stderr. Feature used for developing
and debugging only,
* src/pic16/glue.c (pic16glue): reformatted, deleted some old and
obsolete chunks of code,
* if optimization flag OF_LR_SUPPORT was set, call pic16_OptimizeLocalRegs,
* src/pic16/main.c (_pic16_parseOptions): added handler for --flr-support,
* pic16/src/pcode.c (pic16_newpCodeInfo,
* (pic16_newpCodeOpLocalRegs),
* (pic16_convertLocalRegs2Support): NEW, to support new optimization
feature,
* (pic16_pCodeConstString): printing of the initial value of a
symbol as a comment is inhibited since parsing was already done by
copyStr and output is corrupt,
* (pic16_pCode2str, genericPrint): handle PC_INFO pCode,

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

14 files changed:
ChangeLog
device/lib/pic16/libsdcc/Makefile
device/lib/pic16/libsdcc/float/Makefile
device/lib/pic16/libsdcc/lregs/Makefile [new file with mode: 0644]
device/lib/pic16/libsdcc/lregs/lrrest.c [new file with mode: 0644]
device/lib/pic16/libsdcc/lregs/lrst.c [new file with mode: 0644]
src/pic16/device.h
src/pic16/gen.c
src/pic16/genutils.c
src/pic16/genutils.h
src/pic16/glue.c
src/pic16/main.c
src/pic16/pcode.c
src/pic16/pcode.h

index e7cac1e7d35458c7011b397e86c92a7dcd481411..4f71c922923f4bc32c47c273abcb4cec88d86088 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,35 @@
+2004-10-20 Vangelis Rokas <vrokas AT otenet.gr>
+
+       * device/lib/pic16/libsdcc/Makefile: added lregs directory in
+       makefile targets,
+       * device/lib/pic16/libsdcc/lregs/{Makefile,lrst.c,lrrest.c}: NEW
+       support functions to replace long sequences of MOVFF's from access
+       bank registers to stack and vice versa,
+       * src/pic16/device.h: added new field opt_flags, where optimization
+       flags can be set to enable certain features,
+       * src/pic16/gen.c (pic16_emitpinfo): NEW to add PC_INFO pCode in
+       * pBlock, (genFunction, genEndFunction): surroung loop for
+       saving/loading used registers in stack with PC_INFO pCodes,
+       INF_LREGS. Code in between can then be optimized by pCode optimizer
+       to support function calls,
+       * (genDataPointerSet): fixed bug which loaded float fields in
+       structures with corrupt data,
+       * src/pic16/genutils.c (debugf, _debugf): macro/function which emits
+       in a standard way debug info on stderr. Feature used for developing
+       and debugging only,
+       * src/pic16/glue.c (pic16glue): reformatted, deleted some old and
+       obsolete chunks of code,
+       * if optimization flag OF_LR_SUPPORT was set, call pic16_OptimizeLocalRegs,
+       * src/pic16/main.c (_pic16_parseOptions): added handler for --flr-support,
+       * pic16/src/pcode.c (pic16_newpCodeInfo,
+       * (pic16_newpCodeOpLocalRegs),
+       * (pic16_convertLocalRegs2Support): NEW, to support new optimization
+       feature,
+       * (pic16_pCodeConstString): printing of the initial value of a
+       symbol as a comment is inhibited since parsing was already done by
+       copyStr and output is corrupt,
+       * (pic16_pCode2str, genericPrint): handle PC_INFO pCode,
+
 2004-10-20 Erik Petrich <epetrich AT ivorytower.norman.ok.us>
 
        * src/mcs51/ralloc.c (packRegisters): fixed bug #1044601
index bd6b60d36dceabed1acd0d996c65ea82670aaa71..391342be930687511d70354c8c3d168eeb4cebde 100644 (file)
@@ -16,7 +16,8 @@ DIRS  =       char \
                int \
                long \
                float \
-               gptr
+               gptr \
+               lregs
 
 
 LIB    = libsdcc.lib
index cc1dd1f8725f248dc88f16f3a41b1362535da791..841273e5418845d4e2985628db6b562960937c5f 100644 (file)
@@ -38,9 +38,6 @@ SRCS  =       fs2schar \
 
 include ../Makefile.rules
 
-CFLAGS += -I$(LIBC_INC_DIR)
-
-
 all: build-library
 
 build-library: $(LIB)
diff --git a/device/lib/pic16/libsdcc/lregs/Makefile b/device/lib/pic16/libsdcc/lregs/Makefile
new file mode 100644 (file)
index 0000000..0677a42
--- /dev/null
@@ -0,0 +1,25 @@
+#
+# Makefile - Makefile to build pic16 local register store/restore
+#           support 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$
+#
+#
+
+
+SRCS   =       lrst \
+               lrrest
+
+
+include ../Makefile.rules
+
+
+all: build-library
+
+build-library: $(OFILES)
diff --git a/device/lib/pic16/libsdcc/lregs/lrrest.c b/device/lib/pic16/libsdcc/lregs/lrrest.c
new file mode 100644 (file)
index 0000000..f3c21cd
--- /dev/null
@@ -0,0 +1,46 @@
+/*-------------------------------------------------------------------------
+
+   lrrest.c :- restore local registers in stack upon function exit
+
+   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$
+*/
+
+/* FSR0 points to last register to store, WREG holds the register count
+ */
+extern PREINC1;
+extern POSTDEC0;
+extern WREG;
+
+void _lr_restore(void) _naked
+{
+  _asm
+loop:
+    movff      _PREINC1, _POSTDEC0
+    decfsz     _WREG, f
+    bra                loop
+    
+    return
+  _endasm;
+}
diff --git a/device/lib/pic16/libsdcc/lregs/lrst.c b/device/lib/pic16/libsdcc/lregs/lrst.c
new file mode 100644 (file)
index 0000000..7252805
--- /dev/null
@@ -0,0 +1,46 @@
+/*-------------------------------------------------------------------------
+
+   lrst.c :- store local registers in stack upon function entry
+
+   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$
+*/
+
+/* FSR0 points to first register to store, WREG holds the register count
+ */
+extern POSTDEC1;
+extern POSTINC0;
+extern WREG;
+
+void _lr_store(void) _naked
+{
+  _asm
+loop:
+    movff      _POSTINC0, _POSTDEC1
+    decfsz     _WREG, f
+    bra                loop
+    
+    return
+  _endasm;
+}
index f25163331f7cb69712928763ccab8264bde0776a..f603305506a61eb7eac125492f023c13d2b6057c 100644 (file)
@@ -86,6 +86,8 @@ typedef struct PIC16_device {
 /* Given a pointer to a register, this macro returns the bank that it is in */
 #define REG_ADDR(r)        ((r)->isBitField ? (((r)->address)>>3) : (r)->address)
 
+#define OF_LR_SUPPORT  0x00000001
+
 
 typedef struct {
   int no_banksel;
@@ -100,6 +102,7 @@ typedef struct {
   char *crt_name;
   int no_crt;
   int ip_stack;
+  unsigned long opt_flags;
 } pic16_options_t;
 
 #define STACK_MODEL_SMALL      (pic16_options.stack_model == 0)
index 1424a756b39162f2de134babf4eb9e74651d07ec..159eeb8b559d304db8eb3f5cde1ea12488de16ab 100644 (file)
@@ -297,10 +297,16 @@ void pic16_emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
     pic16_addpCode2pBlock(pb,pic16_newpCode(poc,pcop));
   else
     DEBUGpic16_emitcode(";","%s  ignoring NULL pcop",__FUNCTION__);
-    
-//    fprintf(stderr, "%s\n", pcop->name);
 }
 
+void pic16_emitpinfo(INFO_TYPE itype, pCodeOp *pcop)
+{
+  if(pcop)
+    pic16_addpCode2pBlock(pb, pic16_newpCodeInfo(itype, pcop));
+  else
+    DEBUGpic16_emitcode(";","%s  ignoring NULL pcop",__FUNCTION__);
+}
+  
 void pic16_emitpcodeNULLop(PIC_OPCODE poc)
 {
 
@@ -3547,6 +3553,7 @@ static void genFunction (iCode *ic)
         if (sym->regsUsed) {
           /* save the registers used */
           DEBUGpic16_emitcode("; **", "Saving used registers in stack");
+          pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_ENTRY_BEGIN));
           for ( i = 0 ; i < sym->regsUsed->size ; i++) {
             if (bitVectBitValue(sym->regsUsed,i)) {
               pic16_pushpCodeOp( pic16_popRegFromIdx(i) );
@@ -3559,6 +3566,7 @@ static void genFunction (iCode *ic)
               }
             }
           }
+          pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_ENTRY_END));
         }
     }
        
@@ -3602,6 +3610,7 @@ static void genEndFunction (iCode *ic)
     if (sym->regsUsed) {
       int i;
 
+        pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_EXIT_BEGIN));
         /* restore registers used */
         DEBUGpic16_emitcode("; **", "Restoring used registers from stack");
         for ( i = sym->regsUsed->size; i >= 0; i--) {
@@ -3610,6 +3619,8 @@ static void genEndFunction (iCode *ic)
             _G.nRegsSaved--;
           }
         }
+        pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_EXIT_END));
+
     }
 
     if(strcmp(sym->name, "main")) {
@@ -10826,19 +10837,32 @@ static void genDataPointerSet(operand *right,
 
        while (size--) {
                if (AOP_TYPE(right) == AOP_LIT) {
-                 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
-
-                       lit = lit >> (8*offset);
-                       if(lit&0xff) {
-                               pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff));
-                               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // pstch 8
-                       } else {
-                               pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset)); // patch 8
-                       }
-               } else {
-                       mov2w(AOP(right), offset);
-                       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // patch 8
-               }
+                 unsigned int lit;
+
+                   if(!IS_FLOAT(operandType( right )))
+                     lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
+                    else {
+                      union {
+                        unsigned long lit_int;
+                        float lit_float;
+                      } info;
+       
+                        /* take care if literal is a float */
+                        info.lit_float = floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
+                        lit = info.lit_int;
+                    }
+
+                    lit = lit >> (8*offset);
+                    if(lit&0xff) {
+                      pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff));
+                      pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // pstch 8
+                    } else {
+                      pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset)); // patch 8
+                    }
+                } else {
+                  mov2w(AOP(right), offset);
+                  pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // patch 8
+                }
                offset++;
                resoffset++;
        }
index 284d60ce65abac46384733d48f8685a21ca12b2c..ace571cf4ece2ebc253e5f72bc333e3ccc143f60 100644 (file)
@@ -418,6 +418,19 @@ 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;
+  
+    va_start(ap, frm);
+    fprintf(stderr, "%s:%d ", f, l);
+    vfprintf(stderr, frm, ap);
+    va_end(ap);
+}
+
+
 
 void gpsimio2_pcop(pCodeOp *pcop)
 {
index 07914e33cc66d3f98e06190a0d910938080e120b..2f18180133bcbb2b115ec5c2ed3fec2dea7e3576 100644 (file)
@@ -38,4 +38,7 @@ void gpsimio2_lit(unsigned char lit);
 
 void gpsimDebug_StackDump(char *fname, int line, char *info);
 
+#define debugf(frm, rest)       _debugf(__FILE__, __LINE__, frm, rest)
+void _debugf(char *f, int l, char *frm, ...);
+
 #endif /* __GENUTILS_H__ */
index 73b13398cb04534c156be14a11bf2087ca34df0c..56e458b0f3cd5dd497b91aac15f4fbca898ff34b 100644 (file)
@@ -78,6 +78,9 @@ 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                        */
 /*-----------------------------------------------------------------*/
@@ -659,30 +662,24 @@ pic16_printIvalChar (sym_link * type, initList * ilist, char *s, char ptype, voi
   fprintf(stderr, "%s\n",__FUNCTION__);
 #endif
 
-  if (!s)
-    {
-
-      val = list2val (ilist);
-      /* if the value is a character string  */
-      if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
-       {
-         if (!DCL_ELEM (type))
-           DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
-
-           for(remain=0; remain<DCL_ELEM(type); remain++)
-               pic16_emitDB(SPEC_CVAL(val->etype).v_char[ remain ], ptype, p);
-                       
-         if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0) {
-             while (remain--) {
-                  pic16_emitDB(0x00, ptype, p);
-              }
-          }
-         return 1;
-       }
-      else
-       return 0;
-    }
-  else {
+  if(!s) {
+    val = list2val (ilist);
+    /* if the value is a character string  */
+    if(IS_ARRAY (val->type) && IS_CHAR (val->etype)) {
+      if(!DCL_ELEM (type))
+        DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
+
+      for(remain=0; remain<strlen(SPEC_CVAL(val->etype).v_char)+1; remain++)
+        pic16_emitDB(SPEC_CVAL(val->etype).v_char[ remain ], ptype, p);
+      
+      if((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0) {
+        while(remain--) {
+          pic16_emitDB(0x00, ptype, p);
+        }
+      }
+      return 1;
+    } else return 0;
+  } else {
     for(remain=0; remain<strlen(s); remain++) {
         pic16_emitDB(s[remain], ptype, p);
     }
@@ -1355,7 +1352,7 @@ CODESPACE: %d\tCONST: %d\tPTRCONST: %d\tSPEC_CONST: %d\n", __FUNCTION__,
              if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
                  SPEC_CVAL (sym->etype).v_char) {
                
-//             fprintf(stderr, "%s:%d printing code string from %s\n", __FILE__, __LINE__, sym->rname);
+//             fprintf(stderr, "%s:%d printing code string for %s\n", __FILE__, __LINE__, sym->rname);
 
                pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
              } else {
@@ -1610,233 +1607,218 @@ pic16emitOverlay (FILE * afile)
 void
 pic16glue ()
 {
-
   FILE *vFile;
   FILE *asmFile;
   FILE *ovrFile = tempfile();
 
+    mainf = newSymbol ("main", 0);
+    mainf->block = 0;
 
-       mainf = newSymbol ("main", 0);
-       mainf->block = 0;
+    mainf = findSymWithLevel(SymbolTab, mainf);
 
-       mainf = findSymWithLevel(SymbolTab, mainf);
-#if 0
-       /* only if the main function exists */
-       if (!(mainf = findSymWithLevel (SymbolTab, mainf))) {
-               if (!options.cc_only)
-                       werror (E_NO_MAIN);
-               return;
-       }
-#endif
-
-//     fprintf(stderr, "main function= %p (%s)\thas body= %d\n", mainf, (mainf?mainf->name:NULL), mainf?IFFUNC_HASBODY(mainf->type):-1);
-
-       addSetHead(&tmpfileSet,ovrFile);
-       pic16_pCodeInitRegisters();
+    addSetHead(&tmpfileSet,ovrFile);
+    pic16_pCodeInitRegisters();
 
+    if(pic16_options.no_crt && mainf && IFFUNC_HASBODY(mainf->type)) {
+      pBlock *pb = pic16_newpCodeChain(NULL,'X',pic16_newpCodeCharP("; Starting pCode block"));
 
-       if (pic16_options.no_crt && mainf && IFFUNC_HASBODY(mainf->type)) {
-         pBlock *pb = pic16_newpCodeChain(NULL,'X',pic16_newpCodeCharP("; Starting pCode block"));
+        pic16_addpBlock(pb);
 
-               pic16_addpBlock(pb);
+        /* entry point @ start of CSEG */
+        pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("__sdcc_program_startup",-1));
 
-               /* entry point @ start of CSEG */
-               pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("__sdcc_program_startup",-1));
-
-               if(initsfpnt) {
-                       pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
-                               pic16_popGetLit2(1, pic16_newpCodeOpRegFromStr("_stack_end"))));
-                       pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
-                               pic16_popGetLit2(2, pic16_newpCodeOpRegFromStr("_stack_end"))));
-               }
+        if(initsfpnt) {
+          pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
+                  pic16_popGetLit2(1, pic16_newpCodeOpRegFromStr("_stack_end"))));
+          pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
+                  pic16_popGetLit2(2, pic16_newpCodeOpRegFromStr("_stack_end"))));
+        }
 
-               /* put in the call to main */
-               pic16_addpCode2pBlock(pb,pic16_newpCode(POC_CALL,pic16_newpCodeOp("_main",PO_STR)));
+        /* put in the call to main */
+        pic16_addpCode2pBlock(pb,pic16_newpCode(POC_CALL,pic16_newpCodeOp("_main",PO_STR)));
 
-               if (options.mainreturn) {
-                       pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will return to caller\n"));
-                       pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETURN,NULL));
-               } else {
-                       pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will lock up\n"));
-                       pic16_addpCode2pBlock(pb,pic16_newpCode(POC_GOTO,pic16_newpCodeOp("$",PO_STR)));
-               }
-       }
+        if (options.mainreturn) {
+          pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will return to caller\n"));
+          pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETURN,NULL));
+        } else {
+          pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will lock up\n"));
+          pic16_addpCode2pBlock(pb,pic16_newpCode(POC_GOTO,pic16_newpCodeOp("$",PO_STR)));
+        }
+    }
 
-       /* At this point we've got all the code in the form of pCode structures */
-       /* Now it needs to be rearranged into the order it should be placed in the */
-       /* code space */
+    /* At this point we've got all the code in the form of pCode structures */
+    /* Now it needs to be rearranged into the order it should be placed in the */
+    /* code space */
 
-       pic16_movepBlock2Head('P');              // Last
-       pic16_movepBlock2Head(code->dbName);
-       pic16_movepBlock2Head('X');
-       pic16_movepBlock2Head(statsg->dbName);   // First
+    pic16_movepBlock2Head('P');              // Last
+    pic16_movepBlock2Head(code->dbName);
+    pic16_movepBlock2Head('X');
+    pic16_movepBlock2Head(statsg->dbName);   // First
 
-       /* print the global struct definitions */
-//     if (options.debug)
-//             cdbStructBlock (0);     //,cdbFile);
+    /* print the global struct definitions */
 
-       vFile = tempfile();
-       /* PENDING: this isnt the best place but it will do */
-       if (port->general.glue_up_main) {
-               /* create the interrupt vector table */
-               pic16createInterruptVect (vFile);
-       }
+    vFile = tempfile();
+    /* PENDING: this isnt the best place but it will do */
+    if (port->general.glue_up_main) {
+      /* create the interrupt vector table */
+      pic16createInterruptVect (vFile);
+    }
 
-       addSetHead(&tmpfileSet,vFile);
+    addSetHead(&tmpfileSet,vFile);
     
-       /* emit code for the all the variables declared */
-       pic16emitMaps ();
-       /* do the overlay segments */
-       pic16emitOverlay(ovrFile);
-       pic16_AnalyzepCode('*');
+    /* emit code for the all the variables declared */
+    pic16emitMaps ();
+
+    /* do the overlay segments */
+    pic16emitOverlay(ovrFile);
+    pic16_AnalyzepCode('*');
 
 #if 1
-       if(pic16_options.dumpcalltree) {
-         FILE *cFile;
-               sprintf(buffer, dstFileName);
-               strcat(buffer, ".calltree");
-               cFile = fopen(buffer, "w");
-               pic16_printCallTree( cFile );
-               fclose(cFile);
-       }
+    if(pic16_options.dumpcalltree) {
+      FILE *cFile;
+        
+        sprintf(buffer, dstFileName);
+        strcat(buffer, ".calltree");
+        cFile = fopen(buffer, "w");
+        pic16_printCallTree( cFile );
+        fclose(cFile);
+    }
 #endif
 
-       pic16_InlinepCode();
-       pic16_AnalyzepCode('*');
+    pic16_InlinepCode();
+    pic16_AnalyzepCode('*');
 
-       if(pic16_debug_verbose)
-               pic16_pcode_test();
 
-       /* now put it all together into the assembler file */
-       /* create the assembler file name */
-       if ((noAssemble || options.c1mode)  && fullDstFileName) {
-               sprintf (buffer, fullDstFileName);
-       } else {
-               sprintf (buffer, dstFileName);
-               strcat (buffer, ".asm");
-       }
+    if(pic16_debug_verbose)
+      pic16_pcode_test();
 
-       if (!(asmFile = fopen (buffer, "w"))) {
-               werror (E_FILE_OPEN_ERR, buffer);
-               exit (1);
-       }
+    /* now put it all together into the assembler file */
+    /* create the assembler file name */
+    if((noAssemble || options.c1mode)  && fullDstFileName) {
+      sprintf (buffer, fullDstFileName);
+    } else {
+      sprintf (buffer, dstFileName);
+      strcat (buffer, ".asm");
+    }
+
+    if(!(asmFile = fopen (buffer, "w"))) {
+      werror (E_FILE_OPEN_ERR, buffer);
+      exit (1);
+    }
     
-       /* initial comments */
-       pic16initialComments (asmFile);
+    /* initial comments */
+    pic16initialComments (asmFile);
 
-       /* print module name */
-       if(options.debug)
-               fprintf(asmFile, "\t.file\t\"%s\"\n", fullSrcFileName);
+    /* print module name */
+    if(options.debug)
+      fprintf(asmFile, "\t.file\t\"%s\"\n", fullSrcFileName);
 
-       /* Let the port generate any global directives, etc. */
-       if (port->genAssemblerPreamble) {
-               port->genAssemblerPreamble(asmFile);
-       }
-       
-       /* print the extern variables to this module */
-       pic16_printExterns(asmFile);
+    /* Let the port generate any global directives, etc. */
+    if(port->genAssemblerPreamble) {
+      port->genAssemblerPreamble(asmFile);
+    }
        
-       /* print the global variables in this module */
-       pic16printPublics (asmFile);
+    /* Put all variables into a cblock */
+    pic16_AnalyzeBanking();
 
-#if 0
-       /* copy the sfr segment */
-       fprintf (asmFile, "%s", iComments2);
-       fprintf (asmFile, "; special function registers\n");
-       fprintf (asmFile, "%s", iComments2);
-       copyFile (asmFile, sfr->oFile);
-#endif
+    if(pic16_options.opt_flags & OF_LR_SUPPORT) {
+      pic16_OptimizeLocalRegs();
+    }
 
-       /* Put all variables into a cblock */
-       pic16_AnalyzeBanking();
-       pic16_writeUsedRegs(asmFile);
+    /* print the extern variables to this module */
+    pic16_printExterns(asmFile);
+       
+    /* print the global variables in this module */
+    pic16printPublics (asmFile);
+
+    pic16_writeUsedRegs(asmFile);
 
 #if 0
-       /* no xdata in pic */
-       /* if external stack then reserve space of it */
-       if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
-               fprintf (asmFile, "%s", iComments2);
-               fprintf (asmFile, "; external stack \n");
-               fprintf (asmFile, "%s", iComments2);
-               fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
-               fprintf (asmFile,";\t.ds 256\n");
-       }
+    /* no xdata in pic */
+    /* if external stack then reserve space of it */
+    if(mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
+      fprintf (asmFile, "%s", iComments2);
+      fprintf (asmFile, "; external stack \n");
+      fprintf (asmFile, "%s", iComments2);
+      fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
+      fprintf (asmFile,";\t.ds 256\n");
+    }
 #endif
 
 #if 0  
-       /* no xdata in pic */
-       /* copy xtern ram data */
-       fprintf (asmFile, "%s", iComments2);
-       fprintf (asmFile, "; external ram data\n");
-       fprintf (asmFile, "%s", iComments2);
-       copyFile (asmFile, xdata->oFile);
+    /* no xdata in pic */
+    /* copy xtern ram data */
+    fprintf (asmFile, "%s", iComments2);
+    fprintf (asmFile, "; external ram data\n");
+    fprintf (asmFile, "%s", iComments2);
+    copyFile (asmFile, xdata->oFile);
 #endif
 
 #if 0
-       /* copy the bit segment */
-       fprintf (asmFile, "%s", iComments2);
-       fprintf (asmFile, "; bit data\n");
-       fprintf (asmFile, "%s", iComments2);
-       copyFile (asmFile, bit->oFile);
+    /* copy the bit segment */
+    fprintf (asmFile, "%s", iComments2);
+    fprintf (asmFile, "; bit data\n");
+    fprintf (asmFile, "%s", iComments2);
+    copyFile (asmFile, bit->oFile);
 #endif
 
-       /* copy the interrupt vector table */
-       if(mainf && IFFUNC_HASBODY(mainf->type)) {
-               fprintf (asmFile, "\n%s", iComments2);
-               fprintf (asmFile, "; interrupt vector \n");
-               fprintf (asmFile, "%s", iComments2);
-               copyFile (asmFile, vFile);
-       }
+    /* copy the interrupt vector table */
+    if(mainf && IFFUNC_HASBODY(mainf->type)) {
+      fprintf (asmFile, "\n%s", iComments2);
+      fprintf (asmFile, "; interrupt vector \n");
+      fprintf (asmFile, "%s", iComments2);
+      copyFile (asmFile, vFile);
+    }
     
-       /* copy global & static initialisations */
-       fprintf (asmFile, "\n%s", iComments2);
-       fprintf (asmFile, "; global & static initialisations\n");
-       fprintf (asmFile, "%s", iComments2);
+    /* copy global & static initialisations */
+    fprintf (asmFile, "\n%s", iComments2);
+    fprintf (asmFile, "; global & static initialisations\n");
+    fprintf (asmFile, "%s", iComments2);
     
-       if(pic16_debug_verbose)
-               fprintf(asmFile, "; A code from now on!\n");
-       pic16_copypCode(asmFile, 'A');
-
-
-       if(pic16_options.no_crt) {
-               if(mainf && IFFUNC_HASBODY(mainf->type)) {
-                       fprintf(asmFile, "\tcode\n");
-                       fprintf(asmFile,"__sdcc_gsinit_startup:\n");
-               }
-       }
+    if(pic16_debug_verbose)
+      fprintf(asmFile, "; A code from now on!\n");
+    
+    pic16_copypCode(asmFile, 'A');
 
-//     copyFile (stderr, code->oFile);
+    if(pic16_options.no_crt) {
+      if(mainf && IFFUNC_HASBODY(mainf->type)) {
+        fprintf(asmFile, "\tcode\n");
+        fprintf(asmFile,"__sdcc_gsinit_startup:\n");
+      }
+    }
 
-       fprintf(asmFile, "; I code from now on!\n");
-       pic16_copypCode(asmFile, 'I');
+//    copyFile (stderr, code->oFile);
 
-       if(pic16_debug_verbose)
-               fprintf(asmFile, "; dbName from now on!\n");
-       pic16_copypCode(asmFile, statsg->dbName);
+    fprintf(asmFile, "; I code from now on!\n");
+    pic16_copypCode(asmFile, 'I');
 
+    if(pic16_debug_verbose)
+      fprintf(asmFile, "; dbName from now on!\n");
+    
+    pic16_copypCode(asmFile, statsg->dbName);
 
-       if(pic16_options.no_crt) {
-               if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type)) {
-                       fprintf (asmFile,"\tgoto\t__sdcc_program_startup\n");
-               }
-       }
+    if(pic16_options.no_crt) {
+      if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type)) {
+        fprintf (asmFile,"\tgoto\t__sdcc_program_startup\n");
+      }
+    }
        
+    if(pic16_debug_verbose)
+      fprintf(asmFile, "; X code from now on!\n");
 
-       if(pic16_debug_verbose)
-               fprintf(asmFile, "; X code from now on!\n");
-       pic16_copypCode(asmFile, 'X');
+    pic16_copypCode(asmFile, 'X');
 
-       if(pic16_debug_verbose)
-               fprintf(asmFile, "; M code from now on!\n");
-       pic16_copypCode(asmFile, 'M');
+    if(pic16_debug_verbose)
+      fprintf(asmFile, "; M code from now on!\n");
 
+    pic16_copypCode(asmFile, 'M');
 
-       pic16_copypCode(asmFile, code->dbName);
-
-       pic16_copypCode(asmFile, 'P');
-
-       fprintf (asmFile,"\tend\n");
-       fclose (asmFile);
+    pic16_copypCode(asmFile, code->dbName);
+    
+    pic16_copypCode(asmFile, 'P');
 
-       rm_tmpfiles();
+    fprintf (asmFile,"\tend\n");
+    fclose (asmFile);
+    
+    rm_tmpfiles();
 }
index f298a0ea528ed714586f6730dfb77395b2977501..c24466af2814f00f707e061f190dc9e68dc94f24 100644 (file)
@@ -296,6 +296,9 @@ _process_pragma(const char *sz)
 #define NL_OPT         "--nl="
 #define USE_CRT                "--use-crt="
 
+#define        OFMSG_LRSUPPORT "--flr-support"
+
+
 char *alt_asm=NULL;
 char *alt_link=NULL;
 
@@ -334,6 +337,7 @@ OPTION pic16_optionsTable[]= {
        { 0,    NL_OPT,         NULL,                           "new line, \"lf\" or \"crlf\""},
        { 0,    USE_CRT,        NULL,   "use <crt-o> run-time initialization module"},
        { 0,    "--no-crt",     &pic16_options.no_crt,  "do not link any default run-time initialization module"},
+       { 0,    OFMSG_LRSUPPORT,        NULL,           "use support functions for local register store/restore"},
        { 0,    NULL,           NULL,   NULL}
        };
 
@@ -352,71 +356,76 @@ _pic16_parseOptions (int *pargc, char **argv, int *i)
   /* TODO: allow port-specific command line options to specify
    * segment names here.
    */
-       /* check for arguments that have associated an integer variable */
-       while(pic16_optionsTable[j].pparameter) {
-               if(ISOPT( pic16_optionsTable[j].longOpt )) {
-                       (*pic16_optionsTable[j].pparameter)++;
-                       return TRUE;
-               }
-               j++;
-       }
-
+  
+    /* check for arguments that have associated an integer variable */
+    while(pic16_optionsTable[j].pparameter) {
+      if(ISOPT( pic16_optionsTable[j].longOpt )) {
+        (*pic16_optionsTable[j].pparameter)++;
+        return TRUE;
+      }
+      j++;
+    }
 
-       if(ISOPT(STACK_MODEL)) {
-               stkmodel = getStringArg(STACK_MODEL, argv, i, *pargc);
-               if(!STRCASECMP(stkmodel, "small"))pic16_options.stack_model = 0;
-               else if(!STRCASECMP(stkmodel, "large"))pic16_options.stack_model = 1;
-               else {
-                       fprintf(stderr, "Unknown stack model: %s", stkmodel);
-                       exit(-1);
-               }
-               return TRUE;
-       }
+    if(ISOPT(STACK_MODEL)) {
+      stkmodel = getStringArg(STACK_MODEL, argv, i, *pargc);
+      if(!STRCASECMP(stkmodel, "small"))pic16_options.stack_model = 0;
+      else if(!STRCASECMP(stkmodel, "large"))pic16_options.stack_model = 1;
+      else {
+        fprintf(stderr, "Unknown stack model: %s", stkmodel);
+        exit(-1);
+      }
+      return TRUE;
+    }
 
-       if(ISOPT(OPT_BANKSEL)) {
-               pic16_options.opt_banksel = getIntArg(OPT_BANKSEL, argv, i, *pargc);
-               return TRUE;
-       }
+    if(ISOPT(OPT_BANKSEL)) {
+      pic16_options.opt_banksel = getIntArg(OPT_BANKSEL, argv, i, *pargc);
+      return TRUE;
+    }
 
-       if(ISOPT(REP_UDATA)) {
-               pic16_sectioninfo.at_udata = Safe_strdup(getStringArg(REP_UDATA, argv, i, *pargc));
-               return TRUE;
-       }
+    if(ISOPT(REP_UDATA)) {
+      pic16_sectioninfo.at_udata = Safe_strdup(getStringArg(REP_UDATA, argv, i, *pargc));
+      return TRUE;
+    }
        
-       if(ISOPT(ALT_ASM)) {
-               alt_asm = Safe_strdup(getStringArg(ALT_ASM, argv, i, *pargc));
-               return TRUE;
-       }
+    if(ISOPT(ALT_ASM)) {
+      alt_asm = Safe_strdup(getStringArg(ALT_ASM, argv, i, *pargc));
+      return TRUE;
+    }
        
-       if(ISOPT(ALT_LINK)) {
-               alt_link = Safe_strdup(getStringArg(ALT_LINK, argv, i, *pargc));
-               return TRUE;
-       }
+    if(ISOPT(ALT_LINK)) {
+      alt_link = Safe_strdup(getStringArg(ALT_LINK, argv, i, *pargc));
+      return TRUE;
+    }
 
-       if(ISOPT(IVT_LOC)) {
-               pic16_options.ivt_loc = getIntArg(IVT_LOC, argv, i, *pargc);
-               return TRUE;
-       }
+    if(ISOPT(IVT_LOC)) {
+      pic16_options.ivt_loc = getIntArg(IVT_LOC, argv, i, *pargc);
+      return TRUE;
+    }
        
-       if(ISOPT(NL_OPT)) {
-          char *tmp;
+    if(ISOPT(NL_OPT)) {
+      char *tmp;
             
-            tmp = Safe_strdup( getStringArg(NL_OPT, argv, i, *pargc) );
-            if(!STRCASECMP(tmp, "lf"))pic16_nl = 0;
-            else if(!STRCASECMP(tmp, "crlf"))pic16_nl = 1;
-            else {
-                  fprintf(stderr, "invalid termination character id\n");
-                  exit(-1);
-            }
-            return TRUE;
+        tmp = Safe_strdup( getStringArg(NL_OPT, argv, i, *pargc) );
+        if(!STRCASECMP(tmp, "lf"))pic16_nl = 0;
+        else if(!STRCASECMP(tmp, "crlf"))pic16_nl = 1;
+        else {
+          fprintf(stderr, "invalid termination character id\n");
+          exit(-1);
         }
+        return TRUE;
+    }
 
-        if(ISOPT(USE_CRT)) {
-            pic16_options.no_crt = 0;
-            pic16_options.crt_name = Safe_strdup( getStringArg(USE_CRT, argv, i, *pargc) );
+    if(ISOPT(USE_CRT)) {
+      pic16_options.no_crt = 0;
+      pic16_options.crt_name = Safe_strdup( getStringArg(USE_CRT, argv, i, *pargc) );
 
-            return TRUE;
-        }
+      return TRUE;
+    }
+
+    if(ISOPT(OFMSG_LRSUPPORT)) {
+      pic16_options.opt_flags |= OF_LR_SUPPORT;
+      return TRUE;
+    }
         
   return FALSE;
 }
index 14b8863d6c5ba71f8d45658806654fdb7c79baa2..38abb36008d12a4a4f10793609ed90eda8a02632 100644 (file)
@@ -115,6 +115,9 @@ pCodeOpReg pic16_pc_ssave     = {{PO_GPR_REGISTER,  "SSAVE"}, -1, NULL,0,NULL};
 pCodeOpReg pic16_pc_gpsimio   = {{PO_GPR_REGISTER, "GPSIMIO"}, -1, NULL, 0, NULL};
 pCodeOpReg pic16_pc_gpsimio2  = {{PO_GPR_REGISTER, "GPSIMIO2"}, -1, NULL, 0, NULL};
 
+char *OPT_TYPE_STR[] = { "begin", "end" };
+char *LR_TYPE_STR[] = { "entry begin", "entry end", "exit begin", "exit end" };
+
 
 static int mnemonics_initialized = 0;
 
@@ -171,9 +174,15 @@ extern void pic16_pCodeInsertAfter(pCode *pc1, pCode *pc2);
 extern pCodeOp *pic16_popCopyReg(pCodeOpReg *pc);
 pCodeOp *pic16_popCopyGPR2Bit(pCodeOp *pc, int bitval);
 void pic16_pCodeRegMapLiveRanges(pBlock *pb);
+void OptimizeLocalRegs(void);
 
 char *dumpPicOptype(PIC_OPTYPE type);
 
+pCodeOp *pic16_popGetLit2(int, pCodeOp *);
+pCodeOp *pic16_popGetLit(int);
+pCodeOp *pic16_popGetWithString(char *);
+
+
 /****************************************************************/
 /*                    PIC Instructions                          */
 /****************************************************************/
@@ -3778,12 +3787,24 @@ pCode *pic16_newpCodeLabelFORCE(char *name, int key)
   return ( (pCode *)pcl );
 }
 
-#if 0
 pCode *pic16_newpCodeInfo(INFO_TYPE type, pCodeOp *pcop)
 {
+  pCodeInfo *pci;
 
+    pci = Safe_calloc(1, sizeof(pCodeInfo));
+    pci->pci.pc.type = PC_INFO;
+    pci->pci.pc.prev = pci->pci.pc.next = NULL;
+    pci->pci.pc.pb = NULL;
+    pci->pci.label = NULL;
+       
+    pci->pci.pc.destruct = genericDestruct;
+    pci->pci.pc.print = genericPrint;
+    
+    pci->type = type;
+    pci->oper1 = pcop;
+  
+  return ((pCode *)pci);
 }
-#endif
 
 
 /*-----------------------------------------------------------------*/
@@ -4114,6 +4135,19 @@ pCodeOp *pic16_newpCodeOpOpt(OPT_TYPE type, char *key)
   return (PCOP(pcop));
 }
 
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+pCodeOp *pic16_newpCodeOpLocalRegs(LR_TYPE type)
+{
+  pCodeOpLocalReg *pcop;
+
+       pcop = Safe_calloc(1, sizeof(pCodeOpLocalReg));
+       
+       pcop->type = type;
+
+  return (PCOP(pcop));
+}
+
 
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
@@ -4263,9 +4297,11 @@ void pic16_pCodeConstString(char *name, char *value)
 
   pic16_addpBlock(pb);
 
-  sprintf(buffer,"; %s = %s",name,value);
-  
-  pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(buffer));
+//  sprintf(buffer,"; %s = ", name);
+//  strcat(buffer, value);
+//  fputs(buffer, stderr);
+
+//  pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(buffer));
   pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(name,-1));
 
   do {
@@ -4791,6 +4827,17 @@ char *pic16_pCode2str(char *str, size_t size, pCode *pc)
     SAFE_snprintf(&s,&size,";%s", ((pCodeComment *)pc)->comment);
     break;
 
+  case PC_INFO:
+    SAFE_snprintf(&s,&size,"; info ==>");
+    switch(((pCodeInfo *)pc)->type) {
+      case INF_OPTIMIZATION:
+          SAFE_snprintf(&s,&size, " [optimization] %s\n", OPT_TYPE_STR[ PCOO(PCINF(pc)->oper1)->type ]);
+          break;
+      case INF_LOCALREGS:
+          SAFE_snprintf(&s,&size, " [localregs] %s\n", LR_TYPE_STR[ PCOLR(PCINF(pc)->oper1)->type ]);
+          break;
+    }; break;
+
   case PC_INLINE:
     /* assuming that inline code ends with a \n */
     SAFE_snprintf(&s,&size,"%s", ((pCodeComment *)pc)->comment);
@@ -4826,10 +4873,6 @@ char *pic16_pCode2str(char *str, size_t size, pCode *pc)
   case PC_BAD:
     SAFE_snprintf(&s,&size,";A bad pCode is being used\n");
     break;
-
-  case PC_INFO:
-    SAFE_snprintf(&s,&size,"; PC INFO pcode\n");
-    break;
   }
 
   return str;
@@ -4847,9 +4890,30 @@ static void genericPrint(FILE *of, pCode *pc)
 
   switch(pc->type) {
   case PC_COMMENT:
-    fprintf(of,";%s\n", ((pCodeComment *)pc)->comment);
+//    fputs(((pCodeComment *)pc)->comment, of);
+    fprintf(of,"; %s\n", ((pCodeComment *)pc)->comment);
     break;
 
+  case PC_INFO:
+    {
+      pBranch *pbl = PCI(pc)->label;
+      while(pbl && pbl->pc) {
+        if(pbl->pc->type == PC_LABEL)
+          pCodePrintLabel(of, pbl->pc);
+        pbl = pbl->next;
+      }
+    }
+          
+    fprintf(of, "; info ==>");
+    switch(((pCodeInfo *)pc)->type) {
+      case INF_OPTIMIZATION:
+          fprintf(of, " [optimization] %s\n", OPT_TYPE_STR[ PCOO(PCINF(pc)->oper1)->type ]);
+          break;
+      case INF_LOCALREGS:
+          fprintf(of, " [localregs] %s\n", LR_TYPE_STR[ PCOLR(PCINF(pc)->oper1)->type ]);
+          break;
+    }; break;
+
   case PC_INLINE:
     fprintf(of,"%s\n", ((pCodeComment *)pc)->comment);
      break;
@@ -7043,9 +7107,162 @@ void pic16_AnalyzepCode(char dbName)
 
   } while(changes && (i++ < MAX_PASSES));
 
+  
   buildCallTree();
 }
 
+
+/* convert a series of movff's of local regs to stack, with a single call to
+ * a support functions which does the same thing via loop */
+static void pic16_convertLocalRegs2Support(pCode *pcstart, pCode *pcend, int count, regs *r, int entry)
+{
+  pBranch *pbr;
+  pCode *pc, *pct;
+  char *fname[]={"__lr_store", "__lr_restore"};
+
+//    pc = pic16_newpCode(POC_CALL, pic16_popGetFromString( (entry?fname[0]:fname[1]) ));
+
+    pct = pic16_findNextInstruction(pcstart->next);
+    do {
+      pc = pct;
+      pct = pc->next;  //pic16_findNextInstruction(pc->next);
+//      pc->print(stderr, pc);
+      if(isPCI(pc) && PCI(pc)->label) {
+        pbr = PCI(pc)->label;
+        while(pbr && pbr->pc) {
+          PCI(pcstart)->label = pic16_pBranchAppend(PCI(pcstart)->label, pbr);
+          pbr = pbr->next;
+        }
+
+//        pc->print(stderr, pc);
+        /* unlink pCode */
+        pc->prev->next = pct;
+        pct->prev = pc->prev;
+//        pc->next = NULL;
+//        pc->prev = NULL;
+      }
+    } while ((pc) && (pc != pcend));
+
+    /* unlink movff instructions */
+    pcstart->next = pcend;
+    pcend->prev = pcstart;
+
+    pic16_pCodeInsertAfter(pcstart, (pct=pic16_newpCode(POC_LFSR, pic16_popGetLit2(0, pic16_popGetWithString(r->name))))); pc = pct;
+    pic16_pCodeInsertAfter(pc, pct=pic16_newpCode(POC_MOVLW, pic16_popGetLit( count ))); pc = pct;
+    pic16_pCodeInsertAfter(pc, pct=pic16_newpCode(POC_CALL, pic16_popGetWithString( fname[ (entry==1?0:1) ] )));
+    
+    {
+      symbol *sym;
+
+        sym = newSymbol( fname[ entry?0:1 ], 0 );
+        strcpy(sym->rname, fname[ entry?0:1 ]);
+        checkAddSym(&externs, sym);
+        
+//        fprintf(stderr, "%s:%d adding extern symbol %s in externs\n", __FILE__, __LINE__, fname[ entry?0:1 ]);
+    }
+
+}
+
+
+/*-----------------------------------------------------------------*/
+/* OptimizeLocalRegs - turn sequence of MOVFF instructions for     */
+/*    local registers to a support function call                   */
+/*-----------------------------------------------------------------*/
+void pic16_OptimizeLocalRegs(void)
+{
+  pBlock  *pb;
+  pCode   *pc;
+  pCodeInfo *pci;
+  pCodeOpLocalReg *pclr;
+  int regCount=0;
+  int inRegCount=0;
+  regs *r, *lastr=NULL, *firstr=NULL;
+  pCode *pcstart=NULL, *pcend=NULL;
+  int inEntry=0;
+
+       /* Overview:
+        *   local_regs begin mark
+        *      MOVFF r0x01, POSTDEC1
+        *      MOVFF r0x02, POSTDEC1
+        *      ...
+        *      ...
+        *      MOVFF r0x0n, POSTDEC1
+        *   local_regs end mark
+        *
+        * convert the above to the below:
+        *      MOVLW   starting_register_index
+        *      MOVWF   PRODL
+        *      MOVLW   register_count
+        *      call    __save_registers_in_stack
+        */
+
+    if(!the_pFile)
+      return;
+
+    for(pb = the_pFile->pbHead; pb; pb = pb->next) {
+      inRegCount = regCount = 0;
+      firstr = lastr = NULL;
+      for(pc = pb->pcHead; pc; pc = pc->next) {
+        if(pc && (pc->type == PC_INFO)) {
+          pci = PCINF(pc);
+
+          if(pci->type == INF_LOCALREGS) {
+            pclr = PCOLR(pci->oper1);
+            
+            if((pclr->type == LR_ENTRY_BEGIN)
+              || (pclr->type == LR_ENTRY_END))inEntry = 1;
+            else inEntry = 0;
+            
+            switch(pclr->type) {
+              case LR_ENTRY_BEGIN:
+              case LR_EXIT_BEGIN:
+                       inRegCount = 1; regCount = 0;
+                       pcstart = pc;   //pic16_findNextInstruction(pc->next);
+                       firstr = lastr = NULL;
+                       break;
+              
+              case LR_ENTRY_END:
+              case LR_EXIT_END:
+                       inRegCount = -1;
+                       pcend = pc;     //pic16_findPrevInstruction(pc->prev);
+
+#if 1
+                        if(regCount>2) {
+                          pic16_convertLocalRegs2Support(pcstart, pcend, regCount,
+                               firstr, inEntry);
+                        }
+#endif
+                        firstr = lastr = NULL;
+                       break;
+            }
+            
+            if(inRegCount == -1) {
+//              fprintf(stderr, "%s:%d registers used [%s] %d\n", __FILE__, __LINE__, inEntry?"entry":"exit", regCount);
+              regCount = 0;
+              inRegCount = 0;
+            }
+          }
+        } else {
+          if(isPCI(pc) && (PCI(pc)->op == POC_MOVFF) && (inRegCount == 1)) {
+            if(inEntry)
+              r = pic16_getRegFromInstruction(pc);
+            else
+              r = pic16_getRegFromInstruction2(pc);
+            if(r && (r->type == REG_GPR) && (r->pc_type == PO_GPR_TEMP)) {
+              if(!firstr)firstr = r;
+              regCount++;
+//              fprintf(stderr, "%s:%d\t%s\t%i\t%d/%d\n", __FILE__, __LINE__, r->name, r->rIdx);
+            }
+          }
+        }
+      }
+    }
+}
+              
+            
+
+
+
 /*-----------------------------------------------------------------*/
 /* ispCodeFunction - returns true if *pc is the pCode of a         */
 /*                   function                                      */
index 55ae2e9e1eba93eac74aa055dd3fabc784f4ad9a..c3d17fd9aab6d765bfeb36faf80817d2a6fb44a8 100644 (file)
@@ -313,6 +313,7 @@ typedef enum
 typedef enum
 {
   INF_OPTIMIZATION,      /* structure contains optimization information */
+  INF_LOCALREGS          /* structure contains local register information */
 } INFO_TYPE;
 
 
@@ -327,6 +328,17 @@ typedef enum
   OPT_END,               /* mark ending of optimization block */
 } OPT_TYPE;
 
+/***********************************************************************
+ *  LR_TYPE  - optimization node types
+ ***********************************************************************/
+
+typedef enum
+{
+  LR_ENTRY_BEGIN,             /* mark beginning of optimization block */
+  LR_ENTRY_END,               /* mark ending of optimization block */
+  LR_EXIT_BEGIN,
+  LR_EXIT_END
+} LR_TYPE;
 
 
 /************************************************/
@@ -481,7 +493,12 @@ typedef struct pCodeOpOpt
   char *key;              /* key by which a block is identified */
 } pCodeOpOpt;
 
-  
+typedef struct pCodeOpLocalReg
+{
+  pCodeOp pcop;
+
+  LR_TYPE type;
+} pCodeOpLocalReg;  
 
 /*************************************************
     pCode
@@ -746,14 +763,14 @@ typedef struct pCodeWild
     
     Here are stored generic informaton
 *************************************************/
-typedef struct pInfo
+typedef struct pCodeInfo
 {
-  pCode pc;
+  pCodeInstruction pci;
   
   INFO_TYPE type;      /* info node type */
   
   pCodeOp *oper1;      /* info node arguments */
-} pInfo;
+} pCodeInfo;
   
 
 /*************************************************
@@ -907,6 +924,7 @@ typedef struct peepCommand {
 #define PCW(x)    ((pCodeWild *)(x))
 #define PCCS(x)   ((pCodeCSource *)(x))
 #define PCAD(x)          ((pCodeAsmDir *)(x))
+#define PCINF(x)  ((pCodeInfo *)(x))
 
 #define PCOP(x)   ((pCodeOp *)(x))
 //#define PCOB(x)   ((pCodeOpBit *)(x))
@@ -917,6 +935,7 @@ typedef struct peepCommand {
 #define PCOR2(x)  ((pCodeOpReg2 *)(x))
 #define PCORB(x)  ((pCodeOpRegBit *)(x))
 #define PCOO(x)   ((pCodeOpOpt *)(x))
+#define PCOLR(x)  ((pCodeOpLocalReg *)(x))
 #define PCOW(x)   ((pCodeOpWild *)(x))
 #define PCOW2(x)  (PCOW(PCOW(x)->pcop2))
 #define PBR(x)    ((pBranch *)(x))
@@ -966,6 +985,7 @@ void pic16_addpBlock(pBlock *pb);                  // Add a pBlock to a pFile
 void pic16_copypCode(FILE *of, char dbName);       // Write all pBlocks with dbName to *of
 void pic16_movepBlock2Head(char dbName);           // move pBlocks around
 void pic16_AnalyzepCode(char dbName);
+void pic16_OptimizeLocalRegs(void);
 void pic16_AssignRegBanks(void);
 void pic16_printCallTree(FILE *of);
 void pCodePeepInit(void);
@@ -987,6 +1007,10 @@ pCodeOp *pic16_newpCodeOpRegFromStr(char *name);
 pCodeOp *pic16_newpCodeOp(char *name, PIC_OPTYPE p);
 pCodeOp *pic16_pCodeOpCopy(pCodeOp *pcop);
 
+pCode *pic16_newpCodeInfo(INFO_TYPE type, pCodeOp *pcop);
+pCodeOp *pic16_newpCodeOpOpt(OPT_TYPE type, char *key);
+pCodeOp *pic16_newpCodeOpLocalRegs(LR_TYPE type);
+
 pCode * pic16_findNextInstruction(pCode *pci);
 pCode * pic16_findNextpCode(pCode *pc, PC_TYPE pct);
 int pic16_isPCinFlow(pCode *pc, pCode *pcflow);