fixed bug #460010
[fw/sdcc] / src / pic / pcode.c
index 1e80a0547f7a97661377ea9bff35706aa0efed33..95da354efd3198dab43976dc340230b6cd5fe210 100644 (file)
 
 #include "pcode.h"
 #include "ralloc.h"
+
+#if defined(__BORLANDC__) || defined(_MSC_VER)
+#define STRCASECMP stricmp
+#else
+#define STRCASECMP strcasecmp
+#endif
+
 // Eventually this will go into device dependent files:
 pCodeOpReg pc_status    = {{PO_STATUS,  "STATUS"}, -1, NULL,NULL};
 pCodeOpReg pc_indf      = {{PO_INDF,    "INDF"}, -1, NULL,NULL};
@@ -552,7 +559,7 @@ pCodeInstruction pciRETURN = {
    AnalyzeRETURN,
    genericDestruct,
    genericPrint},
-  POC_RETLW,
+  POC_RETURN,
   "RETURN",
   NULL, // operand
   0,    // num ops
@@ -682,6 +689,39 @@ char *Safe_strdup(char *str)
     
 }
 
+
+/*-----------------------------------------------------------------*/
+/* SAFE_snprintf - like snprintf except the string pointer is      */
+/*                 after the string has been printed to. This is   */
+/*                 useful for printing to string as though if it   */
+/*                 were a stream.                                  */
+/*-----------------------------------------------------------------*/
+void SAFE_snprintf(char **str, size_t *size, const  char  *format, ...)
+{
+  va_list val;
+  int len;
+
+  if(!str || !*str)
+    return;
+
+  va_start(val, format);
+#if 0
+  // Alas, vsnprintf is not ANSI standard, and does not exist
+  // on Solaris (and probably other non-Gnu flavored Unixes).
+  vsnprintf(*str, *size, format, val);
+#else
+  // This, of course, is *not* safe, despite the name.
+  vsprintf(*str, format, val);
+#endif
+    
+  va_end (val);
+
+  len = strlen(*str);
+  *str += len;
+  *size -= len;
+
+}
+
 void  pCodeInitRegisters(void)
 {
 
@@ -696,7 +736,7 @@ void  pCodeInitRegisters(void)
 /*                                                                 */
 /*-----------------------------------------------------------------*/
 
-int mnem2key(char *mnem)
+int mnem2key(char const *mnem)
 {
   int key = 0;
 
@@ -705,7 +745,7 @@ int mnem2key(char *mnem)
 
   while(*mnem) {
 
-    key += *mnem++ +1;
+    key += toupper(*mnem++) +1;
 
   }
 
@@ -767,39 +807,6 @@ void pic14initMnemonics(void)
   for(i=0; i<MAX_PIC14MNEMONICS; i++)
     if(pic14Mnemonics[i])
       hTabAddItem(&pic14MnemonicsHash, mnem2key(pic14Mnemonics[i]->mnemonic), pic14Mnemonics[i]);
-/*
-  hTabAddItem(&pic14MnemonicsHash, mnem2key(scpADDLW), scpADDLW);
-  hTabAddItem(&pic14MnemonicsHash, mnem2key(scpADDWF),scpADDWF);
-  hTabAddItem(&pic14MnemonicsHash, mnem2key(scpANDLW),scpANDLW);
-  hTabAddItem(&pic14MnemonicsHash, mnem2key(scpANDWF),scpANDWF);
-  hTabAddItem(&pic14MnemonicsHash, mnem2key(scpBCF),scpBCF);
-  hTabAddItem(&pic14MnemonicsHash, mnem2key(scpBSF),scpBSF);
-  hTabAddItem(&pic14MnemonicsHash, mnem2key(scpBTFSC),scpBTFSC);
-  hTabAddItem(&pic14MnemonicsHash, mnem2key(scpBTFSS),scpBTFSS);
-  hTabAddItem(&pic14MnemonicsHash, mnem2key(scpCALL),scpCALL);
-  hTabAddItem(&pic14MnemonicsHash, mnem2key(scpCOMF),scpCOMF);
-  hTabAddItem(&pic14MnemonicsHash, mnem2key(scpCLRF),scpCLRF);
-  hTabAddItem(&pic14MnemonicsHash, mnem2key(scpCLRW),scpCLRW);
-  hTabAddItem(&pic14MnemonicsHash, mnem2key(scpDECF),scpDECF);
-  hTabAddItem(&pic14MnemonicsHash, mnem2key(scpDECFSZ),scpDECFSZ);
-  hTabAddItem(&pic14MnemonicsHash, mnem2key(scpGOTO),scpGOTO);
-  hTabAddItem(&pic14MnemonicsHash, mnem2key(scpINCF),scpINCF);
-  hTabAddItem(&pic14MnemonicsHash, mnem2key(scpINCFSZ),scpINCFSZ);
-  hTabAddItem(&pic14MnemonicsHash, mnem2key(scpIORLW),scpIORLW);
-  hTabAddItem(&pic14MnemonicsHash, mnem2key(scpIORWF),scpIORWF);
-  hTabAddItem(&pic14MnemonicsHash, mnem2key(scpMOVF),scpMOVF);
-  hTabAddItem(&pic14MnemonicsHash, mnem2key(scpMOVLW),scpMOVLW);
-  hTabAddItem(&pic14MnemonicsHash, mnem2key(scpMOVWF),scpMOVWF);
-  hTabAddItem(&pic14MnemonicsHash, mnem2key(scpNEGF),scpNEGF);
-  hTabAddItem(&pic14MnemonicsHash, mnem2key(scpRETLW),scpRETLW);
-  hTabAddItem(&pic14MnemonicsHash, mnem2key(scpRETURN),scpRETURN);
-  hTabAddItem(&pic14MnemonicsHash, mnem2key(scpSUBLW),scpSUBLW);
-  hTabAddItem(&pic14MnemonicsHash, mnem2key(scpSUBWF),scpSUBWF);
-  hTabAddItem(&pic14MnemonicsHash, mnem2key(scpTRIS),scpTRIS);
-  hTabAddItem(&pic14MnemonicsHash, mnem2key(scpXORLW),scpXORLW);
-  hTabAddItem(&pic14MnemonicsHash, mnem2key(scpXORWF),scpXORWF);
-*/
-
   pci = hTabFirstItem(pic14MnemonicsHash, &key);
 
   while(pci) {
@@ -810,6 +817,30 @@ void pic14initMnemonics(void)
   mnemonics_initialized = 1;
 }
 
+int getpCode(char *mnem,unsigned dest)
+{
+
+  pCodeInstruction *pci;
+  int key = mnem2key(mnem);
+
+  if(!mnemonics_initialized)
+    pic14initMnemonics();
+
+  pci = hTabFirstItemWK(pic14MnemonicsHash, key);
+
+  while(pci) {
+
+    if(STRCASECMP(pci->mnemonic, mnem) == 0) {
+      if((pci->num_ops <= 1) || (pci->dest == dest))
+       return(pci->op);
+    }
+
+    pci = hTabNextItemWK (pic14MnemonicsHash);
+  
+  }
+
+  return -1;
+}
 
 char getpBlock_dbName(pBlock *pb)
 {
@@ -965,7 +996,7 @@ pCode *newpCode (PIC_OPCODE op, pCodeOp *pcop)
     
   pci = Safe_calloc(1, sizeof(pCodeInstruction));
 
-  if((op < MAX_PIC14MNEMONICS) && pic14Mnemonics[op]) {
+  if((op>=0) && (op < MAX_PIC14MNEMONICS) && pic14Mnemonics[op]) {
     memcpy(pci, pic14Mnemonics[op], sizeof(pCodeInstruction));
     pci->pcop = pcop;
 
@@ -995,6 +1026,10 @@ pCode *newpCode (PIC_OPCODE op, pCodeOp *pcop)
 /* line (of assembly code) is declared matched. Note that the      */
 /* operand may be wild too.                                        */
 /*                                                                 */
+/*   Note, a wild instruction is specified just like a wild var:   */
+/*      %4     ; A wild instruction,                               */
+/*  See the peeph.def file for additional examples                 */
+/*                                                                 */
 /*-----------------------------------------------------------------*/
 
 pCode *newpCodeWild(int pCodeID, pCodeOp *optional_operand, pCodeOp *optional_label)
@@ -1013,7 +1048,7 @@ pCode *newpCodeWild(int pCodeID, pCodeOp *optional_operand, pCodeOp *optional_la
   pcw->pc.destruct = genericDestruct;
   pcw->pc.print = genericPrint;
 
-  pcw->id = pCodeID;
+  pcw->id = pCodeID;              // this is the 'n' in %n
   pcw->operand = optional_operand;
   pcw->label   = optional_label;
 
@@ -1083,6 +1118,20 @@ pCode *newpCodeFunction(char *mod,char *f)
 
 }
 
+static void pCodeLabelDestruct(pCode *pc)
+{
+
+  if(!pc)
+    return;
+
+  unlinkPC(pc);
+
+  if(PCL(pc)->label)
+    free(PCL(pc)->label);
+
+  free(pc);
+
+}
 
 pCode *newpCodeLabel(int key)
 {
@@ -1098,7 +1147,7 @@ pCode *newpCodeLabel(int key)
   pcl->pc.pb = NULL;
 
   pcl->pc.analyze = genericAnalyze;
-  pcl->pc.destruct = genericDestruct;
+  pcl->pc.destruct = pCodeLabelDestruct;
   pcl->pc.print = pCodePrintLabel;
 
   pcl->key = key;
@@ -1129,7 +1178,7 @@ pBlock *newpBlock(void)
 
   pBlock *PpB;
 
-  _ALLOC(PpB,sizeof(pBlock));
+  PpB = Safe_calloc(1,sizeof(pBlock) );
   PpB->next = PpB->prev = NULL;
 
   PpB->function_entries = PpB->function_exits = PpB->function_calls = NULL;
@@ -1141,7 +1190,7 @@ pBlock *newpBlock(void)
 }
 
 /*-----------------------------------------------------------------*/
-/* newpCodeChain - create a new chain of pCodes                    */
+/* newpCodeChai0n - create a new chain of pCodes                    */
 /*-----------------------------------------------------------------*
  *
  *  This function will create a new pBlock and the pointer to the
@@ -1161,20 +1210,6 @@ pBlock *newpCodeChain(memmap *cm,char c, pCode *pc)
   return pB;
 }
 
-/*-----------------------------------------------------------------*/
-/*-----------------------------------------------------------------*/
-
-pCodeOp *newpCodeOp(char *name, PIC_OPTYPE type)
-{
-  pCodeOp *pcop;
-
-  pcop = Safe_calloc(1,sizeof(pCodeOp) );
-  pcop->type = type;
-  pcop->name = Safe_strdup(name);   
-
-  return pcop;
-}
-
 /*-----------------------------------------------------------------*/
 /* newpCodeOpLabel - Create a new label given the key              */
 /*  Note, a negative key means that the label is part of wild card */
@@ -1207,11 +1242,14 @@ pCodeOp *newpCodeOpLit(int lit)
   pCodeOp *pcop;
 
 
-  _ALLOC(pcop,sizeof(pCodeOpLit) );
+  pcop = Safe_calloc(1,sizeof(pCodeOpLit) );
   pcop->type = PO_LITERAL;
-  sprintf(s,"0x%02x",lit);
-  _ALLOC_ATOMIC(pcop->name,strlen(s)+1);
-  strcpy(pcop->name,s);
+  if(lit>=0) {
+    sprintf(s,"0x%02x",lit);
+    pcop->name = Safe_strdup(s);
+  } else
+    pcop->name = NULL;
+
   ((pCodeOpLit *)pcop)->lit = lit;
 
   return pcop;
@@ -1245,9 +1283,10 @@ pCodeOp *newpCodeOpBit(char *s, int bit)
 {
   pCodeOp *pcop;
 
-  _ALLOC(pcop,sizeof(pCodeOpBit) );
+  pcop = Safe_calloc(1,sizeof(pCodeOpBit) );
   pcop->type = PO_BIT;
   pcop->name = Safe_strdup(s);   
+
   PCOB(pcop)->bit = bit;
   if(bit>=0)
     PCOB(pcop)->inBitSpace = 1;
@@ -1257,17 +1296,52 @@ pCodeOp *newpCodeOpBit(char *s, int bit)
   return pcop;
 }
 
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+
+pCodeOp *newpCodeOp(char *name, PIC_OPTYPE type)
+{
+  pCodeOp *pcop;
+
+  switch(type) {
+  case PO_BIT:
+    pcop = newpCodeOpBit(name, -1);
+    break;
+
+  case PO_LITERAL:
+    pcop = newpCodeOpLit(-1);
+    break;
+
+  case PO_LABEL:
+    pcop = newpCodeOpLabel(-1);
+    break;
+
+  default:
+    pcop = Safe_calloc(1,sizeof(pCodeOp) );
+    pcop->type = type;
+    pcop->name = Safe_strdup(name);   
+  }
+
+  return pcop;
+}
+
 /*-----------------------------------------------------------------*/
 /* addpCode2pBlock - place the pCode into the pBlock linked list   */
 /*-----------------------------------------------------------------*/
 void addpCode2pBlock(pBlock *pb, pCode *pc)
 {
-
-  pb->pcTail->next = pc;
-  pc->prev = pb->pcTail;
-  pc->next = NULL;
-  pc->pb = pb;
-  pb->pcTail = pc;
+  if(!pb->pcHead) {
+    /* If this is the first pcode to be added to a block that
+     * was initialized with a NULL pcode, then go ahead and
+     * make this pcode the head and tail */
+    pb->pcHead  = pb->pcTail = pc;
+  } else {
+    pb->pcTail->next = pc;
+    pc->prev = pb->pcTail;
+    pc->next = NULL;
+    pc->pb = pb;
+    pb->pcTail = pc;
+  }
 }
 
 /*-----------------------------------------------------------------*/
@@ -1343,10 +1417,12 @@ static void unlinkPC(pCode *pc)
 }
 static void genericDestruct(pCode *pc)
 {
+  fprintf(stderr,"warning, calling default pCode destructor\n");
+
   unlinkPC(pc);
 
-  fprintf(stderr,"warning, calling default pCode destructor\n");
   free(pc);
+
 }
 
 
@@ -1357,7 +1433,6 @@ void pBlockRegs(FILE *of, pBlock *pb)
 
   r = setFirstItem(pb->registers);
   while (r) {
-    fprintf(of,"   %s\n",r->name);
     r = setNextItem(pb->registers);
   }
 }
@@ -1375,7 +1450,7 @@ static char *get_op( pCodeInstruction *pcc)
     case PO_FSR:
     case PO_GPR_TEMP:
       r = pic14_regWithIdx(PCOR(pcc->pcop)->r->rIdx);
-      fprintf(stderr,"getop: getting %s\nfrom:\n",r->name); //pcc->pcop->name);
+      //fprintf(stderr,"getop: getting %s\nfrom:\n",r->name); //pcc->pcop->name);
       pBlockRegs(stderr,pcc->pc.pb);
       return r->name;
 
@@ -1397,6 +1472,70 @@ static void pCodeOpPrint(FILE *of, pCodeOp *pcop)
   fprintf(of,"pcodeopprint\n");
 }
 
+char *pCode2str(char *str, int size, pCode *pc)
+{
+  char *s = str;
+
+  switch(pc->type) {
+
+  case PC_OPCODE:
+
+    SAFE_snprintf(&s,&size, "\t%s\t", PCI(pc)->mnemonic);
+
+    if( (PCI(pc)->num_ops >= 1) && (PCI(pc)->pcop)) {
+
+      if(PCI(pc)->bit_inst) {
+       if(PCI(pc)->pcop->type == PO_BIT) {
+         if( (((pCodeOpBit *)(PCI(pc)->pcop))->inBitSpace) )
+           SAFE_snprintf(&s,&size,"(%s >> 3), (%s & 7)", 
+                         PCI(pc)->pcop->name ,
+                         PCI(pc)->pcop->name );
+         else
+           SAFE_snprintf(&s,&size,"%s,%d", get_op(PCI(pc)), 
+                         (((pCodeOpBit *)(PCI(pc)->pcop))->bit ));
+       } else
+         SAFE_snprintf(&s,&size,"%s,0 ; ?bug", get_op(PCI(pc)));
+       //PCI(pc)->pcop->t.bit );
+      } else {
+
+       if(PCI(pc)->pcop->type == PO_BIT) {
+         if( PCI(pc)->num_ops == 2)
+           SAFE_snprintf(&s,&size,"(%s >> 3),%c",get_op(PCI(pc)),((PCI(pc)->dest) ? 'F':'W'));
+         else
+           SAFE_snprintf(&s,&size,"(1 << (%s & 7))",get_op(PCI(pc)));
+
+       }else {
+         SAFE_snprintf(&s,&size,"%s",get_op(PCI(pc)));
+
+         if( PCI(pc)->num_ops == 2)
+           SAFE_snprintf(&s,&size,",%c", ( (PCI(pc)->dest) ? 'F':'W'));
+       }
+      }
+
+    }
+    break;
+
+  case PC_COMMENT:
+    /* assuming that comment ends with a \n */
+    SAFE_snprintf(&s,&size,";%s", ((pCodeComment *)pc)->comment);
+    break;
+
+  case PC_LABEL:
+    SAFE_snprintf(&s,&size,";label=%s, key=%d\n",PCL(pc)->label,PCL(pc)->key);
+    break;
+  case PC_FUNCTION:
+    SAFE_snprintf(&s,&size,";modname=%s,function=%s: id=%d\n",PCF(pc)->modname,PCF(pc)->fname);
+    break;
+  case PC_WILD:
+    SAFE_snprintf(&s,&size,";\tWild opcode: id=%d\n",PCW(pc)->id);
+    break;
+
+  }
+
+  return str;
+
+}
+
 /*-----------------------------------------------------------------*/
 /* genericPrint - the contents of a pCode to a file                */
 /*-----------------------------------------------------------------*/
@@ -1422,41 +1561,13 @@ static void genericPrint(FILE *of, pCode *pc)
       }
     }
 
-    fprintf(of, "\t%s\t", PCI(pc)->mnemonic);
-    if( (PCI(pc)->num_ops >= 1) && (PCI(pc)->pcop)) {
-
-      if(PCI(pc)->bit_inst) {
-       if(PCI(pc)->pcop->type == PO_BIT) {
-         if( (((pCodeOpBit *)(PCI(pc)->pcop))->inBitSpace) )
-           fprintf(of,"(%s >> 3), (%s & 7)", 
-                   PCI(pc)->pcop->name ,
-                   PCI(pc)->pcop->name );
-         else
-           fprintf(of,"%s,%d", get_op(PCI(pc)), (((pCodeOpBit *)(PCI(pc)->pcop))->bit ));
-       } else
-         fprintf(of,"%s,0 ; ?bug", get_op(PCI(pc)));
-       //PCI(pc)->pcop->t.bit );
-      } else {
 
-       if(PCI(pc)->pcop->type == PO_BIT) {
-         if( PCI(pc)->num_ops == 2)
-           fprintf(of,"(%s >> 3),%c",get_op(PCI(pc)),((PCI(pc)->dest) ? 'F':'W'));
-         else
-           fprintf(of,"(1 << (%s & 7))",get_op(PCI(pc)));
-
-/*
-         if( PCI(pc)->num_ops == 2)
-           fprintf(of,"(%s >> 3),%c",PCI(pc)->pcop->name,((PCI(pc)->dest) ? 'F':'W'));
-         else
-           fprintf(of,"(1 << (%s & 7))",PCI(pc)->pcop->name);
-*/
-       }else {
-         fprintf(of,"%s",get_op(PCI(pc)));
+    {
+      char str[256];
+      
+      pCode2str(str, 256, pc);
 
-         if( PCI(pc)->num_ops == 2)
-           fprintf(of,",%c", ( (PCI(pc)->dest) ? 'F':'W'));
-       }
-      }
+      fprintf(of,"%s",str);
     }
 
     {
@@ -1485,6 +1596,9 @@ static void genericPrint(FILE *of, pCode *pc)
 
   case PC_WILD:
     fprintf(of,";\tWild opcode: id=%d\n",PCW(pc)->id);
+    if(pc->label)
+      pCodePrintLabel(of, pc->label->pc);
+
     if(PCW(pc)->operand) {
       fprintf(of,";\toperand  ");
       pCodeOpPrint(of,PCW(pc)->operand );
@@ -1546,7 +1660,7 @@ static void pCodePrintLabel(FILE *of, pCode *pc)
   else if (PCL(pc)->key >=0) 
     fprintf(of,"_%05d_DS_:\n",PCL(pc)->key);
   else
-    fprintf(of,";wild card label\n");
+    fprintf(of,";wild card label: id=%d\n",-PCL(pc)->key);
 
 }
 /*-----------------------------------------------------------------*/
@@ -1729,7 +1843,7 @@ pCode * findNextInstruction(pCode *pc)
 {
 
   while(pc) {
-    if(pc->type == PC_OPCODE)
+    if((pc->type == PC_OPCODE) || (pc->type == PC_WILD))
       return pc;
 
     pc = pc->next;