* sim/ucsim/cmd.src/cmdutil.cc: NUL device is detected as CG_FILE type
[fw/sdcc] / src / pic16 / pcodepeep.c
index b905e0221a34eec5197419c9e52a217b2aa2258c..ec373e3358477a89c119be5c21a0e67899355907 100644 (file)
 #include "pcodeflow.h"
 #include "ralloc.h"
 
-#if defined(__BORLANDC__) || defined(_MSC_VER)
-#define STRCASECMP stricmp
-#else
-#define STRCASECMP strcasecmp
-#endif
-
 pCodeOp *pic16_popCopyGPR2Bit(pCodeOpReg *pc, int bitval);
 
 pCodeOp *pic16_newpCodeOpWild(int id, pCodeWildBlock *pcwb, pCodeOp *subtype);
@@ -48,7 +42,7 @@ int pic16_getpCode(char *mnem,int dest);
 int pic16_getpCodePeepCommand(char *cmd);
 void pic16_pBlockMergeLabels(pBlock *pb);
 char *pic16_pCode2str(char *str, int size, pCode *pc);
-char *pic16_get_op( pCodeOp *pcop,char *buf,int buf_size);
+//char *pic16_get_op(pCodeOp *pcop,char *buf, size_t buf_size);
 pCodeOp *pic16_popCombine2(pCodeOp *, pCodeOp *, int);
 
 extern pCodeInstruction *pic16Mnemonics[];
@@ -276,7 +270,7 @@ static int cvt_extract_destination(parsedPattern *pp)
 
     // just check first letter for now
 
-    if(toupper(*pp->pct[0].tok.s) == 'F')
+    if(toupper((unsigned char)*pp->pct[0].tok.s) == 'F')
       return 1;
 
   } else if (pp->pct[0].tt == PCT_NUMBER) {
@@ -307,14 +301,14 @@ static pCodeOp *cvt_extract_status(char *reg, char *bit)
 
   if(len == 1) {
     // check C,Z
-    if(toupper(*bit) == 'C')
+    if(toupper((unsigned char)*bit) == 'C')
       return PCOP(pic16_popCopyGPR2Bit(&pic16_pc_status,PIC_C_BIT));
-    if(toupper(*bit) == 'Z')
+    if(toupper((unsigned char)*bit) == 'Z')
       return PCOP(pic16_popCopyGPR2Bit(&pic16_pc_status,PIC_Z_BIT));
   }
 
   // Check DC
-  if(len ==2 && toupper(bit[0]) == 'D' && toupper(bit[1]) == 'C')
+  if(len ==2 && toupper((unsigned char)bit[0]) == 'D' && toupper((unsigned char)bit[1]) == 'C')
     return PCOP(pic16_popCopyGPR2Bit(&pic16_pc_status,PIC_DC_BIT));
 
   return NULL;
@@ -513,7 +507,7 @@ static void * cvt_altpat_mnem1a(void *pp,pCodeWildBlock *pcwb)
   }
 
   if(pic16Mnemonics[opcode]->isBitInst)
-    pcosubtype = pic16_newpCodeOpBit(NULL,-1,0);
+    pcosubtype = pic16_newpCodeOpBit(NULL,-1,0, PO_GPR_REGISTER);
   else
     pcosubtype = pic16_newpCodeOp(NULL,PO_GPR_REGISTER);
 
@@ -810,7 +804,7 @@ static void * cvt_altpat_mnem3(void *pp,pCodeWildBlock *pcwb)
     //pcosubtype = cvt_extract_status(p[1].pct[0].tok.s, p[3].pct[0].tok.s);
 
     //if(pcosubtype == NULL) {
-    pcosubtype = pic16_newpCodeOpBit(p[1].pct[0].tok.s,p[3].pct[0].tok.n,0);
+    pcosubtype = pic16_newpCodeOpBit(p[1].pct[0].tok.s,p[3].pct[0].tok.n,0, PO_GPR_REGISTER);
     //}
   } else
     pcosubtype = pic16_newpCodeOp(p[1].pct[0].tok.s,PO_GPR_REGISTER);
@@ -962,15 +956,15 @@ static void tokenizeLineNode(char *ln)
 //     fprintf(stderr, "%s:%d: processing %s\n", __FILE__, __LINE__, ln); 
 
   while(*ln) {
-    if(isspace(*ln)) {
+    if(isspace((unsigned char)*ln)) {
       // add a SPACE token and eat the extra spaces.
       tokArr[tokIdx++].tt = PCT_SPACE;
-      while (isspace (*ln))
+      while (isspace ((unsigned char)*ln))
        ln++;
       continue;
     }
 
-    if(isdigit(*ln)) {
+    if(isdigit((unsigned char)*ln)) {
 
       tokArr[tokIdx].tt = PCT_NUMBER;
       tokArr[tokIdx++].tok.n = strtol(ln, &ln, 0);
@@ -1003,11 +997,11 @@ static void tokenizeLineNode(char *ln)
 
 
     default:                           // hack to allow : goto $
-      if(isalpha(*ln) || (*ln == '_')  || (!parsing_peeps && (*ln == '$'))) {
+      if(isalpha((unsigned char)*ln) || (*ln == '_')  || (!parsing_peeps && (*ln == '$'))) {
        char buffer[50];
        int i=0;
 
-       while( (isalpha(*ln)  ||  isdigit(*ln) || (*ln == '_') || (*ln == '$')) && i<49)
+       while( (isalpha((unsigned char)*ln) || isdigit((unsigned char)*ln) || (*ln == '_') || (*ln == '$')) && i<49)
          buffer[i++] = *ln++;
 
        ln--;
@@ -1739,7 +1733,7 @@ int pic16_pCodeSearchCondition(pCode *pc, unsigned int cond)
  *-----------------------------------------------------------------*/
 static int pCodeOpCompare(pCodeOp *pcops, pCodeOp *pcopd)
 {
-  char b[50], *n2;
+  char b[1024], *n2;
 
   if(!pcops || !pcopd)
     return 0;
@@ -1765,8 +1759,8 @@ static int pCodeOpCompare(pCodeOp *pcops, pCodeOp *pcopd)
     return 0;
   }
 
-  b[0]=0;
-  pic16_get_op(pcops,b,50);
+  memset(b, 0, sizeof(b) );       //b[0]=0;
+  pic16_get_op(pcops,b, sizeof(b) );
 
   n2 = pic16_get_op(pcopd,NULL,0);
 
@@ -1907,7 +1901,8 @@ static int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd)
 
       /* Compare the operands */
       if(PCI(pcd)->pcop) {
-       if (PCI(pcd)->pcop->type == PO_WILD) {
+       /* assert that optimizations do not touch operations that work on SFRs or INDF registers */
+       if ((PCI(pcd)->pcop->type == PO_WILD) && (!(PCI(pcs)->pcop) || ((PCI(pcs)->pcop->type != PO_SFR_REGISTER) && (PCI(pcs)->pcop->type != PO_INDF0)))) {
          index = PCOW(PCI(pcd)->pcop)->id;
          //DFPRINTF((stderr,"destination is wild\n"));
 #ifdef DEBUG_PCODEPEEP
@@ -1961,11 +1956,12 @@ static int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd)
 //           return 1;
            }
          }
-  
+
          /* now check whether the second operand matches */
-         if(PCOW2(PCI(pcd)->pcop) && (PCOR2(PCI(pcd)->pcop)->pcop2->type == PO_WILD)) {
+         /* assert that optimizations do not touch operations that work on SFRs or INDF registers */
+         if(PCOW2(PCI(pcd)->pcop) && (PCOP2(PCI(pcd)->pcop)->pcopR->type == PO_WILD) && (!(PCOP2(PCI(pcs)->pcop)->pcopR) || ((PCOP2(PCI(pcs)->pcop)->pcopR->type != PO_SFR_REGISTER) && (PCOP2(PCI(pcs)->pcop)->pcopR) && (PCOP2(PCI(pcs)->pcop)->pcopR->type != PO_INDF0)))) {
        
-               fprintf(stderr, "%s:%d %s second operand is wild\n", __FILE__, __LINE__, __FUNCTION__);
+//             fprintf(stderr, "%s:%d %s second operand is wild\n", __FILE__, __LINE__, __FUNCTION__);
        
                  index = PCOW2(PCI(pcd)->pcop)->id;
                //DFPRINTF((stderr,"destination is wild\n"));
@@ -1976,9 +1972,9 @@ static int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd)
                }
 #endif
 
-               PCOW2(PCI(pcd)->pcop)->matched = PCOR2(PCI(pcs)->pcop)->pcop2;
+               PCOW2(PCI(pcd)->pcop)->matched = PCOP2(PCI(pcs)->pcop)->pcopR;
                if(!peepBlock->target.wildpCodeOps[index]) {
-                       peepBlock->target.wildpCodeOps[index] = PCOR2(PCI(pcs)->pcop)->pcop2;
+                       peepBlock->target.wildpCodeOps[index] = PCOP2(PCI(pcs)->pcop)->pcopR;
 
                //if(PCI(pcs)->pcop->type == PO_GPR_TEMP) 
 
@@ -1992,21 +1988,21 @@ static int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd)
                                );
                        */
 
-                 return ((havematch==1) && pCodeOpCompare(PCOR2(PCI(pcs)->pcop)->pcop2,
+                 return ((havematch==1) && pCodeOpCompare(PCOP2(PCI(pcs)->pcop)->pcopR,
                                peepBlock->target.wildpCodeOps[index]));
                }
 
-               if(PCOR2(PCI(pcs)->pcop)->pcop2) {
+               if(PCOP2(PCI(pcs)->pcop)->pcopR) {
                  char *n;
 
-                       switch(PCOR2(PCI(pcs)->pcop)->pcop2->type) {
+                       switch(PCOP2(PCI(pcs)->pcop)->pcopR->type) {
                        case PO_GPR_TEMP:
                        case PO_FSR0:
                      //case PO_INDF0:
-                               n = PCOR(PCOR2(PCI(pcs)->pcop)->pcop2)->r->name;
+                               n = PCOR(PCOP2(PCI(pcs)->pcop)->pcopR)->r->name;
                                break;
                        default:
-                               n = PCOR2(PCI(pcs)->pcop)->pcop2->name;
+                               n = PCOP2(PCI(pcs)->pcop)->pcopR->name;
                        }
 
                        if(peepBlock->target.vars[index])
@@ -2018,11 +2014,16 @@ static int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd)
                        }
                }
          
-       } else return (havematch);
+         } else if (PCOW2(PCI(pcd)->pcop) && (PCOP2(PCI(pcd)->pcop)->pcopR->type == PO_WILD) && PCOP2(PCI(pcs)->pcop)->pcopR)
+           {
+             return 0;
+           } else {
+             return havematch;
+           }
 #if 0
         else if (PCI(pcd)->pcop->type == PO_LITERAL) {
          return (havematch &&
-               pCodeOpCompare(PCOR2(PCI(pcs)->pcop)->pcop2, PCOR2(PCI(pcd)->pcop)->pcop2);
+               pCodeOpCompare(PCOR2(PCI(pcs)->pcop)->pcop2, PCOR2(PCI(pcd)->pcop)->pcop2));
 
        }
 #endif
@@ -2174,13 +2175,58 @@ pCodeOp *pic16_pCodeOpCopy(pCodeOp *pcop)
     return NULL;
 
   switch(pcop->type) { 
+  case PO_NONE:
+  case PO_STR:
+  case PO_REL_ADDR:
+       pcopnew = Safe_calloc(1, sizeof (pCodeOp));
+       memcpy(pcopnew, pcop, sizeof (pCodeOp));
+       break;
+
+  case PO_W:
+  case PO_WREG:
+  case PO_STATUS:
+  case PO_BSR:
+  case PO_FSR0:
+  case PO_INDF0:
+  case PO_INTCON:
+  case PO_GPR_REGISTER:
+  case PO_GPR_TEMP:
+  case PO_SFR_REGISTER:
+  case PO_PCL:
+  case PO_PCLATH:
+  case PO_PCLATU:
+  case PO_PRODL:
+  case PO_PRODH:
+  case PO_DIR:
+    //DFPRINTF((stderr,"pCodeOpCopy GPR register\n"));
+    /* XXX: might also be pCodeOpReg2 -- that's why the two structs are identical */
+    pcopnew = Safe_calloc(1,sizeof(pCodeOpReg) );
+    memcpy (pcopnew, pcop, sizeof(pCodeOpReg));
+    break;
+    
+  case PO_LITERAL:
+    //DFPRINTF((stderr,"pCodeOpCopy lit\n"));
+    /* XXX: might also be pCodeOpLit2, that's why the two structs are identical... */
+    pcopnew = Safe_calloc(1,sizeof(pCodeOpLit) );
+    memcpy (pcopnew, pcop, sizeof(pCodeOpLit));
+    break;
+
+  case PO_IMMEDIATE:
+    pcopnew = Safe_calloc(1,sizeof(pCodeOpImmd) );
+    memcpy (pcopnew, pcop, sizeof(pCodeOpImmd));
+    break;
+    
+  case PO_GPR_BIT:
   case PO_CRY:
   case PO_BIT:
-    //DFPRINTF((stderr,"pCodeOpCopy bit\n"));
-    pcopnew = Safe_calloc(1,sizeof(pCodeOpRegBit) );
-    PCORB(pcopnew)->bit = PCORB(pcop)->bit;
-    PCORB(pcopnew)->inBitSpace = PCORB(pcop)->inBitSpace;
+    pcopnew = Safe_calloc(1, sizeof (pCodeOpRegBit));
+    memcpy (pcopnew, pcop, sizeof (pCodeOpRegBit));
+    break;
 
+  case PO_LABEL:
+    //DFPRINTF((stderr,"pCodeOpCopy label\n"));
+    pcopnew = Safe_calloc(1,sizeof(pCodeOpLabel) );
+    memcpy (pcopnew, pcop, sizeof (pCodeOpLabel));
     break;
 
   case PO_WILD:
@@ -2195,84 +2241,19 @@ pCodeOp *pic16_pCodeOpCopy(pCodeOp *pcop)
       pcopnew->name = Safe_strdup(PCOW(pcop)->pcwb->vars[PCOW(pcop)->id]);
       //DFPRINTF((stderr,"copied a wild op named %s\n",pcopnew->name));
     }
-
     return pcopnew;
     break;
 
-  case PO_LABEL:
-    //DFPRINTF((stderr,"pCodeOpCopy label\n"));
-    pcopnew = Safe_calloc(1,sizeof(pCodeOpLabel) );
-    PCOLAB(pcopnew)->key =  PCOLAB(pcop)->key;
-    break;
-
-  case PO_IMMEDIATE:
-    pcopnew = Safe_calloc(1,sizeof(pCodeOpImmd) );
-    PCOI(pcopnew)->index = PCOI(pcop)->index;
-    PCOI(pcopnew)->offset = PCOI(pcop)->offset;
-    PCOI(pcopnew)->_const = PCOI(pcop)->_const;
-    break;
-
-  case PO_LITERAL:
-    //DFPRINTF((stderr,"pCodeOpCopy lit\n"));
-    pcopnew = Safe_calloc(1,sizeof(pCodeOpLit) );
-    PCOL(pcopnew)->lit = PCOL(pcop)->lit;
-    break;
-
-#if 0 // mdubuc - To add
-  case PO_REL_ADDR:
-    break;
-#endif
-
-  case PO_GPR_BIT:
-
-    pcopnew = pic16_newpCodeOpBit(pcop->name, PCORB(pcop)->bit,PCORB(pcop)->inBitSpace);
-    PCOR(pcopnew)->r = PCOR(pcop)->r;
-    PCOR(pcopnew)->rIdx = PCOR(pcop)->rIdx;
-    DFPRINTF((stderr," pCodeOpCopy Bit -register index\n"));
+  case PO_TWO_OPS:
+    pcopnew = pic16_newpCodeOp2( pic16_pCodeOpCopy( PCOP2(pcop)->pcopL ),
+    pic16_pCodeOpCopy( PCOP2(pcop)->pcopR ) );
     return pcopnew;
-    break;
-
-  case PO_GPR_REGISTER:
-  case PO_GPR_TEMP:
-  case PO_FSR0:
-  case PO_INDF0:
-    //DFPRINTF((stderr,"pCodeOpCopy GPR register\n"));
-    pcopnew = Safe_calloc(1,sizeof(pCodeOpReg) );
-    PCOR(pcopnew)->r = PCOR(pcop)->r;
-    PCOR(pcopnew)->rIdx = PCOR(pcop)->rIdx;
-    PCOR(pcopnew)->instance = PCOR(pcop)->instance;
-    DFPRINTF((stderr," register index %d\n", PCOR(pcop)->r->rIdx));
-    break;
-
-  case PO_DIR:
-    //fprintf(stderr,"pCodeOpCopy PO_DIR\n");
-    pcopnew = Safe_calloc(1,sizeof(pCodeOpReg) );
-    PCOR(pcopnew)->r = PCOR(pcop)->r;
-    PCOR(pcopnew)->rIdx = PCOR(pcop)->rIdx;
-    PCOR(pcopnew)->instance = PCOR(pcop)->instance;
-    break;
-  case PO_STATUS:
-    DFPRINTF((stderr,"pCodeOpCopy PO_STATUS\n"));
-  case PO_BSR:
-    DFPRINTF((stderr,"pCodeOpCopy PO_BSR\n"));
-  case PO_SFR_REGISTER:
-  case PO_STR:
-  case PO_NONE:
-  case PO_W:
-  case PO_WREG:
-  case PO_INTCON:
-  case PO_PCL:
-  case PO_PCLATH:
-  case PO_PCLATU:
-  case PO_PRODL:
-  case PO_PRODH:
-  case PO_REL_ADDR:
-    //DFPRINTF((stderr,"pCodeOpCopy register type %d\n", pcop->type));
-    pcopnew = Safe_calloc(1,sizeof(pCodeOp) );
 
-  }
+  default:
+    assert ( !"unhandled pCodeOp type copied" );
+  } // switch
 
-  pcopnew->type = pcop->type;
+  /* strdup pcop->name (prevent access to shared but released memory) */
   if(pcop->name)
     pcopnew->name = Safe_strdup(pcop->name);
   else
@@ -2428,16 +2409,16 @@ int pic16_pCodePeepMatchRule(pCode *pc)
        pcin->prev = pc->prev;
 
 
-#if 0
+#if 1
       {
        /*     DEBUG    */
        /* Converted the deleted pCodes into comments */
 
-       char buf[256];
+       char buf[1024];
        pCodeCSource *pc_cline2=NULL;
 
-       buf[0] = ';';
-       buf[1] = '#';
+//     buf[0] = ';';
+       buf[0] = '#';
 
        while(pc &&  pc!=pcin) {
 
@@ -2451,7 +2432,7 @@ int pic16_pCodePeepMatchRule(pCode *pc)
            }
          }
 
-         pic16_pCode2str(&buf[2], 254, pc);
+         pic16_pCode2str(&buf[1], sizeof( buf )-1, pc);
          pic16_pCodeInsertAfter(pcprev, pic16_newpCodeCharP(buf));
          pcprev = pcprev->next;
          pc = pc->next;
@@ -2491,11 +2472,11 @@ int pic16_pCodePeepMatchRule(pCode *pc)
              pcop = pic16_pCodeOpCopy(PCI(pcr)->pcop);
          }
 
-         if(PCI(pcr)->is2MemOp && PCOR2(PCI(pcr)->pcop)->pcop2) {
+         if(PCI(pcr)->is2MemOp && PCOP2(PCI(pcr)->pcop)->pcopR) {
            /* The replacing instruction has also a second operand.
             * Is it wild? */
 //             fprintf(stderr, "%s:%d pcop2= %p\n", __FILE__, __LINE__, PCOR2(PCI(pcr)->pcop)->pcop2);
-           if(PCOR2(PCI(pcr)->pcop)->pcop2->type == PO_WILD) {
+           if(PCOP2(PCI(pcr)->pcop)->pcopR->type == PO_WILD) {
              int index = PCOW2(PCI(pcr)->pcop)->id;
 //             fprintf(stderr, "%s:%d replacing index= %d\n", __FUNCTION__, __LINE__, index);
              //DFPRINTF((stderr,"copying wildopcode\n"));
@@ -2506,7 +2487,7 @@ int pic16_pCodePeepMatchRule(pCode *pc)
                DFPRINTF((stderr,"error, wildopcode in replace but not source?\n"));
            } else
              pcop = pic16_popCombine2(pic16_pCodeOpCopy(pcop),
-               pic16_pCodeOpCopy(PCOR2(PCI(pcr)->pcop)->pcop2), 0);
+               pic16_pCodeOpCopy(PCOP2(PCI(pcr)->pcop)->pcopR), 0);
              
          }