More enhancements to register optimization algorithms.
authorsdattalo <sdattalo@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Thu, 4 Jul 2002 19:45:40 +0000 (19:45 +0000)
committersdattalo <sdattalo@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Thu, 4 Jul 2002 19:45:40 +0000 (19:45 +0000)
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@2028 4a8a32a2-be11-0410-ad9d-d568d2c75423

src/pic/gen.c
src/pic/pcode.c
src/pic/pcode.h
src/pic/pcodeflow.h
src/pic/pcodepeep.c
src/pic/pcoderegs.c
src/pic/peeph.def
src/pic/ralloc.h
src/regression/b.c
src/regression/create_stc
src/regression/simulate

index b734cf6ade538ca62eeaa3b5d1873d87afb905ab..6057496d23188ae559de4775c6598427eda982ca 100644 (file)
@@ -1383,7 +1383,7 @@ pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
       return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
 
     case AOP_STR:
-      DEBUGpic14_emitcode(";","%d",__LINE__);
+      DEBUGpic14_emitcode(";","%d  %s",__LINE__,aop->aopu.aop_str[offset]);
       return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
       /*
       pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
@@ -3030,7 +3030,6 @@ static void genRet (iCode *ic)
        }
        if(size) {
          emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
-         pic14_emitcode("movwf","%s",fReturn[offset]);
        }
        offset++;
       }
index 36d2aa7c35476effd22ac6aad48cae0d16ecf5f5..6aad570383c1467926b7fc7e309d2098d41bbf22 100644 (file)
@@ -176,7 +176,7 @@ pCodeInstruction pciADDLW = {
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
   POC_NOP,
-  PCC_W,   // inCond
+  (PCC_W | PCC_LITERAL),   // inCond
   (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond
 };
 
@@ -197,7 +197,7 @@ pCodeInstruction pciANDLW = {
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
   POC_NOP,
-  PCC_W,   // inCond
+  (PCC_W | PCC_LITERAL),   // inCond
   (PCC_W | PCC_Z) // outCond
 };
 
@@ -260,7 +260,7 @@ pCodeInstruction pciBCF = {
   1,1,  // dest, bit instruction
   0,0,  // branch, skip
   POC_BSF,
-  PCC_REGISTER,   // inCond
+  (PCC_REGISTER | PCC_EXAMINE_PCOP),   // inCond
   PCC_REGISTER // outCond
 };
 
@@ -281,8 +281,8 @@ pCodeInstruction pciBSF = {
   1,1,  // dest, bit instruction
   0,0,  // branch, skip
   POC_BCF,
-  PCC_REGISTER,   // inCond
-  PCC_REGISTER // outCond
+  (PCC_REGISTER | PCC_EXAMINE_PCOP),   // inCond
+  (PCC_REGISTER | PCC_EXAMINE_PCOP) // outCond
 };
 
 pCodeInstruction pciBTFSC = {
@@ -302,8 +302,8 @@ pCodeInstruction pciBTFSC = {
   0,1,  // dest, bit instruction
   1,1,  // branch, skip
   POC_BTFSS,
-  PCC_REGISTER,   // inCond
-  PCC_NONE // outCond
+  (PCC_REGISTER | PCC_EXAMINE_PCOP),   // inCond
+  PCC_EXAMINE_PCOP // outCond
 };
 
 pCodeInstruction pciBTFSS = {
@@ -323,8 +323,8 @@ pCodeInstruction pciBTFSS = {
   0,1,  // dest, bit instruction
   1,1,  // branch, skip
   POC_BTFSC,
-  PCC_REGISTER,   // inCond
-  PCC_NONE // outCond
+  (PCC_REGISTER | PCC_EXAMINE_PCOP),   // inCond
+  PCC_EXAMINE_PCOP // outCond
 };
 
 pCodeInstruction pciCALL = {
@@ -680,7 +680,7 @@ pCodeInstruction pciIORLW = {
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
   POC_NOP,
-  PCC_W,   // inCond
+  (PCC_W | PCC_LITERAL),   // inCond
   (PCC_W | PCC_Z) // outCond
 };
 
@@ -764,7 +764,7 @@ pCodeInstruction pciMOVLW = {
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
   POC_NOP,
-  PCC_NONE,   // inCond
+  (PCC_NONE | PCC_LITERAL),   // inCond
   PCC_W // outCond
 };
 
@@ -826,7 +826,7 @@ pCodeInstruction pciRETLW = {
   0,0,  // dest, bit instruction
   1,0,  // branch, skip
   POC_NOP,
-  PCC_NONE,   // inCond
+  PCC_LITERAL,   // inCond
   PCC_W // outCond
 };
 
@@ -994,7 +994,7 @@ pCodeInstruction pciSUBLW = {
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
   POC_NOP,
-  PCC_W,   // inCond
+  (PCC_W | PCC_LITERAL),   // inCond
   (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond
 };
 
@@ -1120,7 +1120,7 @@ pCodeInstruction pciXORLW = {
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
   POC_NOP,
-  PCC_W,   // inCond
+  (PCC_W | PCC_LITERAL),   // inCond
   (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond
 };
 
@@ -1593,11 +1593,11 @@ pCode *newpCode (PIC_OPCODE op, pCodeOp *pcop)
     memcpy(pci, pic14Mnemonics[op], sizeof(pCodeInstruction));
     pci->pcop = pcop;
 
-    if(pci->inCond == PCC_EXAMINE_PCOP)
-      pci->inCond   = RegCond(pcop);
+    if(pci->inCond & PCC_EXAMINE_PCOP)
+      pci->inCond  |= RegCond(pcop);
 
-    if(pci->outCond == PCC_EXAMINE_PCOP)
-      pci->outCond   = RegCond(pcop);
+    if(pci->outCond & PCC_EXAMINE_PCOP)
+      pci->outCond  |= RegCond(pcop);
 
     pci->pc.prev = pci->pc.next = NULL;
     return (pCode *)pci;
@@ -2013,13 +2013,21 @@ pCodeOp *newpCodeOpImmd(char *name, int offset, int index, int code_space)
   pcop = Safe_calloc(1,sizeof(pCodeOpImmd) );
   pcop->type = PO_IMMEDIATE;
   if(name) {
+    regs *r = dirregWithName(name);
     pcop->name = Safe_strdup(name);
+    PCOI(pcop)->r = r;
+    if(r) {
+      //fprintf(stderr, " newpCodeOpImmd reg %s exists\n",name);
+      PCOI(pcop)->rIdx = r->rIdx;
+    } else {
+      //fprintf(stderr, " newpCodeOpImmd reg %s doesn't exist\n",name);
+      PCOI(pcop)->rIdx = -1;
+    }
     //fprintf(stderr,"%s %s %d\n",__FUNCTION__,name,offset);
   } else {
     pcop->name = NULL;
   }
 
-
   PCOI(pcop)->index = index;
   PCOI(pcop)->offset = offset;
   PCOI(pcop)->_const = code_space;
@@ -3124,6 +3132,7 @@ static void AnalyzeRETURN(pCode *pc)
 /*-----------------------------------------------------------------*/
 regs * getRegFromInstruction(pCode *pc)
 {
+
   if(!pc                   || 
      !isPCI(pc)            ||
      !PCI(pc)->pcop        ||
@@ -3141,8 +3150,12 @@ regs * getRegFromInstruction(pCode *pc)
     return PCOR(PCI(pc)->pcop)->r;
 
   case PO_IMMEDIATE:
+    if(PCOI(PCI(pc)->pcop)->r)
+      return (PCOI(PCI(pc)->pcop)->r);
+
     //fprintf(stderr, "getRegFromInstruction - immediate\n");
-    return NULL; // PCOR(PCI(pc)->pcop)->r;
+    return dirregWithName(PCI(pc)->pcop->name);
+    //return NULL; // PCOR(PCI(pc)->pcop)->r;
 
   case PO_GPR_BIT:
     return PCOR(PCI(pc)->pcop)->r;
@@ -4619,6 +4632,8 @@ void AnalyzeBanking(void)
   //  for(pb = the_pFile->pbHead; pb; pb = pb->next)
   pCodeRegOptimizeRegUsage();
 
+  OptimizepCode('*');
+
 /*
   for(pb = the_pFile->pbHead; pb; pb = pb->next)
     DumpFlow(pb);
index 7d896723a3c1b6f014be82f4f2e1cdc32e464092..c6d1ec2b22aa0f8f63d5370dc3830647eff27874 100644 (file)
@@ -310,9 +310,12 @@ typedef struct pCodeOpLit
 typedef struct pCodeOpImmd
 {
   pCodeOp pcop;
-  int offset;                   /* low,med, or high byte of immediat value */
-  int index;                    /* add this to the immediate value */
-  unsigned _const:1;           /* is in code space    */
+  int offset;           /* low,med, or high byte of immediat value */
+  int index;            /* add this to the immediate value */
+  unsigned _const:1;    /* is in code space    */
+
+  int rIdx;             /* If this immd points to a register */
+  struct regs *r;       /* then this is the reg. */
 
 } pCodeOpImmd;
 
index 6db2382cd9a1e2debf43a5c6b296288c9be64727..c8b53199895582965ec5c8b11bb4c65392af919c 100644 (file)
@@ -56,6 +56,7 @@
 #define  PCC_REG_BANK1     (1<<7)
 #define  PCC_REG_BANK2     (1<<8)
 #define  PCC_REG_BANK3     (1<<9)
+#define  PCC_LITERAL       (1<<10)
 
 /*------------------------------------------------------------*/
 
index 96b334cbc64685e90651f408e1fd9735439134f1..3aeb99d98df824ef397ad6ebc38ab8be36393172 100644 (file)
@@ -660,13 +660,14 @@ static void * cvt_altpat_mnem2a(void *pp,pCodeWildBlock *pcwb)
 
 static void tokenizeLineNode(char *ln)
 {
-
+  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(*ln)) {
@@ -723,6 +724,11 @@ static void tokenizeLineNode(char *ln)
        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);
       }
     }
 
@@ -1028,6 +1034,8 @@ void parseTokens(pCodeWildBlock *pcwb)
              state = PS_HAVE_COMMA;
            } else
              fprintf(stderr,"  unexpected comma\n");
+           break;
+
          }
 
          matching = 1;
@@ -1227,7 +1235,7 @@ void  peepRules2pCode(peepRule *rules)
     peepRuleBlock2pCodeBlock(pr->match, &currentRule->target);
 
     //DFPRINTF((stderr,"finished target, here it is in pcode form:\n"));
-    //printpBlock(stderr, curBlock);
+    //printpBlock(stderr, currentRule->target.pb);
 
     //DFPRINTF((stderr,"target with labels merged:\n"));
     //pBlockMergeLabels(curBlock);
@@ -1356,7 +1364,7 @@ static void * DLL_append(_DLL *list, _DLL *next)
 /*-----------------------------------------------------------------*/
 int pCodeSearchCondition(pCode *pc, unsigned int cond)
 {
-
+  //fprintf(stderr,"Checking conditions %d\n",cond);
   while(pc) {
 
     /* If we reach a function end (presumably an end since we most
@@ -1368,6 +1376,7 @@ int pCodeSearchCondition(pCode *pc, unsigned int cond)
     if(pc->type == PC_OPCODE) {
       //fprintf(stderr," checking conditions of: ");
       //pc->print(stderr,pc);
+      //fprintf(stderr,"\t\tinCond=%d\toutCond=%d\n",PCI(pc)->inCond,PCI(pc)->outCond);
       if(PCI(pc)->inCond & cond)
        return 1;
       if(PCI(pc)->outCond & cond)
@@ -1404,6 +1413,14 @@ int pCodeOpCompare(pCodeOp *pcops, pCodeOp *pcopd)
     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);
 
@@ -1547,7 +1564,6 @@ int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd)
       if(PCI(pcd)->pcop) {
        if (PCI(pcd)->pcop->type == PO_WILD) {
          index = PCOW(PCI(pcd)->pcop)->id;
-
          //DFPRINTF((stderr,"destination is wild\n"));
 #ifdef DEBUG_PCODEPEEP
          if (index > peepBlock->nops) {
@@ -1598,6 +1614,9 @@ int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd)
            }
          }
 
+       } else if (PCI(pcd)->pcop->type == PO_LITERAL) {
+         return pCodeOpCompare(PCI(pcs)->pcop, PCI(pcd)->pcop);
+
        }
        /* FIXME - need an else to check the case when the destination 
         * isn't a wild card */
@@ -1611,7 +1630,6 @@ int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd)
 
   if((pcd->type == PC_WILD) && (pcs->type == PC_OPCODE)) {
 
-
     index = PCW(pcd)->id;
 #ifdef PCODE_DEBUG
     DFPRINTF((stderr,"%s comparing wild cards\n",__FUNCTION__));
@@ -1687,12 +1705,12 @@ void pCodePeepClrVars(pCodePeep *pcp)
   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++)
@@ -1934,11 +1952,8 @@ int pCodePeepMatchRule(pCode *pc)
       }
     }
 
-    if(matched) {
+    if(matched && pcin) {
 
-      //pCode *pcr = peepBlock->replace.pb->pcHead;
-      //if(pcr) pcr->print(stderr,pcr);
-      
       /* 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.
@@ -1948,11 +1963,16 @@ int pCodePeepMatchRule(pCode *pc)
        * 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) )
        matched = 0;
 
-      if(!matched) fprintf(stderr,"failed on conditions\n");
+      //fprintf(stderr," condition results = %d\n",pCodeSearchCondition(pcin,peepBlock->postFalseCond));
+
+
+      //if(!matched) fprintf(stderr,"failed on conditions\n");
     }
 
     if(matched) {
@@ -1982,7 +2002,7 @@ int pCodePeepMatchRule(pCode *pc)
        pcin->prev = pc->prev;
 
 
-#if 0
+      //#if 0
       {
        /*     DEBUG    */
        /* Converted the deleted pCodes into comments */
@@ -2014,7 +2034,7 @@ int pCodePeepMatchRule(pCode *pc)
        if(pc_cline2)
          pc_cline2->pc.next = NULL;
       }
-#endif
+      //#endif
 
       if(pcin)
        pCodeDeleteChain(pc,pcin);
index 5a5ebbff9b316210750f5e5ab0ac6e943f346835..5b0b9d92c407394fac5138960dd6c46a01801d8c 100644 (file)
@@ -38,6 +38,7 @@
 
 extern void pCodeInsertAfter(pCode *pc1, pCode *pc2);
 extern void dbg_dumpregusage(void);
+extern pCode * findPrevInstruction(pCode *pci);
 void unlinkpCode(pCode *pc);
 
 int total_registers_saved=0;
@@ -71,45 +72,47 @@ void dbg_regusage(set *fregs)
 
   for (reg = setFirstItem(fregs) ; reg ;
        reg = setNextItem(fregs)) {
-    
-    fprintf (stderr, "%s  addr=0x%03x rIdx=0x%03x",
-            reg->name,
-            reg->address,
-            reg->rIdx);
-
-    pcfl = setFirstItem(reg->reglives.usedpFlows);
-    if(pcfl)
-      fprintf(stderr, "\n   used in seq");
-
-    while(pcfl) {
-      fprintf(stderr," 0x%03x",pcfl->seq);
-      pcfl = setNextItem(reg->reglives.usedpFlows);
-    }
 
-    pcfl = setFirstItem(reg->reglives.assignedpFlows);
-    if(pcfl)
-      fprintf(stderr, "\n   assigned in seq");
+    if(elementsInSet(reg->reglives.usedpCodes)) {
+    
+      fprintf (stderr, "%s  addr=0x%03x rIdx=0x%03x",
+              reg->name,
+              reg->address,
+              reg->rIdx);
 
-    while(pcfl) {
-      fprintf(stderr," 0x%03x",pcfl->seq);
-      pcfl = setNextItem(reg->reglives.assignedpFlows);
-    }
+      pcfl = setFirstItem(reg->reglives.usedpFlows);
+      if(pcfl)
+       fprintf(stderr, "\n   used in seq");
 
-    pc = setFirstItem(reg->reglives.usedpCodes);
-    if(pc)
-      fprintf(stderr, "\n   used in instructions ");
+      while(pcfl) {
+       fprintf(stderr," 0x%03x",pcfl->seq);
+       pcfl = setNextItem(reg->reglives.usedpFlows);
+      }
 
-    while(pc) {
-      pcfl = PCODE(PCI(pc)->pcflow);
+      pcfl = setFirstItem(reg->reglives.assignedpFlows);
       if(pcfl)
-       fprintf(stderr," 0x%03x:",pcfl->seq);
-      fprintf(stderr,"0x%03x",pc->seq);
+       fprintf(stderr, "\n   assigned in seq");
 
-      pc = setNextItem(reg->reglives.usedpCodes);
-    }
+      while(pcfl) {
+       fprintf(stderr," 0x%03x",pcfl->seq);
+       pcfl = setNextItem(reg->reglives.assignedpFlows);
+      }
+
+      pc = setFirstItem(reg->reglives.usedpCodes);
+      if(pc)
+       fprintf(stderr, "\n   used in instructions ");
 
-    fprintf(stderr, "\n");
+      while(pc) {
+       pcfl = PCODE(PCI(pc)->pcflow);
+       if(pcfl)
+         fprintf(stderr," 0x%03x:",pcfl->seq);
+       fprintf(stderr,"0x%03x",pc->seq);
+
+       pc = setNextItem(reg->reglives.usedpCodes);
+      }
 
+      fprintf(stderr, "\n");
+    }
   }
 }
 
@@ -167,7 +170,7 @@ void pCodeRegMapLiveRangesInFlow(pCodeFlow *pcfl)
 
       addSetIfnotP(& (PCFL(pcfl)->registers), reg);
 
-      if(PCC_REGISTER & PCI(pc)->inCond)
+      if((PCC_REGISTER | PCC_LITERAL) & PCI(pc)->inCond)
        addSetIfnotP(& (reg->reglives.usedpFlows), pcfl);
 
       if(PCC_REGISTER & PCI(pc)->outCond)
@@ -217,7 +220,7 @@ void pCodeRegMapLiveRanges(pBlock *pb)
 
   }
 
-  //dbg_dumpregusage();
+//  dbg_dumpregusage();
 
 }
 
@@ -306,16 +309,25 @@ void RemoveUnusedRegisters(void)
  *-----------------------------------------------------------------*/
 static void Remove2pcodes(pCode *pcflow, pCode *pc1, pCode *pc2, regs *reg)
 {
+  if(!reg)
+    return;
+
+  if(pc1) {
+    deleteSetItem (&(reg->reglives.usedpCodes),pc1);
+    pc1->destruct(pc1);
+  }
 
-  deleteSetItem (&(reg->reglives.usedpCodes),pc1);
-  deleteSetItem (&(reg->reglives.usedpCodes),pc2);
-  deleteSetItem (&(PCFL(pcflow)->registers), reg);
+  if(pc2) {
+    deleteSetItem (&(reg->reglives.usedpCodes),pc2);
+    pc2->destruct(pc2);
 
-  pc1->destruct(pc1);
-  pc2->destruct(pc2);
+    deleteSetItem (&(PCFL(pcflow)->registers), reg);
+
+    reg->isFree = 1;
+    reg->wasUsed = 0;
+
+  }
 
-  reg->isFree = 1;
-  reg->wasUsed = 0;
   pCodeRegMapLiveRangesInFlow(PCFL(pcflow));
 }
 
@@ -353,6 +365,7 @@ void OptimizeRegUsage(set *fregs)
 
 
   while(fregs) {
+      pCode *pcfl_used, *pcfl_assigned;
 
     /* Step through the set by directly accessing the 'next' pointer.
      * We could also step through by using the set API, but the 
@@ -362,25 +375,28 @@ void OptimizeRegUsage(set *fregs)
     reg = fregs->item;
     fregs = fregs->next;
 
-    used = elementsInSet(reg->reglives.usedpCodes);
 
+    pcfl_used = setFirstItem(reg->reglives.usedpFlows);
+    pcfl_assigned = setFirstItem(reg->reglives.assignedpFlows);
+
+    used = elementsInSet(reg->reglives.usedpCodes);
     if(used == 2) { 
 
-      pCode *pcfl_used, *pcfl_assigned;
+      /*
+       * In this section, all registers that are used in only in two 
+       * instructions are examined. If possible, they're optimized out.
+       */
+
       pCode *pc1, *pc2;
-      pCode *t;
+      pCode *pct1, *pct2; /* two temporaries */
+      regs  *reg1, *reg2;
 
-      /* This register has only been used twice. Chances are we can
-        get rid of it */
 /*
       fprintf (stderr, "OptimizeRegUsage: %s  addr=0x%03x rIdx=0x%03x  used=%d\n",
               reg->name,
               reg->address,
               reg->rIdx, used);
 */
-      pcfl_used = setFirstItem(reg->reglives.usedpFlows);
-      pcfl_assigned = setFirstItem(reg->reglives.assignedpFlows);
-
       pc1 = setFirstItem(reg->reglives.usedpCodes);
       pc2 = setNextItem(reg->reglives.usedpCodes);
 
@@ -390,39 +406,57 @@ void OptimizeRegUsage(set *fregs)
           expected case - the register has been assigned a value and is
           subsequently used 
        */
+
        //fprintf(stderr," used only twice\n");
        if(pcfl_used->seq == pcfl_assigned->seq) {
 
          //fprintf(stderr, "  and used in same flow\n");
          if(pc2->seq < pc1->seq) {
-           t = pc2;
+           pct1 = pc2;
            pc2 = pc1;
-           pc1 = t;
+           pc1 = pct1;
          }
 
          //pc1->print(stderr,pc1);
          //pc2->print(stderr,pc2);
 
 
-         /* ADHOC pattern checking */
+         /* ADHOC pattern checking 
+          * Now look for specific sequences that are easy to optimize.
+          * Many of these sequences are characteristic of the compiler
+          * (i.e. it'd probably be a waste of time to apply these adhoc
+          * checks to hand written assembly.)
+          * 
+          */
          if((PCI(pc1)->op == POC_CLRF) && (PCI(pc2)->op == POC_MOVFW) ){
+
+           /*
+                clrf  reg
+                stuff...
+                movf  reg,w
+
+                can be replaced with
+
+                stuff...
+                movlw 0
+           */
+
            pCode *newpc;
            //fprintf(stderr, "   CLRF/MOVFW. instruction after MOVFW is:\n");
-           t = findNextInstruction(pc2->next);
+           pct1 = findNextInstruction(pc2->next);
            //t->print(stderr,t);
 
-           if(PCI(t)->op == POC_MOVWF) {
-             newpc = newpCode(POC_CLRF, PCI(t)->pcop);
+           if(PCI(pct1)->op == POC_MOVWF) {
+             newpc = newpCode(POC_CLRF, PCI(pct1)->pcop);
+             pct1->destruct(pct1);
            } else {
              newpc = newpCode(POC_MOVLW, newpCodeOpLit(0));
            }
 
+           pCodeInsertAfter(pc2, newpc);
            PCI(newpc)->pcflow = PCFL(pcfl_used);
-           newpc->seq = t->seq;
-
-           pCodeInsertAfter(t, newpc);
+           newpc->seq = pc2->seq;
 
-           t->destruct(t);
            Remove2pcodes(pcfl_used, pc1, pc2, reg);
            total_registers_saved++;  // debugging stats.
 
@@ -432,21 +466,54 @@ void OptimizeRegUsage(set *fregs)
            Remove2pcodes(pcfl_used, pc1, pc2, reg);
            total_registers_saved++;  // debugging stats.
 
-         }  else if((PCI(pc1)->op == POC_MOVWF) && (PCI(pc2)->op == POC_MOVFW) ){
-           //fprintf(stderr, "   MOVWF/MOVFW. instruction after MOVFW is:\n");
-           t = findNextInstruction(pc2->next);
-           // t->print(stderr,t);
-
-           if(PCI(t)->op == POC_MOVWF) {
-             regs *nextreg = getRegFromInstruction(t);
-             if(nextreg && !regUsedinRange(pc1,pc2,nextreg)) {
-               t->seq = pc1->seq;
-               unlinkpCode(t);
-               pCodeInsertAfter(pc1,t);
+         }  else if(PCI(pc1)->op == POC_MOVWF) {
+
+           pct2 = findNextInstruction(pc2->next);
+
+           if(PCI(pc2)->op == POC_MOVFW) {
+             //fprintf(stderr, "   MOVWF/MOVFW. instruction after MOVFW is:\n");
+             // t->print(stderr,t);
+
+             if(PCI(pct2)->op == POC_MOVWF) {
+               reg2 = getRegFromInstruction(pct2);
+               if(reg2 && !regUsedinRange(pc1,pc2,reg2)) {
+                 pct2->seq = pc1->seq;
+                 unlinkpCode(pct2);
+                 pCodeInsertAfter(pc1,pct2);
+                 Remove2pcodes(pcfl_used, pc1, pc2, reg);
+                 total_registers_saved++;  // debugging stats.
+                 continue;
+               }
+             }
+           }
+
+           pct1 = findPrevInstruction(pc1->prev);
+           if(pct1 && 
+              (PCI(pct1)->pcflow == PCI(pc1)->pcflow) && 
+              (PCI(pct1)->op == POC_MOVFW)) {
+
+             reg1 = getRegFromInstruction(pct1);
+             if(reg1 && !regUsedinRange(pc1,pc2,reg1)) {
+             /*
+               movf   reg1,w
+               movwf  reg
+
+               stuff...
+               opcode reg,w
+             */
+               pct2 = newpCode(PCI(pc2)->op, PCI(pct1)->pcop);
+               pCodeInsertAfter(pc2, pct2);
+               PCI(pct2)->pcflow = PCFL(pcfl_used);
+               pct2->seq = pc2->seq;
+
                Remove2pcodes(pcfl_used, pc1, pc2, reg);
+               Remove2pcodes(pcfl_used, pct1, NULL, reg1);
                total_registers_saved++;  // debugging stats.
+
              }
            }
+
+
          }
 
        } else {
@@ -461,52 +528,40 @@ void OptimizeRegUsage(set *fregs)
        /*
          register has been used twice without ever being assigned */
        fprintf(stderr,"WARNING %s: reg %s used without being assigned\n",__FUNCTION__,reg->name);
+
       } else {
-       fprintf(stderr,"WARNING %s: reg %s assigned without being used\n",__FUNCTION__,reg->name);
+       //fprintf(stderr,"WARNING %s: reg %s assigned without being used\n",__FUNCTION__,reg->name);
+       Remove2pcodes(pcfl_assigned, pc1, pc2, reg);
+       total_registers_saved++;  // debugging stats.
       }
     } else {
-      //if(used) fprintf (stderr, "  over used OptimizeRegUsage: %s  used=%d\n", reg->name, used);
-
-    }
 
-  }
+      if(used && !pcfl_used && pcfl_assigned) {
+       pCode *pc;
 
-#if 0
-    pcfl = setFirstItem(reg->reglives.usedpFlows);
-    if(pcfl)
-      fprintf(stderr, "\n   used in seq");
+       //fprintf(stderr,"WARNING %s: reg %s assigned without being used\n",__FUNCTION__,reg->name);
 
-    while(pcfl) {
-      fprintf(stderr," 0x%03x",pcfl->seq);
-      pcfl = setNextItem(reg->reglives.usedpFlows);
-    }
+       pc = setFirstItem(reg->reglives.usedpCodes);
+       while(pc) {
+         pcfl_assigned = PCI(pc)->pcflow;
+         deleteSetItem (&(PCFL(pcfl_assigned)->registers), reg);
+         deleteSetItem (&(reg->reglives.usedpCodes),pc);
+         pc->destruct(pc);
 
-    pcfl = setFirstItem(reg->reglives.assignedpFlows);
-    if(pcfl)
-      fprintf(stderr, "\n   assigned in seq");
+         pc = setNextItem(reg->reglives.usedpCodes);
+       }
 
-    while(pcfl) {
-      fprintf(stderr," 0x%03x",pcfl->seq);
-      pcfl = setNextItem(reg->reglives.assignedpFlows);
-    }
 
-    pc = setFirstItem(reg->reglives.usedpCodes);
-    if(pc)
-      fprintf(stderr, "\n   used in instructions ");
+       reg->isFree = 1;
+       reg->wasUsed = 0;
 
-    while(pc) {
-      pcfl = PCODE(PCI(pc)->pcflow);
-      if(pcfl)
-       fprintf(stderr," 0x%03x:",pcfl->seq);
-      fprintf(stderr,"0x%03x",pc->seq);
+       total_registers_saved++;  // debugging stats.
+      }
 
-      pc = setNextItem(reg->reglives.usedpCodes);
     }
 
-    fprintf(stderr, "\n");
-
   }
-#endif
+
 }
 /*-----------------------------------------------------------------*
  * void pCodeRegOptimeRegUsage(pBlock *pb) 
@@ -522,11 +577,22 @@ void pCodeRegOptimizeRegUsage(void)
 
     /* Identify registers used in one flow sequence */
     OptimizeRegUsage(dynAllocRegs);
+    OptimizeRegUsage(dynStackRegs);
+    OptimizeRegUsage(dynDirectRegs);
 
     if(total_registers_saved != saved)
       fprintf(stderr, " *** Saved %d registers, total saved %d ***\n", total_registers_saved-saved,total_registers_saved);
 
 
   } while( passes-- && (total_registers_saved != saved));
+/*
+  fprintf(stderr,"dynamically allocated regs:\n");
+  dbg_regusage(dynAllocRegs);
+  fprintf(stderr,"stack regs:\n");
+  dbg_regusage(dynStackRegs);
+  fprintf(stderr,"direct regs:\n");
+  dbg_regusage(dynDirectRegs);
+*/
+
 
 }
index 09923399983d64151f94024ef1d9caf26390472f..be2cd557dab2b2d474a8cd39592b887a8cf60d3a 100644 (file)
@@ -199,3 +199,31 @@ replace restart {
        ; peep 6 - Removed redundant move
        movwf   %1
 }
+
+replace restart {
+       movlw   0
+       iorwf   %1,w
+} by {
+       ; peep 7 - Removed redundant move
+       movf    %1,w
+}
+
+replace restart {
+       movf    %1,w
+       movwf   %2
+       decf    %2,f
+} by {
+       ; peep 8 - Removed redundant move
+       decf    %1,w
+       movwf   %2
+}
+
+replace restart {
+       movwf   %1
+       movf    %2,w
+       xorwf   %1,w
+} by {
+       ; peep 9 - Removed redundant move
+       movwf   %1
+       xorwf   %2,w
+}
index 4e49651b5aa58e00fe96bfeed9bcf9a35362a3ec..a330ece3593f856b0cac826e5c20d26b0ac83f91 100644 (file)
@@ -40,12 +40,20 @@ enum
     X12_IDX, CND_IDX
   };
 
-
-#define REG_PTR 0x01
-#define REG_GPR 0x02
-#define REG_CND 0x04
-#define REG_SFR 0x08
-#define REG_STK 0x10  /* Use a register as a psuedo stack */
+enum {
+ REG_PTR=1,
+ REG_GPR,
+ REG_CND,
+ REG_SFR,
+ REG_STK,
+ REG_TMP
+};
+//#define REG_PTR 0x01
+//#define REG_GPR 0x02
+//#define REG_CND 0x04
+//#define REG_SFR 0x08
+//#define REG_STK 0x10  /* Use a register as a psuedo stack */
+//#define REG_TMP 0x20  
 
 /* definition for the registers */
 typedef struct regs
index cf09e5c3fe92f2fbe0a942aa9414d550c0e84914..27cc34cbe2cf4a3ac8a5c93e2fc52763b7d7e9f6 100644 (file)
@@ -1,5 +1,5 @@
 
-unsigned char success = 0;
+unsigned char failures = 0;
 unsigned char dummy = 0;
 
 unsigned char uchar0=0;
@@ -47,7 +47,7 @@ void main(void)
   //incptr(&uchar0);
   inc(uchar0);
   if(uchar0 !=2)
-    success++;
+    failures++;
 
   uchar0 = 2;
   uchar1 = 1;
@@ -55,7 +55,7 @@ void main(void)
   nested_call(uchar2);
 
   if(uchar0 !=4)
-    success++;
+    failures++;
 
   done();
 }
index 95eca6417ef5a3a46509af38d5c089d1dd1e7029..6684058fd9e0e98d833502f3903367c4089e9bfa 100755 (executable)
@@ -12,5 +12,5 @@ fi
 echo "load s $1" > $2
 echo "break e _done" >> $2
 echo "run" >> $2
-echo "x _success" >> $2
+echo "x _failures" >> $2
 echo "abort_gpsim_now" >> $2
index 548d3dbd262fc5186ca9a68a32ebaa06fb657771..55c60bd5e4382fd6d7cfd3cb8b01588a5ba73877 100755 (executable)
@@ -13,9 +13,9 @@ LOGFILE=$2
 touch $2
 echo "Test $GPSIM_SCRIPT" >> $LOGFILE
 gpsim --cli -c $GPSIM_SCRIPT $2> test
-grep "success " test | grep "= 0x0"
+grep "failures " test | grep "= 0x0"
 if [ $? -eq 0 ] ; then
   echo "PASSED" >> $LOGFILE
 else
   echo "FAILED" >> $LOGFILE
-fi
\ No newline at end of file
+fi