More peephole to pCode parsing.
[fw/sdcc] / src / pic / pcodepeep.c
index 8b3e0575d5ec9cf2e98bf1ecf6a8a0a9e887fabc..40eb56ed56e700cb355e2fd06498966416d3aebc 100644 (file)
@@ -19,6 +19,7 @@
 -------------------------------------------------------------------------*/
 
 #include <stdio.h>
+#include <stdlib.h>
 
 #include "common.h"   // Include everything in the SDCC src directory
 #include "newalloc.h"
@@ -32,7 +33,7 @@ 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);
 
 /****************************************************************/
 /*
@@ -41,7 +42,9 @@ char *Safe_strdup(char *str);
  * defined in peep.def.
  */
 
-extern peepRule *rootRules;
+//extern peepRule *rootRules;
+
+
 
 
 /****************************************************************/
@@ -60,8 +63,711 @@ typedef struct pCodePeepSnippets
 } pCodePeepSnippets;
 
 
+/****************************************************************/
+/*                                                              */
+/* peepSnippets -                                               */
+/*                                                              */
+/****************************************************************/
+
 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;
+
+} pCodeToken;
+
+pCodeToken tokArr[50];
+unsigned   tokIdx=0;
+
+
+typedef enum  {
+  PCT_SPACE=1,
+  PCT_PERCENT,
+  PCT_COLON,
+  PCT_COMMA,
+  PCT_COMMENT,
+  PCT_STRING,
+  PCT_NUMBER
+
+} pCodeTokens;
+
+
+typedef struct parsedPattern {
+  struct pcPattern *pcp;
+  pCodeToken *pct;
+} parsedPattern;
+
+#define MAX_PARSEDPATARR 50
+parsedPattern parsedPatArr[MAX_PARSEDPATARR];
+unsigned int parsedPatIdx=0;
+
+
+typedef enum {
+  PCP_LABEL=1,
+  PCP_NUMBER,
+  PCP_STR,
+  PCP_WILDVAR,
+  PCP_WILDSTR,
+  PCP_COMMA
+} pCodePatterns;
+
+static char pcpat_label[]      = {PCT_PERCENT, PCT_NUMBER, PCT_COLON, 0};
+static char pcpat_number[]     = {PCT_NUMBER, 0};
+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};
+
+
+typedef struct pcPattern {
+  char pt;                 // Pattern type
+  char *tokens;           // list of tokens that describe the pattern
+  void * (*f) (void *);
+} 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}
+};
+
+#define PCPATTERNS (sizeof(pcpArr)/sizeof(pcPattern))
+
+// Assembly Line Token
+typedef enum {
+  ALT_LABEL=1,
+  ALT_MNEM0,
+  ALT_MNEM1,
+  ALT_MNEM1A,
+  ALT_MNEM1B,
+  ALT_MNEM2,
+  ALT_MNEM2A
+} altPatterns;
+
+static char alt_label[]     = { PCP_LABEL, 0};
+static char alt_mnem0[]     = { PCP_STR, 0};
+static char alt_mnem1[]     = { PCP_STR, PCP_STR, 0};
+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_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_MNEM0,        alt_mnem0,  cvt_altpat_mnem0},
+
+};
+
+#define ALTPATTERNS (sizeof(altArr)/sizeof(pcPattern))
+
+/*-----------------------------------------------------------------*/
+/* cvt_altpat_label - convert assembly line type to a pCode label  */
+/* INPUT: pointer to the parsedPattern                             */
+/*                                                                 */
+/*  pp[0] - label                                                  */
+/*                                                                 */
+/* label pattern => '%' number ':'                                 */
+/* at this point, we wish to extract only the 'number'             */
+/*                                                                 */
+/*-----------------------------------------------------------------*/
+static void * cvt_altpat_label(void *pp)
+{
+  parsedPattern *p = pp;
+
+  fprintf(stderr,"altpat_label with ID = %d\n",p->pct[1].tok.n);
+  return newpCodeOpLabel(-p->pct[1].tok.n);
+
+}
+
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+static void * cvt_altpat_mnem0(void *pp)
+{
+  fprintf(stderr,"altpat_mnem0\n");
+  return NULL;
+}
+
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+static void * cvt_altpat_mnem1(void *pp)
+{
+  fprintf(stderr,"altpat_mnem1\n");
+  return NULL;
+}
+
+/*-----------------------------------------------------------------*/
+/* cvt_altpat_mem1a - convert assembly line type to a pCode        */
+/*                    instruction with 1 wild operand.             */
+/*                                                                 */
+/*  pp[0] - mnem                                                   */
+/*  pp[1] - wild var                                               */
+/*                                                                 */
+/*-----------------------------------------------------------------*/
+static void * cvt_altpat_mnem1a(void *pp)
+{
+  parsedPattern *p = pp;
+
+  pCodeInstruction *pci=NULL;
+
+  //    pCodeOp *pcw;
+
+  //  pcw = newpCodeOpWild(0,pcp,newpCodeOp(NULL,PO_GPR_REGISTER));
+
+  fprintf(stderr,"altpat_mnem1a %s var %d\n",  p->pct[0].tok.s,p[1].pct[1].tok.n);
+
+/*
+  pci = PCI(newpCode(getpCode(p->pct[0].tok.s),
+                    newpCodeOpWild(p[1].pct[1].tok.n, curPeep, NULL)));
+
+  if(!pci)
+    fprintf(stderr,"couldn't find mnemonic\n");
+*/
+
+  return pci;
+}
+
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+static void * cvt_altpat_mnem1b(void *pp)
+{
+  fprintf(stderr,"altpat_mnem1b\n");
+  return NULL;
+}
+
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+static void * cvt_altpat_mnem2(void *pp)
+{
+  fprintf(stderr,"altpat_mnem2\n");
+  return NULL;
+}
+
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+static void * cvt_altpat_mnem2a(void *pp)
+{
+  fprintf(stderr,"altpat_mnem2a\n");
+  return NULL;
+}
+
+
+
+
+#if 0
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+static pCode * cvt_pcpat_wildMnem(parsedPattern *pp)
+{
+  fprintf(stderr,"pcpat_wildMnem\n");
+  return NULL;
+}
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+static pCode * cvt_pcpat_Mnem(parsedPattern *pp)
+{
+  fprintf(stderr,"pcpat_Mnem\n");
+  return NULL;
+}
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+static pCode * cvt_pcpat_wildVar(parsedPattern *pp)
+{
+  fprintf(stderr,"pcpat_wildVar\n");
+  return NULL;
+}
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+static pCode * cvt_pcpat_var(parsedPattern *pp)
+{
+  fprintf(stderr,"pcpat_var\n");
+  return NULL;
+}
+#endif
+
+
+
+
+
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+
+
+static void parseLineNode(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, 10);
+
+      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;
+}
+
+
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+
+
+
+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);
+
+
+  }
+}
+
+
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+
+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 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 advTokIdx(int *v, int amt)
+{
+
+  if(*v + amt > tokIdx)
+    return 1;
+
+  *v += amt;
+  return 0;
+
+}
+
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+
+void dumpTokens(void)
+{
+  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,k;
+
+    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) )//|| (tokArr[ltokIdx].tt == PCT_COMMA))
+          && (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");
+         }
+
+         matching = 1;
+         parsedPatArr[lparsedPatIdx].pcp = &pcpArr[lpcpIdx];
+         parsedPatArr[lparsedPatIdx].pct = &tokArr[ltokIdx];
+         lparsedPatIdx++;
+
+         //dump1Token(tokArr[ltokIdx].tt);
+
+         if(advTokIdx(&ltokIdx, strlen(pcpArr[lpcpIdx].tokens) ) ) {
+           fprintf(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;
+      //fprintf(stderr,"comparing alt pattern %d (first token %d)\n",k,altArr[k].tokens[0]);
+      if( (c=altComparePattern( altArr[k].tokens, &parsedPatArr[j],10) ) ) {
+       //fprintf(stderr," found a valid assembly line!!!\n");
+       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);
+       }
+       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");
+
+  }
+
+
+}
+
+/*-----------------------------------------------------------------*/
+/* peepRules2pCode - parse the "parsed" peep hole rules to generate*/
+/*                   pCode.                                        */
+/*                                                                 */
+/* SDCCpeeph parses the peep rules file and extracts variables,    */
+/* removes white space, and checks the syntax. This function       */
+/* extends that processing to produce pCode objects. You can kind  */
+/* think of this function as an "assembler", though instead of     */
+/* taking raw text to produce machine code, it produces pCode.     */
+/*                                                                 */
+/*-----------------------------------------------------------------*/
+
+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));
+    //peepSnippets = DLL_append((_DLL*)peepSnippets,(_DLL*)pcps);
+
+    for(ln = pr->match; ln; ln = ln->next) {
+      fprintf(stderr,"%s\n",ln->line);
+
+      parseLineNode(ln->line);
+      dumpTokens();
+
+    }
+
+    fprintf(stderr,"\nReplaced by:\n");
+    for(ln = pr->replace; ln; ln = ln->next)
+      fprintf(stderr,"%s\n",ln->line);
+
+    if(pr->cond)
+      fprintf(stderr,"\nCondition:  %s\n",pr->cond);
+
+  }
+
+}
 
 void printpCodeString(FILE *of, pCode *pc, int max)
 {
@@ -233,11 +939,33 @@ void pCodePeepInit(void)
   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);
@@ -665,7 +1393,7 @@ int pCodePeepMatchRule(pCode *pc)
        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]);
@@ -685,3 +1413,84 @@ int pCodePeepMatchRule(pCode *pc)
 
   return 0;
 }
+
+
+
+
+
+
+
+
+
+
+#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++;
+
+    }
+  }
+
+  return pc;
+  
+}
+#endif