Previous fix was BADDD . this should do it
[fw/sdcc] / src / mcs51 / gen.c
index a7779cb51ca019eb107b535f05da984b368ae38d..6ea17c482f7864b701db871d101b18b5d35e52b4 100644 (file)
@@ -377,7 +377,7 @@ aopForRemat (symbol * sym)
 {
   iCode *ic = sym->rematiCode;
   asmop *aop = newAsmop (AOP_IMMD);
-  int ptr_type ;
+  int ptr_type=0;
   int val = 0;
 
   for (;;)
@@ -391,6 +391,10 @@ aopForRemat (symbol * sym)
              aop->aopu.aop_immd.from_cast_remat = 1;
              ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
              ptr_type = DCL_TYPE(from_type);
+             if (ptr_type == IPOINTER) {
+               // bug #481053
+               ptr_type = POINTER;
+             }
              continue ;
       } else break;
 
@@ -550,7 +554,7 @@ aopOp (operand * op, iCode * ic, bool result)
     }
 
   /* if already has a asmop then continue */
-  if (op->aop)
+  if (op->aop )
     return;
 
   /* if the underlying symbol has a aop */
@@ -622,6 +626,10 @@ aopOp (operand * op, iCode * ic, bool result)
        }
 
       /* else spill location  */
+      if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
+         /* force a new aop if sizes differ */
+         sym->usl.spillLoc->aop = NULL;
+      }
       sym->aop = op->aop = aop =
        aopForSym (ic, sym->usl.spillLoc, result);
       aop->size = getSize (sym->type);
@@ -1956,6 +1964,7 @@ genCall (iCode * ic)
   /* if we need assign a result value */
   if ((IS_ITEMP (IC_RESULT (ic)) &&
        (OP_SYMBOL (IC_RESULT (ic))->nRegs ||
+       OP_SYMBOL (IC_RESULT (ic))->accuse || 
        OP_SYMBOL (IC_RESULT (ic))->spildir)) ||
       IS_TRUE_SYMOP (IC_RESULT (ic)))
     {
@@ -2625,6 +2634,8 @@ genRet (iCode * ic)
 {
   int size, offset = 0, pushed = 0;
 
+  D(emitcode (";", "genRet"));
+
   /* if we have no return value then
      just generate the "ret" */
   if (!IC_LEFT (ic))
@@ -2735,8 +2746,6 @@ genPlusIncr (iCode * ic)
   unsigned int icount;
   unsigned int size = getDataSize (IC_RESULT (ic));
 
-  D(emitcode (";", "genPlusIncr"));
-
   /* will try to generate an increment */
   /* if the right side is not a literal
      we cannot */
@@ -2748,6 +2757,8 @@ genPlusIncr (iCode * ic)
   if ((icount = (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit)) > 4)
     return FALSE;
 
+  D(emitcode (";", "genPlusIncr"));
+
   /* if increment 16 bits in register */
   if (sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))) &&
       (size > 1) &&
@@ -2883,6 +2894,8 @@ outBitAcc (operand * result)
 static void
 genPlusBits (iCode * ic)
 {
+  D(emitcode (";", "genPlusBits"));
+
   if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY)
     {
       symbol *lbl = newiTempLabel (NULL);
@@ -3087,8 +3100,6 @@ genMinusDec (iCode * ic)
   unsigned int icount;
   unsigned int size = getDataSize (IC_RESULT (ic));
 
-  D(emitcode (";", "genMinusDec"));
-
   /* will try to generate an increment */
   /* if the right side is not a literal
      we cannot */
@@ -3100,6 +3111,8 @@ genMinusDec (iCode * ic)
   if ((icount = (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit)) > 4)
     return FALSE;
 
+  D(emitcode (";", "genMinusDec"));
+
   /* if decrement 16 bits in register */
   if (sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))) &&
       (size > 1) &&
@@ -3227,6 +3240,9 @@ static void
 genMinusBits (iCode * ic)
 {
   symbol *lbl = newiTempLabel (NULL);
+
+  D(emitcode (";", "genMinusBits"));
+
   if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY)
     {
       emitcode ("mov", "c,%s", AOP (IC_LEFT (ic))->aopu.aop_dir);
@@ -3256,6 +3272,8 @@ genMinus (iCode * ic)
   int size, offset = 0;
   unsigned long lit = 0L;
 
+  D(emitcode (";", "genMinus"));
+
   aopOp (IC_LEFT (ic), ic, FALSE);
   aopOp (IC_RIGHT (ic), ic, FALSE);
   aopOp (IC_RESULT (ic), ic, TRUE);
@@ -3328,6 +3346,8 @@ genMultbits (operand * left,
             operand * right,
             operand * result)
 {
+  D(emitcode (";", "genMultbits"));
+
   emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
   emitcode ("anl", "c,%s", AOP (right)->aopu.aop_dir);
   outBitC (result);
@@ -3346,6 +3366,8 @@ genMultOneByte (operand * left,
   symbol *lbl;
   int size=AOP_SIZE(result);
 
+  D(emitcode (";", "genMultOneByte"));
+
   if (size<1 || size>2) {
     // this should never happen
       fprintf (stderr, "size!=1||2 (%d) in %s at line:%d \n", 
@@ -3448,6 +3470,8 @@ genMult (iCode * ic)
   operand *right = IC_RIGHT (ic);
   operand *result = IC_RESULT (ic);
 
+  D(emitcode (";", "genMult"));
+
   /* assign the amsops */
   aopOp (left, ic, FALSE);
   aopOp (right, ic, FALSE);
@@ -3496,6 +3520,8 @@ genDivbits (operand * left,
 
   char *l;
 
+  D(emitcode (";", "genDivbits"));
+
   /* the result must be bit */
   emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE));
   l = aopGet (AOP (left), 0, FALSE, FALSE);
@@ -3520,6 +3546,8 @@ genDivOneByte (operand * left,
   symbol *lbl;
   int size, offset;
 
+  D(emitcode (";", "genDivOneByte"));
+
   size = AOP_SIZE (result) - 1;
   offset = 1;
   /* signed or unsigned */
@@ -3603,6 +3631,8 @@ genDiv (iCode * ic)
   operand *right = IC_RIGHT (ic);
   operand *result = IC_RESULT (ic);
 
+  D(emitcode (";", "genDiv"));
+
   /* assign the amsops */
   aopOp (left, ic, FALSE);
   aopOp (right, ic, FALSE);
@@ -3644,6 +3674,8 @@ genModbits (operand * left,
 
   char *l;
 
+  D(emitcode (";", "genModbits"));
+
   /* the result must be bit */
   emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE));
   l = aopGet (AOP (left), 0, FALSE, FALSE);
@@ -3668,6 +3700,8 @@ genModOneByte (operand * left,
   char *l;
   symbol *lbl;
 
+  D(emitcode (";", "genModOneByte"));
+
   /* signed or unsigned */
   if (SPEC_USIGN (opetype))
     {
@@ -3741,6 +3775,8 @@ genMod (iCode * ic)
   operand *right = IC_RIGHT (ic);
   operand *result = IC_RESULT (ic);
 
+  D(emitcode (";", "genMod"));
+
   /* assign the amsops */
   aopOp (left, ic, FALSE);
   aopOp (right, ic, FALSE);
@@ -3782,6 +3818,8 @@ genIfxJump (iCode * ic, char *jval)
   symbol *tlbl = newiTempLabel (NULL);
   char *inst;
 
+  D(emitcode (";", "genIfxJump"));
+
   /* if true label then we jump if condition
      supplied is true */
   if (IC_TRUE (ic))
@@ -3818,6 +3856,8 @@ genCmp (operand * left, operand * right,
   int size, offset = 0;
   unsigned long lit = 0L;
 
+  D(emitcode (";", "genCmp"));
+
   /* if left & right are bit variables */
   if (AOP_TYPE (left) == AOP_CRY &&
       AOP_TYPE (right) == AOP_CRY)
@@ -3926,6 +3966,8 @@ genCmpGt (iCode * ic, iCode * ifx)
   sym_link *letype, *retype;
   int sign;
 
+  D(emitcode (";", "genCmpGt"));
+
   left = IC_LEFT (ic);
   right = IC_RIGHT (ic);
   result = IC_RESULT (ic);
@@ -3953,6 +3995,8 @@ genCmpLt (iCode * ic, iCode * ifx)
   sym_link *letype, *retype;
   int sign;
 
+  D(emitcode (";", "genCmpLt"));
+
   left = IC_LEFT (ic);
   right = IC_RIGHT (ic);
   result = IC_RESULT (ic);
@@ -4068,6 +4112,8 @@ genCmpEq (iCode * ic, iCode * ifx)
 {
   operand *left, *right, *result;
 
+  D(emitcode (";", "genCmpEq"));
+
   aopOp ((left = IC_LEFT (ic)), ic, FALSE);
   aopOp ((right = IC_RIGHT (ic)), ic, FALSE);
   aopOp ((result = IC_RESULT (ic)), ic, TRUE);
@@ -4275,6 +4321,8 @@ hasInc (operand *op, iCode *ic)
     if (bitVectBitValue(OP_USES(op),lic->key) || (unsigned) lic->defKey == op->key) {
       return NULL;
     }
+    /* if GOTO or IFX */
+    if (lic->op == IFX || lic->op == GOTO) break;
     lic = lic->next;
   }
   return NULL;
@@ -4289,6 +4337,8 @@ genAndOp (iCode * ic)
   operand *left, *right, *result;
   symbol *tlbl;
 
+  D(emitcode (";", "genAndOp"));
+
   /* note here that && operations that are in an
      if statement are taken away by backPatchLabels
      only those used in arthmetic operations remain */
@@ -4329,6 +4379,8 @@ genOrOp (iCode * ic)
   operand *left, *right, *result;
   symbol *tlbl;
 
+  D(emitcode (";", "genOrOp"));
+
   /* note here that || operations that are in an
      if statement are taken away by backPatchLabels
      only those used in arthmetic operations remain */
@@ -4438,6 +4490,8 @@ genAnd (iCode * ic, iCode * ifx)
   int bytelit = 0;
   char buffer[10];
 
+  D(emitcode (";", "genAnd"));
+
   aopOp ((left = IC_LEFT (ic)), ic, FALSE);
   aopOp ((right = IC_RIGHT (ic)), ic, FALSE);
   aopOp ((result = IC_RESULT (ic)), ic, TRUE);
@@ -4740,6 +4794,8 @@ genOr (iCode * ic, iCode * ifx)
   int size, offset = 0;
   unsigned long lit = 0L;
 
+  D(emitcode (";", "genOr"));
+
   aopOp ((left = IC_LEFT (ic)), ic, FALSE);
   aopOp ((right = IC_RIGHT (ic)), ic, FALSE);
   aopOp ((result = IC_RESULT (ic)), ic, TRUE);
@@ -7355,7 +7411,10 @@ genGenPointerGet (operand * left,
       if (AOP_TYPE (left) == AOP_IMMD)
        {
          emitcode ("mov", "dptr,%s", aopGet (AOP (left), 0, TRUE, FALSE));
-         emitcode ("mov", "b,#%d", pointerCode (retype));
+         if (AOP(left)->aopu.aop_immd.from_cast_remat) 
+                 emitcode ("mov", "b,%s",aopGet(AOP (left), AOP_SIZE(left)-1, FALSE, FALSE));
+         else
+                 emitcode ("mov", "b,#%d", pointerCode (retype));
        }
       else
        {                       /* we need to get it byte by byte */
@@ -7387,6 +7446,7 @@ genGenPointerGet (operand * left,
   if (pi && AOP_TYPE (left) != AOP_IMMD && AOP_TYPE (left) != AOP_STR) {
     aopPut ( AOP (left), "dpl", 0);
     aopPut ( AOP (left), "dph", 1);
+    aopPut ( AOP (left), "b", 2);
     pi->generated = 1;
   }
   freeAsmop (left, NULL, ic, TRUE);
@@ -7421,6 +7481,13 @@ genPointerGet (iCode * ic, iCode *pi)
       p_type = PTR_TYPE (SPEC_OCLS (etype));
     }
 
+  /* special case when cast remat */
+  if (p_type == GPOINTER && OP_SYMBOL(left)->remat &&
+      IS_CAST_ICODE(OP_SYMBOL(left)->rematiCode)) {
+         left = IC_RIGHT(OP_SYMBOL(left)->rematiCode);
+         type =   type = operandType (left);
+         p_type = DCL_TYPE (type);
+  }
   /* now that we have the pointer type we assign
      the pointer values */
   switch (p_type)
@@ -7952,7 +8019,10 @@ genGenPointerSet (operand * right,
       if (AOP_TYPE (result) == AOP_IMMD)
        {
          emitcode ("mov", "dptr,%s", aopGet (AOP (result), 0, TRUE, FALSE));
-         emitcode ("mov", "b,%s + 1", aopGet (AOP (result), 0, TRUE, FALSE));
+         if (AOP(result)->aopu.aop_immd.from_cast_remat) 
+                 emitcode ("mov", "b,%s",aopGet(AOP (result), AOP_SIZE(result)-1, FALSE, FALSE));
+         else 
+                 emitcode ("mov", "b,%s + 1", aopGet (AOP (result), 0, TRUE, FALSE));
        }
       else
        {                       /* we need to get it byte by byte */
@@ -7985,6 +8055,7 @@ genGenPointerSet (operand * right,
   if (pi && AOP_TYPE (result) != AOP_STR && AOP_TYPE (result) != AOP_IMMD) {
     aopPut (AOP(result),"dpl",0);
     aopPut (AOP(result),"dph",1);
+    aopPut (AOP(result),"b",2);
     pi->generated=1;
   }
   freeAsmop (result, NULL, ic, TRUE);
@@ -8021,6 +8092,13 @@ genPointerSet (iCode * ic, iCode *pi)
       p_type = PTR_TYPE (SPEC_OCLS (etype));
     }
 
+  /* special case when cast remat */
+  if (p_type == GPOINTER && OP_SYMBOL(result)->remat &&
+      IS_CAST_ICODE(OP_SYMBOL(result)->rematiCode)) {
+         result = IC_RIGHT(OP_SYMBOL(result)->rematiCode);
+         type =   type = operandType (result);
+         p_type = DCL_TYPE (type);
+  }
   /* now that we have the pointer type we assign
      the pointer values */
   switch (p_type)
@@ -8106,7 +8184,9 @@ genAddrOf (iCode * ic)
       if (sym->stack)
        {
          emitcode ("mov", "a,_bp");
-         emitcode ("add", "a,#0x%02x", ((char) sym->stack & 0xff));
+         emitcode ("add", "a,#0x%02x", ((sym->stack < 0) ?
+                                        ((char) (sym->stack - _G.nRegsSaved)) :
+                                        ((char) sym->stack)) & 0xff);
          aopPut (AOP (IC_RESULT (ic)), "a", 0);
        }
       else