Registers used inline were not getting allocated.
[fw/sdcc] / src / pic / pcode.c
index 2acf43f53ee03805b66d5a4acc2a6f8822216b1d..3dcb4748ae08af43ea1155c28713a7cf4faaa34f 100644 (file)
@@ -83,7 +83,8 @@ int GpcFlowSeq = 1;
 extern void RemoveUnusedRegisters(void);
 extern void RegsUnMapLiveRanges(void);
 extern void BuildFlowTree(pBlock *pb);
-extern void pCodeRegOptimizeRegUsage(void);
+extern void pCodeRegOptimizeRegUsage(int level);
+extern int picIsInitialized(void);
 
 /****************************************************************/
 /*                      Forward declarations                    */
@@ -434,6 +435,27 @@ pCodeInstruction pciCLRW = {
   PCC_W  // outCond
 };
 
+pCodeInstruction pciCLRWDT = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_CLRWDT,
+  "CLRWDT",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
+  NULL, // operand
+  NULL, // flow block
+  NULL, // C source 
+  0,    // num ops
+  0,0,  // dest, bit instruction
+  0,0,  // branch, skip
+  POC_NOP,
+  PCC_NONE, // inCond
+  PCC_NONE  // outCond
+};
+
 pCodeInstruction pciDECF = {
   {PC_OPCODE, NULL, NULL, 0, NULL, 
    //   genericAnalyze,
@@ -1295,6 +1317,7 @@ void pic14initMnemonics(void)
   pic14Mnemonics[POC_COMFW] = &pciCOMFW;
   pic14Mnemonics[POC_CLRF] = &pciCLRF;
   pic14Mnemonics[POC_CLRW] = &pciCLRW;
+  pic14Mnemonics[POC_CLRWDT] = &pciCLRWDT;
   pic14Mnemonics[POC_DECF] = &pciDECF;
   pic14Mnemonics[POC_DECFW] = &pciDECFW;
   pic14Mnemonics[POC_DECFSZ] = &pciDECFSZ;
@@ -1358,7 +1381,7 @@ int getpCode(char *mnem,unsigned dest)
   while(pci) {
 
     if(STRCASECMP(pci->mnemonic, mnem) == 0) {
-      if((pci->num_ops <= 1) || (pci->isModReg == dest))
+      if((pci->num_ops <= 1) || (pci->isModReg == dest) || (pci->isBitInst))
        return(pci->op);
     }
 
@@ -2083,6 +2106,9 @@ pCodeOp *newpCodeOpBit(char *s, int bit, int inBitSpace)
   PCORB(pcop)->bit = bit;
   PCORB(pcop)->inBitSpace = inBitSpace;
 
+  /* pCodeOpBit is derived from pCodeOpReg. We need to init this too */
+  PCOR(pcop)->r = NULL;
+  PCOR(pcop)->rIdx = 0;
   return pcop;
 }
 
@@ -2110,7 +2136,6 @@ pCodeOp *newpCodeOpReg(int rIdx)
 
     if(PCOR(pcop)->r)
       PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
-    //fprintf(stderr, "newpcodeOpReg - rIdx = %d\n", PCOR(pcop)->r->rIdx);
   }
 
   pcop->type = PCOR(pcop)->r->pc_type;
@@ -2155,6 +2180,13 @@ pCodeOp *newpCodeOp(char *name, PIC_OPTYPE type)
     pcop = newpCodeOpReg(-1);
     break;
 
+  case PO_GPR_REGISTER:
+    if(name)
+      pcop = newpCodeOpRegFromStr(name);
+    else
+      pcop = newpCodeOpReg(-1);
+    break;
+
   default:
     pcop = Safe_calloc(1,sizeof(pCodeOp) );
     pcop->type = type;
@@ -2224,16 +2256,22 @@ void pCodeReadCodeTable(void)
 /*-----------------------------------------------------------------*/
 void addpCode2pBlock(pBlock *pb, pCode *pc)
 {
+
+  if(!pc)
+    return;
+
   if(!pb->pcHead) {
     /* If this is the first pcode to be added to a block that
      * was initialized with a NULL pcode, then go ahead and
      * make this pcode the head and tail */
     pb->pcHead  = pb->pcTail = pc;
   } else {
+    //    if(pb->pcTail)
     pb->pcTail->next = pc;
+
     pc->prev = pb->pcTail;
-    //pc->next = NULL;
     pc->pb = pb;
+
     pb->pcTail = pc;
   }
 }
@@ -2678,8 +2716,13 @@ static void genericPrint(FILE *of, pCode *pc)
     break;
 
   case PC_FLOW:
-    if(debug_verbose)
-      fprintf(of,";<>Start of new flow, seq=%d\n",pc->seq);
+    if(debug_verbose) {
+      fprintf(of,";<>Start of new flow, seq=0x%x",pc->seq);
+      if(PCFL(pc)->ancestor)
+       fprintf(of," ancestor = 0x%x", PCODE(PCFL(pc)->ancestor)->seq);
+      fprintf(of,"\n");
+
+    }
     break;
 
   case PC_CSOURCE:
@@ -3339,14 +3382,22 @@ void BuildFlow(pBlock *pb)
       InsertpFlow(pc, &pflow);
       seq = 0;
 
-    } else if (checkLabel(pc)) { //(PCI_HAS_LABEL(pc)) {
+    } else if (checkLabel(pc)) { 
 
       /* This instruction marks the beginning of a
        * new flow segment */
 
       pc->seq = 0;
-      seq = 1; 
-      InsertpFlow(findPrevInstruction(pc->prev), &pflow);
+      seq = 1;
+
+      /* If the previous pCode is not a flow object, then 
+       * insert a new flow object. (This check prevents 
+       * two consecutive flow objects from being insert in
+       * the case where a skip instruction preceeds an
+       * instruction containing a label.) */
+
+      if(last_pci && (PCI(last_pci)->pcflow == PCFL(pflow)))
+       InsertpFlow(findPrevInstruction(pc->prev), &pflow);
 
       PCI(pc)->pcflow = PCFL(pflow);
       
@@ -3580,8 +3631,15 @@ void LinkFlow_pCode(pCodeInstruction *from, pCodeInstruction *to)
 
 }
 
-/*-----------------------------------------------------------------*/
-/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*
+ * void LinkFlow(pBlock *pb)
+ *
+ * In BuildFlow, the PIC code has been partitioned into contiguous
+ * non-branching segments. In LinkFlow, we determine the execution
+ * order of these segments. For example, if one of the segments ends
+ * with a skip, then we know that there are two possible flow segments
+ * to which control may be passed.
+ *-----------------------------------------------------------------*/
 void LinkFlow(pBlock *pb)
 {
   pCode *pc=NULL;
@@ -3622,7 +3680,7 @@ void LinkFlow(pBlock *pb)
       //pc->print(stderr,pc);
 
       if(!(pcol && isPCOLAB(pcol))) {
-       if((PCI(pc)->op != POC_RETLW) && (PCI(pc)->op != POC_RETURN) && (PCI(pc)->op != POC_CALL)) {
+       if((PCI(pc)->op != POC_RETLW) && (PCI(pc)->op != POC_RETURN) && (PCI(pc)->op != POC_CALL) && (PCI(pc)->op != POC_RETFIE) ) {
          pc->print(stderr,pc);
          fprintf(stderr, "ERROR: %s, branch instruction doesn't have label\n",__FUNCTION__);
        }
@@ -3656,6 +3714,8 @@ void LinkFlow(pBlock *pb)
     
   }
 }
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
 
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
@@ -4315,7 +4375,11 @@ void pBlockMergeLabels(pBlock *pb)
 
   /* Now loop through the pBlock and merge the labels with the opcodes */
 
-  for(pc = pb->pcHead; pc; pc = pc->next) {
+  pc = pb->pcHead;
+  //  for(pc = pb->pcHead; pc; pc = pc->next) {
+
+  while(pc) {
+    pCode *pcn = pc->next;
 
     if(pc->type == PC_LABEL) {
 
@@ -4323,8 +4387,6 @@ void pBlockMergeLabels(pBlock *pb)
       //fprintf(stderr,"Checking label key = %d\n",PCL(pc)->key);
       if((pcnext = findNextInstruction(pc) )) {
 
-       pCode *pcn = pc->next;
-
        // Unlink the pCode label from it's pCode chain
        unlinkpCode(pc);
        
@@ -4340,10 +4402,7 @@ void pBlockMergeLabels(pBlock *pb)
        pbr->pc = pc;
        pbr->next = NULL;
 
-
        PCI(pcnext)->label = pBranchAppend(PCI(pcnext)->label,pbr);
-      
-       pc = pcn;
 
       } else {
        fprintf(stderr, "WARNING: couldn't associate label %s with an instruction\n",PCL(pc)->label);
@@ -4353,18 +4412,15 @@ void pBlockMergeLabels(pBlock *pb)
       /* merge the source line symbolic info into the next instruction */
       if((pcnext = findNextInstruction(pc) )) {
 
-       pCode *pcn = pc->next;
-
        // Unlink the pCode label from it's pCode chain
        unlinkpCode(pc);
        PCI(pcnext)->cline = PCCS(pc);
        //fprintf(stderr, "merging CSRC\n");
        //genericPrint(stderr,pcnext);
-       pc = pcn;
       }
 
     }
-
+    pc = pcn;
   }
   pBlockRemoveUnusedLabels(pb);
 
@@ -4579,9 +4635,14 @@ void mergepBlocks(char dbName)
 /*-----------------------------------------------------------------*/
 /* AnalyzeFlow - Examine the flow of the code and optimize         */
 /*                                                                 */
+/* level 0 == minimal optimization                                 */
+/*   optimize registers that are used only by two instructions     */
+/* level 1 == maximal optimization                                 */
+/*   optimize by looking at pairs of instructions that use the     */
+/*   register.                                                     */
 /*-----------------------------------------------------------------*/
 
-void AnalyzeFlow(void)
+void AnalyzeFlow(int level)
 {
   static int times_called=0;
 
@@ -4638,10 +4699,10 @@ void AnalyzeFlow(void)
    * In this phase, the individual flow blocks are examined
    * to determine their order of excution.
    */
-  /*
+
   for(pb = the_pFile->pbHead; pb; pb = pb->next)
     BuildFlowTree(pb);
-  */
+
 
   /* Phase x - Flow Analysis - Used Banks
    *
@@ -4659,7 +4720,7 @@ void AnalyzeFlow(void)
   RemoveUnusedRegisters();
 
   //  for(pb = the_pFile->pbHead; pb; pb = pb->next)
-  pCodeRegOptimizeRegUsage();
+  pCodeRegOptimizeRegUsage(level);
 
   OptimizepCode('*');
 
@@ -4702,17 +4763,29 @@ void AnalyzeBanking(void)
 {
   pBlock  *pb;
 
+  if(!picIsInitialized()) {
+    fprintf(stderr,"Temporary ERROR: at the moment you have to use\n");
+    fprintf(stderr,"an include file create by inc2h.pl. See SDCC source:\n");
+    fprintf(stderr,"support/scripts/inc2h.pl\n");
+    fprintf(stderr,"this is a nuisance bug that will be fixed shortly\n");
+
+    exit(1);
+  }
+
   /* Phase x - Flow Analysis - Used Banks
    *
    * In this phase, the individual flow blocks are examined
    * to determine the Register Banks they use
    */
 
-  AnalyzeFlow();
-  AnalyzeFlow();
+  AnalyzeFlow(0);
+  AnalyzeFlow(1);
 
   for(pb = the_pFile->pbHead; pb; pb = pb->next)
     BanksUsedFlow(pb);
+  for(pb = the_pFile->pbHead; pb; pb = pb->next)
+    FixRegisterBanking(pb);
+
 }
 
 /*-----------------------------------------------------------------*/