* src/pic16/gen.c (genNearPointerSet): fixed handling of literals
[fw/sdcc] / src / pic16 / gen.c
index 898f47302e83cacbfe09e06d7319053cd4b539b2..fd084f76ef22d8e95ebc9f93d779fe33c725df40 100644 (file)
@@ -182,7 +182,7 @@ static struct {
 
 extern int pic16_ptrRegReq ;
 extern int pic16_nRegs;
-extern FILE *codeOutFile;
+extern struct dbuf_s *codeOutBuf;
 //static void saverbank (int, iCode *,bool);
 
 static lineNode *lineHead = NULL;
@@ -266,6 +266,7 @@ void pic16_emitpcomment (char *fmt, ...)
                     (lineHead = newLineNode(lb)));
     lineCurr->isInline = _G.inLine;
     lineCurr->isDebug  = _G.debugLine;
+    lineCurr->isComment = 1;
 
     pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
     va_end(ap);
@@ -378,6 +379,8 @@ void pic16_emitcode (char *inst,char *fmt, ...)
                     (lineHead = newLineNode(lb)));
     lineCurr->isInline = _G.inLine;
     lineCurr->isDebug  = _G.debugLine;
+    lineCurr->isLabel = (lbp[strlen (lbp) - 1] == ':');
+    lineCurr->isComment = (*lbp == ';');
 
 // VR    fprintf(stderr, "lb = <%s>\n", lbp);
 
@@ -952,7 +955,9 @@ static asmop *aopForRemat (operand *op, bool result) // x symbol *sym)
        for (;;) {
                oldic = ic;
 
-//             pic16_emitpcomment("ic: %s\n", printILine(ic));
+//              chat *iLine = printILine(ic);
+//             pic16_emitpcomment("ic: %s\n", iLine);
+//              dbuf_free(iLine);
        
                if (ic->op == '+') {
                        val += (int) operandLitValue(IC_RIGHT(ic));
@@ -3593,12 +3598,6 @@ static int resultRemat (iCode *ic)
   return 0;
 }
 
-#if defined(__BORLANDC__) || defined(_MSC_VER)
-#define STRCASECMP stricmp
-#else
-#define STRCASECMP strcasecmp
-#endif
-
 #if 0
 /*-----------------------------------------------------------------*/
 /* inExcludeList - return 1 if the string is in exclude Reg list   */
@@ -3705,6 +3704,9 @@ static void genFunction (iCode *ic)
     pic16_emitcode(";"," function %s",sym->name);
     pic16_emitcode(";","-----------------------------------------");
 
+    /* prevent this symbol from being emitted as 'extern' */
+    pic16_stringInSet(sym->rname, &pic16_localFunctions, 1);
+
     pic16_emitcode("","%s:",sym->rname);
     pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(moduleName,sym->rname));
 
@@ -3755,6 +3757,8 @@ static void genFunction (iCode *ic)
         pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
         pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l ));
         pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
+        pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_pclath ));
+        pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_pclatu ));
         
 //        pic16_pBlockConvert2ISR(pb);
     }
@@ -3939,6 +3943,8 @@ static void genEndFunction (iCode *ic)
     _G.useWreg = 0;
 
     if (IFFUNC_ISISR(sym->type)) {
+      pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_pclatu ));
+      pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_pclath ));
       pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
       pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l));
       pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
@@ -8475,112 +8481,119 @@ static void genXor (iCode *ic, iCode *ifx)
 static void genInline (iCode *ic)
 {
   char *buffer, *bp, *bp1;
+  bool inComment = FALSE;
     
-       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+  DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-       _G.inLine += (!options.asmpeep);
+  _G.inLine += (!options.asmpeep);
 
-       buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
-       strcpy(buffer,IC_INLINE(ic));
-       
-       while((bp1=strstr(bp, "\\n"))) {
-         *bp1++ = '\n';
-         *bp1++ = ' ';
-         bp = bp1;
-        }
-        bp = bp1 = buffer;
+  buffer = bp = bp1 = Safe_strdup (IC_INLINE (ic));
+  
+  while((bp1=strstr(bp, "\\n"))) {
+    *bp1++ = '\n';
+    *bp1++ = ' ';
+    bp = bp1;
+  }
+  bp = bp1 = buffer;
 
 #if 0
   /* This is an experimental code for #pragma inline
      and is temporarily disabled for 2.5.0 release */
-        if(asmInlineMap)
-        {
-          symbol *sym;
-          char *s;
-          char *cbuf;
-          int cblen;
-
-            cbuf = Safe_strdup(buffer);
-            cblen = strlen(buffer)+1;
-            memset(cbuf, 0, cblen);
-
-            bp = buffer;
-            bp1 = cbuf;
-            while(*bp) {
-              if(*bp != '%')*bp1++ = *bp++;
-              else {
-                int i;
-
-                  bp++;
-                  i = *bp - '0';
-                  if(i>elementsInSet(asmInlineMap))break;
-                  
-                  bp++;
-                  s = indexSet(asmInlineMap, i);
-                  DEBUGpc("searching symbol s = `%s'", s);
-                  sym = findSym(SymbolTab, NULL, s);
-
-                  if(sym->reqv) {
-                    strcat(bp1, sym->reqv->operand.symOperand->regs[0]->name);
-                  } else {
-                    strcat(bp1, sym->rname);
-                  }
-                  
-                  while(*bp1)bp1++;
-              }
-              
-              if(strlen(bp1) > cblen - 16) {
-                int i = strlen(cbuf);
-                cblen += 50;
-                cbuf = realloc(cbuf, cblen);
-                memset(cbuf+i, 0, 50);
-                bp1 = cbuf + i;
-              }
-            }
+  if(asmInlineMap)
+  {
+    symbol *sym;
+    char *s;
+    char *cbuf;
+    int cblen;
+
+      cbuf = Safe_strdup(buffer);
+      cblen = strlen(buffer)+1;
+      memset(cbuf, 0, cblen);
+
+      bp = buffer;
+      bp1 = cbuf;
+      while(*bp) {
+        if(*bp != '%')*bp1++ = *bp++;
+        else {
+          int i;
+
+            bp++;
+            i = *bp - '0';
+            if(i>elementsInSet(asmInlineMap))break;
             
-            free(buffer);
-            buffer = Safe_strdup( cbuf );
-            free(cbuf);
+            bp++;
+            s = indexSet(asmInlineMap, i);
+            DEBUGpc("searching symbol s = `%s'", s);
+            sym = findSym(SymbolTab, NULL, s);
+
+            if(sym->reqv) {
+              strcat(bp1, sym->reqv->operand.symOperand->regs[0]->name);
+            } else {
+              strcat(bp1, sym->rname);
+            }
             
-            bp = bp1 = buffer;
+            while(*bp1)bp1++;
+        }
+        
+        if(strlen(bp1) > cblen - 16) {
+          int i = strlen(cbuf);
+          cblen += 50;
+          cbuf = realloc(cbuf, cblen);
+          memset(cbuf+i, 0, 50);
+          bp1 = cbuf + i;
         }
+      }
+      
+      free(buffer);
+      buffer = Safe_strdup( cbuf );
+      free(cbuf);
+      
+      bp = bp1 = buffer;
+  }
 #endif  /* 0 */
 
-       /* emit each line as a code */
-       while (*bp) {
-               if (*bp == '\n') {
-                       *bp++ = '\0';
+  /* emit each line as a code */
+  while (*bp)
+    {
+      switch (*bp)
+        {
+        case ';':
+          inComment = TRUE;
+          ++bp;
+          break;
 
-                       if(*bp1)
-                               pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); // inline directly, no process
-                       bp1 = bp;
-               } else {
-                       if (*bp == ':') {
-                               bp++;
-                               *bp = '\0';
-                               bp++;
-
-                               /* print label, use this special format with NULL directive
-                                * to denote that the argument should not be indented with tab */
-                               pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(NULL, bp1)); // inline directly, no process
-                               bp1 = bp;
-                       } if (*bp == ';') {
-                               /* advance to end of line (prevent splitting of comments at ':' */
-                               while (*bp && *bp != '\n') {
-                                       bp++;
-                               } // while
-                       } else
-                               bp++;
-               }
-       }
+        case '\n':
+          inComment = FALSE;
+          *bp++ = '\0';
+          if (*bp1)
+            pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); // inline directly, no process
+          bp1 = bp;
+          break;
 
-       if ((bp1 != bp) && *bp1)
-               pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); // inline directly, no process
+        default:
+          /* Add \n for labels, not dirs such as c:\mydir */
+          if (!inComment && (*bp == ':') && (isspace((unsigned char)bp[1])))
+            {
+              ++bp;
+              *bp = '\0';
+              ++bp;
+              /* print label, use this special format with NULL directive
+               * to denote that the argument should not be indented with tab */
+              pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(NULL, bp1)); // inline directly, no process
+              bp1 = bp;
+            }
+          else
+            ++bp;
+          break;
+        }
+    }
 
+  if ((bp1 != bp) && *bp1)
+    pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); // inline directly, no process
 
-    Safe_free(buffer);
+  Safe_free (buffer);
 
-    _G.inLine -= (!options.asmpeep);
+  _G.inLine -= (!options.asmpeep);
 }
 
 /*-----------------------------------------------------------------*/
@@ -11715,7 +11728,7 @@ static void genPackBits (sym_link    *etype , operand *result,
       || SPEC_BLEN(etype) <= 8 )  {
     int fsr0_setup = 0;
 
-    if (blen != 8 || bstr != 0) {
+    if (blen != 8 || (bstr % 8) != 0) {
       // we need to combine the value with the old value
       if(!shifted_and_masked)
       {
@@ -11750,7 +11763,12 @@ static void genPackBits (sym_link    *etype , operand *result,
         if (lit != 0)
          pic16_emitpcode(POC_IORLW, pic16_popGetLit(lit));
       }
-    } // if (blen != 8 || bstr != 0)
+    } else { // if (blen == 8 && (bstr % 8) == 0)
+       if (shifted_and_masked) {
+           // move right (literal) to WREG (only case where right is not yet in WREG)
+           pic16_mov2w(AOP(right), (bstr / 8));
+       }
+    }
 
     /* write new value back */
     if ((IS_SYMOP(result) && !IS_PTR(operandType(result)))
@@ -11959,7 +11977,7 @@ static void genNearPointerSet (operand *right,
            
         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
         while (size--) {
-          if (AOP_TYPE(right) == AOP_LIT) {
+          if (is_LitOp(right)) {
             pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
             if (size) {
               pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_postinc0));
@@ -13164,12 +13182,12 @@ static void genCast (iCode *ic)
              tag = GPTR_TAG_CODE;
            } else if (IS_PTR(rtype)) {
              PERFORM_ONCE(weirdcast,
-             fprintf (stderr, "%s:%u: WARNING: casting `(generic*)(unknown*)' -- assumimg __data space\n", ic->filename, ic->lineno);
+             fprintf (stderr, "%s:%u: WARNING: casting `(generic*)(unknown*)' -- assuming __data space\n", ic->filename, ic->lineno);
              );
              tag = GPTR_TAG_DATA;
            } else {
              PERFORM_ONCE(weirdcast,
-             fprintf (stderr, "%s:%u: WARNING: casting `(generic*)(non-pointer)' -- assumimg __data space\n", ic->filename, ic->lineno);
+             fprintf (stderr, "%s:%u: WARNING: casting `(generic*)(non-pointer)' -- assuming __data space\n", ic->filename, ic->lineno);
              );
              tag = GPTR_TAG_DATA;
            }
@@ -13623,11 +13641,12 @@ void genpic16Code (iCode *lic)
       }
        
       if(options.iCodeInAsm) {
-        char *l;
+        char *iLine;
 
           /* insert here code to print iCode as comment */
-          l = Safe_strdup(printILine(ic));
-          pic16_emitpcomment("ic:%d: %s", ic->seq, l);
+          iLine = printILine(ic);
+          pic16_emitpcomment("ic:%d: %s", ic->seq, iLine);
+          dbuf_free(iLine);
       }
 
       /* if the result is marked as
@@ -13835,7 +13854,7 @@ void genpic16Code (iCode *lic)
       peepHole (&lineHead);
 
     /* now do the actual printing */
-    printLine (lineHead, codeOutFile);
+    printLine (lineHead, codeOutBuf);
 
 #ifdef PCODE_DEBUG
     DFPRINTF((stderr,"printing pBlock\n\n"));