* src/SDCCast.c (decorateType),
[fw/sdcc] / src / pic16 / pcodepeep.c
index b62d9c6375efdd5e03b7b31e4f3d23820fa82f3b..4b6c1a96e7c509c45a4b07bdb1d47e63f21dc388 100644 (file)
@@ -1,6 +1,7 @@
 /*-------------------------------------------------------------------------
 
-   pcodepeep.c - post code generation
+  pcodepeep.c - post code generation
+
    Written By -  Scott Dattalo scott@dattalo.com
    Ported to PIC16 By - Martin Dubuc m.dubuc@rogers.com
 
@@ -45,9 +46,10 @@ int pic16_getpCodePeepCommand(char *cmd);
 void pic16_pBlockMergeLabels(pBlock *pb);
 char *pCode2str(char *str, int size, pCode *pc);
 char *pic16_get_op( pCodeOp *pcop,char *buf,int buf_size);
+pCodeOp *pic16_popCombine2(pCodeOp *, pCodeOp *, int);
 
 extern pCodeInstruction *pic16Mnemonics[];
-
+static int parsing_peeps=1;
 
 #define IS_PCCOMMENT(x) ( x && (x->type==PC_COMMENT))
 
@@ -202,7 +204,10 @@ typedef enum {
   ALT_MNEM1B,
   ALT_MNEM2,
   ALT_MNEM2A,
-  ALT_MNEM3
+  ALT_MNEM2B,
+  ALT_MNEM3,
+  ALT_MNEM4,
+  ALT_MNEM4a
 } altPatterns;
 
 static char alt_comment[]   = { PCP_COMMENT, 0};
@@ -214,7 +219,10 @@ 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 char alt_mnem2b[]    = { PCP_STR, PCP_WILDVAR, PCP_COMMA, PCP_WILDVAR, 0};
 static char alt_mnem3[]     = { PCP_STR, PCP_STR, PCP_COMMA, PCP_NUMBER, 0};
+static char alt_mnem4[]            = { PCP_STR, PCP_NUMBER, PCP_COMMA, PCP_STR, 0};    // for lfsr 0 , name
+static char alt_mnem4a[]    = { PCP_STR, PCP_NUMBER, PCP_COMMA, PCP_NUMBER, 0}; // for lfsr 0 , value
 
 static void * cvt_altpat_label(void *pp,pCodeWildBlock *pcwb);
 static void * cvt_altpat_comment(void *pp,pCodeWildBlock *pcwb);
@@ -225,12 +233,19 @@ 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_mnem2b(void *pp, pCodeWildBlock *pcwb);
 static void * cvt_altpat_mnem3(void *pp,pCodeWildBlock *pcwb);
+static void * cvt_altpat_mnem4(void *pp, pCodeWildBlock *pcwb);
+static void * cvt_altpat_mnem4a(void *pp, pCodeWildBlock *pcwb);
 
+/* NOTE: Order is important in the following table */
 static pcPattern altArr[] = {
   {ALT_LABEL,        alt_label,  cvt_altpat_label},
   {ALT_COMMENT,      alt_comment,cvt_altpat_comment},
+  {ALT_MNEM4a,       alt_mnem4a, cvt_altpat_mnem4a},
+  {ALT_MNEM4,        alt_mnem4,  cvt_altpat_mnem4},
   {ALT_MNEM3,        alt_mnem3,  cvt_altpat_mnem3},
+//  {ALT_MNEM2B,       alt_mnem2b, cvt_altpat_mnem2b},
   {ALT_MNEM2A,       alt_mnem2a, cvt_altpat_mnem2a},
   {ALT_MNEM2,        alt_mnem2,  cvt_altpat_mnem2},
   {ALT_MNEM1B,       alt_mnem1b, cvt_altpat_mnem1b},
@@ -433,8 +448,10 @@ static void * cvt_altpat_mnem1(void *pp,pCodeWildBlock *pcwb)
 
   if(pic16Mnemonics[opcode]->isBitInst)
     pcosubtype = pic16_newpCodeOp(p[1].pct[0].tok.s,PO_BIT);
-  else
-    pcosubtype = pic16_newpCodeOp(p[1].pct[0].tok.s,PO_GPR_REGISTER);
+  else {
+//     fprintf(stderr, "%s:%d tok.s= %s\n", __FILE__, __LINE__, p[1].pct[0].tok.s);
+    pcosubtype = pic16_newpCodeOp(p[1].pct[0].tok.s,PO_STR);   //GPR_REGISTER);
+  }
 
 
   pci = PCI(pic16_newpCode(opcode, pcosubtype));
@@ -566,7 +583,6 @@ static void * cvt_altpat_mnem2(void *pp,pCodeWildBlock *pcwb)
          p[3].pct[0].tok.s,
          dest));
 
-
   opcode = pic16_getpCode(p->pct[0].tok.s,dest);
   if(opcode < 0) {
     fprintf(stderr, "Bad mnemonic\n");
@@ -580,8 +596,15 @@ static void * cvt_altpat_mnem2(void *pp,pCodeWildBlock *pcwb)
       return NULL;
     }
       
+  } else
+  if(pic16Mnemonics[opcode]->is2MemOp) {
+       /* support for movff instruction */
+       pcosubtype = pic16_popCombine2(
+               pic16_newpCodeOp(p[1].pct[0].tok.s, PO_GPR_REGISTER),
+               pic16_newpCodeOp(p[3].pct[0].tok.s, PO_GPR_REGISTER), 0);
   } else
     pcosubtype = pic16_newpCodeOp(p[1].pct[0].tok.s,PO_GPR_REGISTER);
 
 
   pci = PCI(pic16_newpCode(opcode,pcosubtype));
@@ -636,6 +659,13 @@ static void * cvt_altpat_mnem2a(void *pp,pCodeWildBlock *pcwb)
   if(pic16Mnemonics[opcode]->isBitInst)
     pcosubtype = pic16_newpCodeOp(NULL,PO_BIT);
   else
+  if(pic16Mnemonics[opcode]->is2MemOp) {
+       return NULL;
+       /* support for movff instruction */
+       pcosubtype = pic16_popCombine2(
+               pic16_newpCodeOp(p[1].pct[0].tok.s, PO_GPR_REGISTER),
+               pic16_newpCodeOp(p[3].pct[0].tok.s, PO_GPR_REGISTER), 0);
+  } else
     pcosubtype = pic16_newpCodeOp(NULL,PO_GPR_REGISTER);
 
 
@@ -656,6 +686,70 @@ static void * cvt_altpat_mnem2a(void *pp,pCodeWildBlock *pcwb)
 
 }
 
+#if 0
+/*-----------------------------------------------------------------*/
+/* cvt_altpat_mem2b - convert assembly line type to a pCode        */
+/*                    instruction with 2 wild operands             */
+/*                                                                 */
+/*  pp[0] - mnem                                                   */
+/*  pp[1] - wild var                                               */
+/*  pp[2] - comma                                                  */
+/*  pp[3] - wild var                                               */
+/*                                                                 */
+/*-----------------------------------------------------------------*/
+static void * cvt_altpat_mnem2b(void *pp,pCodeWildBlock *pcwb)
+{
+  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_mnem2b %s src %d dst (%d)\n",
+         p->pct[0].tok.s,
+         p[1].pct[1].tok.n,
+         p[3].pct[1].tok.n));
+
+
+  opcode = pic16_getpCode(p->pct[0].tok.s,dest);
+  if(opcode < 0) {
+    fprintf(stderr, "Bad mnemonic\n");
+    return NULL;
+  }
+
+  if(pic16Mnemonics[opcode]->is2MemOp) {
+       /* support for movff instruction */
+       pcosubtype = pic16_popCombine2(
+               pic16_newpCodeOp(NULL, PO_GPR_REGISTER),
+               pic16_newpCodeOp(NULL, PO_GPR_REGISTER), 0);
+  } else pcosubtype = NULL;
+
+  pci = PCI(pic16_newpCode(opcode,
+                    pic16_newpCodeOpWild(p[1].pct[1].tok.n, pcwb, pcosubtype)));
+
+  /* Save the index of the maximum wildcard variable */
+  //if(p[1].pct[1].tok.n > sMaxWildVar)
+  //  sMaxWildVar = p[1].pct[1].tok.n;
+
+  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;
+
+}
+#endif
+
 
 /*-----------------------------------------------------------------*/
 /* cvt_altpat_mem3 -  convert assembly line type to a pCode        */
@@ -715,6 +809,110 @@ static void * cvt_altpat_mnem3(void *pp,pCodeWildBlock *pcwb)
 
 }
 
+/*-----------------------------------------------------------------*/
+/* cvt_altpat_mem4 -  convert assembly line type to a pCode        */
+/*                    This rule is for lfsr instruction            */
+/*                                                                 */
+/*                                                                 */
+/*  pp[0] - mnem                                                   */
+/*  pp[1] - number                                                 */
+/*  pp[2] - comma                                                  */
+/*  pp[3] - source                                                 */
+/*                                                                 */
+/*-----------------------------------------------------------------*/
+static void * cvt_altpat_mnem4(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_mnem4 %s fsr %d source %s\n",
+         p->pct[0].tok.s,
+         p[1].pct[0].tok.n,
+         p[3].pct[0].tok.s));
+
+  opcode = pic16_getpCode(p->pct[0].tok.s,0);
+  if(opcode < 0) {
+    fprintf(stderr, "Bad mnemonic\n");
+    return NULL;
+  }
+  DFPRINTF((stderr, "Found mnemonic opcode= %d\n", opcode));
+
+  if(pic16Mnemonics[opcode]->is2LitOp) {
+    pcosubtype = pic16_newpCodeOpLit2(p[1].pct[0].tok.n, pic16_newpCodeOp(p[3].pct[0].tok.s, PO_STR));
+  }
+
+  if(pcosubtype == NULL) {
+    fprintf(stderr, "Bad operand\n");
+    return NULL;
+  }
+
+  pci = PCI(pic16_newpCode(opcode, pcosubtype));
+
+  if(!pci)
+    fprintf(stderr,"couldn't find mnemonic\n");
+
+  return pci;
+
+}
+
+/*-----------------------------------------------------------------*/
+/* cvt_altpat_mem4a -  convert assembly line type to a pCode       */
+/*                    This rule is for lfsr instruction            */
+/*                                                                 */
+/*                                                                 */
+/*  pp[0] - mnem                                                   */
+/*  pp[1] - number                                                 */
+/*  pp[2] - comma                                                  */
+/*  pp[3] - value                                                  */
+/*                                                                 */
+/*-----------------------------------------------------------------*/
+static void * cvt_altpat_mnem4a(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_mnem4a %s fsr %d value 0x%02x\n",
+         p->pct[0].tok.s,
+         p[1].pct[0].tok.n,
+         p[3].pct[0].tok.n));
+
+  opcode = pic16_getpCode(p->pct[0].tok.s,0);
+  if(opcode < 0) {
+    fprintf(stderr, "Bad mnemonic\n");
+    return NULL;
+  }
+  DFPRINTF((stderr, "Found mnemonic opcode= %d\n", opcode));
+
+  if(pic16Mnemonics[opcode]->is2LitOp) {
+    pcosubtype = pic16_newpCodeOpLit2(p[1].pct[0].tok.n, pic16_newpCodeOpLit(p[3].pct[0].tok.n));
+  }
+
+  if(pcosubtype == NULL) {
+    fprintf(stderr, "Bad operand\n");
+    return NULL;
+  }
+
+  pci = PCI(pic16_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.      */
@@ -784,12 +982,12 @@ static void tokenizeLineNode(char *ln)
       break;
 
 
-    default:
-      if(isalpha(*ln) || (*ln == '_') ) {
+    default:                           // hack to allow : goto $
+      if(isalpha(*ln) || (*ln == '_')  || (!parsing_peeps && (*ln == '$'))) {
        char buffer[50];
        int i=0;
 
-       while( (isalpha(*ln)  ||  isdigit(*ln) || (*ln == '_')) && i<49)
+       while( (isalpha(*ln)  ||  isdigit(*ln) || (*ln == '_') || (*ln == '$')) && i<49)
          buffer[i++] = *ln++;
 
        ln--;
@@ -799,10 +997,12 @@ static void tokenizeLineNode(char *ln)
        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);
+       if(parsing_peeps) {
+               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);
+       }
       }
     }
 
@@ -886,7 +1086,7 @@ static int pcComparePattern(pCodeToken *pct, char *pat, int max_tokens)
       return (i+1);
     }
 
-    //dump1Token(*pat); DFPRINTF((stderr,"\n"));
+//     dump1Token(*pat); fputc('\n', stderr); DFPRINTF((stderr,"\n"));
 
     if(pct->tt != *pat) 
       return 0;
@@ -914,11 +1114,11 @@ static int altComparePattern( char *pct, parsedPattern *pat, int max_tokens)
   while(i < max_tokens) {
 
     if(*pct == 0) {
-      //DFPRINTF((stderr,"matched\n"));
+       DFPRINTF((stderr,"matched\n"));
       return i;
     }
 
-    //dump1Token(*pat); DFPRINTF((stderr,"\n"));
+//     dump1Token(*pat); DFPRINTF((stderr,"\n"));
 
     if( !pat || !pat->pcp )
       return 0;
@@ -926,7 +1126,7 @@ static int altComparePattern( char *pct, parsedPattern *pat, int max_tokens)
     if (pat->pcp->pt != *pct)  
       return 0;
 
-    //DFPRINTF((stderr," pct=%d\n",*pct));
+       DFPRINTF((stderr," pct=%d\n",*pct));
     pct++;
     pat++;
     i++;
@@ -1121,7 +1321,7 @@ static int parseTokens(pCodeWildBlock *pcwb, pCode **pcret)
          parsedPatArr[lparsedPatIdx].pct = &tokArr[ltokIdx];
          lparsedPatIdx++;
 
-         //dump1Token(tokArr[ltokIdx].tt);
+//             dump1Token(tokArr[ltokIdx].tt);
 
          if(advTokIdx(&ltokIdx, strlen(pcpArr[lpcpIdx].tokens) ) ) {
            DFPRINTF((stderr," reached end \n"));
@@ -1198,6 +1398,7 @@ static void  peepRuleBlock2pCodeBlock(  lineNode *ln, pCodeWildBlock *pcwb)
   for( ; ln; ln = ln->next) {
 
     //DFPRINTF((stderr,"%s\n",ln->line));
+//     fprintf(stderr, "peep rule : %s\n", ln->line);
 
     tokenizeLineNode(ln->line);
     
@@ -1205,7 +1406,7 @@ static void  peepRuleBlock2pCodeBlock(  lineNode *ln, pCodeWildBlock *pcwb)
       int i;
       fprintf(stderr,"ERROR assembling line:\n%s\n",ln->line);
       fprintf(stderr,"Tokens:\n");
-      for(i=0; i<5; i++)
+      for(i=0; i<8; i++)
        dump1Token(tokArr[i].tt);
       fputc('\n',stderr);
       exit (1);
@@ -1214,9 +1415,10 @@ static void  peepRuleBlock2pCodeBlock(  lineNode *ln, pCodeWildBlock *pcwb)
 }
 
 /*-----------------------------------------------------------------*/
-/*                                                                 */
+/* pic16_AssembleLine - parse line and return the pCode equivalent */
+/*                      peeps=1 if parsing peep rules, 0 otherwise */
 /*-----------------------------------------------------------------*/
-pCode *pic16_AssembleLine(char *line)
+pCode *pic16_AssembleLine(char *line, int peeps)
 {
   pCode *pc=NULL;
 
@@ -1225,11 +1427,18 @@ pCode *pic16_AssembleLine(char *line)
     return NULL;
   }
 
+  parsing_peeps = peeps;
+
   tokenizeLineNode(line);
     
   if(parseTokens(NULL,&pc))
     fprintf(stderr, "WARNING: unable to assemble line:\n%s\n",line);
+  else {
+       DFPRINTF((stderr, "pc= %p\n", pc));
+//     if(pc)pc->print(stderr, pc);
+  }
 
+  parsing_peeps = 1;
   return pc;
 
 }
@@ -1349,7 +1558,7 @@ void  pic16_peepRules2pCode(peepRule *rules)
     peepRuleBlock2pCodeBlock(pr->match, &currentRule->target);
 
     //DFPRINTF((stderr,"finished target, here it is in pcode form:\n"));
-    //pic16_printpBlock(stderr, currentRule->target.pb);
+//     pic16_printpBlock(stderr, currentRule->target.pb);
 
     //DFPRINTF((stderr,"target with labels merged:\n"));
     //pic16_pBlockMergeLabels(curBlock);
@@ -1514,13 +1723,14 @@ static int pCodeOpCompare(pCodeOp *pcops, pCodeOp *pcopd)
 
   if(!pcops || !pcopd)
     return 0;
-/*
+
+#if 0
   fprintf(stderr," Comparing operands %s",
          pic16_get_op( pcops,NULL,0));
 
   fprintf(stderr," to %s\n",
          pic16_get_op( pcopd,NULL,0));
-*/
+#endif
 
   if(pcops->type != pcopd->type) {
     //fprintf(stderr,"  - fail - diff types\n");
@@ -1705,14 +1915,37 @@ static int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd)
            return pCodeOpCompare(PCI(pcs)->pcop, peepBlock->target.wildpCodeOps[index]);
          }
 
-         {
+         if(PCI(pcs)->pcop) {
            char *n;
 
            switch(PCI(pcs)->pcop->type) {
            case PO_GPR_TEMP:
            case PO_FSR0:
              //case PO_INDF0:
-             n = PCOR(PCI(pcs)->pcop)->r->name;
+               n = PCOR(PCI(pcs)->pcop)->r->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;
+           }
+         }
+         
+         if(PCI(pcs)->is2MemOp) {
+           char *n;
+
+           switch(PCOP(PCOR2(PCI(pcs))->pcop2)->type) {
+           case PO_GPR_TEMP:
+           case PO_FSR0:
+             //case PO_INDF0:
+               n = PCOR(PCOR2(PCI(pcs))->pcop2)->r->name;
 
              break;
            default:
@@ -2066,7 +2299,7 @@ int pic16_pCodePeepMatchRule(pCode *pc)
 
       if(!pcin && pct) {
        DFPRINTF((stderr," partial match... no more code\n"));
-       fprintf(stderr," partial match... no more code\n");
+//     fprintf(stderr," partial match... no more code\n");
        matched = 0; 
       }
       if(!pct) {
@@ -2107,7 +2340,7 @@ int pic16_pCodePeepMatchRule(pCode *pc)
         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);
+//      printpCodeString(stderr,peepBlock->target.pb->pcHead,10);
       DFPRINTF((stderr,"first thing matched\n"));
       pc->print(stderr,pc);
       if(pcin) {