* src/mcs51/gen.c (adjustArithmeticResult): fixed bug 1839299
[fw/sdcc] / src / ds390 / gen.c
index d578e4a9774a24af24d7fb03cec0c2e10b7a234c..761b4a9d3cea90939a60f918c93ec4bbd3e8b2b3 100644 (file)
@@ -1947,9 +1947,7 @@ reAdjustPreg (asmop * aop)
 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;
     }
@@ -1962,8 +1960,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);
@@ -2455,12 +2453,32 @@ unsaveRegisters (iCode * ic)
 
 
 /*-----------------------------------------------------------------*/
-/* pushSide -                */
+/* 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, FALSE);
+
+  if (nPushed != _G.r0Pushed + _G.r1Pushed)
+    {
+      while (offset < size)
+        {
+          char *l = aopGet (oper, offset, FALSE, TRUE, NULL);
+          emitcode ("mov", "%s,%s", fReturn[offset++], l);
+        }
+      freeAsmop (oper, NULL, ic, TRUE);
+      offset = 0;
+      while (offset < size)
+        {
+          emitcode ("push", "%s", fReturn[offset++]);
+        }
+      return;
+    }
+
   _startLazyDPSEvaluation ();
   while (size--)
     {
@@ -2478,6 +2496,7 @@ pushSide (operand * oper, int size)
         }
     }
   _endLazyDPSEvaluation ();
+  freeAsmop (oper, NULL, ic, TRUE);
 }
 
 /*-----------------------------------------------------------------*/
@@ -3235,14 +3254,10 @@ genPcall (iCode * ic)
       emitcode ("push", "acc");
     }
 
-  /* now push the calling address */
-  aopOp (IC_LEFT (ic), ic, FALSE, 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));
@@ -4450,8 +4465,8 @@ adjustArithmeticResult (iCode * ic)
     }
 
   if (opIsGptr (IC_RESULT (ic)) &&
-      AOP_SIZE (IC_LEFT (ic)) < GPTRSIZE &&
-      AOP_SIZE (IC_RIGHT (ic)) < GPTRSIZE &&
+      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))))
     {
@@ -11935,13 +11950,14 @@ 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--)
     {
       char s[SDCC_NAME_MAX];
-      if (offset) {
+      if (offset)
+        {
           switch (offset) {
           case 1:
               tsprintf(s, sizeof(s), "#!his",sym->rname);
@@ -11953,9 +11969,7 @@ genAddrOf (iCode * ic)
               tsprintf(s, sizeof(s), "#!hihihis",sym->rname);
               break;
           default: /* should not need this (just in case) */
-              SNPRINTF (s, sizeof(s), "#(%s >> %d)",
-                       sym->rname,
-                       offset * 8);
+              SNPRINTF (s, sizeof(s), "#(%s >> %d)", sym->rname, offset * 8);
           }
       }
       else
@@ -11965,6 +11979,13 @@ genAddrOf (iCode * ic)
 
       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);
@@ -12253,7 +12274,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);
@@ -12295,6 +12316,7 @@ genAssign (iCode * ic)
         }
       _endLazyDPSEvaluation ();
     }
+  adjustArithmeticResult (ic);
 
 release:
   freeAsmop (result, NULL, ic, TRUE);
@@ -14240,7 +14262,7 @@ gen390Code (iCode * lic)
           cln = ic->lineno;
         }
       if (options.iCodeInAsm) {
-        char *iLine = printILine(ic);
+        const char *iLine = printILine(ic);
         emitcode(";", "ic:%d: %s", ic->key, iLine);
         dbuf_free(iLine);
       }
@@ -14466,7 +14488,7 @@ gen390Code (iCode * lic)
 
         default:
             /* This should never happen, right? */
-            fprintf(stderr, "*** Probable error: unsupported op 0x%x (%c) in %s @ %d\n", 
+            fprintf(stderr, "*** Probable error: unsupported op 0x%x (%c) in %s @ %d\n",
                     ic->op, ic->op, __FILE__, __LINE__);
             ic = ic;
         }