* src/SDCCloop.c (loopInvariants): applied fix for bug 1717943, thanks
[fw/sdcc] / src / mcs51 / gen.c
index 8fb85cad76451b20c4a5c4474abc462c8bc3a0d5..a5da703fa0e3dec3487f80268bae174fecb9e9e5 100644 (file)
@@ -1006,8 +1006,7 @@ aopOp (operand * op, iCode * ic, bool result)
               oldAsmOp = sym->usl.spillLoc->aop;
               sym->usl.spillLoc->aop = NULL;
             }
-          sym->aop = op->aop = aop =
-                     aopForSym (ic, sym->usl.spillLoc, result);
+          sym->aop = op->aop = aop = aopForSym (ic, sym->usl.spillLoc, result);
           if (getSize(sym->type) != getSize(sym->usl.spillLoc->type))
             {
               /* Don't reuse the new aop, go with the last one */
@@ -1042,7 +1041,7 @@ aopOp (operand * op, iCode * ic, bool result)
 
 /*-----------------------------------------------------------------*/
 /* freeAsmop - free up the asmop given to an operand               */
-/*----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
 static void
 freeAsmop (operand * op, asmop * aaop, iCode * ic, bool pop)
 {
@@ -1787,15 +1786,13 @@ reAdjustPreg (asmop * aop)
 }
 
 /*-----------------------------------------------------------------*/
-/* opIsGptr: returns non-zero if the passed operand is       */
-/* a generic pointer type.             */
+/* opIsGptr: returns non-zero if the passed operand is             */
+/* a generic pointer type.                                         */
 /*-----------------------------------------------------------------*/
 static int
 opIsGptr (operand * op)
 {
-  sym_link *type = operandType (op);
-
-  if ((AOP_SIZE (op) == GPTRSIZE) && IS_GENPTR (type))
+  if (op && IS_GENPTR (operandType (op)) && (AOP_SIZE (op) == GPTRSIZE))
     {
       return 1;
     }
@@ -1808,8 +1805,8 @@ opIsGptr (operand * op)
 static int
 getDataSize (operand * op)
 {
-  int size;
-  size = AOP_SIZE (op);
+  int size = AOP_SIZE (op);
+
   if (size == GPTRSIZE)
     {
       sym_link *type = operandType (op);
@@ -2174,7 +2171,7 @@ genUminus (iCode * ic)
           if (offset == 0)
             SETC;
           emitcode ("cpl", "a");
-          emitcode ("addc", "a,#0");
+          emitcode ("addc", "a,#0x00");
         }
       else
         {
@@ -2278,7 +2275,7 @@ saveRegisters (iCode * lic)
             }
           emitcode ("mov", "r0,%s", spname);
           MOVA ("r0");
-          emitcode ("add", "a,#%d", count);
+          emitcode ("add", "a,#0x%02x", count);
           emitcode ("mov", "%s,a", spname);
           for (i = 0; i < mcs51_nRegs; i++)
             {
@@ -2420,9 +2417,29 @@ unsaveRegisters (iCode * ic)
 /* pushSide -                                                      */
 /*-----------------------------------------------------------------*/
 static void
-pushSide (operand * oper, int size)
+pushSide (operand * oper, int size, iCode * ic)
 {
   int offset = 0;
+  int nPushed = _G.r0Pushed + _G.r1Pushed;
+
+  aopOp (oper, ic, FALSE);
+
+  if (nPushed != _G.r0Pushed + _G.r1Pushed)
+    {
+      while (offset < size)
+        {
+          char *l = aopGet (oper, offset, FALSE, TRUE);
+          emitcode ("mov", "%s,%s", fReturn[offset++], l);
+        }
+      freeAsmop (oper, NULL, ic, TRUE);
+      offset = 0;
+      while (offset < size)
+        {
+          emitcode ("push", "%s", fReturn[offset++]);
+        }
+      return;
+    }
+
   while (size--)
     {
       char *l = aopGet (oper, offset++, FALSE, TRUE);
@@ -2438,6 +2455,8 @@ pushSide (operand * oper, int size)
           emitcode ("push", "%s", l);
         }
     }
+
+  freeAsmop (oper, NULL, ic, TRUE);
 }
 
 /*-----------------------------------------------------------------*/
@@ -2502,7 +2521,7 @@ genXpush (iCode * ic)
       // allocate space first
       emitcode ("mov", "%s,%s", r->name, spname);
       MOVA (r->name);
-      emitcode ("add", "a,#%d", size);
+      emitcode ("add", "a,#0x%02x", size);
       emitcode ("mov", "%s,a", spname);
 
       while (size--)
@@ -2645,7 +2664,7 @@ saveRBank (int bank, iCode * ic, bool pushPsw)
       // allocate space first
       emitcode ("mov", "%s,%s", r->name, spname);
       MOVA (r->name);
-      emitcode ("add", "a,#%d", count);
+      emitcode ("add", "a,#0x%02x", count);
       emitcode ("mov", "%s,a", spname);
     }
 
@@ -3147,14 +3166,10 @@ genPcall (iCode * ic)
           emitcode ("mov", "a,#(%05d$ >> 8)", (rlbl->key + 100));
           emitcode ("push", "acc");
 
-          /* now push the calling address */
-          aopOp (IC_LEFT (ic), ic, FALSE);
+          /* now push the function address */
+          pushSide (IC_LEFT (ic), FPTRSIZE, ic);
 
-          pushSide (IC_LEFT (ic), FPTRSIZE);
-
-          freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
-
-          /* if send set is not empty the assign */
+          /* if send set is not empty then assign */
           if (_G.sendSet)
             {
               genSend(reverseSet(_G.sendSet));
@@ -4410,34 +4425,58 @@ adjustArithmeticResult (iCode * ic)
 static void
 adjustArithmeticResult (iCode * ic)
 {
-  if (opIsGptr (IC_RESULT (ic)) &&
-      opIsGptr (IC_LEFT (ic)) &&
-      !sameRegs (AOP (IC_RESULT (ic)), AOP (IC_LEFT (ic))))
+  if (opIsGptr (IC_RESULT (ic)))
     {
-      aopPut (IC_RESULT (ic),
-              aopGet (IC_LEFT (ic), GPTRSIZE - 1, FALSE, FALSE),
-              GPTRSIZE - 1);
-    }
+      char buffer[10];
 
-  if (opIsGptr (IC_RESULT (ic)) &&
-      opIsGptr (IC_RIGHT (ic)) &&
-      !sameRegs (AOP (IC_RESULT (ic)), AOP (IC_RIGHT (ic))))
-    {
-      aopPut (IC_RESULT (ic),
-              aopGet (IC_RIGHT (ic), GPTRSIZE - 1, FALSE, FALSE),
-              GPTRSIZE - 1);
-    }
+      if (opIsGptr (IC_LEFT (ic)))
+        {
+          if (!sameRegs (AOP (IC_RESULT (ic)), AOP (IC_LEFT (ic))))
+            {
+              aopPut (IC_RESULT (ic),
+                      aopGet (IC_LEFT (ic), GPTRSIZE - 1, FALSE, FALSE),
+                      GPTRSIZE - 1);
+            }
+          return;
+        }
 
-  if (opIsGptr (IC_RESULT (ic)) &&
-      AOP_SIZE (IC_LEFT (ic)) < GPTRSIZE &&
-      AOP_SIZE (IC_RIGHT (ic)) < GPTRSIZE &&
-      !sameRegs (AOP (IC_RESULT (ic)), AOP (IC_LEFT (ic))) &&
-      !sameRegs (AOP (IC_RESULT (ic)), AOP (IC_RIGHT (ic))))
-    {
-      char buffer[5];
-      SNPRINTF (buffer, sizeof(buffer),
-                "#%d", pointerTypeToGPByte (pointerCode (getSpec (operandType (IC_LEFT (ic)))), NULL, NULL));
-      aopPut (IC_RESULT (ic), buffer, GPTRSIZE - 1);
+      if (opIsGptr (IC_RIGHT (ic)))
+        {
+          if (!sameRegs (AOP (IC_RESULT (ic)), AOP (IC_RIGHT (ic))))
+            {
+              aopPut (IC_RESULT (ic),
+                      aopGet (IC_RIGHT (ic), GPTRSIZE - 1, FALSE, FALSE),
+                      GPTRSIZE - 1);
+            }
+          return;
+        }
+
+      if (IC_LEFT (ic) && AOP_SIZE (IC_LEFT (ic)) < GPTRSIZE &&
+          IC_RIGHT (ic) && AOP_SIZE (IC_RIGHT (ic)) < GPTRSIZE &&
+          !sameRegs (AOP (IC_RESULT (ic)), AOP (IC_LEFT (ic))) &&
+          !sameRegs (AOP (IC_RESULT (ic)), AOP (IC_RIGHT (ic))))
+        {
+          SNPRINTF (buffer, sizeof(buffer),
+                    "#0x%02x", pointerTypeToGPByte (pointerCode (getSpec (operandType (IC_LEFT (ic)))), NULL, NULL));
+          aopPut (IC_RESULT (ic), buffer, GPTRSIZE - 1);
+          return;
+        }
+      if (IC_LEFT (ic) && AOP_SIZE (IC_LEFT (ic)) < GPTRSIZE &&
+          !sameRegs (AOP (IC_RESULT (ic)), AOP (IC_LEFT (ic))))
+        {
+          SNPRINTF (buffer, sizeof(buffer),
+                    "#0x%02x", pointerTypeToGPByte (pointerCode (getSpec (operandType (IC_LEFT (ic)))), NULL, NULL));
+          aopPut (IC_RESULT (ic), buffer, GPTRSIZE - 1);
+          return;
+        }
+      if (IC_RIGHT (ic) && AOP_SIZE (IC_RIGHT (ic)) < GPTRSIZE &&
+          !sameRegs (AOP (IC_RESULT (ic)), AOP (IC_RIGHT (ic))))
+        {
+          SNPRINTF (buffer, sizeof(buffer),
+                    "#0x%02x", pointerTypeToGPByte (pointerCode (getSpec (operandType (IC_RIGHT (ic)))), NULL, NULL));
+          aopPut (IC_RESULT (ic), buffer, GPTRSIZE - 1);
+          return;
+        }
     }
 }
 #endif
@@ -5155,10 +5194,10 @@ genMultOneByte (operand * left,
         emitcode ("inc", "a"); /* inc doesn't set carry flag */
       else
         {
-          emitcode ("add", "a,#1"); /* this sets carry flag */
+          emitcode ("add", "a,#0x01"); /* this sets carry flag */
           emitcode ("xch", "a,b");
           emitcode ("cpl", "a"); /* msb 2's complement */
-          emitcode ("addc", "a,#0");
+          emitcode ("addc", "a,#0x00");
           emitcode ("xch", "a,b");
         }
       emitLabel (lbl);
@@ -5441,7 +5480,7 @@ genDivOneByte (operand * left,
             }
           else /* compiletimeSign */
             {
-              if (aopPutUsesAcc (result, "#0xFF", offset))
+              if (aopPutUsesAcc (result, "#0xff", offset))
                 {
                   emitcode ("push", "acc");
                   pushedA = TRUE;
@@ -7161,7 +7200,7 @@ genOr (iCode * ic, iCode * ifx)
                 }
               else if (bytelit == 0x0FF)
                 {
-                  aopPut (result, "#0xFF", offset);
+                  aopPut (result, "#0xff", offset);
                 }
               else if (IS_AOP_PREG (left))
                 {
@@ -7302,7 +7341,7 @@ genOr (iCode * ic, iCode * ifx)
                       /* dummy read of volatile operand */
                       if (isOperandVolatile (left, FALSE))
                         MOVA (aopGet (left, offset, FALSE, FALSE));
-                      aopPut (result, "#0xFF", offset);
+                      aopPut (result, "#0xff", offset);
                       continue;
                     }
                 }
@@ -9729,7 +9768,7 @@ emitPtrByteSet (char *rname, int p_type, char *src)
 /*-----------------------------------------------------------------*/
 /* genUnpackBits - generates code for unpacking bits               */
 /*-----------------------------------------------------------------*/
-static void
+static char*
 genUnpackBits (operand * result, char *rname, int ptype, iCode *ifx)
 {
   int offset = 0;       /* result byte offset */
@@ -9738,7 +9777,8 @@ genUnpackBits (operand * result, char *rname, int ptype, iCode *ifx)
   sym_link *etype;      /* bitfield type information */
   int blen;             /* bitfield length */
   int bstr;             /* bitfield starting bit within byte */
-  char buffer[10];
+  static char* const accBits[] = {"acc.0", "acc.1", "acc.2", "acc.3",
+                                  "acc.4", "acc.5", "acc.6", "acc.7"};
 
   D(emitcode (";", "genUnpackBits"));
 
@@ -9752,18 +9792,15 @@ genUnpackBits (operand * result, char *rname, int ptype, iCode *ifx)
       emitPtrByteGet (rname, ptype, FALSE);
       if (blen == 1)
         {
-          SNPRINTF (buffer, sizeof(buffer),
-                    "acc.%d", bstr);
-          genIfxJump (ifx, buffer, NULL, NULL, NULL);
+          return accBits[bstr];;
         }
       else
         {
           if (blen < 8)
             emitcode ("anl", "a,#0x%02x",
                       (((unsigned char) -1) >> (8 - blen)) << bstr);
-          genIfxJump (ifx, "a", NULL, NULL, NULL);
+          return "a";
         }
-      return;
     }
   wassert (!ifx);
 
@@ -9832,6 +9869,7 @@ finish:
       while (rsize--)
         aopPut (result, source, offset++);
     }
+  return NULL;
 }
 
 
@@ -9885,9 +9923,9 @@ genNearPointerGet (operand * left,
   asmop *aop = NULL;
   regs *preg = NULL;
   char *rname;
+  char *ifxCond = "a";
   sym_link *rtype, *retype;
   sym_link *ltype = operandType (left);
-  char buffer[80];
 
   D (emitcode (";", "genNearPointerGet"));
 
@@ -9908,6 +9946,9 @@ genNearPointerGet (operand * left,
       return;
     }
 
+  //aopOp (result, ic, FALSE);
+  aopOp (result, ic, result?TRUE:FALSE);
+
  /* if the value is already in a pointer register
      then don't need anything more */
   if (!AOP_INPREG (AOP (left)))
@@ -9942,12 +9983,9 @@ genNearPointerGet (operand * left,
   else
     rname = aopGet (left, 0, FALSE, FALSE);
 
-  //aopOp (result, ic, FALSE);
-  aopOp (result, ic, result?TRUE:FALSE);
-
   /* if bitfield then unpack the bits */
   if (IS_BITFIELD (retype))
-    genUnpackBits (result, rname, POINTER, ifx);
+    ifxCond = genUnpackBits (result, rname, POINTER, ifx);
   else
     {
       /* we have can just get the values */
@@ -9965,6 +10003,8 @@ genNearPointerGet (operand * left,
             }
           else
             {
+              char buffer[80];
+
               SNPRINTF (buffer, sizeof(buffer), "@%s", rname);
               aopPut (result, buffer, offset);
             }
@@ -10003,7 +10043,7 @@ genNearPointerGet (operand * left,
 
   if (ifx && !ifx->generated)
     {
-      genIfxJump (ifx, "a", left, NULL, result);
+      genIfxJump (ifx, ifxCond, left, NULL, result);
     }
 
   /* done */
@@ -10025,6 +10065,7 @@ genPagedPointerGet (operand * left,
   asmop *aop = NULL;
   regs *preg = NULL;
   char *rname;
+  char *ifxCond = "a";
   sym_link *rtype, *retype;
 
   D (emitcode (";", "genPagedPointerGet"));
@@ -10034,6 +10075,8 @@ genPagedPointerGet (operand * left,
 
   aopOp (left, ic, FALSE);
 
+  aopOp (result, ic, FALSE);
+
   /* if the value is already in a pointer register
      then don't need anything more */
   if (!AOP_INPREG (AOP (left)))
@@ -10049,11 +10092,9 @@ genPagedPointerGet (operand * left,
   else
     rname = aopGet (left, 0, FALSE, FALSE);
 
-  aopOp (result, ic, FALSE);
-
   /* if bitfield then unpack the bits */
   if (IS_BITFIELD (retype))
-    genUnpackBits (result, rname, PPOINTER, ifx);
+    ifxCond = genUnpackBits (result, rname, PPOINTER, ifx);
   else
     {
       /* we have can just get the values */
@@ -10102,7 +10143,7 @@ genPagedPointerGet (operand * left,
 
   if (ifx && !ifx->generated)
     {
-      genIfxJump (ifx, "a", left, NULL, result);
+      genIfxJump (ifx, ifxCond, left, NULL, result);
     }
 
   /* done */
@@ -10179,6 +10220,7 @@ genFarPointerGet (operand * left,
                   operand * result, iCode * ic, iCode * pi, iCode * ifx)
 {
   int size, offset;
+  char *ifxCond = "a";
   sym_link *retype = getSpec (operandType (result));
 
   D (emitcode (";", "genFarPointerGet"));
@@ -10191,7 +10233,7 @@ genFarPointerGet (operand * left,
 
   /* if bit then unpack */
   if (IS_BITFIELD (retype))
-    genUnpackBits (result, "dptr", FPOINTER, ifx);
+    ifxCond = genUnpackBits (result, "dptr", FPOINTER, ifx);
   else
     {
       size = AOP_SIZE (result);
@@ -10216,7 +10258,7 @@ genFarPointerGet (operand * left,
 
   if (ifx && !ifx->generated)
     {
-      genIfxJump (ifx, "a", left, NULL, result);
+      genIfxJump (ifx, ifxCond, left, NULL, result);
     }
 
   freeAsmop (result, NULL, ic, TRUE);
@@ -10231,6 +10273,7 @@ genCodePointerGet (operand * left,
                     operand * result, iCode * ic, iCode *pi, iCode *ifx)
 {
   int size, offset;
+  char *ifxCond = "a";
   sym_link *retype = getSpec (operandType (result));
 
   D (emitcode (";", "genCodePointerGet"));
@@ -10243,7 +10286,7 @@ genCodePointerGet (operand * left,
 
   /* if bit then unpack */
   if (IS_BITFIELD (retype))
-    genUnpackBits (result, "dptr", CPOINTER, ifx);
+    ifxCond = genUnpackBits (result, "dptr", CPOINTER, ifx);
   else
     {
       size = AOP_SIZE (result);
@@ -10269,7 +10312,7 @@ genCodePointerGet (operand * left,
 
   if (ifx && !ifx->generated)
     {
-      genIfxJump (ifx, "a", left, NULL, result);
+      genIfxJump (ifx, ifxCond, left, NULL, result);
     }
 
   freeAsmop (result, NULL, ic, TRUE);
@@ -10284,6 +10327,7 @@ genGenPointerGet (operand * left,
                   operand * result, iCode * ic, iCode *pi, iCode *ifx)
 {
   int size, offset;
+  char *ifxCond = "a";
   sym_link *retype = getSpec (operandType (result));
 
   D (emitcode (";", "genGenPointerGet"));
@@ -10297,7 +10341,7 @@ genGenPointerGet (operand * left,
   /* if bit then unpack */
   if (IS_BITFIELD (retype))
     {
-      genUnpackBits (result, "dptr", GPOINTER, ifx);
+      ifxCond = genUnpackBits (result, "dptr", GPOINTER, ifx);
     }
   else
     {
@@ -10323,7 +10367,7 @@ genGenPointerGet (operand * left,
 
   if (ifx && !ifx->generated)
     {
-      genIfxJump (ifx, "a", left, NULL, result);
+      genIfxJump (ifx, ifxCond, left, NULL, result);
     }
 
   freeAsmop (result, NULL, ic, TRUE);
@@ -10788,10 +10832,9 @@ genPagedPointerSet (operand * right,
          if size > 0 && this could be used again
          we have to point it back to where it
          belongs */
-      if ((AOP_SIZE (right) > 1 &&
+      if (AOP_SIZE (right) > 1 &&
           !OP_SYMBOL (result)->remat &&
-          (OP_SYMBOL (result)->liveTo > ic->seq ||
-            ic->depth)) &&
+          (OP_SYMBOL (result)->liveTo > ic->seq || ic->depth) &&
           !pi)
         {
           int size = AOP_SIZE (right) - 1;
@@ -10997,7 +11040,7 @@ genIfx (iCode * ic, iCode * popIc)
 
   /* if there was something to be popped then do it */
   if (popIc)
-    genIpop (popIc);
+      genIpop (popIc);
 
   /* if the condition is a bit variable */
   if (isbit && dup)
@@ -11070,7 +11113,7 @@ genAddrOf (iCode * ic)
     }
 
   /* object not on stack then we need the name */
-  size = AOP_SIZE (IC_RESULT (ic));
+  size = getDataSize (IC_RESULT (ic));
   offset = 0;
 
   while (size--)
@@ -11084,6 +11127,13 @@ genAddrOf (iCode * ic)
         SNPRINTF (s, sizeof(s), "#%s", sym->rname);
       aopPut (IC_RESULT (ic), s, offset++);
     }
+  if (opIsGptr (IC_RESULT (ic)))
+    {
+      char buffer[10];
+      SNPRINTF (buffer, sizeof(buffer),
+                "#0x%02x", pointerTypeToGPByte (pointerCode (getSpec (operandType (IC_LEFT (ic)))), NULL, NULL));
+      aopPut (IC_RESULT (ic), buffer, GPTRSIZE - 1);
+    }
 
 release:
   freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
@@ -11171,7 +11221,7 @@ genAssign (iCode * ic)
 
   /* bit variables done */
   /* general case */
-  size = AOP_SIZE (result);
+  size = getDataSize (result);
   offset = 0;
   if (AOP_TYPE (right) == AOP_LIT)
     lit = ulFromVal (AOP (right)->aopu.aop_lit);
@@ -11212,6 +11262,7 @@ genAssign (iCode * ic)
           offset++;
         }
     }
+  adjustArithmeticResult (ic);
 
 release:
   freeAsmop (result, NULL, ic, TRUE);
@@ -11247,7 +11298,7 @@ genJumpTab (iCode * ic)
       /* multiply by three */
       if (aopGetUsesAcc (IC_JTCOND (ic), 0))
         {
-          emitcode ("mov", "b,#3");
+          emitcode ("mov", "b,#0x03");
           emitcode ("mul", "ab");
         }
       else
@@ -11425,7 +11476,7 @@ genCast (iCode * ic)
                     exit(1);
                 }
 
-                sprintf(gpValStr, "#0x%x", gpVal);
+                sprintf(gpValStr, "#0x%02x", gpVal);
                 aopPut (result, gpValStr, GPTRSIZE - 1);
             }
           goto release;
@@ -11898,18 +11949,18 @@ gen51Code (iCode * lic)
           break;
 
         case IPOP:
-          /* IPOP happens only when trying to restore a
-             spilt live range, if there is an ifx statement
+            /* IPOP happens only when trying to restore a
+               spilt live range, if there is an ifx statement
              following this pop then the if statement might
-             be using some of the registers being popped which
-             would destory the contents of the register so
-             we need to check for this condition and handle it */
+               be using some of the registers being popped which
+               would destory the contents of the register so
+               we need to check for this condition and handle it */
           if (ic->next &&
               ic->next->op == IFX &&
               regsInCommon (IC_LEFT (ic), IC_COND (ic->next)))
             genIfx (ic->next, ic);
-          else
-            genIpop (ic);
+            else
+              genIpop (ic);
           break;
 
         case CALL: