* src/SDCCast.c (gatherAutoInit): allow pic16 to emit static
authorvrokas <vrokas@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Mon, 20 Dec 2004 21:48:32 +0000 (21:48 +0000)
committervrokas <vrokas@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Mon, 20 Dec 2004 21:48:32 +0000 (21:48 +0000)
variables initial values to idata section,
* src/SDCCicode.c (geniCodeCall): patch from ### to fix unreferenced
variables in some functions. This utilizes parmBytes field of iCode
structure to hold the offset of the variable in stack. (might be
able to use the stack field too?)
* applied patch from Raphael Neider # ### , # ###
* src/pic16/glue.c (pic16emitRegularMap): fix to print static
variable initial values in idata section,
* src/pic16/ralloc.c (pic16_allocDirReg): don't allocate register
for static variables with initial value
* src/device/lib/pic16/libsdcc/float/ulong2fs.c (__ulong2fs):
applied fix in while loop from Raphael Neider.

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

14 files changed:
ChangeLog
device/lib/pic16/libsdcc/float/ulong2fs.c
src/SDCCBBlock.c
src/SDCCast.c
src/SDCCicode.c
src/SDCClrange.c
src/SDCCsymt.c
src/pic16/gen.c
src/pic16/gen.h
src/pic16/genarith.c
src/pic16/glue.c
src/pic16/pcode.c
src/pic16/pcode.h
src/pic16/ralloc.c

index 059d1cb52a39076bbf51c0bd012790a31628c928..0ac92a39eacd437fce2e6180fc09378bd18a17ff 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2004-12-20 Vangelis Rokas <vrokas AT otenet.gr>
+
+       * src/SDCCast.c (gatherAutoInit): allow pic16 to emit static
+       variables initial values to idata section,
+       * src/SDCCicode.c (geniCodeCall): patch from ### to fix unreferenced
+       variables in some functions. This utilizes parmBytes field of iCode
+       structure to hold the offset of the variable in stack. (might be
+       able to use the stack field too?)
+       * applied patch from Raphael Neider # ### , # ###
+       * src/pic16/glue.c (pic16emitRegularMap): fix to print static
+       variable initial values in idata section,
+       * src/pic16/ralloc.c (pic16_allocDirReg): don't allocate register
+       for static variables with initial value
+       * src/device/lib/pic16/libsdcc/float/ulong2fs.c (__ulong2fs):
+       applied fix in while loop from Raphael Neider.
+
 2004-12-19 Maarten Brock <sourceforge.brock AT dse.nl>
 
        * src/ds390/gen.c (genCpl): fixed bit=~(char/bit) bugs, added warning
index 90322f28fc454c969872e5321baf7a8638a8023a..7f673c2bca84e0dbcffe5399b0a196970a393672 100644 (file)
@@ -50,7 +50,7 @@ float __ulong2fs (unsigned long a ) _FS_REENTRANT
        do {
                a<<=1;
                exp--;
-       } while (a > HIDDEN);
+       } while (a < HIDDEN);
   }
 
 #if 0
index 5c757bca4bce7e7d2a12474e18ddbd224c87515e..931fefcd38652ba4b5def589005cbe0a3ae698b4 100644 (file)
@@ -88,7 +88,9 @@ newEdge (eBBlock * from, eBBlock * to)
 /*-----------------------------------------------------------------*/
 FILE *createDumpFile (int id) {
   struct _dumpFiles *dumpFilesPtr=dumpFiles;
-
+  static int dumpIndex=0;
+  static char dumpIndexStr[32];
+  
   while (dumpFilesPtr->id) {
     if (dumpFilesPtr->id==id)
       break;
@@ -100,15 +102,26 @@ FILE *createDumpFile (int id) {
     exit (1);
   }
 
+  sprintf(dumpIndexStr, ".%d", dumpIndex);
+  dumpIndex++;
+
   if (!dumpFilesPtr->filePtr) {
     // not used before, create it
     strncpyz (scratchFileName, dstFileName, PATH_MAX);
+#if 0
+    strncatz (scratchFileName, dumpIndexStr, PATH_MAX);
+#endif
     strncatz (scratchFileName, dumpFilesPtr->ext, PATH_MAX);
     if (!(dumpFilesPtr->filePtr = fopen (scratchFileName, "w"))) {
       werror (E_FILE_OPEN_ERR, scratchFileName);
       exit (1);
     }
   } 
+
+#if 0
+  fprintf(dumpFilesPtr->filePtr, "Dump file index: %d\n", dumpIndex);
+#endif
+
   return dumpFilesPtr->filePtr;
 }
 
index b3e14fe434ed7b9bcd28b03362ff62386745fa6a..206e5bfedc732bc683c158b20b57f6f7563c5600 100644 (file)
@@ -1130,6 +1130,21 @@ gatherAutoInit (symbol * autoChain)
       if (sym->ival)
         resolveIvalSym (sym->ival, sym->type);
 
+#if 1
+      /* if we are PIC16 port,
+       * and this is a static,
+       * and have initial value,
+       * and not S_CODE, don't emit in gs segment,
+       * but allow glue.c:pic16emitRegularMap to put symbol
+       * in idata section */
+      if(TARGET_IS_PIC16 &&
+        IS_STATIC (sym->etype) && sym->ival
+        && SPEC_SCLS(sym->etype) != S_CODE) {
+        SPEC_SCLS (sym->etype) = S_DATA;
+        continue;
+      }
+#endif
+
       /* if this is a static variable & has an */
       /* initial value the code needs to be lifted */
       /* here to the main portion since they can be */
index 8a1d05043942a8bbe5c94981586d92d592edcf2e..b989c88dd6fd79ab1e2724fc72971947bfc8f240 100644 (file)
@@ -3379,6 +3379,8 @@ geniCodeCall (operand * left, ast * parms,int lvl)
 static void 
 geniCodeReceive (value * args)
 {
+  unsigned char paramByteCounter = 0;
+
   /* for all arguments that are passed in registers */
   while (args)
     {
@@ -3419,6 +3421,17 @@ geniCodeReceive (value * args)
              first = 0;
          }
          IC_RESULT (ic) = opr;
+         
+         /* misuse of parmBytes (normally used for functions) 
+          * to save estimated stack position of this argument.
+          * Normally this should be zero for RECEIVE iCodes.
+          * No idea if this causes side effects on other ports. - dw
+          */
+         ic->parmBytes = paramByteCounter;
+         
+         /* what stack position do we have? */
+         paramByteCounter += getSize (sym->type);
+
          ADDTOCHAIN (ic);
        }
 
index d99df74ce0928b5c5f04ff77715a61b1342e1290..194d37a22bdad0b642bb2adfc8aec7306e9fb9f9 100644 (file)
@@ -531,6 +531,8 @@ rlivePoint (eBBlock ** ebbs, int count)
                        }
                    }
                }
+//                fprintf(stderr, "%s:%d IS_SYMOP left\t", __FILE__, __LINE__);printOperand(IC_LEFT(ic), stderr);
+//                fprintf(stderr, "\n");
            }
 
          if (IS_SYMOP(IC_RIGHT(ic)))
@@ -543,6 +545,8 @@ rlivePoint (eBBlock ** ebbs, int count)
                  ic->rlive = bitVectSetBit (ic->rlive, IC_RIGHT(ic)->key);
                  findNextUse (ebbs[i], ic->next, IC_RIGHT(ic));
                }
+//                fprintf(stderr, "%s:%d IS_SYMOP right\t", __FILE__, __LINE__);printOperand(IC_RIGHT(ic), stderr);
+//                fprintf(stderr, "\n");
            }
 
          if (POINTER_SET(ic) && IS_SYMOP(IC_RESULT(ic)))
index e6ab1b766f326a7cc69c6e199d46e5e2adf9a621..7ccca8c333cf0003ef27fba9cb77bc1bd523a630 100644 (file)
@@ -1485,8 +1485,9 @@ checkSClass (symbol * sym, int isProto)
 
   /* if parameter or local variable then change */
   /* the storage class to reflect where the var will go */
-  if (sym->level && SPEC_SCLS (sym->etype) == S_FIXED &&
-      !IS_STATIC(sym->etype))
+  if (sym->level && SPEC_SCLS (sym->etype) == S_FIXED
+   && !IS_STATIC(sym->etype)
+      )
     {
       if (options.stackAuto || (currFunc && IFFUNC_ISREENT (currFunc->type)))
         {
index fed12d129bf8bcf7a811ad40103805edbe973277..e474f6c0901fea2841419e33daeab67f8ab5cf66 100644 (file)
@@ -57,7 +57,6 @@ extern void pic16_printpBlock(FILE *of, pBlock *pb);
 static asmop *newAsmop (short type);
 static pCodeOp *pic16_popRegFromString(char *str, int size, int offset, operand *op);
 extern pCode *pic16_newpCodeAsmDir(char *asdir, char *argfmt, ...);
-static void mov2w (asmop *aop, int offset);
 static void mov2f(asmop *dst, asmop *src, int offset);
 static void mov2fp(pCodeOp *dst, asmop *src, int offset);
 static pCodeOp *pic16_popRegFromIdx(int rIdx);
@@ -681,8 +680,8 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result)
        for(i=0;i<aop->size;i++) {
 
          /* initialise for stack access via frame pointer */
-         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(sym->stack + i + _G.stack_lat));
-
+         // operands on stack are accessible via "FSR2 - index" with index starting at 0 for the first operand
+         pic16_emitpcode(POC_MOVLW, pic16_popGetLit((sym->stack + 1 + i /*+ _G.stack_lat*/)));
          pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
                          pic16_popCopyReg(&pic16_pc_plusw2), pcop[i]));
         }
@@ -1304,8 +1303,8 @@ void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
                 if(_G.accInUse)pic16_pushpCodeOp( pic16_popCopyReg(&pic16_pc_wreg) );
                 for(i=0;i<aop->size;i++) {
                   /* initialise for stack access via frame pointer */
-                  pic16_emitpcode(POC_MOVLW, pic16_popGetLit(OP_SYMBOL(IC_RESULT(ic))->stack + i + _G.stack_lat));
-
+                  // operands on stack are accessible via "FSR2 - index" with index starting at 0 for the first operand
+                  pic16_emitpcode(POC_MOVLW, pic16_popGetLit((OP_SYMBOL(IC_RESULT(ic))->stack + 1 + i /*+ _G.stack_lat*/)));
                   pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
                         aop->aopu.stk.pop[i], pic16_popCopyReg(&pic16_pc_plusw2)));
                 }
@@ -1910,7 +1909,9 @@ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
        
     case AOP_REG:
       {
-       int rIdx = aop->aopu.aop_reg[offset]->rIdx;
+       int rIdx;
+       assert (aop && aop->aopu.aop_reg[offset] != NULL);
+       rIdx = aop->aopu.aop_reg[offset]->rIdx;
 
        DEBUGpic16_emitcode(";","%d\tAOP_REG", __LINE__);
        
@@ -2217,7 +2218,7 @@ void pic16_aopPut (asmop *aop, char *s, int offset)
 /*-----------------------------------------------------------------*/
 /* mov2w - generate either a MOVLW or MOVFW based operand type     */
 /*-----------------------------------------------------------------*/
-static void mov2w (asmop *aop, int offset)
+void mov2w (asmop *aop, int offset)
 {
   DEBUGpic16_emitcode ("; ***","%s  %d  offset=%d",__FUNCTION__,__LINE__,offset);
 
@@ -2903,6 +2904,9 @@ static void assignResultValue(operand * oper, int rescall)
 
 
       /* its called from genReceive (probably) -- VR */
+      /* I hope this code will not be called from somewhere else in the future! 
+       * We manually set the pseudo stack pointer in genReceive. - dw
+       */
       if(!GpsuedoStkPtr && _G.useWreg) {
 //        DEBUGpic16_emitcode("; ", "pop %d", GpsuedoStkPtr);
 
@@ -2913,6 +2917,7 @@ static void assignResultValue(operand * oper, int rescall)
           offset++;
 //          debugf("receive from WREG\n", 0);
         }
+       GpsuedoStkPtr++; /* otherwise the calculation below fails (-_G.useWreg) */
       }
 //      GpsuedoStkPtr++;
       _G.stack_lat = AOP_SIZE(oper)-1;
@@ -2920,7 +2925,7 @@ static void assignResultValue(operand * oper, int rescall)
       while (size) {
         size--;
         GpsuedoStkPtr++;
-        popaopidx(AOP(oper), offset, GpsuedoStkPtr);
+        popaopidx(AOP(oper), offset, GpsuedoStkPtr - _G.useWreg);
 //        debugf("receive from STACK\n", 0);
         offset++;
       }
@@ -3604,7 +3609,7 @@ static void genFunction (iCode *ic)
 
       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(sym->stack));
       pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(&pic16_pc_fsr1l));
-      emitSKPNC;
+      emitSKPC;
       pic16_emitpcode(POC_DECF, pic16_popCopyReg(&pic16_pc_fsr1h));
     }
           
@@ -3672,10 +3677,19 @@ static void genEndFunction (iCode *ic)
     
     if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)
           && sym->stack) {
-      pic16_emitpcode(POC_MOVLW, pic16_popGetLit(sym->stack));
-      pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(&pic16_pc_fsr1l));
-      emitSKPNC;
-      pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_fsr1h));
+      if (sym->stack == 1) {
+        pic16_emitpcode(POC_INFSNZ, pic16_popCopyReg(&pic16_pc_fsr1l));
+        pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_fsr1h));
+      } else {
+        // we have to add more than one...
+        pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postinc1)); // this holds a return value!
+        pic16_emitpcode(POC_MOVLW, pic16_popGetLit(sym->stack-1));
+        pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(&pic16_pc_fsr1l));
+        emitSKPNC;
+        pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_fsr1h));
+        pic16_emitpcode(POC_COMF,  pic16_popCopyReg(&pic16_pc_wreg)); // WREG = -(WREG+1)!
+        pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_plusw1)); // this holds a retrun value!
+      }
     }
 
 //    sym->regsUsed = _G.fregsUsed;
@@ -7507,9 +7521,9 @@ static void genAnd (iCode *ic, iCode *ifx)
       else {
         if(ifx) {
           pic16_emitpcode(POC_BRA, pic16_popGetLabel(rIfx.lbl->key));
-          pic16_emitpLabel(tlbl->key);
           ifx->generated = 1;
         }
+        pic16_emitpLabel(tlbl->key);
         goto release;
       }
     }
@@ -10293,12 +10307,7 @@ static void genUnpackBits (operand *result, operand *left, char *rname, int ptyp
       /* it is a single bit, so use the appropriate bit instructions */
       DEBUGpic16_emitcode (";","%s %d optimize bit read",__FUNCTION__,__LINE__);
 
-      if(IS_BITFIELD(etype)/* && !IS_ITEMP(left)*/) {
-        pic16_emitpcode(POC_MOVFW, pic16_popGet( AOP(result), 0 ));
-        pic16_emitpcode(POC_BCF, pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_wreg), bstr));
-      } else {
-        pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
-      }
+      pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
       
       if((ptype == POINTER) && (result)) {
         /* workaround to reduce the extra lfsr instruction */
@@ -10309,12 +10318,7 @@ static void genUnpackBits (operand *result, operand *left, char *rname, int ptyp
               pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr));
       }
        
-
-      if(IS_BITFIELD(etype)) {
-        pic16_emitpcode(POC_BSF, pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_wreg), bstr));
-      } else {
-        pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_wreg));
-      }      
+      pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_wreg));
 
       pic16_emitpcode(POC_MOVWF, pic16_popGet( AOP(result), 0 ));      
       return;
@@ -12029,11 +12033,12 @@ static void genAddrOf (iCode *ic)
       pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
                       pic16_popCopyReg(&pic16_pc_fsr2h),
                       pic16_popGet(AOP(result), 1)));
-      
-      pic16_emitpcode(POC_MOVLW, pic16_popGetLit( OP_SYMBOL( IC_LEFT(ic))->stack ) /*+ _G.stack_lat*/);
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 0));
-      emitSKPNC;
-      pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result), 1));
+     
+      // operands on stack are accessible via "FSR2 - index" with index starting at 0 for the first operand
+      pic16_emitpcode(POC_MOVLW, pic16_popGetLit( - (OP_SYMBOL( IC_LEFT(ic))->stack + 1 ) /*+ _G.stack_lat*/));
+      pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(result), 0));
+      emitSKPC;
+      pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result), 1));
 
       goto release;
     }
@@ -12207,6 +12212,16 @@ static void genAssign (iCode *ic)
 //  fprintf(stderr, "%s:%d: assigning value 0x%04lx (%d:%d)\n", __FUNCTION__, __LINE__, lit,
 //                     sizeof(unsigned long int), sizeof(float));
 
+
+  if (AOP_TYPE(right) == AOP_REG) {
+    DEBUGpic16_emitcode(";   ", "%s:%d assign from register\n", __FUNCTION__, __LINE__);
+    while (size--) {
+      
+      pic16_emitpcode (POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset++));
+    } // while
+    goto release;
+  }
+
   if(AOP_TYPE(right) != AOP_LIT
        && IN_CODESPACE(SPEC_OCLS(OP_SYMBOL(right)->etype))
        && !IS_FUNC(OP_SYM_TYPE(right))
@@ -12288,8 +12303,8 @@ 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__);
-       pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
+        //debugf("%s: BTFSS offset == 0\n", __FUNCTION__);
+       pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
        pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
       }
     } else if ( (AOP_TYPE(right) == AOP_PCODE) && (AOP(right)->aopu.pcop->type == PO_IMMEDIATE) ) {
@@ -12387,6 +12402,7 @@ static void genJumpTab (iCode *ic)
 #endif
     pic16_freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
 
+    pic16_emitpinfo (INF_OPTIMIZATION, pic16_newpCodeOpOpt (OPT_JUMPTABLE_BEGIN, ""));
     /* now generate the jump labels */
     for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
          jtab = setNextItem(IC_JTLABELS(ic))) {
@@ -12394,6 +12410,7 @@ static void genJumpTab (iCode *ic)
        pic16_emitpcode(POC_GOTO,pic16_popGetLabel(jtab->key));
        
     }
+    pic16_emitpinfo (INF_OPTIMIZATION, pic16_newpCodeOpOpt (OPT_JUMPTABLE_END, ""));
 
 }
 
@@ -12951,10 +12968,14 @@ static void genReceive (iCode *ic)
       }
   } else {
     DEBUGpic16_emitcode ("; ***","2 %s  %d argreg = %d",__FUNCTION__,__LINE__, SPEC_ARGREG(OP_SYM_ETYPE(IC_RESULT(ic)) ));
-
     _G.accInUse++;
     pic16_aopOp(IC_RESULT(ic),ic,FALSE);  
     _G.accInUse--;
+
+    /* set pseudo stack pointer to where it should be - dw*/
+    GpsuedoStkPtr = ic->parmBytes;
+
+    /* setting GpsuedoStkPtr has side effects here: */
     assignResultValue(IC_RESULT(ic), 0);
   }
 
index dd649f372789872c2e2ccd3629188104438ad7e8..84af5945cfec479c45eaafd117b94c130f7f0678 100644 (file)
@@ -202,6 +202,7 @@ void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop);
 const char *pic16_pCodeOpType(  pCodeOp *pcop);
 int pic16_my_powof2 (unsigned long num);
 
+void mov2w (asmop *aop, int offset);
 
 void dumpiCode(iCode *lic);
 
index b5b707a89d170b6543ce81bc329faa04d2e73577..8221433fd7b5558891ae2fa8fc788b100f1121dc 100644 (file)
 #include "pcode.h"
 #include "gen.h"
 
-//#define D_POS(txt) DEBUGpic16_emitcode ("; TECODEV::: " txt, " (%s:%d (%s))", __FILE__, __LINE__, __FUNCTION__)
-
-#define D_POS(msg)     DEBUGpic16_emitcode("; ", msg, "%s:%d (%s)", __FILE__, __LINE__, __FUNCTION__)
-
 #if 1
 #define pic16_emitcode DEBUGpic16_emitcode
 #endif
@@ -533,7 +529,6 @@ static void genAddLit (iCode *ic, int lit)
          pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
          break;
        default: /* 0x01LL */
-         D_POS("FIXED: added default case for adding 0x01??");
          pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
          pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
          emitSKPNC;
@@ -578,11 +573,9 @@ static void genAddLit (iCode *ic, int lit)
          genAddLit2byte (result, MSB16, hi);
          break;
        case 1:  /* 0xHH01 */
-         D_POS(">>> IMPROVED");
          pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
          pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
          pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
-         D_POS("<<< IMPROVED");
          break;
 /*     case 0xff: * 0xHHff *
          pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0,FALSE,FALSE));
@@ -594,9 +587,7 @@ static void genAddLit (iCode *ic, int lit)
          pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
          pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
          pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
-         D_POS(">>> IMPROVED");
          pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
-         D_POS("<<< IMPROVED");
          break;
        }
 
@@ -613,22 +604,17 @@ static void genAddLit (iCode *ic, int lit)
        if(carry_info) {
          switch(lo) {
          case 0:
-           D_POS(">>> IMPROVED and compacted 0");
            emitSKPNC;
            pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
-           D_POS("<<< IMPROVED and compacted");
            break;
          case 0xff:
            pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
-           D_POS(">>> Changed from SKPZ/SKPC to always SKPC");
            emitSKPC;
            pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
            break;
          default:
-           D_POS(">>> IMPROVED and compacted - default");
            pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
            pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
-           D_POS("<<< IMPROVED and compacted");
            break;
          }
        }else {
@@ -702,9 +688,8 @@ static void genAddLit (iCode *ic, int lit)
        /* left addend is in a register */
        switch(lit & 0xff) {
        case 0:
-         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
+         mov2w(AOP(left),0);
          emitMOVWF(result, 0);
-         D_POS(">>> REMOVED double assignment");
          break;
        case 1:
          pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
@@ -732,7 +717,7 @@ static void genAddLit (iCode *ic, int lit)
        pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
        pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
       } else {
-       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
+       mov2w(AOP(left),0);
        /* We don't know the state of the carry bit at this point */
        clear_carry = 1;
       }
@@ -748,26 +733,20 @@ static void genAddLit (iCode *ic, int lit)
 
            pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
            pic16_emitpcode(POC_ADDFW,  pic16_popGet(AOP(left),offset));
-           D_POS(">>> FIXED from left to result");
            pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
-           D_POS("<<< FIXED from left to result");
 
            clear_carry = 0;
 
          } else {
-           D_POS(">>> FIXED");
            pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
            pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),offset));
            pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
-           D_POS("<<< FIXED");
          }
 
        } else {
-         D_POS(">>> IMPROVED");
          pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),offset));
-         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
+         mov2w(AOP(left),offset);
          pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
-         D_POS("<<< IMPROVED");
        }
        offset++;
       }
@@ -881,7 +860,7 @@ void pic16_genPlus (iCode *ic)
                                        AOP(IC_RIGHT(ic))->aopu.aop_dir);
                                        pic16_emitcode(" xorlw","1");
                                } else {
-                                       pic16_emitpcode(POC_MOVFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
+                                       mov2w(AOP(IC_LEFT(ic)),0);
                                        pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
                                        pic16_emitpcode(POC_INCFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
 
@@ -923,7 +902,7 @@ void pic16_genPlus (iCode *ic)
 
                        } else {
                                emitCLRZ; // needed here as well: INCFW is not always executed, Z is undefined then
-                               pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
+                               mov2w(AOP(IC_LEFT(ic)),0);
                                pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(IC_RIGHT(ic)),0));
                                pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
                                //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
@@ -1014,9 +993,7 @@ void pic16_genPlus (iCode *ic)
                                // right is signed, oh dear ...
                                for(i=size; i< AOP_SIZE(result); i++) {
                                        pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
-                                       D_POS(">>> FIXED sign test from result to right");
                                        pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
-                                       D_POS("<<< FIXED sign test from result to right");
                                        pic16_emitpcode(POC_COMF, pic16_popGet(AOP(result),i));
                                        pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
                                        pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
@@ -1031,7 +1008,7 @@ void pic16_genPlus (iCode *ic)
                        // add first bytes
                        for(i=0; i<size; i++) {
                                if (AOP_TYPE(right) != AOP_ACC)
-                                       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),i));
+                                 mov2w(AOP(right),i);
                                if (pic16_sameRegs(AOP(left), AOP(result)))
                                {
                                        if(i) { // add with carry
@@ -1058,11 +1035,9 @@ void pic16_genPlus (iCode *ic)
                                                pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
                                                pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
                                        } else { // not same
-                                               D_POS (">>> FIXED added to uninitialized result");
                                                pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
                                                pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
                                                pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
-                                               D_POS ("<<< FIXED");
                                        }
                                }
                        } else {
@@ -1423,7 +1398,6 @@ void pic16_genMinus (iCode *ic)
          if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
            if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
              if(lit & 1) {
-               D_POS(">>> FIXED from MOVLW right(=result) to MOVLW left(=literal,left&1==1)");
                pic16_emitpcode(POC_MOVLW , pic16_popGetLit(1));
                pic16_emitpcode(POC_XORWF , pic16_popGet(AOP(IC_RIGHT(ic)),0));
              }
@@ -1440,13 +1414,12 @@ void pic16_genMinus (iCode *ic)
            pic16_emitpcode(POC_MOVLW , pic16_popGetLit(lit & 0xff));
            pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
            pic16_emitpcode(POC_MOVLW , pic16_popGetLit((lit-1) & 0xff));
-           D_POS(">>> IMPROVED removed following assignment W-->result");
            //pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
 
          }
 
        } else {
-         pic16_emitpcode(POC_MOVFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
+         mov2w(AOP(IC_LEFT(ic)),0);
          pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
          pic16_emitpcode(POC_DECFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
        }
@@ -1481,9 +1454,7 @@ void pic16_genMinus (iCode *ic)
     if( (size == 1) && ((lit & 0xff) == 0) ) {
       /* res = 0 - right */
       if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
-       D_POS(">>> IMPROVED changed comf,incf to negf");
        pic16_emitpcode(POC_NEGF,  pic16_popGet(AOP(IC_RIGHT(ic)),0));
-       D_POS("<<< IMPROVED changed comf,incf to negf");
       } else { 
        pic16_emitpcode(POC_COMFW,  pic16_popGet(AOP(IC_RIGHT(ic)),0));
        pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),0));
@@ -1492,7 +1463,7 @@ void pic16_genMinus (iCode *ic)
       goto release;
     }
 
-    pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(IC_RIGHT(ic)),0));
+    mov2w(AOP(IC_RIGHT(ic)),0);
     pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));    
     pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
 
@@ -1501,7 +1472,6 @@ void pic16_genMinus (iCode *ic)
     while(--size) {
       lit >>= 8;
       offset++;
-      D_POS(">>> FIXED and compacted");
       if(same) {
        // here we have x = lit - x   for sizeof(x)>1
        pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
@@ -1511,7 +1481,6 @@ void pic16_genMinus (iCode *ic)
        pic16_emitpcode(POC_SUBFWB_D0,  pic16_popGet(AOP(IC_RIGHT(ic)),offset));
        pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
       }
-      D_POS("<<< FIXED and compacted");
     }
   
 
@@ -1532,7 +1501,7 @@ void pic16_genMinus (iCode *ic)
 
        DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC) 
-         pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(IC_RIGHT(ic)),0));
+         mov2w(AOP(IC_RIGHT(ic)),0);
 
        if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
          pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
@@ -1569,13 +1538,10 @@ void pic16_genMinus (iCode *ic)
 
     while(size--){
       if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
-       pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(IC_RIGHT(ic)),offset));
-       D_POS(">>> IMPROVED by replacing emitSKPC, incfszw by subwfb");
+       mov2w(AOP(IC_RIGHT(ic)),offset);
        pic16_emitpcode(POC_SUBWFB_D1,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
-       D_POS("<<< IMPROVED by replacing emitSKPC, incfszw by subwfb");
       } else {
-       D_POS(">>> FIXED for same regs right and result");
-       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
+       mov2w(AOP(IC_RIGHT(ic)),offset);
        pic16_emitpcode(POC_SUBWFB_D0,  pic16_popGet(AOP(IC_LEFT(ic)),offset));
        pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(IC_RESULT(ic)),offset));
       }        
@@ -1841,7 +1807,7 @@ void pic16_genUMult8X8_8 (operand *left,
        if(AOP_TYPE(left) != AOP_ACC) {
                // left is not WREG
                if(AOP_TYPE(right) != AOP_ACC) {
-                       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
+                       mov2w(AOP(left), 0);
                        pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
                } else {
                        pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
@@ -1909,7 +1875,7 @@ void pic16_genUMult16X16_16 (operand *left,
                pct3 = pic16_popGetTempReg(1);
                pct4 = pic16_popGetTempReg(1);
 
-               pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
+               mov2w(AOP(left), 0);
                pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
                pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
                        pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
@@ -1921,7 +1887,7 @@ void pic16_genUMult16X16_16 (operand *left,
                pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
                        pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
                
-               pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
+               mov2w(AOP(left), 1);
                pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
                pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
                        pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
@@ -1941,7 +1907,7 @@ void pic16_genUMult16X16_16 (operand *left,
 
        } else {
 
-               pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
+               mov2w(AOP(left), 0);
                pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
                pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
                        pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
@@ -1953,7 +1919,7 @@ void pic16_genUMult16X16_16 (operand *left,
                pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
                pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
                
-               pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
+               mov2w(AOP(left), 1);
                pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
                pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
                pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
@@ -1994,7 +1960,7 @@ void pic16_genSMult8X8_8 (operand *left,
 #if 0
   pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
   pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(result_hi));
-  pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
+  mov2w(AOP(left),0);
   pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
   pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(result),1));
 #endif
@@ -2186,7 +2152,7 @@ void pic16_genUMult32X32_32 (operand *left,
                pct3 = pic16_popGetTempReg(1);
                pct4 = pic16_popGetTempReg(1);
 
-               pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
+               mov2w(AOP(left), 0);
                pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
                pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
                        pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
@@ -2198,7 +2164,7 @@ void pic16_genUMult32X32_32 (operand *left,
                pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
                        pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
                
-               pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
+               mov2w(AOP(left), 1);
                pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
                pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
                        pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
@@ -2218,7 +2184,7 @@ void pic16_genUMult32X32_32 (operand *left,
 
        } else {
 
-               pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
+               mov2w(AOP(left), 0);
                pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
                pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
                        pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
@@ -2230,7 +2196,7 @@ void pic16_genUMult32X32_32 (operand *left,
                pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
                pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
                
-               pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
+               mov2w(AOP(left), 1);
                pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
                pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
                pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
index 9b67242373ec3bacc8a955f5eb9bfad65c112c8d..573f83c5069c235a8604502cc9435d6ae5dd6f2b 100644 (file)
@@ -175,12 +175,20 @@ pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag)
                  
                        checkAddSym(&publics, sym);
                } else
+#if 1
+                        /* new version */
                        if(IS_STATIC(sym->etype)
-                               && !(sym->ival && !sym->level)
-                       ) {
+                               && !sym->ival) /* && !sym->level*/ {
+#else
+                        /* old version */
+                        if(IS_STATIC(sym->etype)
+                                && !(sym->ival && !sym->level)) {
+#endif
                          regs *reg;
                           sectSym *ssym;
                           int found=0;
+
+//                            debugf("adding symbol %s\n", sym->name);
 #define SET_IMPLICIT   1
 
 #if SET_IMPLICIT
@@ -191,15 +199,15 @@ pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag)
                                reg = pic16_allocDirReg( operandFromSymbol( sym ));
                                
                                if(reg) {
-#if 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);
+                                    debugf("Coudld not find %s in pic16_rel_udata. Check!\n", reg->name);
+//                                 checkAddSym(&publics, sym);
 
                                 }
                        }
@@ -214,28 +222,9 @@ pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag)
                        continue;
                }
 
-#if 0
-               /* print extra debug info if required */
-               if (options.debug || sym->level == 0) {
-                       cdbWriteSymbol (sym);   //, cdbFile, FALSE, FALSE);
-
-                       if (!sym->level)        /* global */
-                               if (IS_STATIC (sym->etype))
-                                       fprintf (map->oFile, "F%s_", moduleName);               /* scope is file */
-                               else
-                                       fprintf (map->oFile, "G_");     /* scope is global */
-                       else
-                               /* symbol is local */
-                               fprintf (map->oFile, "L%s_", (sym->localof ? sym->localof->name : "-null-"));
-                       fprintf (map->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
-               }
-#endif
-
-
                /* if is has an absolute address then generate
                an equate for this no need to allocate space */
                if (SPEC_ABSA (sym->etype)) {
-//                     if (options.debug || sym->level == 0)
 //                             fprintf (stderr,"; %s == 0x%04x\t\treqv= %p nRegs= %d\n",
 //                                     sym->name, SPEC_ADDR (sym->etype), sym->reqv, sym->regType);
 
@@ -343,7 +332,9 @@ pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag)
                /* if it has an initial value then do it only if
                        it is a global variable */
 
-               if (sym->ival && sym->level == 0) {
+               if (sym->ival
+                 && ((sym->level == 0)
+                     || IS_STATIC(sym->etype)) ) {
                  ast *ival = NULL;
 
 #if 0
@@ -1460,6 +1451,8 @@ pic16printPublics (FILE *afile)
        fprintf (afile, "%s", iComments2);
 
        for(sym = setFirstItem (publics); sym; sym = setNextItem (publics))
+         /* sanity check */
+         if(!IS_STATIC(sym->etype))
                fprintf(afile, "\tglobal %s\n", sym->rname);
 }
 
@@ -1545,27 +1538,6 @@ pic16emitOverlay (FILE * afile)
          if (IS_FUNC (sym->type))
            continue;
 
-#if 0
-         /* print extra debug info if required */
-         if (options.debug || sym->level == 0)
-           {
-
-             cdbSymbol (sym, cdbFile, FALSE, FALSE);
-
-             if (!sym->level)
-               {               /* global */
-                 if (IS_STATIC (sym->etype))
-                   fprintf (afile, "F%s_", moduleName);        /* scope is file */
-                 else
-                   fprintf (afile, "G_");      /* scope is global */
-               }
-             else
-               /* symbol is local */
-               fprintf (afile, "L%s_",
-                        (sym->localof ? sym->localof->name : "-null-"));
-             fprintf (afile, "%s_%d_%d", sym->name, sym->level, sym->block);
-           }
-#endif
 
          /* if is has an absolute address then generate
             an equate for this no need to allocate space */
index 8eba51028e9f56157687c961ed3a4bddeab0463c..9f5522b2b27e69a1a8c3c2b1ecfd0f2ea069e048 100644 (file)
@@ -6907,10 +6907,12 @@ int instrSize (pCode *pc)
  */
 int isLabel (pCode *pc, char *label)
 {
-  if (isPCI(pc) || isPCAD(pc)) {
+  if (!pc) return 0;
+
+  // label attached to the pCode?  
+  if (isPCI(pc) || isPCAD(pc) || isPCW(pc) || pc->type == PC_INFO) {
     pBranch *lab = NULL;
-    if (isPCI(pc)) lab = PCI(pc)->label;
-    else if (isPCAD(pc)) lab = PCAD(pc)->pci.label;
+    lab = PCI(pc)->label;
 
     while (lab) {
       if (isPCL(lab->pc) && strcmp(PCL(lab->pc)->label, label) == 0) {
@@ -6918,12 +6920,23 @@ int isLabel (pCode *pc, char *label)
       }
       lab = lab->next;
     } // while
-  }
+  } // if
+
+  // is inline assembly label?
+  if (isPCAD(pc) && PCAD(pc)->directive == NULL && PCAD(pc)->arg) {
+    // do not compare trailing ':'
+    if (strncmp (PCAD(pc)->arg, label, strlen (label)) == 0) {
+      return 1;
+    }
+  } // if
+  
+  // is pCodeLabel?
   if (isPCL(pc)) {
       if (strcmp(PCL(pc)->label,label) == 0) {
       return 1;
     }
-  }
+  } // if
+  
   // no label/no label attached/wrong label(s)
   return 0;
 }
@@ -6933,7 +6946,7 @@ int isLabel (pCode *pc, char *label)
  * Returns max if the label could not be found or
  * its distance from pc in (-max..+max).
  */
-int findpCodeLabel (pCode *pc, char *label, int max) {
+int findpCodeLabel (pCode *pc, char *label, int max, pCode **target) {
   int dist = instrSize(pc);
   pCode *curr = pc;
 
@@ -6942,7 +6955,10 @@ int findpCodeLabel (pCode *pc, char *label, int max) {
     curr = curr->prev;
     dist += instrSize(curr); // sizeof (instruction)
   } // while
-  if (curr && dist < max) return -dist;
+  if (curr && dist < max) {
+    if (target != NULL) *target = curr;
+    return -dist;
+  }
 
   dist = 0;
   curr = pic16_findNextInstruction (pc->next);
@@ -6951,33 +6967,15 @@ int findpCodeLabel (pCode *pc, char *label, int max) {
     dist += instrSize(curr); // sizeof (instruction)
     curr = curr->next;
   } // while
-  if (curr && dist < max) return dist;
+  if (curr && dist < max) {
+    if (target != NULL) *target = curr;
+    return dist;
+  }
 
+  if (target != NULL) *target = NULL;
   return max;
 }
 
-/* Returns 0 if the pCode pc is known to NOT be in a jumptable.
- * If in doubt (or sure that pc is part of a jumptable), 1 is returned.
- */
-int isJumptable (pCode *pc, pCode *prev, pCode *next)
-{
-  // we might be the last item in a jump table or not in
-  // jumptable at all -- then we don't care
-  if (!next || !isPCI(next) || PCI(next)->op != POC_GOTO)
-    return 0;
-
-  // preceding instruction is a skip instruction (cannot be jumptable)
-  if (prev && isPCI(prev) && (isPCI_SKIP(prev)))
-    return 0;
-
-  // GOTOs within a jumptable are unlabelled...
-  if (next && isPCI(next) && PCI(next)->op == POC_GOTO && PCI(next)->label)
-    return 0;
-  
-  // if in doubt: assume we are in a jumptable
-  return 1;
-}
-
 /* Returns -1 if pc does NOT denote an instruction like
  * BTFS[SC] STATUS,i
  * Otherwise we return 
@@ -7036,15 +7034,21 @@ int hasNoLabel (pCode *pc)
   pCode *prev;
   if (!pc) return 1;
 
-  // has labels attached?
-  if (isPCI(pc) && PCI(pc)->label) return 0;
-  
   // are there any label pCodes between pc and the previous instruction?
   prev = pic16_findPrevInstruction (pc->prev);
-  pc = pc->prev;
   while (pc && pc != prev) {
+    // pCode with attached label?
+    if ((isPCI(pc) || isPCAD(pc) || isPCW(pc) || pc->type == PC_INFO)
+       && PCI(pc)->label) {
+      return 0;
+    }
+    // is inline assembly label?
+    if (isPCAD(pc) && PCAD(pc)->directive == NULL) return 0;
     if (isPCW(pc) && PCW(pc)->label) return 0;
+
+    // pCodeLabel?
     if (isPCL(pc)) return 0;
+
     pc = pc->prev;
   } // if
 
@@ -7052,9 +7056,112 @@ int hasNoLabel (pCode *pc)
   return 1;
 }
 
+/* Replaces the old pCode with the new one, moving the labels,
+ * C source line and probably flow information to the new pCode.
+ */
+void pic16_pCodeReplace (pCode *oldPC, pCode *newPC) {
+  if (!oldPC || !newPC || !isPCI(oldPC) || !isPCI(newPC))
+    return;
+
+  /* first move all labels from old to new */
+  PCI(newPC)->label = pic16_pBranchAppend (PCI(oldPC)->label, PCI(newPC)->label);
+  PCI(oldPC)->label = NULL;
+  
+  /* move C source line (if possible) */
+  if (PCI(oldPC)->cline && !PCI(newPC)->cline)
+    PCI(newPC)->cline = PCI(oldPC)->cline;
+
+  /* insert new pCode into pBlock */
+  pic16_pCodeInsertAfter (oldPC, newPC);
+  pic16_unlinkpCode (oldPC);
+  
+  /* TODO: update flow (newPC->from, newPC->to) */
+  PCI(newPC)->pcflow = PCI(oldPC)->pcflow;
+
+  /* destruct replaced pCode */
+  oldPC->destruct (oldPC);
+}
+
+/* Returns the inverted conditional branch (if any) or NULL.
+ * pcop must be set to the new jump target.
+ */
+pCode *getNegatedBcc (pCode *bcc, pCodeOp *pcop)
+{
+  pCode *newBcc;
+
+  if (!bcc || !isPCI(bcc)) return NULL;
+
+  switch (PCI(bcc)->op) {
+  case POC_BC:   newBcc = pic16_newpCode (POC_BNC , pcop); break;
+  case POC_BZ:   newBcc = pic16_newpCode (POC_BNZ , pcop); break;
+  case POC_BOV:  newBcc = pic16_newpCode (POC_BNOV, pcop); break;
+  case POC_BN:   newBcc = pic16_newpCode (POC_BNN , pcop); break;
+  case POC_BNC:  newBcc = pic16_newpCode (POC_BC  , pcop); break;
+  case POC_BNZ:  newBcc = pic16_newpCode (POC_BZ  , pcop); break;
+  case POC_BNOV: newBcc = pic16_newpCode (POC_BOV , pcop); break;
+  case POC_BNN:  newBcc = pic16_newpCode (POC_BN  , pcop); break;
+  default:
+    newBcc = NULL;
+  }
+  return newBcc;
+}
+
+#define MAX_DIST_GOTO 0x7FFFFFFF
 #define MAX_DIST_BRA 1020
 #define MAX_DIST_BCC 120
-#define IS_GOTO(arg) ((arg) && isPCI(arg) && (PCI(arg)->op == POC_GOTO))
+#define IS_GOTO(arg) ((arg) && isPCI(arg) && (PCI(arg)->op == POC_GOTO || PCI(arg)->op == POC_BRA))
+
+/* Follows GOTO/BRA instructions to their target instructions, stores the
+ * final destination (not a GOTO or BRA instruction) in target and returns
+ * the distance from the original pc to *target.
+ */
+int resolveJumpChain (pCode *pc, pCode **target, pCodeOp **pcop) {
+  pCode *curr = pc;
+  pCode *last = NULL;
+  pCodeOp *lastPCOP = NULL;
+  int dist = 0;
+
+  /* only follow unconditional branches, except for the initial pCode (which may be a conditional branch) */
+  while (curr && isPCI(curr) && (PCI(curr)->op == POC_GOTO || PCI(curr)->op == POC_BRA
+                                || (curr == pc && isConditionalBranch(curr)))) {
+    last = curr;
+    lastPCOP = PCI(curr)->pcop;
+    dist = findpCodeLabel (pc, PCI(curr)->pcop->name, MAX_DIST_GOTO, &curr);
+  } // while
+  
+  if (target) *target = last;
+  if (pcop) *pcop = lastPCOP;
+  return dist;
+}
+
+/* Returns pc if it is not a OPT_JUMPTABLE_BEGIN INFO pCode.
+ * Otherwise the first pCode after the jumptable (after
+ * the OPT_JUMPTABLE_END tag) is returned.
+ */
+pCode *skipJumptables (pCode *pc)
+{
+  if (!pc) return NULL;
+
+  while (pc->type == PC_INFO && PCINF(pc)->type == INF_OPTIMIZATION && PCOO(PCINF(pc)->oper1)->type == OPT_JUMPTABLE_BEGIN) {
+    do {
+      pc = pc->next;
+    } while (pc && (pc->type != PC_INFO || PCINF(pc)->type != INF_OPTIMIZATION
+                   || PCOO(PCINF(pc)->oper1)->type != OPT_JUMPTABLE_END));
+    // skip OPT_END as well
+    if (pc) pc = pc->next;
+  } // while
+
+  return pc;
+}
+
+pCode *pic16_findNextInstructionSkipJumptables (pCode *pc)
+{
+  while (pc && !isPCI(pc) && !isPCAD(pc) && !isPCW(pc)) {
+    pc = skipJumptables (pc->next);
+  } // while
+  
+  return pc;
+}
 
 /* Turn GOTOs into BRAs if distance between GOTO and label
  * is less than 1024 bytes.
@@ -7069,156 +7176,204 @@ void pic16_OptimizeJumps ()
   pCode *pc_prev = NULL;
   pCode *pc_next = NULL;
   pBlock *pb;
+  pCode *target;
+  int change, iteration;
   int isHandled = 0;
-  int opt=0, toofar=0, jumptabs=0, opt_cond = 0, cond_toofar=0, opt_reorder = 0;
+  char *label;
+  int opt=0, toofar=0, opt_cond = 0, cond_toofar=0, opt_reorder = 0, opt_gotonext = 0, opt_gotochain = 0;
   
   if (!the_pFile) return;
   
+  //fprintf (stderr, "%s:%d: %s\n", __FILE__, __LINE__, __FUNCTION__);
+  
   for (pb = the_pFile->pbHead; pb != NULL; pb = pb->next) {
-    pc = pic16_findNextInstruction (pb->pcHead);
+    iteration = 1;
+    int matchedInvertRule = 1;
+    do {
+      //fprintf (stderr, "%s:%d: iterating over pBlock %p\n", __FUNCTION__, __LINE__, pb);
+      change = 0;
+      pc = pic16_findNextInstruction (pb->pcHead);
     
-    while (pc) {
-      pc_next = pic16_findNextInstruction (pc->next);
-      // turn GOTOs into BRAs (if absolute distance to label < 1024)
-      if (IS_GOTO(pc)) {
-       char *label = PCI(pc)->pcop->name;
-       int condBraType = isSkipOnStatus(pc_prev);
-       int dist = findpCodeLabel(pc, label, MAX_DIST_BRA);
-       if (dist < 0) dist = -dist;
-       //fprintf (stderr, "distance: %d (", dist); pc->print(stderr, pc);fprintf (stderr, ")\n");
-       isHandled = 0;
-
-       if (condBraType != -1 && hasNoLabel(pc)) {
-         if (dist < MAX_DIST_BCC) {
-           pCode *bcc = NULL;
-           switch (condBraType) {
-           case 0x00: bcc = pic16_newpCode (POC_BC, PCI(pc)->pcop);break;
-             // no BDC on DIGIT CARRY available
-           case 0x02: bcc = pic16_newpCode (POC_BZ, PCI(pc)->pcop);break;
-           case 0x03: bcc = pic16_newpCode (POC_BOV, PCI(pc)->pcop);break;
-           case 0x04: bcc = pic16_newpCode (POC_BN, PCI(pc)->pcop);break;
-           case 0x10: bcc = pic16_newpCode (POC_BNC, PCI(pc)->pcop);break;
-             // no BNDC on DIGIT CARRY available
-           case 0x12: bcc = pic16_newpCode (POC_BNZ, PCI(pc)->pcop);break;
-           case 0x13: bcc = pic16_newpCode (POC_BNOV, PCI(pc)->pcop);break;
-           case 0x14: bcc = pic16_newpCode (POC_BNN, PCI(pc)->pcop);break;
-           default:
-             // no replacement possible
-             bcc = NULL;
-             break;
-           } // switch
-           if (bcc) {
-             // ATTENTION: keep labels attached to BTFSx!
-             // HINT: GOTO is label free (checked above)
-             isHandled = 1;
-             PCI(bcc)->label = PCI(pc_prev)->label;
+      while (pc) {
+       pc_next = pic16_findNextInstructionSkipJumptables (pc->next);
+       
+
+       /* (1) resolve chained jumps
+        * Do not perform this until pattern (4) is no longer present! Otherwise we will
+        * (a) leave dead code in and
+        * (b) skip over the dead code with an (unneccessary) jump.
+        */
+       if (!matchedInvertRule && (IS_GOTO(pc) || isConditionalBranch(pc))) {
+         pCodeOp *lastTargetOp = NULL;
+         int newDist = resolveJumpChain (pc, &target, &lastTargetOp);
+         int maxDist = MAX_DIST_BCC;
+         if (PCI(pc)->op == POC_BRA) maxDist = MAX_DIST_BRA;
+         if (PCI(pc)->op == POC_GOTO) maxDist = MAX_DIST_GOTO;
+         
+         /* be careful NOT to make the jump instruction longer (might break previously shortened jumps!) */
+         if (lastTargetOp && newDist <= maxDist && lastTargetOp != PCI(pc)->pcop
+             && strcmp (lastTargetOp->name, PCI(pc)->pcop->name) != 0) {
+           //fprintf (stderr, "(1) ");pc->print(stderr, pc); fprintf (stderr, " --> %s\n", lastTargetOp->name);
+           if (pic16_pcode_verbose) { pic16_pCodeInsertAfter (pc->prev, pic16_newpCodeCharP("(1) jump chain resolved")); }
+           PCI(pc)->pcop->name = lastTargetOp->name;
+           change++;
+           opt_gotochain++;
+         } // if
+       } // if
+
+
+       if (IS_GOTO(pc)) {
+         label = PCI(pc)->pcop->name;
+         int condBraType = isSkipOnStatus(pc_prev);
+         int dist = findpCodeLabel(pc, label, MAX_DIST_BRA, &target);
+         if (dist < 0) dist = -dist;
+         //fprintf (stderr, "distance: %d (", dist); pc->print(stderr, pc);fprintf (stderr, ")\n");
+         isHandled = 0;
+         
+         
+         /* (2) remove "GOTO label; label:" */
+         if (isLabel (pc_next, label)) {
+           //fprintf (stderr, "(2) GOTO next instruction: ");pc->print(stderr, pc);fprintf (stderr, " --> ");pc_next->print(stderr, pc_next); fprintf(stderr, "\n");
+           // first remove all preceeding SKIP instructions
+           while (pc_prev && isPCI_SKIP(pc_prev)) {
+             // attach labels on this instruction to pc_next
+             //fprintf (stderr, "(2) preceeding SKIP removed: ");pc_prev->print(stderr, pc_prev);fprintf(stderr, "\n");
+             PCI(pc_next)->label = pic16_pBranchAppend (PCI(pc_prev)->label, PCI(pc_next)->label);
              PCI(pc_prev)->label = NULL;
-             pic16_pCodeInsertAfter (pc, bcc);
-             pic16_pCodeInsertAfter(pc_prev, pic16_newpCodeCharP("goto-optimization 1"));
-             pc_prev->destruct(pc_prev);
-             pc->destruct(pc);
-             pc = bcc;
-             opt_cond++;
+             if (pic16_pcode_verbose) { pic16_pCodeInsertAfter (pc->prev, pic16_newpCodeCharP("(2) SKIP removed")); }
+             pic16_unlinkpCode (pc_prev);
+             pc_prev = pic16_findPrevInstruction (pc);
+           } // while
+           // now remove the redundant goto itself
+           PCI(pc_next)->label = pic16_pBranchAppend (PCI(pc)->label, PCI(pc_next)->label);
+           if (pic16_pcode_verbose) { pic16_pCodeInsertAfter (pc, pic16_newpCodeCharP("(2) GOTO next instruction removed")); }
+           pic16_unlinkpCode (pc);
+           pc = pic16_findPrevInstruction(pc_next->prev);
+           isHandled = 1; // do not perform further optimizations
+           opt_gotonext++;
+           change++;
+         } // if
+         
+         
+         /* (3) turn BTFSx STATUS,i; GOTO label into Bcc label if possible */
+         if (!isHandled && condBraType != -1 && hasNoLabel(pc)) {
+           if (dist < MAX_DIST_BCC) {
+             pCode *bcc = NULL;
+             switch (condBraType) {
+             case 0x00: bcc = pic16_newpCode (POC_BC, PCI(pc)->pcop);break;
+               // no BDC on DIGIT CARRY available
+             case 0x02: bcc = pic16_newpCode (POC_BZ, PCI(pc)->pcop);break;
+             case 0x03: bcc = pic16_newpCode (POC_BOV, PCI(pc)->pcop);break;
+             case 0x04: bcc = pic16_newpCode (POC_BN, PCI(pc)->pcop);break;
+             case 0x10: bcc = pic16_newpCode (POC_BNC, PCI(pc)->pcop);break;
+               // no BNDC on DIGIT CARRY available
+             case 0x12: bcc = pic16_newpCode (POC_BNZ, PCI(pc)->pcop);break;
+             case 0x13: bcc = pic16_newpCode (POC_BNOV, PCI(pc)->pcop);break;
+             case 0x14: bcc = pic16_newpCode (POC_BNN, PCI(pc)->pcop);break;
+             default:
+               // no replacement possible
+               bcc = NULL;
+               break;
+             } // switch
+             if (bcc) {
+               // ATTENTION: keep labels attached to BTFSx!
+               // HINT: GOTO is label free (checked above)
+               //fprintf (stderr, "%s:%d: (3) turning %s %s into %s %s\n", __FUNCTION__, __LINE__, PCI(pc)->mnemonic, label, PCI(bcc)->mnemonic, label);
+               isHandled = 1; // do not perform further optimizations
+               if (pic16_pcode_verbose) { pic16_pCodeInsertAfter(pc_prev->prev, pic16_newpCodeCharP("(3) conditional branch introduced")); }
+               pic16_pCodeReplace (pc_prev, bcc);
+               pc->destruct(pc);
+               pc = bcc;
+               opt_cond++;
+               change++;
+             } // if
+           } else {
+             //fprintf (stderr, "(%d, too far for Bcc)\n", dist);
+             cond_toofar++;
            } // if
-         } else {
-           //fprintf (stderr, "(%d, too far for Bcc)\n", dist);
-           cond_toofar++;
          } // if
-       } // if
 
-       if (!isHandled) {
-         // eliminate the following (common) tripel:
-         //           <pred.>;
-         //  labels1: Bcc label2;
-         //           GOTO somewhere;    ; <-- instruction referenced by pc
-         //  label2:  <cont.>
-         // and replace it by
-         //  labels1: B#(cc) somewhere;  ; #(cc) is the negated condition cc
-         //  label2:  <cont.>
-         // ATTENTION: all labels pointing to "Bcc label2" must be attached
-         //            to <cont.> instead
-         // ATTENTION: This optimization is only valid if <pred.> is
-         //            not a skip operation!
-         // ATTENTION: somewhere must be within MAX_DIST_BCC bytes!
-         // ATTENTION: no label may be attached to the GOTO instruction!
-         if (isConditionalBranch(pc_prev)
-             && (!isPCI_SKIP(pic16_findPrevInstruction(pc_prev->prev)))
-             && (dist < MAX_DIST_BCC)
-             && isLabel(pc_next,PCI(pc_prev)->pcop->name)
-             && hasNoLabel(pc)) {
-           pCode *newBcc = NULL;
-           switch (PCI(pc_prev)->op) {
-           case POC_BC:   newBcc = pic16_newpCode (POC_BNC , PCI(pc)->pcop); break;
-           case POC_BZ:   newBcc = pic16_newpCode (POC_BNZ , PCI(pc)->pcop); break;
-           case POC_BOV:  newBcc = pic16_newpCode (POC_BNOV, PCI(pc)->pcop); break;
-           case POC_BN:   newBcc = pic16_newpCode (POC_BNN , PCI(pc)->pcop); break;
-           case POC_BNC:  newBcc = pic16_newpCode (POC_BC  , PCI(pc)->pcop); break;
-           case POC_BNZ:  newBcc = pic16_newpCode (POC_BZ  , PCI(pc)->pcop); break;
-           case POC_BNOV: newBcc = pic16_newpCode (POC_BOV , PCI(pc)->pcop); break;
-           case POC_BNN:  newBcc = pic16_newpCode (POC_BN  , PCI(pc)->pcop); break;
-           default:
-             newBcc = NULL;
-           }
+         if (!isHandled) {
+           // (4) eliminate the following (common) tripel:
+           //           <pred.>;
+           //  labels1: Bcc label2;
+           //           GOTO somewhere;    ; <-- instruction referenced by pc
+           //  label2:  <cont.>
+           // and replace it by
+           //  labels1: B#(cc) somewhere;  ; #(cc) is the negated condition cc
+           //  label2:  <cont.>
+           // ATTENTION: all labels pointing to "Bcc label2" must be attached
+           //            to <cont.> instead
+           // ATTENTION: This optimization is only valid if <pred.> is
+           //            not a skip operation!
+           // ATTENTION: somewhere must be within MAX_DIST_BCC bytes!
+           // ATTENTION: no label may be attached to the GOTO instruction!
+           if (isConditionalBranch(pc_prev)
+               && (!isPCI_SKIP(pic16_findPrevInstruction(pc_prev->prev)))
+               && (dist < MAX_DIST_BCC)
+               && isLabel(pc_next,PCI(pc_prev)->pcop->name)
+               && hasNoLabel(pc)) {
+             pCode *newBcc = getNegatedBcc (pc_prev, PCI(pc)->pcop);
            
-           if (newBcc) {
-             PCI(newBcc)->label = PCI(pc_prev)->label;
-             PCI(pc_prev)->label = NULL;
-            
-             pic16_pCodeInsertAfter(pc_prev, newBcc);
-             pic16_pCodeInsertAfter(pc_prev, pic16_newpCodeCharP("goto-optimization 2"));
-             pc->destruct(pc);
-             pc->destruct(pc_prev);
-             pc = newBcc;
-             isHandled = 1;
-             opt_reorder++;
+             if (newBcc) {
+               //fprintf (stderr, "%s:%d: (4) turning %s %s into %s %s\n", __FUNCTION__, __LINE__, PCI(pc)->mnemonic, label, PCI(newBcc)->mnemonic, label);
+               isHandled = 1; // do not perform further optimizations
+               if (pic16_pcode_verbose) { pic16_pCodeInsertAfter(pc_prev->prev, pic16_newpCodeCharP("(4) conditional skipping branch inverted")); }
+               pic16_pCodeReplace (pc_prev, newBcc);
+               pc->destruct(pc);
+               pc = newBcc;
+               opt_reorder++;
+               change++;
+               matchedInvertRule++;
+             }
            }
          }
-       }
-
-       if (!isHandled) {
-         // now just turn GOTO into BRA
-         if (!isJumptable(pc, pc_prev, pc_next)) {
+         
+         /* (5) now just turn GOTO into BRA */ 
+         if (!isHandled && (PCI(pc)->op == POC_GOTO)) {
            if (dist < MAX_DIST_BRA) {
              pCode *newBra = pic16_newpCode (POC_BRA, PCI(pc)->pcop);
-             isHandled = 1;
-             PCI(newBra)->label = PCI(pc)->label;
-             pic16_pCodeInsertAfter (pc, newBra);
-             pic16_pCodeInsertAfter(pc_prev, pic16_newpCodeCharP("goto-optimization 3"));
-             pc->destruct(pc);
+             //fprintf (stderr, "%s:%d: (5) turning %s %s into %s %s\n", __FUNCTION__, __LINE__, PCI(pc)->mnemonic, label, PCI(newBra)->mnemonic, label);
+             if (pic16_pcode_verbose) { pic16_pCodeInsertAfter(pc->prev, pic16_newpCodeCharP("(5) GOTO replaced by BRA")); }
+             pic16_pCodeReplace (pc, newBra);
              pc = newBra;
              opt++;
+             change++;
            } else {
              //fprintf (stderr, "(%d, too far for BRA)\n", dist);
              toofar++;
            }
-         } else {
-           //fprintf (stderr, "(in jumptable)\n");
-           jumptabs++;
-         }
-       } // if (!isHandled)
-      } // if
+         } // if (!isHandled)
+       } // if
 
-      pc_prev = pc;
-      pc = pc_next;
-    } // while (pc)
+       pc_prev = pc;
+       pc = pc_next;
+      } // while (pc)
+      
+      pBlockRemoveUnusedLabels (pb);
+      
+      // This line enables goto chain resolution!
+      if (matchedInvertRule > 1) matchedInvertRule = 1; else matchedInvertRule = 0;
+
+      iteration++;
+    } while (change); /* fixpoint iteration per pBlock */
   } // for (pb)
   
   // emit some statistics concerning goto-optimization
   // (maybe this should be moved to the general statistics?)
-  fprintf (stderr, "optimize-goto: %d GOTO->BRA; (%d GOTOs too far and "
-          "%d GOTOs in jumptables ignored); "
-          "%d BTFSx, GOTO->Bcc (%d too far), %d jumps reordered\n",
-          opt, toofar, jumptabs, opt_cond, cond_toofar, opt_reorder);
-  /*
-  fprintf (stderr, "saved %d + %d + %d = %d bytes in program memory\n",
-          (4 - 2) * opt,
-          (6 - 2) * opt_cond,
-          (6 - 2) * opt_reorder,
-          (4 - 2) * opt +  (6 - 2) * opt_cond + (6 - 2) * opt_reorder);
-  */
+  if (pic16_debug_verbose || pic16_pcode_verbose) {
+    fprintf (stderr, "optimize-goto:\n"
+            "\t%5d GOTO->BRA; (%d GOTOs too far)\n"
+            "\t%5d BTFSx, GOTO->Bcc (%d too far)\n"
+            "\t%5d conditional \"skipping\" jumps inverted\n"
+            "\t%5d GOTOs to next instruction removed\n"
+            "\t%5d chained GOTOs resolved\n",
+            opt, toofar, opt_cond, cond_toofar, opt_reorder, opt_gotonext, opt_gotochain);
+  } // if
 }
 
 #undef IS_GOTO
+#undef MAX_DIST_GOTO
 #undef MAX_DIST_BRA
 #undef MAX_DIST_BCC
 
index 41f864122c66666c018e0502a4e16d1f32e327dd..43dd89f47367ffdcb6690c7b3b3c5c2dfbe29f1b 100644 (file)
@@ -326,6 +326,8 @@ typedef enum
 {
   OPT_BEGIN,             /* mark beginning of optimization block */
   OPT_END,               /* mark ending of optimization block */
+  OPT_JUMPTABLE_BEGIN,   /* mark beginning of a jumptable */
+  OPT_JUMPTABLE_END      /* mark end of jumptable */
 } OPT_TYPE;
 
 /***********************************************************************
index 79351a97998d31ac729391320c43b8d1689a6df9..a0523c99e7a658cb4a01245eb6bb759d828bf317 100644 (file)
@@ -881,7 +881,12 @@ pic16_allocDirReg (operand *op )
 //                     fprintf(stderr, "%s:%d adding %s in direct registers\n", __FILE__, __LINE__, reg->name);
 //                     addSet(&pic16_dynDirectRegs, reg);
 
-                       checkAddReg(&pic16_dynDirectRegs, reg);
+#if 1
+                  if(!(IS_STATIC(OP_SYM_ETYPE(op))
+                      && OP_SYMBOL(op)->ival
+                  ))
+#endif
+                    checkAddReg(&pic16_dynDirectRegs, reg);
                }
        
        } else {