a CPOINTER can be used as a function
[fw/sdcc] / src / pic / pcode.c
index 3b464c3480bd23c63cc35ebec6625fd01501ffb2..95da354efd3198dab43976dc340230b6cd5fe210 100644 (file)
@@ -1,6 +1,6 @@
 /*-------------------------------------------------------------------------
 
-   pcode.h - post code generation
+   pcode.c - post code generation
    Written By -  Scott Dattalo scott@dattalo.com
 
    This program is free software; you can redistribute it and/or modify it
 
 #include "common.h"   // Include everything in the SDCC src directory
 #include "newalloc.h"
-#include "ralloc.h"
+
 
 #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:
-pCodeOp pc_status    = {PO_STATUS,  "STATUS"};
-pCodeOp pc_indf      = {PO_INDF,    "INDF"};
-pCodeOp pc_fsr       = {PO_FSR,     "FSR"};
+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};
+
+static int mnemonics_initialized = 0;
 
+#if 0
 //static char *PIC_mnemonics[] = {
 static char *scpADDLW = "ADDLW";
 static char *scpADDWF = "ADDWF";
@@ -62,35 +72,21 @@ static char *scpSUBWF = "SUBWF";
 static char *scpTRIS = "TRIS";
 static char *scpXORLW = "XORLW";
 static char *scpXORWF = "XORWF";
+#endif
+
+static hTab *pic14MnemonicsHash = NULL;
+
 
 
 static pFile *the_pFile = NULL;
 static int peepOptimizing = 1;
 static int GpCodeSequenceNumber = 1;
 
-/****************************************************************/
-/****************************************************************/
-typedef struct _DLL {
-  struct _DLL *prev;
-  struct _DLL *next;
-  //  void *data;
-} _DLL;
-
-
-typedef struct pCodePeepSnippets
-{
-  _DLL dll;
-  pCodePeep *peep;
-} pCodePeepSnippets;
-
-
-static pCodePeepSnippets  *peepSnippets=NULL;
-
 /****************************************************************/
 /*                      Forward declarations                    */
 /****************************************************************/
 
-static void unlink(pCode *pc);
+static void unlinkPC(pCode *pc);
 static void genericAnalyze(pCode *pc);
 static void AnalyzeGOTO(pCode *pc);
 static void AnalyzeSKIP(pCode *pc);
@@ -107,6 +103,575 @@ int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd);
 int pCodePeepMatchRule(pCode *pc);
 
 
+pCodeInstruction pciADDWF = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_ADDWF,
+  "ADDWF",
+  NULL, // operand
+  2,    // num ops
+  1,0,  // dest, bit instruction
+  (PCC_W | PCC_REGISTER),   // inCond
+  (PCC_REGISTER | PCC_Z) // outCond
+};
+
+pCodeInstruction pciADDFW = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_ADDWF,
+  "ADDWF",
+  NULL, // operand
+  2,    // num ops
+  0,0,  // dest, bit instruction
+  (PCC_W | PCC_REGISTER),   // inCond
+  (PCC_W | PCC_Z) // outCond
+};
+
+pCodeInstruction pciADDLW = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_ADDLW,
+  "ADDLW",
+  NULL, // operand
+  1,    // num ops
+  0,0,  // dest, bit instruction
+  PCC_W,   // inCond
+  (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond
+};
+
+pCodeInstruction pciANDLW = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_ANDLW,
+  "ANDLW",
+  NULL, // operand
+  1,    // num ops
+  0,0,  // dest, bit instruction
+  PCC_W,   // inCond
+  (PCC_W | PCC_Z) // outCond
+};
+
+pCodeInstruction pciANDWF = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_ANDWF,
+  "ANDWF",
+  NULL, // operand
+  2,    // num ops
+  1,0,  // dest, bit instruction
+  (PCC_W | PCC_REGISTER),   // inCond
+  (PCC_REGISTER | PCC_Z) // outCond
+};
+
+pCodeInstruction pciANDFW = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_ANDWF,
+  "ANDWF",
+  NULL, // operand
+  2,    // num ops
+  0,0,  // dest, bit instruction
+  (PCC_W | PCC_REGISTER),   // inCond
+  (PCC_W | PCC_Z) // outCond
+};
+
+pCodeInstruction pciBCF = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_BCF,
+  "BCF",
+  NULL, // operand
+  2,    // num ops
+  0,1,  // dest, bit instruction
+  PCC_NONE,   // inCond
+  PCC_EXAMINE_PCOP // outCond
+};
+
+pCodeInstruction pciBSF = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_BSF,
+  "BSF",
+  NULL, // operand
+  2,    // num ops
+  0,1,  // dest, bit instruction
+  PCC_NONE,   // inCond
+  PCC_EXAMINE_PCOP // outCond
+};
+
+pCodeInstruction pciBTFSC = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   AnalyzeSKIP,
+   genericDestruct,
+   genericPrint},
+  POC_BTFSC,
+  "BTFSC",
+  NULL, // operand
+  2,    // num ops
+  0,1,  // dest, bit instruction
+  PCC_EXAMINE_PCOP,   // inCond
+  PCC_NONE // outCond
+};
+
+pCodeInstruction pciBTFSS = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   AnalyzeSKIP,
+   genericDestruct,
+   genericPrint},
+  POC_BTFSS,
+  "BTFSS",
+  NULL, // operand
+  2,    // num ops
+  0,1,  // dest, bit instruction
+  PCC_EXAMINE_PCOP,   // inCond
+  PCC_NONE // outCond
+};
+
+pCodeInstruction pciCALL = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_CALL,
+  "CALL",
+  NULL, // operand
+  1,    // num ops
+  0,0,  // dest, bit instruction
+  PCC_NONE, // inCond
+  PCC_NONE  // outCond
+};
+
+//fixme - need a COMFW instruction.
+pCodeInstruction pciCOMF = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_COMF,
+  "COMF",
+  NULL, // operand
+  2,    // num ops
+  0,0,  // dest, bit instruction
+  PCC_NONE, // inCond
+  PCC_NONE  // outCond
+};
+
+pCodeInstruction pciCLRF = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_CLRF,
+  "CLRF",
+  NULL, // operand
+  1,    // num ops
+  0,0,  // dest, bit instruction
+  PCC_REGISTER, // inCond
+  PCC_REGISTER  // outCond
+};
+
+pCodeInstruction pciCLRW = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_CLRW,
+  "CLRW",
+  NULL, // operand
+  0,    // num ops
+  0,0,  // dest, bit instruction
+  PCC_W, // inCond
+  PCC_W  // outCond
+};
+
+pCodeInstruction pciDECF = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_DECF,
+  "DECF",
+  NULL, // operand
+  2,    // num ops
+  1,0,  // dest, bit instruction
+  PCC_REGISTER,   // inCond
+  PCC_REGISTER    // outCond
+};
+
+pCodeInstruction pciDECFW = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_DECFW,
+  "DECF",
+  NULL, // operand
+  2,    // num ops
+  0,0,  // dest, bit instruction
+  PCC_REGISTER,   // inCond
+  PCC_W    // outCond
+};
+
+pCodeInstruction pciDECFSZ = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   AnalyzeSKIP,
+   genericDestruct,
+   genericPrint},
+  POC_DECFSZ,
+  "DECFSZ",
+  NULL, // operand
+  2,    // num ops
+  1,0,  // dest, bit instruction
+  PCC_REGISTER,   // inCond
+  PCC_REGISTER    // outCond
+};
+
+pCodeInstruction pciDECFSZW = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   AnalyzeSKIP,
+   genericDestruct,
+   genericPrint},
+  POC_DECFSZW,
+  "DECFSZ",
+  NULL, // operand
+  2,    // num ops
+  0,0,  // dest, bit instruction
+  PCC_REGISTER,   // inCond
+  PCC_W           // outCond
+};
+
+pCodeInstruction pciGOTO = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   AnalyzeGOTO,
+   genericDestruct,
+   genericPrint},
+  POC_GOTO,
+  "GOTO",
+  NULL, // operand
+  1,    // num ops
+  0,0,  // dest, bit instruction
+  PCC_NONE,   // inCond
+  PCC_NONE    // outCond
+};
+
+
+pCodeInstruction pciINCF = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_INCF,
+  "INCF",
+  NULL, // operand
+  2,    // num ops
+  1,0,  // dest, bit instruction
+  PCC_REGISTER,   // inCond
+  PCC_REGISTER    // outCond
+};
+
+pCodeInstruction pciINCFW = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_INCFW,
+  "INCF",
+  NULL, // operand
+  2,    // num ops
+  0,0,  // dest, bit instruction
+  PCC_REGISTER,   // inCond
+  PCC_W    // outCond
+};
+
+pCodeInstruction pciINCFSZ = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   AnalyzeSKIP,
+   genericDestruct,
+   genericPrint},
+  POC_INCFSZ,
+  "INCFSZ",
+  NULL, // operand
+  2,    // num ops
+  1,0,  // dest, bit instruction
+  PCC_REGISTER,   // inCond
+  PCC_REGISTER    // outCond
+};
+
+pCodeInstruction pciINCFSZW = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   AnalyzeSKIP,
+   genericDestruct,
+   genericPrint},
+  POC_INCFSZW,
+  "INCFSZ",
+  NULL, // operand
+  2,    // num ops
+  0,0,  // dest, bit instruction
+  PCC_REGISTER,   // inCond
+  PCC_W           // outCond
+};
+
+pCodeInstruction pciIORWF = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_IORWF,
+  "IORWF",
+  NULL, // operand
+  2,    // num ops
+  1,0,  // dest, bit instruction
+  (PCC_W | PCC_REGISTER),   // inCond
+  (PCC_REGISTER | PCC_Z) // outCond
+};
+
+pCodeInstruction pciIORFW = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_IORWF,
+  "IORWF",
+  NULL, // operand
+  2,    // num ops
+  0,0,  // dest, bit instruction
+  (PCC_W | PCC_REGISTER),   // inCond
+  (PCC_W | PCC_Z) // outCond
+};
+
+pCodeInstruction pciIORLW = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_IORLW,
+  "IORLW",
+  NULL, // operand
+  1,    // num ops
+  0,0,  // dest, bit instruction
+  PCC_W,   // inCond
+  (PCC_W | PCC_Z) // outCond
+};
+
+pCodeInstruction pciMOVF = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_MOVF,
+  "MOVF",
+  NULL, // operand
+  2,    // num ops
+  1,0,  // dest, bit instruction
+  PCC_REGISTER,   // inCond
+  PCC_Z // outCond
+};
+
+pCodeInstruction pciMOVFW = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_MOVFW,
+  "MOVF",
+  NULL, // operand
+  2,    // num ops
+  0,0,  // dest, bit instruction
+  PCC_REGISTER,   // inCond
+  (PCC_W | PCC_Z) // outCond
+};
+
+pCodeInstruction pciMOVWF = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_MOVWF,
+  "MOVWF",
+  NULL, // operand
+  1,    // num ops
+  0,0,  // dest, bit instruction
+  PCC_W,   // inCond
+  0 // outCond
+};
+
+pCodeInstruction pciMOVLW = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_MOVLW,
+  "MOVLW",
+  NULL, // operand
+  1,    // num ops
+  0,0,  // dest, bit instruction
+  PCC_NONE,   // inCond
+  PCC_W // outCond
+};
+
+pCodeInstruction pciNEGF = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_NEGF,
+  "NEGF",
+  NULL, // operand
+  1,    // num ops
+  0,0,  // dest, bit instruction
+  PCC_REGISTER,   // inCond
+  PCC_NONE // outCond
+};
+
+
+pCodeInstruction pciRETLW = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   AnalyzeRETURN,
+   genericDestruct,
+   genericPrint},
+  POC_RETLW,
+  "RETLW",
+  NULL, // operand
+  1,    // num ops
+  0,0,  // dest, bit instruction
+  PCC_NONE,   // inCond
+  PCC_W // outCond
+};
+
+pCodeInstruction pciRETURN = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   AnalyzeRETURN,
+   genericDestruct,
+   genericPrint},
+  POC_RETURN,
+  "RETURN",
+  NULL, // operand
+  0,    // num ops
+  0,0,  // dest, bit instruction
+  PCC_NONE,   // inCond
+  PCC_W // outCond
+};
+
+
+pCodeInstruction pciSUBWF = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_SUBWF,
+  "SUBWF",
+  NULL, // operand
+  2,    // num ops
+  1,0,  // dest, bit instruction
+  (PCC_W | PCC_REGISTER),   // inCond
+  (PCC_REGISTER | PCC_Z) // outCond
+};
+
+pCodeInstruction pciSUBFW = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_SUBWF,
+  "SUBWF",
+  NULL, // operand
+  2,    // num ops
+  0,0,  // dest, bit instruction
+  (PCC_W | PCC_REGISTER),   // inCond
+  (PCC_W | PCC_Z) // outCond
+};
+
+pCodeInstruction pciSUBLW = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_SUBLW,
+  "SUBLW",
+  NULL, // operand
+  1,    // num ops
+  0,0,  // dest, bit instruction
+  PCC_W,   // inCond
+  (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond
+};
+
+pCodeInstruction pciTRIS = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_TRIS,
+  "TRIS",
+  NULL, // operand
+  1,    // num ops
+  0,0,  // dest, bit instruction
+  PCC_NONE,   // inCond
+  PCC_NONE
+};
+
+
+pCodeInstruction pciXORWF = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_XORWF,
+  "XORWF",
+  NULL, // operand
+  2,    // num ops
+  1,0,  // dest, bit instruction
+  (PCC_W | PCC_REGISTER),   // inCond
+  (PCC_REGISTER | PCC_Z) // outCond
+};
+
+pCodeInstruction pciXORFW = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_XORWF,
+  "XORWF",
+  NULL, // operand
+  2,    // num ops
+  0,0,  // dest, bit instruction
+  (PCC_W | PCC_REGISTER),   // inCond
+  (PCC_W | PCC_Z) // outCond
+};
+
+pCodeInstruction pciXORLW = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_XORLW,
+  "XORLW",
+  NULL, // operand
+  1,    // num ops
+  0,0,  // dest, bit instruction
+  PCC_W,   // inCond
+  (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond
+};
+
+
+#define MAX_PIC14MNEMONICS 100
+pCodeInstruction *pic14Mnemonics[MAX_PIC14MNEMONICS];
+
 char *Safe_strdup(char *str)
 {
   char *copy;
@@ -124,6 +689,159 @@ 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)
+{
+
+  pc_fsr.rIdx = 4;
+  pc_fsr.r = pic14_regWithIdx(4);
+
+}
+
+/*-----------------------------------------------------------------*/
+/*  mnem2key - convert a pic mnemonic into a hash key              */
+/*   (BTW - this spreads the mnemonics quite well)                 */
+/*                                                                 */
+/*-----------------------------------------------------------------*/
+
+int mnem2key(char const *mnem)
+{
+  int key = 0;
+
+  if(!mnem)
+    return 0;
+
+  while(*mnem) {
+
+    key += toupper(*mnem++) +1;
+
+  }
+
+  return (key & 0x1f);
+
+}
+
+void pic14initMnemonics(void)
+{
+  int i = 0;
+  int key;
+  //  char *str;
+  pCodeInstruction *pci;
+
+  if(mnemonics_initialized)
+    return;
+
+  pic14Mnemonics[POC_ADDLW] = &pciADDLW;
+  pic14Mnemonics[POC_ADDWF] = &pciADDWF;
+  pic14Mnemonics[POC_ADDFW] = &pciADDFW;
+  pic14Mnemonics[POC_ANDLW] = &pciANDLW;
+  pic14Mnemonics[POC_ANDWF] = &pciANDWF;
+  pic14Mnemonics[POC_ANDFW] = &pciANDFW;
+  pic14Mnemonics[POC_BCF] = &pciBCF;
+  pic14Mnemonics[POC_BSF] = &pciBSF;
+  pic14Mnemonics[POC_BTFSC] = &pciBTFSC;
+  pic14Mnemonics[POC_BTFSS] = &pciBTFSS;
+  pic14Mnemonics[POC_CALL] = &pciCALL;
+  pic14Mnemonics[POC_COMF] = &pciCOMF;
+  pic14Mnemonics[POC_CLRF] = &pciCLRF;
+  pic14Mnemonics[POC_CLRW] = &pciCLRW;
+  pic14Mnemonics[POC_DECF] = &pciDECF;
+  pic14Mnemonics[POC_DECFW] = &pciDECFW;
+  pic14Mnemonics[POC_DECFSZ] = &pciDECFSZ;
+  pic14Mnemonics[POC_DECFSZW] = &pciDECFSZW;
+  pic14Mnemonics[POC_GOTO] = &pciGOTO;
+  pic14Mnemonics[POC_INCF] = &pciINCF;
+  pic14Mnemonics[POC_INCFW] = &pciINCFW;
+  pic14Mnemonics[POC_INCFSZ] = &pciINCFSZ;
+  pic14Mnemonics[POC_INCFSZW] = &pciINCFSZW;
+  pic14Mnemonics[POC_IORLW] = &pciIORLW;
+  pic14Mnemonics[POC_IORWF] = &pciIORWF;
+  pic14Mnemonics[POC_IORFW] = &pciIORFW;
+  pic14Mnemonics[POC_MOVF] = &pciMOVF;
+  pic14Mnemonics[POC_MOVFW] = &pciMOVFW;
+  pic14Mnemonics[POC_MOVLW] = &pciMOVLW;
+  pic14Mnemonics[POC_MOVWF] = &pciMOVWF;
+  pic14Mnemonics[POC_NEGF] = &pciNEGF;
+  pic14Mnemonics[POC_RETLW] = &pciRETLW;
+  pic14Mnemonics[POC_RETURN] = &pciRETURN;
+  pic14Mnemonics[POC_SUBLW] = &pciSUBLW;
+  pic14Mnemonics[POC_SUBWF] = &pciSUBWF;
+  pic14Mnemonics[POC_SUBFW] = &pciSUBFW;
+  pic14Mnemonics[POC_TRIS] = &pciTRIS;
+  pic14Mnemonics[POC_XORLW] = &pciXORLW;
+  pic14Mnemonics[POC_XORWF] = &pciXORWF;
+  pic14Mnemonics[POC_XORFW] = &pciXORFW;
+
+  for(i=0; i<MAX_PIC14MNEMONICS; i++)
+    if(pic14Mnemonics[i])
+      hTabAddItem(&pic14MnemonicsHash, mnem2key(pic14Mnemonics[i]->mnemonic), pic14Mnemonics[i]);
+  pci = hTabFirstItem(pic14MnemonicsHash, &key);
+
+  while(pci) {
+    fprintf( stderr, "element %d key %d, mnem %s\n",i++,key,pci->mnemonic);
+    pci = hTabNextItem(pic14MnemonicsHash, &key);
+  }
+
+  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)
 {
   if(!pb)
@@ -196,6 +914,8 @@ void pcode_test(void)
 
   printf("pcode is alive!\n");
 
+  //initMnemonics();
+
   if(the_pFile) {
 
     pBlock *pb;
@@ -225,6 +945,26 @@ void pcode_test(void)
     }
   }
 }
+static int RegCond(pCodeOp *pcop)
+{
+
+  if(!pcop)
+    return 0;
+
+  if(pcop->type == PO_BIT  && !strcmp(pcop->name, pc_status.pcop.name)) {
+    switch(PCOB(pcop)->bit) {
+    case PIC_C_BIT:
+      return PCC_C;
+    case PIC_DC_BIT:
+       return PCC_DC;
+    case PIC_Z_BIT:
+      return PCC_Z;
+    }
+
+  }
+
+  return 0;
+}
 
 /*-----------------------------------------------------------------*/
 /* newpCode - create and return a newly initialized pCode          */
@@ -250,194 +990,29 @@ void pcode_test(void)
 pCode *newpCode (PIC_OPCODE op, pCodeOp *pcop)
 {
   pCodeInstruction *pci ;
-    
 
+  if(!mnemonics_initialized)
+    pic14initMnemonics();
+    
   pci = Safe_calloc(1, sizeof(pCodeInstruction));
 
-  pci->pc.analyze  = genericAnalyze;       // pointers to the generic functions, it
-  pci->pc.destruct = genericDestruct;      // doesn't hurt to think about C++ virtual
-  pci->pc.print    = genericPrint;         // functions here.
-  pci->pc.type = PC_OPCODE;                // 
-  pci->op = op;                            // the "opcode" for the instruction.
-  pci->pc.prev = pci->pc.next = NULL;      // The pCode gets linked in later
-  pci->pcop = pcop;                        // The operand of the instruction
-  pci->dest = 0;                           // e.g. W or F 
-  pci->bit_inst = 0;                       // e.g. btfxx instructions
-  pci->num_ops = 2;                        // Most instructions have two ops...
-  pci->inCond = pci->outCond = PCC_NONE;   /* input/output conditions. This is used during
-                                           * optimization to ascertain instruction dependencies.
-                                           * For example, if an instruction affects the Z bit,
-                                           * then the output condition for this instruction
-                                           * is "z bit is affected". The "conditions" are bit
-                                           * constants defined in pcode.h. */
-  pci->pc.from = pci->pc.to = NULL;        // Flow linkages are defined later
-  pci->pc.label = NULL;                    // Labels get merged into instructions here.
-  pci->pc.pb = NULL;                       // The pBlock to which this instruction belongs
-
-  if(pcop && pcop->name)
-    printf("newpCode  operand name %s\n",pcop->name);
-
-  // The most pic dependent portion of the pCode logic:
-  switch(op) { 
-
-  case POC_ANDLW:
-    pci->inCond   = PCC_W;
-    pci->outCond  = PCC_W | PCC_Z;
-    pci->mnemonic = scpANDLW;
-    pci->num_ops  = 1;
-    break;
-  case POC_ANDWF:
-    pci->dest = 1;
-    pci->inCond   = PCC_W | PCC_REGISTER;
-    pci->outCond  = PCC_REGISTER | PCC_Z;
-    pci->mnemonic = scpANDWF;
-    break;
-  case POC_ANDFW:
-    pci->inCond   = PCC_W | PCC_REGISTER;
-    pci->outCond  = PCC_W | PCC_Z;
-    pci->mnemonic = scpANDWF;
-    break;
+  if((op>=0) && (op < MAX_PIC14MNEMONICS) && pic14Mnemonics[op]) {
+    memcpy(pci, pic14Mnemonics[op], sizeof(pCodeInstruction));
+    pci->pcop = pcop;
 
-  case POC_ADDLW:
-    pci->inCond   = PCC_W;
-    pci->outCond  = PCC_W | PCC_Z | PCC_C | PCC_DC;
-    pci->mnemonic = scpADDLW;
-    pci->num_ops = 1;
-    break;
-  case POC_ADDWF:
-    pci->dest     = 1;
-    pci->inCond   = PCC_W | PCC_REGISTER;
-    pci->outCond  = PCC_REGISTER | PCC_Z | PCC_C | PCC_DC;
-    pci->mnemonic = scpADDWF;
-    break;
-  case POC_ADDFW:
-    pci->inCond   = PCC_W | PCC_REGISTER;
-    pci->outCond  = PCC_W | PCC_Z | PCC_C | PCC_DC;
-    pci->mnemonic = scpADDWF;
-    break;
+    if(pci->inCond == PCC_EXAMINE_PCOP)
+      pci->inCond   = RegCond(pcop);
 
-  case POC_BCF:
-    pci->bit_inst = 1;
-    pci->mnemonic = scpBCF;
-    break;
-  case POC_BSF:
-    pci->bit_inst = 1;
-    pci->mnemonic = scpBSF;
-    break;
-  case POC_BTFSC:
-    pci->bit_inst = 1;
-    pci->mnemonic = scpBTFSC;
-    pci->pc.analyze = AnalyzeSKIP;
-    break;
-  case POC_BTFSS:
-    pci->bit_inst = 1;
-    pci->mnemonic = scpBTFSS;
-    pci->pc.analyze = AnalyzeSKIP;
-    break;
-  case POC_CALL:
-    pci->num_ops = 1;
-    pci->mnemonic = scpCALL;
-    break;
-  case POC_COMF:
-    pci->mnemonic = scpCOMF;
-    break;
-  case POC_CLRF:
-    pci->num_ops = 1;
-    pci->mnemonic = scpCLRF;
-    break;
-  case POC_CLRW:
-    pci->num_ops = 0;
-    pci->mnemonic = scpCLRW;
-    break;
-  case POC_DECF:
-    pci->dest = 1;
-  case POC_DECFW:
-    pci->mnemonic = scpDECF;
-    break;
-  case POC_DECFSZ:
-    pci->dest = 1;
-  case POC_DECFSZW:
-    pci->mnemonic = scpDECFSZ;
-    pci->pc.analyze = AnalyzeSKIP;
-    break;
-  case POC_GOTO:
-    pci->num_ops = 1;
-    pci->mnemonic = scpGOTO;
-    pci->pc.analyze = AnalyzeGOTO;
-    break;
-  case POC_INCF:
-    pci->dest = 1;
-  case POC_INCFW:
-    pci->mnemonic = scpINCF;
-    break;
-  case POC_INCFSZ:
-    pci->dest = 1;
-  case POC_INCFSZW:
-    pci->mnemonic = scpINCFSZ;
-    pci->pc.analyze = AnalyzeSKIP;
-    break;
-  case POC_IORLW:
-    pci->num_ops = 1;
-    pci->mnemonic = scpIORLW;
-    break;
-  case POC_IORWF:
-    pci->dest = 1;
-  case POC_IORFW:
-    pci->mnemonic = scpIORWF;
-    break;
-  case POC_MOVF:
-    pci->dest = 1;
-  case POC_MOVFW:
-    pci->mnemonic = scpMOVF;
-    break;
-  case POC_MOVLW:
-    pci->num_ops = 1;
-    pci->mnemonic = scpMOVLW;
-    break;
-  case POC_MOVWF:
-    pci->num_ops = 1;
-    pci->mnemonic = scpMOVWF;
-    break;
-  case POC_NEGF:
-    pci->mnemonic = scpNEGF;
-    break;
-  case POC_RETLW:
-    pci->num_ops = 1;
-    pci->mnemonic = scpRETLW;
-    pci->pc.analyze = AnalyzeRETURN;
-    break;
-  case POC_RETURN:
-    pci->num_ops = 0;
-    pci->mnemonic = scpRETURN;
-    pci->pc.analyze = AnalyzeRETURN;
-    break;
-  case POC_SUBLW:
-    pci->mnemonic = scpSUBLW;
-    pci->num_ops = 1;
-    break;
-  case POC_SUBWF:
-    pci->dest = 1;
-  case POC_SUBFW:
-    pci->mnemonic = scpSUBWF;
-    break;
-  case POC_TRIS:
-    pci->mnemonic = scpTRIS;
-    break;
-  case POC_XORLW:
-    pci->num_ops = 1;
-    pci->mnemonic = scpXORLW;
-    break;
-  case POC_XORWF:
-    pci->dest = 1;
-  case POC_XORFW:
-    pci->mnemonic = scpXORWF;
-    break;
+    if(pci->outCond == PCC_EXAMINE_PCOP)
+      pci->outCond   = RegCond(pcop);
 
-  default:
-    pci->pc.print = genericPrint;
+    return (pCode *)pci;
   }
-   
-  return (pCode *)pci;
+
+  fprintf(stderr, "pCode mnemonic error %s,%d\n",__FUNCTION__,__LINE__);
+  exit(1);
+
+  return NULL;
 }      
 
 /*-----------------------------------------------------------------*/
@@ -451,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)
@@ -469,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;
 
@@ -539,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)
 {
@@ -554,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;
@@ -585,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;
@@ -597,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
@@ -617,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 */
@@ -663,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;
@@ -701,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;
@@ -713,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;
+  }
 }
 
 /*-----------------------------------------------------------------*/
@@ -746,15 +1364,6 @@ void addpBlock(pBlock *pb)
   the_pFile->pbTail = pb;
 }
 
-void printpCodeString(FILE *of, pCode *pc, int max)
-{
-  int i=0;
-
-  while(pc && (i++<max)) {
-    pc->print(of,pc);
-    pc = pc->next;
-  }
-}
 /*-----------------------------------------------------------------*/
 /* printpCode - write the contents of a pCode to a file            */
 /*-----------------------------------------------------------------*/
@@ -798,7 +1407,7 @@ void printpBlock(FILE *of, pBlock *pb)
 /*                                                                 */
 /*-----------------------------------------------------------------*/
 
-static void unlink(pCode *pc)
+static void unlinkPC(pCode *pc)
 {
   if(pc  && pc->prev && pc->next) {
 
@@ -808,10 +1417,12 @@ static void unlink(pCode *pc)
 }
 static void genericDestruct(pCode *pc)
 {
-  unlink(pc);
-
   fprintf(stderr,"warning, calling default pCode destructor\n");
+
+  unlinkPC(pc);
+
   free(pc);
+
 }
 
 
@@ -822,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);
   }
 }
@@ -830,25 +1440,27 @@ void pBlockRegs(FILE *of, pBlock *pb)
 
 static char *get_op( pCodeInstruction *pcc)
 {
+  regs *r;
+
   if(pcc && pcc->pcop) {
 
 
+    switch(pcc->pcop->type) {
 
-  if(pcc->pcop->type == PO_GPR_TEMP) {
-    regs *r;
-    r = pic14_regWithIdx(PCOR(pcc->pcop)->r->rIdx);
-    //pcc->pcop->name = Safe_strdup(r->name);
-    //sprintf(buffer, "R0X%x",PCOR(pcc->pcop)->rIdx);
-    //pcc->pcop->name = Safe_strdup(PCOR(pcc->pcop)->r->name);
-    fprintf(stderr,"getop: getting %s\nfrom:\n",r->name); //pcc->pcop->name);
-    pBlockRegs(stderr,pcc->pc.pb);
-    return r->name;
-  }
+    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);
+      pBlockRegs(stderr,pcc->pc.pb);
+      return r->name;
 
-  if  (pcc->pcop->name)
-    return pcc->pcop->name;
+    default:
+      if  (pcc->pcop->name)
+       return pcc->pcop->name;
 
+    }
   }
+
   return "NO operand";
 }
 
@@ -860,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                */
 /*-----------------------------------------------------------------*/
@@ -885,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);
     }
 
     {
@@ -948,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 );
@@ -1009,46 +1660,9 @@ 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);
 
 }
-
-/*-----------------------------------------------------------------*/
-/* _DLL * DLL_append                                               */
-/*                                                                 */ 
-/*  Append a _DLL object to the end of a _DLL (doubly linked list) */ 
-/* If The list to which we want to append is non-existant then one */ 
-/* is created. Other wise, the end of the list is sought out and   */ 
-/* a new DLL object is appended to it. In either case, the void    */
-/* *data is added to the newly created DLL object.                 */
-/*-----------------------------------------------------------------*/
-
-static void * DLL_append(_DLL *list, _DLL *next)
-{
-  _DLL *b;
-
-
-  /* If there's no list, then create one: */
-  if(!list) {
-    next->next = next->prev = NULL;
-    return next;
-  }
-
-
-  /* Search for the end of the list. */
-  b = list;
-  while(b->next)
-    b = b->next;
-
-  /* Now append the new DLL object */
-  b->next = next;
-  b->next->prev = b;
-  b = b->next; 
-  b->next = NULL;
-
-  return list;
-  
-}  
 /*-----------------------------------------------------------------*/
 
 static pBranch * pBranchAppend(pBranch *h, pBranch *n)
@@ -1229,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;
@@ -1907,577 +2521,3 @@ void printCallTree(FILE *of)
     fprintf(of,"block dbname: %c\n", getpBlock_dbName(pb));
   }
 }
-/*-----------------------------------------------------------------
-
-  pCode peephole optimization
-
-
-  The pCode "peep hole" optimization is not too unlike the peep hole
-  optimization in SDCCpeeph.c. The major difference is that here we
-  use pCode's whereas there we use ASCII strings. The advantage with
-  pCode's is that we can ascertain flow information in the instructions
-  being optimized.
-
-
-<FIX ME> - elaborate...
-
-  -----------------------------------------------------------------*/
-
-#if 0
-/*-----------------------------------------------------------------*/
-/* pCodePeep */
-/*-----------------------------------------------------------------*/
-int pCodePeepCompare(pCode *pc, pCodePeep *pcp)
-{
-  pCode *pcfrom,*pcto;
-
-  pcfrom = pc;
-  for( pcto=pcp->target; pcto; pcto=pcto->next) {
-
-    pcfrom = findNextInstruction(pcfrom);
-
-    if( pcfrom &&  
-       (PCI(pcfrom)->op == PCI(pcto)->op || 
-        PCI(pcto)->op == POC_WILD))
-      continue;
-    return 0;
-  }
-  return 0;
-}
-
-/*-----------------------------------------------------------------*/
-/* pCodePeep */
-/*-----------------------------------------------------------------*/
-void pCodePeepSearch(pCodePeep *snippet)
-{
-  pBlock *pb;
-  pCode *pc;
-
-  if(!the_pFile)
-    return;
-
-  /* compare the chain to the pCode that we've 
-     got so far. If a match is found, then replace
-     the pCode chain.
-  */
-  for(pb = the_pFile->pbHead; pb; pb = pb->next) {
-    for(pc = pb->pcHead; pc; pc = pc->next) {
-      pCodePeepCompare(pc,snippet);
-    }
-  }
-
-}
-#endif
-
-#if 0
-pBlock *pBlockAppend(pBlock *pb1, pBlock *pb2)
-{
-  pBlock *pb;
-
-  if(!pb1->tail)
-    return pb2;
-
-  pb = pb1->tail;
-
-  pb2->head = pb1;
-  pb2->tail = NULL;
-  pb1->tail = pb2;
-
-}
-
-#endif
-
-void pCodePeepInit(void)
-{
-  pBlock *pb;
-  //  pCode *pc;
-  pCodePeep *pcp;
-  pCodePeepSnippets *pcps;
-
-  /* Declare a peep code snippet */
-  /* <FIXME> do I really need a separate struct just to DLL the snippets? */
-  /* e.g. I could put the DLL into the pCodePeep structure */
-  pcps = Safe_calloc(1,sizeof(pCodePeepSnippets));
-  pcp = pcps->peep  = Safe_calloc(1,sizeof(pCodePeep));
-  peepSnippets = DLL_append((_DLL*)peepSnippets,(_DLL*)pcps);
-
-
-  pb = newpCodeChain(NULL, 'W', newpCode(POC_MOVWF, newpCodeOpWild(0,pcp,newpCodeOp(NULL,PO_GPR_REGISTER))) );
-  addpCode2pBlock( pb,     newpCode(POC_MOVFW, newpCodeOpWild(0,pcp,newpCodeOp(NULL,PO_GPR_REGISTER))) );
-
-  pcp->target = pb;
-
-  pcp->replace = newpCodeChain(NULL, 'W',newpCode(POC_MOVWF, newpCodeOpWild(0,pcp,newpCodeOp(NULL,PO_GPR_REGISTER))) );
-
-  /* Allocate space to store pointers to the wildcard variables */
-  pcp->nvars = 1;
-  pcp->vars  = Safe_calloc(pcp->nvars, sizeof(char *));
-  pcp->nwildpCodes = 0;
-  pcp->wildpCodes  = NULL;
-
-  pcp->postFalseCond = PCC_Z;
-  pcp->postTrueCond  = PCC_NONE;
-
-  fprintf(stderr,"Peep rule\nTarget:\n");
-  printpCodeString(stderr,pcp->target->pcHead, 10);
-  fprintf(stderr,"Replaced with:\n");
-  printpCodeString(stderr,pcp->replace->pcHead, 10);
-
-  /* Now for another peep example */
-  pcps = Safe_calloc(1,sizeof(pCodePeepSnippets));
-  pcp = pcps->peep  = Safe_calloc(1,sizeof(pCodePeep));
-  peepSnippets = DLL_append((_DLL*)peepSnippets,(_DLL*)pcps);
-
-  {
-    pCodeOp *pcl;
-    pCodeOp *pcw;
-    pCodeOp *pcwb;
-
-    pcwb =  newpCodeOpWild(0,pcp,newpCodeOpBit(NULL,-1));
-    pb = newpCodeChain(NULL, 'W',newpCode(POC_BTFSC,pcwb));
-
-    pcl = newpCodeOpLabel(-1);
-    pcw = newpCodeOpWild(1, pcp, pcl);
-    addpCode2pBlock( pb,     newpCode(POC_GOTO,  pcw));
-    addpCode2pBlock( pb,     newpCodeWild(0,NULL,NULL));
-    addpCode2pBlock( pb,     newpCodeWild(1,NULL,pcw));
-
-
-    pcp->target = pb;
-
-    pb = newpCodeChain(NULL, 'W',newpCode(POC_BTFSS, pcwb));
-    addpCode2pBlock( pb,     newpCodeWild(0,NULL,NULL));
-    addpCode2pBlock( pb,     newpCodeWild(1,NULL,pcw));
-
-    pcp->replace = pb;
-
-    /* Allocate space to store pointers to the wildcard variables */
-    pcp->nvars = 2;
-    pcp->vars = Safe_calloc(pcp->nvars, sizeof(char *));
-    pcp->nwildpCodes = 2;
-    pcp->wildpCodes = Safe_calloc(pcp->nwildpCodes, sizeof(pCode *));
-
-    pcp->postFalseCond = PCC_NONE;
-    pcp->postTrueCond  = PCC_NONE;
-  }
-
-
-
-
-
-
-
-
-
-
-  //-------------
-
-  /* Now for another peep example */
-  pcps = Safe_calloc(1,sizeof(pCodePeepSnippets));
-  pcp = pcps->peep  = Safe_calloc(1,sizeof(pCodePeep));
-  peepSnippets = DLL_append((_DLL*)peepSnippets,(_DLL*)pcps);
-
-  {
-    pCodeOp *pcw;
-
-    pcw = newpCodeOpWild(0,pcp,newpCodeOp(NULL,PO_GPR_REGISTER));
-
-    pb = newpCodeChain(NULL, 'W', newpCode(POC_MOVWF, pcw));
-    addpCode2pBlock( pb,     newpCode(POC_MOVWF, pcw));
-
-    pcp->target = pb;
-
-    pb = newpCodeChain(NULL, 'W',newpCode(POC_MOVWF, pcw));
-
-    pcp->replace = pb;
-
-    /* Allocate space to store pointers to the wildcard variables */
-    pcp->nvars = 1;
-    pcp->vars = Safe_calloc(pcp->nvars, sizeof(char *));
-    pcp->nwildpCodes = 0;
-    pcp->wildpCodes = NULL;
-
-    pcp->postFalseCond = PCC_NONE;
-    pcp->postTrueCond  = PCC_NONE;
-  }
-
-
-
-
-}
-
-/*-----------------------------------------------------------------*/
-/* pCodeSearchCondition - Search a pCode chain for a 'condition'   */
-/*                                                                 */
-/* return conditions                                               */
-/*  1 - The Condition was found for a pCode's input                */
-/*  0 - No matching condition was found for the whole chain        */
-/* -1 - The Condition was found for a pCode's output               */
-/*                                                                 */
-/*-----------------------------------------------------------------*/
-int pCodeSearchCondition(pCode *pc, unsigned int cond)
-{
-
-  while(pc) {
-
-    /* If we reach a function end (presumably an end since we most
-       probably began the search in the middle of a function), then
-       the condition was not found. */
-    if(pc->type == PC_FUNCTION)
-      return 0;
-
-    if(pc->type == PC_OPCODE) {
-      if(PCI(pc)->inCond & cond)
-       return 1;
-      if(PCI(pc)->outCond & cond)
-       return -1;
-    }
-
-    pc = pc->next;
-  }
-
-  return 0;
-}
-/*-----------------------------------------------------------------*/
-/* pCodePeepMatchLine - Compare source and destination pCodes to   */
-/*                      see they're the same.                      */
-/*-----------------------------------------------------------------*/
-int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd)
-{
-  int index;   // index into wild card arrays
-
-  if(pcs->type == pcd->type) {
-
-    if(pcs->type == PC_OPCODE) {
-
-      /* If the opcodes don't match then the line doesn't match */
-      if(PCI(pcs)->op != PCI(pcd)->op)
-       return 0;
-
-      fprintf(stderr,"%s comparing\n",__FUNCTION__);
-      pcs->print(stderr,pcs);
-      pcd->print(stderr,pcd);
-
-      /* Compare the operands */
-      if(PCI(pcd)->pcop) {
-       if (PCI(pcd)->pcop->type == PO_WILD) {
-         index = PCOW(PCI(pcd)->pcop)->id;
-
-         fprintf(stderr,"destination is wild\n");
-#ifdef DEBUG_PCODEPEEP
-         if (index > peepBlock->nvars) {
-           fprintf(stderr,"%s - variables exceeded\n",__FUNCTION__);
-           exit(1);
-         }
-#endif
-         PCOW(PCI(pcd)->pcop)->matched = PCI(pcs)->pcop;
-         {
-           char *n;
-
-           if(PCI(pcs)->pcop->type == PO_GPR_TEMP)
-             n = PCOR(PCI(pcs)->pcop)->r->name;
-           else
-             n = PCI(pcs)->pcop->name;
-
-           if(peepBlock->vars[index])
-             return  (strcmp(peepBlock->vars[index],n) == 0);
-           else {
-             peepBlock->vars[index] = n; //PCI(pcs)->pcop->name;
-             return 1;
-           }
-         }
-       }
-      } else
-       /* The pcd has no operand. Lines match if pcs has no operand either*/
-       return (PCI(pcs)->pcop == NULL);
-    }
-  }
-
-
-  if((pcd->type == PC_WILD) && (pcs->type == PC_OPCODE)) {
-
-    int labindex;
-
-    index = PCW(pcd)->id;
-
-    fprintf(stderr,"%s comparing wild cards\n",__FUNCTION__);
-    pcs->print(stderr,pcs);
-    pcd->print(stderr,pcd);
-
-    peepBlock->wildpCodes[PCW(pcd)->id] = pcs;
-
-    /* Check for a label associated with this wild pCode */
-    // If the wild card has a label, make sure the source code does too.
-    if(PCW(pcd)->label) {
-      if(!pcs->label)
-       return 0;
-
-      labindex = PCOW(PCW(pcd)->label)->id;
-      if(peepBlock->vars[labindex] == NULL) {
-       // First time to encounter this label
-       peepBlock->vars[labindex] = PCL(pcs->label->pc)->label;
-       fprintf(stderr,"first time for a label\n");
-      } else {
-       if(strcmp(peepBlock->vars[labindex],PCL(pcs->label->pc)->label) != 0) {
-         fprintf(stderr,"labels don't match\n");
-         return 0;
-       }
-       fprintf(stderr,"matched a label\n");
-      }
-
-    }
-
-    if(PCW(pcd)->operand) {
-      PCOW(PCI(pcd)->pcop)->matched = PCI(pcs)->pcop;
-      if(peepBlock->vars[index]) {
-       int i = (strcmp(peepBlock->vars[index],PCI(pcs)->pcop->name) == 0);
-       if(i)
-         fprintf(stderr," (matched)\n");
-       else {
-         fprintf(stderr," (no match: wild card operand mismatch\n");
-         fprintf(stderr,"  peepblock= %s,  pcodeop= %s\n",
-                 peepBlock->vars[index],
-                 PCI(pcs)->pcop->name);
-       }
-       return i;
-      } else {
-       peepBlock->vars[index] = PCI(pcs)->pcop->name;
-       return 1;
-      }
-    }
-
-    pcs = findNextInstruction(pcs->next); 
-    if(pcs) {
-      fprintf(stderr," (next to match)\n");
-      pcs->print(stderr,pcs);
-    }
-
-    return 1; /*  wild card matches */
-  }
-
-  return 0;
-}
-
-/*-----------------------------------------------------------------*/
-/*-----------------------------------------------------------------*/
-void pCodePeepClrVars(pCodePeep *pcp)
-{
-
-  int i;
-
-  for(i=0;i<pcp->nvars; i++)
-    pcp->vars[i] = NULL;
-
-}
-
-/*-----------------------------------------------------------------*/
-/*-----------------------------------------------------------------*/
-void pCodeInsertAfter(pCode *pc1, pCode *pc2)
-{
-
-  if(!pc1 || !pc2)
-    return;
-
-  pc2->next = pc1->next;
-  if(pc1->next)
-    pc1->next->prev = pc2;
-
-  pc2->prev = pc1;
-  pc1->next = pc2;
-
-}
-
-/*-----------------------------------------------------------------*/
-/* pCodeOpCopy - copy a pcode operator                             */
-/*-----------------------------------------------------------------*/
-static pCodeOp *pCodeOpCopy(pCodeOp *pcop)
-{
-  pCodeOp *pcopnew=NULL;
-
-  if(!pcop)
-    return NULL;
-
-  switch(pcop->type) { 
-  case PO_CRY:
-  case PO_BIT:
-    pcopnew = Safe_calloc(1,sizeof(pCodeOpBit) );
-    PCOB(pcopnew)->bit = PCOB(pcop)->bit;
-    PCOB(pcopnew)->inBitSpace = PCOB(pcop)->inBitSpace;
-
-    break;
-
-  case PO_WILD:
-    /* Here we expand the wild card into the appropriate type: */
-    /* By recursively calling pCodeOpCopy */
-    if(PCOW(pcop)->matched)
-      pcopnew = pCodeOpCopy(PCOW(pcop)->matched);
-    else {
-      // Probably a label
-      pcopnew = pCodeOpCopy(PCOW(pcop)->subtype);
-      pcopnew->name = Safe_strdup(PCOW(pcop)->pcp->vars[PCOW(pcop)->id]);
-      fprintf(stderr,"copied a wild op named %s\n",pcopnew->name);
-    }
-
-    return pcopnew;
-    break;
-
-  case PO_LABEL:
-    pcopnew = Safe_calloc(1,sizeof(pCodeOpLabel) );
-    PCOLAB(pcopnew)->key =  PCOLAB(pcop)->key;
-    break;
-
-  case PO_LITERAL:
-  case PO_IMMEDIATE:
-    pcopnew = Safe_calloc(1,sizeof(pCodeOpLit) );
-    PCOL(pcopnew)->lit = PCOL(pcop)->lit;
-    break;
-
-  case PO_GPR_REGISTER:
-  case PO_GPR_TEMP:
-  case PO_SFR_REGISTER:
-  case PO_DIR:
-  case PO_STR:
-  case PO_NONE:
-  case PO_W:
-  case PO_STATUS:
-  case PO_FSR:
-  case PO_INDF:
-
-    pcopnew = Safe_calloc(1,sizeof(pCodeOp) );
-
-  }
-
-  pcopnew->type = pcop->type;
-  pcopnew->name = Safe_strdup(pcop->name);
-
-  return pcopnew;
-}
-
-#if 0
-/*-----------------------------------------------------------------*/
-/* pCodeCopy - copy a pcode                                        */
-/*-----------------------------------------------------------------*/
-static pCode *pCodeCopy(pCode *pc)
-{
-
-  pCode *pcnew;
-
-  pcnew = newpCode(pc->type,pc->pcop);
-}
-#endif
-/*-----------------------------------------------------------------*/
-/*-----------------------------------------------------------------*/
-void pCodeDeleteChain(pCode *f,pCode *t)
-{
-  pCode *pc;
-
-  while(f && f!=t) {
-    fprintf(stderr,"delete pCode:\n");
-    pc = f->next;
-    f->print(stderr,f);
-    //f->delete(f);
-    f = pc;
-  }
-
-}
-/*-----------------------------------------------------------------*/
-/*-----------------------------------------------------------------*/
-int pCodePeepMatchRule(pCode *pc)
-{
-  pCodePeep *peepBlock;
-  pCode *pct, *pcin;
-  _DLL *peeprules;
-  int matched;
-
-  peeprules = (_DLL *)peepSnippets;
-
-  while(peeprules) {
-    peepBlock = ((pCodePeepSnippets*)peeprules)->peep;
-    pCodePeepClrVars(peepBlock);
-
-    pcin = pc;
-    pct = peepBlock->target->pcHead;
-    matched = 0;
-    while(pct && pcin) {
-
-      if(! (matched = pCodePeepMatchLine(peepBlock, pcin,pct)))
-       break;
-
-      pcin = findNextInstruction(pcin->next);
-      pct = pct->next;
-      //debug:
-      fprintf(stderr,"    matched\n");
-      if(!pcin)
-       fprintf(stderr," end of code\n");
-      if(!pct)
-       fprintf(stderr," end of rule\n");
-    }
-
-    if(matched && pcin) {
-
-      /* So far we matched the rule up to the point of the conditions .
-       * In other words, all of the opcodes match. Now we need to see
-       * if the post conditions are satisfied.
-       * First we check the 'postFalseCond'. This means that we check
-       * to see if any of the subsequent pCode's in the pCode chain 
-       * following the point just past where we have matched depend on
-       * the `postFalseCond' as input then we abort the match
-       */
-      fprintf(stderr,"    matched rule so far, now checking conditions\n");
-      if (peepBlock->postFalseCond && 
-         (pCodeSearchCondition(pcin,peepBlock->postFalseCond) > 0) )
-       matched = 0;
-    }
-
-    if(matched && pcin) {
-
-      pCode *pcprev;
-      pCode *pcr;
-
-
-      /* We matched a rule! Now we have to go through and remove the
-        inefficient code with the optimized version */
-
-      fprintf(stderr, "Found a pcode peep match:\nRule:\n");
-      printpCodeString(stderr,peepBlock->target->pcHead,10);
-      fprintf(stderr,"first thing matched\n");
-      pc->print(stderr,pc);
-      fprintf(stderr,"last thing matched\n");
-      pcin->print(stderr,pcin);
-
-      /* Unlink the original code */
-      pcprev = pc->prev;
-      pcprev->next = pcin;
-      pcin->prev = pc->prev;
-      pCodeDeleteChain(pc,pcin);
-
-      /* Generate the replacement code */
-      pc = pcprev;
-      pcr = peepBlock->replace->pcHead;  // This is the replacement code
-      while (pcr) {
-       pCodeOp *pcop=NULL;
-       /* If the replace pcode is an instruction with an operand, */
-       /* then duplicate the operand (and expand wild cards in the process). */
-       if(pcr->type == PC_OPCODE) {
-         if(PCI(pcr)->pcop)
-           pcop = pCodeOpCopy(PCI(pcr)->pcop);
-
-         pCodeInsertAfter(pc, newpCode(PCI(pcr)->op,pcop));
-       } else if (pcr->type == PC_WILD) {
-         pCodeInsertAfter(pc,peepBlock->wildpCodes[PCW(pcr)->id]);
-       }
-
-
-       pc = pc->next;
-       pc->print(stderr,pc);
-       pcr = pcr->next;
-      }
-
-      return 1;
-    }
-
-    peeprules = peeprules->next;
-  }
-
-  return 0;
-}