another AVR
[fw/sdcc] / src / avr / ralloc.c
index 781925462a3fe16d0790723e68fceabfbb80003a..dc2404f7277f683dbe134a44eec329b1274ed551 100644 (file)
@@ -56,43 +56,43 @@ int avr_ptrRegReq; /* pointer register required */
 /* AVR registers */
 regs regsAVR[] = 
 {
-    { REG_GPR  ,R0_IDX , REG_GPR , "r0",  "r0" , "" , 0, 1 },
-    { REG_GPR  ,R1_IDX , REG_GPR , "r1",  "r1" , "" , 0, 1 },
-    { REG_GPR  ,R2_IDX , REG_GPR , "r2",  "r2" , "" , 0, 1 },
-    { REG_GPR  ,R3_IDX , REG_GPR , "r3",  "r3" , "" , 0, 1 },
-    { REG_GPR  ,R4_IDX , REG_GPR , "r4",  "r4" , "" , 0, 1 },
-    { REG_GPR  ,R5_IDX , REG_GPR , "r5",  "r5" , "" , 0, 1 },
-    { REG_GPR  ,R6_IDX , REG_GPR , "r6",  "r6" , "" , 0, 1 },
-    { REG_GPR  ,R7_IDX , REG_GPR , "r7",  "r7" , "" , 0, 1 },
-    { REG_GPR  ,R8_IDX , REG_GPR , "r8",  "r8" , "" , 0, 1 },
-    { REG_GPR  ,R9_IDX , REG_GPR , "r9",  "r9" , "" , 0, 1 },
-    { REG_GPR  ,R10_IDX, REG_GPR , "r10", "r10", "" , 0, 1 },
-    { REG_GPR  ,R11_IDX, REG_GPR , "r11", "r11", "" , 0, 1 },
-    { REG_GPR  ,R12_IDX, REG_GPR , "r12", "r12", "" , 0, 1 },
-    { REG_GPR  ,R13_IDX, REG_GPR , "r13", "r13", "" , 0, 1 },
-    { REG_GPR  ,R14_IDX, REG_GPR , "r14", "r14", "" , 0, 1 },
-    { REG_GPR  ,R15_IDX, REG_GPR , "r15", "r15", "" , 0, 1 },
-    { REG_GPR  ,R16_IDX, REG_GPR , "r16", "r16", "" , 0, 1 }, 
-    { REG_GPR  ,R17_IDX, REG_GPR , "r17", "r17", "" , 0, 1 },
-    { REG_GPR  ,R18_IDX, REG_GPR , "r18", "r18", "" , 0, 1 },
-    { REG_GPR  ,R19_IDX, REG_GPR , "r19", "r19", "" , 0, 1 },
-    { REG_GPR  ,R20_IDX, REG_GPR , "r20", "r20", "" , 0, 1 },
-    { REG_GPR  ,R21_IDX, REG_GPR , "r21", "r21", "" , 0, 1 },
-    { REG_GPR  ,R22_IDX, REG_GPR , "r22", "r22", "" , 0, 1 },
-    { REG_GPR  ,R23_IDX, REG_GPR , "r23", "r23", "" , 0, 1 },
-    { REG_GPR  ,R24_IDX, REG_GPR , "r24", "r24", "" , 0, 1 },
-    { REG_GPR  ,R25_IDX, REG_GPR , "r25", "r25", "" , 0, 0 }, /* special literal use */
-    { REG_GPR  ,R26_IDX, REG_GPR , "r26", "r26", "" , 0, 0 }, /* used as pointer reg */
-    { REG_GPR  ,R27_IDX, REG_GPR , "r27", "r27", "" , 0, 0 },
-    { REG_GPR  ,R28_IDX, REG_GPR , "r28", "r28", "" , 0, 0 },
-    { REG_GPR  ,R29_IDX, REG_GPR , "r29", "r29", "" , 0, 0 },
-    { REG_GPR  ,R30_IDX, REG_GPR , "r30", "r30", "" , 0, 0 },
-    { REG_GPR  ,R31_IDX, REG_GPR , "r31", "r31", "" , 0, 0 },
-    { REG_PTR  ,X_IDX  , REG_PTR , "X"  , "X"  , "" , 0, 1 },
-    { REG_PTR  ,Z_IDX  , REG_PTR , "Z"  , "Z"  , "" , 0, 1 },
+    { REG_GPR  ,R0_IDX , REG_GPR , "r0",  "r0" , "" , 0, 0, 0 }, /* used as scratch */
+    { REG_GPR  ,R1_IDX , REG_GPR , "r1",  "r1" , "" , 0, 0, 0 }, /* used as 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_PTR  ,X_IDX  , REG_PTR , "X"  , "X"  , "" , 0, 1, 0 },
+    { REG_PTR  ,Z_IDX  , REG_PTR , "Z"  , "Z"  , "" , 0, 1, 0 },
 };
-int avr_nRegs = 25;
-int avr_fReg  = 8; /* first allocatable register */
+int avr_nRegs = 32;
+int avr_fReg  = 0; /* first allocatable register */
 
 static void spillThis (symbol *);
 
@@ -103,21 +103,6 @@ static regs *allocReg (short type)
 {
     int i;
 
-    /* if type is a pointer register then
-       look for X or Z */
-    if (type == REG_PTR) {
-       /* two choices */
-       if (regsAVR[X_IDX].isFree) {
-           regsAVR[X_IDX].isFree = 0;
-           return &regsAVR[X_IDX];
-       }
-       if (regsAVR[Z_IDX].isFree ) {
-           regsAVR[Z_IDX].isFree = 0;
-           return &regsAVR[Z_IDX];
-       }
-       return NULL;
-    }
-
     for ( i = avr_fReg ; i < avr_nRegs ; i++ ) {
 
        /* if type is given as 0 then any
@@ -126,8 +111,7 @@ static regs *allocReg (short type)
            regsAVR[i].isFree ) {
            regsAVR[i].isFree = 0;
            if (currFunc)
-               currFunc->regsUsed = 
-                   bitVectSetBit(currFunc->regsUsed,i);
+               currFunc->regsUsed = bitVectSetBit(currFunc->regsUsed,i);
            return &regsAVR[i];
        }
        /* other wise look for specific type
@@ -215,8 +199,7 @@ static bool allDefsOutOfRange (bitVect *defs,int fseq, int toseq)
            (ic = hTabItemWithKey(iCodehTab,i)) &&
            ( ic->seq >= fseq  && ic->seq <= toseq))
            
-           return FALSE;
-       
+           return FALSE;       
     }
     
     return TRUE;
@@ -634,11 +617,13 @@ static symbol *selectSpil (iCode *ic, eBBlock *ebp, symbol *forSym)
        if (!_G.blockSpil && 
            (selectS = liveRangesWith(lrcs,notUsedInRemaining,ebp,ic))) {
            sym = leastUsedLR (selectS);
-           if (!sym->remat) {
-               sym->remainSpil = 1;
-               _G.blockSpil++;
+           if (sym != forSym) {
+               if (!sym->remat) {
+                   sym->remainSpil = 1;
+                   _G.blockSpil++;
+               }
+               return sym;
            }
-           return sym;
        }
     }   
 
@@ -758,6 +743,31 @@ static regs *getRegPtr (iCode *ic, eBBlock *ebp, symbol *sym)
     goto tryAgain ;    
 }
 
+/*-----------------------------------------------------------------*/
+/* getRegScr - will try for SCR if not a GPR type if not spil      */
+/*-----------------------------------------------------------------*/
+static regs *getRegScr (iCode *ic, eBBlock *ebp, symbol *sym)
+{
+    regs *reg;
+
+ tryAgain:
+    /* try for a ptr type */
+    if ((reg = allocReg(REG_SCR))) 
+       return reg;    
+
+    /* try for gpr type */
+    if ((reg = allocReg(REG_GPR)))        
+       return reg;    
+
+    /* 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 ;    
+}
+
 /*-----------------------------------------------------------------*/
 /* getRegGpr - will try for GPR if not spil                        */
 /*-----------------------------------------------------------------*/
@@ -868,11 +878,13 @@ static void deassignLRs (iCode *ic, eBBlock *ebp)
                  sym->nRegs) >= result->nRegs)
                ) {
                
-               for (i = 0 ; i < max(sym->nRegs,result->nRegs) ; i++)
+               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);
+                           result->regs[i] = getRegGpr (ic,ebp,result);
 
                _G.regAssigned = bitVectSetBit(_G.regAssigned,result->key);
                
@@ -1024,7 +1036,6 @@ static void serialRegAssign (eBBlock **ebbs, int count)
                bitVect *spillable;
                int willCS ;
                int j;
-               int ptrRegSet = 0;
                               
                /* if it does not need or is spilt 
                   or is already assigned to registers
@@ -1072,20 +1083,14 @@ static void serialRegAssign (eBBlock **ebbs, int count)
                    }
                }               
                
-               /* if we need ptr regs for the right side
-                  then mark it */
-               if (POINTER_GET(ic) && 
-                   getSize(OP_SYMBOL(IC_LEFT(ic))->type) <= 2) 
-               {
-                   avr_ptrRegReq++;
-                   ptrRegSet = 1;
-               }
-               /* else we assign registers to it */            
+               /* 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 if (sym->regType == REG_SCR) 
+                       sym->regs[j] = getRegScr(ic,ebbs[i],sym);
                    else
                        sym->regs[j] = getRegGpr(ic,ebbs[i],sym);
 
@@ -1102,15 +1107,10 @@ static void serialRegAssign (eBBlock **ebbs, int count)
                                     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 && ic->op != '=')
+                   OP_SYMBOL(IC_RIGHT(ic))->nRegs )
                        positionRegs(OP_SYMBOL(IC_RESULT(ic)),
                                     OP_SYMBOL(IC_RIGHT(ic)),ic->lineno);
-               
-               if (ptrRegSet) {
-                   avr_ptrRegReq--;
-                   ptrRegSet = 0;
-               }
-                               
+                                               
            }       
        }
     }
@@ -1241,10 +1241,17 @@ static void createRegMask (eBBlock **ebbs, int count)
                    continue ;
 
                /* for all the registers allocated to it */
-               for (k = 0 ; k < sym->nRegs ;k++)
-                   if (sym->regs[k])
+               for (k = 0 ; k < sym->nRegs ;k++) {
+                   if (sym->regs[k]) {
                        ic->rMask =
                            bitVectSetBit(ic->rMask,sym->regs[k]->rIdx);
+                       /* special case for X & Z registers */
+                       if (k == R26_IDX || k == R27_IDX)
+                           ic->rMask = bitVectSetBit(ic->rMask,X_IDX);
+                       if (k == R30_IDX || k == R31_IDX)
+                           ic->rMask = bitVectSetBit(ic->rMask,Z_IDX);
+                   }
+               }
            }
        }
     }
@@ -1320,22 +1327,7 @@ static void regTypeNum ()
                                      bitVectFirstBit(sym->defs))) &&
                POINTER_GET(ic) && 
                !IS_BITVAR(sym->etype)) {
-               
-                               
-               /* if remat in data space */
-/*             if (OP_SYMBOL(IC_LEFT(ic))->remat && */
-/*                 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 in data space or idata space then try to
                   allocate pointer register */
                   
@@ -1352,13 +1344,19 @@ static void regTypeNum ()
             }
            
            /* 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 ;
-           
+           if (sym->nRegs == 2   && /* size is two */
+               IS_PTR(sym->type) && /* is a pointer */
+               sym->uptr)   {        /* has pointer usage i.e. get/set pointer */
+               sym->regType = REG_PTR ;
+               avr_ptrRegReq++;
+           }
+           else {
+               /* live accross a function call then gpr else scratch */
+               if (sym->isLiveFcall)
+                   sym->regType = REG_GPR ;
+               else
+                   sym->regType = REG_SCR ;
+           }
        } else 
            /* for the first run we don't provide */
            /* registers for true symbols we will */
@@ -1368,17 +1366,6 @@ static void regTypeNum ()
     
 }
 
-/*-----------------------------------------------------------------*/
-/* freeAllRegs - mark all registers as free                        */
-/*-----------------------------------------------------------------*/
-static void freeAllRegs()
-{
-    int i;
-
-    for (i=0;i< avr_nRegs;i++ )
-       regsAVR[i].isFree = 1;
-}
-
 /*-----------------------------------------------------------------*/
 /* deallocStackSpil - this will set the stack pointer back         */
 /*-----------------------------------------------------------------*/
@@ -1466,15 +1453,6 @@ static int packRegsForAssign (iCode *ic,eBBlock *ebp)
        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;
-       
-    }
     /* 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 */    
@@ -1548,6 +1526,9 @@ static int packRegsForAssign (iCode *ic,eBBlock *ebp)
            return 0;                
     }
 pack:
+    /* if in far space & tru symbol then don't */
+    if ((IS_TRUE_SYMOP(IC_RESULT(ic))) && isOperandInFarSpace(IC_RESULT(ic)))
+       return 0;
     /* found the definition */
     /* replace the result with the result of */
     /* this assignment and remove this assignment */
@@ -1725,7 +1706,7 @@ static iCode *packRegsForOneuse (iCode *ic, operand *op , eBBlock *ebp)
     
     /* only upto 2 bytes since we cannot predict
        the usage of b, & acc */
-    if (getSize(operandType(op)) >  (fReturnSize - 2) &&
+    if (getSize(operandType(op)) > fAVRReturnSize  &&
        ic->op != RETURN             &&
        ic->op != SEND)
        return NULL;
@@ -1760,7 +1741,7 @@ static iCode *packRegsForOneuse (iCode *ic, operand *op , eBBlock *ebp)
        a function call */
     if (dic->op == CALL || dic->op == PCALL ) {
        if (ic->op != SEND && ic->op != RETURN) {
-/*         OP_SYMBOL(op)->ruonly = 1; */
+           OP_SYMBOL(op)->ruonly = 1;
            return dic;
        }
        dic = dic->next ;
@@ -1769,9 +1750,7 @@ static iCode *packRegsForOneuse (iCode *ic, operand *op , eBBlock *ebp)
     
     /* 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))          ||
+    if (IS_OP_RUONLY(IC_LEFT(ic))          ||
        IS_OP_RUONLY(IC_RIGHT(ic)) )        {
        return NULL;
     }
@@ -1818,17 +1797,14 @@ static iCode *packRegsForOneuse (iCode *ic, operand *op , eBBlock *ebp)
                return NULL;
 
        /* 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))          ||
+       if (IS_OP_RUONLY(IC_LEFT(dic))          ||
            IS_OP_RUONLY(IC_RIGHT(dic))         ||
            IS_OP_RUONLY(IC_RESULT(dic))            ) {
            return NULL;
        }
     }
                
-/*     OP_SYMBOL(op)->ruonly = 1; */
+    OP_SYMBOL(op)->ruonly = 1;
     return sic;
        
 }
@@ -2132,10 +2108,8 @@ static void packRegisters (eBBlock *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 ((ic->op == RETURN || ic->op == SEND))
+           packRegsForOneuse (ic,IC_LEFT(ic),ebp);     
 
        /* if pointer set & left has a size more than
           one and right is not in far space */
@@ -2229,6 +2203,98 @@ static void packRegisters (eBBlock *ebp)
 
     }
 }
+
+/*-----------------------------------------------------------------*/
+/* preAssignParms - we have a leaf function preassign registers    */
+/*-----------------------------------------------------------------*/
+static void preAssignParms (iCode *ic)
+{
+    int i = R16_IDX;
+    /* look for receives and assign registers
+       to the result of the receives */
+    while (ic) {
+       /* if it is a receive */
+       if (ic->op == RECEIVE) {
+           symbol *r = OP_SYMBOL(IC_RESULT(ic));
+           int size = getSize(r->type);
+           if (r->regType == REG_GPR || r->regType == REG_SCR) {
+               int j = 0;
+               while (size--) {
+                   r->regs[j++] = &regsAVR[i++];
+                   regsAVR[i-1].isFree = 0;
+               }
+               /* put in the regassigned vector */
+               _G.regAssigned = bitVectSetBit(_G.regAssigned,r->key);
+           } else {
+               /* not a GPR then we should mark as free */
+               while (size--) {
+                   regsAVR[i++].isFree =1;
+               }
+           }
+       }
+       ic = ic->next;
+    }
+    /* mark anything remaining as free */
+    while (i <= R23_IDX)
+       regsAVR[i++].isFree =1;
+}
+
+/*-----------------------------------------------------------------*/
+/* setdefaultRegs - do setup stuff for register allocation         */
+/*-----------------------------------------------------------------*/
+static void setDefaultRegs(eBBlock **ebbs,int count)
+{
+    int i ;
+
+    /* if no pointer registers required in this function
+       then mark r26-27 & r30-r31 as GPR & free */
+    regsAVR[R26_IDX].isFree =
+       regsAVR[R27_IDX].isFree =
+       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 ;   
+    } else {
+       regsAVR[R26_IDX].type =
+           regsAVR[R27_IDX].type =
+           regsAVR[R30_IDX].type =
+           regsAVR[R31_IDX].type = REG_PTR ;
+    }
+
+    /* registers 0-1 / 24-25 used as scratch */
+    regsAVR[R0_IDX].isFree = 
+       regsAVR[R1_IDX].isFree =
+       regsAVR[R24_IDX].isFree =
+       regsAVR[R25_IDX].isFree = 0;
+    
+    /* if this has no function calls then we need
+       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);
+    } else {
+
+       /* otherwise mark them as free scratch */
+       for (i= R16_IDX ; i <= R23_IDX ;i++) {
+           regsAVR[i].type = REG_SCR;
+           regsAVR[i].isFree = 1;
+       }
+    }
+
+    /* Y - is not allocated (it is the stack frame) */
+    regsAVR[R28_IDX].isFree =
+       regsAVR[R28_IDX].isFree =0;
+}
   
 /*-----------------------------------------------------------------*/
 /* assignRegisters - assigns registers to each live range as need  */
@@ -2240,13 +2306,7 @@ void avr_assignRegisters (eBBlock **ebbs, int count)
 
     setToNull((void *)&_G.funcrUsed);
     avr_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
-    
-    /* is a leaf function then we can allocate the
-       parameter registers as well */
-    if (!currFunc->hasFcall)
-       avr_fReg =0;
-    else
-       avr_fReg = 8;
+
     /* change assignments this will remove some
        live ranges reducing some register pressure */
     for (i = 0 ; i < count ;i++ )
@@ -2258,7 +2318,10 @@ void avr_assignRegisters (eBBlock **ebbs, int count)
     /* first determine for each live range the number of 
        registers & the type of registers required for each */
     regTypeNum ();
-    
+
+    /* setup the default registers */
+    setDefaultRegs(ebbs,count);
+   
     /* and serially allocate registers */ 
     serialRegAssign(ebbs,count);
 
@@ -2290,14 +2353,14 @@ void avr_assignRegisters (eBBlock **ebbs, int count)
 
 
     genAVRCode(ic);
-
+/*     for (; ic ; ic = ic->next) */
+/*         piCode(ic,stdout); */
     /* 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();
 
     return ;
 }