* Added z80 blurb.
[fw/sdcc] / src / z80 / ralloc.c
index 54e34049b2e5c8b1e9ffa58aa6738dc563706780..02a2fc90cc64b471ee0c0f5aa97a211ceb802e08 100644 (file)
@@ -7,8 +7,9 @@
     hardware.  It allocates based on usage and how long the varible
     lives into registers or temporary memory on the stack.
 
-    On the Z80 hl, ix, iy, and a are reserved for the code generator,
-    leaving bc and de for allocation.  The extra register pressure
+    On the Z80 hl and ix and a are reserved for the code generator,
+    leaving bc and de for allocation.  iy is unusable due to currently
+    as it's only adressable as a pair.  The extra register pressure
     from reserving hl is made up for by how much easier the sub
     operations become.  You could swap hl for iy if the undocumented
     iyl/iyh instructions are available.
 
 #include "z80.h"
 
+enum {
+    DISABLE_PACK_ACC   = 0,
+    DISABLE_PACK_ASSIGN        = 0,
+    LIMITED_PACK_ACC   = 1
+};
+
+#define D_ALLOC                1
+
+#if 0
+#define D(_a, _s)      if (_a)  { printf _s; fflush(stdout); }
+#else
+#define D(_a, _s)
+#endif
+
 /*-----------------------------------------------------------------*/
 /* At this point we start getting processor specific although      */
 /* some routines are non-processor specific & can be reused when   */
@@ -59,7 +74,6 @@ bitVect *regAssigned = NULL;
 short blockSpil = 0;
 int slocNum = 0 ;
 extern void genZ80Code(iCode *);
-int ptrRegReq = 0; /* one byte pointer register required */
 bitVect *funcrUsed = NULL; /* registers used in a function */
 int stackExtend = 0;
 int dataExtend  = 0;
@@ -69,8 +83,8 @@ int _nRegs;
 #define DEBUG_FAKE_EXTRA_REGS  0
 
 static regs _gbz80_regs[] = {
-    { REG_GPR, C_IDX , "b", 1 },
-    { REG_GPR, B_IDX , "c", 1 },
+    { REG_GPR, C_IDX , "c", 1 },
+    { REG_GPR, B_IDX , "b", 1 },
     { REG_CND, CND_IDX, "c", 1}
 };
 
@@ -119,9 +133,11 @@ static regs *allocReg (short type)
            if (currFunc)
                currFunc->regsUsed = 
                    bitVectSetBit(currFunc->regsUsed,i);
+           D(D_ALLOC, ("allocReg: alloced %zr\n", &regsZ80[i]));
            return &regsZ80[i];
        }
     }
+    D(D_ALLOC, ("allocReg: No free.\n"));
     return NULL;
 }
 
@@ -134,7 +150,7 @@ regs *regWithIdx (int idx)
     for (i=0;i < _nRegs;i++)
        if (regsZ80[i].rIdx == idx)
            return &regsZ80[i];
-
+    
     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
           "regWithIdx not found");
     exit(1);
@@ -144,8 +160,9 @@ regs *regWithIdx (int idx)
  */
 static void freeReg (regs *reg)
 {
-    assert(!reg->isFree);
+    wassert(!reg->isFree);
     reg->isFree = 1;
+    D(D_ALLOC, ("freeReg: freed %zr\n", reg));
 }
 
 
@@ -334,14 +351,12 @@ static int noOverLap (set *itmpStack, symbol *fsym)
 {
     symbol *sym;
    
-
     for (sym = setFirstItem(itmpStack); sym;
         sym = setNextItem(itmpStack)) {
        if (sym->liveTo > fsym->liveFrom )
            return 0;
            
     }
-
     return 1;
 }
 
@@ -372,14 +387,6 @@ DEFSETFUNC(isFree)
     return 0;
 }
 
-/*-----------------------------------------------------------------*/
-/* spillLRWithPtrReg :- will spil those live ranges which use PTR  */
-/*-----------------------------------------------------------------*/
-static void spillLRWithPtrReg (symbol *forSym)
-{
-    /* Always just return */
-}
-
 /*-----------------------------------------------------------------*/
 /* createStackSpil - create a location on the stack to spil        */
 /*-----------------------------------------------------------------*/
@@ -387,6 +394,8 @@ symbol *createStackSpil (symbol *sym)
 {
     symbol *sloc= NULL;
 
+    D(D_ALLOC, ("createStackSpil: for sym %zs\n", sym));
+
     /* first go try and find a free one that is already 
        existing on the stack */
     if (applyToSet(stackSpil,isFree,&sloc, sym)) {
@@ -395,6 +404,7 @@ symbol *createStackSpil (symbol *sym)
        sym->stackSpil= 1;
        sloc->isFree = 0;
        addSetHead(&sloc->usl.itmpStack,sym);
+       D(D_ALLOC, ("createStackSpil: found existing\n"));
        return sym;
     }
 
@@ -436,6 +446,8 @@ symbol *createStackSpil (symbol *sym)
     /* add it to the set of itempStack set 
        of the spill location */
     addSetHead(&sloc->usl.itmpStack,sym);
+
+    D(D_ALLOC, ("createStackSpil: created new\n"));
     return sym;
 }
 
@@ -471,12 +483,14 @@ bool isSpiltOnStack (symbol *sym)
 static void spillThis (symbol *sym)
 {
     int i;
+
+    D(D_ALLOC, ("spillThis: spilling %zs\n", sym));
+
     /* 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;
@@ -484,21 +498,16 @@ static void spillThis (symbol *sym)
        
     bitVectUnSetBit(regAssigned,sym->key);
 
-    for (i = 0 ; i < sym->nRegs ; i++)
-
+    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 (!ptrRegReq && isSpiltOnStack(sym)) {
-       ptrRegReq++ ;
-       spillLRWithPtrReg(sym);
-    }
-
     if (sym->usl.spillLoc && !sym->remat)
        sym->usl.spillLoc->allocreq = 1;
     return;
@@ -512,12 +521,13 @@ symbol *selectSpil (iCode *ic, eBBlock *ebp, symbol *forSym)
     set *selectS ;
     symbol *sym;
 
+    D(D_ALLOC, ("selectSpil: finding spill for ic %zi\n", ic));
     /* get the spillable live ranges */
     lrcs = computeSpillable (ic);
 
     /* get all live ranges that are rematerizable */
     if ((selectS = liveRangesWith(lrcs,rematable,ebp,ic))) {
-
+       D(D_ALLOC, ("selectSpil: using remat.\n"));
        /* return the least used of these */
        return leastUsedLR(selectS);
     }
@@ -573,7 +583,7 @@ symbol *selectSpil (iCode *ic, eBBlock *ebp, symbol *forSym)
 
     /* find live ranges with spillocation */
     if ((selectS = liveRangesWith(lrcs,hasSpilLoc,ebp,ic))) {
-       
+       D(D_ALLOC, ("selectSpil: using with spill.\n"));
        sym = leastUsedLR(selectS);
        sym->usl.spillLoc->allocreq = 1;
        return sym;
@@ -583,6 +593,7 @@ symbol *selectSpil (iCode *ic, eBBlock *ebp, symbol *forSym)
        location on the stack , for which one? the least
        used ofcourse */
     if ((selectS = liveRangesWith(lrcs,noSpilLoc,ebp,ic))) {
+       D(D_ALLOC, ("selectSpil: creating new spill.\n"));
        /* return a created spil location */
        sym = createStackSpil(leastUsedLR(selectS));
        sym->usl.spillLoc->allocreq = 1;
@@ -591,6 +602,7 @@ symbol *selectSpil (iCode *ic, eBBlock *ebp, symbol *forSym)
     
     /* this is an extreme situation we will spill
        this one : happens very rarely but it does happen */
+    D(D_ALLOC, ("selectSpil: using spillThis.\n"));
     spillThis ( forSym );
     return forSym;
    
@@ -604,6 +616,8 @@ bool spilSomething (iCode *ic, eBBlock *ebp, symbol *forSym)
     symbol *ssym;
     int i ;
 
+    D(D_ALLOC, ("spilSomething: spilling on ic %zi\n", ic));
+
     /* get something we can spil */
     ssym = selectSpil(ic,ebp,forSym);
     
@@ -619,7 +633,6 @@ bool spilSomething (iCode *ic, eBBlock *ebp, symbol *forSym)
     for (i = 0 ; i < ssym->nRegs ;i++ )
        if (ssym->regs[i])
            freeReg(ssym->regs[i]);
-     
 #if 0
     /* if spilt on stack then free up r0 & r1 
        if they could have been assigned to as gprs */
@@ -655,6 +668,8 @@ bool spilSomething (iCode *ic, eBBlock *ebp, symbol *forSym)
     }
 #endif
 
+    D(D_ALLOC, ("spilSomething: done.\n"));
+
     if (ssym == forSym )
        return FALSE ;
     else
@@ -667,18 +682,19 @@ regs *getRegGpr (iCode *ic, eBBlock *ebp,symbol *sym)
 {
     regs *reg;
 
+    D(D_ALLOC, ("getRegGpr: on ic %zi\n"));
  tryAgain:
     /* try for gpr type */
-    if ((reg = allocReg(REG_GPR)))        
+    if ((reg = allocReg(REG_GPR))) {
+       D(D_ALLOC, ("getRegGpr: got a reg.\n"));
        return reg;    
-
-    if (!ptrRegReq)
-       if ((reg = allocReg(REG_PTR)))
-           return reg ;
+    }
 
     /* we have to spil */
-    if (!spilSomething (ic,ebp,sym))
+    if (!spilSomething (ic,ebp,sym)) {
+       D(D_ALLOC, ("getRegGpr: have to spill.\n"));
        return NULL ;
+    }
 
     /* this looks like an infinite loop but 
        in really selectSpil will abort  */
@@ -738,6 +754,8 @@ static void deassignLRs (iCode *ic, eBBlock *ebp)
            !OP_SYMBOL(IC_LEFT(ic->prev))->isspilt) 
            psym = OP_SYMBOL(IC_LEFT(ic->prev));
 
+       D(D_ALLOC, ("deassignLRs: in loop on sym %zs", sym));
+
        if (sym->nRegs) {
            int i = 0;
            
@@ -766,15 +784,23 @@ static void deassignLRs (iCode *ic, eBBlock *ebp)
                ((nfreeRegsType(result->regType) +
                  sym->nRegs) >= result->nRegs)
                ) {
-               
-               for (i = 0 ; i < max(sym->nRegs,result->nRegs) ; i++)
+               for (i = 0 ; i < max(sym->nRegs,result->nRegs) ; i++) {
                    if (i < sym->nRegs )
                        result->regs[i] = sym->regs[i] ;
                    else
                        result->regs[i] = getRegGpr (ic,ebp,result);
+                   
+                   /* if the allocation falied which means
+                      this was spilt then break */
+                   if (!result->regs[i]) {
+                       wassert(0);
+                       assert(0);
+                       break;
+                   }
+               }
 
                regAssigned = bitVectSetBit(regAssigned,result->key);
-           }                   
+           }                   
            
            /* free the remaining */
            for (; i < sym->nRegs ; i++) {
@@ -783,6 +809,7 @@ static void deassignLRs (iCode *ic, eBBlock *ebp)
                        freeReg(sym->regs[i]);
                } else
                    freeReg(sym->regs[i]);
+               //              sym->regs[i] = NULL;
            }
        }
     }
@@ -796,6 +823,8 @@ static void reassignLR (operand *op)
     symbol *sym = OP_SYMBOL(op);
     int i;
 
+    D(D_ALLOC, ("reassingLR: on sym %zs\n", sym));
+
     /* not spilt any more */     
     sym->isspilt = sym->blockSpil  = sym->remainSpil = 0;
     bitVectUnSetBit(spiltSet,sym->key);
@@ -827,30 +856,32 @@ static int willCauseSpill ( int nr, int rt)
 */
 static void positionRegs (symbol *result, symbol *opsym, int lineno)
 {
-       int count = min(result->nRegs,opsym->nRegs);
-       int i , j = 0, shared = 0;
+    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 ;
+    D(D_ALLOC, ("positionRegs: on result %zs opsum %zs line %u\n", result, opsym, lineno));
+
+    /* 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;
-                       }
-               }
+    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;
-       }
+    if (shared) {
+       regs *tmp = result->regs[i];
+       result->regs[i] = result->regs[j];
+       result->regs[j] = tmp;          
+       goto again;
+    }
 }
 
 /** Try to allocate a pair of registers to the symbol.
@@ -858,7 +889,7 @@ static void positionRegs (symbol *result, symbol *opsym, int lineno)
 bool tryAllocatingRegPair(symbol *sym)
 {
     int i;
-    assert(sym->nRegs == 2);
+    wassert(sym->nRegs == 2);
     for ( i = 0 ; i < _nRegs ; i+=2 ) {
        if ((regsZ80[i].isFree)&&(regsZ80[i+1].isFree)) {
            regsZ80[i].isFree = 0;
@@ -871,9 +902,11 @@ bool tryAllocatingRegPair(symbol *sym)
                currFunc->regsUsed = 
                    bitVectSetBit(currFunc->regsUsed,i+1);
            }
+           D(D_ALLOC, ("tryAllocRegPair: succeded for sym %zs\n", sym));
            return TRUE;
        }
     }
+    D(D_ALLOC, ("tryAllocRegPair: failed on sym %zs\n", sym));
     return FALSE;
 }
 
@@ -900,8 +933,10 @@ static void serialRegAssign (eBBlock **ebbs, int count)
         
            /* if this is an ipop that means some live
               range will have to be assigned again */
-           if (ic->op == IPOP)
+           if (ic->op == IPOP) {
+               wassert(0);
                reassignLR (IC_LEFT(ic));
+           }
 
            /* if result is present && is a true symbol */
            if (IC_RESULT(ic) && ic->op != IFX &&
@@ -928,19 +963,24 @@ static void serialRegAssign (eBBlock **ebbs, int count)
                int willCS ;
                int j;
 
+               D(D_ALLOC, ("serialRegAssign: in loop on result %zs\n", sym));
+
                /* 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(regAssigned,sym->key) ||
-                   sym->liveTo <= ic->seq)
+                   sym->liveTo <= ic->seq) {
+                   D(D_ALLOC, ("serialRegAssign: wont live long enough.\n"));
                    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 (blockSpil && sym->liveTo > ebbs[i]->lSeq) {
+                   D(D_ALLOC, ("serialRegAssign: \"spilling to be safe.\"\n"));
                    spillThis (sym);
                    continue ;
                }
@@ -953,6 +993,7 @@ static void serialRegAssign (eBBlock **ebbs, int count)
                if ( sym->remat ||                  
                    (willCS  && bitVectIsZero(spillable) ) ) {
 
+                   D(D_ALLOC, ("serialRegAssign: \"remat spill\"\n"));
                    spillThis (sym) ;
                    continue ;
 
@@ -979,6 +1020,7 @@ static void serialRegAssign (eBBlock **ebbs, int count)
 
                /* Special case:  Try to fit into a reg pair if
                   available */
+               D(D_ALLOC, ("serialRegAssign: actually allocing regs!\n"));
                if ((sym->nRegs == 2)&&tryAllocatingRegPair(sym)) {
                }
                else {
@@ -1032,8 +1074,7 @@ bitVect *rUmaskForOp (operand *op)
     rumask = newBitVect(_nRegs);
 
     for (j = 0; j < sym->nRegs; j++) {
-       rumask = bitVectSetBit(rumask,
-                              sym->regs[j]->rIdx);
+       rumask = bitVectSetBit(rumask, sym->regs[j]->rIdx);
     }
 
     return rumask;
@@ -1169,7 +1210,7 @@ char *rematStr (symbol *sym)
 /*-----------------------------------------------------------------*/
 /* regTypeNum - computes the type & number of registers required   */
 /*-----------------------------------------------------------------*/
-static void regTypeNum ()
+static void regTypeNum (void)
 {
     symbol *sym;
     int k;
@@ -1182,6 +1223,8 @@ static void regTypeNum ()
        if ((sym->liveTo - sym->liveFrom) == 0)
            continue ;
 
+       D(D_ALLOC, ("regTypeNum: loop on sym %zs\n", sym));
+       
        /* if the live range is a temporary */
        if (sym->isitmp) {
 
@@ -1202,6 +1245,8 @@ static void regTypeNum ()
                          getSize(sym->type = aggrToPtr(sym->type,FALSE)) :
                          getSize(sym->type));
 
+           D(D_ALLOC, ("regTypeNum: setup to assign regs sym %zs\n", sym));
+
            if (sym->nRegs > 4) {
                fprintf(stderr,"allocated more than 4 or 0 registers for type ");
                printTypeChain(sym->type,stderr);fprintf(stderr,"\n");
@@ -1226,6 +1271,8 @@ static void freeAllRegs()
 {
     int i;
 
+    D(D_ALLOC, ("freeAllRegs: running.\n"));
+
     for (i=0;i< _nRegs;i++ )
        regsZ80[i].isFree = 1;
 }
@@ -1246,6 +1293,8 @@ DEFSETFUNC(deallocStackSpil)
 static int packRegsForAssign (iCode *ic,eBBlock *ebp)
 {
     iCode *dic, *sic;
+
+    D(D_ALLOC, ("packRegsForAssing: running on ic %zi\n", ic));
     
     if (
        /*      !IS_TRUE_SYMOP(IC_RESULT(ic)) ||*/
@@ -1299,11 +1348,13 @@ static int packRegsForAssign (iCode *ic,eBBlock *ebp)
            dic = NULL;
            break;
        }
+#if 0
        if (POINTER_SET(dic) && 
            IC_RESULT(dic)->key == IC_RESULT(ic)->key ) {
            dic = NULL ;
            break;
        }
+#endif
     }
     
     if (!dic)
@@ -1429,6 +1480,8 @@ static int packRegsForSupport (iCode *ic, eBBlock *ebp)
     /* for the left & right operand :- look to see if the
        left was assigned a true symbol in far space in that
        case replace them */
+    D(D_ALLOC, ("packRegsForSupport: running on ic %zi\n", ic));
+
     if (IS_ITEMP(IC_LEFT(ic)) && 
        OP_SYMBOL(IC_LEFT(ic))->liveTo <= ic->seq) {
        iCode *dic = findAssignToSym(IC_LEFT(ic),ic);
@@ -1484,6 +1537,8 @@ static iCode *packRegsForOneuse (iCode *ic, operand *op , eBBlock *ebp)
     bitVect *uses ;
     iCode *dic, *sic;
 
+    D(D_ALLOC, ("packRegsForOneUse: running on ic %zi\n", ic));
+
     /* if returning a literal then do nothing */
     if (!IS_SYMOP(op))
        return NULL;
@@ -1749,17 +1804,39 @@ static void packRegsForAccUse (iCode *ic)
 
 bool opPreservesA(iCode *ic, iCode *uic)
 {
+    /* if it is a conditional branch then we definitely can */
+    if (uic->op == IFX  ) 
+       return FALSE;
+
+    if ( uic->op == JUMPTABLE )
+       return FALSE;
+
     /* if the usage has only one operand then we can */
-    if (IC_LEFT(ic) == NULL ||
-       IC_RIGHT(ic) == NULL) 
-       return TRUE;
+    /* PENDING: check */
+    if (IC_LEFT(uic) == NULL ||
+       IC_RIGHT(uic) == NULL) 
+       return FALSE;
 
-    if (uic->op != '=' && 
-       !IS_ARITHMETIC_OP(uic) &&
+    /* PENDING: check this rule */
+    if (getSize(operandType(IC_RESULT(uic))) > 1) {
+       return FALSE;
+    }
+
+    /*
+      Bad:
+       !IS_ARITHMETIC_OP(uic) (sub requires A)
+    */
+    if (
+       uic->op != '+' &&
        !IS_BITWISE_OP(uic)    &&
+       uic->op != '=' && 
        uic->op != EQ_OP &&
+       !POINTER_GET(uic) &&
+       /*
        uic->op != LEFT_OP &&
-       uic->op != RIGHT_OP ) {
+       uic->op != RIGHT_OP &&*/
+       1
+       ) {
        return FALSE;
     }
 
@@ -1784,11 +1861,26 @@ bool opPreservesA(iCode *ic, iCode *uic)
 /** Pack registers for acc use.
     When the result of this operation is small and short lived it may
     be able to be stored in the accumelator.
+
+    Note that the 'A preserving' list is currently emperical :)e
  */
 static void packRegsForAccUse2(iCode *ic)
 {
     iCode *uic;
-    
+
+    D(D_ALLOC, ("packRegsForAccUse2: running on ic %zi\n", ic));
+
+    /* Filter out all but those 'good' commands */
+    if (
+       !POINTER_GET(ic) &&
+       ic->op != '+' &&
+       !IS_BITWISE_OP(ic)    &&
+       ic->op != '=' && 
+       ic->op != EQ_OP &&
+       ic->op != CAST &&
+       1)
+       return;
+
     /* if + or - then it has to be one byte result.
        MLH: Ok.
      */
@@ -1963,8 +2055,10 @@ static void packRegisters (eBBlock *ebp)
 {
     iCode *ic ;
     int change = 0 ;
+
+    D(D_ALLOC, ("packRegisters: entered.\n"));
     
-    while (1) {
+    while (1 && !DISABLE_PACK_ASSIGN) {
        change = 0;
        /* look for assignments of the form */
        /* iTempNN = TRueSym (someoperation) SomeOperand */
@@ -1983,6 +2077,9 @@ static void packRegisters (eBBlock *ebp)
        /* Safe: address of a true sym is always constant. */
        /* if this is an itemp & result of a address of a true sym 
           then mark this as rematerialisable   */
+
+       D(D_ALLOC, ("packRegisters: looping on ic %zi\n", ic));
+    
        if (ic->op == ADDRESS_OF && 
            IS_ITEMP(IC_RESULT(ic)) &&
            IS_TRUE_SYMOP(IC_LEFT(ic)) &&
@@ -2038,29 +2135,25 @@ static void packRegisters (eBBlock *ebp)
            !options.model)
            packRegsForOneuse (ic,IC_LEFT(ic),ebp);     
 #endif
-
-       if (!IS_GB) {
-           /* if pointer set & left has a size more than
+       /* if pointer set & left has a size more than
           one and right is not in far space */
-           if (POINTER_SET(ic)                    &&
-               /* MLH: no such thing.
-                  !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)                    &&
-               /* MLH: dont have far space
-                  !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 (POINTER_SET(ic)                    &&
+           /* MLH: no such thing.
+              !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)                    &&
+           /* MLH: dont have far space
+              !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);
        /* 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
@@ -2076,13 +2169,7 @@ static void packRegisters (eBBlock *ebp)
            getSize(operandType(IC_RESULT(ic))) <= 2)
            packRegsForAccUse (ic);
 #else
-       if ((POINTER_GET(ic) ||
-            IS_ARITHMETIC_OP(ic) ||
-            IS_BITWISE_OP(ic) ||
-            ic->op == LEFT_OP ||
-            ic->op == RIGHT_OP
-            ) &&
-           IS_ITEMP(IC_RESULT(ic)) &&
+       if (!DISABLE_PACK_ACC && IS_ITEMP(IC_RESULT(ic)) &&
            getSize(operandType(IC_RESULT(ic))) == 1)
            packRegsForAccUse2(ic);
 #endif
@@ -2097,8 +2184,10 @@ void z80_assignRegisters (eBBlock **ebbs, int count)
     iCode *ic;
     int i ;
 
+    D(D_ALLOC, ("\n-> z80_assignRegisters: entered.\n"));
+
     setToNull((void *)&funcrUsed);
-    ptrRegReq = stackExtend = dataExtend = 0;
+    stackExtend = dataExtend = 0;
 
     if (IS_GB) {
        /* DE is required for the code gen. */