]> git.gag.com Git - fw/sdcc/blobdiff - src/pic16/pcode.c
* src/SDCCmain.c (linkEdit): do not test for PIC16 target since, PIC16
[fw/sdcc] / src / pic16 / pcode.c
index 9d4114f820430a22eac8a9afe345d460e9e8b846..e20eb83206fbce78c8fc6da68c39329c5f22ccd4 100644 (file)
@@ -4244,26 +4244,28 @@ pCodeOp *pic16_newpCodeOpBit_simple (struct asmop *op, int offs, int bit)
 pCodeOp *pic16_newpCodeOpReg(int rIdx)
 {
   pCodeOp *pcop;
+  regs *r;
 
   pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
 
   pcop->name = NULL;
 
   if(rIdx >= 0) {
-    PCOR(pcop)->rIdx = rIdx;
-    PCOR(pcop)->r = pic16_regWithIdx(rIdx);
+       r = pic16_regWithIdx(rIdx);
+       if(!r)
+               r = pic16_allocWithIdx(rIdx);
   } else {
-    PCOR(pcop)->r = pic16_findFreeReg(REG_GPR);
+    r = pic16_findFreeReg(REG_GPR);
 
-    if(PCOR(pcop)->r)
-      PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
-    else {
+    if(!r) {
        fprintf(stderr, "%s:%d Could not find a free GPR register\n",
                __FUNCTION__, __LINE__);
        exit(-1);
     }
   }
 
+  PCOR(pcop)->rIdx = rIdx;
+  PCOR(pcop)->r = r;
   pcop->type = PCOR(pcop)->r->pc_type;
 
   return pcop;
@@ -5932,7 +5934,7 @@ static void AnalyzepBlock(pBlock *pb)
       }
       if(PCI(pc)->pcop->type == PO_GPR_REGISTER) {
        if(PCOR(PCI(pc)->pcop)->r) {
-         pic16_allocWithIdx (PCOR(PCI(pc)->pcop)->r->rIdx);
+         pic16_allocWithIdx(PCOR(PCI(pc)->pcop)->r->rIdx);                     /* FIXME! - VR */
          DFPRINTF((stderr,"found register in pblock: reg 0x%x\n",PCOR(PCI(pc)->pcop)->r->rIdx));
        } else {
          if(PCI(pc)->pcop->name)
@@ -9451,6 +9453,42 @@ static int pic16_safepCodeUnlink (pCode *pc, char *comment) {
   /* move labels to next instruction (if possible) */
   if (PCI(pc)->label && !pcnext) return 0;
 
+  /* if this is a SKIP with side-effects -- do not remove */
+  /* XXX: might try to replace this one with the side-effect only version */
+  if (isPCI_SKIP(pc)
+       && ((PCI(pc)->outCond & (PCC_REGISTER | PCC_W)) != 0))
+  {
+    pCode *newpc;
+    switch (PCI(pc)->op)
+    {
+    case POC_INCFSZ:
+    case POC_INFSNZ:
+      newpc = pic16_newpCode(POC_INCF, pic16_pCodeOpCopy( PCI(pc)->pcop ) );
+      pic16_pCodeReplace( pc, newpc );
+      return 1;
+      break;
+    case POC_INCFSZW:
+      newpc = pic16_newpCode(POC_INCFW, pic16_pCodeOpCopy( PCI(pc)->pcop ) );
+      pic16_pCodeReplace( pc, newpc );
+      return 1;
+      break;
+    case POC_DECFSZ:
+    case POC_DCFSNZ:
+      newpc = pic16_newpCode(POC_INCF, pic16_pCodeOpCopy( PCI(pc)->pcop ) );
+      pic16_pCodeReplace( pc, newpc );
+      return 1;
+      break;
+    case POC_DECFSZW:
+      newpc = pic16_newpCode(POC_INCF, pic16_pCodeOpCopy( PCI(pc)->pcop ) );
+      pic16_pCodeReplace( pc, newpc );
+      return 1;
+      break;
+    default:
+      return 0;
+    }
+    return 0;
+  }
+
   /* if previous instruction is a skip -- do not remove */
   if (pcprev && isPCI_SKIP(pcprev)) {
     if (!pic16_safepCodeUnlink (pcprev, "=DF= removed now unused SKIP")) {
@@ -10700,7 +10738,12 @@ static int pic16_pCodeIsAlive (pCode *pc) {
   while (map && map->pc != pc) map = map->next;
 
   /* no entries found? something is fishy with DF analysis... -- play safe */
-  if (!map) { fprintf (stderr, "%s: defmap not found\n", __FUNCTION__); return 1; }
+  if (!map) {
+    if (pic16_pcode_verbose) {
+      fprintf (stderr, "%s: defmap not found\n", __FUNCTION__);
+    }
+    return 1;
+  }
 
   /* remember first item assigned to pc for later use */
   lastpc = map;