* src/pic16/gen.c, src/pic16/ralloc.c: use
[fw/sdcc] / src / pic16 / gen.c
index 46f7b482c65561e005473421f457efe59a3f00d1..358a2e266e2c18fa9f460776978fbc946a6e114b 100644 (file)
@@ -868,14 +868,14 @@ static bool operandsEqu ( operand *op1, operand *op2)
     if (IS_ITEMP(op1)  &&
         !IS_ITEMP(op2) &&
         sym1->isspilt  &&
-        (sym1->usl.spillLoc == sym2))
+        (SYM_SPIL_LOC(sym1) == sym2))
         return TRUE;
 
     if (IS_ITEMP(op2)  &&
         !IS_ITEMP(op1) &&
         sym2->isspilt  &&
         sym1->level > 0 &&
-        (sym2->usl.spillLoc == sym1))
+        (SYM_SPIL_LOC(sym2) == sym1))
         return TRUE ;
 
     return FALSE ;
@@ -1019,7 +1019,7 @@ void pic16_aopOp (operand *op, iCode *ic, bool result)
             aop->size = getSize(sym->type);
             for ( i = 0 ; i < 1 ; i++ ) {
                 aop->aopu.aop_str[i] = accUse[i];
-//                aop->aopu.pcop = pic16_popRegFromString("WREG", aop->size, sym->usl.spillLoc->offset);
+//                aop->aopu.pcop = pic16_popRegFromString("WREG", aop->size, SYM_SPIL_LOC(sym)->offset);
             }
             fprintf(stderr, "%s:%d allocating AOP_ACC for sym= %s\n", __FILE__, __LINE__, sym->name);
             DEBUGpic16_emitcode(";","%d size=%d",__LINE__,aop->size);
@@ -1031,7 +1031,7 @@ void pic16_aopOp (operand *op, iCode *ic, bool result)
         if (sym->ruonly) {
           /*
           sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
-          aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
+          aop->aopu.pcop = pic16_popGetImmd(SYM_SPIL_LOC(sym)->rname,0,SYM_SPIL_LOC(sym)->offset);
           //pic16_allocDirReg (IC_LEFT(ic));
           aop->size = getSize(sym->type);
           */
@@ -1048,24 +1048,24 @@ void pic16_aopOp (operand *op, iCode *ic, bool result)
         }
 #endif
         /* else spill location  */
-        if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
+        if (SYM_SPIL_LOC(sym) && getSize(sym->type) != getSize(SYM_SPIL_LOC(sym)->type)) {
             /* force a new aop if sizes differ */
-            sym->usl.spillLoc->aop = NULL;
+            SYM_SPIL_LOC(sym)->aop = NULL;
         }
 
 #if 0
         DEBUGpic16_emitcode(";","%s %d %s sym->rname = %s, offset %d",
                             __FUNCTION__,__LINE__,
-                            sym->usl.spillLoc->rname,
-                            sym->rname, sym->usl.spillLoc->offset);
+                            SYM_SPIL_LOC(sym)->rname,
+                            sym->rname, SYM_SPIL_LOC(sym)->offset);
 #endif
 
-        //aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
-        if (sym->usl.spillLoc && sym->usl.spillLoc->rname) {
+        //aop->aopu.pcop = pic16_popGetImmd(SYM_SPIL_LOC(sym)->rname,0,SYM_SPIL_LOC(sym)->offset);
+        if (SYM_SPIL_LOC(sym) && SYM_SPIL_LOC(sym)->rname) {
           sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
-          aop->aopu.pcop = pic16_popRegFromString(sym->usl.spillLoc->rname,
+          aop->aopu.pcop = pic16_popRegFromString(SYM_SPIL_LOC(sym)->rname,
                                                   getSize(sym->type),
-                                                  sym->usl.spillLoc->offset, op);
+                                                  SYM_SPIL_LOC(sym)->offset, op);
         } else if (getSize(sym->type) <= 1) {
           //fprintf (stderr, "%s:%d called for a spillLocation -- assigning WREG instead --- CHECK (size:%u)!\n", __FUNCTION__, __LINE__, getSize(sym->type));
           pic16_emitpcomment (";!!! %s:%d called for a spillLocation -- assigning WREG instead --- CHECK", __FUNCTION__, __LINE__);
@@ -2296,7 +2296,7 @@ static void genUminusFloat(operand *op,operand *result)
 /*-----------------------------------------------------------------*/
 static void genUminus (iCode *ic)
 {
-  int size, i;
+  int lsize, rsize, i;
   sym_link *optype, *rtype;
   symbol *label;
   int needLabel=0;
@@ -2331,40 +2331,65 @@ static void genUminus (iCode *ic)
     }
 
     /* otherwise subtract from zero by taking the 2's complement */
-    size = AOP_SIZE(IC_LEFT(ic));
-    assert( size == AOP_SIZE(IC_RESULT(ic)) );
+    lsize = AOP_SIZE(IC_LEFT(ic));
+    rsize = AOP_SIZE(IC_RESULT(ic));
     label = newiTempLabel ( NULL );
 
     if (pic16_sameRegs (AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
-      for (i=size-1; i > 0; i--) {
-        pic16_emitpcode (POC_COMF, pic16_popGet (AOP(IC_LEFT(ic)), i));
+      /* If the result is longer than the operand,
+         store sign extension (0x00 or 0xff) in W */
+      if (rsize > lsize) {
+        pic16_emitpcode (POC_MOVLW, pic16_popGetLit(0x00));
+        pic16_emitpcode (POC_BTFSS, pic16_popCopyGPR2Bit(pic16_popGet(AOP(IC_LEFT(ic)), lsize-1), 7));
+        pic16_emitpcode (POC_MOVLW, pic16_popGetLit(0xFF));
+      }
+      for (i = rsize - 1; i > 0; --i) {
+        if (i > lsize - 1) {
+          pic16_emitpcode (POC_MOVWF, pic16_popGet (AOP(IC_RESULT(ic)), i));
+        } else {
+          pic16_emitpcode (POC_COMF, pic16_popGet (AOP(IC_RESULT(ic)), i));
+        } // if
       } // for
-      pic16_emitpcode (POC_NEGF, pic16_popGet (AOP(IC_LEFT(ic)), 0));
-      for (i=1; i < size; i++) {
-        if (i == size - 1) { emitSKPNZ; } else { pic16_emitpcode (POC_BNZ, pic16_popGetLabel (label->key)); needLabel++; }
-        pic16_emitpcode (POC_INCF, pic16_popGet (AOP(IC_LEFT(ic)), i));
+      pic16_emitpcode (POC_NEGF, pic16_popGet (AOP(IC_RESULT(ic)), 0));
+      for (i = 1; i < rsize; ++i) {
+        if (i == rsize - 1) {
+          emitSKPNZ;
+        } else {
+          pic16_emitpcode (POC_BNZ, pic16_popGetLabel (label->key)); needLabel++;
+        }
+        pic16_emitpcode (POC_INCF, pic16_popGet (AOP(IC_RESULT(ic)), i));
       } // for
     } else {
-      for (i=size-1; i >= 0; i--) {
+      for (i = min(rsize, lsize) - 1; i >= 0; i--) {
         pic16_emitpcode (POC_COMFW, pic16_popGet (AOP(IC_LEFT(ic)), i));
         pic16_emitpcode (POC_MOVWF, pic16_popGet (AOP(IC_RESULT(ic)), i));
       } // for
-      if (size > 1) {
-        for (i=0; i < size-2; i++) {
+      /* Sign extend if the result is longer than the operand */
+      if (rsize > lsize) {
+        pic16_emitpcode (POC_MOVLW, pic16_popGetLit(0x00));
+        pic16_emitpcode (POC_BTFSC, pic16_popCopyGPR2Bit(pic16_popGet(AOP(IC_RESULT(ic)), lsize - 1), 7));
+        pic16_emitpcode (POC_MOVLW, pic16_popGetLit(0xFF));
+        for (i = rsize - 1; i > lsize - 1; --i) {
+          pic16_emitpcode (POC_MOVWF, pic16_popGet (AOP(IC_RESULT(ic)), i));
+        } // for
+      } // if
+      if (rsize > 1) {
+        for (i = 0; i < rsize - 2; i++) {
           pic16_emitpcode (POC_INCF, pic16_popGet (AOP(IC_RESULT(ic)),i));
-          pic16_emitpcode (POC_BNZ, pic16_popGetLabel (label->key)); needLabel++;
+          pic16_emitpcode (POC_BNZ, pic16_popGetLabel (label->key));
+          needLabel++;
         } // for
-        pic16_emitpcode (POC_INFSNZ, pic16_popGet (AOP(IC_RESULT(ic)), size-2));
+        pic16_emitpcode (POC_INFSNZ, pic16_popGet (AOP(IC_RESULT(ic)), rsize - 2));
       } // if
-      pic16_emitpcode (POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)), size-1));
+      pic16_emitpcode (POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)), rsize - 1));
     }
     if (needLabel)
       pic16_emitpLabel (label->key);
 
 release:
     /* release the aops */
-    pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
-    pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
+    pic16_freeAsmop(IC_LEFT(ic), NULL, ic, (RESULTONSTACK(ic) ? 0 : 1));
+    pic16_freeAsmop(IC_RESULT(ic), NULL, ic, TRUE);
 }
 
 void pic16_loadFromReturn(operand *op, int offset, pCodeOp *src)
@@ -6142,10 +6167,10 @@ static void genXor (iCode *ic, iCode *ifx)
               if  (t == 0x00L)
                 continue;
               else
-               {
-                 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
-                 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(left), offset));
-               }
+                {
+                  pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
+                  pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(left), offset));
+                }
             }
           else
             {
@@ -6607,9 +6632,9 @@ static void AccRsh (int shCount, int andmask)
                 case 7 :
                         pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
                         break;
-               default:
-                       // Rotating by 8 is a NOP.
-                       break;
+                default:
+                        // Rotating by 8 is a NOP.
+                        break;
         }
 
         if (andmask)
@@ -7664,7 +7689,7 @@ static void genRightShiftLiteral (operand *left,
     } // for
   } else if (shCount >= (lsize * 8)) {
     if (sign) {
-      /* 
+      /*
        * Do NOT use
        *    CLRF    result
        *    BTFSC   left, 7
@@ -7903,8 +7928,10 @@ static void pic16_derefPtr (operand *ptr, int p_type, int doWrite, int *fsr0_set
   p_type = DCL_TYPE(operandType(ptr));
 
   switch (p_type) {
-    case FPOINTER:
     case POINTER:
+    case FPOINTER:
+    case IPOINTER:
+    case PPOINTER:
       if (!fsr0_setup || !*fsr0_setup)
       {
         pic16_loadFSR0( ptr, 0 );
@@ -7938,6 +7965,29 @@ static void pic16_derefPtr (operand *ptr, int p_type, int doWrite, int *fsr0_set
       }
       break;
 
+    case CPOINTER:
+      /* XXX: Writing to CPOINTERs not (yet) implemented. */
+      assert ( !doWrite && "Cannot write into __code space!" );
+      if( (AOP_TYPE(ptr) == AOP_PCODE)
+              && ((AOP(ptr)->aopu.pcop->type == PO_IMMEDIATE)
+                  || (AOP(ptr)->aopu.pcop->type == PO_DIR)))
+      {
+          pic16_emitpcode(POC_MOVLW, pic16_popGet     (AOP (ptr), 0));
+          pic16_emitpcode(POC_MOVWF, pic16_popCopyReg (&pic16_pc_tblptrl));
+          pic16_emitpcode(POC_MOVLW, pic16_popGet     (AOP (ptr), 1));
+          pic16_emitpcode(POC_MOVWF, pic16_popCopyReg (&pic16_pc_tblptrh));
+          pic16_emitpcode(POC_MOVLW, pic16_popGet     (AOP (ptr), 2));
+          pic16_emitpcode(POC_MOVWF, pic16_popCopyReg (&pic16_pc_tblptru));
+      } else {
+          mov2fp(pic16_popCopyReg(&pic16_pc_tblptrl), AOP(ptr), 0);
+          mov2fp(pic16_popCopyReg(&pic16_pc_tblptrh), AOP(ptr), 1);
+          mov2fp(pic16_popCopyReg(&pic16_pc_tblptru), AOP(ptr), 2);
+      } // if
+
+      pic16_emitpcodeNULLop (POC_TBLRD_POSTINC);
+      pic16_emitpcode (POC_MOVFW, pic16_popCopyReg (&pic16_pc_tablat));
+      break;
+
     default:
       assert (0 && "invalid pointer type specified");
       break;
@@ -8293,6 +8343,12 @@ static void genConstPointerGet (operand *left,
   pic16_aopOp(result,ic,TRUE);
   size = AOP_SIZE(result);
 
+  /* if bit then unpack */
+  if (IS_BITFIELD(getSpec (operandType (left)))) {
+    genUnpackBits(result,left,"BAD",GPOINTER);
+    goto release;
+  } // if
+
   DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
 
   DEBUGpic16_emitcode ("; "," %d getting const pointer",__LINE__);
@@ -8320,6 +8376,7 @@ static void genConstPointerGet (operand *left,
     offset++;
   }
 
+release:
   pic16_freeAsmop(left,NULL,ic,TRUE);
   pic16_freeAsmop(result,NULL,ic,TRUE);
 }
@@ -8387,20 +8444,10 @@ static void genPointerGet (iCode *ic)
       case POINTER:
       case FPOINTER:
       case IPOINTER:
-        genNearPointerGet (left,result,ic);
-        break;
-
-#if 0
-      /* MUST move them somewhere; handle [PF]POINTERs like POINTERS or like GPOINTERs?!? */
       case PPOINTER:
-        genPagedPointerGet(left,result,ic);
+        genNearPointerGet (left,result,ic);
         break;
 
-      case FPOINTER:
-        genFarPointerGet (left,result,ic);
-        break;
-#endif
-
       case CPOINTER:
         genConstPointerGet (left,result,ic);
         //pic16_emitcodePointerGet (left,result,ic);
@@ -8929,19 +8976,9 @@ static void genPointerSet (iCode *ic)
       case POINTER:
       case FPOINTER:
       case IPOINTER:
-        genNearPointerSet (right,result,ic);
-        break;
-
-#if 0
-      /* MUST move them somewhere; handle [PF]POINTERs like POINTERS or like GPOINTERs?!? */
       case PPOINTER:
-        genPagedPointerSet (right,result,ic);
-        break;
-
-      case FPOINTER:
-        genFarPointerSet (right,result,ic);
+        genNearPointerSet (right,result,ic);
         break;
-#endif
 
       case GPOINTER:
         genGenPointerSet (right,result,ic);
@@ -9222,7 +9259,7 @@ static void genAssign (iCode *ic)
       && !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);
+      //fprintf(stderr, "%s:%d symbol %s = [ %s ] is in code space\n", __FILE__, __LINE__, OP_SYMBOL(result)->name, OP_SYMBOL(right)->name);
 
       // set up table pointer
       if(pic16_isLitOp(right)) {
@@ -9770,7 +9807,6 @@ static void genCast (iCode *ic)
 
                 /* pointer to generic pointer */
                 if (IS_GENPTR(ctype)) {
-                  char *l = zero;
 
                         if (IS_PTR(type))
                                 p_type = DCL_TYPE(type);
@@ -9819,9 +9855,10 @@ static void genCast (iCode *ic)
             }
             /* the last byte depending on type */
             switch (p_type) {
-            case IPOINTER:
             case POINTER:
             case FPOINTER:
+            case IPOINTER:
+            case PPOINTER:
                 pic16_movLit2f(pic16_popGet(AOP(result), GPTRSIZE-1), GPTR_TAG_DATA);
                 break;
 
@@ -9829,11 +9866,6 @@ static void genCast (iCode *ic)
                 pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), GPTRSIZE-1));
                 break;
 
-            case PPOINTER:
-              pic16_emitcode(";BUG!? ","%d",__LINE__);
-                l = "#0x03";
-                break;
-
             case GPOINTER:
                 if (GPTRSIZE > AOP_SIZE(right)) {
                   // assume __data pointer... THIS MIGHT BE WRONG!