* src/mcs51/gen.c (genFunction): optimize RECEIVE in reentrant
[fw/sdcc] / src / ds390 / ralloc.c
index 96da72af7f7c8dd03343cb98ead589ce4bd947c5..3743e964dcf776f0369cdb7aa3971d007aa844e4 100644 (file)
 /* some routines are non-processor specific & can be reused when   */
 /* targetting other processors. The decision for this will have    */
 /* to be made on a routine by routine basis                        */
-/* routines used to pack registers are most definitely not reusable*/
+/* routines used to pack registers are most definitely not reusable */
 /* since the pack the registers depending strictly on the MCU      */
 /*-----------------------------------------------------------------*/
 
+#define D(x)
+
 /* Global data */
-static struct {
+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 */
+    bitVect *funcrUsed;                /* registers used in a function */
     int stackExtend;
     int dataExtend;
-} _G;
+  }
+_G;
 
 /* Shared with gen.c */
-int ds390_ptrRegReq; /* one byte pointer register required */
+int ds390_ptrRegReq;           /* one byte pointer register required */
 
 /* 8051 registers */
-regs regs390[] = 
+regs regs390[] =
 {
 
-    { REG_GPR  ,R2_IDX , REG_GPR , "r2",  "ar2", "0", 2, 1 },
-    { REG_GPR  ,R3_IDX , REG_GPR , "r3",  "ar3", "0", 3, 1 },
-    { REG_GPR  ,R4_IDX , REG_GPR , "r4",  "ar4", "0", 4, 1 },
-    { REG_GPR  ,R5_IDX , REG_GPR , "r5",  "ar5", "0", 5, 1 },
-    { REG_GPR  ,R6_IDX , REG_GPR , "r6",  "ar6", "0", 6, 1 },
-    { REG_GPR  ,R7_IDX , REG_GPR , "r7",  "ar7", "0", 7, 1 },
-    { REG_PTR  ,R0_IDX , REG_PTR , "r0" , "ar0", "0", 0, 1 },
-    { REG_PTR  ,R1_IDX , REG_PTR , "r1" , "ar1", "0", 1, 1 },    
-    { REG_GPR  ,X8_IDX , REG_GPR , "x8",  "x8" , "xreg", 0, 1 },
-    { REG_GPR  ,X9_IDX , REG_GPR , "x9",  "x9" , "xreg", 1, 1 },
-    { REG_GPR  ,X10_IDX,REG_GPR , "x10", "x10",  "xreg", 2, 1 },
-    { REG_GPR  ,X11_IDX,REG_GPR , "x11", "x11",  "xreg", 3, 1 },
-    { REG_GPR  ,X12_IDX,REG_GPR , "x12", "x12",  "xreg", 4, 1 },
-    { REG_CND  ,CND_IDX,REG_CND , "C"  , "C"  ,  "xreg", 0, 1 },  
+  {REG_GPR, R2_IDX, REG_GPR, "r2", "ar2", "0", 2, 1, 1},
+  {REG_GPR, R3_IDX, REG_GPR, "r3", "ar3", "0", 3, 1, 1},
+  {REG_GPR, R4_IDX, REG_GPR, "r4", "ar4", "0", 4, 1, 1},
+  {REG_GPR, R5_IDX, REG_GPR, "r5", "ar5", "0", 5, 1, 1},
+  {REG_GPR, R6_IDX, REG_GPR, "r6", "ar6", "0", 6, 1, 1},
+  {REG_GPR, R7_IDX, REG_GPR, "r7", "ar7", "0", 7, 1, 1},
+  {REG_PTR, R0_IDX, REG_PTR, "r0", "ar0", "0", 0, 1, 1},
+  {REG_PTR, R1_IDX, REG_PTR, "r1", "ar1", "0", 1, 1, 1},
+  {REG_GPR, DPL_IDX, REG_GPR, "dpl", "dpl", "dpl", 0, 0, 0},
+  {REG_GPR, DPH_IDX, REG_GPR, "dph", "dph", "dph", 0, 0, 0},
+  {REG_GPR, DPX_IDX, REG_GPR, "dpx", "dpx", "dpx", 0, 0, 0},
+  {REG_GPR, B_IDX, REG_GPR, "b", "b", "b", 0, 0, 0},
+  {REG_GPR, X8_IDX, REG_GPR, "x8", "x8", "xreg", 0, 0, 0},
+  {REG_GPR, X9_IDX, REG_GPR, "x9", "x9", "xreg", 1, 0, 0},
+  {REG_GPR, X10_IDX, REG_GPR, "x10", "x10", "xreg", 2, 0, 0},
+  {REG_GPR, X11_IDX, REG_GPR, "x11", "x11", "xreg", 3, 0, 0},
+  {REG_GPR, X12_IDX, REG_GPR, "x12", "x12", "xreg", 4, 0, 0},
+  {REG_CND, CND_IDX, REG_GPR, "C", "psw", "xreg", 0, 0, 0},
+  {0, DPL1_IDX, 0, "dpl1", "dpl1", "dpl1", 0, 0, 0},
+  {0, DPH1_IDX, 0, "dph1", "dph1", "dph1", 0, 0, 0},
+  {0, DPX1_IDX, 0, "dpx1", "dpx1", "dpx1", 0, 0, 0},
+  {0, DPS_IDX, 0, "dps", "dps", "dps", 0, 0, 0},
+  {0, A_IDX, 0, "a", "acc", "acc", 0, 0, 0},
+  {0, AP_IDX, 0, "ap", "ap", "ap", 0, 0, 0},
 };
 int ds390_nRegs = 13;
 static void spillThis (symbol *);
+static void freeAllRegs ();
+static iCode * packRegsDPTRuse (operand *);
+static int packRegsDPTRnuse (operand *,int);
 
 /*-----------------------------------------------------------------*/
 /* allocReg - allocates register of given type                     */
 /*-----------------------------------------------------------------*/
-static regs *allocReg (short type)
+static regs *
+allocReg (short type)
 {
-    int i;
+  int i;
+
+  for (i = 0; i < ds390_nRegs; i++)
+    {
 
-    for ( i = 0 ; i < ds390_nRegs ; i++ ) {
-
-       /* if type is given as 0 then any
-          free register will do */
-       if (!type &&
-           regs390[i].isFree ) {
-           regs390[i].isFree = 0;
-           if (currFunc)
-               currFunc->regsUsed = 
-                   bitVectSetBit(currFunc->regsUsed,i);
-           return &regs390[i];
+      /* if type is given as 0 then any
+         free register will do */
+      if (!type &&
+         regs390[i].isFree)
+       {
+         regs390[i].isFree = 0;
+         if (currFunc)
+           currFunc->regsUsed =
+             bitVectSetBit (currFunc->regsUsed, i);
+         return &regs390[i];
        }
-       /* other wise look for specific type
-          of register */
-       if (regs390[i].isFree && 
-           regs390[i].type == type) {
-           regs390[i].isFree = 0;
-           if (currFunc)
-               currFunc->regsUsed = 
-                   bitVectSetBit(currFunc->regsUsed,i);
-           return &regs390[i];
+      /* other wise look for specific type
+         of register */
+      if (regs390[i].isFree &&
+         regs390[i].type == type)
+       {
+         regs390[i].isFree = 0;
+         if (currFunc)
+           currFunc->regsUsed =
+             bitVectSetBit (currFunc->regsUsed, i);
+         return &regs390[i];
        }
     }
-    return NULL;
+  return NULL;
 }
 
 /*-----------------------------------------------------------------*/
 /* ds390_regWithIdx - returns pointer to register wit index number       */
 /*-----------------------------------------------------------------*/
-regs *ds390_regWithIdx (int idx)
+regs *
+ds390_regWithIdx (int idx)
 {
-    int i ;
-    
-    for (i=0;i < ds390_nRegs;i++)
-       if (regs390[i].rIdx == idx)
-           return &regs390[i];
+  int i;
 
-    werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
-          "regWithIdx not found");
-    exit(1);
+  for (i = 0; i < sizeof(regs390)/sizeof(regs); i++)
+    if (regs390[i].rIdx == idx)
+      return &regs390[i];
+
+  werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+         "regWithIdx not found");
+  exit (1);
 }
 
 /*-----------------------------------------------------------------*/
 /* freeReg - frees a register                                      */
 /*-----------------------------------------------------------------*/
-static void freeReg (regs *reg)
+static void
+freeReg (regs * reg)
+{
+  reg->isFree = 1;
+}
+
+/*-----------------------------------------------------------------*/
+/* useReg - marks a register  as used                              */
+/*-----------------------------------------------------------------*/
+static void
+useReg (regs * reg)
 {
-    reg->isFree = 1;
+  reg->isFree = 0;
 }
 
 
 /*-----------------------------------------------------------------*/
 /* nFreeRegs - returns number of free registers                    */
 /*-----------------------------------------------------------------*/
-static int nFreeRegs (int type)
+static int
+nFreeRegs (int type)
 {
-    int i;
-    int nfr=0;
-    
-    for (i = 0 ; i < ds390_nRegs; i++ )
-       if (regs390[i].isFree && regs390[i].type == type)
-           nfr++;
-    return nfr;
+  int i;
+  int nfr = 0;
+
+  for (i = 0; i < ds390_nRegs; i++)
+    if (regs390[i].isFree && regs390[i].type == type)
+      nfr++;
+  return nfr;
 }
 
 /*-----------------------------------------------------------------*/
 /* nfreeRegsType - free registers with type                         */
 /*-----------------------------------------------------------------*/
-static int nfreeRegsType (int type)
+static int
+nfreeRegsType (int type)
 {
-    int nfr ;
-    if (type == REG_PTR) {
-       if ((nfr = nFreeRegs(type)) == 0)
-           return nFreeRegs(REG_GPR);
-    } 
-    
-    return nFreeRegs(type);
+  int nfr;
+  if (type == REG_PTR)
+    {
+      if ((nfr = nFreeRegs (type)) == 0)
+       return nFreeRegs (REG_GPR);
+    }
+
+  return nFreeRegs (type);
 }
 
 
+
 /*-----------------------------------------------------------------*/
-/* allDefsOutOfRange - all definitions are out of a range          */
+/* isOperandInReg - returns true if operand is currently in regs   */
 /*-----------------------------------------------------------------*/
-static bool allDefsOutOfRange (bitVect *defs,int fseq, int toseq) 
+static int isOperandInReg(operand *op)
 {
-    int i ;
-
-    if (!defs)
-       return TRUE ;
-
-    for ( i = 0 ;i < defs->size ; i++ ) {
-       iCode *ic;
-
-       if (bitVectBitValue(defs,i)             &&
-           (ic = hTabItemWithKey(iCodehTab,i)) &&
-           ( ic->seq >= fseq  && ic->seq <= toseq))
-           
-           return FALSE;
-       
-    }
-    
-    return TRUE;
+    if (!IS_SYMOP(op)) return 0;
+    if (OP_SYMBOL(op)->ruonly) return 1;
+    if (OP_SYMBOL(op)->accuse) return 1;
+    if (OP_SYMBOL(op)->dptr) return 1;
+    return bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(op)->key);
 }
-  
+
 /*-----------------------------------------------------------------*/
 /* computeSpillable - given a point find the spillable live ranges */
 /*-----------------------------------------------------------------*/
-static bitVect *computeSpillable (iCode *ic)
+static bitVect *
+computeSpillable (iCode * ic)
 {
-    bitVect *spillable ;
-
-    /* spillable live ranges are those that are live at this 
-       point . the following categories need to be subtracted
-       from this set. 
-       a) - those that are already spilt
-       b) - if being used by this one
-       c) - defined by this one */
-    
-    spillable = bitVectCopy(ic->rlive);
-    spillable = 
-       bitVectCplAnd(spillable,_G.spiltSet); /* those already spilt */
-    spillable = 
-       bitVectCplAnd(spillable,ic->uses); /* used in this one */    
-    bitVectUnSetBit(spillable,ic->defKey);
-    spillable = bitVectIntersect(spillable,_G.regAssigned);
-    return spillable;
-    
+  bitVect *spillable;
+
+  /* spillable live ranges are those that are live at this 
+     point . the following categories need to be subtracted
+     from this set. 
+     a) - those that are already spilt
+     b) - if being used by this one
+     c) - defined by this one */
+
+  spillable = bitVectCopy (ic->rlive);
+  spillable =
+    bitVectCplAnd (spillable, _G.spiltSet);    /* those already spilt */
+  spillable =
+    bitVectCplAnd (spillable, ic->uses);       /* used in this one */
+  bitVectUnSetBit (spillable, ic->defKey);
+  spillable = bitVectIntersect (spillable, _G.regAssigned);
+  return spillable;
+
 }
 
 /*-----------------------------------------------------------------*/
 /* noSpilLoc - return true if a variable has no spil location      */
 /*-----------------------------------------------------------------*/
-static int noSpilLoc (symbol *sym, eBBlock *ebp,iCode *ic)
+static int
+noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
 {
-    return (sym->usl.spillLoc ? 0 : 1);
+  return (sym->usl.spillLoc ? 0 : 1);
 }
 
 /*-----------------------------------------------------------------*/
 /* hasSpilLoc - will return 1 if the symbol has spil location      */
 /*-----------------------------------------------------------------*/
-static int hasSpilLoc (symbol *sym, eBBlock *ebp, iCode *ic)
+static int
+hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
 {
-    return (sym->usl.spillLoc ? 1 : 0);
+  return (sym->usl.spillLoc ? 1 : 0);
 }
 
 /*-----------------------------------------------------------------*/
 /* directSpilLoc - will return 1 if the splilocation is in direct  */
 /*-----------------------------------------------------------------*/
-static int directSpilLoc (symbol *sym, eBBlock *ebp, iCode *ic)
+static int
+directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
 {
-    if ( sym->usl.spillLoc &&
-        (IN_DIRSPACE(SPEC_OCLS(sym->usl.spillLoc->etype))))
-       return 1;
-    else
-       return 0;
+  if (sym->usl.spillLoc &&
+      (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
+    return 1;
+  else
+    return 0;
 }
 
 /*-----------------------------------------------------------------*/
-/* hasSpilLocnoUptr - will return 1 if the symbol has spil location*/
+/* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
 /*                    but is not used as a pointer                 */
 /*-----------------------------------------------------------------*/
-static int hasSpilLocnoUptr (symbol *sym, eBBlock *ebp, iCode *ic)
+static int
+hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
 {
-    return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
+  return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
 }
 
 /*-----------------------------------------------------------------*/
 /* rematable - will return 1 if the remat flag is set              */
 /*-----------------------------------------------------------------*/
-static int rematable (symbol *sym, eBBlock *ebp, iCode *ic)
+static int
+rematable (symbol * sym, eBBlock * ebp, iCode * ic)
 {
-    return sym->remat;
-}
-
-/*-----------------------------------------------------------------*/
-/* notUsedInBlock - not used in this block                         */
-/*-----------------------------------------------------------------*/
-static int notUsedInBlock (symbol *sym, eBBlock *ebp, iCode *ic)
-{   
-    return (!bitVectBitsInCommon(sym->defs,ebp->usesDefs) &&
-           allDefsOutOfRange (sym->defs,ebp->fSeq,ebp->lSeq));
-/*     return (!bitVectBitsInCommon(sym->defs,ebp->usesDefs)); */
+  return sym->remat;
 }
 
 /*-----------------------------------------------------------------*/
 /* notUsedInRemaining - not used or defined in remain of the block */
 /*-----------------------------------------------------------------*/
-static int notUsedInRemaining (symbol *sym, eBBlock *ebp, iCode *ic)
+static int
+notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
 {
-    return ((usedInRemaining (operandFromSymbol(sym),ic) ? 0 : 1) &&
-           allDefsOutOfRange (sym->defs,ebp->fSeq,ebp->lSeq));
+  return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
+         allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
 }
 
 /*-----------------------------------------------------------------*/
 /* allLRs - return true for all                                    */
 /*-----------------------------------------------------------------*/
-static int allLRs (symbol *sym, eBBlock *ebp, iCode *ic)
+static int
+allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
 {
-    return 1;
+  return 1;
 }
 
 /*-----------------------------------------------------------------*/
 /* liveRangesWith - applies function to a given set of live range  */
 /*-----------------------------------------------------------------*/
-static set *liveRangesWith (bitVect *lrs, int (func)(symbol *,eBBlock *, iCode *),
-                    eBBlock *ebp, iCode *ic)
+static set *
+liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
+               eBBlock * ebp, iCode * ic)
 {
-    set *rset = NULL;
-    int i;
+  set *rset = NULL;
+  int i;
 
-    if (!lrs || !lrs->size)
-       return NULL;
-
-    for ( i = 1 ; i < lrs->size ; i++ ) {
-       symbol *sym;
-       if (!bitVectBitValue(lrs,i))
-           continue ;
+  if (!lrs || !lrs->size)
+    return NULL;
 
-       /* if we don't find it in the live range 
-          hash table we are in serious trouble */
-       if (!(sym = hTabItemWithKey(liveRanges,i))) {
-           werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
-                  "liveRangesWith could not find liveRange");
-           exit(1);
+  for (i = 1; i < lrs->size; i++)
+    {
+      symbol *sym;
+      if (!bitVectBitValue (lrs, i))
+       continue;
+
+      /* if we don't find it in the live range 
+         hash table we are in serious trouble */
+      if (!(sym = hTabItemWithKey (liveRanges, i)))
+       {
+         werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+                 "liveRangesWith could not find liveRange");
+         exit (1);
        }
-       
-       if (func(sym,ebp,ic) && bitVectBitValue(_G.regAssigned,sym->key))
-           addSetHead(&rset,sym);
+
+      if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
+       addSetHead (&rset, sym);
     }
 
-    return rset;
+  return rset;
 }
 
 
 /*-----------------------------------------------------------------*/
 /* leastUsedLR - given a set determines which is the least used    */
 /*-----------------------------------------------------------------*/
-static symbol *leastUsedLR (set *sset)
+static symbol *
+leastUsedLR (set * sset)
 {
-    symbol *sym = NULL, *lsym = NULL ;
-    
-    sym = lsym = setFirstItem(sset);
+  symbol *sym = NULL, *lsym = NULL;
 
-    if (!lsym)
-       return NULL;
+  sym = lsym = setFirstItem (sset);
 
-    for (; lsym; lsym = setNextItem(sset)) {
-       
-       /* if usage is the same then prefer
-          the spill the smaller of the two */
-       if ( lsym->used == sym->used )
-           if (getSize(lsym->type) < getSize(sym->type))
-               sym = lsym;
-
-       /* if less usage */
-       if (lsym->used < sym->used )
-           sym = lsym;
-       
-   }
+  if (!lsym)
+    return NULL;
 
-    setToNull((void **)&sset);
-    sym->blockSpil = 0;
-    return sym;
+  for (; lsym; lsym = setNextItem (sset))
+    {
+
+      /* if usage is the same then prefer
+         the spill the smaller of the two */
+      if (lsym->used == sym->used)
+       if (getSize (lsym->type) < getSize (sym->type))
+         sym = lsym;
+
+      /* if less usage */
+      if (lsym->used < sym->used)
+       sym = lsym;
+
+    }
+
+  setToNull ((void *) &sset);
+  sym->blockSpil = 0;
+  return sym;
 }
 
 /*-----------------------------------------------------------------*/
 /* noOverLap - will iterate through the list looking for over lap  */
 /*-----------------------------------------------------------------*/
-static int noOverLap (set *itmpStack, symbol *fsym)
+static int
+noOverLap (set * itmpStack, symbol * fsym)
 {
-    symbol *sym;
-   
+  symbol *sym;
 
-    for (sym = setFirstItem(itmpStack); sym;
-        sym = setNextItem(itmpStack)) {
-       if (sym->liveTo > fsym->liveFrom )
-           return 0;
-           
+  for (sym = setFirstItem (itmpStack); sym;
+       sym = setNextItem (itmpStack))
+    {
+       if (bitVectBitValue(sym->clashes,fsym->key)) return 0;
     }
-
-    return 1;
+  return 1;
 }
 
 /*-----------------------------------------------------------------*/
 /* isFree - will return 1 if the a free spil location is found     */
 /*-----------------------------------------------------------------*/
-static DEFSETFUNC(isFree)
+static
+DEFSETFUNC (isFree)
 {
-    symbol *sym = item;
-    V_ARG(symbol **,sloc);
-    V_ARG(symbol *,fsym);
+  symbol *sym = item;
+  V_ARG (symbol **, sloc);
+  V_ARG (symbol *, fsym);
 
-    /* if already found */
-    if (*sloc)
-       return 0;
+  /* if already found */
+  if (*sloc)
+    return 0;
 
-    /* if it is free && and the itmp assigned to
-       this does not have any overlapping live ranges
-       with the one currently being assigned and
-       the size can be accomodated  */
-    if (sym->isFree                        && 
-       noOverLap(sym->usl.itmpStack,fsym) &&
-       getSize(sym->type) >= getSize(fsym->type)) {
-       *sloc = sym;
-       return 1;
+  /* if it is free && and the itmp assigned to
+     this does not have any overlapping live ranges
+     with the one currently being assigned and
+     the size can be accomodated  */
+  if (sym->isFree &&
+      noOverLap (sym->usl.itmpStack, fsym) &&
+      getSize (sym->type) >= getSize (fsym->type))
+    {
+      *sloc = sym;
+      return 1;
     }
 
-    return 0;
+  return 0;
 }
 
 /*-----------------------------------------------------------------*/
 /* spillLRWithPtrReg :- will spil those live ranges which use PTR  */
 /*-----------------------------------------------------------------*/
-static void spillLRWithPtrReg (symbol *forSym)
+static void
+spillLRWithPtrReg (symbol * forSym)
 {
-    symbol *lrsym;
-    regs *r0,*r1;
-    int k;
-
-    if (!_G.regAssigned ||
-       bitVectIsZero(_G.regAssigned))
-       return;
-
-    r0 = ds390_regWithIdx(R0_IDX);
-    r1 = ds390_regWithIdx(R1_IDX);
+  symbol *lrsym;
+  regs *r0, *r1;
+  int k;
 
-    /* for all live ranges */
-    for (lrsym = hTabFirstItem(liveRanges,&k) ; lrsym ; 
-        lrsym = hTabNextItem(liveRanges,&k) ) {
-       int j;       
-
-       /* if no registers assigned to it or
-          spilt */
-       /* if it does not overlap with this then 
-          not need to spill it */
+  if (!_G.regAssigned ||
+      bitVectIsZero (_G.regAssigned))
+    return;
 
-       if (lrsym->isspilt || !lrsym->nRegs ||
-           (lrsym->liveTo < forSym->liveFrom))
-           continue ;
+  r0 = ds390_regWithIdx (R0_IDX);
+  r1 = ds390_regWithIdx (R1_IDX);
 
-       /* go thru the registers : if it is either
-          r0 or r1 then spil it */
-       for (j = 0 ; j < lrsym->nRegs ; j++ ) 
-           if (lrsym->regs[j] == r0 ||
-               lrsym->regs[j] == r1 ) {
-               spillThis (lrsym);
-               break;
-           }
+  /* for all live ranges */
+  for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
+       lrsym = hTabNextItem (liveRanges, &k))
+    {
+      int j;
+
+      /* if no registers assigned to it or
+         spilt */
+      /* if it does not overlap with this then 
+         not need to spill it */
+
+      if (lrsym->isspilt || !lrsym->nRegs ||
+         (lrsym->liveTo < forSym->liveFrom))
+       continue;
+
+      /* go thru the registers : if it is either
+         r0 or r1 then spil it */
+      for (j = 0; j < lrsym->nRegs; j++)
+       if (lrsym->regs[j] == r0 ||
+           lrsym->regs[j] == r1)
+         {
+           spillThis (lrsym);
+           break;
+         }
     }
 
 }
@@ -435,458 +466,559 @@ static void spillLRWithPtrReg (symbol *forSym)
 /*-----------------------------------------------------------------*/
 /* createStackSpil - create a location on the stack to spil        */
 /*-----------------------------------------------------------------*/
-static symbol *createStackSpil (symbol *sym)
+static symbol *
+createStackSpil (symbol * sym)
 {
-    symbol *sloc= NULL;
-    int useXstack, model, noOverlay;
-
-    char slocBuffer[30];
-
-    /* first go try and find a free one that is already 
-       existing on the stack */
-    if (applyToSet(_G.stackSpil,isFree,&sloc, sym)) {
-       /* found a free one : just update & return */
-       sym->usl.spillLoc = sloc;
-       sym->stackSpil= 1;
-       sloc->isFree = 0;
-       addSetHead(&sloc->usl.itmpStack,sym);
-       return sym;
-    }
+  symbol *sloc = NULL;
+  int useXstack, model, noOverlay;
 
-    /* could not then have to create one , this is the hard part
-       we need to allocate this on the stack : this is really a
-       hack!! but cannot think of anything better at this time */
-       
-    if (sprintf(slocBuffer,"sloc%d",_G.slocNum++) >= sizeof(slocBuffer))
+  char slocBuffer[30];
+
+  /* first go try and find a free one that is already 
+     existing on the stack */
+  if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
     {
-       fprintf(stderr, "***Internal error: slocBuffer overflowed: %s:%d\n",
-               __FILE__, __LINE__);
-       exit(1);        
+      /* found a free one : just update & return */
+      sym->usl.spillLoc = sloc;      
+      sym->stackSpil = 1;
+      sloc->isFree = 0;
+      addSetHead (&sloc->usl.itmpStack, sym);
+      return sym;
     }
 
-    sloc = newiTemp(slocBuffer);
-
-    /* set the type to the spilling symbol */
-    sloc->type = copyLinkChain(sym->type);
-    sloc->etype = getSpec(sloc->type);
-    SPEC_SCLS(sloc->etype) = options.model ? S_XDATA : S_DATA;
-    SPEC_EXTR(sloc->etype) = 0;
-
-    /* we don't allow it to be allocated`
-       onto the external stack since : so we
-       temporarily turn it off ; we also
-       turn off memory model to prevent
-       the spil from going to the external storage
-       and turn off overlaying 
-    */
-    
-    useXstack = options.useXstack;
-    model = options.model;
-    noOverlay = options.noOverlay;
-    options.noOverlay = 1;
-    
-    /* options.model = options.useXstack = 0; */
+  /* could not then have to create one , this is the hard part
+     we need to allocate this on the stack : this is really a
+     hack!! but cannot think of anything better at this time */
 
-    allocLocal(sloc);
+  if (SNPRINTF (slocBuffer, sizeof(slocBuffer), 
+               "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
+    {
+      fprintf (stderr, "***Internal error: slocBuffer overflowed: %s:%d\n",
+              __FILE__, __LINE__);
+      exit (1);
+    }
 
-    options.useXstack = useXstack;
-    options.model     = model;
-    options.noOverlay = noOverlay;
-    sloc->isref = 1; /* to prevent compiler warning */
-    
-    /* if it is on the stack then update the stack */
-    if (IN_STACK(sloc->etype)) {
-       currFunc->stack += getSize(sloc->type);
-       _G.stackExtend += getSize(sloc->type);
-    } else
-       _G.dataExtend += getSize(sloc->type);
-
-    /* add it to the _G.stackSpil set */
-    addSetHead(&_G.stackSpil,sloc);
-    sym->usl.spillLoc = sloc;
-    sym->stackSpil = 1;
-    
-    /* add it to the set of itempStack set 
-       of the spill location */
-    addSetHead(&sloc->usl.itmpStack,sym);
-    return sym;
+  sloc = newiTemp (slocBuffer);
+
+  /* set the type to the spilling symbol */
+  sloc->type = copyLinkChain (sym->type);
+  sloc->etype = getSpec (sloc->type);
+  if (options.model == MODEL_SMALL) {
+    SPEC_SCLS (sloc->etype) = S_DATA;
+  } else {
+    SPEC_SCLS (sloc->etype) = S_XDATA;
+  }
+  SPEC_EXTR (sloc->etype) = 0;
+  SPEC_STAT (sloc->etype) = 0;
+  SPEC_VOLATILE(sloc->etype) = 0;
+  SPEC_ABSA(sloc->etype) = 0;
+
+  /* we don't allow it to be allocated`
+     onto the external stack since : so we
+     temporarily turn it off ; we also
+     turn off memory model to prevent
+     the spil from going to the external storage
+     and turn off overlaying 
+   */
+
+  useXstack = options.useXstack;
+  model = options.model;
+  noOverlay = options.noOverlay;
+  options.noOverlay = 1;
+
+  /* options.model = options.useXstack = 0; */
+
+  allocLocal (sloc);
+
+  options.useXstack = useXstack;
+  options.model = model;
+  options.noOverlay = noOverlay;
+  sloc->isref = 1;             /* to prevent compiler warning */
+
+  /* if it is on the stack then update the stack */
+  if (IN_STACK (sloc->etype))
+    {
+      currFunc->stack += getSize (sloc->type);
+      _G.stackExtend += getSize (sloc->type);
+    }
+  else
+    _G.dataExtend += getSize (sloc->type);
+
+  /* add it to the _G.stackSpil set */
+  addSetHead (&_G.stackSpil, sloc);
+  sym->usl.spillLoc = sloc;
+  sym->stackSpil = 1;
+
+  /* add it to the set of itempStack set 
+     of the spill location */
+  addSetHead (&sloc->usl.itmpStack, sym);
+  return sym;
 }
 
 /*-----------------------------------------------------------------*/
 /* isSpiltOnStack - returns true if the spil location is on stack  */
 /*-----------------------------------------------------------------*/
-static bool isSpiltOnStack (symbol *sym)
+static bool
+isSpiltOnStack (symbol * sym)
 {
-    link *etype;
+  sym_link *etype;
 
-    if (!sym)
-       return FALSE ;
-    
-    if (!sym->isspilt)
-       return FALSE ;
+  if (!sym)
+    return FALSE;
+
+  if (!sym->isspilt)
+    return FALSE;
 
 /*     if (sym->_G.stackSpil) */
-/*     return TRUE; */
-    
-    if (!sym->usl.spillLoc)
-       return FALSE;
+/*      return TRUE; */
+
+  if (!sym->usl.spillLoc)
+    return FALSE;
 
-    etype = getSpec(sym->usl.spillLoc->type);
-    if (IN_STACK(etype))
-       return TRUE;
+  etype = getSpec (sym->usl.spillLoc->type);
+  if (IN_STACK (etype))
+    return TRUE;
 
-    return FALSE ;
+  return FALSE;
 }
 
 /*-----------------------------------------------------------------*/
 /* spillThis - spils a specific operand                            */
 /*-----------------------------------------------------------------*/
-static void spillThis (symbol *sym)
+static void
+spillThis (symbol * sym)
 {
-    int i;
-    /* if this is rematerializable or has a spillLocation
-       we are okay, else we need to create a spillLocation
-       for it */
-    if (!(sym->remat || sym->usl.spillLoc)) 
-       createStackSpil (sym);
-    
+  int i;
+  /* if this is rematerializable or has a spillLocation
+     we are okay, else we need to create a spillLocation
+     for it */
+  if (!(sym->remat || sym->usl.spillLoc))
+    createStackSpil (sym);
 
-    /* mark it has spilt & put it in the spilt set */
-    sym->isspilt = 1;
-    _G.spiltSet = bitVectSetBit(_G.spiltSet,sym->key);
-       
-    bitVectUnSetBit(_G.regAssigned,sym->key);
 
-    for (i = 0 ; i < sym->nRegs ; i++)
+  /* mark it has spilt & put it in the spilt set */
+  sym->isspilt = sym->spillA = 1;
+  _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
 
-       if (sym->regs[i]) {
-           freeReg(sym->regs[i]);
-           sym->regs[i] = NULL;
-       }
-    
-    /* if spilt on stack then free up r0 & r1 
-       if they could have been assigned to some
-       LIVE ranges */
-    if (!ds390_ptrRegReq && isSpiltOnStack(sym)) {
-       ds390_ptrRegReq++ ;
-       spillLRWithPtrReg(sym);
+  bitVectUnSetBit (_G.regAssigned, sym->key);
+  bitVectUnSetBit (_G.totRegAssigned, sym->key);
+
+  for (i = 0; i < sym->nRegs; i++)
+
+    if (sym->regs[i])
+      {
+       freeReg (sym->regs[i]);
+       sym->regs[i] = NULL;
+      }
+
+  /* if spilt on stack then free up r0 & r1
+     if they could have been assigned to some
+     LIVE ranges */
+  if (!ds390_ptrRegReq && isSpiltOnStack (sym) && !options.stack10bit)
+    {
+      ds390_ptrRegReq ++;
+      spillLRWithPtrReg (sym);
     }
 
-    if (sym->usl.spillLoc && !sym->remat)
-       sym->usl.spillLoc->allocreq = 1;
-    return;
+  if (sym->usl.spillLoc && !sym->remat)
+    sym->usl.spillLoc->allocreq++;
+  return;
 }
 
 /*-----------------------------------------------------------------*/
 /* selectSpil - select a iTemp to spil : rather a simple procedure */
 /*-----------------------------------------------------------------*/
-static symbol *selectSpil (iCode *ic, eBBlock *ebp, symbol *forSym)
+static symbol *
+selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
 {
-    bitVect *lrcs= NULL ; 
-    set *selectS ;
-    symbol *sym;
+  bitVect *lrcs = NULL;
+  set *selectS;
+  symbol *sym;
 
-    /* get the spillable live ranges */
-    lrcs = computeSpillable (ic);
+  /* get the spillable live ranges */
+  lrcs = computeSpillable (ic);
 
-    /* get all live ranges that are rematerizable */
-    if ((selectS = liveRangesWith(lrcs,rematable,ebp,ic))) {
+  /* get all live ranges that are rematerizable */
+  if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
+    {
 
-       /* return the least used of these */
-       return leastUsedLR(selectS);
+      /* return the least used of these */
+      return leastUsedLR (selectS);
     }
 
-    /* get live ranges with spillLocations in direct space */
-    if ((selectS = liveRangesWith(lrcs,directSpilLoc,ebp,ic))) {
-       sym = leastUsedLR(selectS);
-       strcpy(sym->rname,(sym->usl.spillLoc->rname[0] ? 
-                          sym->usl.spillLoc->rname : 
-                          sym->usl.spillLoc->name)); 
-       sym->spildir = 1;
-       /* mark it as allocation required */
-       sym->usl.spillLoc->allocreq = 1;
-       return sym;
+  /* get live ranges with spillLocations in direct space */
+  if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
+    {
+      sym = leastUsedLR (selectS);
+      strncpyz (sym->rname,
+               sym->usl.spillLoc->rname[0] ?
+                  sym->usl.spillLoc->rname : sym->usl.spillLoc->name,
+               sizeof(sym->rname));
+      sym->spildir = 1;
+      /* mark it as allocation required */
+      sym->usl.spillLoc->allocreq++;
+      return sym;
     }
 
-    /* if the symbol is local to the block then */
-    if (forSym->liveTo < ebp->lSeq) {       
-
-       /* check if there are any live ranges allocated
-          to registers that are not used in this block */
-       if (!_G.blockSpil && (selectS = liveRangesWith(lrcs,notUsedInBlock,ebp,ic))) {
-           sym = leastUsedLR(selectS);
-           /* if this is not rematerializable */
-           if (!sym->remat) {
-               _G.blockSpil++;
-               sym->blockSpil = 1;
+  /* if the symbol is local to the block then */
+  if (forSym->liveTo < ebp->lSeq)
+    {
+
+      /* check if there are any live ranges allocated
+         to registers that are not used in this block */
+      if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
+       {
+         sym = leastUsedLR (selectS);
+         /* if this is not rematerializable */
+         if (!sym->remat)
+           {
+             _G.blockSpil++;
+             sym->blockSpil = 1;
            }
-           return sym;
-       } 
-
-       /* check if there are any live ranges that not
-          used in the remainder of the block */
-       if (!_G.blockSpil && (selectS = liveRangesWith(lrcs,notUsedInRemaining,ebp,ic))) {
-           sym = leastUsedLR (selectS);
-           if (sym != forSym) {
-               if (!sym->remat) {
-                   sym->remainSpil = 1;
-                   _G.blockSpil++;
+         return sym;
+       }
+
+      /* check if there are any live ranges that not
+         used in the remainder of the block */
+      if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
+       {
+         sym = leastUsedLR (selectS);
+         if (sym != forSym)
+           {
+             if (!sym->remat)
+               {
+                 sym->remainSpil = 1;
+                 _G.blockSpil++;
                }
-               return sym;
+             return sym;
            }
        }
-    }   
-
-    /* find live ranges with spillocation && not used as pointers */
-    if ((selectS = liveRangesWith(lrcs,hasSpilLocnoUptr,ebp,ic))) {
-       
-       sym =  leastUsedLR(selectS);
-       /* mark this as allocation required */
-       sym->usl.spillLoc->allocreq = 1;
-       return sym;
     }
 
-    /* find live ranges with spillocation */
-    if ((selectS = liveRangesWith(lrcs,hasSpilLoc,ebp,ic))) {
-       
-       sym = leastUsedLR(selectS);
-       sym->usl.spillLoc->allocreq = 1;
-       return sym;
+  /* find live ranges with spillocation && not used as pointers */
+  if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
+    {
+
+      sym = leastUsedLR (selectS);
+      /* mark this as allocation required */
+      sym->usl.spillLoc->allocreq++;
+      return sym;
     }
 
-    /* couldn't find then we need to create a spil
-       location on the stack , for which one? the least
-       used ofcourse */
-    if ((selectS = liveRangesWith(lrcs,noSpilLoc,ebp,ic))) {
-       
-       /* return a created spil location */
-       sym = createStackSpil(leastUsedLR(selectS));
-       sym->usl.spillLoc->allocreq = 1;
-       return sym;
+  /* find live ranges with spillocation */
+  if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
+    {
+
+      sym = leastUsedLR (selectS);
+      sym->usl.spillLoc->allocreq++;
+      return sym;
     }
-    
-    /* this is an extreme situation we will spill
-       this one : happens very rarely but it does happen */
-    spillThis ( forSym );
-    return forSym ;
-   
+
+  /* couldn't find then we need to create a spil
+     location on the stack , for which one? the least
+     used ofcourse */
+  if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
+    {
+
+      /* return a created spil location */
+      sym = createStackSpil (leastUsedLR (selectS));
+      sym->usl.spillLoc->allocreq++;
+      return sym;
+    }
+
+  /* this is an extreme situation we will spill
+     this one : happens very rarely but it does happen */
+  spillThis (forSym);
+  return forSym;
+
 }
 
 /*-----------------------------------------------------------------*/
 /* spilSomething - spil some variable & mark registers as free     */
 /*-----------------------------------------------------------------*/
-static bool spilSomething (iCode *ic, eBBlock *ebp, symbol *forSym)
+static bool
+spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
 {
-    symbol *ssym;
-    int i ;
+  symbol *ssym;
+  int i;
 
-    /* get something we can spil */
-    ssym = selectSpil(ic,ebp,forSym);
-    
-    /* mark it as spilt */
-    ssym->isspilt = 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);
-    /* mark the registers as free */    
-    for (i = 0 ; i < ssym->nRegs ;i++ )
-       if (ssym->regs[i])
-           freeReg(ssym->regs[i]);
-     
-    /* if spilt on stack then free up r0 & r1 
-       if they could have been assigned to as gprs */
-    if (!ds390_ptrRegReq && isSpiltOnStack(ssym) ) {
-       ds390_ptrRegReq++ ;
-       spillLRWithPtrReg(ssym);
+  /* get something we can spil */
+  ssym = selectSpil (ic, ebp, forSym);
+
+  /* mark it as spilt */
+  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++)
+    if (ssym->regs[i])
+      freeReg (ssym->regs[i]);
+
+  /* if spilt on stack then free up r0 & r1 
+     if they could have been assigned to as gprs */
+  if (!ds390_ptrRegReq && isSpiltOnStack (ssym) && !options.stack10bit)
+    {
+           ds390_ptrRegReq++;
+      spillLRWithPtrReg (ssym);
     }
 
-    /* if this was a block level spil then insert push & pop 
-       at the start & end of block respectively */
-    if (ssym->blockSpil) {
-       iCode *nic = newiCode(IPUSH,operandFromSymbol(ssym),NULL);
-       /* add push to the start of the block */
-       addiCodeToeBBlock(ebp,nic,( ebp->sch->op == LABEL ? 
+  /* if this was a block level spil then insert push & pop 
+     at the start & end of block respectively */
+  if (ssym->blockSpil)
+    {
+      iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
+      /* add push to the start of the block */
+      addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
                                    ebp->sch->next : ebp->sch));
-       nic = newiCode(IPOP,operandFromSymbol(ssym),NULL);
-       /* add pop to the end of the block */
-       addiCodeToeBBlock(ebp,nic,NULL);
-    }       
-
-    /* if spilt because not used in the remainder of the
-       block then add a push before this instruction and
-       a pop at the end of the block */
-    if (ssym->remainSpil) {
-
-       iCode *nic = newiCode(IPUSH,operandFromSymbol(ssym),NULL);
-       /* add push just before this instruction */
-       addiCodeToeBBlock(ebp,nic,ic);
-                                   
-       nic = newiCode(IPOP,operandFromSymbol(ssym),NULL);
-       /* add pop to the end of the block */
-       addiCodeToeBBlock(ebp,nic,NULL);    
+      nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
+      /* add pop to the end of the block */
+      addiCodeToeBBlock (ebp, nic, NULL);
+    }
+
+  /* if spilt because not used in the remainder of the
+     block then add a push before this instruction and
+     a pop at the end of the block */
+  if (ssym->remainSpil)
+    {
+
+      iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
+      /* add push just before this instruction */
+      addiCodeToeBBlock (ebp, nic, ic);
+
+      nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
+      /* add pop to the end of the block */
+      addiCodeToeBBlock (ebp, nic, NULL);
     }
 
-    if (ssym == forSym )
-       return FALSE ;
-    else
-       return TRUE ;
+  if (ssym == forSym)
+    return FALSE;
+  else
+    return TRUE;
 }
 
 /*-----------------------------------------------------------------*/
 /* getRegPtr - will try for PTR if not a GPR type if not spil      */
 /*-----------------------------------------------------------------*/
-static regs *getRegPtr (iCode *ic, eBBlock *ebp, symbol *sym)
+static regs *
+getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
 {
-    regs *reg;
+  regs *reg;
+  int j;
 
- tryAgain:
-    /* try for a ptr type */
-    if ((reg = allocReg(REG_PTR))) 
-       return reg;    
+tryAgain:
+  /* try for a ptr type */
+  if ((reg = allocReg (REG_PTR)))
+    return reg;
 
-    /* try for gpr type */
-    if ((reg = allocReg(REG_GPR)))        
-       return reg;    
+  /* try for gpr type */
+  if ((reg = allocReg (REG_GPR)))
+    return reg;
 
-    /* we have to spil */
-    if (!spilSomething (ic,ebp,sym))
-       return NULL ;
+  /* we have to spil */
+  if (!spilSomething (ic, ebp, sym))
+    return NULL;
 
-    /* this looks like an infinite loop but 
-       in really selectSpil will abort  */
-    goto tryAgain ;    
+  /* make sure partially assigned registers aren't reused */
+  for (j=0; j<=sym->nRegs; j++)
+    if (sym->regs[j])
+      sym->regs[j]->isFree = 0;
+      
+  /* this looks like an infinite loop but 
+     in really selectSpil will abort  */
+  goto tryAgain;
 }
 
 /*-----------------------------------------------------------------*/
 /* getRegGpr - will try for GPR if not spil                        */
 /*-----------------------------------------------------------------*/
-static regs *getRegGpr (iCode *ic, eBBlock *ebp,symbol *sym)
+static regs *
+getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
 {
-    regs *reg;
+  regs *reg;
+  int j;
 
- tryAgain:
-    /* try for gpr type */
-    if ((reg = allocReg(REG_GPR)))        
-       return reg;    
+tryAgain:
+  /* try for gpr type */
+  if ((reg = allocReg (REG_GPR)))
+    return reg;
 
-    if (!ds390_ptrRegReq)
-       if ((reg = allocReg(REG_PTR)))
-           return reg ;
-       
-    /* we have to spil */
-    if (!spilSomething (ic,ebp,sym))
-       return NULL ;
+  if (!ds390_ptrRegReq)
+    if ((reg = allocReg (REG_PTR)))
+      return reg;
+
+  /* we have to spil */
+  if (!spilSomething (ic, ebp, sym))
+    return NULL;
+
+  /* make sure partially assigned registers aren't reused */
+  for (j=0; j<=sym->nRegs; j++)
+    if (sym->regs[j])
+      sym->regs[j]->isFree = 0;
+      
+  /* this looks like an infinite loop but 
+     in really selectSpil will abort  */
+  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);
+
+  /* just to make the compiler happy */
+  return 0;
+}
+
+/*-----------------------------------------------------------------*/
+/* getRegGprNoSpil - get it cannot split                           */
+/*-----------------------------------------------------------------*/
+static regs *getRegGprNoSpil()
+{
+
+  regs *reg;
+  if ((reg = allocReg (REG_GPR)))
+    return reg;
 
-    /* this looks like an infinite loop but 
-       in really selectSpil will abort  */
-    goto tryAgain ;    
+  if (!ds390_ptrRegReq)
+    if ((reg = allocReg (REG_PTR)))
+      return reg;
+
+  assert(0);
+
+  /* just to make the compiler happy */
+  return 0;
 }
 
 /*-----------------------------------------------------------------*/
 /* symHasReg - symbol has a given register                         */
 /*-----------------------------------------------------------------*/
-static bool symHasReg(symbol *sym,regs *reg)
+static bool
+symHasReg (symbol * sym, regs * reg)
 {
-    int i;
+  int i;
 
-    for ( i = 0 ; i < sym->nRegs ; i++)
-       if (sym->regs[i] == reg)
-           return TRUE;
-           
-    return FALSE;
+  for (i = 0; i < sym->nRegs; i++)
+    if (sym->regs[i] == reg)
+      return TRUE;
+
+  return FALSE;
 }
 
 /*-----------------------------------------------------------------*/
-/* deassignLRs - check the live to and if they have registers & are*/
+/* deassignLRs - check the live to and if they have registers & are */
 /*               not spilt then free up the registers              */
 /*-----------------------------------------------------------------*/
-static void deassignLRs (iCode *ic, eBBlock *ebp)
+static void
+deassignLRs (iCode * ic, eBBlock * ebp)
 {
-    symbol *sym;
-    int k;
-    symbol *result;
+  symbol *sym;
+  int k;
+  symbol *result;
 
-    for (sym = hTabFirstItem(liveRanges,&k); sym;
-        sym = hTabNextItem(liveRanges,&k)) {
-       
-       symbol *psym= NULL;
-       /* if it does not end here */
-       if (sym->liveTo > ic->seq )
-           continue ;
+  for (sym = hTabFirstItem (liveRanges, &k); sym;
+       sym = hTabNextItem (liveRanges, &k))
+    {
 
-       /* if it was spilt on stack then we can 
-          mark the stack spil location as free */
-       if (sym->isspilt ) {
-           if (sym->stackSpil) {
-               sym->usl.spillLoc->isFree = 1;
-               sym->stackSpil = 0;
+      symbol *psym = NULL;
+      /* if it does not end here */
+      if (sym->liveTo > ic->seq)
+       continue;
+
+      /* if it was spilt on stack then we can 
+         mark the stack spil location as free */
+      if (sym->isspilt)
+       {
+         if (sym->stackSpil)
+           {
+             sym->usl.spillLoc->isFree = 1;
+             sym->stackSpil = 0;
            }
-           continue ;
+         continue;
        }
-       
-       if (!bitVectBitValue(_G.regAssigned,sym->key))
-           continue;
-       
-       /* special case check if this is an IFX &
-          the privious one was a pop and the 
-          previous one was not spilt then keep track
-          of the symbol */     
-       if (ic->op == IFX && ic->prev &&
-           ic->prev->op == IPOP && 
-           !ic->prev->parmPush  &&
-           !OP_SYMBOL(IC_LEFT(ic->prev))->isspilt) 
-           psym = OP_SYMBOL(IC_LEFT(ic->prev));
-
-       if (sym->nRegs) {
-           int i = 0;
-           
-           bitVectUnSetBit(_G.regAssigned,sym->key);
-
-           /* if the result of this one needs registers
-              and does not have it then assign it right
-              away */
-           if (IC_RESULT(ic) &&
-               !  (SKIP_IC2(ic) ||               /* not a special icode */
-                   ic->op == JUMPTABLE ||
-                   ic->op == IFX ||
-                   ic->op == IPUSH ||
-                   ic->op == IPOP ||
-                   ic->op == RETURN ||
-                   POINTER_SET(ic))     &&             
-               (result = OP_SYMBOL(IC_RESULT(ic))) && /* has a result */
-               result->liveTo > ic->seq &&            /* and will live beyond this */
-               result->liveTo <= ebp->lSeq &&         /* does not go beyond this block */
-               result->regType == sym->regType &&     /* same register types */
-               result->nRegs            &&            /* which needs registers */
-               ! result->isspilt        &&            /* and does not already have them */
-               ! result->remat          &&
-               ! bitVectBitValue(_G.regAssigned,result->key) &&
-               /* the number of free regs + number of regs in this LR
-                  can accomodate the what result Needs */
-               ((nfreeRegsType(result->regType) +
-                 sym->nRegs) >= result->nRegs)
-               ) {
-               
-               for (i = 0 ; i < result->nRegs ; i++)
-                   if (i < sym->nRegs )
-                       result->regs[i] = sym->regs[i] ;
-                   else
-                       result->regs[i] = getRegGpr (ic,ebp,result);
 
-               _G.regAssigned = bitVectSetBit(_G.regAssigned,result->key);
-               
-           }                   
-           
-           /* free the remaining */
-           for (; i < sym->nRegs ; i++) {
-               if (psym) {
-                   if (!symHasReg(psym,sym->regs[i]))
-                       freeReg(sym->regs[i]);
-               } else
-                   freeReg(sym->regs[i]);
+      if (!bitVectBitValue (_G.regAssigned, sym->key))
+       continue;
+
+      /* special case check if this is an IFX &
+         the privious one was a pop and the 
+         previous one was not spilt then keep track
+         of the symbol */
+      if (ic->op == IFX && ic->prev &&
+         ic->prev->op == IPOP &&
+         !ic->prev->parmPush &&
+         !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
+       psym = OP_SYMBOL (IC_LEFT (ic->prev));
+
+      if (sym->nRegs)
+       {
+         int i = 0;
+
+         bitVectUnSetBit (_G.regAssigned, sym->key);
+
+         /* if the result of this one needs registers
+            and does not have it then assign it right
+            away */
+         if (IC_RESULT (ic) &&
+             !(SKIP_IC2 (ic) ||        /* not a special icode */
+               ic->op == JUMPTABLE ||
+               ic->op == IFX ||
+               ic->op == IPUSH ||
+               ic->op == IPOP ||
+               ic->op == RETURN ||
+               POINTER_SET (ic)) &&
+             (result = OP_SYMBOL (IC_RESULT (ic))) &&  /* has a result */
+             result->liveTo > ic->seq &&       /* and will live beyond this */
+             result->liveTo <= ebp->lSeq &&    /* does not go beyond this block */
+             result->regType == sym->regType &&        /* same register types */
+             result->nRegs &&  /* which needs registers */
+             !result->isspilt &&       /* and does not already have them */
+             !result->remat &&
+             !bitVectBitValue (_G.regAssigned, result->key) &&
+         /* the number of free regs + number of regs in this LR
+            can accomodate the what result Needs */
+             ((nfreeRegsType (result->regType) +
+               sym->nRegs) >= result->nRegs)
+           )
+           {
+
+             for (i = 0; i < result->nRegs; i++)
+               if (i < sym->nRegs)
+                 result->regs[i] = sym->regs[i];
+               else
+                 result->regs[i] = getRegGpr (ic, ebp, result);
+
+             _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
+             _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, result->key);
+
+           }
+
+         /* free the remaining */
+         for (; i < sym->nRegs; i++)
+           {
+             if (psym)
+               {
+                 if (!symHasReg (psym, sym->regs[i]))
+                   freeReg (sym->regs[i]);
+               }
+             else
+               freeReg (sym->regs[i]);
            }
        }
     }
@@ -896,357 +1028,745 @@ static void deassignLRs (iCode *ic, eBBlock *ebp)
 /*-----------------------------------------------------------------*/
 /* reassignLR - reassign this to registers                         */
 /*-----------------------------------------------------------------*/
-static void reassignLR (operand *op)
+static void
+reassignLR (operand * op)
 {
-    symbol *sym = OP_SYMBOL(op);
-    int i;
+  symbol *sym = OP_SYMBOL (op);
+  int i;
 
-    /* not spilt any more */     
-    sym->isspilt = sym->blockSpil  = sym->remainSpil = 0;
-    bitVectUnSetBit(_G.spiltSet,sym->key);
-      
-    _G.regAssigned = bitVectSetBit(_G.regAssigned,sym->key);
+  /* not spilt any more */
+  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--;
+  _G.blockSpil--;
 
-    for (i=0;i<sym->nRegs;i++)
-       sym->regs[i]->isFree = 0;
+  for (i = 0; i < sym->nRegs; i++)
+    sym->regs[i]->isFree = 0;
 }
 
 /*-----------------------------------------------------------------*/
 /* willCauseSpill - determines if allocating will cause a spill    */
 /*-----------------------------------------------------------------*/
-static int willCauseSpill ( int nr, int rt)
+static int
+willCauseSpill (int nr, int rt)
 {
-    /* first check if there are any avlb registers
-       of te type required */
-    if (rt == REG_PTR) {
-       /* special case for pointer type 
-          if pointer type not avlb then 
-          check for type gpr */
-       if (nFreeRegs(rt) >= nr)
+  /* first check if there are any avlb registers
+     of te type required */
+  if (rt == REG_PTR)
+    {
+      /* special case for pointer type 
+         if pointer type not avlb then 
+         check for type gpr */
+      if (nFreeRegs (rt) >= nr)
+       return 0;
+      if (nFreeRegs (REG_GPR) >= nr)
+       return 0;
+    }
+  else
+    {
+      if (ds390_ptrRegReq)
+       {
+         if (nFreeRegs (rt) >= nr)
            return 0;
-       if (nFreeRegs(REG_GPR) >= nr)
+       }
+      else
+       {
+         if (nFreeRegs (REG_PTR) +
+             nFreeRegs (REG_GPR) >= nr)
            return 0;
-    } else {
-       if (ds390_ptrRegReq) {
-           if (nFreeRegs(rt) >= nr)
-               return 0;
-       } else {
-           if (nFreeRegs(REG_PTR) +
-               nFreeRegs(REG_GPR) >= nr)
-               return 0;
        }
     }
 
-    /* it will cause a spil */
-    return 1;
+  /* it will cause a spil */
+  return 1;
 }
 
 /*-----------------------------------------------------------------*/
-/* positionRegs - the allocator can allocate same registers to res-*/
+/* positionRegs - the allocator can allocate same registers to res- */
 /* ult and operand, if this happens make sure they are in the same */
 /* position as the operand otherwise chaos results                 */
 /*-----------------------------------------------------------------*/
-static void positionRegs (symbol *result, symbol *opsym, int lineno)
+static int
+positionRegs (symbol * result, symbol * opsym)
 {
-       int count = min(result->nRegs,opsym->nRegs);
-       int i , j = 0, shared = 0;
-
-       /* if the result has been spilt then cannot share */
-       if (opsym->isspilt)
-               return ;
- again:
-       shared = 0;
-       /* first make sure that they actually share */
-       for ( i = 0 ; i < count; i++ ) {
-               for (j = 0 ; j < count ; j++ ) {
-                       if (result->regs[i] == opsym->regs[j] && i !=j) {
-                               shared = 1;
-                               goto xchgPositions;
-                       }
-               }
-       }
- xchgPositions:
-       if (shared) {
-               regs *tmp = result->regs[i];
-               result->regs[i] = result->regs[j];
-               result->regs[j] = tmp;          
-               goto again;
+  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 0;
+again:
+  shared = 0;
+  /* first make sure that they actually share */
+  for (i = 0; i < count; i++)
+    {
+      for (j = 0; j < count; j++)
+       {
+         if (result->regs[i] == opsym->regs[j] && i != j)
+           {
+             shared = 1;
+             goto xchgPositions;
+           }
        }
+    }
+xchgPositions:
+  if (shared)
+    {
+      regs *tmp = result->regs[i];
+      result->regs[i] = result->regs[j];
+      result->regs[j] = tmp;
+      change ++;
+      goto again;
+    }
+  return change ;
 }
 
 /*-----------------------------------------------------------------*/
-/* serialRegAssign - serially allocate registers to the variables  */
+/* unusedLRS - returns a bitVector of liveranges not used in 'ebp' */
 /*-----------------------------------------------------------------*/
-static void serialRegAssign (eBBlock **ebbs, int count)
+bitVect *unusedLRs (eBBlock *ebp) 
 {
-    int i;
-
-    /* for all blocks */
-    for (i = 0; i < count ; i++ ) {
-       
-       iCode *ic;
+    bitVect *ret = NULL;
+    symbol *sym;
+    int key;
+    
+    if (!ebp) return NULL;
+    for (sym = hTabFirstItem(liveRanges,&key); sym ; 
+        sym = hTabNextItem(liveRanges,&key)) {
        
-       if (ebbs[i]->noPath &&
-           (ebbs[i]->entryLabel != entryLabel &&
-            ebbs[i]->entryLabel != returnLabel ))
-           continue ;
-
-       /* of all instructions do */
-       for (ic = ebbs[i]->sch ; ic ; ic = ic->next) {
-        
-           /* if this is an ipop that means some live
-              range will have to be assigned again */
-           if (ic->op == IPOP)
-               reassignLR (IC_LEFT(ic));
-
-           /* 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;
-
-           /* take away registers from live
-              ranges that end at this instruction */      
-           deassignLRs (ic, ebbs[i]) ;         
-                   
-           /* some don't need registers */
-           if (SKIP_IC2(ic) ||
-               ic->op == JUMPTABLE ||
-               ic->op == IFX ||
-               ic->op == IPUSH ||
-               ic->op == IPOP ||
-               (IC_RESULT(ic) &&POINTER_SET(ic)) )
-               continue;   
-           
-           /* now we need to allocate registers
-              only for the result */
-           if (IC_RESULT(ic)) {
-               symbol *sym = OP_SYMBOL(IC_RESULT(ic));
-               bitVect *spillable;
-               int willCS ;
-               int j;
-               int ptrRegSet = 0;
-                              
-               /* if it does not need or is spilt 
-                  or is already assigned to registers
-                  or will not live beyond this instructions */
-               if (!sym->nRegs      || 
-                   sym->isspilt     || 
-                   bitVectBitValue(_G.regAssigned,sym->key) ||
-                   sym->liveTo <= ic->seq)
-                   continue ;
-
-               /* if some liverange has been spilt at the block level
-                  and this one live beyond this block then spil this
-                  to be safe */
-               if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq) {
-                   spillThis (sym);
-                   continue ;
-               }
-               /* if trying to allocate this will cause
-                  a spill and there is nothing to spill 
-                  or this one is rematerializable then
-                  spill this one */
-               willCS = willCauseSpill(sym->nRegs,sym->regType);
-               spillable = computeSpillable(ic);
-               if ( sym->remat ||                  
-                   (willCS  && bitVectIsZero(spillable) ) ) {
-
-                   spillThis (sym) ;
-                   continue ;
-
-               }
-
-               /* if it has a spillocation & is used less than
-                  all other live ranges then spill this */
-               if ( willCS && sym->usl.spillLoc ) {
-
-                   symbol *leastUsed = 
-                       leastUsedLR(liveRangesWith (spillable ,
-                                                   allLRs,
-                                                   ebbs[i],
-                                                   ic));
-                   if (leastUsed && 
-                       leastUsed->used > sym->used) {
-                       spillThis (sym);
-                       continue;
-                   }
-               }               
-               
-               /* if we need ptr regs for the right side
-                  then mark it */
-               if (POINTER_GET(ic) && getSize(OP_SYMBOL(IC_LEFT(ic))->type) 
-                   <= PTRSIZE) 
-               {
-                   ds390_ptrRegReq++;
-                   ptrRegSet = 1;
-               }
-               /* else we assign registers to it */            
-               _G.regAssigned = bitVectSetBit(_G.regAssigned,sym->key);
-
-               for (j = 0 ; j < sym->nRegs ;j++ ) {
-                   if (sym->regType == REG_PTR)
-                       sym->regs[j] = getRegPtr(ic,ebbs[i],sym);
-                   else
-                       sym->regs[j] = getRegGpr(ic,ebbs[i],sym);
-
-                   /* if the allocation falied which means
-                      this was spilt then break */
-                   if (!sym->regs[j])
-                       break;
-               }
-               /* if it shares registers with operands make sure
-                  that they are in the same position */
-               if (IC_LEFT(ic) && IS_SYMOP(IC_LEFT(ic)) &&
-                   OP_SYMBOL(IC_LEFT(ic))->nRegs  && ic->op != '=')
-                       positionRegs(OP_SYMBOL(IC_RESULT(ic)),
-                                    OP_SYMBOL(IC_LEFT(ic)),ic->lineno);
-               /* do the same for the right operand */
-               if (IC_RIGHT(ic) && IS_SYMOP(IC_RIGHT(ic)) &&
-                   OP_SYMBOL(IC_RIGHT(ic))->nRegs)
-                       positionRegs(OP_SYMBOL(IC_RESULT(ic)),
-                                    OP_SYMBOL(IC_RIGHT(ic)),ic->lineno);
-               
-               if (ptrRegSet) {
-                   ds390_ptrRegReq--;
-                   ptrRegSet = 0;
-               }
-                               
-           }       
+       if (notUsedInBlock(sym,ebp,NULL)) {
+           ret = bitVectSetBit(ret,sym->key);
        }
     }
+
+    return ret;
 }
 
 /*-----------------------------------------------------------------*/
-/* rUmaskForOp :- returns register mask for an operand             */
+/* deassignUnsedLRs - if this baisc block ends in a return then    */
+/*                   deassign symbols not used in this block      */
 /*-----------------------------------------------------------------*/
-static bitVect *rUmaskForOp (operand *op)
+bitVect *deassignUnsedLRs(eBBlock *ebp)
 {
-    bitVect *rumask;
-    symbol *sym;
-    int j;
-    
-    /* only temporaries are assigned registers */
-    if (!IS_ITEMP(op)) 
-       return NULL;
+    bitVect *unused = NULL;
+    int i;
 
-    sym = OP_SYMBOL(op);
+    switch (returnAtEnd(ebp)) {
+    case 2: /* successor block ends in a return */
+       unused = unusedLRs((eBBlock *) setFirstItem(ebp->succList));
+       /* fall thru */
+    case 1: /* this block ends in a return */
+       unused = bitVectIntersect(unused,unusedLRs(ebp));
+       break;
+    }
     
-    /* if spilt or no registers assigned to it
-       then nothing */
-    if (sym->isspilt || !sym->nRegs)
-       return NULL;
+    if (unused) {
+       for (i = 0 ; i < unused->size ; i++ ) {
+
+           /* if unused  */
+           if (bitVectBitValue(unused,i)) {
+
+               /* if assigned to registers */
+               if (bitVectBitValue(_G.regAssigned,i)) {
+                   symbol *sym;
+                   int j;
+                   
+                   sym = hTabItemWithKey(liveRanges,i);
+                   /* remove it from regassigned & mark the
+                      register free */
+                   bitVectUnSetBit(_G.regAssigned,i);
+                   for (j = 0 ; j < sym->nRegs; j++)
+                       freeReg(sym->regs[j]);
+               } else {
+                   /* not assigned to registers : remove from set*/
+                   bitVectUnSetBit(unused,i);
+               }
+           }
+       }
+    }
+    return unused;
+}
 
-    rumask = newBitVect(ds390_nRegs);
+/*-----------------------------------------------------------------*/
+/* reassignUnusedLRs - put registers to unused Live ranges         */
+/*-----------------------------------------------------------------*/
+void reassignUnusedLRs (bitVect *unused)
+{
+    int i;
+    if (!unused) return ;
+
+    for (i = 0 ; i < unused->size ; i++ ) {
+       /* if unused : means it was assigned to registers before */
+       if (bitVectBitValue(unused,i)) {
+           symbol *sym;
+           int j;
+           
+           /* put it back into reg set*/
+           bitVectSetBit(_G.regAssigned,i) ;
 
-    for (j = 0; j < sym->nRegs; j++) { 
-       rumask = bitVectSetBit(rumask,
-                              sym->regs[j]->rIdx);
+           sym = hTabItemWithKey(liveRanges,i);
+           /* makr registers busy */
+           for (j = 0 ; j < sym->nRegs; j++)
+               sym->regs[j]->isFree = 0;
+       }
     }
+}
 
-    return rumask;
+/*------------------------------------------------------------------*/
+/* verifyRegsAssigned - make sure an iTemp is properly initialized; */
+/* it should either have registers or have beed spilled. Otherwise, */
+/* there was an uninitialized variable, so just spill this to get   */
+/* the operand in a valid state.                                    */
+/*------------------------------------------------------------------*/
+static void
+verifyRegsAssigned (operand *op, iCode * ic)
+{
+  symbol * sym;
+  
+  if (!op) return;
+  if (!IS_ITEMP (op)) return;
+  
+  sym = OP_SYMBOL (op);
+  if (sym->isspilt) return;
+  if (!sym->nRegs) return;
+  if (sym->regs[0]) return;
+  
+  werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT, 
+           sym->prereqv ? sym->prereqv->name : sym->name);
+  spillThis (sym);
 }
 
+
 /*-----------------------------------------------------------------*/
-/* regsUsedIniCode :- returns bit vector of registers used in iCode*/
+/* serialRegAssign - serially allocate registers to the variables  */
 /*-----------------------------------------------------------------*/
-static bitVect *regsUsedIniCode (iCode *ic)
+static void
+serialRegAssign (eBBlock ** ebbs, int count)
 {
-    bitVect *rmask = newBitVect(ds390_nRegs);
+  int i;
 
-    /* do the special cases first */
-    if (ic->op == IFX ) {
-       rmask = bitVectUnion(rmask,
-                            rUmaskForOp(IC_COND(ic)));
-       goto ret;
-    }
+  /* for all blocks */
+  for (i = 0; i < count; i++)
+      { /* ebbs */
 
-    /* for the jumptable */
-    if (ic->op == JUMPTABLE) {
-       rmask = bitVectUnion(rmask,
-                            rUmaskForOp(IC_JTCOND(ic)));
+      iCode *ic;
+      bitVect *unusedLRs = NULL;
 
-        goto ret;
+      if (ebbs[i]->noPath &&
+         (ebbs[i]->entryLabel != entryLabel &&
+          ebbs[i]->entryLabel != returnLabel))
+       continue;
+      
+      unusedLRs = deassignUnsedLRs(ebbs[i]);
+      
+      /* of all instructions do */
+      for (ic = ebbs[i]->sch; ic; ic = ic->next)
+       {
+
+         /* if this is an ipop that means some live
+            range will have to be assigned again */
+         if (ic->op == IPOP)
+           reassignLR (IC_LEFT (ic));
+
+         /* 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++;
+
+         /* take away registers from live
+            ranges that end at this instruction */
+         deassignLRs (ic, ebbs[i]);
+
+         /* some don't need registers */
+         if (SKIP_IC2 (ic) ||
+             ic->op == JUMPTABLE ||
+             ic->op == IFX ||
+             ic->op == IPUSH ||
+             ic->op == IPOP ||
+             (IC_RESULT (ic) && POINTER_SET (ic)))
+           continue;
+
+         /* now we need to allocate registers
+            only for the result */
+         if (IC_RESULT (ic))
+           {
+             symbol *sym = OP_SYMBOL (IC_RESULT (ic));
+             bitVect *spillable;
+             int willCS;
+             int j;
+             int ptrRegSet = 0;
+
+             /* if it does not need or is spilt 
+                or is already assigned to registers
+                or will not live beyond this instructions */
+             if (!sym->nRegs ||
+                 sym->isspilt ||
+                 bitVectBitValue (_G.regAssigned, sym->key) ||
+                 sym->liveTo <= ic->seq)
+               continue;
+
+             /* if some liverange has been spilt at the block level
+                and this one live beyond this block then spil this
+                to be safe */
+             if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
+               {
+                 spillThis (sym);
+                 continue;
+               }
+             /* if trying to allocate this will cause
+                a spill and there is nothing to spill 
+                or this one is rematerializable then
+                spill this one */
+             willCS = willCauseSpill (sym->nRegs, sym->regType);
+             spillable = computeSpillable (ic);
+             if (sym->remat ||
+                 (willCS && bitVectIsZero (spillable)))
+               {
+
+                 spillThis (sym);
+                 continue;
+
+               }
+
+             /* if it has a spillocation & is used less than
+                all other live ranges then spill this */
+               if (willCS) {
+                   if (sym->usl.spillLoc) {
+                       symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
+                                                                        allLRs, ebbs[i], ic));
+                       if (leastUsed && leastUsed->used > sym->used) {
+                           spillThis (sym);
+                           continue;
+                       }
+                   } else {
+                       /* if none of the liveRanges have a spillLocation then better
+                          to spill this one than anything else already assigned to registers */
+                       if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
+                           /* if this is local to this block then we might find a block spil */
+                           if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
+                               spillThis (sym);
+                               continue;
+                           }
+                       }
+                   }
+               }
+
+             /* if we need ptr regs for the right side
+                then mark it */
+             if (POINTER_GET (ic) && IS_SYMOP (IC_LEFT (ic))
+                 && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
+                 <= (unsigned) PTRSIZE)
+               {
+                 ds390_ptrRegReq++;
+                 ptrRegSet = 1;
+               }
+             /* 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++)
+               {
+                 if (sym->regType == REG_PTR)
+                   sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
+                 else
+                   sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
+
+                 /* if the allocation falied which means
+                    this was spilt then break */
+                 if (!sym->regs[j])
+                   break;
+               }
+             
+              /* if it shares registers with operands make sure
+                that they are in the same position */
+             if (!POINTER_SET(ic) && !POINTER_GET(ic))
+                {
+                 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
+                     OP_SYMBOL (IC_LEFT (ic))->nRegs)
+                    {
+                     positionRegs (OP_SYMBOL (IC_RESULT (ic)),
+                                   OP_SYMBOL (IC_LEFT (ic)));
+                   }
+                 /* do the same for the right operand */
+                 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
+                     OP_SYMBOL (IC_RIGHT (ic))->nRegs)
+                    {
+                     positionRegs (OP_SYMBOL (IC_RESULT (ic)),
+                                   OP_SYMBOL (IC_RIGHT (ic)));
+                   }
+                }
+
+             if (ptrRegSet)
+               {
+                 ds390_ptrRegReq--;
+                 ptrRegSet = 0;
+               }
+
+           }
+       }
+      reassignUnusedLRs(unusedLRs);
     }
 
-    /* of all other cases */
-    if (IC_LEFT(ic)) 
-       rmask = bitVectUnion(rmask,
-                            rUmaskForOp(IC_LEFT(ic)));
-       
-    
-    if (IC_RIGHT(ic))
-       rmask = bitVectUnion(rmask,
-                            rUmaskForOp(IC_RIGHT(ic)));
+    /* Check for and fix any problems with uninitialized operands */
+    for (i = 0; i < count; i++)
+      {
+       iCode *ic;
 
-    if (IC_RESULT(ic))
-       rmask = bitVectUnion(rmask,
-                            rUmaskForOp(IC_RESULT(ic)));
+       if (ebbs[i]->noPath &&
+           (ebbs[i]->entryLabel != entryLabel &&
+            ebbs[i]->entryLabel != returnLabel))
+           continue;
 
- ret:
-    return rmask;
+       for (ic = ebbs[i]->sch; ic; ic = ic->next)
+         {
+           if (SKIP_IC2 (ic))
+             continue;
+
+           if (ic->op == IFX)
+             {
+               verifyRegsAssigned (IC_COND (ic), ic);
+               continue;
+             }
+
+           if (ic->op == JUMPTABLE)
+             {
+               verifyRegsAssigned (IC_JTCOND (ic), ic);
+               continue;
+             }
+
+           verifyRegsAssigned (IC_RESULT (ic), ic);
+           verifyRegsAssigned (IC_LEFT (ic), ic);
+           verifyRegsAssigned (IC_RIGHT (ic), ic);
+          }
+      }    
+    
 }
 
 /*-----------------------------------------------------------------*/
-/* createRegMask - for each instruction will determine the regsUsed*/
+/* fillGaps - Try to fill in the Gaps left by Pass1                */
 /*-----------------------------------------------------------------*/
-static void createRegMask (eBBlock **ebbs, int count)
+static void fillGaps()
 {
-    int i;
+    symbol *sym =NULL;
+    int key =0;    
+    int loop = 0, change;
+    int pass;
 
-    /* for all blocks */
-    for (i = 0; i < count ; i++ ) {
-       iCode *ic ;
+    if (getenv("DISABLE_FILL_GAPS")) return;
+    
+    /* First try to do DPTRuse once more since now we know what got into
+       registers */ 
+    
+    while (loop++ < 10) {
+       change = 0;
 
-       if ( ebbs[i]->noPath &&
-            ( ebbs[i]->entryLabel != entryLabel &&
-              ebbs[i]->entryLabel != returnLabel ))
-           continue ;
+       for (sym = hTabFirstItem(liveRanges,&key) ; sym ; 
+            sym = hTabNextItem(liveRanges,&key)) {
+           int size = getSize(sym->type);
 
-       /* for all instructions */
-       for ( ic = ebbs[i]->sch ; ic ; ic = ic->next ) {
-           
-           int j;
+           if (sym->liveFrom == sym->liveTo) continue;
 
-           if (SKIP_IC2(ic) || !ic->rlive)
-               continue ;
-           
-           /* first mark the registers used in this
-              instruction */
-           ic->rUsed = regsUsedIniCode(ic);
-           _G.funcrUsed = bitVectUnion(_G.funcrUsed,ic->rUsed);
-
-           /* now create the register mask for those 
-              registers that are in use : this is a
-              super set of ic->rUsed */
-           ic->rMask = newBitVect(ds390_nRegs+1);
-
-           /* for all live Ranges alive at this point */
-           for (j = 1; j < ic->rlive->size; j++ ) {
-               symbol *sym;
-               int k;
+           if (sym->uptr && sym->dptr==0 && !sym->ruonly && 
+               size < 4 && size > 1) {
 
-               /* if not alive then continue */
-               if (!bitVectBitValue(ic->rlive,j))
+               if (packRegsDPTRuse(operandFromSymbol(sym))) {
+                   
+                   /* if this was ssigned to registers then */
+                   if (bitVectBitValue(_G.totRegAssigned,sym->key)) {
+                       /* take it out of the register assigned set */
+                       bitVectUnSetBit(_G.totRegAssigned,sym->key);
+                   } else if (sym->usl.spillLoc) {
+                       sym->usl.spillLoc->allocreq--;
+                       sym->usl.spillLoc = NULL;
+                   }
+                   
+                   sym->nRegs = 0;                 
+                   sym->isspilt = sym->spillA = 0;
                    continue ;
-
-               /* find the live range we are interested in */
-               if (!(sym = hTabItemWithKey(liveRanges,j))) {
-                   werror (E_INTERNAL_ERROR,__FILE__,__LINE__,
-                           "createRegMask cannot find live range");
-                   exit(0);
                }
 
-               /* if no register assigned to it */
-               if (!sym->nRegs || sym->isspilt)
+               /* try assigning other dptrs */
+               if (sym->dptr == 0 && packRegsDPTRnuse(operandFromSymbol(sym),1) && !getenv("DPTRnDISABLE")) {
+                   /* if this was ssigned to registers then */
+                   if (bitVectBitValue(_G.totRegAssigned,sym->key)) {
+                       /* take it out of the register assigned set */
+                       bitVectUnSetBit(_G.totRegAssigned,sym->key);
+                   } else if (sym->usl.spillLoc) {
+                       sym->usl.spillLoc->allocreq--;
+                       sym->usl.spillLoc = NULL;
+                   }
+                   sym->nRegs = 0;                 
+                   sym->isspilt = sym->spillA = 0;                 
+               }
+           }
+       }
+       
+       /* look for livernages that was spilt by the allocator */
+       for (sym = hTabFirstItem(liveRanges,&key) ; sym ; 
+            sym = hTabNextItem(liveRanges,&key)) {
+           
+           int i;
+           int pdone = 0;
+           
+           if (!sym->spillA || !sym->clashes || sym->remat) continue ;
+           if (!sym->uses || !sym->defs) 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 ;
+               
+               clr = hTabItemWithKey(liveRanges,i);
+               assert(clr);
+               
+               /* 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 ();            
+           }
+           
+           /* For all its definitions check if the registers
+              allocated needs positioning NOTE: we can position
+              only ONCE if more than One positioning required 
+              then give up.
+              We may need to perform the checks twice; once to
+              position the registers as needed, the second to
+              verify any register repositioning is still
+              compatible.
+              */
+           sym->isspilt = 0;
+            for (pass=0; pass<2; pass++) {
+               for (i = 0 ; i < sym->defs->size ; i++ ) {
+                   if (bitVectBitValue(sym->defs,i)) {
+                       iCode *ic;
+                       if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
+                       if (SKIP_IC(ic)) continue;
+                       assert(isSymbolEqual(sym,OP_SYMBOL(IC_RESULT(ic)))); /* just making sure */
+                        /* if left is assigned to registers */
+                        if (IS_SYMOP(IC_LEFT(ic)) && 
+                         bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_LEFT(ic))->key)) {
+                           pdone += (positionRegs(sym,OP_SYMBOL(IC_LEFT(ic)))>0);
+                       }
+                       if (IS_SYMOP(IC_RIGHT(ic)) && 
+                         bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RIGHT(ic))->key)) {
+                           pdone += (positionRegs(sym,OP_SYMBOL(IC_RIGHT(ic)))>0);
+                       }
+                       if (pdone > 1) break;
+                   }
+               }
+               for (i = 0 ; i < sym->uses->size ; i++ ) {
+                   if (bitVectBitValue(sym->uses,i)) {
+                       iCode *ic;
+                       if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
+                       if (SKIP_IC(ic)) continue;
+                       if (POINTER_SET(ic) || POINTER_GET(ic)) continue ;
+
+                       /* if result is assigned to registers */
+                       if (IS_SYMOP(IC_RESULT(ic)) && 
+                         bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RESULT(ic))->key)) {
+                           pdone += (positionRegs(sym,OP_SYMBOL(IC_RESULT(ic)))>0);
+                       }
+                       if (pdone > 1) break;
+                   }
+               }
+                if (pdone == 0) break; /* second pass only if regs repositioned */
+               if (pdone > 1) break;
+            }
+           /* had to position more than once GIVE UP */
+           if (pdone > 1) {
+               /* UNDO all the changes we made to try this */
+               sym->isspilt = 1;
+               for (i=0; i < sym->nRegs ; i++ ) {
+                   sym->regs[i] = NULL;
+               }
+               freeAllRegs();
+               D (fprintf (stderr, "Fill Gap gave up due to positioning for "
+                           "%s in function %s\n",
+                           sym->name, currFunc ? currFunc->name : "UNKNOWN"));
+               continue ;          
+           }
+           D (fprintf (stderr, "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--;
+           sym->usl.spillLoc = NULL;
+           freeAllRegs();
+           change ++;
+       }
+       if (!change) break;
+    }
+}
+
+/*-----------------------------------------------------------------*/
+/* rUmaskForOp :- returns register mask for an operand             */
+/*-----------------------------------------------------------------*/
+bitVect *
+ds390_rUmaskForOp (operand * op)
+{
+  bitVect *rumask;
+  symbol *sym;
+  int j;
+
+  /* only temporaries are assigned registers */
+  if (!IS_ITEMP (op))
+    return NULL;
+
+  sym = OP_SYMBOL (op);
+
+  /* if spilt or no registers assigned to it
+     then nothing */
+  if (sym->isspilt || !sym->nRegs)
+    return NULL;
+
+  rumask = newBitVect (ds390_nRegs);
+
+  for (j = 0; j < sym->nRegs; j++)
+    {
+      rumask = bitVectSetBit (rumask,
+                             sym->regs[j]->rIdx);
+    }
+
+  return rumask;
+}
+
+/*-----------------------------------------------------------------*/
+/* regsUsedIniCode :- returns bit vector of registers used in iCode */
+/*-----------------------------------------------------------------*/
+static bitVect *
+regsUsedIniCode (iCode * ic)
+{
+  bitVect *rmask = newBitVect (ds390_nRegs);
 
-               /* for all the registers allocated to it */
-               for (k = 0 ; k < sym->nRegs ;k++)
-                   if (sym->regs[k])
-                       ic->rMask =
-                           bitVectSetBit(ic->rMask,sym->regs[k]->rIdx);
+  /* do the special cases first */
+  if (ic->op == IFX)
+    {
+      rmask = bitVectUnion (rmask,
+                           ds390_rUmaskForOp (IC_COND (ic)));
+      goto ret;
+    }
+
+  /* for the jumptable */
+  if (ic->op == JUMPTABLE)
+    {
+      rmask = bitVectUnion (rmask,
+                           ds390_rUmaskForOp (IC_JTCOND (ic)));
+
+      goto ret;
+    }
+
+  /* of all other cases */
+  if (IC_LEFT (ic))
+    rmask = bitVectUnion (rmask,
+                         ds390_rUmaskForOp (IC_LEFT (ic)));
+
+
+  if (IC_RIGHT (ic))
+    rmask = bitVectUnion (rmask,
+                         ds390_rUmaskForOp (IC_RIGHT (ic)));
+
+  if (IC_RESULT (ic))
+    rmask = bitVectUnion (rmask,
+                         ds390_rUmaskForOp (IC_RESULT (ic)));
+
+ret:
+  return rmask;
+}
+
+/*-----------------------------------------------------------------*/
+/* createRegMask - for each instruction will determine the regsUsed */
+/*-----------------------------------------------------------------*/
+static void
+createRegMask (eBBlock ** ebbs, int count)
+{
+  int i;
+
+  /* for all blocks */
+  for (i = 0; i < count; i++)
+    {
+      iCode *ic;
+
+      if (ebbs[i]->noPath &&
+         (ebbs[i]->entryLabel != entryLabel &&
+          ebbs[i]->entryLabel != returnLabel))
+       continue;
+
+      /* for all instructions */
+      for (ic = ebbs[i]->sch; ic; ic = ic->next)
+       {
+
+         int j;
+
+         if (SKIP_IC2 (ic) || !ic->rlive)
+           continue;
+
+         /* first mark the registers used in this
+            instruction */
+         ic->rUsed = regsUsedIniCode (ic);
+         _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
+
+         /* now create the register mask for those 
+            registers that are in use : this is a
+            super set of ic->rUsed */
+         ic->rMask = newBitVect (ds390_nRegs + 1);
+
+         /* for all live Ranges alive at this point */
+         for (j = 1; j < ic->rlive->size; j++)
+           {
+             symbol *sym;
+             int k;
+
+             /* if not alive then continue */
+             if (!bitVectBitValue (ic->rlive, j))
+               continue;
+
+             /* find the live range we are interested in */
+             if (!(sym = hTabItemWithKey (liveRanges, j)))
+               {
+                 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+                         "createRegMask cannot find live range");
+                 exit (0);
+               }
+#if 0
+             /* special case for ruonly */
+             if (sym->ruonly && sym->liveFrom != sym->liveTo) {
+                 int size = getSize(sym->type);
+                 int j = DPL_IDX;
+                 for (k = 0 ; k < size; k++ )
+                     ic->rMask = bitVectSetBit (ic->rMask, j++);
+                 continue ;
+             }
+#endif
+             /* if no register assigned to it */
+             if (!sym->nRegs || sym->isspilt)
+               continue;
+
+             /* for all the registers allocated to it */
+             for (k = 0; k < sym->nRegs; k++)
+               if (sym->regs[k])
+                 ic->rMask =
+                   bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
            }
        }
     }
@@ -1255,1087 +1775,1414 @@ static void createRegMask (eBBlock **ebbs, int count)
 /*-----------------------------------------------------------------*/
 /* rematStr - returns the rematerialized string for a remat var    */
 /*-----------------------------------------------------------------*/
-static char *rematStr (symbol *sym)
+static char *
+rematStr (symbol * sym)
 {
-    char *s = buffer;   
-    iCode *ic = sym->rematiCode;    
-
-    while (1) {
-
-        /* if plus or minus print the right hand side */
-        if (ic->op == '+' || ic->op == '-') {
-            sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
-                    ic->op );
-            s += strlen(s);
-            ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
-            continue ;
-        }
-
-        /* we reached the end */
-        sprintf(s,"%s",OP_SYMBOL(IC_LEFT(ic))->rname);
-        break;
+  char *s = buffer;
+  iCode *ic = sym->rematiCode;
+
+  *s = 0;
+    
+  while (1)
+    {
+
+      /* if plus or minus print the right hand side */
+      if (ic->op == '+' || ic->op == '-')
+       {
+         SNPRINTF (s, sizeof(buffer) - strlen(buffer), 
+                   "0x%04x %c ", (int) operandLitValue (IC_RIGHT (ic)),
+                   ic->op);
+         s += strlen (s);
+         ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
+         continue;
+       }
+      /* cast then continue */
+      if (IS_CAST_ICODE(ic)) {
+         ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
+         continue;
+      }
+      /* we reached the end */
+      SNPRINTF (s, sizeof(buffer) - strlen(buffer), 
+               "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
+      break;
     }
 
-    return buffer ;
+  return buffer;
 }
 
 /*-----------------------------------------------------------------*/
 /* regTypeNum - computes the type & number of registers required   */
 /*-----------------------------------------------------------------*/
-static void regTypeNum ()
+static void
+regTypeNum ()
 {
-    symbol *sym;
-    int k;
-    iCode *ic;
+  symbol *sym;
+  int k;
+  iCode *ic;
 
-    /* for each live range do */
-    for ( sym = hTabFirstItem(liveRanges,&k); sym ;
-         sym = hTabNextItem(liveRanges,&k)) {
+  /* for each live range do */
+  for (sym = hTabFirstItem (liveRanges, &k); sym;
+       sym = hTabNextItem (liveRanges, &k))
+    {
 
-       /* if used zero times then no registers needed */
-       if ((sym->liveTo - sym->liveFrom) == 0)
-           continue ;
+      /* if used zero times then no registers needed */
+      if ((sym->liveTo - sym->liveFrom) == 0)
+       continue;
 
 
-       /* if the live range is a temporary */
-       if (sym->isitmp) {
+      /* if the live range is a temporary */
+      if (sym->isitmp)
+       {
 
-           /* if the type is marked as a conditional */
-           if (sym->regType == REG_CND)
-               continue ;
+         /* if the type is marked as a conditional */
+         if (sym->regType == REG_CND)
+           continue;
 
-           /* if used in return only then we don't 
-              need registers */
-           if (sym->ruonly || sym->accuse) {
-               if (IS_AGGREGATE(sym->type) || sym->isptr)
-                   sym->type = aggrToPtr(sym->type,FALSE);
-               continue ;
+         /* if used in return only then we don't 
+            need registers */
+         if (sym->ruonly || sym->accuse)
+           {
+             if (IS_AGGREGATE (sym->type) || sym->isptr)
+               sym->type = aggrToPtr (sym->type, FALSE);
+             continue;
            }
-           
-           /* if the symbol has only one definition &
-              that definition is a get_pointer and the
-              pointer we are getting is rematerializable and
-              in "data" space */
-              
-           if (bitVectnBitsOn(sym->defs) == 1 &&
-               (ic = hTabItemWithKey(iCodehTab,
-                                     bitVectFirstBit(sym->defs))) &&
-               POINTER_GET(ic) && 
-               !IS_BITVAR(sym->etype)) {
-               
-                               
-               /* if remat in data space */
-               if (OP_SYMBOL(IC_LEFT(ic))->remat &&
-                   // sym->type &&
-                   DCL_TYPE(aggrToPtr(sym->type,FALSE)) == POINTER) {
-               
-                   /* create a psuedo symbol & force a spil */
-                   symbol *psym = newSymbol(rematStr(OP_SYMBOL(IC_LEFT(ic))),1);
-                   psym->type = sym->type;
-                   psym->etype = sym->etype;
-                   strcpy(psym->rname,psym->name);
-                   sym->isspilt = 1;
-                   sym->usl.spillLoc = psym;
-                   continue ;
+
+         /* if the symbol has only one definition &
+            that definition is a get_pointer */
+         if (bitVectnBitsOn (sym->defs) == 1 &&
+             (ic = hTabItemWithKey (iCodehTab,
+                                    bitVectFirstBit (sym->defs))) &&
+             POINTER_GET (ic) &&
+             !sym->noSpilLoc &&
+             !IS_BITVAR (sym->etype))
+           {
+             /* and that pointer is remat in data space */
+             if (IS_SYMOP (IC_LEFT (ic)) &&
+                 OP_SYMBOL (IC_LEFT (ic))->remat &&
+                 !IS_CAST_ICODE(OP_SYMBOL (IC_LEFT (ic))->rematiCode) &&
+                 DCL_TYPE (aggrToPtr (operandType(IC_LEFT(ic)), FALSE)) == POINTER)
+               {
+
+                 /* create a psuedo symbol & force a spil */
+                 symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
+                 psym->type = sym->type;
+                 psym->etype = sym->etype;
+                 strncpyz (psym->rname, psym->name, sizeof(psym->rname));
+                 sym->isspilt = 1;
+                 sym->usl.spillLoc = psym;
+                 continue;
                }
 
-               /* if in data space or idata space then try to
-                  allocate pointer register */
-                  
+             /* if in data space or idata space then try to
+                allocate pointer register */
+
            }
-               
-           /* if not then we require registers */
-           sym->nRegs = ((IS_AGGREGATE(sym->type) || sym->isptr ) ?
-                         getSize(sym->type = aggrToPtr(sym->type,FALSE)) :
-                         getSize(sym->type));
-
-           if (sym->nRegs > 4) {
-               fprintf(stderr,"allocated more than 4 or 0 registers for type ");
-               printTypeChain(sym->type,stderr);fprintf(stderr,"\n");
-            }
-           
-           /* determine the type of register required */
-           if (sym->nRegs == 1   && 
-               IS_PTR(sym->type) && 
-               sym->uptr) 
-               sym->regType = REG_PTR ;            
-           else 
-               sym->regType = REG_GPR ;
-           
-       } else 
-           /* for the first run we don't provide */
-           /* registers for true symbols we will */
-           /* see how things go                  */
-           sym->nRegs = 0 ;    
+
+         /* if not then we require registers */
+         sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
+                       getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
+                       getSize (sym->type));
+
+         if (sym->nRegs > 4)
+           {
+             fprintf (stderr, "allocated more than 4 or 0 registers for type ");
+             printTypeChain (sym->type, stderr);
+             fprintf (stderr, "\n");
+           }
+
+         /* determine the type of register required */
+         if (sym->nRegs == 1 &&
+             IS_PTR (sym->type) &&
+             sym->uptr)
+           sym->regType = REG_PTR;
+         else
+           sym->regType = REG_GPR;
+
+       }
+      else
+       /* for the first run we don't provide */
+       /* registers for true symbols we will */
+       /* see how things go                  */
+       sym->nRegs = 0;
     }
-    
+
 }
 
 /*-----------------------------------------------------------------*/
 /* freeAllRegs - mark all registers as free                        */
 /*-----------------------------------------------------------------*/
-static void freeAllRegs()
+static void
+freeAllRegs ()
 {
-    int i;
+  int i;
 
-    for (i=0;i< ds390_nRegs;i++ )
-       regs390[i].isFree = 1;
+  for (i = 0; i < ds390_nRegs; i++)
+    regs390[i].isFree = 1;
 }
 
 /*-----------------------------------------------------------------*/
 /* deallocStackSpil - this will set the stack pointer back         */
 /*-----------------------------------------------------------------*/
-static DEFSETFUNC(deallocStackSpil)
+static
+DEFSETFUNC (deallocStackSpil)
 {
-    symbol *sym = item;
+  symbol *sym = item;
 
-    deallocLocal(sym);
-    return 0;
+  deallocLocal (sym);
+  return 0;
 }
 
 /*-----------------------------------------------------------------*/
 /* farSpacePackable - returns the packable icode for far variables */
 /*-----------------------------------------------------------------*/
-static iCode *farSpacePackable (iCode *ic)
+static iCode *
+farSpacePackable (iCode * ic)
 {
-    iCode *dic ;
+  iCode *dic;
 
-    /* go thru till we find a definition for the
-       symbol on the right */
-    for ( dic = ic->prev ; dic ; dic = dic->prev) {
-               
-       /* if the definition is a call then no */
-       if ((dic->op == CALL || dic->op == PCALL) &&
-           IC_RESULT(dic)->key == IC_RIGHT(ic)->key) {
-           return NULL;
+  /* go thru till we find a definition for the
+     symbol on the right */
+  for (dic = ic->prev; dic; dic = dic->prev)
+    {
+
+      /* if the definition is a call then no */
+      if ((dic->op == CALL || dic->op == PCALL) &&
+         IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
+       {
+         return NULL;
        }
-       
-       /* if shift by unknown amount then not */
-       if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
-           IC_RESULT(dic)->key == IC_RIGHT(ic)->key)
-           return NULL;
 
-       /* if pointer get and size > 1 */
-       if (POINTER_GET(dic) &&
-           getSize(aggrToPtr(operandType(IC_LEFT(dic)),FALSE)) > 1)
-           return NULL ;
+      /* if shift by unknown amount then not */
+      if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
+         IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
+       return NULL;
 
-       if (POINTER_SET(dic) &&
-           getSize(aggrToPtr(operandType(IC_RESULT(dic)),FALSE)) > 1)
-           return NULL ;
+      /* if pointer get and size > 1 */
+      if (POINTER_GET (dic) &&
+         getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
+       return NULL;
 
-       /* if any three is a true symbol in far space */
-       if (IC_RESULT(dic) &&
-           IS_TRUE_SYMOP(IC_RESULT(dic)) &&
-           isOperandInFarSpace(IC_RESULT(dic)))         
-           return NULL;
+      if (POINTER_SET (dic) &&
+         getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
+       return NULL;
 
-       if (IC_RIGHT(dic) &&
-           IS_TRUE_SYMOP(IC_RIGHT(dic)) &&
-           isOperandInFarSpace(IC_RIGHT(dic)) &&
-           !isOperandEqual(IC_RIGHT(dic),IC_RESULT(ic)))
-           return NULL;
+      /* if any three is a true symbol in far space */
+      if (IC_RESULT (dic) &&
+         IS_TRUE_SYMOP (IC_RESULT (dic)) &&
+         isOperandInFarSpace (IC_RESULT (dic)))
+       return NULL;
+
+      if (IC_RIGHT (dic) &&
+         IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
+         isOperandInFarSpace (IC_RIGHT (dic)) &&
+         !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
+       return NULL;
+
+      if (IC_LEFT (dic) &&
+         IS_TRUE_SYMOP (IC_LEFT (dic)) &&
+         isOperandInFarSpace (IC_LEFT (dic)) &&
+         !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
+       return NULL;
 
-       if (IC_LEFT(dic) &&
-           IS_TRUE_SYMOP(IC_LEFT(dic)) &&
-           isOperandInFarSpace(IC_LEFT(dic)) &&
-           !isOperandEqual(IC_LEFT(dic),IC_RESULT(ic)))
+      if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
+       {
+         if ((dic->op == LEFT_OP ||
+              dic->op == RIGHT_OP ||
+              dic->op == '-') &&
+             IS_OP_LITERAL (IC_RIGHT (dic)))
            return NULL;
-       
-       if (isOperandEqual(IC_RIGHT(ic),IC_RESULT(dic))) {
-           if ( (dic->op == LEFT_OP  ||
-                 dic->op == RIGHT_OP ||
-                 dic->op == '-') &&
-                IS_OP_LITERAL(IC_RIGHT(dic)))
-               return NULL;
-           else
-               return dic;
+         else
+           return dic;
        }
     }
 
-    return NULL;
+  return NULL;
 }
 
 /*-----------------------------------------------------------------*/
 /* packRegsForAssign - register reduction for assignment           */
 /*-----------------------------------------------------------------*/
-static int packRegsForAssign (iCode *ic,eBBlock *ebp)
+static int
+packRegsForAssign (iCode * ic, eBBlock * ebp)
 {
-    iCode *dic, *sic;
-    
-    if (!IS_ITEMP(IC_RIGHT(ic))       ||       
-       OP_SYMBOL(IC_RIGHT(ic))->isind ||
-       OP_LIVETO(IC_RIGHT(ic)) > ic->seq) {
-       return 0;
+  iCode *dic, *sic;
+
+  if (!IS_ITEMP (IC_RIGHT (ic)) ||
+      OP_SYMBOL (IC_RIGHT (ic))->isind ||
+      OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
+    {
+      return 0;
     }
-       
-    /* if the true symbol is defined in far space or on stack
-       then we should not since this will increase register pressure */
-    if (isOperandInFarSpace(IC_RESULT(ic))) {
-       if ((dic = farSpacePackable(ic)))
-           goto pack;
-       else
-           return 0;
-       
+
+  /* if the true symbol is defined in far space or on stack
+     then we should not since this will increase register pressure */
+#if 0
+  if (isOperandInFarSpace (IC_RESULT (ic)))
+    {
+      if ((dic = farSpacePackable (ic)))
+       goto pack;
+      else
+       return 0;
     }
-    /* find the definition of iTempNN scanning backwards if we find a 
-       a use of the true symbol in before we find the definition then 
-       we cannot */    
-    for ( dic = ic->prev ; dic ; dic = dic->prev) {
-
-       /* if there is a function call and this is
-          a parameter & not my parameter then don't pack it */
-       if ( (dic->op == CALL || dic->op == PCALL) &&
-            (OP_SYMBOL(IC_RESULT(ic))->_isparm &&
-             !OP_SYMBOL(IC_RESULT(ic))->ismyparm)) {
-           dic = NULL;
-           break;
+#else
+  if (isOperandInFarSpace(IC_RESULT(ic)) && !farSpacePackable(ic)) {
+    return 0;
+  }
+#endif
+
+  /* find the definition of iTempNN scanning backwards if we find a 
+     a use of the true symbol in before we find the definition then 
+     we cannot */
+  for (dic = ic->prev; dic; dic = dic->prev)
+    {
+      /* if there is a function call then don't pack it */
+      if ((dic->op == CALL || dic->op == PCALL))
+       {
+         dic = NULL;
+         break;
        }
 
-       if (SKIP_IC2(dic))
-           continue;
+      if (SKIP_IC2 (dic))
+       continue;
 
-       if (IS_TRUE_SYMOP(IC_RESULT(dic)) &&
-           IS_OP_VOLATILE(IC_RESULT(dic))) {
-               dic = NULL;
-               break;
+      if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
+         IS_OP_VOLATILE (IC_RESULT (dic)))
+       {
+         dic = NULL;
+         break;
        }
 
-       if (IS_SYMOP(IC_RESULT(dic)) &&
-           IC_RESULT(dic)->key == IC_RIGHT(ic)->key) {
-           if (POINTER_SET(dic))
-               dic = NULL;
+      if (IS_SYMOP (IC_RESULT (dic)) &&
+         IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
+       {
+         if (POINTER_SET (dic))
+           dic = NULL;
 
-           break;          
+         break;
        }
 
-       if (IS_SYMOP(IC_RIGHT(dic)) && 
-           (IC_RIGHT(dic)->key == IC_RESULT(ic)->key ||
-            IC_RIGHT(dic)->key == IC_RIGHT(ic)->key)) {
-           dic = NULL;
-           break;
+      if (IS_SYMOP (IC_RIGHT (dic)) &&
+         (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
+          IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
+       {
+         dic = NULL;
+         break;
        }
-       
-       if (IS_SYMOP(IC_LEFT(dic)) && 
-           (IC_LEFT(dic)->key == IC_RESULT(ic)->key ||
-            IC_LEFT(dic)->key == IC_RIGHT(ic)->key)) {
-           dic = NULL;
-           break;
+
+      if (IS_SYMOP (IC_LEFT (dic)) &&
+         (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
+          IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
+       {
+         dic = NULL;
+         break;
        }
 
-       if (POINTER_SET(dic) && 
-           IC_RESULT(dic)->key == IC_RESULT(ic)->key ) {
-           dic = NULL ;
-           break;
+      if (POINTER_SET (dic) &&
+         IC_RESULT (dic)->key == IC_RESULT (ic)->key)
+       {
+         dic = NULL;
+         break;
        }
     }
-    
-    if (!dic)
-       return 0 ; /* did not find */
-           
-    /* if the result is on stack or iaccess then it must be
-       the same atleast one of the operands */
-    if (OP_SYMBOL(IC_RESULT(ic))->onStack  || 
-       OP_SYMBOL(IC_RESULT(ic))->iaccess ) {
-       
-       /* the operation has only one symbol
-          operator then we can pack */
-       if ((IC_LEFT(dic) && !IS_SYMOP(IC_LEFT(dic))) ||
-           (IC_RIGHT(dic) && !IS_SYMOP(IC_RIGHT(dic))))
-           goto pack;
-
-       if (!((IC_LEFT(dic) &&
-            IC_RESULT(ic)->key == IC_LEFT(dic)->key) ||
-             (IC_RIGHT(dic) &&
-              IC_RESULT(ic)->key == IC_RIGHT(dic)->key)))
-           return 0;                
+
+  if (!dic)
+    return 0;                  /* did not find */
+
+  /* if the result is on stack or iaccess then it must be
+     the same atleast one of the operands */
+  if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
+      OP_SYMBOL (IC_RESULT (ic))->iaccess)
+    {
+
+      /* the operation has only one symbol
+         operator then we can pack */
+      if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
+         (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
+       goto pack;
+
+      if (!((IC_LEFT (dic) &&
+            IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
+           (IC_RIGHT (dic) &&
+            IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
+       return 0;
     }
 pack:
-    /* found the definition */
-    /* replace the result with the result of */
-    /* this assignment and remove this assignment */
-    IC_RESULT(dic) = IC_RESULT(ic) ;
+  /* found the definition */
+  /* replace the result with the result of */
+  /* this assignment and remove this assignment */
+  bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
 
-    if (IS_ITEMP(IC_RESULT(dic)) && OP_SYMBOL(IC_RESULT(dic))->liveFrom > dic->seq) {
-           OP_SYMBOL(IC_RESULT(dic))->liveFrom = dic->seq;
+  IC_RESULT (dic) = IC_RESULT (ic);
+
+  if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
+    {
+      OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
     }
-    /* delete from liverange table also 
-       delete from all the points inbetween and the new
-       one */
-    for ( sic = dic; sic != ic ; sic = sic->next ) {   
-       bitVectUnSetBit(sic->rlive,IC_RESULT(ic)->key);
-       if (IS_ITEMP(IC_RESULT(dic)))
-           bitVectSetBit(sic->rlive,IC_RESULT(dic)->key);
+  /* delete from liverange table also 
+     delete from all the points inbetween and the new
+     one */
+  for (sic = dic; sic != ic; sic = sic->next)
+    {
+      bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
+      if (IS_ITEMP (IC_RESULT (dic)))
+       bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
     }
-        
-    remiCodeFromeBBlock(ebp,ic);
-    hTabDeleteItem (&iCodehTab,ic->key,ic,DELETE_ITEM,NULL);
-    OP_DEFS(IC_RESULT(dic)) = bitVectSetBit(OP_DEFS(IC_RESULT(dic)),dic->key);
-    return 1;
-    
+
+  remiCodeFromeBBlock (ebp, ic);
+  bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
+  hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
+  OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
+  return 1;
+
 }
 
 /*-----------------------------------------------------------------*/
-/* findAssignToSym : scanning backwards looks for first assig found*/
+/* findAssignToSym : scanning backwards looks for first assig found */
 /*-----------------------------------------------------------------*/
-static iCode *findAssignToSym (operand *op,iCode *ic)
+static iCode *
+findAssignToSym (operand * op, iCode * ic)
 {
-    iCode *dic;
+  iCode *dic;
 
-    for (dic = ic->prev ; dic ; dic = dic->prev) {
-       
-       /* if definition by assignment */
-       if (dic->op == '='                 && 
-           !POINTER_SET(dic)              &&
-           IC_RESULT(dic)->key == op->key
-/*         &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) */
-           ) {    
-
-           /* we are interested only if defined in far space */
-           /* or in stack space in case of + & - */
-
-           /* if assigned to a non-symbol then return
-              true */
-           if (!IS_SYMOP(IC_RIGHT(dic)))
-               break ;
-
-           /* if the symbol is in far space then
-              we should not */
-           if (isOperandInFarSpace(IC_RIGHT(dic)))
-               return NULL ;
-
-           /* for + & - operations make sure that
-              if it is on the stack it is the same
-              as one of the three operands */
-           if ((ic->op == '+' || ic->op == '-') &&
-               OP_SYMBOL(IC_RIGHT(dic))->onStack) {
-
-               if ( IC_RESULT(ic)->key != IC_RIGHT(dic)->key &&
-                    IC_LEFT(ic)->key   != IC_RIGHT(dic)->key &&
-                    IC_RIGHT(ic)->key  != IC_RIGHT(dic)->key)
-                   return NULL;
-           }           
-
-           break ;
-               
-       }
+  for (dic = ic->prev; dic; dic = dic->prev)
+    {
 
-       /* if we find an usage then we cannot delete it */
-       if (IC_LEFT(dic) && IC_LEFT(dic)->key == op->key)
-           return NULL;
-           
-       if (IC_RIGHT(dic) && IC_RIGHT(dic)->key == op->key)
+      /* if definition by assignment */
+      if (dic->op == '=' &&
+         !POINTER_SET (dic) &&
+         IC_RESULT (dic)->key == op->key
+/*          &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) */
+       )
+       {
+
+         /* we are interested only if defined in far space */
+         /* or in stack space in case of + & - */
+
+         /* if assigned to a non-symbol then return
+            FALSE */
+         if (!IS_SYMOP (IC_RIGHT (dic)))
            return NULL;
 
-       if (POINTER_SET(dic) && IC_RESULT(dic)->key == op->key)
+         /* if the symbol is in far space then
+            we should not */
+         if (isOperandInFarSpace (IC_RIGHT (dic)))
            return NULL;
-    }
 
-    /* now make sure that the right side of dic
-       is not defined between ic & dic */       
-    if (dic) {
-       iCode *sic = dic->next ;
+         /* for + & - operations make sure that
+            if it is on the stack it is the same
+            as one of the three operands */
+         if ((ic->op == '+' || ic->op == '-') &&
+             OP_SYMBOL (IC_RIGHT (dic))->onStack)
+           {
 
-       for (; sic != ic ; sic = sic->next)
-           if (IC_RESULT(sic) &&
-               IC_RESULT(sic)->key == IC_RIGHT(dic)->key)
+             if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
+                 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
+                 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
                return NULL;
+           }
+
+         break;
+
+       }
+
+      /* if we find an usage then we cannot delete it */
+      if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
+       return NULL;
+
+      if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
+       return NULL;
+
+      if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
+       return NULL;
     }
 
-    return dic;
-       
-       
+  /* now make sure that the right side of dic
+     is not defined between ic & dic */
+  if (dic)
+    {
+      iCode *sic = dic->next;
+
+      for (; sic != ic; sic = sic->next)
+       if (IC_RESULT (sic) &&
+           IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
+         return NULL;
+    }
+
+  return dic;
+
+
 }
 
 /*-----------------------------------------------------------------*/
 /* packRegsForSupport :- reduce some registers for support calls   */
 /*-----------------------------------------------------------------*/
-static int packRegsForSupport (iCode *ic, eBBlock *ebp)
-{
-    int change = 0 ;
-    /* for the left & right operand :- look to see if the
-       left was assigned a true symbol in far space in that
-       case replace them */
-    if (IS_ITEMP(IC_LEFT(ic)) && 
-       OP_SYMBOL(IC_LEFT(ic))->liveTo <= ic->seq) {
-       iCode *dic = findAssignToSym(IC_LEFT(ic),ic);
-       iCode *sic;
-
-       if (!dic)
-           goto right ;
-
-       /* found it we need to remove it from the
-          block */
-       for ( sic = dic; sic != ic ; sic = sic->next )
-           bitVectUnSetBit(sic->rlive,IC_LEFT(ic)->key);
-
-       IC_LEFT(ic)->operand.symOperand =
-           IC_RIGHT(dic)->operand.symOperand;
-       IC_LEFT(ic)->key = IC_RIGHT(dic)->operand.symOperand->key;
-       remiCodeFromeBBlock(ebp,dic);
-       hTabDeleteItem (&iCodehTab,dic->key,dic,DELETE_ITEM,NULL);
-       change++;      
+static int
+packRegsForSupport (iCode * ic, eBBlock * ebp)
+{    
+  int change = 0;
+  
+  /* for the left & right operand :- look to see if the
+     left was assigned a true symbol in far space in that
+     case replace them */
+  if (IS_ITEMP (IC_LEFT (ic)) &&
+      OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
+    {
+      iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
+      iCode *sic;
+
+      if (!dic)
+       goto right;
+
+      /* found it we need to remove it from the
+         block */
+      for (sic = dic; sic != ic; sic = sic->next) {
+       bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
+       sic->rlive = bitVectSetBit (sic->rlive, IC_RIGHT (dic)->key);
+      }
+
+      wassert(IS_SYMOP(IC_LEFT (ic)));
+      wassert(IS_SYMOP(IC_RIGHT (dic)));
+      IC_LEFT (ic)->operand.symOperand =
+       IC_RIGHT (dic)->operand.symOperand;
+      OP_SYMBOL(IC_LEFT(ic))->liveTo = ic->seq;
+      IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
+      bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
+      remiCodeFromeBBlock (ebp, dic);
+      hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
+      change++;
     }
-    
-    /* do the same for the right operand */
- right:    
-    if (!change && 
-       IS_ITEMP(IC_RIGHT(ic)) &&
-       OP_SYMBOL(IC_RIGHT(ic))->liveTo <= ic->seq) {
-       iCode *dic = findAssignToSym(IC_RIGHT(ic),ic);
-       iCode *sic;
-       
-       if (!dic)
-           return change ;
-
-       /* if this is a subtraction & the result
-          is a true symbol in far space then don't pack */
-       if (ic->op == '-' && IS_TRUE_SYMOP(IC_RESULT(dic))) {
-           link *etype =getSpec(operandType(IC_RESULT(dic)));
-           if (IN_FARSPACE(SPEC_OCLS(etype)))
-               return change ;
+
+  /* do the same for the right operand */
+right:
+  if (!change &&
+      IS_ITEMP (IC_RIGHT (ic)) &&
+      OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
+    {
+      iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
+      iCode *sic;
+
+      if (!dic)
+       return change;
+
+      /* if this is a subtraction & the result
+         is a true symbol in far space then don't pack */
+      if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
+       {
+         sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
+         if (IN_FARSPACE (SPEC_OCLS (etype)))
+           return change;
        }
-       /* found it we need to remove it from the
-          block */
-       for ( sic = dic; sic != ic ; sic = sic->next )
-           bitVectUnSetBit(sic->rlive,IC_RIGHT(ic)->key);
-       
-       IC_RIGHT(ic)->operand.symOperand =
-           IC_RIGHT(dic)->operand.symOperand;
-       IC_RIGHT(ic)->key = IC_RIGHT(dic)->operand.symOperand->key;
-       
-       remiCodeFromeBBlock(ebp,dic);
-       hTabDeleteItem (&iCodehTab,dic->key,dic,DELETE_ITEM,NULL);
-       change ++;
+      /* found it we need to remove it from the
+         block */
+      for (sic = dic; sic != ic; sic = sic->next) {
+       bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
+       sic->rlive = bitVectSetBit (sic->rlive, IC_RIGHT (dic)->key);
+      }
+
+      wassert(IS_SYMOP(IC_RIGHT (ic)));
+      wassert(IS_SYMOP(IC_RIGHT (dic)));       
+      IC_RIGHT (ic)->operand.symOperand =
+       IC_RIGHT (dic)->operand.symOperand;
+      IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
+      OP_SYMBOL(IC_RIGHT(ic))->liveTo = ic->seq;
+      remiCodeFromeBBlock (ebp, dic);
+      bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
+      hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
+      change++;
     }
-   
-    return change ;
+
+  return change;
 }
 
 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
 
 
 /*-----------------------------------------------------------------*/
-/* packRegsForOneuse : - will reduce some registers for single Use */ 
+/* packRegsDPTRnuse - color live ranges that can go into extra DPTRS */
 /*-----------------------------------------------------------------*/
-static iCode *packRegsForOneuse (iCode *ic, operand *op , eBBlock *ebp)
+static int packRegsDPTRnuse( operand *op , int dptr)
 {
-#if 1
-    
-    /* I can't figure out how to make this safe yet. */
-    ic; op; ebp;
-    return NULL;
-    
-    
-#else
-    bitVect *uses ;
-    iCode *dic, *sic;
+    int i,key;
+    iCode *ic;
 
-    /* if returning a literal then do nothing */
-    if (!IS_SYMOP(op))
-       return NULL;
+    if (!IS_SYMOP(op) || !IS_ITEMP(op)) return 0;
+    if (OP_SYMBOL(op)->remat || OP_SYMBOL(op)->ruonly || OP_SYMBOL(op)->dptr) 
+       return 0; 
     
-    /* only upto 2 bytes since we cannot predict
-       the usage of b, & acc */
-    if (getSize(operandType(op)) >  (fReturnSize_390 - 2) &&
-       ic->op != RETURN             &&
-       ic->op != SEND               &&
-       !POINTER_SET(ic)             &&
-       !POINTER_GET(ic))
-       return NULL;
+    /* first check if any overlapping liverange has already been
+       assigned to this DPTR */
+    if (OP_SYMBOL(op)->clashes) {
+       for (i = 0 ; i < OP_SYMBOL(op)->clashes->size ; i++ ) {
+           symbol *sym;
+           if (bitVectBitValue(OP_SYMBOL(op)->clashes,i)) {
+               sym = hTabItemWithKey(liveRanges,i);
+               if (sym->dptr == dptr) return 0;
+           }
+       }
+    }
+   
+    /* future for more dptrs */
+    if (dptr > 1) {
+       OP_SYMBOL(op)->dptr = dptr;
+       return 1;
+    }
 
-    /* this routine will mark the a symbol as used in one 
-       instruction use only && if the defintion is local 
-       (ie. within the basic block) && has only one definition &&
-       that definiion is either a return value from a 
-       function or does not contain any variables in
-       far space */
-    uses = bitVectCopy(OP_USES(op));
-    bitVectUnSetBit(uses,ic->key); /* take away this iCode */
-    if (!bitVectIsZero(uses)) /* has other uses */
-       return NULL ;
+    /* DPTR1 is special since it is also used as a scratch by the backend .
+       so we walk thru the entire live range of this operand and make sure
+       DPTR1 will not be used by the backed . The logic here is to find out if 
+       more than one operand in an icode is in far space then we give up : we 
+       don't keep it live across functions for now
+    */
     
-    /* if it has only one defintion */
-    if (bitVectnBitsOn(OP_DEFS(op)) > 1)
-       return NULL ; /* has more than one definition */
-
-    /* get the that definition */
-    if (!(dic = 
-         hTabItemWithKey(iCodehTab,
-                         bitVectFirstBit(OP_DEFS(op)))))
-       return NULL ;
-
-    /* found the definition now check if it is local */
-    if (dic->seq < ebp->fSeq ||
-       dic->seq > ebp->lSeq)
-       return NULL ; /* non-local */
-
-    /* now check if it is the return from
-       a function call */
-    if (dic->op == CALL || dic->op == PCALL ) {
-       if (ic->op != SEND && ic->op != RETURN) {
-           OP_SYMBOL(op)->ruonly = 1;
-           return dic;
+    ic = hTabFirstItemWK(iCodeSeqhTab,OP_SYMBOL(op)->liveFrom);
+    for (; ic && ic->seq <= OP_SYMBOL(op)->liveTo;
+        ic = hTabNextItem(iCodeSeqhTab,&key)) {
+       int nfs =0;
+       
+       if (ic->op == CALL || ic->op == PCALL) return 0;
+
+       /* single operand icode are ok */
+       if (ic->op == IFX || ic->op == IPUSH)
+           continue ;
+
+       if (ic->op == SEND ) {
+           if (ic->argreg != 1 ) return 0;
+           else continue ;
+       }
+       /* two special cases first */
+       if (POINTER_GET(ic) && !isOperandEqual(IC_LEFT(ic),op)  && /* pointer get */
+           !OP_SYMBOL(IC_LEFT(ic))->ruonly                     && /* with result in far space */
+           (isOperandInFarSpace(IC_RESULT(ic)) &&              
+            !isOperandInReg(IC_RESULT(ic)))) {
+           return 0;
+       }
+
+       if (POINTER_SET(ic) && !isOperandEqual(IC_RESULT(ic),op)        && /* pointer set */
+           !OP_SYMBOL(IC_RESULT(ic))->ruonly                           && /* with right in far space */
+           (isOperandInFarSpace(IC_RIGHT(ic)) &&               
+            !isOperandInReg(IC_RIGHT(ic)))) {
+           return 0;
        }
-       dic = dic->next ;
+
+       if (IC_RESULT(ic) && IS_SYMOP(IC_RESULT(ic))    && /* if symbol operand */
+           !isOperandEqual(IC_RESULT(ic),op)           && /* not the same as this */
+           ((isOperandInFarSpace(IC_RESULT(ic)) ||        /* in farspace or */
+             OP_SYMBOL(IC_RESULT(ic))->onStack)        && /* on the stack   */
+            !isOperandInReg(IC_RESULT(ic)))) {            /* and not in register */
+           nfs++;
+       }
+       /* same for left */
+       if (IC_LEFT(ic) && IS_SYMOP(IC_LEFT(ic))        && /* if symbol operand */
+           !isOperandEqual(IC_LEFT(ic),op)             && /* not the same as this */
+           ((isOperandInFarSpace(IC_LEFT(ic)) ||          /* in farspace or */
+             OP_SYMBOL(IC_LEFT(ic))->onStack)          && /* on the stack   */
+            !isOperandInReg(IC_LEFT(ic)))) {              /* and not in register */
+           nfs++;
+       }
+       /* same for right */
+       if (IC_RIGHT(ic) && IS_SYMOP(IC_RIGHT(ic))      && /* if symbol operand */
+           !isOperandEqual(IC_RIGHT(ic),op)            && /* not the same as this */
+           ((isOperandInFarSpace(IC_RIGHT(ic)) ||         /* in farspace or */
+             OP_SYMBOL(IC_RIGHT(ic))->onStack)         && /* on the stack   */
+            !isOperandInReg(IC_RIGHT(ic)))) {             /* and not in register */
+           nfs++;
+       }
+       
+       // Check that no other ops in this range have been assigned to dptr1.
+       // I don't understand why this is not caught by the first check, above.
+       // But it isn't always, see bug 769624.
+       if (IC_RESULT(ic) && IS_SYMOP(IC_RESULT(ic)) &&
+           (OP_SYMBOL(IC_RESULT(ic))->dptr == 1))
+       {           
+           //fprintf(stderr, "dptr1 already in use in live range #1\n");
+           return 0;
+       }
+       
+       if (IC_LEFT(ic) && IS_SYMOP(IC_LEFT(ic)) &&
+           (OP_SYMBOL(IC_LEFT(ic))->dptr == 1))
+       {           
+           //fprintf(stderr, "dptr1 already in use in live range # 2\n");
+           return 0;
+       }
+       
+       if (IC_RIGHT(ic) && IS_SYMOP(IC_RIGHT(ic)) &&
+           (OP_SYMBOL(IC_RIGHT(ic))->dptr == 1))
+       {           
+           //fprintf(stderr, "dptr1 already in use in live range # 3\n");
+           return 0;
+       }       
+       
+       if (nfs && IC_RESULT(ic) && IS_SYMOP(IC_RESULT(ic)) &&
+           OP_SYMBOL(IC_RESULT(ic))->ruonly) return 0;
+
+       if (nfs > 1) return 0;
     }
-        
+    OP_SYMBOL(op)->dptr = dptr;
+    return 1;
+}
+
+/*-----------------------------------------------------------------*/
+/* packRegsDPTRuse : - will reduce some registers for single Use */
+/*-----------------------------------------------------------------*/
+static iCode *
+packRegsDPTRuse (operand * op)
+{
+    /* go thru entire liveRange of this variable & check for
+       other possible usage of DPTR , if we don't find it the
+       assign this to DPTR (ruonly)
+    */
+    int i, key;
+    symbol *sym;
+    iCode *ic, *dic;
+    sym_link *type, *etype;
     
-    /* otherwise check that the definition does
-       not contain any symbols in far space */
-    if (isOperandInFarSpace(IC_LEFT(dic))  ||
-       isOperandInFarSpace(IC_RIGHT(dic)) ||
-       IS_OP_RUONLY(IC_LEFT(ic))          ||
-       IS_OP_RUONLY(IC_RIGHT(ic)) )        {
-       return NULL;
+    if (!IS_SYMOP(op) || !IS_ITEMP(op)) 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 */
+    if (OP_SYMBOL(op)->clashes) {
+       for (i = 0 ; i < OP_SYMBOL(op)->clashes->size ; i++ ) {
+           if (bitVectBitValue(OP_SYMBOL(op)->clashes,i)) {
+               sym = hTabItemWithKey(liveRanges,i);
+               if (sym->ruonly) return NULL ;
+           }
+       }
     }
-    
-    /* if pointer set then make sure the pointer
-       is one byte */
-    if (POINTER_SET(dic) && 
-       !IS_DATA_PTR(aggrToPtr(operandType(IC_RESULT(dic)),FALSE)))
-       return NULL ;
-
-    if (POINTER_GET(dic) && 
-       !IS_DATA_PTR(aggrToPtr(operandType(IC_LEFT(dic)),FALSE)))
-       return NULL ;
-    
-    sic = dic;
 
-    /* also make sure the intervenening instructions
-       don't have any thing in far space */
-    for (dic = dic->next ; dic && dic != ic ; dic = dic->next) {
-               
-       /* if there is an intervening function call then no */
-       if (dic->op == CALL || dic->op == PCALL)
-               return NULL;
-       /* if pointer set then make sure the pointer
-          is one byte */
-       if (POINTER_SET(dic) && 
-           !IS_DATA_PTR(aggrToPtr(operandType(IC_RESULT(dic)),FALSE)))
-           return NULL ;
-       
-       if (POINTER_GET(dic) && 
-           !IS_DATA_PTR(aggrToPtr(operandType(IC_LEFT(dic)),FALSE)))
+    /* no then go thru this guys live range */
+    dic = ic = hTabFirstItemWK(iCodeSeqhTab,OP_SYMBOL(op)->liveFrom);
+    for (; ic && ic->seq <= OP_SYMBOL(op)->liveTo;
+        ic = hTabNextItem(iCodeSeqhTab,&key)) {
+
+       if (SKIP_IC3(ic)) continue;
+
+       /* if PCALL cannot be sure give up */
+       if (ic->op == PCALL) return NULL;
+
+       /* if SEND & not the first parameter then giveup */
+       if (ic->op == SEND && ic->argreg != 1 &&
+           ((isOperandInFarSpace(IC_LEFT(ic))  && !isOperandInReg(IC_LEFT(ic))) || 
+            isOperandEqual(op,IC_LEFT(ic)))) return NULL;
+
+       /* if CALL then make sure it is VOID || return value not used 
+          or the return value is assigned to this one */
+       if (ic->op == CALL) {
+           if (OP_SYMBOL(IC_RESULT(ic))->liveTo == 
+               OP_SYMBOL(IC_RESULT(ic))->liveFrom) continue ;
+           etype = getSpec(type = operandType(IC_RESULT(ic)));
+           if (getSize(type) == 0 || isOperandEqual(op,IC_RESULT(ic))) 
+               continue ;
            return NULL ;
+       }
 
-       /* if address of & the result is remat the okay */
-       if (dic->op == ADDRESS_OF &&
-           OP_SYMBOL(IC_RESULT(dic))->remat)
-           continue ;
-          
-       /* if operand has size of three or more & this
-          operation is a '*','/' or '%' then 'b' may
-          cause a problem */
-       if (( dic->op == '%' || dic->op == '/' || dic->op == '*') &&
-           getSize(operandType(op)) >= 3)
-               return NULL;
+       /* special case of add with a [remat] */
+       if (ic->op == '+' && 
+           OP_SYMBOL(IC_LEFT(ic))->remat &&
+           (isOperandInFarSpace(IC_RIGHT(ic)) &&
+            !isOperandInReg(IC_RIGHT(ic)))) return NULL ;
+
+       /* special cases  */
+       /* pointerGet */
+       if (POINTER_GET(ic) && !isOperandEqual(IC_LEFT(ic),op) &&
+           getSize(operandType(IC_LEFT(ic))) > 1 ) return NULL ;
+
+       /* pointerSet */
+       if (POINTER_SET(ic) && !isOperandEqual(IC_RESULT(ic),op) &&
+           getSize(operandType(IC_RESULT(ic))) > 1 ) return NULL;
+
+       /* conditionals can destroy 'b' - make sure B wont 
+          be used in this one*/
+       if ((IS_CONDITIONAL(ic) || ic->op == '*' || ic->op == '/'  || 
+            ic->op == LEFT_OP || ic->op == RIGHT_OP ) && 
+           getSize(operandType(op)) > 3) return NULL;
+
+       /* if this is a cast to a bigger type */
+       if (ic->op==CAST) {
+         if (!IS_PTR(OP_SYM_TYPE(IC_RESULT(ic))) && 
+             getSize(OP_SYM_TYPE(IC_RESULT(ic))) >
+             getSize(OP_SYM_TYPE(IC_RIGHT(ic)))) {
+           return 0;
+         }
+       }
 
-       /* if left or right or result is in far space */
-       if (isOperandInFarSpace(IC_LEFT(dic))   ||
-           isOperandInFarSpace(IC_RIGHT(dic))  ||
-           isOperandInFarSpace(IC_RESULT(dic)) ||
-           IS_OP_RUONLY(IC_LEFT(dic))          ||
-           IS_OP_RUONLY(IC_RIGHT(dic))         ||
-           IS_OP_RUONLY(IC_RESULT(dic))            ) {
+       /* 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))->onStack) && 
+               !isOperandInReg(IC_RESULT(ic))) || 
+            OP_SYMBOL(IC_RESULT(ic))->ruonly)) 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))               ||
+            OP_SYMBOL(IC_RIGHT(ic))->ruonly) &&
+           ( ( isOperandInFarSpace(IC_RIGHT(ic)) || OP_SYMBOL(IC_RIGHT(ic))->onStack) && 
+               !isOperandInReg(IC_RIGHT(ic))) ) 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))               ||
+            OP_SYMBOL(IC_LEFT(ic))->ruonly) &&
+           ( ( isOperandInFarSpace(IC_LEFT(ic)) || OP_SYMBOL(IC_LEFT(ic))->onStack) && 
+               !isOperandInReg(IC_LEFT(ic))) ) return NULL;
+       
+       if (IC_LEFT(ic) && IC_RIGHT(ic) && 
+           IS_ITEMP(IC_LEFT(ic)) && IS_ITEMP(IC_RIGHT(ic)) &&
+           (isOperandInFarSpace(IC_LEFT(ic)) && !isOperandInReg(IC_LEFT(ic))) && 
+           (isOperandInFarSpace(IC_RIGHT(ic)) && !isOperandInReg(IC_RIGHT(ic))))
            return NULL;
-       }
     }
-               
     OP_SYMBOL(op)->ruonly = 1;
-    return sic;
-#endif 
+    if (OP_SYMBOL(op)->usl.spillLoc) {
+       if (OP_SYMBOL(op)->spillA)
+           OP_SYMBOL(op)->usl.spillLoc->allocreq--;
+       OP_SYMBOL(op)->usl.spillLoc = NULL;
+    }
+    return dic;
 }
 
 /*-----------------------------------------------------------------*/
 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
 /*-----------------------------------------------------------------*/
-static bool isBitwiseOptimizable (iCode *ic)
+static bool
+isBitwiseOptimizable (iCode * ic)
 {
-    link *ltype = getSpec(operandType(IC_LEFT(ic)));
-    link *rtype = getSpec(operandType(IC_RIGHT(ic)));
-
-    /* bitwise operations are considered optimizable
-       under the following conditions (Jean-Louis VERN) 
-       
-       x & lit
-       bit & bit
-       bit & x
-       bit ^ bit
-       bit ^ x
-       x   ^ lit
-       x   | lit
-       bit | bit
-       bit | x
-    */    
-    if ( IS_LITERAL(rtype) ||
-        (IS_BITVAR(ltype) && IN_BITSPACE(SPEC_OCLS(ltype))))
-       return TRUE ;
-    else
-       return FALSE ;    
+  sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
+  sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
+
+  /* bitwise operations are considered optimizable
+     under the following conditions (Jean-Louis VERN) 
+
+     x & lit
+     bit & bit
+     bit & x
+     bit ^ bit
+     bit ^ x
+     x   ^ lit
+     x   | lit
+     bit | bit
+     bit | x
+   */
+  if ( IS_LITERAL (rtype) ||
+      (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
+    return TRUE;
+  else
+    return FALSE;
 }
 
 /*-----------------------------------------------------------------*/
 /* packRegsForAccUse - pack registers for acc use                  */
 /*-----------------------------------------------------------------*/
-static void packRegsForAccUse (iCode *ic)
+static void
+packRegsForAccUse (iCode * ic)
 {
-    iCode *uic;
-    
-    /* if + or - then it has to be one byte result */
-    if ((ic->op == '+' || ic->op == '-')
-       && getSize(operandType(IC_RESULT(ic))) > 1)
-       return ;
-    
-    /* if shift operation make sure right side is not a literal */
-    if (ic->op == RIGHT_OP  &&
-       ( isOperandLiteral(IC_RIGHT(ic)) ||
-         getSize(operandType(IC_RESULT(ic))) > 1))
-       return ;
-       
-    if (ic->op == LEFT_OP &&        
-       ( isOperandLiteral(IC_RIGHT(ic)) ||
-         getSize(operandType(IC_RESULT(ic))) > 1))
-       return ;
-       
-    if (IS_BITWISE_OP(ic) &&
-       getSize(operandType(IC_RESULT(ic))) > 1)
-       return ;
-           
-       
-    /* has only one definition */
-    if (bitVectnBitsOn(OP_DEFS(IC_RESULT(ic))) > 1)
-       return ;
+  iCode *uic;
 
-    /* has only one use */
-    if (bitVectnBitsOn(OP_USES(IC_RESULT(ic))) > 1)
-       return ;
+  /* if this is an aggregate, e.g. a one byte char array */
+  if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
+    return;
+  }
+
+  /* if we are calling a reentrant function that has stack parameters */
+  if (ic->op == CALL &&
+       IFFUNC_ISREENT(operandType(IC_LEFT(ic))) &&
+       FUNC_HASSTACKPARM(operandType(IC_LEFT(ic))))
+      return;
+
+  if (ic->op == PCALL &&
+       IFFUNC_ISREENT(operandType(IC_LEFT(ic))->next) &&
+       FUNC_HASSTACKPARM(operandType(IC_LEFT(ic))->next))
+      return;
+
+  /* if + or - then it has to be one byte result */
+  if ((ic->op == '+' || ic->op == '-')
+      && getSize (operandType (IC_RESULT (ic))) > 1)
+    return;
 
-    /* and the usage immediately follows this iCode */
-    if (!(uic = hTabItemWithKey(iCodehTab,
-                               bitVectFirstBit(OP_USES(IC_RESULT(ic))))))
-       return ;
+  /* if shift operation make sure right side is not a literal */
+  if (ic->op == RIGHT_OP &&
+      (isOperandLiteral (IC_RIGHT (ic)) ||
+       getSize (operandType (IC_RESULT (ic))) > 1))
+    return;
 
-    if (ic->next != uic)
-       return ;
-    
-    /* if it is a conditional branch then we definitely can */
-    if (uic->op == IFX  ) 
-       goto accuse;
-
-    if ( uic->op == JUMPTABLE )
-       return ;
-
-    /* if the usage is not is an assignment
-       or an arithmetic / bitwise / shift operation then not */
-    if (POINTER_SET(uic) && 
-       getSize(aggrToPtr(operandType(IC_RESULT(uic)),FALSE)) > 1)
-       return;
-
-    if (uic->op != '=' && 
-       !IS_ARITHMETIC_OP(uic) &&
-       !IS_BITWISE_OP(uic)    &&
-       uic->op != LEFT_OP &&
-       uic->op != RIGHT_OP )
-       return;
-
-    /* if used in ^ operation then make sure right is not a 
-       literl */
-    if (uic->op == '^' && isOperandLiteral(IC_RIGHT(uic)))
-       return ;
-
-    /* if shift operation make sure right side is not a literal */
-    if (uic->op == RIGHT_OP  &&
-       ( isOperandLiteral(IC_RIGHT(uic)) ||
-         getSize(operandType(IC_RESULT(uic))) > 1))
-       return ;
-
-    if (uic->op == LEFT_OP &&        
-       ( isOperandLiteral(IC_RIGHT(uic)) ||
-         getSize(operandType(IC_RESULT(uic))) > 1))
-       return ;
-           
-    /* make sure that the result of this icode is not on the
-       stack, since acc is used to compute stack offset */
-    if (IS_TRUE_SYMOP(IC_RESULT(uic)) &&
-       OP_SYMBOL(IC_RESULT(uic))->onStack)
-       return ;
-
-    /* if either one of them in far space then we cannot */
-    if ((IS_TRUE_SYMOP(IC_LEFT(uic)) &&
-        isOperandInFarSpace(IC_LEFT(uic))) ||
-       (IS_TRUE_SYMOP(IC_RIGHT(uic)) &&
-        isOperandInFarSpace(IC_RIGHT(uic))))
-       return ;
-
-    /* if the usage has only one operand then we can */
-    if (IC_LEFT(uic) == NULL ||
-       IC_RIGHT(uic) == NULL) 
-       goto accuse;
-
-    /* make sure this is on the left side if not
-       a '+' since '+' is commutative */
-    if (ic->op != '+' &&
-       IC_LEFT(uic)->key != IC_RESULT(ic)->key)
-       return;
-
-    /* if one of them is a literal then we can */
-    if ((IC_LEFT(uic) && IS_OP_LITERAL(IC_LEFT(uic))) ||
-       (IC_RIGHT(uic) && IS_OP_LITERAL(IC_RIGHT(uic)))) {
-       OP_SYMBOL(IC_RESULT(ic))->accuse = 1;
-       return ;
-    }
+  if (ic->op == LEFT_OP &&
+      (isOperandLiteral (IC_RIGHT (ic)) ||
+       getSize (operandType (IC_RESULT (ic))) > 1))
+    return;
 
-    /* if the other one is not on stack then we can */
-    if (IC_LEFT(uic)->key == IC_RESULT(ic)->key &&
-       (IS_ITEMP(IC_RIGHT(uic)) ||
-        (IS_TRUE_SYMOP(IC_RIGHT(uic)) &&
-         !OP_SYMBOL(IC_RIGHT(uic))->onStack))) 
-       goto accuse;
-    
-    if (IC_RIGHT(uic)->key == IC_RESULT(ic)->key &&
-       (IS_ITEMP(IC_LEFT(uic)) ||
-        (IS_TRUE_SYMOP(IC_LEFT(uic)) &&
-         !OP_SYMBOL(IC_LEFT(uic))->onStack))) 
-       goto accuse ;
+  if (IS_BITWISE_OP (ic) &&
+      getSize (operandType (IC_RESULT (ic))) > 1)
+    return;
+
+
+  /* has only one definition */
+  if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
+    return;
+
+  /* has only one use */
+  if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
+    return;
+
+  /* and the usage immediately follows this iCode */
+  if (!(uic = hTabItemWithKey (iCodehTab,
+                              bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
+    return;
+
+  if (ic->next != uic)
+    return;
+
+  /* if it is a conditional branch then we definitely can */
+  if (uic->op == IFX)
+    goto accuse;
+
+  if (uic->op == JUMPTABLE)
+    return;
+
+  /* if the usage is not is an assignment
+     or an arithmetic / bitwise / shift operation then not */
+  if (POINTER_SET (uic) &&
+      getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
+    return;
+
+  if (uic->op != '=' &&
+      !IS_ARITHMETIC_OP (uic) &&
+      !IS_BITWISE_OP (uic) &&
+      uic->op != LEFT_OP &&
+      uic->op != RIGHT_OP)
+    return;
+
+  /* if used in ^ operation then make sure right is not a 
+     literl */
+  if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
+    return;
+
+  /* if shift operation make sure right side is not a literal */
+  if (uic->op == RIGHT_OP &&
+      (isOperandLiteral (IC_RIGHT (uic)) ||
+       getSize (operandType (IC_RESULT (uic))) > 1))
+    return;
+
+  if (uic->op == LEFT_OP &&
+      (isOperandLiteral (IC_RIGHT (uic)) ||
+       getSize (operandType (IC_RESULT (uic))) > 1))
+    return;
+
+  /* make sure that the result of this icode is not on the
+     stack, since acc is used to compute stack offset */
+  if (isOperandOnStack(IC_RESULT(uic)))
+    return;
+
+  /* if either one of them in far space then we cannot */
+  if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
+       isOperandInFarSpace (IC_LEFT (uic))) ||
+      (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
+       isOperandInFarSpace (IC_RIGHT (uic))))
+    return;
+
+  /* if the usage has only one operand then we can */
+  if (IC_LEFT (uic) == NULL ||
+      IC_RIGHT (uic) == NULL)
+    goto accuse;
+
+  /* make sure this is on the left side if not
+     a '+' since '+' is commutative */
+  if (ic->op != '+' &&
+      IC_LEFT (uic)->key != IC_RESULT (ic)->key)
+    return;
+
+  /* if the other one is not on stack then we can */
+  if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
+      (IS_ITEMP (IC_RIGHT (uic)) ||
+       (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
+       !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
+    goto accuse;
+
+  if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
+      (IS_ITEMP (IC_LEFT (uic)) ||
+       (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
+       !OP_SYMBOL (IC_LEFT (uic))->onStack)))
+    goto accuse;
+
+  return;
+
+accuse:
+  OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
 
-    return ;
 
- accuse:
-    OP_SYMBOL(IC_RESULT(ic))->accuse = 1;
-    
-        
 }
 
 /*-----------------------------------------------------------------*/
 /* packForPush - hueristics to reduce iCode for pushing            */
 /*-----------------------------------------------------------------*/
-static void packForPush(iCode *ic, eBBlock *ebp)
+static void
+packForPush (iCode * ic, eBBlock * ebp)
 {
-    iCode *dic;
+  iCode *dic, *lic;
+  bitVect *dbv;
 
-    if (ic->op != IPUSH || !IS_ITEMP(IC_LEFT(ic)))
-       return ;
+  if ((ic->op != IPUSH && ic->op != SEND) || !IS_ITEMP (IC_LEFT (ic)))
+    return;
 
-    /* must have only definition & one usage */
-    if (bitVectnBitsOn(OP_DEFS(IC_LEFT(ic))) != 1 ||
-       bitVectnBitsOn(OP_USES(IC_LEFT(ic))) != 1 )     
-       return ;
-    
-    /* find the definition */
-    if (!(dic = hTabItemWithKey(iCodehTab,
-                               bitVectFirstBit(OP_DEFS(IC_LEFT(ic))))))
-       return ;
+  /* must have only definition & one usage */
+  if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
+      bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
+    return;
 
-    if (dic->op != '=' || POINTER_SET(dic))
-       return;
+  /* find the definition */
+  if (!(dic = hTabItemWithKey (iCodehTab,
+                              bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
+    return;
 
-    /* we now we know that it has one & only one def & use
-       and the that the definition is an assignment */
-    IC_LEFT(ic) = IC_RIGHT(dic);
+  if (dic->op != '=' || POINTER_SET (dic))
+    return;
+  
+  if (dic->eBBlockNum != ic->eBBlockNum) return ;
+
+  /* make sure the right side does not have any definitions
+     inbetween */
+  dbv = OP_DEFS(IC_RIGHT(dic));
+  for (lic = ic; lic && lic != dic ; lic = lic->prev) {
+         if (bitVectBitValue(dbv,lic->key)) return ;
+  }
+  /* make sure they have the same type */
+  if (IS_SPEC(operandType(IC_LEFT(ic))))
+  {
+    sym_link *itype=operandType(IC_LEFT(ic));
+    sym_link *ditype=operandType(IC_RIGHT(dic));
+
+    if (SPEC_USIGN(itype)!=SPEC_USIGN(ditype) ||
+       SPEC_LONG(itype)!=SPEC_LONG(ditype))
+      return;
+  }
+  /* extend the live range of replaced operand if needed */
+  if (OP_SYMBOL(IC_RIGHT(dic))->liveTo < OP_SYMBOL(IC_LEFT(ic))->liveTo) {
+         OP_SYMBOL(IC_RIGHT(dic))->liveTo = OP_SYMBOL(IC_LEFT(ic))->liveTo;
+         OP_SYMBOL(IC_RIGHT(dic))->clashes =
+             bitVectUnion(OP_SYMBOL(IC_RIGHT(dic))->clashes,
+                          OP_SYMBOL(IC_LEFT(ic))->clashes);
+  }
+  for (lic = ic; lic && lic != dic; lic = lic->prev)
+    {
+      bitVectUnSetBit (lic->rlive, IC_LEFT (ic)->key);
+      if (IS_ITEMP (IC_RIGHT (dic)))
+       bitVectSetBit (lic->rlive, IC_RIGHT (dic)->key);
+    }
+  /* we now we know that it has one & only one def & use
+     and the that the definition is an assignment */
+  IC_LEFT (ic) = IC_RIGHT (dic);
 
-    remiCodeFromeBBlock(ebp,dic);
-    hTabDeleteItem (&iCodehTab,dic->key,dic,DELETE_ITEM,NULL);
+  remiCodeFromeBBlock (ebp, dic);
+  bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
+  hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
 }
 
 /*-----------------------------------------------------------------*/
 /* packRegisters - does some transformations to reduce register    */
 /*                   pressure                                      */
 /*-----------------------------------------------------------------*/
-static void packRegisters (eBBlock *ebp)
+static void
+packRegisters (eBBlock * ebp)
 {
-    iCode *ic ;
-    int change = 0 ;
-    
-    while (1) {
+  iCode *ic;
+  int change = 0;
 
-       change = 0;
-       
-       /* look for assignments of the form */
-       /* iTempNN = TRueSym (someoperation) SomeOperand */
-       /*       ....                       */
-       /* TrueSym := iTempNN:1             */
-       for ( ic = ebp->sch ; ic ; ic = ic->next ) {
-           
-           
-           /* find assignment of the form TrueSym := iTempNN:1 */
-           if (ic->op == '=' && !POINTER_SET(ic))
-               change += packRegsForAssign(ic,ebp);
+  while (1)
+    {
+
+      change = 0;
+
+      /* look for assignments of the form */
+      /* iTempNN = TRueSym (someoperation) SomeOperand */
+      /*       ....                       */
+      /* TrueSym := iTempNN:1             */
+      for (ic = ebp->sch; ic; ic = ic->next)
+       {
+
+
+         /* find assignment of the form TrueSym := iTempNN:1 */
+         if (ic->op == '=' && !POINTER_SET (ic))
+           change += packRegsForAssign (ic, ebp);
        }
 
-       if (!change)
-           break;
+      if (!change)
+       break;
     }
-    
-    for ( ic = ebp->sch ; ic ; ic = ic->next ) {
-               
-       /* if this is an itemp & result of a address of a true sym 
-          then mark this as rematerialisable   */
-       if (ic->op == ADDRESS_OF && 
-           IS_ITEMP(IC_RESULT(ic)) &&
-           IS_TRUE_SYMOP(IC_LEFT(ic)) &&
-            bitVectnBitsOn(OP_DEFS(IC_RESULT(ic))) == 1 &&
-           !OP_SYMBOL(IC_LEFT(ic))->onStack ) {
 
-           OP_SYMBOL(IC_RESULT(ic))->remat = 1;
-           OP_SYMBOL(IC_RESULT(ic))->rematiCode = ic;
-           OP_SYMBOL(IC_RESULT(ic))->usl.spillLoc = NULL;
+  for (ic = ebp->sch; ic; ic = ic->next)
+    {
+
+      /* if this is an itemp & result of a address of a true sym 
+         then mark this as rematerialisable   */
+      if (ic->op == ADDRESS_OF &&
+         IS_ITEMP (IC_RESULT (ic)) &&
+         IS_TRUE_SYMOP (IC_LEFT (ic)) &&
+         bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
+         !OP_SYMBOL (IC_LEFT (ic))->onStack)
+       {
+
+         OP_SYMBOL (IC_RESULT (ic))->remat = 1;
+         OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
+         OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
 
-       }
-       
-       /* if straight assignment then carry remat flag if
-          this is the only definition */
-       if (ic->op == '='    && 
-           !POINTER_SET(ic) &&
-           IS_SYMOP(IC_RIGHT(ic)) && 
-           OP_SYMBOL(IC_RIGHT(ic))->remat &&
-           bitVectnBitsOn(OP_SYMBOL(IC_RESULT(ic))->defs) <= 1) {
-
-           OP_SYMBOL(IC_RESULT(ic))->remat = 
-               OP_SYMBOL(IC_RIGHT(ic))->remat;
-           OP_SYMBOL(IC_RESULT(ic))->rematiCode = 
-               OP_SYMBOL(IC_RIGHT(ic))->rematiCode ;
        }
 
-       /* if this is a +/- operation with a rematerizable 
-          then mark this as rematerializable as well */
-       if ((ic->op == '+' || ic->op == '-') &&
-           (IS_SYMOP(IC_LEFT(ic)) && 
-            IS_ITEMP(IC_RESULT(ic)) &&
-            OP_SYMBOL(IC_LEFT(ic))->remat &&
-             bitVectnBitsOn(OP_DEFS(IC_RESULT(ic))) == 1 &&
-            IS_OP_LITERAL(IC_RIGHT(ic))) ) {
-
-           //int i = operandLitValue(IC_RIGHT(ic));
-           OP_SYMBOL(IC_RESULT(ic))->remat = 1;
-           OP_SYMBOL(IC_RESULT(ic))->rematiCode = ic;
-           OP_SYMBOL(IC_RESULT(ic))->usl.spillLoc = NULL;
+       /* if this is an itemp & used as a pointer
+          & assigned to a literal then remat */
+       if (IS_ASSIGN_ICODE(ic) && 
+           IS_ITEMP(IC_RESULT(ic)) &&
+           bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
+           isOperandLiteral(IC_RIGHT(ic))) 
+       {
+         OP_SYMBOL (IC_RESULT (ic))->remat = 1;
+         OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
+         OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;          
        }
 
-       /* mark the pointer usages */
-       if (POINTER_SET(ic))
-           OP_SYMBOL(IC_RESULT(ic))->uptr = 1;
+      /* if straight assignment then carry remat flag if
+         this is the only definition */
+      if (ic->op == '=' &&
+         !POINTER_SET (ic) &&
+         IS_SYMOP (IC_RIGHT (ic)) &&
+         OP_SYMBOL (IC_RIGHT (ic))->remat &&
+         !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode) &&
+         bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
+       {
+
+         OP_SYMBOL (IC_RESULT (ic))->remat =
+           OP_SYMBOL (IC_RIGHT (ic))->remat;
+         OP_SYMBOL (IC_RESULT (ic))->rematiCode =
+           OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
+       }
+      
+      /* if cast to a generic pointer & the pointer being
+        cast is remat, then we can remat this cast as well */
+      if (ic->op == CAST && 
+         IS_SYMOP(IC_RIGHT(ic)) &&
+         !OP_SYMBOL(IC_RESULT(ic))->isreqv &&
+         OP_SYMBOL(IC_RIGHT(ic))->remat ) {
+             sym_link *to_type = operandType(IC_LEFT(ic));
+             sym_link *from_type = operandType(IC_RIGHT(ic));
+             if (IS_GENPTR(to_type) && IS_PTR(from_type)) {                  
+                     OP_SYMBOL (IC_RESULT (ic))->remat = 1;
+                     OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
+                     OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
+             }
+      }
+
+      /* if this is a +/- operation with a rematerizable 
+         then mark this as rematerializable as well */
+      if ((ic->op == '+' || ic->op == '-') &&
+         (IS_SYMOP (IC_LEFT (ic)) &&
+          IS_ITEMP (IC_RESULT (ic)) &&
+          OP_SYMBOL (IC_LEFT (ic))->remat &&
+          (!IS_SYMOP (IC_RIGHT (ic)) || !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode)) &&
+          bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
+          IS_OP_LITERAL (IC_RIGHT (ic))))
+       {
+
+         //int i = operandLitValue(IC_RIGHT(ic));
+         OP_SYMBOL (IC_RESULT (ic))->remat = 1;
+         OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
+         OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
+       }
 
-       if (POINTER_GET(ic))
-           OP_SYMBOL(IC_LEFT(ic))->uptr = 1;
-       
-       if (!SKIP_IC2(ic)) {
-           /* if we are using a symbol on the stack
-              then we should say ds390_ptrRegReq */
-           if (ic->op == IFX && IS_SYMOP(IC_COND(ic)))
-               ds390_ptrRegReq += ((OP_SYMBOL(IC_COND(ic))->onStack ||
-                              OP_SYMBOL(IC_COND(ic))->iaccess) ? 1 : 0);
-           else
-               if (ic->op == JUMPTABLE && IS_SYMOP(IC_JTCOND(ic)))
-                   ds390_ptrRegReq += ((OP_SYMBOL(IC_JTCOND(ic))->onStack ||
-                                  OP_SYMBOL(IC_JTCOND(ic))->iaccess) ? 1 : 0);
-               else {
-                   if (IS_SYMOP(IC_LEFT(ic)))
-                       ds390_ptrRegReq += ((OP_SYMBOL(IC_LEFT(ic))->onStack ||
-                                      OP_SYMBOL(IC_LEFT(ic))->iaccess) ? 1 : 0);
-                   if (IS_SYMOP(IC_RIGHT(ic)))
-                       ds390_ptrRegReq += ((OP_SYMBOL(IC_RIGHT(ic))->onStack ||
-                                      OP_SYMBOL(IC_RIGHT(ic))->iaccess) ? 1 : 0);
-                   if (IS_SYMOP(IC_RESULT(ic)))
-                       ds390_ptrRegReq += ((OP_SYMBOL(IC_RESULT(ic))->onStack ||
-                                      OP_SYMBOL(IC_RESULT(ic))->iaccess) ? 1 : 0);    
-               }
+      /* mark the pointer usages */
+      if (POINTER_SET (ic) && IS_SYMOP (IC_RESULT (ic)))
+       OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
+
+      if (POINTER_GET (ic) && IS_SYMOP (IC_LEFT (ic)))
+       OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
+
+      if (ic->op == RETURN && IS_SYMOP (IC_LEFT(ic)))
+         OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
+
+      if (ic->op == RECEIVE && ic->argreg == 1 &&
+         IS_SYMOP (IC_RESULT (ic)) &&
+         getSize (operandType(IC_RESULT(ic))) <= 3)
+         OP_SYMBOL (IC_RESULT(ic))->uptr = 1;
+
+      if (ic->op == SEND && ic->argreg == 1 &&
+         IS_SYMOP(IC_LEFT(ic)) &&
+         getSize (aggrToPtr(operandType(IC_LEFT(ic)),FALSE)) <= 3)
+         OP_SYMBOL (IC_LEFT(ic))->uptr = 1;
+
+      if (!SKIP_IC2 (ic))
+       {
+         /* if we are using a symbol on the stack
+            then we should say ds390_ptrRegReq */
+         if (options.useXstack && ic->parmPush
+             && (ic->op == IPUSH || ic->op == IPOP))
+           ds390_ptrRegReq++;
+         if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
+                 ds390_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ? !options.stack10bit : 0) +
+                                     OP_SYMBOL (IC_COND (ic))->iaccess +
+                                     (SPEC_OCLS(OP_SYMBOL (IC_COND (ic))->etype) == idata));
+         else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
+                 ds390_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ? !options.stack10bit : 0) +
+                                     OP_SYMBOL (IC_JTCOND (ic))->iaccess +
+                                     (SPEC_OCLS(OP_SYMBOL (IC_JTCOND (ic))->etype) == idata));
+         else
+           {
+             if (IS_SYMOP (IC_LEFT (ic)))
+                     ds390_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ? !options.stack10bit : 0) +
+                                         OP_SYMBOL (IC_LEFT (ic))->iaccess +
+                                         (SPEC_OCLS(OP_SYMBOL (IC_LEFT (ic))->etype) == idata));
+             if (IS_SYMOP (IC_RIGHT (ic)))
+                     ds390_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ? !options.stack10bit : 0) +
+                                         OP_SYMBOL (IC_RIGHT (ic))->iaccess +
+                                         (SPEC_OCLS(OP_SYMBOL (IC_RIGHT (ic))->etype) == idata));
+             if (IS_SYMOP (IC_RESULT (ic)))
+                     ds390_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ? !options.stack10bit : 0) +
+                                         OP_SYMBOL (IC_RESULT (ic))->iaccess +
+                                         (SPEC_OCLS(OP_SYMBOL (IC_RESULT (ic))->etype) == idata));
+           }
        }
 
-       /* if the condition of an if instruction
-          is defined in the previous instruction then
-          mark the itemp as a conditional */
-       if ((IS_CONDITIONAL(ic) ||
-            ( ( ic->op == BITWISEAND      ||
-                ic->op == '|'             ||
-                ic->op == '^' ) &&
-              isBitwiseOptimizable(ic))) &&        
-           ic->next && ic->next->op == IFX &&
-           isOperandEqual(IC_RESULT(ic),IC_COND(ic->next)) &&
-           OP_SYMBOL(IC_RESULT(ic))->liveTo <= ic->next->seq) {
-           
-           OP_SYMBOL(IC_RESULT(ic))->regType = REG_CND;            
-           continue ;
+      /* if the condition of an if instruction
+         is defined in the previous instruction and
+        this is the only usage then
+         mark the itemp as a conditional */
+      if ((IS_CONDITIONAL (ic) ||
+          (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic))) &&
+         ic->next && ic->next->op == IFX &&
+         bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
+         isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
+         OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
+       {
+         OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
+         continue;
        }
-       
-       /* reduce for support function calls */
-       if (ic->supportRtn || ic->op == '+' || ic->op == '-' )
-           packRegsForSupport (ic,ebp);        
-       
-       /* some cases the redundant moves can
-          can be eliminated for return statements */
-       if ((ic->op == RETURN || ic->op == SEND) &&
-           !isOperandInFarSpace(IC_LEFT(ic))    &&
-           !options.model)
-           packRegsForOneuse (ic,IC_LEFT(ic),ebp);     
-
-       /* if pointer set & left has a size more than
-          one and right is not in far space */
-       if (POINTER_SET(ic)                    &&
-           !isOperandInFarSpace(IC_RIGHT(ic)) &&
-           !OP_SYMBOL(IC_RESULT(ic))->remat   &&
-           !IS_OP_RUONLY(IC_RIGHT(ic))        &&
-           getSize(aggrToPtr(operandType(IC_RESULT(ic)),FALSE)) > 1 )
-
-           packRegsForOneuse (ic,IC_RESULT(ic),ebp);
-
-       /* if pointer get */
-       if (POINTER_GET(ic)                    &&
-           !isOperandInFarSpace(IC_RESULT(ic))&&
-           !OP_SYMBOL(IC_LEFT(ic))->remat     &&
-           !IS_OP_RUONLY(IC_RESULT(ic))         &&
-           getSize(aggrToPtr(operandType(IC_LEFT(ic)),FALSE)) > 1 )
-
-           packRegsForOneuse (ic,IC_LEFT(ic),ebp);
-
-
-       /* if this is cast for intergral promotion then
-          check if only use of  the definition of the 
-          operand being casted/ if yes then replace
-          the result of that arithmetic operation with 
-          this result and get rid of the cast */
-       if (ic->op == CAST) {
-           link *fromType = operandType(IC_RIGHT(ic));
-           link *toType = operandType(IC_LEFT(ic));
-
-           if (IS_INTEGRAL(fromType) && IS_INTEGRAL(toType) &&
-               getSize(fromType) != getSize(toType) && 
-               SPEC_USIGN(fromType) == SPEC_USIGN(toType)) {
-
-               iCode *dic = packRegsForOneuse(ic,IC_RIGHT(ic),ebp);
-               if (dic) {
-                   if (IS_ARITHMETIC_OP(dic)) {
-                       IC_RESULT(dic) = IC_RESULT(ic);
-                       remiCodeFromeBBlock(ebp,ic);
-                       hTabDeleteItem (&iCodehTab,ic->key,ic,DELETE_ITEM,NULL);
-                       OP_DEFS(IC_RESULT(dic)) = bitVectSetBit(OP_DEFS(IC_RESULT(dic)),dic->key);
-                       ic = ic->prev;
-                   } else
-                       OP_SYMBOL(IC_RIGHT(ic))->ruonly =  0;
-               }               
-           } else {
-               
-               /* if the type from and type to are the same
-                  then if this is the only use then packit */
-               if (checkType(operandType(IC_RIGHT(ic)),
-                             operandType(IC_LEFT(ic))) == 1) {
-                   iCode *dic = packRegsForOneuse (ic,IC_RIGHT(ic),ebp);
-                   if (dic) {
-                       IC_RESULT(dic) = IC_RESULT(ic);
-                       remiCodeFromeBBlock(ebp,ic);
-                       hTabDeleteItem (&iCodehTab,ic->key,ic,DELETE_ITEM,NULL);
-                       OP_DEFS(IC_RESULT(dic)) = bitVectSetBit(OP_DEFS(IC_RESULT(dic)),dic->key);
-                       ic = ic->prev;
+#if 1
+      /* reduce for support function calls */
+      if (ic->supportRtn || ic->op == '+' || ic->op == '-')
+       packRegsForSupport (ic, ebp);
+#endif
+      /* some cases the redundant moves can
+         can be eliminated for return statements . Can be elminated for the first SEND */      
+      if ((ic->op == RETURN || 
+          ((ic->op == SEND || ic->op == RECEIVE)&& ic->argreg == 1)) &&          
+         !isOperandInFarSpace (IC_LEFT (ic)) &&
+         !options.model) {
+        
+         packRegsDPTRuse (IC_LEFT (ic));
+      }
+
+      if (ic->op == CALL) {
+         sym_link *ftype = operandType(IC_LEFT(ic));
+         if (getSize(operandType(IC_RESULT(ic))) <= 4 &&
+             !IFFUNC_ISBUILTIN(ftype)) {
+             packRegsDPTRuse (IC_RESULT (ic));   
+         }
+      }
+
+      /* if pointer set & left has a size more than
+         one and right is not in far space */
+      if (POINTER_SET (ic) &&
+         !isOperandInFarSpace (IC_RIGHT (ic)) &&
+         IS_SYMOP (IC_RESULT (ic)) &&
+         !OP_SYMBOL (IC_RESULT (ic))->remat &&
+         !IS_OP_RUONLY (IC_RIGHT (ic)) &&
+         getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1) {
+         
+         packRegsDPTRuse (IC_RESULT (ic));
+      }
+
+      /* if pointer get */
+      if (POINTER_GET (ic) &&
+         !isOperandInFarSpace (IC_RESULT (ic)) &&
+         IS_SYMOP (IC_LEFT (ic)) &&
+         !OP_SYMBOL (IC_LEFT (ic))->remat &&
+         !IS_OP_RUONLY (IC_RESULT (ic)) &&
+         getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1) {
+
+         packRegsDPTRuse (IC_LEFT (ic));
+      }
+
+      /* if this is cast for intergral promotion then
+         check if only use of  the definition of the 
+         operand being casted/ if yes then replace
+         the result of that arithmetic operation with 
+         this result and get rid of the cast */
+      if (ic->op == CAST)
+       {
+         sym_link *fromType = operandType (IC_RIGHT (ic));
+         sym_link *toType = operandType (IC_LEFT (ic));
+
+         if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
+             getSize (fromType) != getSize (toType) &&
+             SPEC_USIGN (fromType) == SPEC_USIGN (toType))
+           {
+
+             iCode *dic = packRegsDPTRuse (IC_RIGHT (ic));
+             if (dic)
+               {
+                 if (IS_ARITHMETIC_OP (dic))
+                   {
+                     bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
+                     IC_RESULT (dic) = IC_RESULT (ic);
+                     remiCodeFromeBBlock (ebp, ic);
+                     bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
+                     hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
+                     OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
+                     ic = ic->prev;
+                   }
+                 else
+                   OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
+               }
+           }
+         else
+           {
+
+             /* if the type from and type to are the same
+                then if this is the only use then packit */
+             if (compareType (operandType (IC_RIGHT (ic)),
+                            operandType (IC_LEFT (ic))) == 1)
+               {
+                 iCode *dic = packRegsDPTRuse (IC_RIGHT (ic));
+                 if (dic)
+                   {
+                     bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
+                     IC_RESULT (dic) = IC_RESULT (ic);
+                     remiCodeFromeBBlock (ebp, ic);
+                     bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
+                     hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
+                     OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
+                     ic = ic->prev;
                    }
                }
            }
        }
-       
-       /* pack for PUSH 
-          iTempNN := (some variable in farspace) V1
-          push iTempNN ;
-          -------------
-          push V1
-       */
-       if (ic->op == IPUSH ) {
-           packForPush(ic,ebp);
+
+      /* pack for PUSH 
+         iTempNN := (some variable in farspace) V1
+         push iTempNN ;
+         -------------
+         push V1
+       */
+      if (ic->op == IPUSH || ic->op == SEND)
+       {
+         packForPush (ic, ebp);
        }
-         
-       
-       /* pack registers for accumulator use, when the
-          result of an arithmetic or bit wise operation
-          has only one use, that use is immediately following
-          the defintion and the using iCode has only one
-          operand or has two operands but one is literal &
-          the result of that operation is not on stack then
-          we can leave the result of this operation in acc:b
-          combination */
-       if ((IS_ARITHMETIC_OP(ic) 
-            
-            || IS_BITWISE_OP(ic) 
-            
-            || ic->op == LEFT_OP || ic->op == RIGHT_OP
-            
-            ) &&
-           IS_ITEMP(IC_RESULT(ic)) &&
-           getSize(operandType(IC_RESULT(ic))) <= 2)
 
-           packRegsForAccUse (ic);
 
+      /* pack registers for accumulator use, when the
+         result of an arithmetic or bit wise operation
+         has only one use, that use is immediately following
+         the defintion and the using iCode has only one
+         operand or has two operands but one is literal &
+         the result of that operation is not on stack then
+         we can leave the result of this operation in acc:b
+         combination */
+      if ((IS_ARITHMETIC_OP (ic)
+          || IS_CONDITIONAL(ic)
+          || IS_BITWISE_OP (ic)
+          || ic->op == LEFT_OP || ic->op == RIGHT_OP 
+          || (ic->op == ADDRESS_OF && isOperandOnStack (IC_LEFT (ic)))
+         ) &&
+         IS_ITEMP (IC_RESULT (ic)) &&
+         getSize (operandType (IC_RESULT (ic))) <= 2)
+
+       packRegsForAccUse (ic);
+      
     }
 }
-  
+
 /*-----------------------------------------------------------------*/
 /* assignRegisters - assigns registers to each live range as need  */
 /*-----------------------------------------------------------------*/
-void ds390_assignRegisters (eBBlock **ebbs, int count)
+void
+ds390_assignRegisters (eBBlock ** ebbs, int count)
 {
-    iCode *ic;
-    int i ;
-
-    setToNull((void *)&_G.funcrUsed);
-    ds390_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
-    /* if not register extentions then reduce number
-       of registers */
-    if (options.regExtend)
-       ds390_nRegs = 13;
-    else
-       ds390_nRegs = 8;
-
-    /* change assignments this will remove some
-       live ranges reducing some register pressure */
-    for (i = 0 ; i < count ;i++ )
-       packRegisters (ebbs[i]);
-    
-    if (options.dump_pack)
-       dumpEbbsToFileExt(".dumppack",ebbs,count);
-
-    /* first determine for each live range the number of 
-       registers & the type of registers required for each */
-    regTypeNum ();
-    
-    /* and serially allocate registers */ 
-    serialRegAssign(ebbs,count);
-
-    /* if stack was extended then tell the user */
-    if (_G.stackExtend) {
-/*     werror(W_TOOMANY_SPILS,"stack", */
-/*            _G.stackExtend,currFunc->name,""); */
-       _G.stackExtend = 0 ;
+  iCode *ic;
+  int i;
+
+  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 = 12;
+  if (options.model != MODEL_FLAT24) options.stack10bit = 0;
+  /* change assignments this will remove some
+     live ranges reducing some register pressure */
+  for (i = 0; i < count; i++)
+    packRegisters (ebbs[i]);
+
+  /* liveranges probably changed by register packing
+     so we compute them again */
+  recomputeLiveRanges (ebbs, count);
+
+  if (options.dump_pack)
+    dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
+
+  /* first determine for each live range the number of 
+     registers & the type of registers required for each */
+  regTypeNum ();
+
+  /* and serially allocate registers */
+  serialRegAssign (ebbs, count);
+
+  ds390_nRegs = 8;
+  freeAllRegs ();
+  fillGaps();
+  ds390_nRegs = 12;
+
+  /* if stack was extended then tell the user */
+  if (_G.stackExtend)
+    {
+/*      werror(W_TOOMANY_SPILS,"stack", */
+/*             _G.stackExtend,currFunc->name,""); */
+      _G.stackExtend = 0;
     }
 
-    if (_G.dataExtend) {
-/*     werror(W_TOOMANY_SPILS,"data space", */
-/*            _G.dataExtend,currFunc->name,""); */
-       _G.dataExtend = 0 ;
-    }  
+  if (_G.dataExtend)
+    {
+/*      werror(W_TOOMANY_SPILS,"data space", */
+/*             _G.dataExtend,currFunc->name,""); */
+      _G.dataExtend = 0;
+    }
 
-    /* after that create the register mask
-       for each of the instruction */
-    createRegMask (ebbs,count);
+  /* after that create the register mask
+     for each of the instruction */
+  createRegMask (ebbs, count);
 
-    /* redo that offsets for stacked automatic variables */
+  /* redo that offsets for stacked automatic variables */
+  if (currFunc)
     redoStackOffsets ();
 
-    if (options.dump_rassgn)
-       dumpEbbsToFileExt(".dumprassgn",ebbs,count);
+  /* make sure r0 & r1 are flagged as used if they might be used */
+  /* as pointers */
+  if (currFunc && ds390_ptrRegReq)
+    {
+      currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, R0_IDX);
+      currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, R1_IDX);
+    }
+    
+  if (options.dump_rassgn) {
+    dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
+    dumpLiveRanges (DUMP_LRANGE, liveRanges);
+  }
 
-    /* do the overlaysegment stuff SDCCmem.c */
-    doOverlays(ebbs,count);
+  /* do the overlaysegment stuff SDCCmem.c */
+  doOverlays (ebbs, count);
 
-    /* now get back the chain */
-    ic = iCodeLabelOptimize(iCodeFromeBBlock (ebbs,count));
+  /* now get back the chain */
+  ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
 
 
-    gen390Code(ic);
+  gen390Code (ic);
 
-    /* free up any _G.stackSpil locations allocated */   
-    applyToSet(_G.stackSpil,deallocStackSpil);
-    _G.slocNum = 0;
-    setToNull((void **)&_G.stackSpil);
-    setToNull((void **)&_G.spiltSet);
-    /* mark all registers as free */
-    freeAllRegs();
+  /* free up any _G.stackSpil locations allocated */
+  applyToSet (_G.stackSpil, deallocStackSpil);
+  _G.slocNum = 0;
+  setToNull ((void *) &_G.stackSpil);
+  setToNull ((void *) &_G.spiltSet);
+  /* mark all registers as free */
+  ds390_nRegs = 8;
+  freeAllRegs ();
 
-    return ;
+  return;
 }