Applied patch #2762516
[fw/sdcc] / src / avr / ralloc.c
index 87b84ef7eb276948c988b68ad150a7916232194d..512edc4fdf7f068101e6c1677cfac87a316ef301 100644 (file)
@@ -55,38 +55,38 @@ int avr_ptrRegReq;          /* pointer register required */
 
 /* AVR registers */
 regs regsAVR[] = {
-       {REG_GPR, R0_IDX, REG_GPR, "r0", "r0", "", 0, 0, 0},    /* scratch */
-       {REG_GPR, R1_IDX, REG_GPR, "r1", "r1", "", 0, 0, 0},    /* scratch */
-       {REG_GPR, R2_IDX, REG_GPR, "r2", "r2", "", 0, 1, 1},    /* gpr */
-       {REG_GPR, R3_IDX, REG_GPR, "r3", "r3", "", 0, 1, 1},    /* gpr */
-       {REG_GPR, R4_IDX, REG_GPR, "r4", "r4", "", 0, 1, 1},    /* gpr */
-       {REG_GPR, R5_IDX, REG_GPR, "r5", "r5", "", 0, 1, 1},    /* gpr */
-       {REG_GPR, R6_IDX, REG_GPR, "r6", "r6", "", 0, 1, 1},    /* gpr */
-       {REG_GPR, R7_IDX, REG_GPR, "r7", "r7", "", 0, 1, 1},    /* gpr */
-       {REG_GPR, R8_IDX, REG_GPR, "r8", "r8", "", 0, 1, 1},    /* gpr */
-       {REG_GPR, R9_IDX, REG_GPR, "r9", "r9", "", 0, 1, 1},    /* gpr */
-       {REG_GPR, R10_IDX, REG_GPR, "r10", "r10", "", 0, 1, 1}, /* gpr */
-       {REG_GPR, R11_IDX, REG_GPR, "r11", "r11", "", 0, 1, 1}, /* gpr */
-       {REG_GPR, R12_IDX, REG_GPR, "r12", "r12", "", 0, 1, 1}, /* gpr */
-       {REG_GPR, R13_IDX, REG_GPR, "r13", "r13", "", 0, 1, 1}, /* gpr */
-       {REG_GPR, R14_IDX, REG_GPR, "r14", "r14", "", 0, 1, 1}, /* gpr */
-       {REG_GPR, R15_IDX, REG_GPR, "r15", "r15", "", 0, 1, 1}, /* gpr */
-       {REG_GPR, R16_IDX, REG_GPR, "r16", "r16", "", 0, 1, 0}, /* parm/gpr */
-       {REG_GPR, R17_IDX, REG_GPR, "r17", "r17", "", 0, 1, 0}, /* parm/gpr */
-       {REG_GPR, R18_IDX, REG_GPR, "r18", "r18", "", 0, 1, 0}, /* parm/gpr */
-       {REG_GPR, R19_IDX, REG_GPR, "r19", "r19", "", 0, 1, 0}, /* parm/gpr */
-       {REG_GPR, R20_IDX, REG_GPR, "r20", "r20", "", 0, 1, 0}, /* parm/gpr */
-       {REG_GPR, R21_IDX, REG_GPR, "r21", "r21", "", 0, 1, 0}, /* parm/gpr */
-       {REG_GPR, R22_IDX, REG_GPR, "r22", "r22", "", 0, 1, 0}, /* parm/gpr */
-       {REG_GPR, R23_IDX, REG_GPR, "r23", "r23", "", 0, 1, 0}, /* parm/gpr */
-       {REG_GPR, R24_IDX, REG_GPR, "r24", "r24", "", 0, 0, 0}, /* scratch  */
-       {REG_GPR, R25_IDX, REG_GPR, "r25", "r25", "", 0, 0, 0}, /* scratch */
-       {REG_GPR, R26_IDX, REG_GPR, "r26", "r26", "", 0, 1, 1}, /* used as pointer reg X */
-       {REG_GPR, R27_IDX, REG_GPR, "r27", "r27", "", 0, 1, 1}, /* used as pointer reg X */
-       {REG_GPR, R28_IDX, REG_GPR, "r28", "r28", "", 0, 1, 0}, /* stack frame Y */
-       {REG_GPR, R29_IDX, REG_GPR, "r29", "r29", "", 0, 1, 0}, /* stack frame Y */
-       {REG_GPR, R30_IDX, REG_GPR, "r30", "r30", "", 0, 1, 1}, /* used as pointer reg Z */
-       {REG_GPR, R31_IDX, REG_GPR, "r31", "r31", "", 0, 1, 1}, /* used as pointer reg Z */
+       {REG_GPR|REG_PAIR, R0_IDX, REG_GPR|REG_PAIR, "r0", "r0", "", 0, 0, 0},  /* scratch */
+       {REG_GPR, R1_IDX, REG_GPR         , "r1", "r1", "", 0, 0, 0},           /* scratch */
+       {REG_GPR|REG_PAIR, R2_IDX, REG_GPR|REG_PAIR, "r2", "r2", "", 0, 1, 1},  /* gpr */
+       {REG_GPR, R3_IDX, REG_GPR         , "r3", "r3", "", 0, 1, 1},           /* gpr */
+       {REG_GPR|REG_PAIR, R4_IDX, REG_GPR|REG_PAIR, "r4", "r4", "", 0, 1, 1},  /* gpr */
+       {REG_GPR, R5_IDX, REG_GPR         , "r5", "r5", "", 0, 1, 1},           /* gpr */
+       {REG_GPR|REG_PAIR, R6_IDX, REG_GPR|REG_PAIR, "r6", "r6", "", 0, 1, 1},  /* gpr */
+       {REG_GPR, R7_IDX, REG_GPR         , "r7", "r7", "", 0, 1, 1},           /* gpr */
+       {REG_GPR|REG_PAIR, R8_IDX, REG_GPR|REG_PAIR, "r8", "r8", "", 0, 1, 1},  /* gpr */
+       {REG_GPR, R9_IDX, REG_GPR         , "r9", "r9", "", 0, 1, 1},           /* gpr */
+       {REG_GPR|REG_PAIR, R10_IDX,REG_GPR|REG_PAIR, "r10", "r10","",0, 1, 1},  /* gpr */
+       {REG_GPR, R11_IDX,REG_GPR         , "r11", "r11","",0, 1, 1},           /* gpr */
+       {REG_GPR|REG_PAIR, R12_IDX,REG_GPR|REG_PAIR, "r12", "r12","",0, 1, 1},  /* gpr */
+       {REG_GPR, R13_IDX,REG_GPR         , "r13", "r13","",0, 1, 1},           /* gpr */
+       {REG_GPR|REG_PAIR, R14_IDX,REG_GPR|REG_PAIR, "r14", "r14","",0, 1, 1},  /* gpr */
+       {REG_GPR, R15_IDX,REG_GPR         , "r15", "r15","",0, 1, 1},           /* gpr */
+       {REG_GPR|REG_PAIR, R16_IDX,REG_GPR|REG_PAIR, "r16", "r16","",0, 1, 0},  /* parm/gpr */
+       {REG_GPR, R17_IDX,REG_GPR         , "r17", "r17","",0, 1, 0},           /* parm/gpr */
+       {REG_GPR|REG_PAIR, R18_IDX,REG_GPR|REG_PAIR, "r18", "r18","",0, 1, 0},  /* parm/gpr */
+       {REG_GPR, R19_IDX,REG_GPR         , "r19", "r19","",0, 1, 0},           /* parm/gpr */
+       {REG_GPR|REG_PAIR, R20_IDX,REG_GPR|REG_PAIR, "r20", "r20","",0, 1, 0},  /* parm/gpr */
+       {REG_GPR, R21_IDX,REG_GPR         , "r21", "r21","",0, 1, 0},           /* parm/gpr */
+       {REG_GPR|REG_PAIR, R22_IDX,REG_GPR|REG_PAIR, "r22", "r22","",0, 1, 0},  /* parm/gpr */
+       {REG_GPR, R23_IDX,REG_GPR         , "r23", "r23","",0, 1, 0},           /* parm/gpr */
+       {REG_GPR|REG_PAIR, R24_IDX,REG_GPR|REG_PAIR, "r24", "r24","",0, 0, 0},  /* scratch  */
+       {REG_GPR, R25_IDX,REG_GPR         , "r25", "r25","",0, 0, 0},           /* scratch */
+       {REG_GPR|REG_PAIR, R26_IDX,REG_GPR|REG_PAIR, "r26", "r26","",0, 1, 1},  /* used as pointer reg X */
+       {REG_GPR, R27_IDX,REG_GPR         , "r27", "r27","",0, 1, 1},           /* used as pointer reg X */
+       {REG_GPR|REG_PAIR, R28_IDX,REG_GPR|REG_PAIR, "r28", "r28","",0, 1, 0},  /* stack frame Y */
+       {REG_GPR, R29_IDX,REG_GPR         , "r29", "r29","",0, 1, 0},           /* stack frame Y */
+       {REG_GPR|REG_PAIR, R30_IDX,REG_GPR|REG_PAIR, "r30", "r30","",0, 1, 1},  /* used as pointer reg Z */
+       {REG_GPR, R31_IDX,REG_GPR         , "r31", "r31","",0, 1, 1},           /* used as pointer reg Z */
        {REG_PTR, X_IDX, REG_PTR, "X", "X", "", 0, 1, 0},
        {REG_PTR, Z_IDX, REG_PTR, "Z", "Z", "", 0, 1, 0},
 };
@@ -95,6 +95,343 @@ int avr_fReg = 0;           /* first allocatable register */
 
 static void spillThis (symbol *);
 
+#if 0
+// PENDING: Unused
+/*-----------------------------------------------------------------*/
+/* findAssignToSym : scanning backwards looks for first assig found */
+/*-----------------------------------------------------------------*/
+static iCode *
+findAssignToSym (operand * op, iCode * ic)
+{
+       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;
+
+               }
+
+               /* 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;
+       }
+
+       /* 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;
+
+
+}
+
+/*-----------------------------------------------------------------*/
+/* packForPush - hueristics to reduce iCode for pushing            */
+/*-----------------------------------------------------------------*/
+static void
+packForPush (iCode * ic, eBBlock * ebp)
+{
+       iCode *dic;
+
+       if (ic->op != IPUSH || !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;
+
+       if (dic->op != '=' || POINTER_SET (dic))
+               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);
+
+       remiCodeFromeBBlock (ebp, dic);
+       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
+}
+
+/*-----------------------------------------------------------------*/
+/* 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++;
+       }
+
+       /* 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++;
+       }
+
+       return change;
+}
+
+/*-----------------------------------------------------------------*/
+/* farSpacePackable - returns the packable icode for far variables */
+/*-----------------------------------------------------------------*/
+static iCode *
+farSpacePackable (iCode * ic)
+{
+       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;
+               }
+
+               /* 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 (POINTER_SET (dic) &&
+                   getSize (aggrToPtr (operandType (IC_RESULT (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 (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 (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;
+               }
+       }
+
+       return NULL;
+}
+
+/*-----------------------------------------------------------------*/
+/* rematStr - returns the rematerialized string for a remat var    */
+/*-----------------------------------------------------------------*/
+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;
+       }
+
+       return buffer;
+}
+
+/*-----------------------------------------------------------------*/
+/* isSpiltOnStack - returns true if the spil location is on stack  */
+/*-----------------------------------------------------------------*/
+static bool
+isSpiltOnStack (symbol * sym)
+{
+       sym_link *etype;
+
+       if (!sym)
+               return FALSE;
+
+       if (!sym->isspilt)
+               return FALSE;
+
+
+       if (!sym->usl.spillLoc)
+               return FALSE;
+
+       etype = getSpec (sym->usl.spillLoc->type);
+       if (IN_STACK (etype))
+               return TRUE;
+
+       return FALSE;
+}
+
+/*-----------------------------------------------------------------*/
+/* spillLRWithPtrReg :- will spil those live ranges which use PTR  */
+/*-----------------------------------------------------------------*/
+static void
+spillLRWithPtrReg (symbol * forSym)
+{
+       symbol *lrsym;
+       regs *X, *Z, *X1, *Z1;
+       int k;
+
+       if (!_G.regAssigned || bitVectIsZero (_G.regAssigned))
+               return;
+
+       X = avr_regWithIdx (R26_IDX);
+       X1= avr_regWithIdx (R27_IDX);
+       Z = avr_regWithIdx (R30_IDX);
+       Z1= avr_regWithIdx (R31_IDX);
+
+       /* 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] == X || lrsym->regs[j] == Z ||
+                           lrsym->regs[j] == X1 || lrsym->regs[j] == Z1) {
+                               spillThis (lrsym);
+                               break;
+                       }
+       }
+
+}
+#endif
+
 /*-----------------------------------------------------------------*/
 /* allocReg - allocates register of given type                     */
 /*-----------------------------------------------------------------*/
@@ -114,9 +451,10 @@ allocReg (short type)
                                        bitVectSetBit (currFunc->regsUsed, i);
                        return &regsAVR[i];
                }
+
                /* other wise look for specific type
                   of register */
-               if (regsAVR[i].isFree && regsAVR[i].type == type) {
+               if (regsAVR[i].isFree && (regsAVR[i].type & type)) {
                        regsAVR[i].isFree = 0;
                        if (currFunc)
                                currFunc->regsUsed =
@@ -127,6 +465,34 @@ allocReg (short type)
        return NULL;
 }
 
+/*-----------------------------------------------------------------*/
+/* allocRegPair - allocates register pair of given                 */
+/*-----------------------------------------------------------------*/
+static regs *
+allocRegPair (short type)
+{
+       int i;
+
+       for (i = avr_fReg; i < avr_nRegs; i++) {
+
+               /* look for specific type of register pair */
+               if (regsAVR[i].isFree && (regsAVR[i].type & type) 
+                   && (regsAVR[i].type & REG_PAIR) && regsAVR[i+1].isFree) {
+
+                       regsAVR[i].isFree = 0;
+                       regsAVR[i+1].isFree = 0;
+                       if (currFunc) {
+                               currFunc->regsUsed =
+                                       bitVectSetBit (currFunc->regsUsed, i);
+                               currFunc->regsUsed =
+                                       bitVectSetBit (currFunc->regsUsed, i+1);
+                       }
+                       return &regsAVR[i];
+               }
+       }
+       return NULL;
+}
+
 /*-----------------------------------------------------------------*/
 /* avr_regWithIdx - returns pointer to register wit index number   */
 /*-----------------------------------------------------------------*/
@@ -163,7 +529,7 @@ nFreeRegs (int type)
        int nfr = 0;
 
        for (i = avr_fReg; i < avr_nRegs; i++)
-               if (regsAVR[i].isFree && regsAVR[i].type == type)
+               if (regsAVR[i].isFree && regsAVR[i].type & type)
                        nfr++;
        return nfr;
 }
@@ -183,31 +549,6 @@ nfreeRegsType (int type)
        return nFreeRegs (type);
 }
 
-
-/*-----------------------------------------------------------------*/
-/* allDefsOutOfRange - all definitions are out of a range          */
-/*-----------------------------------------------------------------*/
-static bool
-allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
-{
-       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;
-}
-
 /*-----------------------------------------------------------------*/
 /* computeSpillable - given a point find the spillable live ranges */
 /*-----------------------------------------------------------------*/
@@ -269,16 +610,6 @@ 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));
-}
-
 /*-----------------------------------------------------------------*/
 /* notUsedInRemaining - not used or defined in remain of the block */
 /*-----------------------------------------------------------------*/
@@ -361,7 +692,7 @@ leastUsedLR (set * sset)
 
        }
 
-       setToNull ((void **) &sset);
+       setToNull ((void *) &sset);
        sym->blockSpil = 0;
        return sym;
 }
@@ -413,49 +744,6 @@ DEFSETFUNC (isFree)
        return 0;
 }
 
-/*-----------------------------------------------------------------*/
-/* spillLRWithPtrReg :- will spil those live ranges which use PTR  */
-/*-----------------------------------------------------------------*/
-static void
-spillLRWithPtrReg (symbol * forSym)
-{
-       symbol *lrsym;
-       regs *X, *Z, *X1, *Z1;
-       int k;
-
-       if (!_G.regAssigned || bitVectIsZero (_G.regAssigned))
-               return;
-
-       X = avr_regWithIdx (R26_IDX);
-       X1= avr_regWithIdx (R27_IDX);
-       Z = avr_regWithIdx (R30_IDX);
-       Z1= avr_regWithIdx (R31_IDX);
-
-       /* 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] == X || lrsym->regs[j] == Z ||
-                           lrsym->regs[j] == X1 || lrsym->regs[j] == Z1) {
-                               spillThis (lrsym);
-                               break;
-                       }
-       }
-
-}
-
 /*-----------------------------------------------------------------*/
 /* createStackSpil - create a location on the stack to spil        */
 /*-----------------------------------------------------------------*/
@@ -541,31 +829,6 @@ createStackSpil (symbol * sym)
        return sym;
 }
 
-/*-----------------------------------------------------------------*/
-/* isSpiltOnStack - returns true if the spil location is on stack  */
-/*-----------------------------------------------------------------*/
-static bool
-isSpiltOnStack (symbol * sym)
-{
-       sym_link *etype;
-
-       if (!sym)
-               return FALSE;
-
-       if (!sym->isspilt)
-               return FALSE;
-
-
-       if (!sym->usl.spillLoc)
-               return FALSE;
-
-       etype = getSpec (sym->usl.spillLoc->type);
-       if (IN_STACK (etype))
-               return TRUE;
-
-       return FALSE;
-}
-
 /*-----------------------------------------------------------------*/
 /* spillThis - spils a specific operand                            */
 /*-----------------------------------------------------------------*/
@@ -638,7 +901,8 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
                /* check if there are any live ranges that not
                   used in the remainder of the block */
                if (!_G.blockSpil &&
-                   (selectS =
+                   !isiCodeInFunctionCall (ic) &&
+                    (selectS =
                     liveRangesWith (lrcs, notUsedInRemaining, ebp, ic))) {
                        sym = leastUsedLR (selectS);
                        if (sym != forSym) {
@@ -753,10 +1017,14 @@ getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
 
       tryAgain:
        /* try for a ptr type */
-       if ((reg = allocReg (REG_PTR)))
+       if ((reg = allocReg (REG_PTR|REG_PAIR)))
                return reg;
 
-       /* try for gpr type */
+       /* try for gpr type / pair */
+       if ((reg = allocReg (REG_GPR|REG_PAIR)))
+               return reg;
+
+       /* try for gpr type  */
        if ((reg = allocReg (REG_GPR)))
                return reg;
 
@@ -778,11 +1046,11 @@ getRegScr (iCode * ic, eBBlock * ebp, symbol * sym)
        regs *reg;
 
       tryAgain:
-       /* try for a ptr type */
+
+       /* try for a scratch non-pair */        
        if ((reg = allocReg (REG_SCR)))
                return reg;
-
-       /* try for gpr type */
+                               
        if ((reg = allocReg (REG_GPR)))
                return reg;
 
@@ -799,7 +1067,7 @@ getRegScr (iCode * ic, eBBlock * ebp, symbol * sym)
 /* getRegGpr - will try for GPR if not spil                        */
 /*-----------------------------------------------------------------*/
 static regs *
-getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
+getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym )
 {
        regs *reg;
 
@@ -876,7 +1144,7 @@ deassignLRs (iCode * ic, eBBlock * ebp)
                    ic->prev->op == IPOP &&
                    !ic->prev->parmPush &&
                    !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
-                               psym = OP_SYMBOL (IC_LEFT (ic->prev));
+                       psym = OP_SYMBOL (IC_LEFT (ic->prev));
 
                if (sym->nRegs) {
                        int i = 0;
@@ -896,6 +1164,7 @@ deassignLRs (iCode * ic, eBBlock * ebp)
                            (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->liveFrom == ic->seq &&    /* does not start before here */
                            result->regType == sym->regType &&  /* same register types */
                            result->nRegs &&    /* which needs registers */
                            !result->isspilt && /* and does not already have them */
@@ -903,25 +1172,17 @@ deassignLRs (iCode * ic, eBBlock * ebp)
                            !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 if (result->regType == REG_SCR)
-                                               result->regs[i] =
-                                                       getRegScr (ic, ebp,
-                                                                  result);
-                                       else
-                                               result->regs[i] =
-                                                       getRegGpr (ic, ebp,
-                                                                  result);
+                           ((nfreeRegsType (result->regType) + sym->nRegs) >= result->nRegs)) {
 
-                               _G.regAssigned =
-                                       bitVectSetBit (_G.regAssigned,
-                                                      result->key);
+                               for (i = 0; i < result->nRegs; i++) {
+                                       if (i < sym->nRegs) 
+                                               result->regs[i] = sym->regs[i];
+                                       else if (result->regType == REG_SCR) 
+                                               result->regs[i] = getRegScr (ic, ebp, result);
+                                       else
+                                               result->regs[i] = getRegGpr (ic, ebp, result);
+                               }
+                               _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
 
                        }
 
@@ -931,8 +1192,7 @@ deassignLRs (iCode * ic, eBBlock * ebp)
                                        if (!symHasReg (psym, sym->regs[i]))
                                                freeReg (sym->regs[i]);
                                }
-                               else
-                                       freeReg (sym->regs[i]);
+                               else freeReg (sym->regs[i]);
                        }
                }
        }
@@ -992,22 +1252,6 @@ willCauseSpill (int nr, int rt)
        return 1;
 }
 
-/*-----------------------------------------------------------------*/
-/* makeRegPair - if two registers then try to make a pair          */
-/*-----------------------------------------------------------------*/
-static void makeRegPair (operand *op)
-{
-       symbol *opsym = OP_SYMBOL(op);
-
-       if (opsym->isspilt || opsym->nRegs != 2)
-               return; 
-       if ((opsym->regs[0] - opsym->regs[1]) == 1) {
-               regs *tmp = opsym->regs[0];
-               opsym->regs[0] = opsym->regs[1];
-               opsym->regs[1] = tmp;
-       }
-}
-
 /*-----------------------------------------------------------------*/
 /* positionRegs - the allocator can allocate same registers to res- */
 /* ult and operand, if this happens make sure they are in the same */
@@ -1042,6 +1286,34 @@ positionRegs (symbol * result, symbol * opsym, int lineno)
        }       
 }
 
+/*-----------------------------------------------------------------*/
+/* needsPair - heuristic to determine if a pair would be good      */
+/*-----------------------------------------------------------------*/
+static int needsPair (iCode *ic)
+{
+       symbol *sym = OP_SYMBOL(IC_RESULT(ic));
+       bitVect *uses_defs = 
+               bitVectUnion(OP_USES (IC_RESULT(ic)),OP_DEFS(IC_RESULT(ic)));
+       
+       /* if size is less than 2 then NO */
+       if (sym->nRegs < 2) return 0;
+       /* if type Pointer then YES */
+       if (IS_PTR(sym->type)) return 1;
+       
+       /* go thru the usages of this operand if used with 
+          a constant then yes */
+       while (!bitVectIsZero(uses_defs)) {
+               int ikey = bitVectFirstBit(uses_defs);
+               iCode *uic = hTabItemWithKey(iCodehTab,ikey);
+               sym_link *otype = NULL; 
+               bitVectUnSetBit(uses_defs,ikey);
+               if (!uic) continue;             
+               otype = (IC_RIGHT(uic) ? operandType(IC_RIGHT(uic)) : NULL);
+               if (otype && IS_LITERAL(otype)) return 1;
+       }
+       return 0;       
+}
+
 /*-----------------------------------------------------------------*/
 /* serialRegAssign - serially allocate registers to the variables  */
 /*-----------------------------------------------------------------*/
@@ -1091,7 +1363,13 @@ serialRegAssign (eBBlock ** ebbs, int count)
                                symbol *sym = OP_SYMBOL (IC_RESULT (ic));
                                bitVect *spillable;
                                int willCS;
-                               int j;
+                               int j=0;
+
+                               /* Make sure any spill location is definately allocated */
+                               if (sym->isspilt && !sym->remat && sym->usl.spillLoc &&
+                                   !sym->usl.spillLoc->allocreq) {
+                                       sym->usl.spillLoc->allocreq++;
+                               }
 
                                /* if it does not need or is spilt 
                                   or is already assigned to registers
@@ -1118,49 +1396,67 @@ serialRegAssign (eBBlock ** ebbs, int count)
                                        willCauseSpill (sym->nRegs,
                                                        sym->regType);
                                spillable = computeSpillable (ic);
-                               if (sym->remat ||
-                                   (willCS && bitVectIsZero (spillable))) {
-
+                               if (sym->remat || (willCS && bitVectIsZero (spillable))) {
                                        spillThis (sym);
                                        continue;
+                               }
 
+                               /* If the live range preceeds the point of definition 
+                                  then ideally we must take into account registers that 
+                                  have been allocated after sym->liveFrom but freed
+                                  before ic->seq. This is complicated, so spill this
+                                  symbol instead and let fillGaps handle the allocation. */
+                               if (sym->liveFrom < ic->seq)
+                               {
+                                       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 (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)) {
+                                                       spillThis (sym);
+                                                       continue;
+                                               }
                                        }
                                }
 
                                /* we assign registers to it */
                                _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
-
-                               for (j = 0; j < sym->nRegs; j++) {
+                               if (needsPair(ic)) {
+                                       short regtype ;
+                                       regs *preg;
+                                       if (sym->regType == REG_PTR) regtype = REG_PTR;
+                                       else if (sym->regType == REG_SCR) regtype = REG_SCR;
+                                       else regtype = REG_GPR;
+                                       preg = allocRegPair(regtype);
+                                       if (preg) {
+                                               sym->regs[j++] = preg;
+                                               sym->regs[j++] = &regsAVR[preg->rIdx+1];
+                                       }
+                               }
+                               for (; j < sym->nRegs; j++) {
                                        if (sym->regType == REG_PTR)
                                                sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
                                        else if (sym->regType == REG_SCR)
                                                sym->regs[j] = getRegScr (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 (!sym->regs[j]) break;
                                }
-                               /* make the registers a pair */
-                               makeRegPair(IC_RESULT(ic));
 
                                /* if it shares registers with operands make sure
                                   that they are in the same position */
@@ -1168,16 +1464,12 @@ serialRegAssign (eBBlock ** ebbs, int count)
                                    OP_SYMBOL (IC_LEFT (ic))->nRegs
                                    && ic->op != '=')
                                        positionRegs (OP_SYMBOL (IC_RESULT (ic)),
-                                                     OP_SYMBOL (IC_LEFT
-                                                                (ic)),
-                                                     ic->lineno);
+                                                     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);
+                                                     OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
 
                        }
                }
@@ -1309,48 +1601,21 @@ createRegMask (eBBlock ** ebbs, int count)
                                /* 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);
+                                               int rIdx = sym->regs[k]->rIdx;
+                                               ic->rMask = bitVectSetBit (ic-> rMask,rIdx);
                                                /* special case for X & Z registers */
-                                               if (k == R26_IDX || k == R27_IDX) 
+                                               if (rIdx == R26_IDX || rIdx == R27_IDX) 
                                                        ic->rMask = bitVectSetBit (ic->rMask, X_IDX);
-                                               if (k == R30_IDX || k == R31_IDX) 
+                                               if (rIdx == R30_IDX || rIdx == R31_IDX) 
                                                        ic->rMask = bitVectSetBit (ic->rMask, Z_IDX);
                                        }
-                               }
-                       }
-               }
-       }
-}
-
-/*-----------------------------------------------------------------*/
-/* rematStr - returns the rematerialized string for a remat var    */
-/*-----------------------------------------------------------------*/
-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;
        }
-
-       return buffer;
 }
 
+
 /*-----------------------------------------------------------------*/
 /* regTypeNum - computes the type & number of registers required   */
 /*-----------------------------------------------------------------*/
@@ -1392,9 +1657,7 @@ regTypeNum ()
                           in "data" space */
 
                        if (bitVectnBitsOn (sym->defs) == 1 &&
-                           (ic = hTabItemWithKey (iCodehTab,
-                                                  bitVectFirstBit (sym->
-                                                                   defs)))
+                           (ic = hTabItemWithKey (iCodehTab, bitVectFirstBit (sym-> defs)))
                            && POINTER_GET (ic) && !IS_BITVAR (sym->etype)) {
 
                                /* if in data space or idata space then try to
@@ -1453,70 +1716,6 @@ DEFSETFUNC (deallocStackSpil)
        return 0;
 }
 
-/*-----------------------------------------------------------------*/
-/* farSpacePackable - returns the packable icode for far variables */
-/*-----------------------------------------------------------------*/
-static iCode *
-farSpacePackable (iCode * ic)
-{
-       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;
-               }
-
-               /* 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 (POINTER_SET (dic) &&
-                   getSize (aggrToPtr (operandType (IC_RESULT (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 (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 (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;
-               }
-       }
-
-       return NULL;
-}
-
 /*-----------------------------------------------------------------*/
 /* packRegsForAssign - register reduction for assignment           */
 /*-----------------------------------------------------------------*/
@@ -1630,148 +1829,6 @@ packRegsForAssign (iCode * ic, eBBlock * ebp)
 
 }
 
-/*-----------------------------------------------------------------*/
-/* findAssignToSym : scanning backwards looks for first assig found */
-/*-----------------------------------------------------------------*/
-static iCode *
-findAssignToSym (operand * op, iCode * ic)
-{
-       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;
-
-               }
-
-               /* 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;
-       }
-
-       /* 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++;
-       }
-
-       /* 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++;
-       }
-
-       return change;
-}
-
-#define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
-
 
 /*-----------------------------------------------------------------*/
 /* packRegsForOneuse : - will reduce some registers for single Use */
@@ -1817,7 +1874,8 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
        /* 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) {
+               if (ic->op != SEND && ic->op != RETURN &&
+                   !POINTER_SET(ic) && !POINTER_GET(ic)) {
                        OP_SYMBOL (op)->ruonly = 1;
                        return dic;
                }
@@ -1915,39 +1973,6 @@ isBitwiseOptimizable (iCode * ic)
                return FALSE;
 }
 
-/*-----------------------------------------------------------------*/
-/* packForPush - hueristics to reduce iCode for pushing            */
-/*-----------------------------------------------------------------*/
-static void
-packForPush (iCode * ic, eBBlock * ebp)
-{
-       iCode *dic;
-
-       if (ic->op != IPUSH || !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;
-
-       if (dic->op != '=' || POINTER_SET (dic))
-               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);
-
-       remiCodeFromeBBlock (ebp, dic);
-       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
-}
-
 /*-----------------------------------------------------------------*/
 /* packRegisters - does some transformations to reduce register    */
 /*                   pressure                                      */
@@ -2032,8 +2057,11 @@ packRegisters (eBBlock * ebp)
                if (POINTER_SET (ic))
                        OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
 
-               if (POINTER_GET (ic))
+               if (POINTER_GET (ic)) {
                        OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
+                       if (OP_SYMBOL (IC_LEFT(ic))->remat) 
+                               OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
+               }
 
                /* if the condition of an if instruction
                   is defined in the previous instruction then
@@ -2092,7 +2120,7 @@ packRegisters (eBBlock * ebp)
 
                                /* 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)),
+                               if (compareType (operandType (IC_RIGHT (ic)),
                                               operandType (IC_LEFT (ic))) ==
                                    1) {
                                        iCode *dic =
@@ -2169,16 +2197,16 @@ setDefaultRegs (eBBlock ** ebbs, int count)
                regsAVR[R30_IDX].isFree = regsAVR[R31_IDX].isFree = 1;
 
        if (!avr_ptrRegReq) {
-               regsAVR[R26_IDX].type =
-                       regsAVR[R27_IDX].type =
-                       regsAVR[R30_IDX].type =
-                       regsAVR[R31_IDX].type = REG_GPR;
+               regsAVR[R26_IDX].type = (regsAVR[R26_IDX].type & ~REG_MASK) | REG_GPR;
+               regsAVR[R27_IDX].type = (regsAVR[R27_IDX].type & ~REG_MASK) | REG_GPR;
+               regsAVR[R28_IDX].type = (regsAVR[R28_IDX].type & ~REG_MASK) | REG_GPR;
+               regsAVR[R29_IDX].type = (regsAVR[R29_IDX].type & ~REG_MASK) | REG_GPR;
        }
        else {
-               regsAVR[R26_IDX].type =
-                       regsAVR[R27_IDX].type =
-                       regsAVR[R30_IDX].type =
-                       regsAVR[R31_IDX].type = REG_PTR;
+               regsAVR[R26_IDX].type = (regsAVR[R26_IDX].type & ~REG_MASK) | REG_PTR;
+               regsAVR[R27_IDX].type = (regsAVR[R27_IDX].type & ~REG_MASK) | REG_PTR;
+               regsAVR[R30_IDX].type = (regsAVR[R30_IDX].type & ~REG_MASK) | REG_PTR;
+               regsAVR[R31_IDX].type = (regsAVR[R31_IDX].type & ~REG_MASK) | REG_PTR;
        }
 
        /* registers 0-1 / 24-25 used as scratch */
@@ -2190,23 +2218,14 @@ setDefaultRegs (eBBlock ** ebbs, int count)
           to do something special 
           a) pre-assign registers to parameters RECEIVE
           b) mark the remaining parameter regs as free */
-       if (!currFunc->hasFcall) {
-               /* mark the parameter regs as GPR */
-               for (i = R16_IDX; i <= R23_IDX; i++) {
-                       regsAVR[i].type = REG_SCR;
-                       regsAVR[i].isFree = 1;
-               }
-               preAssignParms (ebbs[0]->sch);
+               /* mark the parameter regs as SCRACH */
+       for (i = R16_IDX; i <= R23_IDX; i++) {
+               regsAVR[i].type = (regsAVR[i].type & ~REG_MASK) | REG_SCR;
+               regsAVR[i].isFree = 1;
        }
-       else {
-
-               /* otherwise mark them as free scratch */
-               for (i = R16_IDX; i <= R23_IDX; i++) {
-                       regsAVR[i].type = REG_SCR;
-                       regsAVR[i].isFree = 1;
-               }
+       if (!IFFUNC_HASFCALL(currFunc->type)) {
+               preAssignParms (ebbs[0]->sch);
        }
-
        /* Y - is not allocated (it is the stack frame) */
        regsAVR[R28_IDX].isFree = regsAVR[R28_IDX].isFree = 0;
 }
@@ -2215,8 +2234,10 @@ setDefaultRegs (eBBlock ** ebbs, int count)
 /* assignRegisters - assigns registers to each live range as need  */
 /*-----------------------------------------------------------------*/
 void
-avr_assignRegisters (eBBlock ** ebbs, int count)
+avr_assignRegisters (ebbIndex * ebbi)
 {
+       eBBlock ** ebbs = ebbi->bbOrder;
+       int count = ebbi->count;
        iCode *ic;
        int i;
 
@@ -2228,8 +2249,12 @@ avr_assignRegisters (eBBlock ** ebbs, int count)
        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 (".dumppack", ebbs, count);
+               dumpEbbsToFileExt (DUMP_PACK, ebbi);
 
        /* first determine for each live range the number of 
           registers & the type of registers required for each */
@@ -2262,7 +2287,7 @@ avr_assignRegisters (eBBlock ** ebbs, int count)
        redoStackOffsets ();
 
        if (options.dump_rassgn)
-               dumpEbbsToFileExt (".dumprassgn", ebbs, count);
+               dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
 
        /* now get back the chain */
        ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
@@ -2274,8 +2299,8 @@ avr_assignRegisters (eBBlock ** ebbs, int count)
        /* free up any _G.stackSpil locations allocated */
        applyToSet (_G.stackSpil, deallocStackSpil);
        _G.slocNum = 0;
-       setToNull ((void **) &_G.stackSpil);
-       setToNull ((void **) &_G.spiltSet);
+       setToNull ((void *) &_G.stackSpil);
+       setToNull ((void *) &_G.spiltSet);
        /* mark all registers as free */
 
        return;