* src/pic/gen.h: added emitpcode macro for debugging
authortecodev <tecodev@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sat, 23 Jul 2005 17:22:21 +0000 (17:22 +0000)
committertecodev <tecodev@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sat, 23 Jul 2005 17:22:21 +0000 (17:22 +0000)
* src/pic/gen.c (emitpcode): renamed to emitpcode_real
  and replace by macro adding debug information on demand
* (genNot): fixed to C semantics (!0 = 1; !x = 0 iff x != 0)
* (gencjne): tried to fix; replaced with correct (slower) code
* (gen{Unp,P}ackBits): fixed single bit access
* src/pic/pcode.c (AnalyzepCode): fixed DFPRINTF argument
* src/pic/pcodepeep.c (pCodeSearchCondition): fixed finding
  previous instruction
* src/pic/pcoderegs.c (regIsSpecial): NEW, check whether a
  register has to be handled with care (forbidding movement
  of assignments/uses, removing assignments completely, ...)
* (pCodeOptime2pCodes): make use of regIsSpecial
* added lots of debugging output (commented out)
* src/pic/rallloc.c (deassignLRs): prevent operand registers
  from being reused as result UNLESS it is known to work

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

ChangeLog
src/pic/gen.c
src/pic/gen.h
src/pic/pcode.c
src/pic/pcodepeep.c
src/pic/pcoderegs.c
src/pic/ralloc.c

index 39ca4d22028c494a52c371356697af58d1f51c0f..14b626a0014ef785a591933759dc2d10ed68d410 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2005-07-23 Raphael Neider <rneider AT web.de>
+
+       * src/pic/gen.h: added emitpcode macro for debugging
+       * src/pic/gen.c (emitpcode): renamed to emitpcode_real
+         and replace by macro adding debug information on demand
+       * (genNot): fixed to C semantics (!0 = 1; !x = 0 iff x != 0)
+       * (gencjne): tried to fix; replaced with correct (slower) code
+       * (gen{Unp,P}ackBits): fixed single bit access
+       * src/pic/pcode.c (AnalyzepCode): fixed DFPRINTF argument
+       * src/pic/pcodepeep.c (pCodeSearchCondition): fixed finding
+         previous instruction
+       * src/pic/pcoderegs.c (regIsSpecial): NEW, check whether a
+         register has to be handled with care (forbidding movement
+         of assignments/uses, removing assignments completely, ...)
+       * (pCodeOptime2pCodes): make use of regIsSpecial
+       * added lots of debugging output (commented out)
+       * src/pic/rallloc.c (deassignLRs): prevent operand registers
+         from being reused as result UNLESS it is known to work
+
 2005-07-23 Maarten Brock <sourceforge.brock AT dse.nl>
 
        * support/Util/dbuf.h: include <stddef.h> for size_t
index 8dd5d042449ab23c66924df95859ea91a87040e5..621357fac0368313b639cc394497877795ddf93c 100644 (file)
@@ -246,7 +246,10 @@ void emitpLabel(int key)
        addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset));
 }
 
-void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
+/* gen.h defines a macro emitpcode that should be used to call emitpcode
+ * as this allows for easy debugging (ever asked the question: where was
+ * this instruction geenrated? Here is the answer... */
+void emitpcode_real(PIC_OPCODE poc, pCodeOp *pcop)
 {
        if(pcop)
                addpCode2pBlock(pb,newpCode(poc,pcop));
@@ -1900,7 +1903,7 @@ void pic14_toBoolean(operand *oper)
 /*-----------------------------------------------------------------*/
 static void genNot (iCode *ic)
 {
-       symbol *tlbl;
+       //symbol *tlbl;
        int size;
 
        FENTRY;
@@ -1924,19 +1927,20 @@ static void genNot (iCode *ic)
                goto release;
        }
        
+       assert (!pic14_sameRegs (AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))));
        size = AOP_SIZE(IC_LEFT(ic));
-       if(size == 1) {
-               emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
-               emitpcode(POC_ANDLW,popGetLit(1));
-               emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
-               goto release;
+       emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
+       mov2w (AOP(IC_LEFT(ic)),0);
+       while (--size > 0)
+       {
+         if (aop_isLitLike (AOP(IC_LEFT(ic))))
+           emitpcode (POC_IORLW, popGetAddr (AOP(IC_LEFT(ic)), size, 0));
+         else
+           emitpcode (POC_IORFW, popGet (AOP(IC_LEFT(ic)), size));
        }
-       pic14_toBoolean(IC_LEFT(ic));
-       
-       tlbl = newiTempLabel(NULL);
-       pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
-       pic14_emitcode("","%05d_DS_:",tlbl->key+100);
-       pic14_outBitC(IC_RESULT(ic));
+       emitSKPNZ;
+       emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
+       goto release;
        
 release:       
        /* release the aops */
@@ -4824,14 +4828,12 @@ static void genc16bit2lit(operand *op, int lit, int offset)
 /*-----------------------------------------------------------------*/
 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
 {
-       int size = max(AOP_SIZE(left),AOP_SIZE(right));
+       int size = min(AOP_SIZE(left),AOP_SIZE(right));
        int offset = 0;
-       int res_offset = 0;  /* the result may be a different size then left or right */
-       int res_size = AOP_SIZE(result);
-       resolvedIfx rIfx;
+       //resolvedIfx rIfx;
        symbol *lbl;
        
-       unsigned long lit = 0L;
+       //unsigned long lit = 0L;
        FENTRY;
        if (!ifx && (!result || AOP_TYPE(result) == AOP_CRY)) {
          emitpComment ("gencjne: no ifx, no (real) result -- comparison ignored");
@@ -4839,10 +4841,48 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
        }
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        DEBUGpic14_AopType(__LINE__,left,right,result);
+       
+       assert (!pic14_sameRegs (AOP(left), AOP(result)));
+       assert (!pic14_sameRegs (AOP(right), AOP(result)));
+       if (AOP_SIZE(result)) {
+         for (offset = 0; offset < AOP_SIZE(result); offset++)
+           emitpcode (POC_CLRF, popGet (AOP(result), offset));
+       }
+       
+       assert (AOP_SIZE(left) == AOP_SIZE(right));
+       //resolveIfx(&rIfx,ifx);
+       lbl = newiTempLabel (NULL);
+       while (size--)
+       {
+         mov2w (AOP(right),size);
+         emitpcode (POC_XORFW, popGet (AOP(left), size));
+         if (size)
+         {
+           emitSKPZ;
+           emitpcode (POC_GOTO, popGetLabel (lbl->key));
+         }
+       } // while
+       emitpLabel (lbl->key);
+       if (AOP_SIZE(result)) {
+         emitSKPNZ;
+         emitpcode (POC_INCF, popGet (AOP(result), 0));
+       } else {
+         assert (ifx);
+         genSkipz (ifx, NULL != IC_TRUE(ifx));
+         ifx->generated = 1;
+       }
+       return;
+#if 0  
        if(result)
+       {
                DEBUGpic14_emitcode ("; ***","%s  %d result is not null",__FUNCTION__,__LINE__);
-       resolveIfx(&rIfx,ifx);
-       lbl =  newiTempLabel(NULL);
+               assert (!pic14_sameRegs (AOP(result), AOP(left)));
+               assert (!pic14_sameRegs (AOP(result), AOP(right)));
+               for (offset=0; offset < AOP_SIZE(result); offset++)
+               {
+                       emitpcode (POC_CLRF, popGet (AOP(result), offset));
+               } // for offset
+       }
        
        
        /* if the left side is a literal or 
@@ -4867,6 +4907,7 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
                        emitpcode(POC_GOTO,popGetLabel(lbl->key));
                        break;
                default:
+                       offset = 0;
                        while (size--) {
                                if(lit & 0xff) {
                                        emitpcode(POC_MOVFW,popGet(AOP(left),offset));
@@ -4878,8 +4919,6 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
                                emitSKPNZ;
                                emitpcode(POC_GOTO,popGetLabel(lbl->key));
                                offset++;
-                               if(res_offset < res_size-1)
-                                       res_offset++;
                                lit >>= 8;
                        }
                        break;
@@ -4895,11 +4934,7 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
                //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
                int lbl_key = lbl->key;
                
-               if(result) {
-                       if (AOP_TYPE(result) != AOP_CRY)
-                               emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
-                       //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
-               }else {
+               if(!result) {
                        DEBUGpic14_emitcode ("; ***","%s  %d -- ERROR",__FUNCTION__,__LINE__);
                        fprintf(stderr, "%s  %d error - expecting result to be non_null\n",
                                __FUNCTION__,__LINE__);
@@ -4913,6 +4948,7 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
                /*       emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
                /*       break; */
                /*     default: */
+               offset = 0;
                while (size--) {
                        int emit_skip=1;
                        if((AOP_TYPE(left) == AOP_DIR) && 
@@ -4929,8 +4965,8 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
                                        break;
                                case 1:
                                        emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
-                                       emitpcode(POC_INCF,popGet(AOP(result),res_offset));
-                                       //emitpcode(POC_GOTO,popGetLabel(lbl->key));
+                                       //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
+                                       emitpcode(POC_GOTO,popGetLabel(lbl->key));
                                        emit_skip=0;
                                        break;
                                case 0xff:
@@ -4965,21 +5001,19 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
                                        else
                                                emitSKPNZ;
                                        emitpcode(POC_GOTO,popGetLabel(lbl_key));
-                                       //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
                                }
                                if(ifx)
                                        ifx->generated=1;
                        }
                        emit_skip++;
                        offset++;
-                       if(res_offset < res_size-1)
-                               res_offset++;
                }
                /*       break; */
                /*     } */
        } else if(AOP_TYPE(right) == AOP_REG &&
                AOP_TYPE(left) != AOP_DIR){
-               
+
+               offset = 0;
                while(size--) {
                        emitpcode(POC_MOVFW,popGet(AOP(left),offset));
                        emitpcode(POC_XORFW,popGet(AOP(right),offset));
@@ -4990,12 +5024,11 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
                                emitSKPZ;
                        emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
                        offset++;
-                       if(res_offset < res_size-1)
-                               res_offset++;
                }
                
        }else{
                /* right is a pointer reg need both a & b */
+               offset = 0;
                while(size--) {
                        char *l = aopGet(AOP(left),offset,FALSE,FALSE);
                        if(strcmp(l,"b"))
@@ -5006,7 +5039,7 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
                }
        }
        
-       emitpcode(POC_INCF,popGet(AOP(result),res_offset));
+       emitpcode(POC_INCF,popGet(AOP(result),0));
        if(!rIfx.condition)
                emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
        
@@ -5016,6 +5049,7 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
        
        if(ifx)
                ifx->generated = 1;
+#endif
 }
 
 #if 0
@@ -8415,19 +8449,16 @@ static void genUnpackBits (operand *result, operand *left, char *rname, int ptyp
                        ifx->generated=1;
                } else {
                        pCodeOp *pcop;
-                       
+                       int i;
+                       assert (!pic14_sameRegs (AOP(result), AOP(left)));
+                       for (i=0; i < AOP_SIZE(result); i++)
+                               emitpcode (POC_CLRF, popGet (AOP(result), i));
                        if (ptype == -1) /* direct */
                                pcop = newpCodeOpBit(aopGet (AOP(left),0,FALSE,FALSE),bstr,0);
                        else
                                pcop = newpCodeOpBit(pc_indf.pcop.name,bstr,0);
                        emitpcode(POC_BTFSC,pcop);
-                       emitpcode(POC_BSF,newpCodeOpBit(aopGet(AOP(result), 0,FALSE,FALSE),bstr,0));
-                       if (ptype == -1) /* direct */
-                               pcop = newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),bstr,0);
-                       else
-                               pcop = newpCodeOpBit(pc_indf.pcop.name,bstr,0);
-                       emitpcode(POC_BTFSS,pcop);
-                       emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),bstr,0));
+                       emitpcode(POC_BSF,newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),0,0));
                }
                return;
        }
@@ -9246,11 +9277,12 @@ static void genPackBits(sym_link *etype,operand *result,operand *right,char *rna
                        if (blen==1) {
                                if (p_type == -1) {
                                        /* Note more efficient code, of pre clearing bit then only setting it if required, can only be done if it is known that the result is not a SFR */
-                                       emitpcode(POC_RLF,popGet(AOP(right),0));
+                                       emitpcode(POC_RRFW,popGet(AOP(right),0));
                                        emitSKPC;
-                                       emitpcode(POC_BCF,popGet(AOP(result),0));
+                                       emitpcode(POC_BCF,newpCodeOpBit (aopGet(AOP(result), 0, FALSE, FALSE), bstr, 0));
                                        emitSKPNC;
-                                       emitpcode(POC_BSF,popGet(AOP(result),0));
+                                       emitpcode(POC_BSF,newpCodeOpBit (aopGet(AOP(result), 0, FALSE, FALSE), bstr, 0));
+                                       return;
                                } else if (p_type!=GPOINTER) {
                                        /* Case with a bitfield length == 1 and no generic pointer
                                        */
index cd40bfe0b812e1da35c23e3510238c9ed121a54b..f12a1bdc7145de5694a7412538342663171bfdc0 100644 (file)
@@ -150,7 +150,8 @@ extern unsigned fReturnSizePic;
 #define emitSETDC   emitpcode(POC_BSF,  popCopyGPR2Bit(PCOP(&pc_status),PIC_DC_BIT))
 
 int pic14_getDataSize(operand *op);
-void emitpcode(PIC_OPCODE poc, pCodeOp *pcop);
+void emitpcode_real(PIC_OPCODE poc, pCodeOp *pcop);
+#define emitpcode(poc,pcop)    do { if (options.debug || debug_verbose) { emitpComment (" >>> %s:%d:%s", __FILE__, __LINE__, __FUNCTION__); } emitpcode_real(poc,pcop); } while(0)
 void emitpComment (const char *fmt, ...);
 void emitpLabel(int key);
 void pic14_emitcode (char *inst,char *fmt, ...);
index a4e6e473fcb084fbfb953cb03b40151c8c3f68dc..f2783431ed262243bd2cf396b457a72f273a82b6 100644 (file)
@@ -5797,7 +5797,7 @@ void AnalyzepCode(char dbName)
                                pBlockMergeLabels(pb);
                                AnalyzepBlock(pb);
                        } else {
-                               DFPRINTF((stderr," skipping block analysis dbName=%c blockname=%c\n",dbName,getpBlock_dbName));
+                               DFPRINTF((stderr," skipping block analysis dbName=%c blockname=%c\n",dbName,getpBlock_dbName(pb)));
                        }
                }
                
index 902178d0fb05a9e609b51a307b4cc743faae8f6d..f9ca9d3f89d03af5eaf8d3b1fc8c7c7b0a68f6e3 100644 (file)
@@ -1491,7 +1491,7 @@ int pCodeSearchCondition(pCode *pc, unsigned int cond, int contIfSkip)
                        if(PCI(pc)->inCond & cond) {
                                if (contIfSkip) {
                                        /* If previous instruction is a skip then continue search as condiction is not certain */
-                                       pCode *pcp = findPrevInstruction(pc);
+                                       pCode *pcp = findPrevInstruction(pc->prev);
                                        if (pcp && !isPCI_SKIP(pcp)) {
                                                return 1;
                                        }
@@ -1502,7 +1502,7 @@ int pCodeSearchCondition(pCode *pc, unsigned int cond, int contIfSkip)
                        if(PCI(pc)->outCond & cond) {
                                if (contIfSkip) {
                                        /* If previous instruction is a skip then continue search as condiction is not certain */
-                                       pCode *pcp = findPrevInstruction(pc);
+                                       pCode *pcp = findPrevInstruction(pc->prev);
                                        if (pcp && !isPCI_SKIP(pcp)) {
                                                return -1;
                                        }
index 4b37f118da39751e6d150889588d0f279e87106e..2f489e3e63cb6a5a2fea1b6faae7abfe153de672 100644 (file)
@@ -240,7 +240,7 @@ static void Remove1pcode(pCode *pc, regs *reg, int debug_code)
        
        if(!reg || !pc)
                return;
-       
+
        deleteSetItem (&(reg->reglives.usedpCodes),pc);
        
        if(PCI(pc)->label) {
@@ -386,6 +386,11 @@ static void Remove2pcodes(pCode *pcflow, pCode *pc1, pCode *pc2, regs *reg, int
        static int debug_code=99;
        if(!reg)
                return;
+#if 0
+       fprintf (stderr, "%s:%d(%s): %d (reg:%s)\n", __FILE__, __LINE__, __FUNCTION__, debug_code, reg ? reg->name : "???");
+       printpCode (stderr, pc1);
+       printpCode (stderr, pc2);
+#endif
        
        //fprintf(stderr,"%s\n",__FUNCTION__);
        if(pc1)
@@ -430,6 +435,15 @@ int regUsedinRange(pCode *pc1, pCode *pc2, regs *reg)
        return 0;
 }
 
+int regIsSpecial (regs *reg, int mayBeGlobal)
+{
+  if (!reg) return 0;
+
+  if (reg->type == REG_SFR || reg->type == REG_STK || (!mayBeGlobal && (reg->isPublic || reg->isExtern))) return 1;
+
+  return 0;
+}
+
 /*-----------------------------------------------------------------*
 * void pCodeOptime2pCodes(pCode *pc1, pCode *pc2) 
 *
@@ -499,6 +513,7 @@ int pCodeOptime2pCodes(pCode *pc1, pCode *pc2, pCode *pcfl_used, regs *reg, int
                        PCI(newpc)->pcflow = PCFL(pcfl_used);
                        newpc->seq = pc2->seq;
                        
+                       //fprintf (stderr, "%s:%d(%s): Remove2pcodes (CLRF reg, ..., MOVF reg,W)\n", __FILE__, __LINE__, __FUNCTION__);
                        Remove2pcodes(pcfl_used, pc1, pc2, reg, can_free);
                        total_registers_saved++;  // debugging stats.
                }
@@ -513,6 +528,7 @@ int pCodeOptime2pCodes(pCode *pc1, pCode *pc2, pCode *pcfl_used, regs *reg, int
                        PCI(pct2)->pcflow = PCFL(pcfl_used);
                        pCodeInsertAfter(pc1,pct2);
                }
+               //fprintf (stderr, "%s:%d(%s): Remove2pcodes (CLRF/IORFW)\n", __FILE__, __LINE__, __FUNCTION__);
                Remove2pcodes(pcfl_used, pc1, pc2, reg, can_free);
                total_registers_saved++;  // debugging stats.
                
@@ -541,7 +557,7 @@ int pCodeOptime2pCodes(pCode *pc1, pCode *pc2, pCode *pcfl_used, regs *reg, int
                                */
                                reg2 = getRegFromInstruction(pct2);
                                /* Check reg2 is not used for something else before it is loaded with reg */
-                               if (reg2 && !regUsedinRange(pc1,pc2,reg2)) {
+                               if (reg2 && !regIsSpecial (reg2, 1) && !regUsedinRange(pc1,pc2,reg2)) {
                                        pCode *pct3 = findNextInstruction(pct2->next);
                                        /* Check following instructions are not relying on the use of W or the Z flag condiction */
                                        if ((pCodeSearchCondition(pct3,PCC_Z,0) < 1) || (pCodeSearchCondition(pct3,PCC_W,0) < 1)) {
@@ -550,10 +566,13 @@ int pCodeOptime2pCodes(pCode *pc1, pCode *pc2, pCode *pcfl_used, regs *reg, int
                                                unlinkpCode(pct2);
                                                pCodeInsertBefore(pc1,pct2);
                                                if(regUsedinRange(pct2,0,reg))
+                                               {
+                                                       //fprintf (stderr, "%s:%d(%s): Remove2pcodes IF (MOVWF reg, ..., MOVW reg,W  MOVWF reg2)\n", __FILE__, __LINE__, __FUNCTION__);
                                                        Remove2pcodes(pcfl_used, pc2, NULL, reg, can_free);
-                                               else
+                                               } else {
+                                                       //fprintf (stderr, "%s:%d(%s): Remove2pcodes ELSE (MOVWF reg, ..., MOVW reg,W  MOVWF reg2)\n", __FILE__, __LINE__, __FUNCTION__);
                                                        Remove2pcodes(pcfl_used, pc1, pc2, reg, can_free);
-                                               
+                                               }
                                                total_registers_saved++;  // debugging stats.
                                                return 1;
                                        }
@@ -568,7 +587,7 @@ int pCodeOptime2pCodes(pCode *pc1, pCode *pc2, pCode *pcfl_used, regs *reg, int
                                (PCI(pc2)->op == POC_MOVFW)) {
                                
                                reg1 = getRegFromInstruction(pct1);
-                               if(reg1 && !regUsedinRange(pc1,pc2,reg1)) {
+                               if(reg1 && !regIsSpecial (reg1, 0) && !regUsedinRange(pc1,pc2,reg1)) {
                                        DFPRINTF((stderr, "   optimising MOVF reg1,W MOVWF reg ... MOVF reg,W\n"));
                                        /*
                                        Change:
@@ -598,6 +617,7 @@ int pCodeOptime2pCodes(pCode *pc1, pCode *pc2, pCode *pcfl_used, regs *reg, int
                                        pct2->seq = pc2->seq;
                                        
                                        if(can_free) {
+                                               //fprintf (stderr, "%s:%d(%s): Remove2pcodes CANFREE (MOVF reg1,W; MOVWF reg2; MOVF reg2,W)\n", __FILE__, __LINE__, __FUNCTION__);
                                                Remove2pcodes(pcfl_used, pc1, pc2, reg, can_free);
                                        } else {
                                        /* If we're not freeing the register then that means (probably)
@@ -605,9 +625,11 @@ int pCodeOptime2pCodes(pCode *pc1, pCode *pc2, pCode *pcfl_used, regs *reg, int
                                                unlinkpCode(pc1);
                                                pCodeInsertAfter(pct2, pc1);
                                                
+                                               //fprintf (stderr, "%s:%d(%s): Remove2pcodes ELSE (MOVF reg1,W; MOVWF reg2; MOVF reg2,W)\n", __FILE__, __LINE__, __FUNCTION__);
                                                Remove2pcodes(pcfl_used, pc2, NULL, reg, can_free);
                                        }
                                        
+                                       //fprintf (stderr, "%s:%d(%s): Remove2pcodes ALWAYS (MOVF reg1,W; MOVWF reg2; MOVF reg2,W)\n", __FILE__, __LINE__, __FUNCTION__);
                                        Remove2pcodes(pcfl_used, pct1, NULL, reg1, 0);
                                        total_registers_saved++;  // debugging stats.
                                        
@@ -692,7 +714,7 @@ void OptimizeRegUsage(set *fregs, int optimize_multi_uses, int optimize_level)
                                fprintf(stderr,"WARNING %s: reg %s used without being assigned\n",__FUNCTION__,reg->name);
                                
                        } else {
-                               fprintf(stderr,"WARNING %s: reg %s assigned without being used\n",__FUNCTION__,reg->name);
+                               //fprintf(stderr,"WARNING %s.1: reg %s assigned without being used\n",__FUNCTION__,reg->name);
                                Remove2pcodes(pcfl_assigned, pc1, pc2, reg, 1);
                                total_registers_saved++;  // debugging stats.
                        }
@@ -703,7 +725,7 @@ void OptimizeRegUsage(set *fregs, int optimize_multi_uses, int optimize_level)
                        if(used && !pcfl_used && pcfl_assigned) {
                                pCode *pc;
                                
-                               fprintf(stderr,"WARNING %s: reg %s assigned without being used\n",__FUNCTION__,reg->name);
+                               //fprintf(stderr,"WARNING %s.2: reg %s assigned without being used\n",__FUNCTION__,reg->name);
                                
                                pc = setFirstItem(reg->reglives.usedpCodes);
                                while(pc) {
index 785db02bd48b2d9c33fca03b155608f28e7901fb..a6e5aef76dab0f9a36411a799f1c00c28e02f43a 100644 (file)
@@ -1944,14 +1944,36 @@ deassignLRs (iCode * ic, eBBlock * ebp)
                /* if it does not end here */
                if (sym->liveTo > ic->seq)
                        continue;
-       
-               /* HACK: result and operand must be disjoint for POINTER_GET/LEFT_OP/RIGHT_OP */
-               if (sym->liveTo == ic->seq && (POINTER_GET(ic) || ic->op == LEFT_OP || ic->op == RIGHT_OP))
+
+               /* Prevent the result from being assigned the same registers as (one)
+                * operand as many genXXX-functions fail otherwise.
+                * POINTER_GET(ic) || ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == NOT
+                * are known to fail. */
+               if (sym->liveTo == ic->seq && IC_RESULT(ic))
                {
-                       //piCode (ic, stderr); fprintf (stderr, " -- registers NOT deallocated\n");
-                       continue;
+                       switch (ic->op)
+                       {
+                       case '=':       /* assignment */
+                       case BITWISEAND: /* bitwise AND */
+                       case '|':       /* bitwise OR */
+                       case '^':       /* bitwise XOR */
+                       case '~':       /* bitwise negate */
+                       case RLC:       /* rotate through carry */
+                       case RRC:
+                       case UNARYMINUS:
+                       case '+':       /* addition */
+                       case '-':       /* subtraction */
+                         /* go ahead, these are safe to use with
+                          * non-disjoint register sets */
+                         break;
+
+                       default:
+                               /* do not release operand registers */
+                               //fprintf (stderr, "%s:%u: operand not freed: ", __FILE__, __LINE__); piCode (ic, stderr); fprintf (stderr, "\n");
+                               continue;
+                       } // switch
                }
-               
+       
                /* if it was spilt on stack then we can 
                mark the stack spil location as free */
                if (sym->isspilt)