Many changes. Started a second pass to the register allocator & true 10bit stack
authorsandeep <sandeep@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Wed, 14 Nov 2001 07:14:17 +0000 (07:14 +0000)
committersandeep <sandeep@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Wed, 14 Nov 2001 07:14:17 +0000 (07:14 +0000)
fully implemented

git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@1589 4a8a32a2-be11-0410-ad9d-d568d2c75423

src/ds390/gen.c
src/ds390/main.c
src/ds390/ralloc.c

index ebc99f5c2b7bb116030f68e492049e21a67565fa..2e25ea96b48922b038fccd80ba579017bcbff94a 100644 (file)
@@ -460,27 +460,29 @@ aopForSym (iCode * ic, symbol * sym, bool result, bool useDP2)
       if (_G.accInUse)
        emitcode ("push", "acc");
 
-      emitcode ("mov", "a,_bp");
-      emitcode ("add", "a,#0x%02x",
-               ((sym->stack < 0) ?
-                ((char) (sym->stack - _G.nRegsSaved)) :
-                ((char) sym->stack)) & 0xff);
-
-      if (useDP2)
-       {
+      emitcode ("mov", "a,_bpx");
+      emitcode ("clr","c");
+      emitcode ("subb", "a,#0x%02x",
+               -((sym->stack < 0) ?
+                 ((short) (sym->stack - _G.nRegsSaved)) :
+                 ((short) sym->stack)) & 0xff);
+      emitcode ("mov","b,a");
+      emitcode ("mov","a,#0x%02x",(-((sym->stack < 0) ?
+                                    ((short) (sym->stack - _G.nRegsSaved)) :
+                                    ((short) sym->stack)) >> 8) & 0xff);
+      emitcode ("subb","a,_bpx+1");
+      if (useDP2) {
          if (options.model == MODEL_FLAT24)
-           emitcode ("mov", "dpx1,#0x40");
+             emitcode ("mov", "dpx1,#0x40");
          TR_DPTR("#2");
-         emitcode ("mov", "dph1,#0x00");
-         emitcode ("mov", "dpl1, a");
-       }
-      else
-       {
+         emitcode ("mov", "dph1,a");
+         emitcode ("mov", "dpl1,b");
+      } else {
          if (options.model == MODEL_FLAT24)
-           emitcode ("mov", "dpx,#0x40");
-         emitcode ("mov", "dph,#0x00");
-         emitcode ("mov", "dpl, a");
-       }
+             emitcode ("mov", "dpx,#0x40");
+         emitcode ("mov", "dph,a");
+         emitcode ("mov", "dpl,b");
+      }
 
       if (_G.accInUse)
        emitcode ("pop", "acc");
@@ -2353,19 +2355,26 @@ genCall (iCode * ic)
 
   /* adjust the stack for parameters if
      required */
-  if (ic->parmBytes)
-    {
-      int i;
-      if (ic->parmBytes > 3)
-       {
-         emitcode ("mov", "a,%s", spname);
-         emitcode ("add", "a,#0x%02x", (-ic->parmBytes) & 0xff);
-         emitcode ("mov", "%s,a", spname);
-       }
-      else
-       for (i = 0; i < ic->parmBytes; i++)
-         emitcode ("dec", "%s", spname);
-    }
+  if (ic->parmBytes) {
+      if (options.stack10bit) {
+         emitcode ("clr","c");
+         emitcode ("mov","a,sp");
+         emitcode ("subb","a,#0x%02x",ic->parmBytes & 0xff);
+         emitcode ("mov","sp,a");
+         emitcode ("mov","a,#0x%02x",(ic->parmBytes >> 8) & 0xff);
+         emitcode ("subb","a,_ESP");
+         emitcode ("mov","_ESP,a");      
+      } else {
+         int i;
+         if (ic->parmBytes > 3) {
+             emitcode ("mov", "a,%s", spname);
+             emitcode ("add", "a,#0x%02x", (-ic->parmBytes) & 0xff);
+             emitcode ("mov", "%s,a", spname);
+         } else
+             for (i = 0; i < ic->parmBytes; i++)
+                 emitcode ("dec", "%s", spname);
+      }
+  }
 
   /* if we hade saved some registers then unsave them */
   if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
@@ -2789,44 +2798,54 @@ genFunction (iCode * ic)
       emitcode ("mov", "psw,#0x%02x", (FUNC_REGBANK (sym->type) << 3) & 0x00ff);
     }
 
-  if (IFFUNC_ISREENT (sym->type) || options.stackAuto)
-    {
-
-      if (options.useXstack)
-       {
-         emitcode ("mov", "r0,%s", spname);
-         emitcode ("mov", "a,_bp");
-         emitcode ("movx", "@r0,a");
-         emitcode ("inc", "%s", spname);
-       }
-      else
-       {
-         /* set up the stack */
-         emitcode ("push", "_bp");     /* save the callers stack  */
-       }
-      emitcode ("mov", "_bp,%s", spname);
-    }
+  if (IFFUNC_ISREENT (sym->type) || options.stackAuto) {
+      if (options.stack10bit) {
+         emitcode ("push","_bpx");
+         emitcode ("push","_bpx+1");
+         emitcode ("mov","_bpx,%s",spname);
+         emitcode ("mov","_bpx+1,_ESP");
+         emitcode ("anl","_bpx+1,#3");
+      } else {
+         if (options.useXstack) {
+             emitcode ("mov", "r0,%s", spname);
+             emitcode ("mov", "a,_bp");
+             emitcode ("movx", "@r0,a");
+             emitcode ("inc", "%s", spname);
+         } else {
+             /* set up the stack */
+             emitcode ("push", "_bp"); /* save the callers stack  */
+         }
+         emitcode ("mov", "_bp,%s", spname);
+      }
+  }
 
   /* adjust the stack for the function */
-  if (sym->stack)
-    {
-
+  if (sym->stack) {
       int i = sym->stack;
-      if (i > 256)
-       werror (W_STACK_OVERFLOW, sym->name);
-
-      if (i > 3 && sym->recvSize < 4)
-       {
-
-         emitcode ("mov", "a,sp");
-         emitcode ("add", "a,#0x%02x", ((char) sym->stack & 0xff));
-         emitcode ("mov", "sp,a");
-
-       }
-      else
-       while (i--)
-         emitcode ("inc", "sp");
-    }
+      if (options.stack10bit) {
+         if ( i > 1024) werror (W_STACK_OVERFLOW, sym->name);
+         assert (sym->recvSize <= 4);
+         emitcode ("mov","a,sp");
+         emitcode ("add","a,#0x%02x", ((short) sym->stack & 0xff));
+         emitcode ("mov","sp,a");
+         emitcode ("mov","a,_ESP");
+         emitcode ("addc","a,0x%02x", (((short) sym->stack) >> 8) & 0xff);
+         emitcode ("mov","_ESP,a");
+      } else {
+         if (i > 256)
+             werror (W_STACK_OVERFLOW, sym->name);
+         
+         if (i > 3 && sym->recvSize < 4) {
+             
+             emitcode ("mov", "a,sp");
+             emitcode ("add", "a,#0x%02x", ((char) sym->stack & 0xff));
+             emitcode ("mov", "sp,a");
+             
+         } else
+             while (i--)
+                 emitcode ("inc", "sp");
+      }
+  }
 
   if (sym->xstack)
     {
@@ -2854,36 +2873,40 @@ genEndFunction (iCode * ic)
       return;
   }
 
-  if (IFFUNC_ISREENT (sym->type) || options.stackAuto)
-    {
-      emitcode ("mov", "%s,_bp", spname);
-    }
+  if (IFFUNC_ISREENT (sym->type) || options.stackAuto) {
+      if (options.stack10bit) {
+         emitcode ("mov", "sp,_bpx", spname);
+         emitcode ("mov", "_ESP,_bpx+1", spname);
+      } else {
+         emitcode ("mov", "%s,_bp", spname);
+      }
+  }
 
   /* if use external stack but some variables were
      added to the local stack then decrement the
      local stack */
-  if (options.useXstack && sym->stack)
-    {
+  if (options.useXstack && sym->stack) {
       emitcode ("mov", "a,sp");
       emitcode ("add", "a,#0x%02x", ((char) -sym->stack) & 0xff);
       emitcode ("mov", "sp,a");
-    }
+  }
 
 
-  if ((IFFUNC_ISREENT (sym->type) || options.stackAuto))
-    {
-      if (options.useXstack)
-       {
+  if ((IFFUNC_ISREENT (sym->type) || options.stackAuto)) {
+      if (options.useXstack) {
          emitcode ("mov", "r0,%s", spname);
          emitcode ("movx", "a,@r0");
          emitcode ("mov", "_bp,a");
          emitcode ("dec", "%s", spname);
-       }
-      else
-       {
-         emitcode ("pop", "_bp");
-       }
-    }
+      } else {
+         if (options.stack10bit) {
+             emitcode ("pop", "_bpx+1");
+             emitcode ("pop", "_bpx");
+         } else {
+             emitcode ("pop", "_bp");
+         }
+      }
+  }
 
   /* restore the register bank  */
   if (FUNC_REGBANK (sym->type) || IFFUNC_ISISR (sym->type))
@@ -3409,9 +3432,10 @@ adjustArithmeticResult (iCode * ic)
 // that the IC_RESULT operand is not aopOp'd.
 #define AOP_OP_3_NOFATAL(ic, rc) \
     aopOp (IC_RIGHT(ic),ic,FALSE, FALSE); \
-    aopOp (IC_LEFT(ic),ic,FALSE, (AOP_TYPE(IC_RIGHT(ic)) == AOP_DPTR)); \
+    aopOp (IC_LEFT(ic),ic,FALSE, (AOP_TYPE(IC_RIGHT(ic)) == AOP_DPTR) || \
+                                  (OP_SYMBOL(IC_RESULT(ic))->ruonly)); \
     if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR2 && \
-        isOperandInFarSpace(IC_RESULT(ic))) \
+        (isOperandInFarSpace(IC_RESULT(ic)) || OP_SYMBOL(IC_RESULT(ic))->ruonly )) \
     { \
        /* No can do; DPTR & DPTR2 in use, and we need another. */ \
        rc = TRUE; \
@@ -3485,7 +3509,22 @@ genPlus (iCode * ic)
   D (emitcode (";", "genPlus "););
 
   /* special cases :- */
-
+  if (isOperandEqual(IC_LEFT(ic),IC_RESULT(ic)) &&
+      isOperandLiteral(IC_RIGHT(ic)) && OP_SYMBOL(IC_RESULT(ic))->ruonly) {
+      aopOp (IC_RIGHT (ic), ic, TRUE, FALSE);
+      size = floatFromVal (AOP (IC_RIGHT(ic))->aopu.aop_lit);
+      while (size--) emitcode ("inc","dptr");
+      freeAsmop (IC_RIGHT (ic), NULL, ic, FALSE);
+      return ;
+  }
+  if ( IS_SYMOP(IC_LEFT(ic)) && 
+       OP_SYMBOL(IC_LEFT(ic))->remat &&
+       isOperandInFarSpace(IC_RIGHT(ic))) {
+      operand *op = IC_RIGHT(ic);
+      IC_RIGHT(ic) = IC_LEFT(ic);
+      IC_LEFT(ic) = op;
+  }
+               
   AOP_OP_3_NOFATAL (ic, pushResult);
   if (pushResult)
     {
@@ -5397,18 +5436,20 @@ hasInc (operand *op, iCode *ic)
   if (IS_BITVAR(retype)||!IS_PTR(type)) return NULL;
   isize = getSize(type->next);
   while (lic) {
-    /* if operand of the form op = op + <sizeof *op> */
-    if (lic->op == '+' && isOperandEqual(IC_LEFT(lic),op) &&
-       isOperandEqual(IC_RESULT(lic),op) && 
-       isOperandLiteral(IC_RIGHT(lic)) &&
-       operandLitValue(IC_RIGHT(lic)) == isize) {
-      return lic;
-    }
-    /* if the operand used or deffed */
-    if (bitVectBitValue(OP_USES(op),lic->key) || (unsigned) lic->defKey == op->key) {
-      return NULL;
-    }
-    lic = lic->next;
+      /* if operand of the form op = op + <sizeof *op> */
+      if (lic->op == '+' && isOperandEqual(IC_LEFT(lic),op) &&
+         isOperandEqual(IC_RESULT(lic),op) && 
+         isOperandLiteral(IC_RIGHT(lic)) &&
+         operandLitValue(IC_RIGHT(lic)) == isize) {
+         return lic;
+      }
+      /* if the operand used or deffed */
+      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;
 }
@@ -8826,7 +8867,6 @@ genFarPointerGet (operand * left,
        }
     }
   /* so dptr know contains the address */
-  freeAsmop (left, NULL, ic, TRUE);
   aopOp (result, ic, FALSE, TRUE);
 
   /* if bit then unpack */
@@ -8858,8 +8898,14 @@ genFarPointerGet (operand * left,
     if (options.model == MODEL_FLAT24)
            aopPut ( AOP (left), "dpx", 2);
     pi->generated = 1;
+  } else if (OP_SYMBOL(left)->ruonly && AOP_SIZE(result) > 1 &&
+            (OP_SYMBOL (left)->liveTo > ic->seq || ic->depth)) {
+      
+      size = AOP_SIZE (result) - 1;
+      while (size--) emitcode ("lcall","__decdptr");
   }
 
+  freeAsmop (left, NULL, ic, TRUE);
   freeAsmop (result, NULL, ic, TRUE);
 }
 
@@ -8935,13 +8981,18 @@ emitcodePointerGet (operand * left,
       _endLazyDPSEvaluation ();
     }
   if (pi && AOP_TYPE (left) != AOP_IMMD) {
-    aopPut ( AOP (left), "dpl", 0);
-    aopPut ( AOP (left), "dph", 1);
-    if (options.model == MODEL_FLAT24)
-           aopPut ( AOP (left), "dpx", 2);
-    pi->generated = 1;
+      aopPut ( AOP (left), "dpl", 0);
+      aopPut ( AOP (left), "dph", 1);
+      if (options.model == MODEL_FLAT24)
+         aopPut ( AOP (left), "dpx", 2);
+      pi->generated = 1;
+  } else if (OP_SYMBOL(left)->ruonly && AOP_SIZE(result) > 1 &&
+            (OP_SYMBOL (left)->liveTo > ic->seq || ic->depth)) {
+      
+      size = AOP_SIZE (result) - 1;
+      while (size--) emitcode ("lcall","__decdptr");
   }
-
+  
   freeAsmop (left, NULL, ic, TRUE);
   freeAsmop (result, NULL, ic, TRUE);
 }
@@ -9033,11 +9084,17 @@ genGenPointerGet (operand * left,
     aopPut ( AOP (left), "dpl", 0);
     aopPut ( AOP (left), "dph", 1);
     if (options.model == MODEL_FLAT24) {
-           aopPut ( AOP (left), "dpx", 2);
-           aopPut ( AOP (left), "b", 3);       
+       aopPut ( AOP (left), "dpx", 2);
+       aopPut ( AOP (left), "b", 3);   
     } else  aopPut ( AOP (left), "b", 2);      
     pi->generated = 1;
+  } else if (OP_SYMBOL(left)->ruonly && AOP_SIZE(result) > 1 &&
+            (OP_SYMBOL (left)->liveTo > ic->seq || ic->depth)) {
+      
+      size = AOP_SIZE (result) - 1;
+      while (size--) emitcode ("lcall","__decdptr");
   }
+
   freeAsmop (left, NULL, ic, TRUE);
   freeAsmop (result, NULL, ic, TRUE);
 }
@@ -9577,11 +9634,16 @@ genFarPointerSet (operand * right,
     }
 
   if (pi && AOP_TYPE (result) != AOP_IMMD) {
-    aopPut (AOP(result),"dpl",0);
-    aopPut (AOP(result),"dph",1);
-    if (options.model == MODEL_FLAT24)
-       aopPut (AOP(result),"dpx",2);
-    pi->generated=1;
+      aopPut (AOP(result),"dpl",0);
+      aopPut (AOP(result),"dph",1);
+      if (options.model == MODEL_FLAT24)
+         aopPut (AOP(result),"dpx",2);
+      pi->generated=1;
+  } else if (OP_SYMBOL(result)->ruonly && AOP_SIZE(right) > 1 &&
+            (OP_SYMBOL (result)->liveTo > ic->seq || ic->depth)) {
+      
+      size = AOP_SIZE (right) - 1;
+      while (size--) emitcode ("lcall","__decdptr");
   }
   freeAsmop (result, NULL, ic, TRUE);
   freeAsmop (right, NULL, ic, TRUE);
@@ -9655,15 +9717,20 @@ genGenPointerSet (operand * right,
     }
 
   if (pi && AOP_TYPE (result) != AOP_IMMD) {
-    aopPut (AOP(result),"dpl",0);
-    aopPut (AOP(result),"dph",1);
-    if (options.model == MODEL_FLAT24) {
-       aopPut (AOP(result),"dpx",2);
-       aopPut (AOP(result),"b",3);
-    } else {
-       aopPut (AOP(result),"b",2);
-    }
-    pi->generated=1;
+      aopPut (AOP(result),"dpl",0);
+      aopPut (AOP(result),"dph",1);
+      if (options.model == MODEL_FLAT24) {
+         aopPut (AOP(result),"dpx",2);
+         aopPut (AOP(result),"b",3);
+      } else {
+         aopPut (AOP(result),"b",2);
+      }
+      pi->generated=1;
+  } else if (OP_SYMBOL(result)->ruonly && AOP_SIZE(right) > 1 &&
+            (OP_SYMBOL (result)->liveTo > ic->seq || ic->depth)) {
+      
+      size = AOP_SIZE (right) - 1;
+      while (size--) emitcode ("lcall","__decdptr");
   }
   freeAsmop (result, NULL, ic, TRUE);
   freeAsmop (right, NULL, ic, TRUE);
@@ -9786,47 +9853,52 @@ genAddrOf (iCode * ic)
   /* if the operand is on the stack then we
      need to get the stack offset of this
      variable */
-  if (sym->onStack)
-    {
-      /* if it has an offset then we need to compute
-         it */
-      if (sym->stack)
-       {
-         emitcode ("mov", "a,_bp");
-         emitcode ("add", "a,#0x%02x", ((char) sym->stack & 0xff));
-         aopPut (AOP (IC_RESULT (ic)), "a", 0);
-       }
-      else
-       {
-         /* we can just move _bp */
-         aopPut (AOP (IC_RESULT (ic)), "_bp", 0);
-       }
-      /* fill the result with zero */
-      size = AOP_SIZE (IC_RESULT (ic)) - 1;
-
-
-      if (options.stack10bit && size < (FPTRSIZE - 1))
-       {
-         fprintf (stderr,
-                  "*** warning: pointer to stack var truncated.\n");
-       }
+  if (sym->onStack) {
+      
+      /* if 10 bit stack */
+      if (options.stack10bit) {
+         /* if it has an offset then we need to compute it */
+         if (sym->stack) {
+             emitcode ("mov", "a,_bpx");
+             emitcode ("add", "a,#0x%02x", ((char) sym->stack & 0xff));
+             emitcode ("mov", "b,a");
+             emitcode ("mov", "a,_bpx+1");
+             emitcode ("addc","a,#0x%02x", (((short) sym->stack) >> 8) & 0xff);
+             aopPut (AOP (IC_RESULT (ic)), "b", 0);
+             aopPut (AOP (IC_RESULT (ic)), "a", 1);
+             aopPut (AOP (IC_RESULT (ic)), "#0x40", 2);
+         } else {
+             /* we can just move _bp */
+             aopPut (AOP (IC_RESULT (ic)), "_bpx", 0);
+             aopPut (AOP (IC_RESULT (ic)), "_bpx+1", 1);
+             aopPut (AOP (IC_RESULT (ic)), "#0x40", 2);
+         }       
+      } else {
+         /* if it has an offset then we need to compute it */
+         if (sym->stack) {
+             emitcode ("mov", "a,_bp");
+             emitcode ("add", "a,#0x%02x", ((char) sym->stack & 0xff));
+             aopPut (AOP (IC_RESULT (ic)), "a", 0);
+         } else {
+             /* we can just move _bp */
+             aopPut (AOP (IC_RESULT (ic)), "_bp", 0);
+         }
+         /* fill the result with zero */
+         size = AOP_SIZE (IC_RESULT (ic)) - 1;
+         
+         
+         if (options.stack10bit && size < (FPTRSIZE - 1)) {
+             fprintf (stderr,
+                      "*** warning: pointer to stack var truncated.\n");
+         }
 
-      offset = 1;
-      while (size--)
-       {
-         /* Yuck! */
-         if (options.stack10bit && offset == 2)
-           {
-             aopPut (AOP (IC_RESULT (ic)), "#0x40", offset++);
-           }
-         else
-           {
+         offset = 1;
+         while (size--) {
              aopPut (AOP (IC_RESULT (ic)), zero, offset++);
-           }
-       }
-
+         }      
+      }
       goto release;
-    }
+  }
 
   /* object not on stack then we need the name */
   size = AOP_SIZE (IC_RESULT (ic));
index b905d3cee1e61b1c7042f96887cf471490b2dcf8..f343ebaf3031a7940b2c5de95995f4ddcbd53808 100644 (file)
@@ -105,9 +105,9 @@ _ds390_finaliseOptions (void)
     port->s.fptr_size = 3;
     port->s.gptr_size = 4;
 
-    port->stack.isr_overhead++;        /* Will save dpx on ISR entry. */
+    port->stack.isr_overhead += 2;     /* Will save dpx on ISR entry. */
 
-    port->stack.call_overhead++;       /* This acounts for the extra byte 
+    port->stack.call_overhead += 2;    /* This acounts for the extra byte 
                                 * of return addres on the stack.
                                 * but is ugly. There must be a 
                                 * better way.
index 06f1be1c6ed3cb043e6739e27ae6ea98e8f0628d..a46422179ab38fc02a3736c2012fc4233f1cd980 100644 (file)
@@ -42,6 +42,7 @@ static struct
     bitVect *spiltSet;
     set *stackSpil;
     bitVect *regAssigned;
+    bitVect *totRegAssigned;    /* final set of LRs that got into registers */
     short blockSpil;
     int slocNum;
     bitVect *funcrUsed;                /* registers used in a function */
@@ -78,6 +79,7 @@ regs regs390[] =
 };
 int ds390_nRegs = 13;
 static void spillThis (symbol *);
+static void freeAllRegs ();
 
 /*-----------------------------------------------------------------*/
 /* allocReg - allocates register of given type                     */
@@ -142,6 +144,15 @@ freeReg (regs * reg)
   reg->isFree = 1;
 }
 
+/*-----------------------------------------------------------------*/
+/* useReg - marks a register  as used                              */
+/*-----------------------------------------------------------------*/
+static void
+useReg (regs * reg)
+{
+  reg->isFree = 0;
+}
+
 
 /*-----------------------------------------------------------------*/
 /* nFreeRegs - returns number of free registers                    */
@@ -482,9 +493,10 @@ createStackSpil (symbol * sym)
   if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
     {
       /* found a free one : just update & return */
-      sym->usl.spillLoc = sloc;
+      sym->usl.spillLoc = sloc;      
       sym->stackSpil = 1;
       sloc->isFree = 0;
+      sloc->allocreq++;
       addSetHead (&sloc->usl.itmpStack, sym);
       return sym;
     }
@@ -596,10 +608,11 @@ spillThis (symbol * sym)
 
 
   /* mark it has spilt & put it in the spilt set */
-  sym->isspilt = 1;
+  sym->isspilt = sym->spillA = 1;
   _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
 
   bitVectUnSetBit (_G.regAssigned, sym->key);
+  bitVectUnSetBit (_G.totRegAssigned, sym->key);
 
   for (i = 0; i < sym->nRegs; i++)
 
@@ -619,7 +632,7 @@ spillThis (symbol * sym)
     }
 
   if (sym->usl.spillLoc && !sym->remat)
-    sym->usl.spillLoc->allocreq = 1;
+    sym->usl.spillLoc->allocreq++;
   return;
 }
 
@@ -653,7 +666,7 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
                           sym->usl.spillLoc->name));
       sym->spildir = 1;
       /* mark it as allocation required */
-      sym->usl.spillLoc->allocreq = 1;
+      sym->usl.spillLoc->allocreq++;
       return sym;
     }
 
@@ -698,7 +711,7 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
 
       sym = leastUsedLR (selectS);
       /* mark this as allocation required */
-      sym->usl.spillLoc->allocreq = 1;
+      sym->usl.spillLoc->allocreq++;
       return sym;
     }
 
@@ -707,7 +720,7 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
     {
 
       sym = leastUsedLR (selectS);
-      sym->usl.spillLoc->allocreq = 1;
+      sym->usl.spillLoc->allocreq++;
       return sym;
     }
 
@@ -719,7 +732,7 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
 
       /* return a created spil location */
       sym = createStackSpil (leastUsedLR (selectS));
-      sym->usl.spillLoc->allocreq = 1;
+      sym->usl.spillLoc->allocreq++;
       return sym;
     }
 
@@ -743,12 +756,13 @@ spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
   ssym = selectSpil (ic, ebp, forSym);
 
   /* mark it as spilt */
-  ssym->isspilt = 1;
+  ssym->isspilt = ssym->spillA = 1;
   _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
 
   /* mark it as not register assigned &
      take it away from the set */
   bitVectUnSetBit (_G.regAssigned, ssym->key);
+  bitVectUnSetBit (_G.totRegAssigned, ssym->key);
 
   /* mark the registers as free */
   for (i = 0; i < ssym->nRegs; i++)
@@ -849,6 +863,41 @@ tryAgain:
   goto tryAgain;
 }
 
+/*-----------------------------------------------------------------*/
+/* getRegPtrNoSpil - get it cannot split                           */
+/*-----------------------------------------------------------------*/
+static regs *getRegPtrNoSpil()
+{
+  regs *reg;
+
+  /* try for a ptr type */
+  if ((reg = allocReg (REG_PTR)))
+    return reg;
+
+  /* try for gpr type */
+  if ((reg = allocReg (REG_GPR)))
+    return reg;
+
+  assert(0);
+}
+
+/*-----------------------------------------------------------------*/
+/* getRegGprNoSpil - get it cannot split                           */
+/*-----------------------------------------------------------------*/
+static regs *getRegGprNoSpil()
+{
+
+  regs *reg;
+  if ((reg = allocReg (REG_GPR)))
+    return reg;
+
+  if (!ds390_ptrRegReq)
+    if ((reg = allocReg (REG_PTR)))
+      return reg;
+
+  assert(0);
+}
+
 /*-----------------------------------------------------------------*/
 /* symHasReg - symbol has a given register                         */
 /*-----------------------------------------------------------------*/
@@ -948,6 +997,7 @@ deassignLRs (iCode * ic, eBBlock * ebp)
                  result->regs[i] = getRegGpr (ic, ebp, result);
 
              _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
+             _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, result->key);
 
            }
 
@@ -977,10 +1027,11 @@ reassignLR (operand * op)
   int i;
 
   /* not spilt any more */
-  sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
+  sym->isspilt = sym->spillA = sym->blockSpil = sym->remainSpil = 0;
   bitVectUnSetBit (_G.spiltSet, sym->key);
 
   _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
+  _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key);
 
   _G.blockSpil--;
 
@@ -1030,15 +1081,16 @@ willCauseSpill (int nr, int rt)
 /* ult and operand, if this happens make sure they are in the same */
 /* position as the operand otherwise chaos results                 */
 /*-----------------------------------------------------------------*/
-static void
+static int
 positionRegs (symbol * result, symbol * opsym, int lineno)
 {
   int count = min (result->nRegs, opsym->nRegs);
   int i, j = 0, shared = 0;
+  int change = 0;
 
   /* if the result has been spilt then cannot share */
   if (opsym->isspilt)
-    return;
+    return 0;
 again:
   shared = 0;
   /* first make sure that they actually share */
@@ -1059,8 +1111,10 @@ xchgPositions:
       regs *tmp = result->regs[i];
       result->regs[i] = result->regs[j];
       result->regs[j] = tmp;
+      change ++;
       goto again;
     }
+  return change ;
 }
 
 /*-----------------------------------------------------------------*/
@@ -1094,7 +1148,7 @@ serialRegAssign (eBBlock ** ebbs, int count)
          /* if result is present && is a true symbol */
          if (IC_RESULT (ic) && ic->op != IFX &&
              IS_TRUE_SYMOP (IC_RESULT (ic)))
-           OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
+           OP_SYMBOL (IC_RESULT (ic))->allocreq++;
 
          /* take away registers from live
             ranges that end at this instruction */
@@ -1182,6 +1236,7 @@ serialRegAssign (eBBlock ** ebbs, int count)
                }
              /* else we assign registers to it */
              _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
+             _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key);
 
              for (j = 0; j < sym->nRegs; j++)
                {
@@ -1218,6 +1273,61 @@ serialRegAssign (eBBlock ** ebbs, int count)
     }
 }
 
+/*-----------------------------------------------------------------*/
+/* fillGaps - Try to fill in the Gaps left by Pass1                */
+/*-----------------------------------------------------------------*/
+static void fillGaps()
+{
+    symbol *sym =NULL;
+    int key =0;    
+    
+    return ; /* NOT YET .. MORE TESTING IN PROGRESS */
+    /* look for livernages that was spilt by the allocator */
+    for (sym = hTabFirstItem(liveRanges,&key) ; sym ; 
+        sym = hTabNextItem(liveRanges,&key)) {
+
+       int i;
+
+       if (!sym->spillA || !sym->clashes || sym->remat) continue ;
+       
+       /* find the liveRanges this one clashes with, that are
+          still assigned to registers & mark the registers as used*/
+       for ( i = 0 ; i < sym->clashes->size ; i ++) {
+           int k;
+           symbol *clr;
+
+           if (bitVectBitValue(sym->clashes,i) == 0 ||    /* those that clash with this */
+               bitVectBitValue(_G.totRegAssigned,i) == 0) /* and are still assigned to registers */
+               continue ;
+
+           assert (clr = hTabItemWithKey(liveRanges,i));
+        
+           /* mark these registers as used */
+           for (k = 0 ; k < clr->nRegs ; k++ ) 
+               useReg(clr->regs[k]);
+       }
+
+       if (willCauseSpill(sym->nRegs,sym->regType)) {
+           /* NOPE :( clear all registers & and continue */
+           freeAllRegs();
+           continue ;
+       }
+
+       /* THERE IS HOPE !!!! */
+       for (i=0; i < sym->nRegs ; i++ ) {
+           if (sym->regType == REG_PTR)
+               sym->regs[i] = getRegPtrNoSpil ();
+           else
+               sym->regs[i] = getRegGprNoSpil ();                
+       }
+       printf("FILLED GAP for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN");
+       _G.totRegAssigned = bitVectSetBit(_G.totRegAssigned,sym->key);
+       sym->isspilt = sym->spillA = 0 ;
+       sym->usl.spillLoc->allocreq--;
+       freeAllRegs();
+    }
+}
+
 /*-----------------------------------------------------------------*/
 /* rUmaskForOp :- returns register mask for an operand             */
 /*-----------------------------------------------------------------*/
@@ -1896,7 +2006,7 @@ packRegsDPTRuse (iCode * lic, operand * op, eBBlock * ebp)
     sym_link *type, *etype;
     
     if (!IS_SYMOP(op)) return NULL;
-    if (OP_SYMBOL(op)->remat) return NULL; 
+    if (OP_SYMBOL(op)->remat || OP_SYMBOL(op)->ruonly) return NULL; 
 
     /* first check if any overlapping liverange has already been
        assigned to DPTR */
@@ -1928,28 +2038,44 @@ packRegsDPTRuse (iCode * lic, operand * op, eBBlock * ebp)
 
        /* special case of add with a [remat] */
        if (ic->op == '+' && 
-           OP_SYMBOL(IC_LEFT(ic))->remat ) continue ;
+           OP_SYMBOL(IC_LEFT(ic))->remat &&
+           !isOperandInFarSpace(IC_RIGHT(ic))) continue ;
+
+       /* special case */
+       /* pointerGet */
+       if (POINTER_GET(ic) && isOperandEqual(IC_RESULT(ic),op) &&
+           getSize(operandType(IC_LEFT(ic))) > 1) return NULL ;
+
+       if (POINTER_SET(ic) && isOperandEqual(IC_RIGHT(ic),op) &&
+           getSize(operandType(IC_RESULT(ic))) > 1) return NULL;
 
        /* general case */
        if (IC_RESULT(ic) && IS_SYMOP(IC_RESULT(ic)) && 
            !isOperandEqual(IC_RESULT(ic),op) &&
            (isOperandInFarSpace(IC_RESULT(ic)) || 
+            OP_SYMBOL(IC_RESULT(ic))->ruonly   ||
             OP_SYMBOL(IC_RESULT(ic))->onStack)) return NULL;
 
        if (IC_RIGHT(ic) && IS_SYMOP(IC_RIGHT(ic)) && 
            !isOperandEqual(IC_RIGHT(ic),op) &&
            (OP_SYMBOL(IC_RIGHT(ic))->liveTo > ic->seq || 
-            IS_TRUE_SYMOP(IC_RIGHT(ic))) &&
+            IS_TRUE_SYMOP(IC_RIGHT(ic))               ||
+            OP_SYMBOL(IC_RIGHT(ic))->ruonly) &&
            (isOperandInFarSpace(IC_RIGHT(ic)) || 
             OP_SYMBOL(IC_RIGHT(ic))->onStack)) return NULL;
 
        if (IC_LEFT(ic) && IS_SYMOP(IC_LEFT(ic)) && 
            !isOperandEqual(IC_LEFT(ic),op) &&
            (OP_SYMBOL(IC_LEFT(ic))->liveTo > ic->seq || 
-            IS_TRUE_SYMOP(IC_LEFT(ic)))&&
+            IS_TRUE_SYMOP(IC_LEFT(ic))               ||
+            OP_SYMBOL(IC_LEFT(ic))->ruonly) &&
            (isOperandInFarSpace(IC_LEFT(ic)) || 
             OP_SYMBOL(IC_LEFT(ic))->onStack)) return NULL;
-
+       
+       if (IC_LEFT(ic) && IC_RIGHT(ic) && 
+           IS_ITEMP(IC_LEFT(ic)) && IS_ITEMP(IC_RIGHT(ic)) &&
+           isOperandInFarSpace(IC_LEFT(ic)) && isOperandInFarSpace(IC_RIGHT(ic)))
+           return NULL;
     }
     OP_SYMBOL(op)->ruonly = 1;
     return dic;
@@ -2347,6 +2473,10 @@ packRegisters (eBBlock * ebp)
          packRegsDPTRuse (ic, IC_LEFT (ic), ebp);
       }
 
+      if ((ic->op == CALL && getSize(operandType(IC_RESULT(ic))) <= 4)) {
+         packRegsDPTRuse (ic, IC_RESULT (ic), ebp);      
+      }
+
       /* if pointer set & left has a size more than
          one and right is not in far space */
       if (POINTER_SET (ic) &&
@@ -2462,7 +2592,10 @@ ds390_assignRegisters (eBBlock ** ebbs, int count)
   iCode *ic;
   int i;
 
-  setToNull ((void *) &_G.funcrUsed);
+  setToNull ((void *) &_G.funcrUsed);  
+  setToNull ((void *) &_G.regAssigned);  
+  setToNull ((void *) &_G.totRegAssigned);  
+  setToNull ((void *) &_G.funcrUsed);  
   ds390_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
   ds390_nRegs = 18;
   if (options.model != MODEL_FLAT24) options.stack10bit = 0;
@@ -2481,6 +2614,11 @@ ds390_assignRegisters (eBBlock ** ebbs, int count)
   /* and serially allocate registers */
   serialRegAssign (ebbs, count);
 
+  ds390_nRegs = 8;
+  freeAllRegs ();
+  fillGaps();
+  ds390_nRegs = 18;
+
   /* if stack was extended then tell the user */
   if (_G.stackExtend)
     {