* src/SDCCmain.c (linkEdit): do not test for PIC16 target since, PIC16
authorvrokas <vrokas@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Wed, 15 Mar 2006 00:43:05 +0000 (00:43 +0000)
committervrokas <vrokas@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Wed, 15 Mar 2006 00:43:05 +0000 (00:43 +0000)
linking is done manually in pic16 port's _linkEdit,
* src/SDCCsymt.c (compStructSize): for target PIC16 and shell variable
PIC16_PACKED_BITFIELDS, compact bitfield structures as much as possible,
* src/pic16/gen.c (aopForSym): when direct register name is WREG then
allocate asmop as AOP_ACC,
(aopForRemat): added parameter 'bool result' in function declaration,
(pic16_aopGet): return AOP_ACC when accessing WREG,
(pic16_popGetTempReg): minor modification,
(pic16_popRegFromIdx): first try with 'pic16_regWithIdx' then with
'pic16_allocWithIdx',
(genPcall): removed ftype, usage of OP_SYM_TYPE asserted error when
calling function in absolute addresses,
(genAssign): take into account AOP_ACC asmop,
* src/pic16/pcode.c (pic16_newpCodeOpReg): minor modifications,
* src/pic16/pcoderegs.c: some debug functions and lines added,
* src/pic16/ralloc.c (decodeRegType): added but commented out,
* (pic16_typeRegWithIdx): search 'pic16_dynInternalRegs' for given
register too,
* (pic16_findFreeReg, pic16_findFreeRegNext): allocate new register via
call to allocReg, not by manually allocating a new one,
(pic16_assignRegisters): now before going through the register
allocating functions mark all registers as free. This eliminates some
side effects resulting from peephole parser done earlier in the backbone

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

.version
ChangeLog
src/SDCCmain.c
src/SDCCsymt.c
src/pic16/gen.c
src/pic16/pcode.c
src/pic16/pcoderegs.c
src/pic16/ralloc.c

index fe16b348d97f7a5d8d995ebbd9712fe708f7423e..0cadbc1e33b27c15475868596b6f73d866de5182 100644 (file)
--- a/.version
+++ b/.version
@@ -1 +1 @@
-2.5.4
+2.5.5
index bd70636419253b70850781fa33bb5426752ae5db..1fc24424f921e2c96ba8768dae3d16967a3abbdb 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,31 @@
+2006-03-14 Vangelis Rokas <vrokas AT users.sourceforge.net>
+
+       * src/.version: increased version number to 2.5.5
+       * src/SDCCmain.c (linkEdit): do not test for PIC16 target since, PIC16
+       linking is done manually in pic16 port's _linkEdit,
+       * src/SDCCsymt.c (compStructSize): for target PIC16 and shell variable
+       PIC16_PACKED_BITFIELDS, compact bitfield structures as much as possible,
+       * src/pic16/gen.c (aopForSym): when direct register name is WREG then
+       allocate asmop as AOP_ACC,
+       (aopForRemat): added parameter 'bool result' in function declaration,
+       (pic16_aopGet): return AOP_ACC when accessing WREG,
+       (pic16_popGetTempReg): minor modification,
+       (pic16_popRegFromIdx): first try with 'pic16_regWithIdx' then with
+       'pic16_allocWithIdx',
+       (genPcall): removed ftype, usage of OP_SYM_TYPE asserted error when
+       calling function in absolute addresses,
+       (genAssign): take into account AOP_ACC asmop,
+       * src/pic16/pcode.c (pic16_newpCodeOpReg): minor modifications,
+       * src/pic16/pcoderegs.c: some debug functions and lines added,
+       * src/pic16/ralloc.c (decodeRegType): added but commented out,
+       * (pic16_typeRegWithIdx): search 'pic16_dynInternalRegs' for given
+       register too,
+       * (pic16_findFreeReg, pic16_findFreeRegNext): allocate new register via
+       call to allocReg, not by manually allocating a new one,
+       (pic16_assignRegisters): now before going through the register
+       allocating functions mark all registers as free. This eliminates some
+       side effects resulting from peephole parser done earlier in the backbone
+
 2006-03-13 Maarten Brock <sourceforge.brock AT dse.nl>
 
        * src/SDCCicode.c (geniCodeLogic),
index f8b61bd741ba23bb163640d6815f186ae319e6d5..9d6a445d4ba114194e796e25b5a3a6be9ab7155d 100644 (file)
@@ -1786,7 +1786,7 @@ linkEdit (char **envp)
       set *tempSet=NULL, *libSet=NULL;
 
       strcpy(buffer3, linkerScriptFileName);
-      if(TARGET_IS_PIC16 || TARGET_IS_PIC) {
+      if(/*TARGET_IS_PIC16 ||*/ TARGET_IS_PIC) {
 
          /* use $l to set the linker include directories */
          tempSet = appendStrSet(libDirsSet, "-I\"", "\"");
index 0c0c00cc0f9d6c2c1642378cfbc798df56e63814..40e1fed661ed02d3e1d3172c0342813453db5a8c 100644 (file)
@@ -1280,12 +1280,24 @@ compStructSize (int su, structdef * sdef)
                     bitOffset += loop->bitVar;
                 } 
                 else {
-                    /* does not fit; need to realign first */
-                    sum++;
-                    loop->offset = (su == UNION ? sum = 0 : sum);
-                    bitOffset = 0;
-                    SPEC_BSTR (loop->etype) = bitOffset;
-                    bitOffset += loop->bitVar;
+                                       if( TARGET_IS_PIC16 && getenv("PIC16_PACKED_BITFIELDS") ) {
+                                               /* if PIC16 && enviroment variable is set, then
+                                                * tightly pack bitfields, this means that when a
+                                                * bitfield goes beyond byte alignment, do not
+                                                * automatically start allocatint from next byte,
+                                                * but also use the available bits first */
+                                               fprintf(stderr, ": packing bitfields in structures\n");
+                                               SPEC_BSTR (loop->etype) = bitOffset;
+                                               bitOffset += loop->bitVar;
+                                               loop->offset = (su == UNION ? sum = 0 : sum);
+                                       } else {
+                                               /* does not fit; need to realign first */
+                           sum++;
+                       loop->offset = (su == UNION ? sum = 0 : sum);
+                           bitOffset = 0;
+                       SPEC_BSTR (loop->etype) = bitOffset;
+                           bitOffset += loop->bitVar;
+                       }
                 }
                 while (bitOffset>8) {
                     bitOffset -= 8;
index 6a0d0683019811532b83bb9273cd0e622edfd983..2290438c401b83a0e6dce2051d3c79f8e3a3ddc5 100644 (file)
@@ -851,14 +851,21 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result)
     }
     /* if it is in direct space */
     if (IN_DIRSPACE(space)) {
-        sym->aop = aop = newAsmop (AOP_DIR);
-        aop->aopu.aop_dir = sym->rname ;
-        aop->size = getSize(sym->type);
-        DEBUGpic16_emitcode(";","%d sym->rname (AOP_DIR) = %s, size = %d",__LINE__,sym->rname,aop->size);
-        pic16_allocDirReg( IC_LEFT(ic) );
-        return aop;
-    }
-
+               if(!strcmp(sym->rname, "_WREG")) {
+                       sym->aop = aop = newAsmop (AOP_ACC);
+                       aop->size = getSize(sym->type);         /* should always be 1 */
+                       assert(aop->size == 1);
+                       DEBUGpic16_emitcode(";","%d sym->rname (AOP_ACC) = %s, size = %d",__LINE__,sym->rname,aop->size);
+                       reutn (aop);
+               } else {
+                       sym->aop = aop = newAsmop (AOP_DIR);
+               aop->aopu.aop_dir = sym->rname ;
+           aop->size = getSize(sym->type);
+               DEBUGpic16_emitcode(";","%d sym->rname (AOP_DIR) = %s, size = %d",__LINE__,sym->rname,aop->size);
+                       pic16_allocDirReg( IC_LEFT(ic) );
+                       return (aop);
+               }
+       }
 
     if (IN_FARSPACE(space) && !IN_CODESPACE(space)) {
         sym->aop = aop = newAsmop (AOP_DIR);
@@ -920,7 +927,7 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result)
 /*-----------------------------------------------------------------*/
 /* aopForRemat - rematerialzes an object                           */
 /*-----------------------------------------------------------------*/
-static asmop *aopForRemat (operand *op) // x symbol *sym)
+static asmop *aopForRemat (operand *op, bool result) // x symbol *sym)
 {
   symbol *sym = OP_SYMBOL(op);
   operand *refop;
@@ -938,6 +945,7 @@ static asmop *aopForRemat (operand *op) // x symbol *sym)
                DEBUGpic16_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
        }
 
+//    if(!result)              /* fixme-vr */
        for (;;) {
                oldic = ic;
 
@@ -1225,7 +1233,7 @@ void pic16_aopOp (operand *op, iCode *ic, bool result)
         /* rematerialize it NOW */
         if (sym->remat) {
 
-            sym->aop = op->aop = aop = aopForRemat (op);
+            sym->aop = op->aop = aop = aopForRemat (op, result);
 //            aop->size = getSize(sym->type);
 //         DEBUGpic16_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
             return;
@@ -1581,7 +1589,7 @@ char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname)
 //         return "acc";
         if(!strcmp(aop->aopu.aop_str[offset], "WREG")) {
           aop->type = AOP_ACC;
-          return Safe_strdup("WREG");
+          return Safe_strdup("_WREG");
         }
         DEBUGpic16_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
        
@@ -1658,7 +1666,7 @@ int _TempReg_lock = 0;
 /*-----------------------------------------------------------------*/
 pCodeOp *pic16_popGetTempReg(int lock)
 {
-  pCodeOp *pcop;
+  pCodeOp *pcop=NULL;
   symbol *cfunc;
 
 //    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
@@ -1671,6 +1679,34 @@ pCodeOp *pic16_popGetTempReg(int lock)
     cfunc = currFunc;
     currFunc = NULL;
 
+#if 0
+       {
+         regs *rr;
+         int i;
+
+               /* this code might seem better but it does the *same* job with
+                * the old code, it all depends on ralloc.c to get a free/unused
+                * register */
+        
+               i=0;
+               while(i < pic16_nRegs) {
+                       rr = pic16_typeRegWithIdx(i, REG_GPR, 0);
+                       fprintf(stderr, "%s:%d checking for TempReg Idx=%d rr=%p\n", __FILE__, __LINE__, i, rr);
+                       if((!rr || (rr && rr->isFree))
+                               && !bitVectBitValue(cfunc->regsUsed, i)) {
+                               pcop = pic16_newpCodeOpReg( i );
+                               PCOR(pcop)->r->wasUsed = 1;
+                               PCOR(pcop)->r->isFree = 0;
+                               break;
+                       }
+                       i++;
+               }
+
+               if(pcop) {
+                       pic16_pushpCodeOp( pic16_pCodeOpCopy(pcop) );
+               }
+       }
+#else
     pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP);
     if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
       PCOR(pcop)->r->wasUsed=1;
@@ -1679,6 +1715,7 @@ pCodeOp *pic16_popGetTempReg(int lock)
       /* push value on stack */
       pic16_pushpCodeOp( pic16_pCodeOpCopy(pcop) );
     }
+#endif
 
     currFunc = cfunc;
 
@@ -1889,6 +1926,7 @@ static pCodeOp *pic16_popRegFromString(char *str, int size, int offset, operand
   //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
 
   PCOR(pcop)->r = pic16_dirregWithName(pcop->name);
+//  PCOR(pcop)->r->wasUsed = 1;
 
   /* make sure that register doesn't exist,
    * and operand isn't NULL
@@ -1913,11 +1951,14 @@ static pCodeOp *pic16_popRegFromIdx(int rIdx)
   pCodeOp *pcop;
 
 //     DEBUGpic16_emitcode ("; ***","%s,%d\trIdx=0x%x", __FUNCTION__,__LINE__,rIdx);
-
+//     fprintf(stderr, "%s:%d rIdx = 0x%0x\n", __FUNCTION__, __LINE__, rIdx);
+       
        pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
        PCOR(pcop)->rIdx = rIdx;
        PCOR(pcop)->r = pic16_regWithIdx(rIdx);
-
+       if(!PCOR(pcop)->r)
+               PCOR(pcop)->r = pic16_allocWithIdx(rIdx);
+               
        PCOR(pcop)->r->isFree = 0;
        PCOR(pcop)->r->wasUsed = 1;
 
@@ -1994,9 +2035,9 @@ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
   char *rs;
   pCodeOp *pcop;
 
-    FENTRY2;
-    /* offset is greater than
-    size then zero */
+       FENTRY2;
+               /* offset is greater than
+                * size then zero */
 
 //    if (offset > (aop->size - 1) &&
 //        aop->type != AOP_LIT)
@@ -2004,69 +2045,65 @@ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
 
     /* depending on type */
     switch (aop->type) {
-       
-    case AOP_R0:
-    case AOP_R1:
-    case AOP_DPTR:
-    case AOP_DPTR2:
-        DEBUGpic16_emitcode(";8051 legacy","%d type = %s",__LINE__,pic16_AopType(aop->type));
-        fprintf(stderr, ";8051 legacy %d type = %s\n",__LINE__,pic16_AopType(aop->type));
-       assert( 0 );
-       return NULL;
-
-
-    case AOP_FSR0:
-    case AOP_FSR2:
-      pcop = Safe_calloc(1, sizeof(pCodeOpReg));
-      PCOR(pcop)->rIdx = aop->aopu.aop_ptr->rIdx+2;    /* access PLUSW register */
-      PCOR(pcop)->r = pic16_regWithIdx( PCOR(pcop)->rIdx );
-      PCOR(pcop)->r->wasUsed = 1;
-      PCOR(pcop)->r->isFree = 0;
+               case AOP_R0:
+               case AOP_R1:
+               case AOP_DPTR:
+               case AOP_DPTR2:
+                       DEBUGpic16_emitcode(";8051 legacy","%d type = %s",__LINE__,pic16_AopType(aop->type));
+                       fprintf(stderr, ";8051 legacy %d type = %s\n",__LINE__,pic16_AopType(aop->type));
+                       assert( 0 );
+                       return NULL;
+
+               case AOP_FSR0:
+               case AOP_FSR2:
+                       pcop = Safe_calloc(1, sizeof(pCodeOpReg));
+                       PCOR(pcop)->rIdx = aop->aopu.aop_ptr->rIdx+2;   /* access PLUSW register */
+                       PCOR(pcop)->r = pic16_regWithIdx( PCOR(pcop)->rIdx );
+                       PCOR(pcop)->r->wasUsed = 1;
+                       PCOR(pcop)->r->isFree = 0;
       
-      PCOR(pcop)->instance = offset;
-      pcop->type = PCOR(pcop)->r->pc_type;
-      return (pcop);
-
-    case AOP_IMMD:
-      DEBUGpic16_emitcode(";","%d\tAOP_IMMD",__LINE__);
-      return pic16_popGetImmd(aop->aopu.aop_immd,offset,0);
-
-    case AOP_STA:
-      /* pCodeOp is already allocated from aopForSym */
-        DEBUGpic16_emitcode(";---", "%d getting stack + offset %d\n", __LINE__, offset);
-        pcop = pic16_pCodeOpCopy(aop->aopu.stk.pop[offset]);
-          
-      return (pcop);
+                       PCOR(pcop)->instance = offset;
+                       pcop->type = PCOR(pcop)->r->pc_type;
+                       return (pcop);
+
+               case AOP_IMMD:
+                       DEBUGpic16_emitcode(";","%d\tAOP_IMMD",__LINE__);
+                       return pic16_popGetImmd(aop->aopu.aop_immd,offset,0);
+
+               case AOP_STA:
+                       /* pCodeOp is already allocated from aopForSym */
+                       DEBUGpic16_emitcode(";---", "%d getting stack + offset %d\n", __LINE__, offset);
+                       pcop = pic16_pCodeOpCopy(aop->aopu.stk.pop[offset]);
+                       return (pcop);
       
-    case AOP_ACC:
-      {
-       int rIdx = IDX_WREG;            //aop->aopu.aop_reg[offset]->rIdx;
+               case AOP_ACC:
+                       {
+                         int rIdx = IDX_WREG;          //aop->aopu.aop_reg[offset]->rIdx;
 
-       fprintf(stderr, "%s:%d returning register AOP_ACC %s\n", __FILE__, __LINE__, aop->aopu.aop_str[offset]);
+                               fprintf(stderr, "%s:%d returning register AOP_ACC %s\n", __FILE__, __LINE__, aop->aopu.aop_str[offset]);
 
-       DEBUGpic16_emitcode(";","%d\tAOP_ACC", __LINE__);
+                               DEBUGpic16_emitcode(";","%d\tAOP_ACC", __LINE__);
        
-       pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
-       PCOR(pcop)->rIdx = rIdx;
-       PCOR(pcop)->r = pic16_typeRegWithIdx(rIdx, REG_SFR, 1); // pic16_regWithIdx(rIdx);
-       PCOR(pcop)->r->wasUsed=1;
-       PCOR(pcop)->r->isFree=0;
+                               pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
+                               PCOR(pcop)->rIdx = rIdx;
+                               PCOR(pcop)->r = pic16_typeRegWithIdx(rIdx, REG_SFR, 1); // pic16_regWithIdx(rIdx);
+                               PCOR(pcop)->r->wasUsed=1;
+                               PCOR(pcop)->r->isFree=0;
 
-       PCOR(pcop)->instance = offset;
-       pcop->type = PCOR(pcop)->r->pc_type;
-//     rs = aop->aopu.aop_reg[offset]->name;
-//     DEBUGpic16_emitcode(";","%d register idx = %d name =%s",__LINE__,rIdx,rs);
-       return pcop;
+                               PCOR(pcop)->instance = offset;
+                               pcop->type = PCOR(pcop)->r->pc_type;
+                               DEBUGpic16_emitcode(";","%d register idx = %d name =%s",__LINE__,rIdx,rs);
+                               return pcop;
 
 
 //     return pic16_popRegFromString(aop->aopu.aop_str[offset], aop->size, offset);
 //      return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
 
 //     assert( 0 );
-      }
+                       }
        
     case AOP_DIR:
-      DEBUGpic16_emitcode(";","%d\tAOP_DIR", __LINE__);
+      DEBUGpic16_emitcode(";","%d\tAOP_DIR (name = %s)", __LINE__, aop->aopu.aop_dir);
       return pic16_popRegFromString(aop->aopu.aop_dir, aop->size, offset, NULL);
        
 #if 0
@@ -2086,7 +2123,7 @@ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
        pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
 //     pcop->type = PO_GPR_REGISTER;
        PCOR(pcop)->rIdx = rIdx;
-       PCOR(pcop)->r = pic16_allocWithIdx( rIdx );     //pic16_regWithIdx(rIdx);
+       PCOR(pcop)->r = pic16_allocWithIdx( rIdx );     //pic16_regWithIdx(rIdx);       
        PCOR(pcop)->r->wasUsed=1;
        PCOR(pcop)->r->isFree=0;
 
@@ -2487,6 +2524,8 @@ void pushaop(asmop *aop, int offset)
 {
   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
+  if(_G.resDirect)return;
+  
   if(is_LitAOp(aop)) {
     pic16_emitpcode(POC_MOVLW, pic16_popGet(aop, offset));
     pic16_emitpcode(POC_MOVWF, pic16_popCopyReg( pic16_stack_postdec ));
@@ -3308,8 +3347,8 @@ static void genCall (iCode *ic)
                 DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
 
 //                pushaop(AOP(IC_LEFT(sic)), size);
-                pic16_mov2w (AOP(IC_LEFT(sic)), size);
-
+                               pic16_mov2w( AOP(IC_LEFT(sic)), size );
+                               
                 if(!_G.resDirect)
                   pushw();
               }
@@ -3745,22 +3784,41 @@ static void genFunction (iCode *ic)
 
         /* if any registers used */
         if (sym->regsUsed) {
-          /* save the registers used */
-          DEBUGpic16_emitcode("; **", "Saving used registers in stack");
-          pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_ENTRY_BEGIN));
-          for ( i = 0 ; i < sym->regsUsed->size ; i++) {
-            if (bitVectBitValue(sym->regsUsed,i)) {
-              pic16_pushpCodeOp( pic16_popRegFromIdx(i) );
-              _G.nRegsSaved++;
-
-              if(!pic16_regWithIdx(i)->wasUsed) {
-                fprintf(stderr, "%s:%d register %s is used in function but was wasUsed = 0d\n",
-                              __FILE__, __LINE__, pic16_regWithIdx(i)->name);
-                pic16_regWithIdx(i)->wasUsed = 1;
+                 pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_ENTRY_BEGIN));
+
+          if(!xinst) {
+            /* save the registers used */
+            DEBUGpic16_emitcode("; **", "Saving used registers in stack");
+            for ( i = 0 ; i < sym->regsUsed->size ; i++) {
+              if (bitVectBitValue(sym->regsUsed,i)) {
+#if 0
+               fprintf(stderr, "%s:%d local register w/rIdx = %d is used in function\n", __FUNCTION__, __LINE__, i);
+#endif
+                pic16_pushpCodeOp( pic16_popRegFromIdx(i) );
+                _G.nRegsSaved++;
+
+                if(!pic16_regWithIdx(i)->wasUsed) {
+                  fprintf(stderr, "%s:%d register %s is used in function but was wasUsed = 0\n",
+                                __FILE__, __LINE__, pic16_regWithIdx(i)->name);
+                  pic16_regWithIdx(i)->wasUsed = 1;
+                }
+              }
+            }
+          } else {
+            
+            /* xinst */
+            DEBUGpic16_emitcode("; **", "Allocate a space in stack to be used as temporary registers");
+            for(i=0;i<sym->regsUsed->size;i++) {
+              if(bitVectBitValue(sym->regsUsed, i)) {
+                _G.nRegsSaved++;
               }
             }
+                        
+//            pic16_emitpcode(POC_ADDFSR, pic16_popGetLit2(2, pic16_popGetLit(_G.nRegsSaved)));
           }
+
           pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_ENTRY_END));
+
         }
     }
        
@@ -12470,8 +12528,16 @@ static void genAssign (iCode *ic)
     } else {
       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-      if(!_G.resDirect)                /* use this aopForSym feature */
-        pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset));
+      if(!_G.resDirect) {                                              /* use this aopForSym feature */
+          if(AOP_TYPE(result) == AOP_ACC) {
+            pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), offset));
+          } else
+          if(AOP_TYPE(right) == AOP_ACC) {
+            pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset));
+          } else {
+            pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset));
+          }
+      }
     }
       
       offset++;
index 34ecf9517fbdb537842330b0b06f14a246ffd475..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)
index 9cbcd596f0056999530746660746b0cc9d40ed1e..1de9fbe1b0c8b35e7b4cae7be11711a1a00e5e06 100644 (file)
 #include "pcoderegs.h"
 #include "pcodeflow.h"
 
+
+#define DEBUG_REMOVE1PCODE     0
+#define HAVE_DBGREGUSAGE       0
+
+
 extern void pic16_pCodeInsertAfter(pCode *pc1, pCode *pc2);
 extern pCode * pic16_findPrevInstruction(pCode *pci);
 extern pBranch * pic16_pBranchAppend(pBranch *h, pBranch *n);
@@ -66,7 +71,8 @@ void AddRegToFlow(regs *reg, pCodeFlow *pcfl)
 /*-----------------------------------------------------------------*
  * 
  *-----------------------------------------------------------------*/
-#if 0
+
+#if HAVE_DBGREGUSAGE
 static void dbg_regusage(set *fregs)
 {
   regs *reg;
@@ -119,13 +125,13 @@ static void dbg_regusage(set *fregs)
     }
   }
 }
-#endif
 
 /*-----------------------------------------------------------------*
  * 
  *-----------------------------------------------------------------*/
-#if 0
-static void dbg_dumpregusage(void)
+
+//static
+void dbg_dumpregusage(void)
 {
 
   fprintf(stderr,"***  Register Usage  ***\n");
@@ -187,7 +193,9 @@ static void pCodeRegMapLiveRangesInFlow(pCodeFlow *pcfl)
       if(PCC_REGISTER & PCI(pc)->outCond)
        addSetIfnotP(& (reg->reglives.assignedpFlows), pcfl);
 
-      addSetIfnotP(& (reg->reglives.usedpCodes), pc);
+       addSetIfnotP(& (reg->reglives.usedpCodes), pc);
+
+//    reg->wasUsed=1;
 
 #if 1
        /* check to see if this pCode has 2 memory operands,
@@ -205,6 +213,8 @@ static void pCodeRegMapLiveRangesInFlow(pCodeFlow *pcfl)
                                        addSetIfnotP(& (reg->reglives.assignedpFlows), pcfl);
                        
                                addSetIfnotP(& (reg->reglives.usedpCodes), pc);
+                               
+//                             reg->wasUsed=1;
                        }
        }
 #endif
@@ -254,7 +264,9 @@ void pic16_pCodeRegMapLiveRanges(pBlock *pb)
   }
 #endif
 
-//  dbg_dumpregusage();
+#if HAVE_DBGREGUSAGE
+  dbg_dumpregusage();
+#endif
 
 }
 
@@ -271,7 +283,7 @@ static void Remove1pcode(pCode *pc, regs *reg)
 
   deleteSetItem (&(reg->reglives.usedpCodes),pc);
 
-#if 0
+#if DEBUG_REMOVE1PCODE
   fprintf(stderr,"removing instruction:\n");
   pc->print(stderr,pc);
 #endif
@@ -289,10 +301,12 @@ static void Remove1pcode(pCode *pc, regs *reg)
 
     if(pcn) {
       if(PCI(pcn)->cline) {
-#if 0
+
+#if DEBUG_REMOVE1PCODE
        fprintf(stderr, "source line has been optimized completely out\n");
        pc->print(stderr,pc);
 #endif
+
       } else {
        PCI(pcn)->cline = PCI(pc)->cline;
       }
@@ -324,7 +338,7 @@ static void  RemoveRegsFromSet(set *regset)
 
       if(used == 0) {
 
-//     fprintf(stderr,"%s:%d: getting rid of reg %s\n",__FILE__, __LINE__, reg->name);
+//  fprintf(stderr,"%s:%d: getting rid of reg %s\n",__FILE__, __LINE__, reg->name);
 
        reg->isFree = 1;
        reg->wasUsed = 0;
index b3b3392c7d258d37455f36ef22a68780bbb2b1fa..83761a206c0a5b125c3e399f05f2376603a8ddd5 100644 (file)
@@ -321,6 +321,21 @@ pic16_decodeOp (unsigned int op)
 
   return buffer;
 }
+
+#if 0
+static char *decodeRegType(short type)
+{
+       switch(type) {
+               case REG_GPR: return "REG_GPR";
+               case REG_PTR: return "REG_PTR";
+               case REG_CND: return "REG_CNT";
+       
+       default:
+               return "<unknown>";
+       }
+}
+#endif
+
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 static char *
@@ -371,7 +386,12 @@ regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alia
        if(name) 
                dReg->name = Safe_strdup(name);
        else {
-               sprintf(buffer,"r0x%02X", dReg->rIdx);
+          if(xinst && pc_type == PO_GPR_TEMP) {
+            sprintf(buffer,"0x%02x", dReg->rIdx);
+          } else {
+            sprintf(buffer,"r0x%02x", dReg->rIdx);
+          }
+          
           if(type == REG_STK) {
             *buffer = 's';
           }
@@ -417,12 +437,18 @@ regWithIdx (set *dRegs, int idx, unsigned fixed)
 {
   regs *dReg;
 
+//#define D(text)      text
+#define D(text)
+
   for (dReg = setFirstItem(dRegs) ; dReg ; 
        dReg = setNextItem(dRegs)) {
 
+       D(fprintf(stderr, "%s:%d testing reg w/rIdx = %d (%d f:%d)\t", __FUNCTION__, __LINE__, dReg->rIdx, idx, fixed));
     if(idx == dReg->rIdx && (fixed == dReg->isFixed)) {
+         D(fprintf(stderr, "found!\n"));
       return dReg;
-    }
+    } else
+         D(fprintf(stderr, "not found!\n"));
   }
 
   return NULL;
@@ -443,6 +469,8 @@ regFindFree (set *dRegs)
 //             __FILE__, __LINE__, dReg->name, dReg, dReg->rIdx, dReg->isFree);
 
     if(dReg->isFree) {
+//             fprintf(stderr, "%s:%d free register found, rIdx = %d\n", __FILE__, __LINE__, dReg->rIdx);
+               
       return dReg;
     }
   }
@@ -528,11 +556,12 @@ allocReg (short type)
 {
   regs * reg=NULL;
   
-#define MAX_P16_NREGS  6
+#define MAX_P16_NREGS  16
 
 
 #if 0
   if(dynrIdx > pic16_nRegs)
+       werror(W_POSSBUG2, __FILE__, __LINE__);
        return NULL;
 #endif
 
@@ -540,12 +569,13 @@ allocReg (short type)
        reg = regFindFree( pic16_dynAllocRegs );
 
        if(reg) {
-//             fprintf(stderr, "%s: [%s] found FREE register %s, rIdx: %d\n", __FILE__, (_inRegAllocator)?"ralloc":"", reg->name, reg->rIdx);
+//             fprintf(stderr, "%s: [%s][cf:%p] found FREE register %s, rIdx: %d\n", __FILE__, (_inRegAllocator)?"ralloc":"", currFunc, reg->name, reg->rIdx);
        }
 
        if(!reg) {
                reg = newReg(REG_GPR, PO_GPR_TEMP, dynrIdx++, NULL, 1, 0, NULL);
-//             fprintf(stderr, "%s: [%s] allocating NEW register %s, rIdx: %d\n", __FILE__, (_inRegAllocator)?"ralloc":"", reg->name, reg->rIdx);
+//             fprintf(stderr, "%s [%s][cf:%p] allocating NEW register %s, rIdx: %d\n", __FILE__,
+//                                     (_inRegAllocator)?"ralloc":"", currFunc, reg->name, reg->rIdx);
 
 #if 1
                 if(_inRegAllocator && (dynrIdx > MAX_P16_NREGS)) {
@@ -553,15 +583,13 @@ allocReg (short type)
 //                  return (NULL);
                 }
 #endif
-
-//             addSet(&pic16_dynAllocRegs, reg);
        }
 
        addSet(&pic16_dynAllocRegs, reg);
        hTabAddItem(&dynAllocRegNames, regname2key(reg->name), reg);
 
-       reg->isFree=0;
-
+//     fprintf(stderr, "%s:%d added reg to pic16_dynAllocRegs = %p\n", __FUNCTION__, __LINE__, pic16_dynAllocRegs);
+       
        debugLog ("%s of type %s for register rIdx: %d (0x%x)\n", __FUNCTION__, debugLogRegType (type), dynrIdx-1, dynrIdx-1);
 
 #if 0
@@ -569,6 +597,7 @@ allocReg (short type)
                __FILE__, __LINE__, __FUNCTION__, reg->name, reg->address, reg->rIdx, reg->isFree);
 #endif
        if(reg) {
+               reg->isFree=0;
                reg->accessBank = 1;    /* this is a temporary register alloc in accessBank */
                reg->isLocal = 1;       /* this is a local frame register */
 //             reg->wasUsed = 1;
@@ -607,7 +636,7 @@ pic16_dirregWithName (char *name)
   while(reg) {
 
     if(STRCASECMP(reg->name, name) == 0) {
-//     fprintf(stderr, "%s:%d: FOUND name = %s\thash = %d\n", __FUNCTION__, __LINE__, reg->name, hkey);
+//             fprintf(stderr, "%s:%d: FOUND name = %s\thash = %d\n", __FUNCTION__, __LINE__, reg->name, hkey);
       return(reg);
     }
 
@@ -634,7 +663,7 @@ pic16_allocregWithName (char *name)
 
   hkey = regname2key(name);
 
-//     fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
+       fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
 
   reg = hTabFirstItemWK(dynAllocRegNames, hkey);
 
@@ -985,7 +1014,7 @@ regs *pic16_typeRegWithIdx (int idx, int type, int fixed)
   regs *dReg;
 
   debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
-//  fprintf(stderr, "%s - requesting index = 0x%x\n", __FUNCTION__, idx);
+//  fprintf(stderr, "%s - requesting index = 0x%x (type = %d [%s])\n", __FUNCTION__, idx, type, decodeRegType(type));
 
   switch (type) {
 
@@ -1000,6 +1029,11 @@ regs *pic16_typeRegWithIdx (int idx, int type, int fixed)
       return dReg;
     }
 
+       if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx, fixed)) != NULL ) {
+      debugLog ("Found an Internal Register!\n");
+      return dReg;
+    }
+               
     break;
   case REG_STK:
     if( (dReg = regWithIdx ( pic16_dynStackRegs, idx, fixed)) != NULL ) {
@@ -1071,10 +1105,10 @@ pic16_allocWithIdx (int idx)
     
     debugLog ("Dynamic Register not found\n");
 
-
+//     return (NULL);
     //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
     werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
-           "regWithIdx not found");
+           "allocWithIdx not found");
     exit (1);
 
   }
@@ -1096,7 +1130,8 @@ pic16_findFreeReg(short type)
   case REG_GPR:
     if((dReg = regFindFree(pic16_dynAllocRegs)) != NULL)
       return dReg;
-    return allocReg( REG_GPR );                //addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL));
+//     return (addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL)));
+    return allocReg( REG_GPR );
 
   case REG_STK:
 
@@ -1123,7 +1158,8 @@ pic16_findFreeRegNext(short type, regs *creg)
   case REG_GPR:
     if((dReg = regFindFreeNext(pic16_dynAllocRegs, creg)) != NULL)
       return dReg;
-    return (addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL)));
+//       return (addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL)));
+    return (allocReg( REG_GPR ) );
 
   case REG_STK:
 
@@ -2860,6 +2896,7 @@ regTypeNum ()
 static DEFSETFUNC (markRegFree)
 {
   ((regs *)item)->isFree = 1;
+//  ((regs *)item)->wasUsed = 0;
 
   return 0;
 }
@@ -3386,6 +3423,8 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
   bitVect *uses;
   iCode *dic, *sic;
 
+  return NULL;
+
   debugLog ("%s\n", __FUNCTION__);
   /* if returning a literal then do nothing */
   if (!IS_SYMOP (op))
@@ -4043,44 +4082,17 @@ pic16_packRegisters (eBBlock * ebp)
 
 
 #if 0
-    /* if this is an arithmetic operation
-     *   && result or left is not rematerializable (so it is a plain arithmetic op)
-     *   && and left is not used after this iCode */
+    /* try to optimize FSR0 usage when reading data memory pointers */
      
-    if(getenv("OPTIMIZE_NEAR_POINTER_GET"))
-
-    if (IS_ARITHMETIC_OP(ic)
-      && !IS_OP_LITERAL (IC_LEFT (ic))
-      && !OP_SYMBOL (IC_RESULT(ic))->rematiCode
-      && !OP_SYMBOL (IC_LEFT(ic))->rematiCode
-      && (OP_LIVETO (IC_LEFT(ic) ) <= ic->seq)
-      ) {
-        iCode *dic = ic->prev;
-        
-          /* search backwards to find assignment from a remat pointer */
-          while(dic && dic->seq >= OP_LIVEFROM( IC_LEFT(ic) )) {
-
-            /* is it a pointer_get? */
-            if(POINTER_GET(dic)
-              && IS_DATA_PTR(OP_SYM_TYPE (IC_LEFT (dic)))) {
-                fprintf(stderr, "%s:%d `%s' is a data pointer (ic seq: %d)\n", __FILE__, __LINE__,
-                          OP_SYMBOL(IC_LEFT(dic))->rname, dic->seq);
-                          
-                /* so we can replace ic->left with dic->left, & remove assignment */
-                ReplaceOpWithCheaperOp( &IC_LEFT(ic), IC_LEFT(dic) );
-                
-                bitVectUnSetBit(OP_USES( IC_LEFT(ic) ), ic->key);
-                bitVectUnSetBit(OP_DEFS( IC_RESULT(dic) ), dic->key );
-                
-//                dic->op = DUMMY_READ_VOLATILE;
-#if 1
-                remiCodeFromeBBlock(ebp, dic);
-                hTabDeleteItem(&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
-#endif
-                break;
-            }
-            dic = dic->prev;
-          }
+    if(getenv("OPTIMIZE_NEAR_POINTER_GET")) {
+         static int fsr0usage=0;
+         static iCode *usic;
+
+               if(POINTER_GET(ic)                              /* this is a memory read */
+                       && ic->loop                                     /* this is in a loop */
+               ) {
+                       fprintf(stderr, "might optimize FSR0 usage\n");
+               }
     }
 #endif
           
@@ -4368,6 +4380,9 @@ dumpEbbsToDebug (eBBlock ** ebbs, int count)
       printiCChain (ebbs[i]->sch, debugF);
     }
 }
+
+void dbg_dumpregusage(void);
+
 /*-----------------------------------------------------------------*/
 /* pic16_assignRegisters - assigns registers to each live range as need  */
 /*-----------------------------------------------------------------*/
@@ -4385,6 +4400,24 @@ pic16_assignRegisters (ebbIndex * ebbi)
 
   _inRegAllocator = 1;
 
+  pic16_freeAllRegs();
+#if 0
+       dbg_dumpregusage();
+       /* clear whats left over from peephole parser */
+       pic16_dynAllocRegs= newSet();   //NULL;
+//     pic16_dynStackRegs= newSet();   //NULL;
+//     pic16_dynProcessorRegs=newSet();        //NULL;
+//     pic16_dynDirectRegs=newSet();           //NULL;
+//     pic16_dynDirectBitRegs=newSet();        //NULL;
+//     pic16_dynInternalRegs=newSet();         //NULL;
+//     pic16_dynAccessRegs=newSet();           //NULL;
+
+//     dynDirectRegNames=NULL;
+       dynAllocRegNames=NULL;
+//     dynProcRegNames=NULL;
+//     dynAccessRegNames=NULL;
+#endif
+
   setToNull ((void *) &_G.funcrUsed);
   pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
 
@@ -4461,6 +4494,8 @@ pic16_assignRegisters (ebbIndex * ebbi)
   if (options.dump_rassgn)
     dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
 
+//  dumpLR(ebbs, count);
+
   /* now get back the chain */
   ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));