allow compile of small large model
[fw/sdcc] / src / ds390 / gen.c
index a9cf9567b8855c86f6ef8a314ba723dbf3c0e289..1984a2e98ad588c2c92baa2937e666de23a7a7c0 100644 (file)
@@ -64,8 +64,11 @@ static char *spname;
 #define D(x) x
 
 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"};
 
@@ -456,13 +459,15 @@ aopForSym (iCode * ic, symbol * sym, bool result, bool useDP2)
 
       if (useDP2)
        {
-         emitcode ("mov", "dpx1,#0x40");
+         if (options.model == MODEL_FLAT24)
+           emitcode ("mov", "dpx1,#0x40");
          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");
        }
@@ -3841,12 +3846,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)
@@ -8253,7 +8263,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
            {
@@ -8262,7 +8273,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");
            }
@@ -8328,7 +8340,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
            {
@@ -8337,7 +8350,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");
            }
@@ -8412,16 +8426,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 ();
        }
@@ -8925,7 +8947,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
            {
@@ -8934,7 +8957,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");
            }
@@ -9000,8 +9024,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 ();
     }
@@ -9209,6 +9237,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         */
 /*-----------------------------------------------------------------*/
@@ -9251,7 +9379,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. */
@@ -9811,6 +9939,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 */
@@ -10042,6 +10178,10 @@ gen390Code (iCode * lic)
          addSet (&_G.sendSet, ic);
          break;
 
+       case ARRAYINIT:
+           genArrayInit(ic);
+           break;
+           
        default:
          ic = ic;
        }