* src/pic16/pcode.c (LinkFlow): fix invalid cast from pCodeLabel
[fw/sdcc] / src / pic16 / pcode.c
index e174f5543ad0c428cf15df96aad2281290cc062d..146ba2d9851074708064a24c15a0023995a62a68 100644 (file)
@@ -3804,6 +3804,8 @@ static void pCodeLabelDestruct(pCode *pc)
   if(!pc)
     return;
 
+  pic16_unlinkpCode(pc);
+
 //  if((pc->type == PC_LABEL) && PCL(pc)->label)
 //    Safe_free(PCL(pc)->label);
 
@@ -4661,10 +4663,16 @@ void pic16_unlinkpCode(pCode *pc)
     fprintf(stderr,"Unlinking: ");
     printpCode(stderr, pc);
 #endif
-    if(pc->prev)
+    if(pc->prev) {
       pc->prev->next = pc->next;
-    if(pc->next)
+    } else if (pc->pb && (pc->pb->pcHead == pc)) {
+        pc->pb->pcHead = pc->next;
+    }
+    if(pc->next) {
       pc->next->prev = pc->prev;
+    } else if (pc->pb && (pc->pb->pcTail == pc)) {
+        pc->pb->pcTail = pc->prev;
+    }
 
     /* move C source line down (or up) */
     if (isPCI(pc) && PCI(pc)->cline) {
@@ -5332,31 +5340,10 @@ void pic16_pCodeUnlink(pCode *pc)
   pBranch *pb1,*pb2;
   pCode *pc1;
 
-  if(!pc->prev || !pc->next) {
-    fprintf(stderr,"unlinking bad pCode in %s:%d\n",__FILE__,__LINE__);
-    exit(1);
-  }
-
-  /* move C source line down (or up) */
-  if (isPCI(pc) && PCI(pc)->cline) {
-    pc1 = pic16_findNextInstruction (pc->next);
-    if (pc1 && isPCI(pc1) && !PCI(pc1)->cline) {
-      PCI(pc1)->cline = PCI(pc)->cline;
-    } else {
-      pc1 = pic16_findPrevInstruction (pc->prev);
-      if (pc1 && isPCI(pc1) && !PCI(pc1)->cline)
-        PCI(pc1)->cline = PCI(pc)->cline;
-    }
+  if (!pc) {
+    return;
   }
 
-  /* first remove the pCode from the chain */
-  pc->prev->next = pc->next;
-  pc->next->prev = pc->prev;
-
-  pc->prev = pc->next = NULL;
-
-  /* Now for the hard part... */
-
   /* Remove the branches */
 
   pb1 = PCI(pc)->from;
@@ -5379,6 +5366,7 @@ void pic16_pCodeUnlink(pCode *pc)
     pb1 = pb1->next;
   }
 
+  pic16_unlinkpCode (pc);
 
 }
 #endif
@@ -6285,7 +6273,7 @@ static void LinkFlow(pBlock *pb)
       }
 
       if( (pct = findLabelinpBlock(pb,pcol)) != NULL)
-        LinkFlow_pCode(PCI(pc),PCI(pct));
+        LinkFlow_pCode(PCI(pc),PCI(pic16_findNextInstruction(pct)));
       else
         fprintf(stderr, "ERROR: %s, couldn't find label. key=%d,lab=%s\n",
                 __FUNCTION__,pcol->key,((PCOP(pcol)->name)?PCOP(pcol)->name:"-"));
@@ -6436,6 +6424,7 @@ static void insertBankSwitch(unsigned char position, pCode *pc)
 }
 
 
+#if 0
 /*-----------------------------------------------------------------*/
 /*int compareBankFlow - compare the banking requirements between   */
 /*  flow objects. */
@@ -6486,6 +6475,7 @@ static int compareBankFlow(pCodeFlow *pcflow, pCodeFlowLink *pcflowLink, int toO
   return 1;
 
 }
+#endif
 
 #if 0
 /*-----------------------------------------------------------------*/
@@ -7758,7 +7748,9 @@ void pic16_AnalyzeBanking(void)
 /*-----------------------------------------------------------------*/
 /* buildCallTree - Look at the flow and extract all of the calls.  */
 /*-----------------------------------------------------------------*/
+#if 0
 static set *register_usage(pBlock *pb);
+#endif
 
 static void buildCallTree(void    )
 {
@@ -8143,6 +8135,7 @@ static pCode *findFunction(char *fname)
   return NULL;
 }
 
+#if 0
 static void MarkUsedRegisters(set *regset)
 {
 
@@ -8156,6 +8149,7 @@ static void MarkUsedRegisters(set *regset)
     r2->wasUsed = 1;
   }
 }
+#endif
 
 static void pBlockStats(FILE *of, pBlock *pb)
 {
@@ -8226,6 +8220,7 @@ static void sequencepCode(void)
 }
 #endif
 
+#if 0
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 static set *register_usage(pBlock *pb)
@@ -8335,6 +8330,7 @@ static set *register_usage(pBlock *pb)
 
   return registers;
 }
+#endif
 
 /*-----------------------------------------------------------------*/
 /* pct2 - writes the call tree to a file                           */
@@ -8971,7 +8967,7 @@ unsigned int attachBsrInfo2pBlock (pBlock *pb, int mod)
 /* bank so that we can make sure the bytes are laid out sequentially in memory)       */
 /* TODO: Symbols with an abslute address must be handled specially!                   */
 /*------------------------------------------------------------------------------------*/
-int assignToSameBank (int bank0, int bank1, int doAbs)
+int assignToSameBank (int bank0, int bank1, int doAbs, int force)
 {
   int eff0, eff1, dummy;
   pseudoBank *pbank0, *pbank1;
@@ -9023,7 +9019,7 @@ int assignToSameBank (int bank0, int bank1, int doAbs)
 #endif
 
   if (pbank1) {
-    if (pbank0->size + pbank1->size > MAX_COMMON_BANK_SIZE) {
+    if (!force && (pbank0->size + pbank1->size > MAX_COMMON_BANK_SIZE)) {
 #if 0
       fprintf (stderr, "bank #%d: %u, bank #%d: %u --> bank #%d': %u > %u (%s,%s)\n",
                pbank0->bank, pbank0->size, pbank1->bank, pbank1->size,
@@ -9166,7 +9162,7 @@ void pic16_OptimizeBanksel ()
     bankNr = reg->address >> 8;
     node = getOrAddGNode (adj, NULL, bankNr);
     bankNr = (pseudoBankNr) getEffectiveBank (getPseudoBankNrFromOperand(reg->name));
-    assignToSameBank (node->hash, bankNr, 1);
+    assignToSameBank (node->hash, bankNr, 1, 1);
 
     assert (bankNr >= 0);
     pbank = (pseudoBank *) hTabFindByKey (coerce, bankNr % coerce->size, (void *) bankNr, &comparePtr);
@@ -9179,6 +9175,7 @@ void pic16_OptimizeBanksel ()
     } else {
       assert (pbank->bank == (reg->address >> 8));
       pbank->bank = reg->address >> 8; //FIXED_BANK;
+      pbank->size++;
     }
     //fprintf (stderr, "ABS: %s (%d bytes) at %x in bank %u\n", reg->name, reg->size, reg->address, bankNr);
   } // for reg
@@ -9197,10 +9194,11 @@ void pic16_OptimizeBanksel ()
       node1next = node1->next;
       base_symbol1 = getSymbolFromOperand (getSymFromBank (getEffectiveBank (node1->hash)), &len1);
       if (len0 == len1 && len0 > 0 && strncmp (base_symbol0, base_symbol1, len0) == 0) {
+        int res;
         // TODO: check for symbols with absolute addresses -- these might be placed across bank boundaries!
         //fprintf (stderr, "merging %s and %s\n", getSymFromBank (getEffectiveBank(node->hash)), getSymFromBank (getEffectiveBank(node1->hash)));
-        if (assignToSameBank (node->hash, node1->hash, 0)) {
-          fprintf (stderr, "%s(%d) == %s(%d)\n", base_symbol0, len0, base_symbol1, len1);
+        if (0 != (res = assignToSameBank (node->hash, node1->hash, 0, 1))) {
+          fprintf (stderr, "%s(%d) == %s(%d), res=%d\n", base_symbol0, len0, base_symbol1, len1, res);
           assert (0 && "Could not assign a symbol to a bank!");
         }
         mergeGraphNodes (node, node1);
@@ -9259,7 +9257,7 @@ void pic16_OptimizeBanksel ()
       node = getGNode (adj, max->src->data, max->src->hash);
       node1 = getGNode (adj, max->node->data, max->node->hash);
 
-      if (0 == assignToSameBank (max->src->hash, max->node->hash, 0)) {
+      if (0 == assignToSameBank (max->src->hash, max->node->hash, 0, 0)) {
         if (max->src->hash < max->node->hash)
           mergeGraphNodes (node, node1);
         else
@@ -11241,6 +11239,10 @@ static void createReachingDefinitions (pBlock *pb) {
   } // for
 
   pc = pic16_findNextInstruction (pb->pcHead);
+  if (!pc) {
+      // empty function, avoid NULL pointer dereference
+      return;
+  } // if
   todo = NULL; blacklist = NULL;
   addSetHead (&todo, PCI(pc)->pcflow);