Added more PIC regression testing.
[fw/sdcc] / src / pic / pcode.c
index 9c3e288bf4fb7641925e932e75b6f052cd681cc0..fc5de12cc524b57ec1f5c9a21e6d39f7dec4db1e 100644 (file)
 pCodeOpReg pc_status    = {{PO_STATUS,  "STATUS"}, -1, NULL,NULL};
 pCodeOpReg pc_indf      = {{PO_INDF,    "INDF"}, -1, NULL,NULL};
 pCodeOpReg pc_fsr       = {{PO_FSR,     "FSR"}, -1, NULL,NULL};
+pCodeOpReg pc_pcl       = {{PO_PCL,     "PCL"}, -1, NULL,NULL};
+pCodeOpReg pc_pclath    = {{PO_PCLATH,  "PCLATH"}, -1, NULL,NULL};
 
 static int mnemonics_initialized = 0;
 
-#if 0
-//static char *PIC_mnemonics[] = {
-static char *scpADDLW = "ADDLW";
-static char *scpADDWF = "ADDWF";
-static char *scpANDLW = "ANDLW";
-static char *scpANDWF = "ANDWF";
-static char *scpBCF = "BCF";
-static char *scpBSF = "BSF";
-static char *scpBTFSC = "BTFSC";
-static char *scpBTFSS = "BTFSS";
-static char *scpCALL = "CALL";
-static char *scpCOMF = "COMF";
-static char *scpCLRF = "CLRF";
-static char *scpCLRW = "CLRW";
-static char *scpDECF = "DECF";
-static char *scpDECFSZ = "DECFSZ";
-static char *scpGOTO = "GOTO";
-static char *scpINCF = "INCF";
-static char *scpINCFSZ = "INCFSZ";
-static char *scpIORLW = "IORLW";
-static char *scpIORWF = "IORWF";
-static char *scpMOVF = "MOVF";
-static char *scpMOVLW = "MOVLW";
-static char *scpMOVWF = "MOVWF";
-static char *scpNEGF = "NEGF";
-static char *scpRETLW = "RETLW";
-static char *scpRETURN = "RETURN";
-static char *scpSUBLW = "SUBLW";
-static char *scpSUBWF = "SUBWF";
-static char *scpTRIS = "TRIS";
-static char *scpXORLW = "XORLW";
-static char *scpXORWF = "XORWF";
-#endif
 
 static hTab *pic14MnemonicsHash = NULL;
 
@@ -257,7 +226,6 @@ pCodeInstruction pciCALL = {
   PCC_NONE  // outCond
 };
 
-//fixme - need a COMFW instruction.
 pCodeInstruction pciCOMF = {
   {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
    genericAnalyze,
@@ -267,9 +235,23 @@ pCodeInstruction pciCOMF = {
   "COMF",
   NULL, // operand
   2,    // num ops
+  1,0,  // dest, bit instruction
+  PCC_REGISTER,  // inCond
+  PCC_REGISTER   // outCond
+};
+
+pCodeInstruction pciCOMFW = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_COMFW,
+  "COMF",
+  NULL, // operand
+  2,    // num ops
   0,0,  // dest, bit instruction
-  PCC_NONE, // inCond
-  PCC_NONE  // outCond
+  PCC_REGISTER,  // inCond
+  PCC_  // outCond
 };
 
 pCodeInstruction pciCLRF = {
@@ -569,6 +551,62 @@ pCodeInstruction pciRETURN = {
 };
 
 
+pCodeInstruction pciRLF = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_RLF,
+  "RLF",
+  NULL, // operand
+  2,    // num ops
+  1,0,  // dest, bit instruction
+  (PCC_C | PCC_REGISTER),   // inCond
+  (PCC_REGISTER | PCC_Z | PCC_C | PCC_DC) // outCond
+};
+
+pCodeInstruction pciRLFW = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_RLFW,
+  "RLF",
+  NULL, // operand
+  2,    // num ops
+  0,0,  // dest, bit instruction
+  (PCC_C | PCC_REGISTER),   // inCond
+  (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond
+};
+
+pCodeInstruction pciRRF = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_RRF,
+  "RRF",
+  NULL, // operand
+  2,    // num ops
+  1,0,  // dest, bit instruction
+  (PCC_C | PCC_REGISTER),   // inCond
+  (PCC_REGISTER | PCC_Z | PCC_C | PCC_DC) // outCond
+};
+
+pCodeInstruction pciRRFW = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_RRFW,
+  "RRF",
+  NULL, // operand
+  2,    // num ops
+  0,0,  // dest, bit instruction
+  (PCC_C | PCC_REGISTER),   // inCond
+  (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond
+};
+
 pCodeInstruction pciSUBWF = {
   {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
    genericAnalyze,
@@ -611,6 +649,33 @@ pCodeInstruction pciSUBLW = {
   (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond
 };
 
+pCodeInstruction pciSWAPF = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_SWAPF,
+  "SWAPF",
+  NULL, // operand
+  2,    // num ops
+  1,0,  // dest, bit instruction
+  (PCC_REGISTER),   // inCond
+  (PCC_REGISTER) // outCond
+};
+
+pCodeInstruction pciSWAPFW = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_SWAPFW,
+  "SWAPF",
+  NULL, // operand
+  2,    // num ops
+  0,0,  // dest, bit instruction
+  (PCC_REGISTER),   // inCond
+  (PCC_W) // outCond
+};
 pCodeInstruction pciTRIS = {
   {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
    genericAnalyze,
@@ -672,21 +737,36 @@ pCodeInstruction pciXORLW = {
 #define MAX_PIC14MNEMONICS 100
 pCodeInstruction *pic14Mnemonics[MAX_PIC14MNEMONICS];
 
-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, ...)
 {
-  char *copy;
-
-  if(!str)
-    return NULL;
+  va_list val;
+  int len;
 
-  copy = strdup(str);
-  if(!copy) {
-    fprintf(stderr, "out of memory %s,%d\n",__FUNCTION__,__LINE__);
-    exit(1);
-  }
+  if(!str || !*str)
+    return;
 
-  return copy;
+  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)
@@ -742,6 +822,7 @@ void pic14initMnemonics(void)
   pic14Mnemonics[POC_BTFSS] = &pciBTFSS;
   pic14Mnemonics[POC_CALL] = &pciCALL;
   pic14Mnemonics[POC_COMF] = &pciCOMF;
+  pic14Mnemonics[POC_COMFW] = &pciCOMFW;
   pic14Mnemonics[POC_CLRF] = &pciCLRF;
   pic14Mnemonics[POC_CLRW] = &pciCLRW;
   pic14Mnemonics[POC_DECF] = &pciDECF;
@@ -763,9 +844,15 @@ void pic14initMnemonics(void)
   pic14Mnemonics[POC_NEGF] = &pciNEGF;
   pic14Mnemonics[POC_RETLW] = &pciRETLW;
   pic14Mnemonics[POC_RETURN] = &pciRETURN;
+  pic14Mnemonics[POC_RLF] = &pciRLF;
+  pic14Mnemonics[POC_RLFW] = &pciRLFW;
+  pic14Mnemonics[POC_RRF] = &pciRRF;
+  pic14Mnemonics[POC_RRFW] = &pciRRFW;
   pic14Mnemonics[POC_SUBLW] = &pciSUBLW;
   pic14Mnemonics[POC_SUBWF] = &pciSUBWF;
   pic14Mnemonics[POC_SUBFW] = &pciSUBFW;
+  pic14Mnemonics[POC_SWAPF] = &pciSWAPF;
+  pic14Mnemonics[POC_SWAPFW] = &pciSWAPFW;
   pic14Mnemonics[POC_TRIS] = &pciTRIS;
   pic14Mnemonics[POC_XORLW] = &pciXORLW;
   pic14Mnemonics[POC_XORWF] = &pciXORWF;
@@ -784,7 +871,7 @@ void pic14initMnemonics(void)
   mnemonics_initialized = 1;
 }
 
-int getpCode(char *mnem,int dest)
+int getpCode(char *mnem,unsigned dest)
 {
 
   pCodeInstruction *pci;
@@ -1043,7 +1130,10 @@ pCode *newpCodeCharP(char *cP)
   pcc->pc.destruct = genericDestruct;
   pcc->pc.print = genericPrint;
 
-  pcc->comment = Safe_strdup(cP);
+  if(cP)
+    pcc->comment = Safe_strdup(cP);
+  else
+    pcc->comment = NULL;
 
   return ( (pCode *)pcc);
 
@@ -1093,7 +1183,7 @@ static void pCodeLabelDestruct(pCode *pc)
 
   unlinkPC(pc);
 
-  if(PCL(pc)->label)
+  if((pc->type == PC_LABEL) && PCL(pc)->label)
     free(PCL(pc)->label);
 
   free(pc);
@@ -1119,11 +1209,13 @@ pCode *newpCodeLabel(int key)
 
   pcl->key = key;
 
+  pcl->label = NULL;
   if(key>0) {
     sprintf(s,"_%05d_DS_",key);
-    pcl->label = Safe_strdup(s);
-  } else
-    pcl->label = NULL;
+    if(s)
+      pcl->label = Safe_strdup(s);
+  }
+
 
   return ( (pCode *)pcl);
 
@@ -1132,7 +1224,10 @@ pCode *newpCodeLabelStr(char *str)
 {
   pCode *pc = newpCodeLabel(-1);
 
-  PCL(pc)->label = Safe_strdup(str);
+  if(str)
+    PCL(pc)->label = Safe_strdup(str);
+  else
+    PCL(pc)->label = NULL;
 
   return pc;
 }
@@ -1157,7 +1252,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
@@ -1192,11 +1287,13 @@ pCodeOp *newpCodeOpLabel(int key)
   pcop = Safe_calloc(1,sizeof(pCodeOpLabel) );
   pcop->type = PO_LABEL;
 
+  pcop->name = NULL;
   if(key>0) {
     sprintf(s,"_%05d_DS_",key);
-    pcop->name = Safe_strdup(s);
-  } else
-    pcop->name = NULL;
+    if(s)
+      pcop->name = Safe_strdup(s);
+  } 
+
 
   ((pCodeOpLabel *)pcop)->key = key;
 
@@ -1211,11 +1308,13 @@ pCodeOp *newpCodeOpLit(int lit)
 
   pcop = Safe_calloc(1,sizeof(pCodeOpLit) );
   pcop->type = PO_LITERAL;
+  pcop->name = NULL;
   if(lit>=0) {
     sprintf(s,"0x%02x",lit);
-    pcop->name = Safe_strdup(s);
-  } else
-    pcop->name = NULL;
+    if(s)
+      pcop->name = Safe_strdup(s);
+  } 
+
 
   ((pCodeOpLit *)pcop)->lit = lit;
 
@@ -1246,19 +1345,32 @@ pCodeOp *newpCodeOpWild(int id, pCodePeep *pcp, pCodeOp *subtype)
   return pcop;
 }
 
-pCodeOp *newpCodeOpBit(char *s, int bit)
+pCodeOp *newpCodeOpBit(char *s, int bit, int inBitSpace)
 {
   pCodeOp *pcop;
 
   pcop = Safe_calloc(1,sizeof(pCodeOpBit) );
   pcop->type = PO_BIT;
-  pcop->name = Safe_strdup(s);   
+  if(s)
+    pcop->name = Safe_strdup(s);   
+  else
+    pcop->name = NULL;
 
   PCOB(pcop)->bit = bit;
-  if(bit>=0)
-    PCOB(pcop)->inBitSpace = 1;
-  else
-    PCOB(pcop)->inBitSpace = 0;
+  PCOB(pcop)->inBitSpace = inBitSpace;
+
+  return pcop;
+}
+
+pCodeOp *newpCodeOpReg(int rIdx)
+{
+  pCodeOp *pcop;
+
+  pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
+
+  PCOR(pcop)->rIdx = rIdx;
+  PCOR(pcop)->r = pic14_regWithIdx(rIdx);
+  pcop->type = PCOR(pcop)->r->pc_type;
 
   return pcop;
 }
@@ -1272,7 +1384,7 @@ pCodeOp *newpCodeOp(char *name, PIC_OPTYPE type)
 
   switch(type) {
   case PO_BIT:
-    pcop = newpCodeOpBit(name, -1);
+    pcop = newpCodeOpBit(name, -1,0);
     break;
 
   case PO_LITERAL:
@@ -1286,7 +1398,10 @@ pCodeOp *newpCodeOp(char *name, PIC_OPTYPE type)
   default:
     pcop = Safe_calloc(1,sizeof(pCodeOp) );
     pcop->type = type;
-    pcop->name = Safe_strdup(name);   
+    if(name)
+      pcop->name = Safe_strdup(name);   
+    else
+      pcop->name = NULL;
   }
 
   return pcop;
@@ -1297,12 +1412,18 @@ pCodeOp *newpCodeOp(char *name, PIC_OPTYPE type)
 /*-----------------------------------------------------------------*/
 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;
+  }
 }
 
 /*-----------------------------------------------------------------*/
@@ -1370,10 +1491,16 @@ void printpBlock(FILE *of, pBlock *pb)
 
 static void unlinkPC(pCode *pc)
 {
-  if(pc  && pc->prev && pc->next) {
 
-    pc->prev->next = pc->next;
-    pc->next->prev = pc->prev;
+
+  if(pc) {
+
+    if(pc->prev) 
+      pc->prev->next = pc->next;
+    if(pc->next)
+      pc->next->prev = pc->prev;
+
+    pc->prev = pc->next = NULL;
   }
 }
 static void genericDestruct(pCode *pc)
@@ -1394,7 +1521,6 @@ void pBlockRegs(FILE *of, pBlock *pb)
 
   r = setFirstItem(pb->registers);
   while (r) {
-    fprintf(of,"   %s\n",r->name);
     r = setNextItem(pb->registers);
   }
 }
@@ -1411,8 +1537,9 @@ static char *get_op( pCodeInstruction *pcc)
 
     case PO_FSR:
     case PO_GPR_TEMP:
+    case PO_GPR_BIT:
       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;
 
@@ -1434,6 +1561,72 @@ 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 if(PCI(pc)->pcop->type == PO_GPR_BIT) {
+         SAFE_snprintf(&s,&size,"%s,%d", get_op(PCI(pc)),PCORB(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                */
 /*-----------------------------------------------------------------*/
@@ -1459,41 +1652,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);
     }
 
     {
@@ -1522,6 +1687,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 );
@@ -1583,10 +1751,26 @@ 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);
 
 }
 /*-----------------------------------------------------------------*/
+static void  unlinkpCodeFromBranch(pBranch *pb , pCode *pc)
+{
+  pBranch *b, *bprev;
+
+  bprev = NULL;
+  b = pb;
+  while(b) {
+    if(b->pc == pc) {
+      if(bprev)
+       bprev->next = b->next;
+    }
+    bprev = b;
+    b = b->next;
+  }
+
+}
 
 static pBranch * pBranchAppend(pBranch *h, pBranch *n)
 {
@@ -1722,6 +1906,29 @@ static void genericAnalyze(pCode *pc)
   }
 }
 
+/*-----------------------------------------------------------------*/
+int compareLabel(pCode *pc, pCodeOpLabel *pcop_label)
+{
+  pBranch *pbr;
+
+  if(pc->type == PC_LABEL) {
+    if( ((pCodeLabel *)pc)->key ==  pcop_label->key)
+      return TRUE;
+  }
+  if(pc->type == PC_OPCODE) {
+    pbr = pc->label;
+    while(pbr) {
+      if(pbr->pc->type == PC_LABEL) {
+       if( ((pCodeLabel *)(pbr->pc))->key ==  pcop_label->key)
+         return TRUE;
+      }
+      pbr = pbr->next;
+    }
+  }
+
+  return FALSE;
+}
+
 /*-----------------------------------------------------------------*/
 /* findLabel - Search the pCode for a particular label             */
 /*-----------------------------------------------------------------*/
@@ -1729,29 +1936,15 @@ pCode * findLabel(pCodeOpLabel *pcop_label)
 {
   pBlock *pb;
   pCode  *pc;
-  pBranch *pbr;
 
   if(!the_pFile)
     return NULL;
 
   for(pb = the_pFile->pbHead; pb; pb = pb->next) {
-    for(pc = pb->pcHead; pc; pc = pc->next) {
-      if(pc->type == PC_LABEL) {
-       if( ((pCodeLabel *)pc)->key ==  pcop_label->key)
-         return pc;
-      }
-      if(pc->type == PC_OPCODE) {
-       pbr = pc->label;
-       while(pbr) {
-         if(pbr->pc->type == PC_LABEL) {
-           if( ((pCodeLabel *)(pbr->pc))->key ==  pcop_label->key)
-             return pc;
-         }
-         pbr = pbr->next;
-       }
-      }
-
-    }
+    for(pc = pb->pcHead; pc; pc = pc->next) 
+      if(compareLabel(pc,pcop_label))
+       return pc;
+    
   }
 
   fprintf(stderr,"Couldn't find label %s", pcop_label->pcop.name);
@@ -1766,7 +1959,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;
@@ -1877,14 +2070,79 @@ int OptimizepBlock(pBlock *pb)
   if(!pb || !peepOptimizing)
     return 0;
 
-  fprintf(stderr," Optimizing pBlock\n");
-
+  fprintf(stderr," Optimizing pBlock: %c\n",getpBlock_dbName(pb));
   for(pc = pb->pcHead; pc; pc = pc->next)
     matches += pCodePeepMatchRule(pc);
 
   return matches;
 
 }
+
+/*-----------------------------------------------------------------*/
+/* pBlockRemoveUnusedLabels - remove the pCode labels from the     */
+/*-----------------------------------------------------------------*/
+pCode * findInstructionUsingLabel(pCodeLabel *pcl, pCode *pcs)
+{
+  pCode *pc;
+
+  for(pc = pcs; pc; pc = pc->next) {
+
+    if((pc->type == PC_OPCODE) && 
+       (PCI(pc)->pcop) && 
+       (PCI(pc)->pcop->type == PO_LABEL) &&
+       (PCOLAB(PCI(pc)->pcop)->key == pcl->key))
+      return pc;
+  }
+
+  return NULL;
+}
+
+/*-----------------------------------------------------------------*/
+/* pBlockRemoveUnusedLabels - remove the pCode labels from the     */
+/*                            pCode chain if they're not used.     */
+/*-----------------------------------------------------------------*/
+void pBlockRemoveUnusedLabels(pBlock *pb)
+{
+  pCode *pc; pCodeLabel *pcl;
+
+  if(!pb)
+    return;
+
+  for(pc = pb->pcHead; pc; pc = pc->next) {
+
+    if(pc->type == PC_LABEL)
+      pcl = PCL(pc);
+    else if (pc->label)
+      pcl = PCL(pc->label->pc);
+    else continue;
+
+      /* This pCode is a label, so search the pBlock to see if anyone
+       * refers to it */
+
+    if( (pcl->key>0) && (!findInstructionUsingLabel(pcl, pb->pcHead))) {
+      /* Couldn't find an instruction that refers to this label
+       * So, unlink the pCode label from it's pCode chain
+       * and destroy the label */
+
+      fprintf(stderr," !!! REMOVED A LABEL !!! key = %d\n", pcl->key);
+
+      if(pc->type == PC_LABEL) {
+       //unlinkPC(pc);
+       pCodeLabelDestruct(pc);
+      } else {
+       unlinkpCodeFromBranch(pc->label, pc);
+       if(pc->label->next == NULL && pc->label->pc == NULL) {
+         free(pc->label);
+       }
+      }
+
+    }
+  }
+
+}
+
+
 /*-----------------------------------------------------------------*/
 /* pBlockMergeLabels - remove the pCode labels from the pCode      */
 /*                     chain and put them into pBranches that are  */
@@ -1899,18 +2157,22 @@ void pBlockMergeLabels(pBlock *pb)
   if(!pb)
     return;
 
+  /* First, Try to remove any unused labels */
+  //pBlockRemoveUnusedLabels(pb);
+
+  /* Now loop through the pBlock and merge the labels with the opcodes */
+
   for(pc = pb->pcHead; pc; pc = pc->next) {
 
     if(pc->type == PC_LABEL) {
+      fprintf(stderr,"Checking label key = %d\n",PCL(pc)->key);
       if( !(pcnext = findNextInstruction(pc)) ) 
        return;  // Couldn't find an instruction associated with this label
 
       // Unlink the pCode label from it's pCode chain
-      if(pc->prev) 
-       pc->prev->next = pc->next;
-      if(pc->next)
-       pc->next->prev = pc->prev;
+      unlinkPC(pc);
 
+      fprintf(stderr,"Merged label key = %d\n",PCL(pc)->key);
       // And link it into the instruction's pBranch labels. (Note, since
       // it's possible to have multiple labels associated with one instruction
       // we must provide a means to accomodate the additional labels. Thus
@@ -1922,9 +2184,14 @@ void pBlockMergeLabels(pBlock *pb)
       pbr->next = NULL;
 
       pcnext->label = pBranchAppend(pcnext->label,pbr);
+      if(pcnext->prev) 
+       pc = pcnext->prev;
+      else
+       pc = pcnext;
     }
 
   }
+  pBlockRemoveUnusedLabels(pb);
 
 }
 
@@ -1975,6 +2242,8 @@ void AnalyzepCode(char dbName)
   /* First, merge the labels with the instructions */
   for(pb = the_pFile->pbHead; pb; pb = pb->next) {
     if('*' == dbName || getpBlock_dbName(pb) == dbName) {
+
+      fprintf(stderr," analyze and merging block %c\n",dbName);
       pBlockMergeLabels(pb);
       AnalyzepBlock(pb);
     }
@@ -2226,7 +2495,10 @@ set *register_usage(pBlock *pb)
                  r1->rIdx, newreg->rIdx);
          r2->rIdx = newreg->rIdx;
          //if(r2->name) free(r2->name);
-         r2->name = Safe_strdup(newreg->name);
+         if(newreg->name)
+           r2->name = Safe_strdup(newreg->name);
+         else
+           r2->name = NULL;
          newreg->isFree = 0;
          newreg->wasUsed = 1;
        }
@@ -2342,7 +2614,10 @@ void pct2(FILE *of,pBlock *pb,int indent)
                  r1->rIdx, newreg->rIdx);
          r2->rIdx = newreg->rIdx;
          //if(r2->name) free(r2->name);
-         r2->name = Safe_strdup(newreg->name);
+         if(newreg->name)
+           r2->name = Safe_strdup(newreg->name);
+         else
+           r2->name = NULL;
          newreg->isFree = 0;
          newreg->wasUsed = 1;
        }