Now --lesspedantic kills EVELYN the modified DOG
[fw/sdcc] / src / ds390 / gen.c
index 0481331e46e0c9bf23d2e63970a57c600024d807..9d27211c2a728064c7ef45bfe326a802140c5ef7 100644 (file)
@@ -41,7 +41,7 @@
 #ifdef HAVE_ENDIAN_H
 #include <endian.h>
 #else
-#if !defined(__BORLANDC__) && !defined(_MSC_VER) && !defined(__MINGW32__)
+#if !defined(__BORLANDC__) && !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__CYGWIN__)
 #warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
 #warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
 #endif
@@ -63,9 +63,15 @@ static char *spname;
 
 #define D(x) x
 
+#define TR_DPTR(s) if (options.model != MODEL_FLAT24) { emitcode(";", " Use_DPTR1 %s ", s); }
+#define TR_AP(s) if (options.model != MODEL_FLAT24) { emitcode(";", " Use_AP %s ", s); }
+
 unsigned fReturnSizeDS390 = 5; /* shared with ralloc.c */
-static char *fReturn[] =
+static char *fReturn24[] =
 {"dpl", "dph", "dpx", "b", "a"};
+static char *fReturn16[] =
+{"dpl", "dph", "b", "a"};
+static char **fReturn = fReturn24;
 static char *accUse[] =
 {"a", "b"};
 
@@ -168,9 +174,9 @@ getFreePtr (iCode * ic, asmop ** aopp, bool result)
 
   /* first check if r0 & r1 are used by this
      instruction, in which case we are in trouble */
-  if ((r0iu = bitVectBitValue (ic->rUsed, R0_IDX)) &&
-      (r1iu = bitVectBitValue (ic->rUsed, R1_IDX)))
-    {
+  r0iu = bitVectBitValue (ic->rUsed, R0_IDX);
+  r1iu = bitVectBitValue (ic->rUsed, R1_IDX);
+  if (r0iu && r1iu) {
       goto endOfWorld;
     }
 
@@ -286,6 +292,7 @@ genSetDPTR (int n)
     }
   else
     {
+      TR_DPTR("#1");
       emitcode ("mov", "dps, #0x01");
     }
 }
@@ -456,13 +463,16 @@ aopForSym (iCode * ic, symbol * sym, bool result, bool useDP2)
 
       if (useDP2)
        {
-         emitcode ("mov", "dpx1,#0x40");
+         if (options.model == MODEL_FLAT24)
+           emitcode ("mov", "dpx1,#0x40");
+   TR_DPTR("#2");
          emitcode ("mov", "dph1,#0x00");
          emitcode ("mov", "dpl1, a");
        }
       else
        {
-         emitcode ("mov", "dpx,#0x40");
+         if (options.model == MODEL_FLAT24)
+           emitcode ("mov", "dpx,#0x40");
          emitcode ("mov", "dph,#0x00");
          emitcode ("mov", "dpl, a");
        }
@@ -973,6 +983,7 @@ aopGet (asmop * aop,
          genSetDPTR (1);
          if (!canClobberACC)
            {
+       TR_AP("#1");
              emitcode ("xch", "a, %s", DP2_RESULT_REG);
            }
        }
@@ -1007,6 +1018,7 @@ aopGet (asmop * aop,
          genSetDPTR (0);
          if (!canClobberACC)
            {
+       TR_AP("#2");
              emitcode ("xch", "a, %s", DP2_RESULT_REG);
              return DP2_RESULT_REG;
            }
@@ -2943,9 +2955,7 @@ genEndFunction (iCode * ic)
        emitcode ("setb", "ea");
 
       /* if debug then send end of function */
-/*  if (options.debug && currFunc)  */
-      if (currFunc)
-       {
+      if (options.debug && currFunc) {
          _G.debugLine = 1;
          emitcode ("", "C$%s$%d$%d$%d ==.",
                    FileBaseName (ic->filename), currFunc->lastLine,
@@ -2983,7 +2993,7 @@ genEndFunction (iCode * ic)
        }
 
       /* if debug then send end of function */
-      if (currFunc)
+      if (options.debug && currFunc)
        {
          _G.debugLine = 1;
          emitcode ("", "C$%s$%d$%d$%d ==.",
@@ -3529,6 +3539,7 @@ genPlus (iCode * ic)
               * above branch.
               */
              assert(AOP_NEEDSACC(IC_RIGHT(ic)));
+       TR_AP("#3");
              D(emitcode(";", "+ AOP_ACC special case."););
              emitcode("xch", "a, %s", DP2_RESULT_REG);
          }
@@ -3537,6 +3548,7 @@ genPlus (iCode * ic)
          {
            if (AOP_TYPE(IC_LEFT(ic)) == AOP_ACC)
            {
+         TR_AP("#4");
                emitcode("add", "a, %s", DP2_RESULT_REG); 
            }
            else
@@ -3843,12 +3855,17 @@ genMinus (iCode * ic)
       else
        {
          /* first add without previous c */
-         if (!offset)
-           emitcode ("add", "a,#0x%02x",
-                     (unsigned int) (lit & 0x0FFL));
-         else
+         if (!offset) {
+           if (!size && lit==-1) {
+             emitcode ("dec", "a");
+           } else {
+             emitcode ("add", "a,#0x%02x",
+                       (unsigned int) (lit & 0x0FFL));
+           }
+         } else {
            emitcode ("addc", "a,#0x%02x",
                      (unsigned int) ((lit >> (offset * 8)) & 0x0FFL));
+         }
        }
 
       if (pushResult)
@@ -5070,6 +5087,7 @@ genFarFarLogicOp(iCode *ic, char *logicOp)
       int size, resultSize, compSize;
       int offset = 0;
       
+      TR_AP("#5");
       D(emitcode(";", "%s special case for 3 far operands.", logicOp););
       compSize = AOP_SIZE(IC_LEFT(ic)) < AOP_SIZE(IC_RIGHT(ic)) ? 
                  AOP_SIZE(IC_LEFT(ic)) : AOP_SIZE(IC_RIGHT(ic));
@@ -6600,7 +6618,6 @@ AccAXRsh (char *x, int shCount)
 #endif
 
 #ifdef BETTER_LITERAL_SHIFT
-//REMOVE ME!!!
 /*-----------------------------------------------------------------*/
 /* AccAXRshS - right shift signed a:x known count (0..7)           */
 /*-----------------------------------------------------------------*/
@@ -6724,7 +6741,7 @@ _loadLeftIntoAx(char      **lsb,
        char *leftByte;
        
        _startLazyDPSEvaluation();
-       if (AOP_TYPE(left) == AOP_DPTR2)
+      if (AOP_TYPE(left) == AOP_DPTR2)
        {
            // Get MSB in A.
                   MOVA(aopGet(AOP(left), offl + MSB16, FALSE, FALSE, TRUE));
@@ -6738,6 +6755,7 @@ _loadLeftIntoAx(char      **lsb,
                   leftByte = aopGet (AOP(left), offl, FALSE, FALSE, TRUE);
            if (strcmp(leftByte, DP2_RESULT_REG))
            {
+               TR_AP("#7");
                emitcode("mov","%s,%s", DP2_RESULT_REG, leftByte);
                   }
                   // And MSB in A.
@@ -6822,11 +6840,11 @@ shiftR2Left2Result (operand * left, int offl,
   /* a:x >> shCount (x = lsb(result)) */
   if (sign)
   {
-    AccAXRshS(aopGet(AOP(result), offr, FALSE, FALSE, FALSE), shCount);
+     AccAXRshS(lsb, shCount);
   }
   else
   {
-    AccAXRsh(aopGet(AOP(result), offr, FALSE, FALSE, FALSE), shCount);
+    AccAXRsh(lsb, shCount);
   }
   
   _storeAxResults(lsb, result, offr);
@@ -7916,7 +7934,7 @@ genUnpackBits (operand * result, char *rname, int ptype)
 
     case CPOINTER:
       emitcode ("clr", "a");
-      emitcode ("movc", "a", "@a+dptr");
+      emitcode ("movc", "a,@a+dptr");
       break;
 
     case GPOINTER:
@@ -7968,7 +7986,7 @@ genUnpackBits (operand * result, char *rname, int ptype)
        case CPOINTER:
          emitcode ("clr", "a");
          emitcode ("inc", "dptr");
-         emitcode ("movc", "a", "@a+dptr");
+         emitcode ("movc", "a,@a+dptr");
          break;
 
        case GPOINTER:
@@ -8256,7 +8274,8 @@ genFarPointerGet (operand * left,
            {
              emitcode ("mov", "dpl,%s", aopGet (AOP (left), 0, FALSE, FALSE, TRUE));
              emitcode ("mov", "dph,%s", aopGet (AOP (left), 1, FALSE, FALSE, TRUE));
-             emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE));
+             if (options.model == MODEL_FLAT24)
+               emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE));
            }
          else
            {
@@ -8265,7 +8284,8 @@ genFarPointerGet (operand * left,
                );
              emitcode ("push", "%s", aopGet (AOP (left), 0, FALSE, TRUE, TRUE));
              emitcode ("push", "%s", aopGet (AOP (left), 1, FALSE, TRUE, TRUE));
-             emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE));
+             if (options.model == MODEL_FLAT24)
+               emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE));
              emitcode ("pop", "dph");
              emitcode ("pop", "dpl");
            }
@@ -8331,7 +8351,8 @@ emitcodePointerGet (operand * left,
            {
              emitcode ("mov", "dpl,%s", aopGet (AOP (left), 0, FALSE, FALSE, TRUE));
              emitcode ("mov", "dph,%s", aopGet (AOP (left), 1, FALSE, FALSE, TRUE));
-             emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE));
+             if (options.model == MODEL_FLAT24)
+               emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE));
            }
          else
            {
@@ -8340,7 +8361,8 @@ emitcodePointerGet (operand * left,
                );
              emitcode ("push", "%s", aopGet (AOP (left), 0, FALSE, TRUE, TRUE));
              emitcode ("push", "%s", aopGet (AOP (left), 1, FALSE, TRUE, TRUE));
-             emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE));
+             if (options.model == MODEL_FLAT24)
+               emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE));
              emitcode ("pop", "dph");
              emitcode ("pop", "dpl");
            }
@@ -8415,16 +8437,24 @@ genGenPointerGet (operand * left,
            genSetDPTR(0);
            _flushLazyDPS();
            emitcode ("mov", "dph,%s", l);
-           l=aopGet(AOP(left),2,FALSE,FALSE,TRUE);
-           genSetDPTR(0);
-           _flushLazyDPS();
-           emitcode ("mov", "dpx,%s", l);
-           emitcode ("mov", "b,%s", aopGet (AOP(left),3,FALSE,FALSE,TRUE));
+           if (options.model == MODEL_FLAT24) {
+             l=aopGet(AOP(left),2,FALSE,FALSE,TRUE);
+             genSetDPTR(0);
+             _flushLazyDPS();
+             emitcode ("mov", "dpx,%s", l);
+             emitcode ("mov", "b,%s", aopGet (AOP(left),3,FALSE,FALSE,TRUE));
+           } else {
+             emitcode ("mov", "b,%s", aopGet (AOP(left),2,FALSE,FALSE,TRUE));
+           }
          } else {
            emitcode ("mov", "dpl,%s", aopGet (AOP(left),0,FALSE,FALSE,TRUE));
            emitcode ("mov", "dph,%s", aopGet (AOP(left),1,FALSE,FALSE,TRUE));
-           emitcode ("mov", "dpx,%s", aopGet (AOP(left),2,FALSE,FALSE,TRUE));
-           emitcode ("mov", "b,%s", aopGet (AOP(left),3,FALSE,FALSE,TRUE));
+           if (options.model == MODEL_FLAT24) {
+             emitcode ("mov", "dpx,%s", aopGet (AOP(left),2,FALSE,FALSE,TRUE));
+             emitcode ("mov", "b,%s", aopGet (AOP(left),3,FALSE,FALSE,TRUE));
+           } else {
+             emitcode ("mov", "b,%s", aopGet (AOP(left),2,FALSE,FALSE,TRUE));
+           }
          }
          _endLazyDPSEvaluation ();
        }
@@ -8928,7 +8958,8 @@ genFarPointerSet (operand * right,
            {
              emitcode ("mov", "dpl,%s", aopGet (AOP (result), 0, FALSE, FALSE, TRUE));
              emitcode ("mov", "dph,%s", aopGet (AOP (result), 1, FALSE, FALSE, TRUE));
-             emitcode ("mov", "dpx,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE));
+             if (options.model == MODEL_FLAT24)
+               emitcode ("mov", "dpx,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE));
            }
          else
            {
@@ -8937,7 +8968,8 @@ genFarPointerSet (operand * right,
                );
              emitcode ("push", "%s", aopGet (AOP (result), 0, FALSE, TRUE, TRUE));
              emitcode ("push", "%s", aopGet (AOP (result), 1, FALSE, TRUE, TRUE));
-             emitcode ("mov", "dpx,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE));
+             if (options.model == MODEL_FLAT24)
+               emitcode ("mov", "dpx,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE));
              emitcode ("pop", "dph");
              emitcode ("pop", "dpl");
            }
@@ -9003,8 +9035,12 @@ genGenPointerSet (operand * right,
        {                       /* we need to get it byte by byte */
          emitcode ("mov", "dpl,%s", aopGet (AOP (result), 0, FALSE, FALSE, TRUE));
          emitcode ("mov", "dph,%s", aopGet (AOP (result), 1, FALSE, FALSE, TRUE));
-         emitcode ("mov", "dpx,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE));
-         emitcode ("mov", "b,%s", aopGet (AOP (result), 3, FALSE, FALSE, TRUE));
+         if (options.model == MODEL_FLAT24) {
+           emitcode ("mov", "dpx,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE));
+           emitcode ("mov", "b,%s", aopGet (AOP (result), 3, FALSE, FALSE, TRUE));
+         } else {
+           emitcode ("mov", "b,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE));
+         }
        }
       _endLazyDPSEvaluation ();
     }
@@ -9212,6 +9248,106 @@ release:
 
 }
 
+/*-----------------------------------------------------------------*/
+/* genArrayInit - generates code for address of                       */
+/*-----------------------------------------------------------------*/
+static void
+genArrayInit (iCode * ic)
+{
+    literalList *iLoop;
+    int         ix, count;
+    int         elementSize = 0, eIndex;
+    unsigned    val, lastVal;
+    sym_link    *type;
+    
+    D (emitcode (";", "genArrayInit "););
+
+    aopOp (IC_LEFT(ic), ic, FALSE, FALSE);
+    
+    if (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD)
+    {
+       // Load immediate value into DPTR.
+       emitcode("mov", "dptr, %s",
+            aopGet(AOP(IC_LEFT(ic)), 0, TRUE, FALSE, TRUE));
+    }
+    else if (AOP_TYPE(IC_LEFT(ic)) != AOP_DPTR)
+    {
+       werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+               "Unexpected operand to genArrayInit.\n");
+       exit(1);
+    }
+    
+    type = operandType(IC_LEFT(ic));
+    
+    if (type && type->next)
+    {
+       elementSize = getSize(type->next);
+    }
+    else
+    {
+       werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+                               "can't determine element size in genArrayInit.\n");
+       exit(1);
+    }
+    
+    iLoop = IC_ARRAYILIST(ic);
+    lastVal = 0xffff;
+    
+    while (iLoop)
+    {
+       bool firstpass = TRUE;
+       
+       emitcode(";", "store %d x 0x%x to DPTR (element size %d)", 
+                iLoop->count, (int)iLoop->literalValue, elementSize);
+       
+       ix = iLoop->count;
+       
+       while (ix)
+       {
+           symbol *tlbl = NULL;
+           
+           count = ix > 256 ? 256 : ix;
+           
+           if (count > 1)
+           {
+               tlbl = newiTempLabel (NULL);
+               if (firstpass || (count & 0xff))
+               {
+                   emitcode("mov", "b, #0x%x", count & 0xff);
+               }
+               
+               emitcode ("", "%05d$:", tlbl->key + 100);
+           }
+           
+           firstpass = FALSE;
+               
+           for (eIndex = 0; eIndex < elementSize; eIndex++)
+           {
+               val = (((int)iLoop->literalValue) >> (eIndex * 8)) & 0xff;
+               if (val != lastVal)
+               {
+                   emitcode("mov", "a, #0x%x", val);
+                   lastVal = val;
+               }
+               
+               emitcode("movx", "@dptr, a");
+               emitcode("inc", "dptr");
+           }
+           
+           if (count > 1)
+           {
+               emitcode("djnz", "b, %05d$", tlbl->key + 100);
+           }
+           
+           ix -= count;
+       }
+       
+       iLoop = iLoop->next;
+    }
+    
+    freeAsmop (IC_LEFT(ic), NULL, ic, TRUE);
+}
+
 /*-----------------------------------------------------------------*/
 /* genFarFarAssign - assignment when both are in far space         */
 /*-----------------------------------------------------------------*/
@@ -9254,7 +9390,7 @@ genFarFarAssign (operand * result, operand * right, iCode * ic)
   {
       /* We can use the '390 auto-toggle feature to good effect here. */
       
-      D(emitcode(";","genFarFarAssign ('390 auto-toggle fun)"););
+      D(emitcode(";","genFarFarAssign (390 auto-toggle fun)"););
       emitcode("mov", "dps, #0x21");   /* Select DPTR2 & auto-toggle. */
       emitcode ("mov", "dptr,#%s", rSym->rname); 
       /* DP2 = result, DP1 = right, DP1 is current. */
@@ -9270,6 +9406,28 @@ genFarFarAssign (operand * result, operand * right, iCode * ic)
       }
       emitcode("mov", "dps, #0");
       freeAsmop (right, NULL, ic, FALSE);
+#if 0
+some alternative code for processors without auto-toggle
+no time to test now, so later well put in...kpb
+        D(emitcode(";","genFarFarAssign (dual-dptr fun)"););
+        emitcode("mov", "dps, #0x01");         /* Select DPTR2. */
+        emitcode ("mov", "dptr,#%s", rSym->rname); 
+        /* DP2 = result, DP1 = right, DP1 is current. */
+        while (size)
+        {
+          --size;
+          emitcode("movx", "a,@dptr");
+          if (size)
+            emitcode("inc", "dptr");
+          emitcode("inc", "dps");
+          emitcode("movx", "@dptr,a");
+          if (size)
+            emitcode("inc", "dptr");
+          emitcode("inc", "dps");
+        }
+        emitcode("mov", "dps, #0");
+        freeAsmop (right, NULL, ic, FALSE);
+#endif
   }
   else
   {
@@ -9814,6 +9972,14 @@ gen390Code (iCode * lic)
 
   lineHead = lineCurr = NULL;
 
+  if (options.model == MODEL_FLAT24) {
+    fReturnSizeDS390 = 5;
+    fReturn = fReturn24;
+  } else {
+    fReturnSizeDS390 = 4;
+    fReturn = fReturn16;
+    options.stack10bit=0;
+  }
 #if 0
   //REMOVE ME!!!
   /* print the allocation information */
@@ -10045,6 +10211,10 @@ gen390Code (iCode * lic)
          addSet (&_G.sendSet, ic);
          break;
 
+       case ARRAYINIT:
+           genArrayInit(ic);
+           break;
+           
        default:
          ic = ic;
        }