* src/pic16/gen.c (genPackBits): removed deprecated warning
[fw/sdcc] / src / pic16 / gen.c
index 26ad8236cdd117d8992744dd0aa4d0f2c57fb2c1..e950d536b3541604bd37c3e303d8572f08cb5da4 100644 (file)
@@ -7,6 +7,7 @@
   PIC port   -  Scott Dattalo scott@dattalo.com (2000)
   PIC16 port -  Martin Dubuc m.dubuc@rogers.com (2002)
              -  Vangelis Rokas vrokas@otenet.gr (2003,2004,2005)
+  Bug Fixes  -  Raphael Neider rneider@web.de (2004,2005)
   
   This program is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the
@@ -68,7 +69,6 @@ extern void pic16_printpBlock(FILE *of, pBlock *pb);
 static asmop *newAsmop (short type);
 static pCodeOp *pic16_popRegFromString(char *str, int size, int offset, operand *op);
 extern pCode *pic16_newpCodeAsmDir(char *asdir, char *argfmt, ...);
-static void mov2f(asmop *dst, asmop *src, int offset);
 static void mov2fp(pCodeOp *dst, asmop *src, int offset);
 static pCodeOp *pic16_popRegFromIdx(int rIdx);
 
@@ -1791,17 +1791,20 @@ pCodeOp *pic16_popCopyReg(pCodeOpReg *pc)
   pCodeOpReg *pcor;
 
   pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
-  pcor->pcop.type = pc->pcop.type;
+  memcpy (pcor, pc, sizeof (pCodeOpReg));
+  pcor->r->wasUsed = 1;
+  
+  //pcor->pcop.type = pc->pcop.type;
   if(pc->pcop.name) {
     if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
       fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
   } else
     pcor->pcop.name = NULL;
 
-  pcor->r = pc->r;
-  pcor->rIdx = pc->rIdx;
-  pcor->r->wasUsed=1;
-  pcor->instance = pc->instance;
+  //pcor->r = pc->r;
+  //pcor->rIdx = pc->rIdx;
+  //pcor->r->wasUsed=1;
+  //pcor->instance = pc->instance;
 
 //  DEBUGpic16_emitcode ("; ***","%s  , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
 
@@ -2380,7 +2383,7 @@ void pic16_mov2w (asmop *aop, int offset)
     pic16_emitpcode(POC_MOVFW,pic16_popGet(aop,offset));
 }
 
-static void mov2f(asmop *dst, asmop *src, int offset)
+void pic16_mov2f(asmop *dst, asmop *src, int offset)
 {
   if(is_LitAOp(src)) {
     pic16_emitpcode(POC_MOVLW, pic16_popGet(src, offset));
@@ -2788,7 +2791,7 @@ static void genUminusFloat(operand *op,operand *result)
     size = AOP_SIZE(op);
 
     while(size--) {
-      mov2f(AOP(result), AOP(op), offset);
+      pic16_mov2f(AOP(result), AOP(op), offset);
       offset++;
     }
     
@@ -3663,14 +3666,16 @@ static void genFunction (iCode *ic)
          * wrapper segment at vector address. The user should take care for
          * this instead. -- VR */
 
-        if(!IFFUNC_ISNAKED(ftype) && (FUNC_INTNO(sym->type) =! INTNO_UNSPEC)) {
+        if(!IFFUNC_ISNAKED(ftype) && (FUNC_INTNO(sym->type) != INTNO_UNSPEC)) {
           asym = newSymbol(asymname, 0);
           apb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute section"));
           pic16_addpBlock( apb );
 
           pic16_addpCode2pBlock(apb, pic16_newpCodeCharP(";-----------------------------------------"));
           pic16_addpCode2pBlock(apb, pic16_newpCodeFunction(moduleName, asym->name));
-          pic16_addpCode2pBlock(apb, pic16_newpCode(POC_GOTO, pic16_popGetWithString( sym->rname )));
+          //pic16_addpCode2pBlock(apb, pic16_newpCode(POC_GOTO, pic16_popGetWithString( sym->rname )));
+          //pic16_addpCode2pBlock(apb, pic16_newpCode(POC_GOTO, pic16_newpCodeOpLabel (sym->rname, 0)));
+         pic16_addpCode2pBlock(apb, pic16_newpCodeAsmDir ("GOTO", "%s", sym->rname)); /* this suppresses a warning in LinkFlow */
                
           /* mark the end of this tiny function */
           pic16_addpCode2pBlock(apb,pic16_newpCodeFunction(NULL,NULL));
@@ -5050,7 +5055,7 @@ static void genCmp (operand *left,operand *right,
     left = right;
     right = dummy;
 
-    performedLt ^= 1; // instead of "left < right" we check for "right >= left+1"
+    performedLt ^= 1; // instead of "left < right" we check for "right >= left+1, i.e. "right < left+1"
   } else if (isAOP_LIT(right)) {
     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
   } // if
@@ -5813,7 +5818,7 @@ static void genCmp (operand *left,operand *right,
        
        pctemp = pic16_popGetTempReg(1);
        pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
-       pic16_emitpcode(POC_MOVWF, pctemp);             //pic16_pic16_popRegFromIdx(pic16_Gstack_base_addr));
+       pic16_emitpcode(POC_MOVWF, pctemp);             //pic16_popRegFromIdx(pic16_Gstack_base_addr));
        pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
        pic16_emitpcode(POC_XORWF, pctemp);             //pic16_popRegFromIdx(pic16_Gstack_base_addr));
        pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
@@ -8223,7 +8228,6 @@ static void genXor (iCode *ic, iCode *ifx)
 static void genInline (iCode *ic)
 {
   char *buffer, *bp, *bp1;
-  char *cbuf;
     
        DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
@@ -8239,12 +8243,14 @@ static void genInline (iCode *ic)
         }
         bp = bp1 = buffer;
 
-       cbuf = Safe_strdup( buffer );
-
+#if 0
+  /* This is an experimental code for #pragma inline
+     and is temporarily disabled for 2.5.0 release */
         if(asmInlineMap)
         {
           symbol *sym;
           char *s;
+          char *cbuf;
           int cblen;
 
             cbuf = Safe_strdup(buffer);
@@ -8291,6 +8297,7 @@ static void genInline (iCode *ic)
             
             bp = bp1 = buffer;
         }
+#endif  /* 0 */
 
        /* emit each line as a code */
        while (*bp) {
@@ -8689,7 +8696,7 @@ static void shiftR1Left2ResultSigned (operand *left, int offl,
     } else {
       pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),offr));
       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0, PO_GPR_REGISTER));
-      pic16_emitpcode(POC_DECF,  pic16_popGet(AOP(result),offr));
+      pic16_emitpcode(POC_SETF,  pic16_popGet(AOP(result),offr));
       pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0, PO_GPR_REGISTER));
       pic16_emitpcode(POC_BCF,   pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0, PO_GPR_REGISTER));
     }
@@ -8704,7 +8711,7 @@ static void shiftR1Left2ResultSigned (operand *left, int offl,
     } else {
       pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),offr));
       pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0, PO_GPR_REGISTER));
-      pic16_emitpcode(POC_DECF,  pic16_popGet(AOP(result),offr));
+      pic16_emitpcode(POC_SETF,  pic16_popGet(AOP(result),offr));
     }
 
   default:
@@ -9544,7 +9551,7 @@ static void genLeftShift (iCode *ic)
 #endif
       {
         /* we don't know if left is a literal or a register, take care -- VR */
-        mov2f(AOP(result), AOP(left), offset);
+        pic16_mov2f(AOP(result), AOP(left), offset);
       }
       offset++;
     }
@@ -9576,7 +9583,7 @@ static void genLeftShift (iCode *ic)
 #if 1
       /* this is already done, why change it? */
       if (!pic16_sameRegs(AOP(left),AOP(result))) {
-                mov2f(AOP(result), AOP(left), 0);
+                pic16_mov2f(AOP(result), AOP(left), 0);
       }
 #endif
 
@@ -9727,7 +9734,7 @@ static void genLeftShift (iCode *ic)
       } else {
 
         /* we don't know if left is a literal or a register, take care -- VR */
-        mov2f(AOP(result), AOP(left), offset);
+        pic16_mov2f(AOP(result), AOP(left), offset);
       }
       offset++;
     }
@@ -9756,7 +9763,7 @@ static void genLeftShift (iCode *ic)
 
       tlbl = newiTempLabel(NULL);
       if (!pic16_sameRegs(AOP(left),AOP(result))) {
-                mov2f(AOP(result), AOP(left), 0);
+                pic16_mov2f(AOP(result), AOP(left), 0);
                 
 //             pic16_emitpcode(POC_MOVFW,  pic16_popGet(AOP(left),0));
 //             pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(result),0));
@@ -9882,7 +9889,7 @@ static void genrshTwo (operand *result,operand *left,
 
     if(sign) {
       pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0, PO_GPR_REGISTER));
-      pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
+      pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),MSB16));
     }
   }
 
@@ -10043,7 +10050,7 @@ static void genRightShiftLiteral (operand *left,
   if(shCount == 0){
     assert (res_size <= lsize);
     while (res_size--) {
-      mov2f (AOP(result), AOP(left), res_size);
+      pic16_mov2f (AOP(result), AOP(left), res_size);
     } // for
   }
 
@@ -10053,7 +10060,7 @@ static void genRightShiftLiteral (operand *left,
       pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),LSB));
       if(sign) {
        pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
-       pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),LSB));
+       pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),LSB));
       }
     } else {
 
@@ -10422,7 +10429,7 @@ static void genGenericShift (iCode *ic, int isShiftLeft) {
   // (e.g. char c = 0x100 << -3 will become c = 0x00 >> 3 == 0x00 instad of 0x20)
   // This is fine, as it only occurs for left shifting with negative count which is not standardized!
   for (offset=0; offset < min(AOP_SIZE(left), AOP_SIZE(result)); offset++) {
-    mov2f (AOP(result),AOP(left), offset);
+    pic16_mov2f (AOP(result),AOP(left), offset);
   } // for
 
   // if result is longer than left, fill with zeros (or sign)
@@ -11498,7 +11505,7 @@ static void genPackBits (sym_link    *etype , operand *result,
                                  pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
                                }
                                
-                               // warnings will be emitted below
+                               // warnings will be emitted below (if desired)
                                //pic16_emitpcomment ("; =?= genPackBits, GPOINTER...");
                                 //werror(W_POSSBUG2, __FILE__, __LINE__);
                                break;
@@ -11543,7 +11550,7 @@ static void genPackBits (sym_link    *etype , operand *result,
                                
                                // this should work in all cases (as soon as gptrget/gptrput work on EEPROM and PROGRAM MEMORY)
                                //pic16_emitpcomment ("; =?= genPackBits, GPOINTER access");
-                                werror(W_POSSBUG2, __FILE__, __LINE__);
+                                //werror(W_POSSBUG2, __FILE__, __LINE__);
                                break;
 
                        default:
@@ -12097,7 +12104,7 @@ static void genGenPointerSet (operand *right,
                               operand *result, iCode *ic)
 {
   int size;
-  sym_link *retype = getSpec(operandType(right));
+  sym_link *retype = getSpec(operandType(result));
 
     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
@@ -12165,6 +12172,7 @@ static void genPointerSet (iCode *ic)
     move it to the correct pointer register */
     type = operandType(result);
     etype = getSpec(type);
+    
     /* if left is of type of pointer then it is simple */
     if (IS_PTR(type) && !IS_FUNC(type->next)) {
         p_type = DCL_TYPE(type);
@@ -12467,16 +12475,21 @@ static void genAssign (iCode *ic)
   if (AOP_TYPE(right) == AOP_REG) {
     DEBUGpic16_emitcode(";   ", "%s:%d assign from register\n", __FUNCTION__, __LINE__);
     while (size--) {
-      
       pic16_emitpcode (POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset++));
     } // while
     goto release;
   }
 
+  /* when do we have to read the program memory?
+   * - if right itself is a symbol in code space
+   *   (we don't care what it points to if it's a pointer)
+   * - AND right is not a function (we would want its address)
+   */
   if(AOP_TYPE(right) != AOP_LIT
-       && IN_CODESPACE(SPEC_OCLS(OP_SYMBOL(right)->etype))
+       && IN_CODESPACE(SPEC_OCLS(OP_SYM_ETYPE(right)))
        && !IS_FUNC(OP_SYM_TYPE(right))
-       ) {
+       && !IS_ITEMP(right))
+  {
        DEBUGpic16_emitcode(";   ", "%s:%d symbol in code space, take special care\n", __FUNCTION__, __LINE__);
        fprintf(stderr, "%s:%d symbol %s = [ %s ] is in code space\n", __FILE__, __LINE__, OP_SYMBOL(result)->name, OP_SYMBOL(right)->name);
 
@@ -12499,7 +12512,8 @@ static void genAssign (iCode *ic)
                                pic16_popCopyReg(&pic16_pc_tblptru)));
        }
 
-       size = min(getSize(OP_SYM_ETYPE(right)), AOP_SIZE(result));
+       /* must fetch 3 bytes for pointers (was OP_SYM_ETYPE before) */
+       size = min(getSize(OP_SYM_TYPE(right)), AOP_SIZE(result));
        while(size--) {
                pic16_emitpcodeNULLop(POC_TBLRD_POSTINC);
                pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_tablat),
@@ -12507,7 +12521,9 @@ static void genAssign (iCode *ic)
                offset++;
        }
 
-       size = getSize(OP_SYM_ETYPE(right));
+       /* FIXME: for pointers we need to extend differently (according
+        * to pointer type DATA/CODE/EEPROM/... :*/
+       size = getSize(OP_SYM_TYPE(right));
        if(AOP_SIZE(result) > size) {
                size = AOP_SIZE(result) - size;
                while(size--) {
@@ -13005,7 +13021,7 @@ static void genCast (iCode *ic)
            while (size--) {
              if(offset < AOP_SIZE(right)) {
                 DEBUGpic16_emitcode("; ***","%s  %d - pointer cast3 ptype = 0x%x",__FUNCTION__,__LINE__, p_type);
-                mov2f(AOP(result), AOP(right), offset);
+                pic16_mov2f(AOP(result), AOP(right), offset);
 /*
                if ((AOP_TYPE(right) == AOP_PCODE) && 
                    AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
@@ -13096,7 +13112,7 @@ static void genCast (iCode *ic)
 
     while (size--) {
       if(!_G.resDirect)
-        mov2f(AOP(result), AOP(right), offset);
+        pic16_mov2f(AOP(result), AOP(right), offset);
       offset++;
     }
 
@@ -13113,7 +13129,7 @@ static void genCast (iCode *ic)
        /* Save one instruction of casting char to int */
        pic16_emitpcode(POC_CLRF,   pic16_popGet(AOP(result),offset));
        pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
-       pic16_emitpcode(POC_DECF,   pic16_popGet(AOP(result),offset));
+       pic16_emitpcode(POC_SETF,   pic16_popGet(AOP(result),offset));
       } else {
         pic16_emitpcode(POC_CLRF,pic16_popCopyReg(&pic16_pc_wreg));