* src/pic16/gen.c: added IS_DIRECT macro for "direct" operands,
authortecodev <tecodev@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sun, 18 Dec 2005 14:51:13 +0000 (14:51 +0000)
committertecodev <tecodev@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sun, 18 Dec 2005 14:51:13 +0000 (14:51 +0000)
  (genUnpackBits): improved code for direct operands,
  (genPackBits): improved code for literal assignment to bitfields
    and for direct destination operands (no FSR indirection),
    prevented redundant AND, fixes #1362800,
  (AccLsh): added parameter to disable masking of the result
* src/pic16/pcode.c (pic16_safepCodeUnlink): fixed to work with
  skip instructions with side-effects (like incfsz),
  (pic16_pCodeIsAlive): suppress verbose output unless pcode_verbose,
* src/pic16/pcoderegs.c (RemoveRegsFromSet): removed annoying warning
* device/lib/pic16/Makefile.common.in: added --asm=@GPASM@ to CC,
  fixes #1375263

git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@4012 4a8a32a2-be11-0410-ad9d-d568d2c75423

ChangeLog
device/lib/pic16/Makefile.common.in
src/pic16/gen.c
src/pic16/pcode.c
src/pic16/pcoderegs.c

index daa3404e4bbc8afd9ae7780743bd4575a32f20fc..70f6a31a87dc767a027574b89d73b3fcd040b850 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2005-12-18 Raphael Neider <rneider AT web.de>
+
+       * src/pic16/gen.c: added IS_DIRECT macro for "direct" operands,
+         (genUnpackBits): improved code for direct operands,
+         (genPackBits): improved code for literal assignment to bitfields
+           and for direct destination operands (no FSR indirection),
+           prevented redundant AND, fixes #1362800,
+         (AccLsh): added parameter to disable masking of the result
+       * src/pic16/pcode.c (pic16_safepCodeUnlink): fixed to work with
+         skip instructions with side-effects (like incfsz),
+         (pic16_pCodeIsAlive): suppress verbose output unless pcode_verbose,
+       * src/pic16/pcoderegs.c (RemoveRegsFromSet): removed annoying warning
+       * device/lib/pic16/Makefile.common.in: added --asm=@GPASM@ to CC,
+         fixes #1375263
+
 2005-12-10 Bernhard Held <bernhard AT bernhardheld.de>
 
        * src/SDCCicode.c (fgeniCodeAssign): fixed bug 11369874, don't use
index 842103facd7764ff0fe41c8343fe35aba5caf817..294ebd740187139b6b27767be38064aafef9239d 100644 (file)
@@ -79,7 +79,7 @@ LIBFLAGS += -c
 #################################################
 ### programs to use
 CPP    = $(topsrcdir)/../../../bin/sdcpp
-CC     = $(topsrcdir)/../../../bin/sdcc
+CC     = $(topsrcdir)/../../../bin/sdcc --asm=@GPASM@
 AS     = @GPASM@
 LD     = @GPLINK@
 LIB    = @GPLIB@
index 1debf03cbbfb0caf565614ca970ff7dfb4b3677f..8e9cd666337f2417accd4efa5dab6598464024ea 100644 (file)
@@ -63,6 +63,7 @@
 #define PIC_IS_DATA_PTR(x)     (IS_DATA_PTR(x) || IS_FARPTR(x))
 #define PIC_IS_FARPTR(x)       (IS_DATA_PTR(x) || IS_FARPTR(x))
 #define PIC_IS_TAGGED(x)       (IS_GENPTR(x) || IS_CODEPTR(x))
+#define IS_DIRECT(op)          ((AOP_TYPE(op) == AOP_PCODE) && (AOP(op)->aopu.pcop->type == PO_DIR))
 
 /* If you change these, you also have to update the library files
  * device/lib/pic16/libsdcc/gptr{get,put}{1,2,3,4}.c */
@@ -8433,7 +8434,7 @@ static void AccRol (int shCount)
 /*-----------------------------------------------------------------*/
 /* AccLsh - left shift accumulator by known count                  */
 /*-----------------------------------------------------------------*/
-static void AccLsh (int shCount)
+static void AccLsh (int shCount, int doMask)
 {
        DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        switch(shCount){
@@ -8466,8 +8467,10 @@ static void AccLsh (int shCount)
                        pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
                        break;
        }
-
-       pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SLMask[shCount]));
+       if (doMask) {
+               /* no masking is required in genPackBits */
+               pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SLMask[shCount]));
+       }
 }
 
 /*-----------------------------------------------------------------*/
@@ -8764,7 +8767,7 @@ static void shiftL1Left2Result (operand *left, int offl,
     //    l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
     //    MOVA(l);
     /* shift left accumulator */
-    //AccLsh(shCount); // don't comment out just yet...
+    //AccLsh(shCount, 1); // don't comment out just yet...
   //    pic16_aopPut(AOP(result),"a",offr);
 
   switch(shCount) {
@@ -9135,7 +9138,7 @@ static void shiftLLeftOrResult (operand *left, int offl,
 
     pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl));
     /* shift left accumulator */
-    AccLsh(shCount);
+    AccLsh(shCount, 1);
     /* or with result */
     /* back to result */
     pic16_emitpcode(POC_IORWF,pic16_popGet(AOP(result),offr));
@@ -10553,7 +10556,7 @@ static void genUnpackBits (operand *result, operand *left, char *rname, int ptyp
 
 #if 1
   if((blen == 1) && (bstr < 8)
-      && (!IS_PTR(operandType(left)) || PIC_IS_DATA_PTR(operandType(left)))) {
+      && (!IS_PTR(operandType(left)) || IS_DIRECT(left) || PIC_IS_DATA_PTR(operandType(left)))) {
     /* it is a single bit, so use the appropriate bit instructions */
     DEBUGpic16_emitcode (";","%s %d optimize bit read",__FUNCTION__,__LINE__);
 
@@ -10561,7 +10564,7 @@ static void genUnpackBits (operand *result, operand *left, char *rname, int ptyp
     op = (same ? pic16_popCopyReg(&pic16_pc_wreg) : pic16_popGet (AOP(result),0));
     pic16_emitpcode(POC_CLRF, op);
 
-    if(!IS_PTR(operandType(left))) {
+    if(!IS_PTR(operandType(left)) || IS_DIRECT(left)) {
       /* workaround to reduce the extra lfsr instruction */
       pic16_emitpcode(POC_BTFSC,
          pic16_popCopyGPR2Bit(pic16_popGet(AOP(left), 0), bstr));
@@ -10589,7 +10592,7 @@ static void genUnpackBits (operand *result, operand *left, char *rname, int ptyp
 
 #endif
 
-  if (!IS_PTR(operandType(left)) /*OP_SYMBOL(left)->remat*/) {
+  if (!IS_PTR(operandType(left)) || IS_DIRECT(left)) {
     // access symbol directly
     pic16_mov2w (AOP(left), 0);
   } else {
@@ -11329,6 +11332,8 @@ static void genPackBits (sym_link    *etype , operand *result,
   int offset = 0  ;
   int rLen = 0 ;
   int blen, bstr ;   
+  int shifted_and_masked = 0;
+  unsigned long lit = (unsigned long)-1;
   sym_link *retype;
 
   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
@@ -11338,15 +11343,14 @@ static void genPackBits (sym_link    *etype , operand *result,
   retype = getSpec(operandType(right));
 
   if(AOP_TYPE(right) == AOP_LIT) {
+    lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
+    
     if((blen == 1) && (bstr < 8)) {
-      unsigned long lit;
       /* it is a single bit, so use the appropriate bit instructions */
 
       DEBUGpic16_emitcode (";","%s %d optimize bit assignment",__FUNCTION__,__LINE__);
 
-      lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
-      //                       pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
-      if(!IS_PTR(operandType(result))) {
+      if(!IS_PTR(operandType(result)) || IS_DIRECT(result)) {
        /* workaround to reduce the extra lfsr instruction */
        if(lit) {
          pic16_emitpcode(POC_BSF,
@@ -11372,11 +11376,14 @@ static void genPackBits (sym_link    *etype , operand *result,
 
       return;
     }
-    /* move literal to W */
-    pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right), 0));
+    /* IORLW below is more efficient */
+    //pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit & ((1UL << blen) - 1)) << bstr));
+    lit = (lit & ((1UL << blen) - 1)) << bstr;
+    shifted_and_masked = 1;
     offset++;
   } else
-    if(IS_BITFIELD(retype) 
+    if (IS_DIRECT(result) && !IS_PTR(operandType(result))
+       && IS_BITFIELD(retype) 
        && (AOP_TYPE(right) == AOP_REG || AOP_TYPE(right) == AOP_DIR)
        && (blen == 1)) {
       int rblen, rbstr;
@@ -11384,7 +11391,6 @@ static void genPackBits (sym_link    *etype , operand *result,
       rblen = SPEC_BLEN( retype );
       rbstr = SPEC_BSTR( retype );
 
-
       if(IS_BITFIELD(etype)) {
        pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result), 0));
        pic16_emitpcode(POC_BCF, pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_wreg), bstr));
@@ -11416,18 +11422,22 @@ static void genPackBits (sym_link    *etype , operand *result,
 
     if (blen != 8 || bstr != 0) {
       // we need to combine the value with the old value
-      pic16_emitpcode(POC_ANDLW, pic16_popGetLit((1U << blen)-1));
+      if(!shifted_and_masked)
+      {
+       pic16_emitpcode(POC_ANDLW, pic16_popGetLit((1U << blen)-1));
 
-      DEBUGpic16_emitcode(";", "shCnt = %d SPEC_BSTR(etype) = %d:%d", shCnt,
-         SPEC_BSTR(etype), SPEC_BLEN(etype));
+       DEBUGpic16_emitcode(";", "shCnt = %d SPEC_BSTR(etype) = %d:%d", shCnt,
+           SPEC_BSTR(etype), SPEC_BLEN(etype));
 
-      /* shift left acc */
-      AccLsh(shCnt);
+       /* shift left acc, do NOT mask the result again */
+       AccLsh(shCnt, 0);
 
-      /* using PRODH as a temporary register here */
-      pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodh));
+       /* using PRODH as a temporary register here */
+       pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodh));
+      }
 
-      if (IS_SYMOP(result) && !IS_PTR(operandType (result))/*OP_SYMBOL(result)->remat*/) {
+      if ((IS_SYMOP(result) && !IS_PTR(operandType (result)))
+       || IS_DIRECT(result)) {
        /* access symbol directly */
        pic16_mov2w (AOP(result), 0);
       } else {
@@ -11438,11 +11448,18 @@ static void genPackBits (sym_link    *etype , operand *result,
       pic16_emitpcode(POC_ANDLW, pic16_popGetLit(
            (unsigned char)((unsigned char)(0xff << (blen+bstr)) |
                            (unsigned char)(0xff >> (8-bstr))) ));
-      pic16_emitpcode(POC_IORFW, pic16_popCopyReg(&pic16_pc_prodh));
+      if (!shifted_and_masked) {
+        pic16_emitpcode(POC_IORFW, pic16_popCopyReg(&pic16_pc_prodh));
+      } else {
+        /* We have the shifted and masked (literal) right value in `lit' */
+        if (lit != 0)
+         pic16_emitpcode(POC_IORLW, pic16_popGetLit(lit));
+      }
     } // if (blen != 8 || bstr != 0)
 
     /* write new value back */
-    if (IS_SYMOP(result) & !IS_PTR(operandType(result))) {
+    if ((IS_SYMOP(result) && !IS_PTR(operandType(result)))
+       || IS_DIRECT(result)) {
       pic16_emitpcode (POC_MOVWF, pic16_popGet(AOP(result),0));
     } else {
       pic16_derefPtr (result, p_type, 1, &fsr0_setup);
index 9d4114f820430a22eac8a9afe345d460e9e8b846..34ecf9517fbdb537842330b0b06f14a246ffd475 100644 (file)
@@ -9451,6 +9451,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 +10736,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;
index c823dd296dd9900a71d67e04b7b61b3b67324993..9cbcd596f0056999530746660746b0cc9d40ed1e 100644 (file)
@@ -361,12 +361,6 @@ static void  RemoveRegsFromSet(set *regset)
            fprintf(stderr,"reg %s, type =%d\n",r->name, r->type);
          }
 
-
-         pc->print(stderr, pc);
-
-         fprintf(stderr,"%s:%d: removing reg %s because it is used only once\n",__FILE__, __LINE__, reg->name);
-
-
          Remove1pcode(pc, reg);
          /*
            pic16_unlinkpCode(pc);