- Added setReverse to reverse the order of a set
[fw/sdcc] / src / pic / pcode.c
index 99a467fccf7fa8000baad737dae74fd6a28961ee..03ab39ad954e8cf26cba52fd6380af9da7c960ac 100644 (file)
@@ -70,6 +70,7 @@ static void pCodeOpPrint(FILE *of, pCodeOp *pcop);
 static char *get_op( pCodeInstruction *pcc);
 int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd);
 int pCodePeepMatchRule(pCode *pc);
+void pBlockStats(FILE *of, pBlock *pb);
 
 
 pCodeInstruction pciADDWF = {
@@ -958,8 +959,10 @@ void copypCode(FILE *of, char dbName)
     return;
 
   for(pb = the_pFile->pbHead; pb; pb = pb->next) {
-    if(getpBlock_dbName(pb) == dbName)
+    if(getpBlock_dbName(pb) == dbName) {
+      pBlockStats(of,pb);
       printpBlock(of,pb);
+    }
   }
 
 }
@@ -999,6 +1002,13 @@ void pcode_test(void)
     }
   }
 }
+/*-----------------------------------------------------------------*/
+/* int RegCond(pCodeOp *pcop) - if pcop points to the STATUS reg-  */
+/*      ister, RegCond will return the bit being referenced.       */
+/*                                                                 */
+/* fixme - why not just OR in the pcop bit field                   */
+/*-----------------------------------------------------------------*/
+
 static int RegCond(pCodeOp *pcop)
 {
 
@@ -1175,14 +1185,15 @@ pCode *newpCodeFunction(char *mod,char *f)
 
 }
 
+/*-----------------------------------------------------------------*/
+/* pCodeLabelDestruct - free memory used by a label.               */
+/*-----------------------------------------------------------------*/
 static void pCodeLabelDestruct(pCode *pc)
 {
 
   if(!pc)
     return;
 
-  unlinkPC(pc);
-
   if((pc->type == PC_LABEL) && PCL(pc)->label)
     free(PCL(pc)->label);
 
@@ -1252,7 +1263,7 @@ pBlock *newpBlock(void)
 }
 
 /*-----------------------------------------------------------------*/
-/* newpCodeChai0n - create a new chain of pCodes                    */
+/* newpCodeChain - create a new chain of pCodes                    */
 /*-----------------------------------------------------------------*
  *
  *  This function will create a new pBlock and the pointer to the
@@ -1300,6 +1311,8 @@ pCodeOp *newpCodeOpLabel(int key)
   return pcop;
 }
 
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
 pCodeOp *newpCodeOpLit(int lit)
 {
   char *s = buffer;
@@ -1321,6 +1334,8 @@ pCodeOp *newpCodeOpLit(int lit)
   return pcop;
 }
 
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
 pCodeOp *newpCodeOpWild(int id, pCodePeep *pcp, pCodeOp *subtype)
 {
   char *s = buffer;
@@ -1345,6 +1360,8 @@ pCodeOp *newpCodeOpWild(int id, pCodePeep *pcp, pCodeOp *subtype)
   return pcop;
 }
 
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
 pCodeOp *newpCodeOpBit(char *s, int bit, int inBitSpace)
 {
   pCodeOp *pcop;
@@ -1514,6 +1531,8 @@ static void genericDestruct(pCode *pc)
 }
 
 
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
 void pBlockRegs(FILE *of, pBlock *pb)
 {
 
@@ -1536,6 +1555,9 @@ static char *get_op( pCodeInstruction *pcc)
     switch(pcc->pcop->type) {
 
     case PO_FSR:
+      r = pic14_regWithIdx(PCOR(pcc->pcop)->rIdx);
+      return r->name;
+      break;
     case PO_GPR_TEMP:
     case PO_GPR_BIT:
       r = pic14_regWithIdx(PCOR(pcc->pcop)->r->rIdx);
@@ -1645,7 +1667,7 @@ static void genericPrint(FILE *of, pCode *pc)
     // If the opcode has a label, print that first
     {
       pBranch *pbl = pc->label;
-      while(pbl) {
+      while(pbl && pbl->pc) {
        if(pbl->pc->type == PC_LABEL)
          pCodePrintLabel(of, pbl->pc);
        pbl = pbl->next;
@@ -1755,16 +1777,28 @@ static void pCodePrintLabel(FILE *of, pCode *pc)
 
 }
 /*-----------------------------------------------------------------*/
-static void  unlinkpCodeFromBranch(pBranch *pb , pCode *pc)
+/* unlinkpCodeFromBranch - Search for a label in a pBranch and     */
+/*                         remove it if it is found.               */
+/*-----------------------------------------------------------------*/
+static void unlinkpCodeFromBranch(pCode *pcl , pCode *pc)
 {
   pBranch *b, *bprev;
 
   bprev = NULL;
-  b = pb;
+  b = pcl->label;
   while(b) {
     if(b->pc == pc) {
-      if(bprev)
-       bprev->next = b->next;
+
+      /* Found a label */
+      if(bprev) {
+       bprev->next = b->next;  /* Not first pCode in chain */
+       free(b);
+      } else {
+       pc->destruct(pc);
+       pcl->label = b->next;   /* First pCode in chain */
+       free(b);
+      }
+      return;  /* A label can't occur more than once */
     }
     bprev = b;
     b = b->next;
@@ -1772,6 +1806,8 @@ static void  unlinkpCodeFromBranch(pBranch *pb , pCode *pc)
 
 }
 
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
 static pBranch * pBranchAppend(pBranch *h, pBranch *n)
 {
   pBranch *b;
@@ -1902,6 +1938,8 @@ static void genericAnalyze(pCode *pc)
        } else
          npc = npc->next;
       }
+      /* reached the end of the pcode chain without finding
+       * an instruction we could link to. */
     }
   }
 }
@@ -2022,6 +2060,8 @@ static void AnalyzeRETURN(pCode *pc)
 
 }
 
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
 
 void AnalyzepBlock(pBlock *pb)
 {
@@ -2036,7 +2076,7 @@ void AnalyzepBlock(pBlock *pb)
       if(PCI(pc)->pcop && PCI(pc)->pcop->type == PO_GPR_TEMP) {
 
        /* Loop through all of the registers declared so far in
-          this block and see if we find this new there */
+          this block and see if we find this one there */
 
        regs *r = setFirstItem(pb->registers);
 
@@ -2062,6 +2102,8 @@ void AnalyzepBlock(pBlock *pb)
   }
 }
 
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
 int OptimizepBlock(pBlock *pb)
 {
   pCode *pc;
@@ -2128,13 +2170,13 @@ void pBlockRemoveUnusedLabels(pBlock *pb)
       fprintf(stderr," !!! REMOVED A LABEL !!! key = %d\n", pcl->key);
 
       if(pc->type == PC_LABEL) {
-       //unlinkPC(pc);
+       unlinkPC(pc);
        pCodeLabelDestruct(pc);
       } else {
-       unlinkpCodeFromBranch(pc->label, pc);
-       if(pc->label->next == NULL && pc->label->pc == NULL) {
+       unlinkpCodeFromBranch(pc, PCODE(pcl));
+       /*if(pc->label->next == NULL && pc->label->pc == NULL) {
          free(pc->label);
-       }
+       }*/
       }
 
     }
@@ -2234,25 +2276,32 @@ void AnalyzepCode(char dbName)
   pCode *pc;
   pBranch *pbr;
 
+  int i,changes;
+
   if(!the_pFile)
     return;
 
   fprintf(stderr," Analyzing pCode");
 
-  /* First, merge the labels with the instructions */
-  for(pb = the_pFile->pbHead; pb; pb = pb->next) {
-    if('*' == dbName || getpBlock_dbName(pb) == dbName) {
+  changes = 0;
+  i = 0;
+  do {
+    /* First, merge the labels with the instructions */
+    for(pb = the_pFile->pbHead; pb; pb = pb->next) {
+      if('*' == dbName || getpBlock_dbName(pb) == dbName) {
 
-      fprintf(stderr," analyze and merging block %c\n",dbName);
-      pBlockMergeLabels(pb);
-      AnalyzepBlock(pb);
+       fprintf(stderr," analyze and merging block %c\n",dbName);
+       pBlockMergeLabels(pb);
+       AnalyzepBlock(pb);
+      }
     }
-  }
 
-  for(pb = the_pFile->pbHead; pb; pb = pb->next) {
-    if('*' == dbName || getpBlock_dbName(pb) == dbName)
-      OptimizepBlock(pb);
-  }
+    for(pb = the_pFile->pbHead; pb; pb = pb->next) {
+      if('*' == dbName || getpBlock_dbName(pb) == dbName)
+       changes += OptimizepBlock(pb);
+    }
+      
+  } while(changes && (i++ < MAX_PASSES));
 
   /* Now build the call tree.
      First we examine all of the pCodes for functions.
@@ -2375,26 +2424,28 @@ void pBlockStats(FILE *of, pBlock *pb)
   pCode *pc;
   regs  *r;
 
-  fprintf(of,"***\n  pBlock Stats\n***\n");
+  fprintf(of,";***\n;  pBlock Stats\n;***\n");
 
   // for now just print the first element of each set
   pc = setFirstItem(pb->function_entries);
   if(pc) {
-    fprintf(of,"entry\n");
+    fprintf(of,";entry:  ");
     pc->print(of,pc);
   }
   pc = setFirstItem(pb->function_exits);
   if(pc) {
-    fprintf(of,"has an exit\n");
-    pc->print(of,pc);
+    fprintf(of,";has an exit\n");
+    //pc->print(of,pc);
   }
 
   pc = setFirstItem(pb->function_calls);
   if(pc) {
-    fprintf(of,"functions called\n");
+    fprintf(of,";functions called:\n");
 
     while(pc) {
-      pc->print(of,pc);
+      if(pc->type == PC_OPCODE && PCI(pc)->op == POC_CALL) {
+       fprintf(of,";   %s\n",get_op(PCI(pc)));
+      }
       pc = setNextItem(pb->function_calls);
     }
   }
@@ -2403,10 +2454,10 @@ void pBlockStats(FILE *of, pBlock *pb)
   if(r) {
     int n = elementsInSet(pb->registers);
 
-    fprintf(of,"%d compiler assigned register%c:\n",n, ( (n!=1) ? 's' : ' '));
+    fprintf(of,";%d compiler assigned register%c:\n",n, ( (n!=1) ? 's' : ' '));
 
     while (r) {
-      fprintf(of,"   %s\n",r->name);
+      fprintf(of,";   %s\n",r->name);
       r = setNextItem(pb->registers);
     }
   }
@@ -2484,10 +2535,10 @@ set *register_usage(pBlock *pb)
 
       r2 = setFirstItem(pb->registers);
 
-      while(r2) {
+      while(r2 && (r1->type != REG_STK)) {
 
        if(r2->rIdx == r1->rIdx) {
-         newreg = pic14_findFreeReg();
+         newreg = pic14_findFreeReg(REG_GPR);
 
 
          if(!newreg) {
@@ -2515,8 +2566,10 @@ set *register_usage(pBlock *pb)
     /* Collisions have been resolved. Now free the registers in the call path */
     r1 = setFirstItem(registersInCallPath);
     while(r1) {
-      newreg = pic14_regWithIdx(r1->rIdx);
-      newreg->isFree = 1;
+      if(r1->type != REG_STK) {
+       newreg = pic14_regWithIdx(r1->rIdx);
+       newreg->isFree = 1;
+      }
       r1 = setNextItem(registersInCallPath);
     }