* src/regression/compare10.c,
[fw/sdcc] / src / pic / pcodepeep.c
index bb4a4fe779b94c07fe85ff186d6d6c41b72d17f2..c3f3602d44f9da1102da2881129722cc36d891a6 100644 (file)
    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 -------------------------------------------------------------------------*/
 
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "common.h"   // Include everything in the SDCC src directory
-#include "newalloc.h"
-
-
 #include "pcode.h"
+#include "pcodeflow.h"
 #include "ralloc.h"
 
-#if defined(__BORLANDC__) || defined(_MSC_VER)
-#define STRCASECMP stricmp
-#else
-#define STRCASECMP strcasecmp
-#endif
-
-pCodeOp *popCopyGPR2Bit(pCodeOpReg *pc, int bitval);
-
-
-pCodeOp *newpCodeOpWild(int id, pCodePeep *pcp, pCodeOp *subtype);
-pCode *newpCodeWild(int pCodeID, pCodeOp *optional_operand, pCodeOp *optional_label);
-pCode * findNextInstruction(pCode *pc);
-char *Safe_strdup(char *str);
-int getpCode(char *mnem,int dest);
-extern pCodeInstruction *pic14Mnemonics[];
-
-
-/****************************************************************/
-/*
- * rootRules - defined in SDCCpeep.c
- *  This is a pointer to the (parsed) peephole rules that are
- * defined in peep.def.
- */
-
-//extern peepRule *rootRules;
-
+//#define PCODE_DEBUG
 
+#define IS_PCCOMMENT(x) ( x && (x->type==PC_COMMENT))
 
 
 /****************************************************************/
 /****************************************************************/
 typedef struct _DLL {
-  struct _DLL *prev;
-  struct _DLL *next;
-  //  void *data;
+       struct _DLL *prev;
+       struct _DLL *next;
+       //  void *data;
 } _DLL;
 
 
 typedef struct pCodePeepSnippets
 {
-  _DLL dll;
-  pCodePeep *peep;
+       _DLL dll;
+       pCodePeep *peep;
 } pCodePeepSnippets;
 
 
@@ -81,67 +51,53 @@ typedef struct pCodePeepSnippets
 
 static pCodePeepSnippets  *peepSnippets=NULL;
 
-/****************************************************************/
-/*                                                              */
-/* curPeep                                                      */
-/*                                                              */
-/****************************************************************/
-
-static pCodePeep          *curPeep=NULL;
-
-/****************************************************************/
-/*                                                              */
-/* curBlock                                                     */
-/*                                                              */
-/****************************************************************/
-
-static pBlock             *curBlock=NULL;
-
 
 typedef struct pCodeToken 
 {
-  int tt;  // token type;
-  union {
-    char c;  // character
-    int  n;  // number
-    char *s; // string
-  } tok;
-
+       int tt;  // token type;
+       union {
+               char c;  // character
+               int  n;  // number
+               char *s; // string
+       } tok;
+       
 } pCodeToken;
 
-pCodeToken tokArr[50];
-unsigned   tokIdx=0;
+static pCodeToken tokArr[50];
+static unsigned   tokIdx=0;
 
 
 typedef enum  {
-  PCT_SPACE=1,
-  PCT_PERCENT,
-  PCT_COLON,
-  PCT_COMMA,
-  PCT_COMMENT,
-  PCT_STRING,
-  PCT_NUMBER
-
+       PCT_NULL=0,
+               PCT_SPACE=1,
+               PCT_PERCENT,
+               PCT_LESSTHAN,
+               PCT_GREATERTHAN,
+               PCT_COLON,
+               PCT_COMMA,
+               PCT_COMMENT,
+               PCT_STRING,
+               PCT_NUMBER
+               
 } pCodeTokens;
 
 
 typedef struct parsedPattern {
-  struct pcPattern *pcp;
-  pCodeToken *pct;
+       struct pcPattern *pcp;
+       pCodeToken *pct;
 } parsedPattern;
 
 #define MAX_PARSEDPATARR 50
-parsedPattern parsedPatArr[MAX_PARSEDPATARR];
-unsigned int parsedPatIdx=0;
-
+static parsedPattern parsedPatArr[MAX_PARSEDPATARR];
 
 typedef enum {
-  PCP_LABEL=1,
-  PCP_NUMBER,
-  PCP_STR,
-  PCP_WILDVAR,
-  PCP_WILDSTR,
-  PCP_COMMA
+       PCP_LABEL=1,
+               PCP_NUMBER,
+               PCP_STR,
+               PCP_WILDVAR,
+               PCP_WILDSTR,
+               PCP_COMMA,
+               PCP_COMMENT
 } pCodePatterns;
 
 static char pcpat_label[]      = {PCT_PERCENT, PCT_NUMBER, PCT_COLON, 0};
@@ -150,37 +106,42 @@ static char pcpat_string[]     = {PCT_STRING, 0};
 static char pcpat_wildString[] = {PCT_PERCENT, PCT_STRING, 0};
 static char pcpat_wildVar[]    = {PCT_PERCENT, PCT_NUMBER, 0};
 static char pcpat_comma[]      = {PCT_COMMA, 0};
+static char pcpat_comment[]    = {PCT_COMMENT, 0};
 
 
 typedef struct pcPattern {
-  char pt;                 // Pattern type
-  char *tokens;           // list of tokens that describe the pattern
-  void * (*f) (void *);
+       char pt;                 // Pattern type
+       char *tokens;           // list of tokens that describe the pattern
+       void * (*f) (void *,pCodeWildBlock *);
 } pcPattern;
 
-pcPattern pcpArr[] = {
-  {PCP_LABEL,     pcpat_label,      NULL},
-  {PCP_WILDSTR,   pcpat_wildString, NULL},
-  {PCP_STR,       pcpat_string,     NULL},
-  {PCP_WILDVAR,   pcpat_wildVar,    NULL},
-  {PCP_COMMA,     pcpat_comma,      NULL},
-  {PCP_NUMBER,    pcpat_number,     NULL}
+static pcPattern pcpArr[] = {
+       {PCP_LABEL,     pcpat_label,      NULL},
+       {PCP_WILDSTR,   pcpat_wildString, NULL},
+       {PCP_STR,       pcpat_string,     NULL},
+       {PCP_WILDVAR,   pcpat_wildVar,    NULL},
+       {PCP_COMMA,     pcpat_comma,      NULL},
+       {PCP_COMMENT,   pcpat_comment,    NULL},
+       {PCP_NUMBER,    pcpat_number,     NULL}
 };
 
 #define PCPATTERNS (sizeof(pcpArr)/sizeof(pcPattern))
 
 // Assembly Line Token
 typedef enum {
-  ALT_LABEL=1,
-  ALT_MNEM0,
-  ALT_MNEM0A,
-  ALT_MNEM1,
-  ALT_MNEM1A,
-  ALT_MNEM1B,
-  ALT_MNEM2,
-  ALT_MNEM2A
+       ALT_LABEL=1,
+               ALT_COMMENT,
+               ALT_MNEM0,
+               ALT_MNEM0A,
+               ALT_MNEM1,
+               ALT_MNEM1A,
+               ALT_MNEM1B,
+               ALT_MNEM2,
+               ALT_MNEM2A,
+               ALT_MNEM3
 } altPatterns;
 
+static char alt_comment[]   = { PCP_COMMENT, 0};
 static char alt_label[]     = { PCP_LABEL, 0};
 static char alt_mnem0[]     = { PCP_STR, 0};
 static char alt_mnem0a[]    = { PCP_WILDVAR, 0};
@@ -189,26 +150,31 @@ static char alt_mnem1a[]    = { PCP_STR, PCP_WILDVAR, 0};
 static char alt_mnem1b[]    = { PCP_STR, PCP_NUMBER, 0};
 static char alt_mnem2[]     = { PCP_STR, PCP_STR, PCP_COMMA, PCP_STR, 0};
 static char alt_mnem2a[]    = { PCP_STR, PCP_WILDVAR, PCP_COMMA, PCP_STR, 0};
-
-static void * cvt_altpat_label(void *pp);
-static void * cvt_altpat_mnem0(void *pp);
-static void * cvt_altpat_mnem0a(void *pp);
-static void * cvt_altpat_mnem1(void *pp);
-static void * cvt_altpat_mnem1a(void *pp);
-static void * cvt_altpat_mnem1b(void *pp);
-static void * cvt_altpat_mnem2(void *pp);
-static void * cvt_altpat_mnem2a(void *pp);
-
-pcPattern altArr[] = {
-  {ALT_LABEL,        alt_label,  cvt_altpat_label},
-  {ALT_MNEM2A,       alt_mnem2a, cvt_altpat_mnem2a},
-  {ALT_MNEM2,        alt_mnem2,  cvt_altpat_mnem2},
-  {ALT_MNEM1B,       alt_mnem1b, cvt_altpat_mnem1b},
-  {ALT_MNEM1A,       alt_mnem1a, cvt_altpat_mnem1a},
-  {ALT_MNEM1,        alt_mnem1,  cvt_altpat_mnem1},
-  {ALT_MNEM0A,       alt_mnem0a, cvt_altpat_mnem0a},
-  {ALT_MNEM0,        alt_mnem0,  cvt_altpat_mnem0},
-
+static char alt_mnem3[]     = { PCP_STR, PCP_STR, PCP_COMMA, PCP_NUMBER, 0};
+
+static void * cvt_altpat_label(void *pp,pCodeWildBlock *pcwb);
+static void * cvt_altpat_comment(void *pp,pCodeWildBlock *pcwb);
+static void * cvt_altpat_mnem0(void *pp,pCodeWildBlock *pcwb);
+static void * cvt_altpat_mnem0a(void *pp,pCodeWildBlock *pcwb);
+static void * cvt_altpat_mnem1(void *pp,pCodeWildBlock *pcwb);
+static void * cvt_altpat_mnem1a(void *pp,pCodeWildBlock *pcwb);
+static void * cvt_altpat_mnem1b(void *pp,pCodeWildBlock *pcwb);
+static void * cvt_altpat_mnem2(void *pp,pCodeWildBlock *pcwb);
+static void * cvt_altpat_mnem2a(void *pp,pCodeWildBlock *pcwb);
+static void * cvt_altpat_mnem3(void *pp,pCodeWildBlock *pcwb);
+
+static pcPattern altArr[] = {
+       {ALT_LABEL,        alt_label,  cvt_altpat_label},
+       {ALT_COMMENT,      alt_comment,cvt_altpat_comment},
+       {ALT_MNEM3,        alt_mnem3,  cvt_altpat_mnem3},
+       {ALT_MNEM2A,       alt_mnem2a, cvt_altpat_mnem2a},
+       {ALT_MNEM2,        alt_mnem2,  cvt_altpat_mnem2},
+       {ALT_MNEM1B,       alt_mnem1b, cvt_altpat_mnem1b},
+       {ALT_MNEM1A,       alt_mnem1a, cvt_altpat_mnem1a},
+       {ALT_MNEM1,        alt_mnem1,  cvt_altpat_mnem1},
+       {ALT_MNEM0A,       alt_mnem0a, cvt_altpat_mnem0a},
+       {ALT_MNEM0,        alt_mnem0,  cvt_altpat_mnem0},
+       
 };
 
 #define ALTPATTERNS (sizeof(altArr)/sizeof(pcPattern))
@@ -223,22 +189,22 @@ static void * DLL_append(_DLL *list, _DLL *next);
 /*-----------------------------------------------------------------*/
 static int cvt_extract_destination(parsedPattern *pp)
 {
-
-  if(pp->pct[0].tt == PCT_STRING) {
-
-    // just check first letter for now
-
-    if(toupper(*pp->pct[0].tok.s) == 'F')
-      return 1;
-
-  } else if (pp->pct[0].tt == PCT_NUMBER) {
-
-    if(pp->pct[0].tok.n)
-      return 1;
-  }
-
-  return 0;
-
+       
+       if(pp->pct[0].tt == PCT_STRING) {
+               
+               // just check first letter for now
+               
+               if(toupper((unsigned char)*pp->pct[0].tok.s) == 'F')
+                       return 1;
+               
+       } else if (pp->pct[0].tt == PCT_NUMBER) {
+               
+               if(pp->pct[0].tok.n)
+                       return 1;
+       }
+       
+       return 0;
+       
 }
 
 /*-----------------------------------------------------------------*/
@@ -250,27 +216,27 @@ static int cvt_extract_destination(parsedPattern *pp)
 
 static pCodeOp *cvt_extract_status(char *reg, char *bit)
 {
-  int len;
-
-  if(STRCASECMP(reg, pc_status.pcop.name))
-    return NULL;
-
-  len = strlen(bit);
-
-  if(len == 1) {
-    // check C,Z
-    if(toupper(*bit) == 'C')
-      return PCOP(popCopyGPR2Bit(&pc_status,PIC_C_BIT));
-    if(toupper(*bit) == 'Z')
-      return PCOP(popCopyGPR2Bit(&pc_status,PIC_Z_BIT));
-  }
-
-  // Check DC
-  if(len ==2 && toupper(bit[0]) == 'D' && toupper(bit[1]) == 'C')
-    return PCOP(popCopyGPR2Bit(&pc_status,PIC_DC_BIT));
-
-  return NULL;
-
+       int len;
+       
+       if(STRCASECMP(reg, pc_status.pcop.name))
+               return NULL;
+       
+       len = strlen(bit);
+       
+       if(len == 1) {
+               // check C,Z
+               if(toupper((unsigned char)*bit) == 'C')
+                       return PCOP(popCopyGPR2Bit(PCOP(&pc_status),PIC_C_BIT));
+               if(toupper((unsigned char)*bit) == 'Z')
+                       return PCOP(popCopyGPR2Bit(PCOP(&pc_status),PIC_Z_BIT));
+       }
+       
+       // Check DC
+       if(len ==2 && toupper((unsigned char)bit[0]) == 'D' && toupper((unsigned char)bit[1]) == 'C')
+               return PCOP(popCopyGPR2Bit(PCOP(&pc_status),PIC_DC_BIT));
+       
+       return NULL;
+       
 }
 
 /*-----------------------------------------------------------------*/
@@ -283,39 +249,68 @@ static pCodeOp *cvt_extract_status(char *reg, char *bit)
 /* at this point, we wish to extract only the 'number'             */
 /*                                                                 */
 /*-----------------------------------------------------------------*/
-static void * cvt_altpat_label(void *pp)
+static void * cvt_altpat_label(void *pp,pCodeWildBlock *pcwb)
 {
-  parsedPattern *p = pp;
-
-  fprintf(stderr,"altpat_label with ID = %d\n",p->pct[1].tok.n);
-  return newpCodeOpLabel(-p->pct[1].tok.n);
-
+       parsedPattern *p = pp;
+       
+       DFPRINTF((stderr,"altpat_label with ID = %d\n",p->pct[1].tok.n));
+       return newpCodeLabel(NULL,-p->pct[1].tok.n);
+       
 }
 
 /*-----------------------------------------------------------------*/
+/* cvt_altpat_comment - convert assembly line type to a comment    */
+/* INPUT: pointer to the parsedPattern                             */
+/*                                                                 */
+/*  pp[0] - comment                                                */
+/*                                                                 */
+/*                                                                 */
 /*-----------------------------------------------------------------*/
-static void * cvt_altpat_mnem0(void *pp)
+static void * cvt_altpat_comment(void *pp,pCodeWildBlock *pcwb)
 {
-  parsedPattern *p = pp;
-  int opcode;
-
-  pCodeInstruction *pci=NULL;
-
-  fprintf(stderr,"altpat_mnem0 %s\n",  p->pct[0].tok.s);
-
-  opcode = getpCode(p->pct[0].tok.s,0);
-  if(opcode < 0) {
-    fprintf(stderr, "Bad mnemonic\n");
-    return NULL;
-  }
-
-  pci = PCI(newpCode(opcode, NULL));
-
-  if(!pci)
-    fprintf(stderr,"couldn't find mnemonic\n");
-
+       parsedPattern *p = pp;
+       
+       DFPRINTF((stderr,"altpat_comment  = %s\n",p->pct[0].tok.s));
+       return newpCodeCharP(p->pct[0].tok.s);
+       
+}
 
-  return pci;
+/*-----------------------------------------------------------------*/
+/* cvt_altpat_mem0  - convert assembly line type to a wild pCode   */
+/*                    instruction                                  */
+/*                                                                 */
+/*  pp[0] - str                                                    */
+/*                                                                 */
+/*-----------------------------------------------------------------*/
+static void * cvt_altpat_mnem0(void *pp,pCodeWildBlock *pcwb)
+{
+       parsedPattern *p = pp;
+       int opcode;
+       
+       pCodeInstruction *pci=NULL;
+       
+       DFPRINTF((stderr,"altpat_mnem0 %s\n",  p->pct[0].tok.s));
+       
+       opcode = getpCode(p->pct[0].tok.s,0);
+       
+       if(opcode < 0) {
+               /* look for special command strings like _NOTBITSKIP_ */
+               
+               //fprintf(stderr, "Bad mnemonic\n");
+               
+               opcode  = getpCodePeepCommand(p->pct[0].tok.s);
+               //if(opcode > 0)
+               //  fprintf(stderr,"  but valid peep command: %s, key = %d\n",p->pct[0].tok.s,opcode);
+               return NULL;
+       }
+       
+       pci = PCI(newpCode(opcode, NULL));
+       
+       if(!pci)
+               fprintf(stderr,"couldn't find mnemonic\n");
+       
+       
+       return pci;
 }
 
 /*-----------------------------------------------------------------*/
@@ -325,14 +320,18 @@ static void * cvt_altpat_mnem0(void *pp)
 /*  pp[0] - wild var                                               */
 /*                                                                 */
 /*-----------------------------------------------------------------*/
-static void * cvt_altpat_mnem0a(void *pp)
+static void * cvt_altpat_mnem0a(void *pp, pCodeWildBlock *pcwb)
 {
-  parsedPattern *p = pp;
-
-  fprintf(stderr,"altpat_mnem0a wild mnem # %d\n",  p[0].pct[1].tok.n);
-
-  return newpCodeWild(p[0].pct[1].tok.n,NULL,NULL);
-
+       parsedPattern *p = pp;
+       
+       DFPRINTF((stderr,"altpat_mnem0a wild mnem # %d\n",  p[0].pct[1].tok.n));
+       
+       /* Save the index of the maximum wildcard mnemonic */
+       if(p[0].pct[1].tok.n > pcwb->nwildpCodes)
+               pcwb->nwildpCodes = p[0].pct[1].tok.n;
+       
+       return newpCodeWild(p[0].pct[1].tok.n,NULL,NULL);
+       
 }
 
 /*-----------------------------------------------------------------*/
@@ -343,36 +342,40 @@ static void * cvt_altpat_mnem0a(void *pp)
 /*  pp[1] - Operand                                                */
 /*                                                                 */
 /*-----------------------------------------------------------------*/
-static void * cvt_altpat_mnem1(void *pp)
+static void * cvt_altpat_mnem1(void *pp,pCodeWildBlock *pcwb)
 {
-
-  parsedPattern *p = pp;
-  int opcode;
-
-  pCodeInstruction *pci=NULL;
-  pCodeOp *pcosubtype;
-
-  fprintf(stderr,"altpat_mnem1 %s var %s\n",  p->pct[0].tok.s,p[1].pct[0].tok.s);
-
-  opcode = getpCode(p->pct[0].tok.s,0);
-  if(opcode < 0) {
-    fprintf(stderr, "Bad mnemonic\n");
-    return NULL;
-  }
-
-  if(pic14Mnemonics[opcode]->bit_inst)
-    pcosubtype = newpCodeOp(p[1].pct[0].tok.s,PO_BIT);
-  else
-    pcosubtype = newpCodeOp(p[1].pct[0].tok.s,PO_GPR_REGISTER);
-
-
-  pci = PCI(newpCode(opcode, pcosubtype));
-
-  if(!pci)
-    fprintf(stderr,"couldn't find mnemonic\n");
-
-
-  return pci;
+       
+       parsedPattern *p = pp;
+       int opcode;
+       
+       pCodeInstruction *pci=NULL;
+       pCodeOp *pcosubtype;
+       
+       DFPRINTF((stderr,"altpat_mnem1 %s var %s\n",  p->pct[0].tok.s,p[1].pct[0].tok.s));
+       
+       opcode = getpCode(p->pct[0].tok.s,0);
+       if(opcode < 0) {
+               //fprintf(stderr, "Bad mnemonic\n");
+               opcode  = getpCodePeepCommand(p->pct[0].tok.s);
+               //if(opcode > 0)
+               //fprintf(stderr,"  but valid peep command: %s, key = %d\n",p->pct[0].tok.s,opcode);
+               
+               return NULL;
+       }
+       
+       if(pic14Mnemonics[opcode]->isBitInst)
+               pcosubtype = newpCodeOp(p[1].pct[0].tok.s,PO_BIT);
+       else
+               pcosubtype = newpCodeOp(p[1].pct[0].tok.s,PO_GPR_REGISTER);
+       
+       
+       pci = PCI(newpCode(opcode, pcosubtype));
+       
+       if(!pci)
+               fprintf(stderr,"couldn't find mnemonic\n");
+       
+       
+       return pci;
 }
 
 /*-----------------------------------------------------------------*/
@@ -383,108 +386,140 @@ static void * cvt_altpat_mnem1(void *pp)
 /*  pp[1] - wild var                                               */
 /*                                                                 */
 /*-----------------------------------------------------------------*/
-static void * cvt_altpat_mnem1a(void *pp)
+static void * cvt_altpat_mnem1a(void *pp,pCodeWildBlock *pcwb)
 {
-  parsedPattern *p = pp;
-  int opcode;
-
-  pCodeInstruction *pci=NULL;
-  pCodeOp *pcosubtype;
-
-  fprintf(stderr,"altpat_mnem1a %s var %d\n",  p->pct[0].tok.s,p[1].pct[1].tok.n);
-
-  opcode = getpCode(p->pct[0].tok.s,0);
-  if(opcode < 0) {
-    fprintf(stderr, "Bad mnemonic\n");
-    return NULL;
-  }
-
-  if(pic14Mnemonics[opcode]->bit_inst)
-    pcosubtype = newpCodeOp(NULL,PO_BIT);
-  else
-    pcosubtype = newpCodeOp(NULL,PO_GPR_REGISTER);
-
-
-  pci = PCI(newpCode(opcode,
-                    newpCodeOpWild(p[1].pct[1].tok.n, curPeep, pcosubtype)));
-
-  if(!pci)
-    fprintf(stderr,"couldn't find mnemonic\n");
-
-
-  return pci;
+       parsedPattern *p = pp;
+       int opcode;
+       
+       pCodeInstruction *pci=NULL;
+       pCodeOp *pcosubtype;
+       
+       DFPRINTF((stderr,"altpat_mnem1a %s var %d\n",  p->pct[0].tok.s,p[1].pct[1].tok.n));
+       
+       opcode = getpCode(p->pct[0].tok.s,0);
+       if(opcode < 0) {
+               int cmd_id = getpCodePeepCommand(p->pct[0].tok.s);
+               pCode *pc=NULL;
+               
+               if(cmd_id<0) {
+                       fprintf(stderr, "Bad mnemonic\n");
+                       return NULL;
+               }
+               
+               if(p[0].pct[1].tok.n > pcwb->nwildpCodes)
+                       pcwb->nwildpCodes = p[0].pct[1].tok.n;
+               
+               pc =  newpCodeWild(p[1].pct[1].tok.n,NULL,NULL);
+               
+               switch(cmd_id) {
+               case NOTBITSKIP:
+                       PCW(pc)->mustNotBeBitSkipInst = 1;
+                       break;
+               case BITSKIP:
+                       PCW(pc)->mustBeBitSkipInst = 1;
+                       break;
+               case INVERTBITSKIP:
+                       PCW(pc)->invertBitSkipInst = 1;
+               }
+               return pc;
+       }
+       
+       if(pic14Mnemonics[opcode]->isBitInst)
+               pcosubtype = newpCodeOpBit(NULL,-1,0);
+       else
+               pcosubtype = newpCodeOp(NULL,PO_GPR_REGISTER);
+       
+       
+       pci = PCI(newpCode(opcode,
+               newpCodeOpWild(p[1].pct[1].tok.n, pcwb, pcosubtype)));
+       
+       /* Save the index of the maximum wildcard variable */
+       if(p[1].pct[1].tok.n > pcwb->nvars)
+               pcwb->nvars = p[1].pct[1].tok.n;
+       
+       if(!pci)
+               fprintf(stderr,"couldn't find mnemonic\n");
+       
+       
+       return pci;
 }
 
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
-static void * cvt_altpat_mnem1b(void *pp)
+static void * cvt_altpat_mnem1b(void *pp,pCodeWildBlock *pcwb)
 {
-  parsedPattern *p = pp;
-  int opcode;
-
-  pCodeInstruction *pci=NULL;
-
-  fprintf(stderr,"altpat_mnem1b %s var %d\n",  p->pct[0].tok.s,p[1].pct[0].tok.n);
-
-  opcode = getpCode(p->pct[0].tok.s,0);
-  if(opcode < 0) {
-    fprintf(stderr, "Bad mnemonic\n");
-    return NULL;
-  }
-
-  pci = PCI(newpCode(opcode, newpCodeOpLit(p[1].pct[0].tok.n) ));
-
-  if(!pci)
-    fprintf(stderr,"couldn't find mnemonic\n");
-
-
-  return pci;
+       parsedPattern *p = pp;
+       int opcode;
+       
+       pCodeInstruction *pci=NULL;
+       
+       DFPRINTF((stderr,"altpat_mnem1b %s var %d\n",  p->pct[0].tok.s,p[1].pct[0].tok.n));
+       
+       opcode = getpCode(p->pct[0].tok.s,0);
+       if(opcode < 0) {
+               fprintf(stderr, "Bad mnemonic\n");
+               return NULL;
+       }
+       
+       pci = PCI(newpCode(opcode, newpCodeOpLit(p[1].pct[0].tok.n) ));
+       
+       if(!pci)
+               fprintf(stderr,"couldn't find mnemonic\n");
+       
+       
+       return pci;
 }
 
 /*-----------------------------------------------------------------*/
+/* cvt_altpat_mnem2                                                */
+/*                                                                 */
+/*  pp[0] - mnem                                                   */
+/*  pp[1] - var                                                    */
+/*  pp[2] - comma                                                  */
+/*  pp[3] - destination                                            */
 /*-----------------------------------------------------------------*/
-static void * cvt_altpat_mnem2(void *pp)
+static void * cvt_altpat_mnem2(void *pp,pCodeWildBlock *pcwb)
 {
-  parsedPattern *p = pp;
-  int opcode;
-  int dest;
-
-  pCodeInstruction *pci=NULL;
-  pCodeOp *pcosubtype;
-
-  dest = cvt_extract_destination(&p[3]);
-
-  fprintf(stderr,"altpat_mnem2 %s var %s destination %s(%d)\n",
-         p->pct[0].tok.s,
-         p[1].pct[0].tok.s,
-         p[3].pct[0].tok.s,
-         dest);
-
-
-  opcode = getpCode(p->pct[0].tok.s,dest);
-  if(opcode < 0) {
-    fprintf(stderr, "Bad mnemonic\n");
-    return NULL;
-  }
-
-  if(pic14Mnemonics[opcode]->bit_inst) {
-    pcosubtype = cvt_extract_status(p[1].pct[0].tok.s, p[3].pct[0].tok.s);
-    if(pcosubtype == NULL) {
-      fprintf(stderr, "bad operand?\n");
-      return NULL;
-    }
-      
-  } else
-    pcosubtype = newpCodeOp(p[1].pct[0].tok.s,PO_GPR_REGISTER);
-
-
-  pci = PCI(newpCode(opcode,pcosubtype));
-
-  if(!pci)
-    fprintf(stderr,"couldn't find mnemonic\n");
-
-  return pci;
-
+       parsedPattern *p = pp;
+       int opcode;
+       int dest;
+       
+       pCodeInstruction *pci=NULL;
+       pCodeOp *pcosubtype;
+       
+       dest = cvt_extract_destination(&p[3]);
+       
+       DFPRINTF((stderr,"altpat_mnem2 %s var %s destination %s(%d)\n",
+               p->pct[0].tok.s,
+               p[1].pct[0].tok.s,
+               p[3].pct[0].tok.s,
+               dest));
+       
+       
+       opcode = getpCode(p->pct[0].tok.s,dest);
+       if(opcode < 0) {
+               fprintf(stderr, "Bad mnemonic\n");
+               return NULL;
+       }
+       
+       if(pic14Mnemonics[opcode]->isBitInst) {
+               pcosubtype = cvt_extract_status(p[1].pct[0].tok.s, p[3].pct[0].tok.s);
+               if(pcosubtype == NULL) {
+                       fprintf(stderr, "bad operand?\n");
+                       return NULL;
+               }
+               
+       } else
+               pcosubtype = newpCodeOp(p[1].pct[0].tok.s,PO_GPR_REGISTER);
+       
+       
+       pci = PCI(newpCode(opcode,pcosubtype));
+       
+       if(!pci)
+               fprintf(stderr,"couldn't find mnemonic\n");
+       
+       return pci;
+       
 }
 
 /*-----------------------------------------------------------------*/
@@ -498,114 +533,216 @@ static void * cvt_altpat_mnem2(void *pp)
 /*  pp[3] - destination                                            */
 /*                                                                 */
 /*-----------------------------------------------------------------*/
-static void * cvt_altpat_mnem2a(void *pp)
+static void * cvt_altpat_mnem2a(void *pp,pCodeWildBlock *pcwb)
 {
-  parsedPattern *p = pp;
-  int opcode;
-  int dest;
-
-  pCodeInstruction *pci=NULL;
-  pCodeOp *pcosubtype;
-
-  dest = cvt_extract_destination(&p[3]);
-
-  fprintf(stderr,"altpat_mnem2a %s var %d destination %s(%d)\n",
-         p->pct[0].tok.s,
-         p[1].pct[1].tok.n,
-         p[3].pct[0].tok.s,
-         dest);
-
-
-  opcode = getpCode(p->pct[0].tok.s,dest);
-  if(opcode < 0) {
-    fprintf(stderr, "Bad mnemonic\n");
-    return NULL;
-  }
-
-  if(pic14Mnemonics[opcode]->bit_inst)
-    pcosubtype = newpCodeOp(NULL,PO_BIT);
-  else
-    pcosubtype = newpCodeOp(NULL,PO_GPR_REGISTER);
-
-
-  pci = PCI(newpCode(opcode,
-                    newpCodeOpWild(p[1].pct[1].tok.n, curPeep, pcosubtype)));
-
-  if(!pci)
-    fprintf(stderr,"couldn't find mnemonic\n");
+       parsedPattern *p = pp;
+       int opcode;
+       int dest;
+       
+       pCodeInstruction *pci=NULL;
+       pCodeOp *pcosubtype;
+       
+       if(!pcwb) {
+               fprintf(stderr,"ERROR %s:%d - can't assemble line\n",__FILE__,__LINE__);
+               return NULL;
+       }
+       
+       dest = cvt_extract_destination(&p[3]);
+       
+       DFPRINTF((stderr,"altpat_mnem2a %s var %d destination %s(%d)\n",
+               p->pct[0].tok.s,
+               p[1].pct[1].tok.n,
+               p[3].pct[0].tok.s,
+               dest));
+       
+       
+       opcode = getpCode(p->pct[0].tok.s,dest);
+       if(opcode < 0) {
+               fprintf(stderr, "Bad mnemonic\n");
+               return NULL;
+       }
+       
+       if(pic14Mnemonics[opcode]->isBitInst)
+               pcosubtype = newpCodeOp(NULL,PO_BIT);
+       else
+               pcosubtype = newpCodeOp(NULL,PO_GPR_REGISTER);
+       
+       
+       pci = PCI(newpCode(opcode,
+               newpCodeOpWild(p[1].pct[1].tok.n, pcwb, pcosubtype)));
+       
+       /* Save the index of the maximum wildcard variable */
+       if(p[1].pct[1].tok.n > pcwb->nvars)
+               pcwb->nvars = p[1].pct[1].tok.n;
+       
+       if(!pci)
+               fprintf(stderr,"couldn't find mnemonic\n");
+       
+       return pci;
+       
+}
 
-  return pci;
 
+/*-----------------------------------------------------------------*/
+/* cvt_altpat_mem3 -  convert assembly line type to a pCode        */
+/*                    This rule is for bsf/bcf type instructions   */
+/*                                                                 */
+/*                                                                 */
+/*  pp[0] - mnem                                                   */
+/*  pp[1] - register                                               */
+/*  pp[2] - comma                                                  */
+/*  pp[3] - number                                                 */
+/*                                                                 */
+/*-----------------------------------------------------------------*/
+static void * cvt_altpat_mnem3(void *pp,pCodeWildBlock *pcwb)
+{
+       parsedPattern *p = pp;
+       int opcode;
+       int dest;  // or could be bit position in the register
+       
+       pCodeInstruction *pci=NULL;
+       pCodeOp *pcosubtype=NULL;
+       
+       dest = cvt_extract_destination(&p[3]);
+       
+       DFPRINTF((stderr,"altpat_mnem3 %s var %s bit (%d)\n",
+               p->pct[0].tok.s,
+               p[1].pct[0].tok.s,
+               p[3].pct[0].tok.n));
+       
+       
+       opcode = getpCode(p->pct[0].tok.s,0);
+       if(opcode < 0) {
+               fprintf(stderr, "Bad mnemonic\n");
+               return NULL;
+       }
+       
+       
+       if(pic14Mnemonics[opcode]->isBitInst) {
+               //pcosubtype = cvt_extract_status(p[1].pct[0].tok.s, p[3].pct[0].tok.s);
+               
+               //if(pcosubtype == NULL) {
+               pcosubtype = newpCodeOpBit(p[1].pct[0].tok.s,p[3].pct[0].tok.n,0);
+               //}
+       } else
+               pcosubtype = newpCodeOp(p[1].pct[0].tok.s,PO_GPR_REGISTER);
+       
+       if(pcosubtype == NULL) {
+               fprintf(stderr, "Bad operand\n");
+               return NULL;
+       }
+       
+       pci = PCI(newpCode(opcode, pcosubtype));
+       
+       if(!pci)
+               fprintf(stderr,"couldn't find mnemonic\n");
+       
+       return pci;
+       
 }
 
 /*-----------------------------------------------------------------*/
+/* tokenizeLineNode - Convert a string (of char's) that was parsed */
+/*                    by SDCCpeeph.c into a string of tokens.      */
+/*                                                                 */
+/*                                                                 */
+/* The tokenizer is of the classic type. When an item is encounterd*/
+/* it is converted into a token. The token is a structure that     */
+/* encodes the item's type and it's value (when appropriate).      */
+/*                                                                 */
+/* Accepted token types:                                           */
+/*    SPACE  NUMBER STRING  %  : ,  ;                              */
+/*                                                                 */
+/*                                                                 */
+/*                                                                 */
 /*-----------------------------------------------------------------*/
 
 
-static void parseLineNode(char *ln)
+static void tokenizeLineNode(char *ln)
 {
-
-  tokIdx = 0;
-
-  if(!ln || !*ln)
-    return;
-
-  while(*ln) {
-
-    if(isspace(*ln)) {
-      tokArr[tokIdx++].tt = PCT_SPACE;
-      while (isspace (*ln))
-       ln++;
-      continue;
-    }
-
-    if(isdigit(*ln)) {
-
-      tokArr[tokIdx].tt = PCT_NUMBER;
-      tokArr[tokIdx++].tok.n = strtol(ln, &ln, 0);
-
-      continue;
-
-    }
-
-    switch(*ln) {
-    case '%':
-      tokArr[tokIdx++].tt = PCT_PERCENT;
-      break;
-    case ':':
-      tokArr[tokIdx++].tt = PCT_COLON;
-      break;
-    case ';':
-      tokArr[tokIdx].tok.s = Safe_strdup(ln);
-      tokArr[tokIdx++].tt = PCT_COMMENT;
-      return;
-    case ',':
-      tokArr[tokIdx++].tt = PCT_COMMA;
-      break;
-
-
-    default:
-      if(isalpha(*ln)) {
-       char buffer[50];
-       int i=0;
-
-       while( (isalpha(*ln)  ||  isdigit(*ln)) && i<49)
-         buffer[i++] = *ln++;
-
-       ln--;
-       buffer[i] = 0;
-
-       tokArr[tokIdx].tok.s = Safe_strdup(buffer);
-       //fprintf(stderr," string %s",tokArr[tokIdx].tok.s);
-
-       tokArr[tokIdx++].tt = PCT_STRING;
-
-      }
-    }
-    ln++;
-  }
-
-  tokArr[tokIdx].tt = 0;
+       char *lnstart=ln;
+       tokIdx = 0;               // Starting off at the beginning
+       tokArr[0].tt = PCT_NULL;  // and assume invalid character for first token.
+       
+       if(!ln || !*ln)
+               return;
+       
+       
+       while(*ln) {
+               
+               if(isspace((unsigned char)*ln)) {
+                       // add a SPACE token and eat the extra spaces.
+                       tokArr[tokIdx++].tt = PCT_SPACE;
+                       while (isspace ((unsigned char)*ln))
+                               ln++;
+                       continue;
+               }
+               
+               if(isdigit((unsigned char)*ln)) {
+                       
+                       tokArr[tokIdx].tt = PCT_NUMBER;
+                       tokArr[tokIdx++].tok.n = strtol(ln, &ln, 0);
+                       
+                       continue;
+                       
+               }
+               
+               switch(*ln) {
+               case '%':
+                       tokArr[tokIdx++].tt = PCT_PERCENT;
+                       break;
+               case '<':
+                       tokArr[tokIdx++].tt = PCT_LESSTHAN;
+                       break;
+               case '>':
+                       tokArr[tokIdx++].tt = PCT_GREATERTHAN;
+                       break;
+               case ':':
+                       tokArr[tokIdx++].tt = PCT_COLON;
+                       break;
+               case ';':
+                       tokArr[tokIdx].tok.s = Safe_strdup(ln);
+                       tokArr[tokIdx++].tt = PCT_COMMENT;
+                       tokArr[tokIdx].tt = PCT_NULL;
+                       return;
+               case ',':
+                       tokArr[tokIdx++].tt = PCT_COMMA;
+                       break;
+                       
+                       
+               default:
+                       if(isalpha((unsigned char)*ln) || (*ln == '_') ) {
+                               char buffer[50];
+                               int i=0;
+                               
+                               while( (isalpha((unsigned char)*ln) || isdigit((unsigned char)*ln) || (*ln == '_')) && i<49)
+                                       buffer[i++] = *ln++;
+                               
+                               ln--;
+                               buffer[i] = 0;
+                               
+                               tokArr[tokIdx].tok.s = Safe_strdup(buffer);
+                               tokArr[tokIdx++].tt = PCT_STRING;
+                               
+                       } else {
+                               fprintf(stderr, "Error while parsing peep rules (check peeph.def)\n");
+                               fprintf(stderr, "Line: %s\n",lnstart);
+                               fprintf(stderr, "Token: '%c'\n",*ln);
+                               exit(1);
+                       }
+               }
+               
+               /* Advance to next character in input string .
+               * Note, if none of the tests passed above, then 
+               * we effectively ignore the `bad' character.
+               * Since the line has already been parsed by SDCCpeeph,
+               * chance are that there are no invalid characters... */
+               
+               ln++;
+               
+       }
+       
+       tokArr[tokIdx].tt = 0;
 }
 
 
@@ -614,326 +751,460 @@ static void parseLineNode(char *ln)
 
 
 
-void dump1Token(pCodeTokens tt)
+static void dump1Token(pCodeTokens tt)
 {
-
-  switch(tt) {
-  case PCT_SPACE:
-    fprintf(stderr, " space ");
-    break;
-  case PCT_PERCENT:
-    fprintf(stderr, " pct ");
-    fputc('%', stderr);
-    break;
-  case PCT_COLON:
-    fprintf(stderr, " col ");
-    fputc(':',stderr);
-    break;
-  case PCT_COMMA:
-    fprintf(stderr, " com ");
-    fputc(',',stderr);
-    break;
-  case PCT_COMMENT:
-  case PCT_STRING:
-    fprintf(stderr, " str ");
-    //fprintf(stderr,"%s",tokArr[i].tok.s);
-    break;
-  case PCT_NUMBER:
-    fprintf(stderr, " num ");
-    //fprintf(stderr,"%d",tokArr[i].tok.n);
-
-
-  }
+       
+       switch(tt) {
+       case PCT_SPACE:
+               fprintf(stderr, " space ");
+               break;
+       case PCT_PERCENT:
+               fprintf(stderr, " pct %%");
+               break;
+       case PCT_LESSTHAN:
+               fprintf(stderr, " pct <");
+               break;
+       case PCT_GREATERTHAN:
+               fprintf(stderr, " pct >");
+               break;
+       case PCT_COLON:
+               fprintf(stderr, " col :");
+               break;
+       case PCT_COMMA:
+               fprintf(stderr, " comma , ");
+               break;
+       case PCT_COMMENT:
+               fprintf(stderr, " comment ");
+               //fprintf(stderr,"%s",tokArr[i].tok.s);
+               break;
+       case PCT_STRING:
+               fprintf(stderr, " str ");
+               //fprintf(stderr,"%s",tokArr[i].tok.s);
+               break;
+       case PCT_NUMBER:
+               fprintf(stderr, " num ");
+               //fprintf(stderr,"%d",tokArr[i].tok.n);
+               break;
+       case PCT_NULL:
+               fprintf(stderr, " null ");
+               
+       }
+       
 }
 
 
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 
-int pcComparePattern(pCodeToken *pct, char *pat, int max_tokens)
+static int pcComparePattern(pCodeToken *pct, char *pat, int max_tokens)
 {
-  int i=0;
-
-  if(!pct || !pat || !*pat)
-    return 0;
-
-  //fprintf(stderr,"comparing against:\n");
-
-  while(i < max_tokens) {
-
-    if(*pat == 0){
-      //fprintf(stderr,"matched\n");
-      return (i+1);
-    }
-
-    //dump1Token(*pat); fprintf(stderr,"\n");
-
-    if(pct->tt != *pat) 
-      return 0;
-
-
-    pct++;
-    pat++;
-  }
-
-  return 0;
-
+       int i=0;
+       
+       if(!pct || !pat || !*pat)
+               return 0;
+       
+       //DFPRINTF((stderr,"comparing against:\n"));
+       
+       while(i < max_tokens) {
+               
+               if(*pat == 0){
+                       //DFPRINTF((stderr,"matched\n"));
+                       return (i+1);
+               }
+               
+               //dump1Token(*pat); DFPRINTF((stderr,"\n"));
+               
+               if(pct->tt != *pat) 
+                       return 0;
+               
+               
+               pct++;
+               pat++;
+       }
+       
+       return 0;
+       
 }
 
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 
-int altComparePattern( char *pct, parsedPattern *pat, int max_tokens)
+static int altComparePattern(char *pct, parsedPattern *pat, int max_tokens)
 {
-  int i=0;
-  
-  if(!pct || !pat || !*pct)
-    return 0;
-
-
-  while(i < max_tokens) {
-
-    if(*pct == 0) {
-      //fprintf(stderr,"matched\n");
-      return i;
-    }
-
-    //dump1Token(*pat); fprintf(stderr,"\n");
-
-    if( !pat || !pat->pcp )
-      return 0;
-
-    if (pat->pcp->pt != *pct)  
-      return 0;
-
-    //fprintf(stderr," pct=%d\n",*pct);
-    pct++;
-    pat++;
-    i++;
-  }
-
-  return 0;
-
+       int i=0;
+       
+       if(!pct || !pat || !*pct)
+               return 0;
+       
+       
+       while(i < max_tokens) {
+               
+               if(*pct == 0) {
+                       //DFPRINTF((stderr,"matched\n"));
+                       return i;
+               }
+               
+               //dump1Token(*pat); DFPRINTF((stderr,"\n"));
+               
+               if( !pat || !pat->pcp )
+                       return 0;
+               
+               if (pat->pcp->pt != *pct)  
+                       return 0;
+               
+               //DFPRINTF((stderr," pct=%d\n",*pct));
+               pct++;
+               pat++;
+               i++;
+       }
+       
+       return 0;
+       
 }
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 
-int advTokIdx(int *v, int amt)
+static int advTokIdx(int *v, int amt)
 {
-
-  if(*v + amt > tokIdx)
-    return 1;
-
-  *v += amt;
-  return 0;
-
+       
+       if((unsigned) (*v + amt) > tokIdx)
+               return 1;
+       
+       *v += amt;
+       return 0;
+       
 }
 
 /*-----------------------------------------------------------------*/
+/* parseTokens - convert the tokens corresponding to a single line */
+/*               of a peep hole assembly into a pCode object.      */
+/*                                                                 */
+/*                                                                 */
+/*                                                                 */
+/*                                                                 */
+/* This is a simple parser that looks for strings of the type      */
+/* allowed in the peep hole definition file. Essentially the format*/
+/* is the same as a line of assembly:                              */
+/*                                                                 */
+/*  label:    mnemonic   op1, op2, op3    ; comment                */
+/*                                                                 */
+/* Some of these items aren't present. It's the job of the parser  */
+/* to determine which are and convert those into the appropriate   */
+/* pcode.                                                          */
 /*-----------------------------------------------------------------*/
 
-void dumpTokens(void)
+static int parseTokens(pCodeWildBlock *pcwb, pCode **pcret)
 {
-  int i;
-  pCode *pc;
-
-  if(!tokIdx)
-    return;
-
-  for(i=0; i<=tokIdx; i++)
-    dump1Token(tokArr[i].tt);
-
-
-  fputc('\n',stderr);
-
-  {
-    int lparsedPatIdx=0;
-    int lpcpIdx;
-    int ltokIdx =0;
-    int matching = 0;
-    int j=0;
-    int k=0;
-
-    char * cPmnem  = NULL;     // Pointer to non-wild mnemonic (if any)
-    char * cP1stop = NULL;
-    char * cP2ndop = NULL;
-
-    //pCodeOp *pcl   = NULL;       // Storage for a label
-    //pCodeOp *pco1  = NULL;       // 1st operand
-    //pCodeOp *pco2  = NULL;       // 2nd operand
-    //pCode   *pc    = NULL;       // Mnemonic
-
-    typedef enum {
-      PS_START,
-      PS_HAVE_LABEL,
-      PS_HAVE_MNEM,
-      PS_HAVE_1OPERAND,
-      PS_HAVE_COMMA,
-      PS_HAVE_2OPERANDS
-    } ParseStates;
-
-    ParseStates state = PS_START;
-
-    do {
-
-      lpcpIdx=0;
-      matching = 0;
-      //fprintf(stderr,"ltokIdx = %d\n",ltokIdx);
-
-      if(  ((tokArr[ltokIdx].tt == PCT_SPACE) )
-          && (advTokIdx(&ltokIdx, 1)) ) // eat space
-       break;
-
-      do {
-       j = pcComparePattern(&tokArr[ltokIdx], pcpArr[lpcpIdx].tokens, tokIdx +1);
-       if( j ) {
-         //fprintf(stderr,"found token pattern match\n");
-         switch(pcpArr[lpcpIdx].pt) {
-         case  PCP_LABEL:
-           if(state == PS_START){
-             fprintf(stderr,"  label\n");
-             state = PS_HAVE_LABEL;
-           } else 
-             fprintf(stderr,"  bad state (%d) for label\n",state);
-           break;
-
-         case  PCP_STR:
-           fprintf(stderr,"  %s is",tokArr[ltokIdx].tok.s);
-           switch(state) {
-           case PS_START:
-           case PS_HAVE_LABEL:
-             fprintf(stderr,"  mnem\n");
-             cPmnem = tokArr[ltokIdx].tok.s;
-             state = PS_HAVE_MNEM;
-             break;
-           case PS_HAVE_MNEM:
-             fprintf(stderr,"  1st operand\n");
-             cP1stop = tokArr[ltokIdx].tok.s;
-             //pco1 = newpCodeOp(NULL,PO_GPR_REGISTER);
-             state = PS_HAVE_1OPERAND;
-             break;
-           case PS_HAVE_1OPERAND:
-             fprintf(stderr,"  error expecting comma\n");
-             break;
-           case PS_HAVE_COMMA:
-             fprintf(stderr,"  2 operands\n");
-             cP2ndop = tokArr[ltokIdx].tok.s;
-             break;
-           case PS_HAVE_2OPERANDS:
-             break;
-           }
-           break;
-
-         case  PCP_WILDVAR:
-           switch(state) {
-           case PS_START:
-           case PS_HAVE_LABEL:
-             fprintf(stderr,"  wild mnem\n");
-             state = PS_HAVE_MNEM;
-             break;
-           case PS_HAVE_MNEM:
-             fprintf(stderr,"  1st operand is wild\n");
-             state = PS_HAVE_1OPERAND;
-             break;
-           case PS_HAVE_1OPERAND:
-             fprintf(stderr,"  error expecting comma\n");
-             break;
-           case PS_HAVE_COMMA:
-             fprintf(stderr,"  2nd operand is wild\n");
-             break;
-           case PS_HAVE_2OPERANDS:
-             break;
-           }
-           break;
-
-         case  PCP_NUMBER:
-           switch(state) {
-           case PS_START:
-           case PS_HAVE_LABEL:
-             fprintf(stderr,"  ERROR number\n");
-             break;
-           case PS_HAVE_MNEM:
-             fprintf(stderr,"  1st operand is a number\n");
-             state = PS_HAVE_1OPERAND;
-             break;
-           case PS_HAVE_1OPERAND:
-             fprintf(stderr,"  error expecting comma\n");
-             break;
-           case PS_HAVE_COMMA:
-             fprintf(stderr,"  2nd operand is a number\n");
-             break;
-           case PS_HAVE_2OPERANDS:
-             break;
-           }
-           break;
-
-         case  PCP_WILDSTR:
-           break;
-         case  PCP_COMMA:
-           if(state == PS_HAVE_1OPERAND){
-             fprintf(stderr,"  got a comma\n");
-             state = PS_HAVE_COMMA;
-           } else
-             fprintf(stderr,"  unexpected comma\n");
+       pCode *pc;
+       int error = 0;
+       
+       if(!tokIdx)
+               return error;
+       
+#ifdef PCODE_DEBUG
+       {
+               unsigned i;
+               for(i=0; i<=tokIdx; i++)
+                       dump1Token(tokArr[i].tt);
+               fputc('\n',stderr);
+       }
+#endif
+       
+       {
+               int lparsedPatIdx=0;
+               int lpcpIdx;
+               int ltokIdx =0;
+               int matching = 0;
+               int j=0;
+               int k=0;
+               
+               char * cPmnem  = NULL;     // Pointer to non-wild mnemonic (if any)
+               char * cP1stop = NULL;
+               char * cP2ndop = NULL;
+               
+               //pCodeOp *pcl   = NULL;       // Storage for a label
+               //pCodeOp *pco1  = NULL;       // 1st operand
+               //pCodeOp *pco2  = NULL;       // 2nd operand
+               //pCode   *pc    = NULL;       // Mnemonic
+               
+               typedef enum {
+                       PS_START,
+                               PS_HAVE_LABEL,
+                               PS_HAVE_MNEM,
+                               PS_HAVE_1OPERAND,
+                               PS_HAVE_COMMA,
+                               PS_HAVE_2OPERANDS
+               } ParseStates;
+               
+               ParseStates state = PS_START;
+               
+               do {
+                       
+                       lpcpIdx=0;
+                       matching = 0;
+                       
+                       if(  ((tokArr[ltokIdx].tt == PCT_SPACE) )
+                               && (advTokIdx(&ltokIdx, 1)) ) // eat space
+                               break;
+                       
+                       do {
+                               j = pcComparePattern(&tokArr[ltokIdx], pcpArr[lpcpIdx].tokens, tokIdx +1);
+                               if( j ) {
+                                       
+                                       switch(pcpArr[lpcpIdx].pt) {
+                                       case  PCP_LABEL:
+                                               if(state == PS_START){
+                                                       DFPRINTF((stderr,"  label\n"));
+                                                       state = PS_HAVE_LABEL;
+                                               } else 
+                                                       DFPRINTF((stderr,"  bad state (%d) for label\n",state));
+                                               break;
+                                               
+                                       case  PCP_STR:
+                                               DFPRINTF((stderr,"  %s is",tokArr[ltokIdx].tok.s));
+                                               switch(state) {
+                                               case PS_START:
+                                               case PS_HAVE_LABEL:
+                                                       DFPRINTF((stderr,"  mnem\n"));
+                                                       cPmnem = tokArr[ltokIdx].tok.s;
+                                                       state = PS_HAVE_MNEM;
+                                                       break;
+                                               case PS_HAVE_MNEM:
+                                                       DFPRINTF((stderr,"  1st operand\n"));
+                                                       cP1stop = tokArr[ltokIdx].tok.s;
+                                                       //pco1 = newpCodeOp(NULL,PO_GPR_REGISTER);
+                                                       state = PS_HAVE_1OPERAND;
+                                                       break;
+                                               case PS_HAVE_1OPERAND:
+                                                       DFPRINTF((stderr,"  error expecting comma\n"));
+                                                       break;
+                                               case PS_HAVE_COMMA:
+                                                       DFPRINTF((stderr,"  2 operands\n"));
+                                                       cP2ndop = tokArr[ltokIdx].tok.s;
+                                                       break;
+                                               case PS_HAVE_2OPERANDS:
+                                                       break;
+                                               }
+                                               break;
+                                               
+                                               case  PCP_WILDVAR:
+                                                       switch(state) {
+                                                       case PS_START:
+                                                       case PS_HAVE_LABEL:
+                                                               DFPRINTF((stderr,"  wild mnem\n"));
+                                                               state = PS_HAVE_MNEM;
+                                                               break;
+                                                       case PS_HAVE_MNEM:
+                                                               DFPRINTF((stderr,"  1st operand is wild\n"));
+                                                               state = PS_HAVE_1OPERAND;
+                                                               break;
+                                                       case PS_HAVE_1OPERAND:
+                                                               DFPRINTF((stderr,"  error expecting comma\n"));
+                                                               break;
+                                                       case PS_HAVE_COMMA:
+                                                               DFPRINTF((stderr,"  2nd operand is wild\n"));
+                                                               break;
+                                                       case PS_HAVE_2OPERANDS:
+                                                               break;
+                                                       }
+                                                       break;
+                                                       
+                                                       case  PCP_NUMBER:
+                                                               switch(state) {
+                                                               case PS_START:
+                                                               case PS_HAVE_LABEL:
+                                                                       fprintf(stderr,"  ERROR number\n");
+                                                                       break;
+                                                               case PS_HAVE_MNEM:
+                                                                       DFPRINTF((stderr,"  1st operand is a number\n"));
+                                                                       state = PS_HAVE_1OPERAND;
+                                                                       break;
+                                                               case PS_HAVE_1OPERAND:
+                                                                       fprintf(stderr,"  error expecting comma\n");
+                                                                       break;
+                                                               case PS_HAVE_COMMA:
+                                                                       DFPRINTF((stderr,"  2nd operand is a number\n"));
+                                                                       break;
+                                                               case PS_HAVE_2OPERANDS:
+                                                                       break;
+                                                               }
+                                                               break;
+                                                               
+                                                               case  PCP_WILDSTR:
+                                                                       break;
+                                                               case  PCP_COMMA:
+                                                                       if(state == PS_HAVE_1OPERAND){
+                                                                               DFPRINTF((stderr,"  got a comma\n"));
+                                                                               state = PS_HAVE_COMMA;
+                                                                       } else
+                                                                               fprintf(stderr,"  unexpected comma\n");
+                                                                       break;
+                                                                       
+                                       }
+                                       
+                                       matching = 1;
+                                       parsedPatArr[lparsedPatIdx].pcp = &pcpArr[lpcpIdx];
+                                       parsedPatArr[lparsedPatIdx].pct = &tokArr[ltokIdx];
+                                       lparsedPatIdx++;
+                                       
+                                       //dump1Token(tokArr[ltokIdx].tt);
+                                       
+                                       if(advTokIdx(&ltokIdx, strlen(pcpArr[lpcpIdx].tokens) ) ) {
+                                               DFPRINTF((stderr," reached end \n"));
+                                               matching = 0;
+                                               //return;
+                                       }
+       }
+       
+       
+         } while ((++lpcpIdx < PCPATTERNS) && !matching);
+         
+       } while (matching);
+       
+       parsedPatArr[lparsedPatIdx].pcp = NULL;
+       parsedPatArr[lparsedPatIdx].pct = NULL;
+       
+       j=k=0;
+       do {
+               int c;
+               
+               if( (c=altComparePattern( altArr[k].tokens, &parsedPatArr[j],10) ) ) {
+                       
+                       if( altArr[k].f) {
+                               pc = altArr[k].f(&parsedPatArr[j],pcwb);
+                               //if(pc && pc->print)
+                               //  pc->print(stderr,pc);
+                               //if(pc && pc->destruct) pc->destruct(pc); dumps core?
+                               
+                               if(pc) {
+                                       if (pcret) {
+                                               *pcret = pc;
+                                               return 0;       // Only accept one line for now.
+                                       } else
+                                               addpCode2pBlock(pcwb->pb, pc);
+                               } else
+                                       error++;
+                       }
+                       j += c;
+               }
+               k++;
+       }
+       while(j<=lparsedPatIdx && k<ALTPATTERNS);
+       
+       /*
+       DFPRINTF((stderr,"\nConverting parsed line to pCode:\n\n"));
+       
+         j = 0;
+         do {
+         if(parsedPatArr[j].pcp && parsedPatArr[j].pcp->f )
+         parsedPatArr[j].pcp->f(&parsedPatArr[j]);
+         DFPRINTF((stderr,"  %d",parsedPatArr[j].pcp->pt));
+         j++;
          }
+         while(j<lparsedPatIdx);
+       */
+       DFPRINTF((stderr,"\n"));
+       
+  }
 
-         matching = 1;
-         parsedPatArr[lparsedPatIdx].pcp = &pcpArr[lpcpIdx];
-         parsedPatArr[lparsedPatIdx].pct = &tokArr[ltokIdx];
-         lparsedPatIdx++;
-
-         //dump1Token(tokArr[ltokIdx].tt);
+  return error;
+}
 
-         if(advTokIdx(&ltokIdx, strlen(pcpArr[lpcpIdx].tokens) ) ) {
-           fprintf(stderr," reached end \n");
-           matching = 0;
-           //return;
-         }
+/*-----------------------------------------------------------------*/
+/*                                                                 */
+/*-----------------------------------------------------------------*/
+static void peepRuleBlock2pCodeBlock(lineNode *ln, pCodeWildBlock *pcwb)
+{
+       
+       if(!ln)
+               return;
+       
+       for( ; ln; ln = ln->next) {
+               
+               //DFPRINTF((stderr,"%s\n",ln->line));
+               
+               tokenizeLineNode(ln->line);
+               
+               if(parseTokens(pcwb,NULL)) {
+                       int i;
+                       fprintf(stderr,"ERROR assembling line:\n%s\n",ln->line);
+                       fprintf(stderr,"Tokens:\n");
+                       for(i=0; i<5; i++)
+                               dump1Token(tokArr[i].tt);
+                       fputc('\n',stderr);
+                       exit (1);
+               }
        }
+}
 
-
-      } while ((++lpcpIdx < PCPATTERNS) && !matching);
-
-    } while (matching);
-
-    parsedPatArr[lparsedPatIdx].pcp = NULL;
-    parsedPatArr[lparsedPatIdx].pct = NULL;
-
-    j=k=0;
-    do {
-      int c;
-
-      if( (c=altComparePattern( altArr[k].tokens, &parsedPatArr[j],10) ) ) {
-
-       if( altArr[k].f) {
-         pc = altArr[k].f(&parsedPatArr[j]);
-         if(pc && pc->print)
-           pc->print(stderr,pc);
-         //if(pc && pc->destruct) pc->destruct(pc); dumps core?
+/*-----------------------------------------------------------------*/
+/* peepRuleCondition                                               */
+/*-----------------------------------------------------------------*/
+static void   peepRuleCondition(char *cond, pCodePeep *pcp)
+{
+       if(!cond || !pcp)
+               return;
+       
+       //DFPRINTF((stderr,"\nCondition:  %s\n",cond));
+       /* brute force compares for now */
+       
+       if(STRCASECMP(cond, "NZ") == 0) {
+               //DFPRINTF((stderr,"found NZ\n"));
+               pcp->postFalseCond = PCC_Z;
+               
        }
-       j += c;
-      }
-      k++;
-    }
-    while(j<=lparsedPatIdx && k<ALTPATTERNS);
-
-/*
-    fprintf(stderr,"\nConverting parsed line to pCode:\n\n");
-
-    j = 0;
-    do {
-      if(parsedPatArr[j].pcp && parsedPatArr[j].pcp->f )
-       parsedPatArr[j].pcp->f(&parsedPatArr[j]);
-      fprintf(stderr,"  %d",parsedPatArr[j].pcp->pt);
-      j++;
-    }
-    while(j<lparsedPatIdx);
-*/
-    fprintf(stderr,"\n");
+       
+}
 
-  }
+static void initpCodeWildBlock(pCodeWildBlock *pcwb)
+{
+       
+       //  pcwb = Safe_calloc(1,sizeof(pCodeWildBlock));
+       
+       if(!pcwb)
+               return;
+       
+       pcwb->vars = NULL; 
+       pcwb->wildpCodes = NULL;
+       pcwb->wildpCodeOps = NULL;
+       
+       pcwb->nvars = 0; 
+       pcwb->nwildpCodes = 0;
+       pcwb->nops = 0;
+       
+}
 
+static void postinit_pCodeWildBlock(pCodeWildBlock *pcwb)
+{
+       
+       if(!pcwb)
+               return;
+       
+       pcwb->nvars+=2;
+       pcwb->nops = pcwb->nvars;
+       
+       pcwb->vars = Safe_calloc(pcwb->nvars, sizeof(char *));
+       pcwb->wildpCodeOps = Safe_calloc(pcwb->nvars, sizeof(pCodeOp *));
+       
+       pcwb->nwildpCodes+=2;
+       pcwb->wildpCodes = Safe_calloc(pcwb->nwildpCodes, sizeof(pCode *));
+       
+}
 
+static void initpCodePeep(pCodePeep *pcp)
+{
+       
+       //  pcwb = Safe_calloc(1,sizeof(pCodeWildBlock));
+       
+       if(!pcp)
+               return;
+       
+       initpCodeWildBlock(&pcp->target);
+       pcp->target.pb = newpCodeChain(NULL, 'W', NULL);
+       
+       initpCodeWildBlock(&pcp->replace);
+       pcp->replace.pb = newpCodeChain(NULL, 'W', NULL);
+       
 }
 
 /*-----------------------------------------------------------------*/
@@ -947,57 +1218,76 @@ void dumpTokens(void)
 /* taking raw text to produce machine code, it produces pCode.     */
 /*                                                                 */
 /*-----------------------------------------------------------------*/
-
-void  peepRules2pCode(peepRule *rules)
+void peepRules2pCode(peepRule *rules)
 {
-  peepRule *pr;
-  lineNode *ln;
-
-  pCodePeepSnippets *pcps;
-
-  for (pr = rules; pr; pr = pr->next) {
-    fprintf(stderr,"\nRule:\n\n");
-
-    pcps = Safe_calloc(1,sizeof(pCodePeepSnippets));
-    curPeep = pcps->peep  = Safe_calloc(1,sizeof(pCodePeep));
-    //curPeep->target = curPeep->replace = NULL;
-    curPeep->vars = NULL; curPeep->wildpCodes = NULL;
-    peepSnippets = DLL_append((_DLL*)peepSnippets,(_DLL*)pcps);
-
-    curPeep->target = curBlock = newpCodeChain(NULL, 'W', NULL);
-
-    for(ln = pr->match; ln; ln = ln->next) {
-
-      fprintf(stderr,"%s\n",ln->line);
-
-      parseLineNode(ln->line);
-      dumpTokens();
-
-    }
-
-    fprintf(stderr,"\nReplaced by:\n");
-
-    curPeep->replace = curBlock = newpCodeChain(NULL, 'W', NULL);
-
-    for(ln = pr->replace; ln; ln = ln->next)
-      fprintf(stderr,"%s\n",ln->line);
-
-    if(pr->cond)
-      fprintf(stderr,"\nCondition:  %s\n",pr->cond);
-
-    return;
-  }
-
-}
-
-void printpCodeString(FILE *of, pCode *pc, int max)
-{
-  int i=0;
-
-  while(pc && (i++<max)) {
-    pc->print(of,pc);
-    pc = pc->next;
-  }
+       peepRule *pr;
+       
+       pCodePeep *currentRule;
+       pCodePeepSnippets *pcps;
+       
+       pic14initpCodePeepCommands();
+       
+       /* The rules are in a linked-list. Each rule has two portions */
+       /* There's the `target' and there's the `replace'. The target */
+       /* is compared against the SDCC generated code and if it      */
+       /* matches, it gets replaced by the `replace' block of code.  */
+       /*                                                            */
+       /* Here we loop through each rule and convert the target's and*/
+       /* replace's into pCode target and replace blocks             */
+       
+       for (pr = rules; pr; pr = pr->next) {
+               
+               //DFPRINTF((stderr,"\nRule:\n\n"));
+               
+               pcps = Safe_calloc(1,sizeof(pCodePeepSnippets));
+               peepSnippets = DLL_append((_DLL*)peepSnippets,(_DLL*)pcps);
+               
+               currentRule = pcps->peep  = Safe_calloc(1,sizeof(pCodePeep));
+               initpCodePeep(currentRule);
+               
+               /* Convert the target block */
+               peepRuleBlock2pCodeBlock(pr->match, &currentRule->target);
+               
+               //DFPRINTF((stderr,"finished target, here it is in pcode form:\n"));
+               //printpBlock(stderr, currentRule->target.pb);
+               
+               pBlockMergeLabels(currentRule->target.pb);
+               //printpBlock(stderr, currentRule->replace.pb);
+               
+               /* Convert the replace block */
+               peepRuleBlock2pCodeBlock(pr->replace, &currentRule->replace);
+               
+               //DFPRINTF((stderr,"replace with labels merged:\n"));
+               
+               pBlockMergeLabels(currentRule->replace.pb);
+               //printpBlock(stderr, currentRule->replace.pb);
+               
+               peepRuleCondition(pr->cond,currentRule);
+               
+               /* The rule has been converted to pCode. Now allocate
+               * space for the wildcards */
+               
+               postinit_pCodeWildBlock(&currentRule->target);
+               postinit_pCodeWildBlock(&currentRule->replace);
+               
+               //return; // debug ... don't want to go through all the rules yet
+       }
+       
+       {
+               pCodePeep *peepBlock;
+               _DLL *peeprules;
+               
+               peeprules = (_DLL *)peepSnippets;
+               //fprintf(stderr,"target rules\n");
+               while(peeprules) {
+                       //fprintf(stderr,"   rule:\n");
+                       peepBlock = ((pCodePeepSnippets*)peeprules)->peep;
+                       //printpBlock(stderr, peepBlock->target.pb);
+                       peeprules = peeprules->next;
+               }
+               //fprintf(stderr," ... done\n");
+       }
+       
 }
 
 /*-----------------------------------------------------------------*/
@@ -1012,29 +1302,29 @@ void printpCodeString(FILE *of, pCode *pc, int max)
 
 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;
-  
+       _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;
+       
 }  
 
 
@@ -1042,223 +1332,19 @@ static void * DLL_append(_DLL *list, _DLL *next)
 
   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...
+                 
+-----------------------------------------------------------------*/
 
-  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)
-{
-#if 0
-  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);
-
-  {
-    /*
-      target:
-
-          btfsc  %0
-           goto  %1
-          %3
-      %1: %4
-
-      replace:
-          btfss  %0
-      %1:  %4
-          %3
-
-         The %3 and %4 are wild opcodes. Since the opcodes
-         are stored in a different array than the wild operands,
-         they can have the same indices and not conflict. So
-         below, the %3 is really a %0, %4 is a %1.
-
-     */
-    pCodeOp *pcl;
-    pCodeOp *pcw;
-    pCodeOp *pcwb;
-
-    // Create a new wild operand subtyped as a bit
-    pcwb =  newpCodeOpWild(0,pcp,newpCodeOpBit(NULL,-1));
-
-    // Create a 
-    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;
-  }
-
-
-
-#endif
-}
 
 /*-----------------------------------------------------------------*/
 /* pCodeSearchCondition - Search a pCode chain for a 'condition'   */
@@ -1269,455 +1355,660 @@ void pCodePeepInit(void)
 /* -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 pCodeSearchCondition(pCode *pc, unsigned int cond, int contIfSkip)
 {
-  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;
-           }
-         }
+       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) {
+                               if (contIfSkip) {
+                                       /* If previous instruction is a skip then continue search as condiction is not certain */
+                                       pCode *pcp = findPrevInstruction(pc->prev);
+                                       if (pcp && !isPCI_SKIP(pcp)) {
+                                               return 1;
+                                       }
+                               } else {
+                                       return 1;
+                               }
+                       }
+                       if(PCI(pc)->outCond & cond) {
+                               if (contIfSkip) {
+                                       /* If previous instruction is a skip then continue search as condiction is not certain */
+                                       pCode *pcp = findPrevInstruction(pc->prev);
+                                       if (pcp && !isPCI_SKIP(pcp)) {
+                                               return -1;
+                                       }
+                               } else {
+                                       return -1;
+                               }
+                       }
+               }
+               
+               pc = pc->next;
        }
-      } 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;
+/*-----------------------------------------------------------------
+* int pCodeOpCompare(pCodeOp *pcops, pCodeOp *pcopd)
+*
+* Compare two pCodeOp's and return 1 if they're the same
+*-----------------------------------------------------------------*/
+static int pCodeOpCompare(pCodeOp *pcops, pCodeOp *pcopd)
+{
+       char b[50], *n2;
+       
+       if(!pcops || !pcopd)
+               return 0;
+               /*
+               fprintf(stderr," Comparing operands %s",
+               get_op( pcops,NULL,0));
+               
+                 fprintf(stderr," to %s\n",
+                 get_op( pcopd,NULL,0));
+       */
+       
+       if(pcops->type != pcopd->type) {
+               //fprintf(stderr,"  - fail - diff types\n");
+               return 0;  // different types
+       }
+       
+       if(pcops->type == PO_LITERAL) {
+               
+               if((PCOL(pcops)->lit >= 0) && (PCOL(pcops)->lit == PCOL(pcopd)->lit))
+                       return 1;
+               
+               return 0;
+       }
+       
+       b[0]=0;
+       get_op(pcops,b,50);
+       
+       n2 = get_op(pcopd,NULL,0);
+       
+       if( !n2 || strcmp(b,n2)) {
+               //fprintf(stderr,"  - fail - diff names: %s, len=%d,  %s, len=%d\n",b,strlen(b), n2, strlen(n2) );
+               return 0;  // different names
        }
-       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);
+       
+       switch(pcops->type) {
+       case PO_DIR:
+               if( PCOR(pcops)->instance != PCOR(pcopd)->instance) {
+                       //fprintf(stderr, "  - fail different instances\n");
+                       return 0;
+               }
+               break;
+       default:
+               break;
        }
-       return i;
-      } else {
-       peepBlock->vars[index] = PCI(pcs)->pcop->name;
+       
+       //fprintf(stderr,"  - pass\n");
+       
        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)
+static int pCodePeepMatchLabels(pCodePeep *peepBlock, pCode *pcs, pCode *pcd)
 {
-
-  int i;
-  if(!pcp)
-    return;
-
-  for(i=0;i<pcp->nvars; i++)
-    pcp->vars[i] = NULL;
+       int labindex;
+       
+       /* Check for a label associated with this wild pCode */
+       // If the wild card has a label, make sure the source code does too.
+       if(PCI(pcd)->label) {
+               pCode *pcl = PCI(pcd)->label->pc;
+               
+#ifdef PCODE_DEBUG
+               int li = -PCL(pcl)->key;
+               
+               if(peepBlock->target.vars[li] == NULL) {
+                       if(PCI(pcs)->label) {
+                               DFPRINTF((stderr,"first time for a label: %d %s\n",li,PCL(PCI(pcs)->label->pc)->label));
+                       }
+               } else {
+                       // DFPRINTF((stderr,"label id = %d \n",PCL(PCI(pcd)->label->pc)->key));
+                       DFPRINTF((stderr," label id: %d %s\n",li,peepBlock->target.vars[li]));
+                       if(PCI(pcs)->label) {
+                               DFPRINTF((stderr," src %s\n",PCL(PCI(pcs)->label->pc)->label));
+                       }
+               }
+#endif
+               
+               
+               if(!PCI(pcs)->label)
+                       return 0;
+               
+               labindex = -PCL(pcl)->key;
+               if(peepBlock->target.vars[labindex] == NULL) {
+                       // First time to encounter this label
+                       peepBlock->target.vars[labindex] = PCL(PCI(pcs)->label->pc)->label;
+                       DFPRINTF((stderr,"first time for a label: %d %s\n",labindex,PCL(PCI(pcs)->label->pc)->label));
+                       
+               } else {
+                       if(strcmp(peepBlock->target.vars[labindex],PCL(PCI(pcs)->label->pc)->label) != 0) {
+                               DFPRINTF((stderr,"labels don't match dest %s != src %s\n",peepBlock->target.vars[labindex],PCL(PCI(pcs)->label->pc)->label));
+                               return 0;
+                       }
+                       DFPRINTF((stderr,"matched a label %d %s -hey\n",labindex,peepBlock->target.vars[labindex]));
+               }
+       } else {
+               //DFPRINTF((stderr,"destination doesn't have a label\n"));
+               
+               if(PCI(pcs)->label)
+                       return 0;
+               
+               //DFPRINTF((stderr,"neither src nor dest have labels\n"));
+               
+       }
+       
+       return 1;
 
 }
 
 /*-----------------------------------------------------------------*/
+/* pCodePeepMatchLine - Compare source and destination pCodes to   */
+/*                      see they're the same.                      */
+/*                                                                 */
+/* In this context, "source" refers to the coded generated by gen.c*/
+/* and "destination" refers to a pcode in a peep rule. If the dest-*/
+/* ination has no wild cards, then MatchLine will compare the two  */
+/* pcodes (src and dest) for a one-to-one match. If the destination*/
+/* has wildcards, then those get expanded. When a wild card is     */
+/* encountered for the first time it autmatically is considered a  */
+/* match and the object that matches it is referenced in the       */
+/* variables or opcodes array (depending on the type of match).    */
+/*                                                                 */
+/*                                                                 */
+/* Inputs:                                                         */
+/*  *peepBlock - A pointer to the peepBlock that contains the      */
+/*               entire rule to which the destination pcode belongs*/
+/*  *pcs - a pointer to the source pcode                           */
+/*  *pcd - a pointer to the destination pcode                      */
+/*                                                                 */
+/* Returns:                                                        */
+/*  1 - pcodes match                                               */
+/*  0 - pcodes don't match                                         */
+/*                                                                 */
+/*                                                                 */
 /*-----------------------------------------------------------------*/
-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)
+static int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd)
 {
-  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) );
+       int index;   // index into wild card arrays
+       
+       /* one-for-one match. Here the source and destination opcodes 
+       * are not wild. However, there may be a label or a wild operand */
+       
+       if(pcs) {
+               if(PCI(pcs)->label) {
+                       DFPRINTF((stderr,"Match line source label: %s\n",PCL(PCI(pcs)->label->pc)->label));
+               }
+       }
+       
+       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;
+                       
+#ifdef PCODE_DEBUG
+                       DFPRINTF((stderr,"%s comparing\n",__FUNCTION__));
+                       pcs->print(stderr,pcs);
+                       pcd->print(stderr,pcd);
+#endif
+                       
+                       if(!pCodePeepMatchLabels(peepBlock, pcs, pcd))
+                               return 0;
+                       
+                       /* Compare the operands */
+                       if(PCI(pcd)->pcop) {
+                               // Volatile types should not be deleted or modified, these include SFR, externs and publics
+                               // They can be used as a matched, however if a match is found then the optimiser intends
+                               // to change some aspect of a block of code, which is most likely a critcal one. As this
+                               // method of optimisation does not allow a means to distiguishing what may change, it is
+                               // best to just negate any match.
+                               if (PCI(pcs)->pcop) {
+                                       struct regs *r;
+                                       pCodeOp *pcop = PCI(pcs)->pcop;
+                                       switch(pcop->type) {
+                                       case PO_W:
+                                       case PO_STATUS:
+                                       case PO_FSR:
+                                       case PO_INDF:
+                                       case PO_INTCON:
+                                       case PO_PCL:
+                                       case PO_PCLATH:
+                                       case PO_SFR_REGISTER:
+                                               return 0; // SFR - do not modify
+                                       case PO_DIR:
+                                       case PO_GPR_REGISTER:
+                                       case PO_GPR_BIT:
+                                       case PO_GPR_TEMP:
+                                       case PO_GPR_POINTER:
+                                               r = PCOR(pcop)->r;
+                                               if (r->isPublic||r->isExtern||r->isFixed) // Changes to these types of registers should not be changed as they may be used else where
+                                                       return 0;
+                                       default:
+                                               break;
+                                       }
+                               }
+                               if (PCI(pcd)->pcop->type == PO_WILD) {
+                                       char *n;
+                                       index = PCOW(PCI(pcd)->pcop)->id;
+                                       //DFPRINTF((stderr,"destination is wild\n"));
+#ifdef DEBUG_PCODEPEEP
+                                       if (index > peepBlock->nops) {
+                                               DFPRINTF((stderr,"%s - variables exceeded\n",__FUNCTION__));
+                                               exit(1);
+                                       }
+#endif
+                                       n = PCI(pcs)->pcop->name;
+                                       if(peepBlock->target.vars[index]) {
+                                               if ((!n)||(strcmp(peepBlock->target.vars[index],n) != 0))
+                                                       return 0; // variable is different
+                                       } else {
+                                               DFPRINTF((stderr,"first time for a variable: %d, %s\n",index,n));
+                                               peepBlock->target.vars[index] = n;
+                                       }
+                                       
+                                       PCOW(PCI(pcd)->pcop)->matched = PCI(pcs)->pcop;
+                                       if(!peepBlock->target.wildpCodeOps[index]) {
+                                               peepBlock->target.wildpCodeOps[index] = PCI(pcs)->pcop;
+                                               
+                                               //fprintf(stderr, "first time for wild opcode #%d\n",index);
+                                               return 1;
+                                               
+                                       } else {
+                                       /*
+                                       pcs->print(stderr,pcs);
+                                       pcd->print(stderr,pcd);
+                                       fprintf(stderr, "comparing operands of these instructions, result %d\n",
+                                       pCodeOpCompare(PCI(pcs)->pcop, peepBlock->target.wildpCodeOps[index])
+                                       );
+                                       */
+                                               
+                                               return pCodeOpCompare(PCI(pcs)->pcop, peepBlock->target.wildpCodeOps[index]);
+                                       }
+                                       /*
+                                       {
+                                               char *n;
+                                       
+                                               switch(PCI(pcs)->pcop->type) {
+                                               case PO_GPR_TEMP:
+                                               case PO_FSR:
+                                               //case PO_INDF:
+                                                       //n = PCOR(PCI(pcs)->pcop)->r->name;
+                                                       n = PCI(pcs)->pcop->name;
+
+                                               break;
+                                               default:
+                                                       n = PCI(pcs)->pcop->name;
+                                               }
+                                               
+                                               if(peepBlock->target.vars[index])
+                                                       return  (strcmp(peepBlock->target.vars[index],n) == 0);
+                                               else {
+                                                       DFPRINTF((stderr,"first time for a variable: %d, %s\n",index,n));
+                                                       peepBlock->target.vars[index] = n;
+                                                       return 1;
+                                               }
+                                       }
+                                       */
+                               } else if (PCI(pcd)->pcop->type == PO_LITERAL) {
+                               /*
+                               pcs->print(stderr,pcs);
+                               pcd->print(stderr,pcd);
+                               
+                               fprintf(stderr, "comparing literal operands of these instructions, result %d\n",
+                               pCodeOpCompare(PCI(pcs)->pcop, PCI(pcd)->pcop));
+                               */
+                                       return pCodeOpCompare(PCI(pcs)->pcop, PCI(pcd)->pcop);
+                                       
+                               } else {
+                                       /* FIXME - need an else to check the case when the destination 
+                                               * isn't a wild card */
+                                       /*
+                                       fprintf(stderr, "Destination is not wild: operand compare =%d\n",
+                                       pCodeOpCompare(PCI(pcs)->pcop, PCI(pcd)->pcop));
+                                       */
+                                       return  pCodeOpCompare(PCI(pcs)->pcop, PCI(pcd)->pcop);
+
+                               }
+                       } else
+                               /* The pcd has no operand. Lines match if pcs has no operand either*/
+                               return (PCI(pcs)->pcop == NULL);
+               }
+       }
 
-  }
+       /* Compare a wild instruction to a regular one. */
+
+       if((pcd->type == PC_WILD) && (pcs->type == PC_OPCODE)) {
 
-  pcopnew->type = pcop->type;
-  pcopnew->name = Safe_strdup(pcop->name);
+               index = PCW(pcd)->id;
+#ifdef PCODE_DEBUG
+               DFPRINTF((stderr,"%s comparing wild cards\n",__FUNCTION__));
+               pcs->print(stderr,pcs);
+               pcd->print(stderr,pcd);
+#endif
+               peepBlock->target.wildpCodes[PCW(pcd)->id] = pcs;
+         
+               if(!pCodePeepMatchLabels(peepBlock, pcs, pcd)) {
+                       DFPRINTF((stderr," Failing because labels don't match\n"));
+                       return 0;
+               }
+
+               if(PCW(pcd)->mustBeBitSkipInst & !(PCI(pcs)->isBitInst && PCI(pcs)->isSkip)) {
+                       // doesn't match because the wild pcode must be a bit skip
+                       DFPRINTF((stderr," Failing match because bit skip is req\n"));
+                       //pcd->print(stderr,pcd);
+                       //pcs->print(stderr,pcs);
+                       return 0;
+               } 
+
+               if(PCW(pcd)->mustNotBeBitSkipInst & (PCI(pcs)->isBitInst && PCI(pcs)->isSkip)) {
+                       // doesn't match because the wild pcode must *not* be a bit skip
+                       DFPRINTF((stderr," Failing match because shouldn't be bit skip\n"));
+                       //pcd->print(stderr,pcd);
+                       //pcs->print(stderr,pcs);
+                       return 0;
+               } 
+
+               if(PCW(pcd)->operand) {
+                       PCOW(PCI(pcd)->pcop)->matched = PCI(pcs)->pcop;
+                       if(peepBlock->target.vars[index]) {
+                               int i = (strcmp(peepBlock->target.vars[index],PCI(pcs)->pcop->name) == 0);
+#ifdef PCODE_DEBUG
+
+                               if(i)
+                                       DFPRINTF((stderr," (matched)\n"));
+                               else {
+                                       DFPRINTF((stderr," (no match: wild card operand mismatch\n"));
+                                       DFPRINTF((stderr,"  peepblock= %s,  pcodeop= %s\n",
+                                               peepBlock->target.vars[index],
+                                               PCI(pcs)->pcop->name));
+                               }
+#endif
+                               return i;
+                       } else {
+                               DFPRINTF((stderr," (matched %s\n",PCI(pcs)->pcop->name));
+                               peepBlock->target.vars[index] = PCI(pcs)->pcop->name;
+                               return 1;
+                       }
+               }
+
+               pcs = findNextInstruction(pcs->next); 
+               if(pcs) {
+                       //DFPRINTF((stderr," (next to match)\n"));
+                       //pcs->print(stderr,pcs);
+               } else if(pcd->next) {
+                       /* oops, we ran out of code, but there's more to the rule */
+                       return 0;
+               }
+
+               return 1; /*  wild card matches */
+       }
 
-  return pcopnew;
+       return 0;
 }
 
-#if 0
 /*-----------------------------------------------------------------*/
-/* pCodeCopy - copy a pcode                                        */
 /*-----------------------------------------------------------------*/
-static pCode *pCodeCopy(pCode *pc)
+static void pCodePeepClrVars(pCodePeep *pcp)
 {
-
-  pCode *pcnew;
-
-  pcnew = newpCode(pc->type,pc->pcop);
+       
+       int i;
+       if(!pcp)
+               return;
+       /*
+       DFPRINTF((stderr," Clearing peep rule vars\n"));
+       DFPRINTF((stderr," %d %d %d  %d %d %d\n",
+       pcp->target.nvars,pcp->target.nops,pcp->target.nwildpCodes,
+       pcp->replace.nvars,pcp->replace.nops,pcp->replace.nwildpCodes));
+       */
+       for(i=0;i<pcp->target.nvars; i++)
+               pcp->target.vars[i] = NULL;
+       for(i=0;i<pcp->target.nops; i++)
+               pcp->target.wildpCodeOps[i] = NULL;
+       for(i=0;i<pcp->target.nwildpCodes; i++)
+               pcp->target.wildpCodes[i] = NULL;
+       
+       for(i=0;i<pcp->replace.nvars; i++)
+               pcp->replace.vars[i] = NULL;
+       for(i=0;i<pcp->replace.nops; i++)
+               pcp->replace.wildpCodeOps[i] = NULL;
+       for(i=0;i<pcp->replace.nwildpCodes; i++)
+               pcp->replace.wildpCodes[i] = NULL;
+       
+       
+       
 }
-#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;
-    if(!peepBlock || !peepBlock->target || !peepBlock->target->pcHead)
-      goto next_rule;
-
-    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);
-         fprintf(stderr,"inserting pCode\n");
-         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;
-    }
-  next_rule:
-    peeprules = peeprules->next;
-  }
-
-  return 0;
-}
-
-
-
-
-
-
-
-
-
-
+       pCodePeep *peepBlock;
+       pCode *pct, *pcin;
+       pCodeCSource *pc_cline=NULL;
+       _DLL *peeprules;
+       int matched;
+       
+       peeprules = (_DLL *)peepSnippets;
+       
+       while(peeprules) {
+               peepBlock = ((pCodePeepSnippets*)peeprules)->peep;
+               
+               if(!peepBlock || /*!peepBlock->target ||*/ !peepBlock->target.pb->pcHead) {
+                       fprintf(stderr, "skipping rule because target pb is NULL\n");
+                       goto next_rule;
+               }
+               
+               pCodePeepClrVars(peepBlock);
+               /*
+               pcin = pc;
+               if(IS_PCCOMMENT(pcin))
+               pc = pcin = findNextInstruction(pcin->next);
+               */
+               pcin = pc = findNextInstruction(pc);
+               
+               pct = peepBlock->target.pb->pcHead;
+#ifdef PCODE_DEBUG
+               {
+                       pCode *pcr = peepBlock->replace.pb->pcHead;
+                       if(pcr) pct->print(stderr,pcr);
+               }
+#endif
+               matched = 0;
+               while(pct && pcin) {
+                       
+                       if(! (matched = pCodePeepMatchLine(peepBlock, pcin,pct)))
+                               break;
+                       
+                       pcin = findNextInstruction(pcin->next);
+                       pct = pct->next;
+                       //debug:
+                       //DFPRINTF((stderr,"    matched\n"));
+                       
+                       if(!pcin && pct) {
+                               DFPRINTF((stderr," partial match... no more code\n"));
+                               matched = 0; 
+                       }
+                       if(!pct) {
+                               DFPRINTF((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
+               */
+                       DFPRINTF((stderr,"    matched rule so far, now checking conditions\n"));
+                       //pcin->print(stderr,pcin);
+                       
+                       if (pcin && peepBlock->postFalseCond && 
+                               (pCodeSearchCondition(pcin,peepBlock->postFalseCond,0) > 0) )
+                               matched = 0;
+                       
+                       //fprintf(stderr," condition results = %d\n",pCodeSearchCondition(pcin,peepBlock->postFalseCond));
+                       
+                       
+                       //if(!matched) fprintf(stderr,"failed on conditions\n");
+               }
+               
+               if(matched) {
+                       
+                       pCode *pcprev;
+                       pCode *pcr, *pcout;
+                       
+                       
+                       /* We matched a rule! Now we have to go through and remove the
+                       inefficient code with the optimized version */
+#ifdef PCODE_DEBUG
+                       DFPRINTF((stderr, "Found a pcode peep match:\nRule:\n"));
+                       //printpCodeString(stderr,peepBlock->target.pb->pcHead,10);
+                       DFPRINTF((stderr,"first thing matched\n"));
+                       pc->print(stderr,pc);
+                       if(pcin) {
+                               DFPRINTF((stderr,"last thing matched\n"));
+                               pcin->print(stderr,pcin);
+                       }
+#endif
+                       
+                       
+                       /* Unlink the original code */
+                       pcout = pc;
+                       pcprev = pc->prev;
+                       pcprev->next = pcin;
+                       if(pcin) 
+                               pcin->prev = pc->prev;
+                       
+                       
 #if 0
-/*******************/
-pCode *parseLineNode(char *ln)
-{
-  char buffer[50], *s;
-  int state=0;          //0 label, 1 mnemonic, 2 operand, 3 operand, 4 comment
-  int var;
-  pCode *pc = NULL;
-  //  pCodeLabel *pcl = NULL;
-
-  if(!ln || !*ln)
-    return pc;
-
-  s = buffer;
-  *s = 0;
-
-  while(*ln) {
-
-    /* skip white space */
-    while (isspace (*ln))
-      ln++;
-
-    switch(state) {
-
-    case 0:   // look for a label
-    case 1:   // look for mnemonic
-
-      if(*ln == '%') {
-
-       // Wild
-
-       ln++;
-       if(!isdigit(*ln) )
-         break;
-         //goto next_state;
-
-       var = strtol(ln, &ln, 10);
-       if(*ln  == ':') {
-         // valid wild card label
-         fprintf(stderr, " wildcard label: %d\n",var);
-         ln++;
-       } else
-         fprintf(stderr, " wild opcode: %d\n",var), state++;
-
-      } else {
-       // not wild
-       // Extract the label/mnemonic from the line
-
-       s = buffer;
-       while(*ln && !(isspace(*ln) || *ln == ':'))
-         *s++ = *ln++;
-
-       *s = 0;
-       if(*ln == ':')
-         fprintf(stderr," regular label: %s\n",buffer), ln++;
-       else
-         fprintf(stderr," regular mnem: %s\n",buffer), state++;
-      }
-      state++;
-      break;
-
-    default:
-      ln++;
-
-    }
-  }
+                       {
+                               /*     DEBUG    */
+                               /* Converted the deleted pCodes into comments */
+                               
+                               char buf[256];
+                               pCodeCSource *pc_cline2=NULL;
+                               
+                               buf[0] = ';';
+                               buf[1] = '#';
+                               
+                               while(pc &&  pc!=pcin) {
+                                       
+                                       if(pc->type == PC_OPCODE && PCI(pc)->cline) {
+                                               if(pc_cline) {
+                                                       pc_cline2->pc.next = PCODE(PCI(pc)->cline);
+                                                       pc_cline2 = PCCS(pc_cline2->pc.next);
+                                               } else {
+                                                       pc_cline = pc_cline2 = PCI(pc)->cline;
+                                                       pc_cline->pc.seq = pc->seq;
+                                               }
+                                       }
+                                       
+                                       pCode2str(&buf[2], 254, pc);
+                                       pCodeInsertAfter(pcprev, newpCodeCharP(buf));
+                                       pcprev = pcprev->next;
+                                       pc = pc->next;
+                                       
+                               }
+                               if(pc_cline2)
+                                       pc_cline2->pc.next = NULL;
+                       }
+#endif
+                       
+                       if(pcin)
+                               pCodeDeleteChain(pc,pcin);
+                       
+                       /* Generate the replacement code */
+                       pc = pcprev;
+                       pcr = peepBlock->replace.pb->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) {
+                                       /* The replacing instruction has an operand.
+                                               * Is it wild? */
+                                               if(PCI(pcr)->pcop->type == PO_WILD) {
+                                                       int index = PCOW(PCI(pcr)->pcop)->id;
+                                                       //DFPRINTF((stderr,"copying wildopcode\n"));
+                                                       if(peepBlock->target.wildpCodeOps[index])
+                                                               pcop = pCodeOpCopy(peepBlock->target.wildpCodeOps[index]);
+                                                       else
+                                                               DFPRINTF((stderr,"error, wildopcode in replace but not source?\n"));
+                                               } else
+                                                       pcop = pCodeOpCopy(PCI(pcr)->pcop);
+                                       }
+                                       //DFPRINTF((stderr,"inserting pCode\n"));
+                                       pCodeInsertAfter(pc, newpCode(PCI(pcr)->op,pcop));
+                               } else if (pcr->type == PC_WILD) {
+                                       if(PCW(pcr)->invertBitSkipInst)
+                                               DFPRINTF((stderr,"We need to invert the bit skip instruction\n"));
+                                       pCodeInsertAfter(pc,
+                                               pCodeInstructionCopy(PCI(peepBlock->target.wildpCodes[PCW(pcr)->id]),
+                                               PCW(pcr)->invertBitSkipInst));
+                               } else if (pcr->type == PC_COMMENT) {
+                                       pCodeInsertAfter(pc, newpCodeCharP( ((pCodeComment *)(pcr))->comment));
+                               }
+
+                               pc = pc->next;
+#ifdef PCODE_DEBUG
+                               DFPRINTF((stderr,"  NEW Code:"));
+                               if(pc) pc->print(stderr,pc);
+#endif
+                               pcr = pcr->next;
+                       }
+                       
+                       /* We have just replaced the inefficient code with the rule.
+                       * Now, we need to re-add the C-source symbols if there are any */
+                       pc = pcprev;
+                       while(pc && pc_cline ) {
+                               
+                               pc =  findNextInstruction(pc->next);
+                               if (!pc) break;
+                               PCI(pc)->cline = pc_cline;
+                               pc_cline = PCCS(pc_cline->pc.next);
+                               
+                       }
+                       
+                       /* Copy C code comments to new code. */
+                       pc = pcprev->next;
+                       if (pc) {
+                               for (; pc && pcout!=pcin; pcout=pcout->next) {
+                                       if (pcout->type==PC_OPCODE && PCI(pcout)->cline) {
+                                               while (pc->type!=PC_OPCODE || PCI(pc)->cline) {
+                                                       pc = pc->next;
+                                                       if (!pc)
+                                                               break;
+                                               }
+                                               if (!pc) break;
+                                               PCI(pc)->cline = PCI(pcout)->cline;
+                                       }
+                               }
+                       }
+                               
+                       return 1;
+               }
+next_rule:
+               peeprules = peeprules->next;
+       }
+       DFPRINTF((stderr," no rule matched\n"));
 
-  return pc;
-  
+       return 0;
 }
-#endif