First pass at DS80C390 flat mode support
[fw/sdcc] / src / mcs51 / ralloc.c
1 /*------------------------------------------------------------------------
2
3   SDCCralloc.c - source file for register allocation. (8051) specific
4
5                 Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
6
7    This program is free software; you can redistribute it and/or modify it
8    under the terms of the GNU General Public License as published by the
9    Free Software Foundation; either version 2, or (at your option) any
10    later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20    
21    In other words, you are welcome to use, share and improve this program.
22    You are forbidden to forbid anyone else to use, share and improve
23    what you give them.   Help stamp out software-hoarding!  
24 -------------------------------------------------------------------------*/
25
26 #include "common.h"
27 #include "ralloc.h"
28
29 /*-----------------------------------------------------------------*/
30 /* At this point we start getting processor specific although      */
31 /* some routines are non-processor specific & can be reused when   */
32 /* targetting other processors. The decision for this will have    */
33 /* to be made on a routine by routine basis                        */
34 /* routines used to pack registers are most definitely not reusable*/
35 /* since the pack the registers depending strictly on the MCU      */
36 /*-----------------------------------------------------------------*/
37
38 extern void gen51Code(iCode *);
39
40 /* Global data */
41 static struct {
42     bitVect *spiltSet;
43     set *stackSpil;
44     bitVect *regAssigned;
45     short blockSpil;
46     int slocNum;
47     bitVect *funcrUsed; /* registers used in a function */
48     int stackExtend;
49     int dataExtend;
50 } _G;
51
52 /* Shared with gen.c */
53 int mcs51_ptrRegReq; /* one byte pointer register required */
54
55 /* 8051 registers */
56 regs regs8051[] = 
57 {
58
59     { REG_GPR  ,R2_IDX , REG_GPR , "r2",  "ar2", "0", 2, 1 },
60     { REG_GPR  ,R3_IDX , REG_GPR , "r3",  "ar3", "0", 3, 1 },
61     { REG_GPR  ,R4_IDX , REG_GPR , "r4",  "ar4", "0", 4, 1 },
62     { REG_GPR  ,R5_IDX , REG_GPR , "r5",  "ar5", "0", 5, 1 },
63     { REG_GPR  ,R6_IDX , REG_GPR , "r6",  "ar6", "0", 6, 1 },
64     { REG_GPR  ,R7_IDX , REG_GPR , "r7",  "ar7", "0", 7, 1 },
65     { REG_PTR  ,R0_IDX , REG_PTR , "r0" , "ar0", "0", 0, 1 },
66     { REG_PTR  ,R1_IDX , REG_PTR , "r1" , "ar1", "0", 1, 1 },    
67     { REG_GPR  ,X8_IDX , REG_GPR , "x8",  "x8" , "xreg", 0, 1 },
68     { REG_GPR  ,X9_IDX , REG_GPR , "x9",  "x9" , "xreg", 1, 1 },
69     { REG_GPR  ,X10_IDX,REG_GPR , "x10", "x10",  "xreg", 2, 1 },
70     { REG_GPR  ,X11_IDX,REG_GPR , "x11", "x11",  "xreg", 3, 1 },
71     { REG_GPR  ,X12_IDX,REG_GPR , "x12", "x12",  "xreg", 4, 1 },
72     { REG_CND  ,CND_IDX,REG_CND , "C"  , "C"  ,  "xreg", 0, 1 },  
73 };
74 int mcs51_nRegs = 13;
75 static void spillThis (symbol *);
76
77 /*-----------------------------------------------------------------*/
78 /* allocReg - allocates register of given type                     */
79 /*-----------------------------------------------------------------*/
80 static regs *allocReg (short type)
81 {
82     int i;
83
84     for ( i = 0 ; i < mcs51_nRegs ; i++ ) {
85
86         /* if type is given as 0 then any
87            free register will do */
88         if (!type &&
89             regs8051[i].isFree ) {
90             regs8051[i].isFree = 0;
91             if (currFunc)
92                 currFunc->regsUsed = 
93                     bitVectSetBit(currFunc->regsUsed,i);
94             return &regs8051[i];
95         }
96         /* other wise look for specific type
97            of register */
98         if (regs8051[i].isFree && 
99             regs8051[i].type == type) {
100             regs8051[i].isFree = 0;
101             if (currFunc)
102                 currFunc->regsUsed = 
103                     bitVectSetBit(currFunc->regsUsed,i);
104             return &regs8051[i];
105         }
106     }
107     return NULL;
108 }
109
110 /*-----------------------------------------------------------------*/
111 /* mcs51_regWithIdx - returns pointer to register wit index number       */
112 /*-----------------------------------------------------------------*/
113 regs *mcs51_regWithIdx (int idx)
114 {
115     int i ;
116     
117     for (i=0;i < mcs51_nRegs;i++)
118         if (regs8051[i].rIdx == idx)
119             return &regs8051[i];
120
121     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
122            "regWithIdx not found");
123     exit(1);
124 }
125
126 /*-----------------------------------------------------------------*/
127 /* freeReg - frees a register                                      */
128 /*-----------------------------------------------------------------*/
129 static void freeReg (regs *reg)
130 {
131     reg->isFree = 1;
132 }
133
134
135 /*-----------------------------------------------------------------*/
136 /* nFreeRegs - returns number of free registers                    */
137 /*-----------------------------------------------------------------*/
138 static int nFreeRegs (int type)
139 {
140     int i;
141     int nfr=0;
142     
143     for (i = 0 ; i < mcs51_nRegs; i++ )
144         if (regs8051[i].isFree && regs8051[i].type == type)
145             nfr++;
146     return nfr;
147 }
148
149 /*-----------------------------------------------------------------*/
150 /* nfreeRegsType - free registers with type                         */
151 /*-----------------------------------------------------------------*/
152 static int nfreeRegsType (int type)
153 {
154     int nfr ;
155     if (type == REG_PTR) {
156         if ((nfr = nFreeRegs(type)) == 0)
157             return nFreeRegs(REG_GPR);
158     } 
159     
160     return nFreeRegs(type);
161 }
162
163
164 /*-----------------------------------------------------------------*/
165 /* allDefsOutOfRange - all definitions are out of a range          */
166 /*-----------------------------------------------------------------*/
167 static bool allDefsOutOfRange (bitVect *defs,int fseq, int toseq) 
168 {
169     int i ;
170
171     if (!defs)
172         return TRUE ;
173
174     for ( i = 0 ;i < defs->size ; i++ ) {
175         iCode *ic;
176
177         if (bitVectBitValue(defs,i)             &&
178             (ic = hTabItemWithKey(iCodehTab,i)) &&
179             ( ic->seq >= fseq  && ic->seq <= toseq))
180             
181             return FALSE;
182         
183     }
184     
185     return TRUE;
186 }
187   
188 /*-----------------------------------------------------------------*/
189 /* computeSpillable - given a point find the spillable live ranges */
190 /*-----------------------------------------------------------------*/
191 static bitVect *computeSpillable (iCode *ic)
192 {
193     bitVect *spillable ;
194
195     /* spillable live ranges are those that are live at this 
196        point . the following categories need to be subtracted
197        from this set. 
198        a) - those that are already spilt
199        b) - if being used by this one
200        c) - defined by this one */
201     
202     spillable = bitVectCopy(ic->rlive);
203     spillable = 
204         bitVectCplAnd(spillable,_G.spiltSet); /* those already spilt */
205     spillable = 
206         bitVectCplAnd(spillable,ic->uses); /* used in this one */    
207     bitVectUnSetBit(spillable,ic->defKey);
208     spillable = bitVectIntersect(spillable,_G.regAssigned);
209     return spillable;
210     
211 }
212
213 /*-----------------------------------------------------------------*/
214 /* noSpilLoc - return true if a variable has no spil location      */
215 /*-----------------------------------------------------------------*/
216 static int noSpilLoc (symbol *sym, eBBlock *ebp,iCode *ic)
217 {
218     return (sym->usl.spillLoc ? 0 : 1);
219 }
220
221 /*-----------------------------------------------------------------*/
222 /* hasSpilLoc - will return 1 if the symbol has spil location      */
223 /*-----------------------------------------------------------------*/
224 static int hasSpilLoc (symbol *sym, eBBlock *ebp, iCode *ic)
225 {
226     return (sym->usl.spillLoc ? 1 : 0);
227 }
228
229 /*-----------------------------------------------------------------*/
230 /* directSpilLoc - will return 1 if the splilocation is in direct  */
231 /*-----------------------------------------------------------------*/
232 static int directSpilLoc (symbol *sym, eBBlock *ebp, iCode *ic)
233 {
234     if ( sym->usl.spillLoc &&
235          (IN_DIRSPACE(SPEC_OCLS(sym->usl.spillLoc->etype))))
236         return 1;
237     else
238         return 0;
239 }
240
241 /*-----------------------------------------------------------------*/
242 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location*/
243 /*                    but is not used as a pointer                 */
244 /*-----------------------------------------------------------------*/
245 static int hasSpilLocnoUptr (symbol *sym, eBBlock *ebp, iCode *ic)
246 {
247     return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
248 }
249
250 /*-----------------------------------------------------------------*/
251 /* rematable - will return 1 if the remat flag is set              */
252 /*-----------------------------------------------------------------*/
253 static int rematable (symbol *sym, eBBlock *ebp, iCode *ic)
254 {
255     return sym->remat;
256 }
257
258 /*-----------------------------------------------------------------*/
259 /* notUsedInBlock - not used in this block                         */
260 /*-----------------------------------------------------------------*/
261 static int notUsedInBlock (symbol *sym, eBBlock *ebp, iCode *ic)
262 {   
263     return (!bitVectBitsInCommon(sym->defs,ebp->usesDefs) &&
264             allDefsOutOfRange (sym->defs,ebp->fSeq,ebp->lSeq));
265 /*     return (!bitVectBitsInCommon(sym->defs,ebp->usesDefs)); */
266 }
267
268 /*-----------------------------------------------------------------*/
269 /* notUsedInRemaining - not used or defined in remain of the block */
270 /*-----------------------------------------------------------------*/
271 static int notUsedInRemaining (symbol *sym, eBBlock *ebp, iCode *ic)
272 {
273     return ((usedInRemaining (operandFromSymbol(sym),ic) ? 0 : 1) &&
274             allDefsOutOfRange (sym->defs,ic->seq,ebp->lSeq));
275 }
276
277 /*-----------------------------------------------------------------*/
278 /* allLRs - return true for all                                    */
279 /*-----------------------------------------------------------------*/
280 static int allLRs (symbol *sym, eBBlock *ebp, iCode *ic)
281 {
282     return 1;
283 }
284
285 /*-----------------------------------------------------------------*/
286 /* liveRangesWith - applies function to a given set of live range  */
287 /*-----------------------------------------------------------------*/
288 static set *liveRangesWith (bitVect *lrs, int (func)(symbol *,eBBlock *, iCode *),
289                      eBBlock *ebp, iCode *ic)
290 {
291     set *rset = NULL;
292     int i;
293
294     if (!lrs || !lrs->size)
295         return NULL;
296
297     for ( i = 1 ; i < lrs->size ; i++ ) {
298         symbol *sym;
299         if (!bitVectBitValue(lrs,i))
300             continue ;
301
302         /* if we don't find it in the live range 
303            hash table we are in serious trouble */
304         if (!(sym = hTabItemWithKey(liveRanges,i))) {
305             werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
306                    "liveRangesWith could not find liveRange");
307             exit(1);
308         }
309         
310         if (func(sym,ebp,ic) && bitVectBitValue(_G.regAssigned,sym->key))
311             addSetHead(&rset,sym);
312     }
313
314     return rset;
315 }
316
317
318 /*-----------------------------------------------------------------*/
319 /* leastUsedLR - given a set determines which is the least used    */
320 /*-----------------------------------------------------------------*/
321 static symbol *leastUsedLR (set *sset)
322 {
323     symbol *sym = NULL, *lsym = NULL ;
324     
325     sym = lsym = setFirstItem(sset);
326
327     if (!lsym)
328         return NULL;
329
330     for (; lsym; lsym = setNextItem(sset)) {
331         
332         /* if usage is the same then prefer
333            the spill the smaller of the two */
334         if ( lsym->used == sym->used )
335             if (getSize(lsym->type) < getSize(sym->type))
336                 sym = lsym;
337
338         /* if less usage */
339         if (lsym->used < sym->used )
340             sym = lsym;
341         
342    }
343
344     setToNull((void **)&sset);
345     sym->blockSpil = 0;
346     return sym;
347 }
348
349 /*-----------------------------------------------------------------*/
350 /* noOverLap - will iterate through the list looking for over lap  */
351 /*-----------------------------------------------------------------*/
352 static int noOverLap (set *itmpStack, symbol *fsym)
353 {
354     symbol *sym;
355    
356
357     for (sym = setFirstItem(itmpStack); sym;
358          sym = setNextItem(itmpStack)) {
359         if (sym->liveTo > fsym->liveFrom )
360             return 0;
361             
362     }
363
364     return 1;
365 }
366
367 /*-----------------------------------------------------------------*/
368 /* isFree - will return 1 if the a free spil location is found     */
369 /*-----------------------------------------------------------------*/
370 static DEFSETFUNC(isFree)
371 {
372     symbol *sym = item;
373     V_ARG(symbol **,sloc);
374     V_ARG(symbol *,fsym);
375
376     /* if already found */
377     if (*sloc)
378         return 0;
379
380     /* if it is free && and the itmp assigned to
381        this does not have any overlapping live ranges
382        with the one currently being assigned and
383        the size can be accomodated  */
384     if (sym->isFree                        && 
385         noOverLap(sym->usl.itmpStack,fsym) &&
386         getSize(sym->type) >= getSize(fsym->type)) {
387         *sloc = sym;
388         return 1;
389     }
390
391     return 0;
392 }
393
394 /*-----------------------------------------------------------------*/
395 /* spillLRWithPtrReg :- will spil those live ranges which use PTR  */
396 /*-----------------------------------------------------------------*/
397 static void spillLRWithPtrReg (symbol *forSym)
398 {
399     symbol *lrsym;
400     regs *r0,*r1;
401     int k;
402
403     if (!_G.regAssigned ||
404         bitVectIsZero(_G.regAssigned))
405         return;
406
407     r0 = mcs51_regWithIdx(R0_IDX);
408     r1 = mcs51_regWithIdx(R1_IDX);
409
410     /* for all live ranges */
411     for (lrsym = hTabFirstItem(liveRanges,&k) ; lrsym ; 
412          lrsym = hTabNextItem(liveRanges,&k) ) {
413         int j;       
414
415         /* if no registers assigned to it or
416            spilt */
417         /* if it does not overlap with this then 
418            not need to spill it */
419
420         if (lrsym->isspilt || !lrsym->nRegs ||
421             (lrsym->liveTo < forSym->liveFrom))
422             continue ;
423
424         /* go thru the registers : if it is either
425            r0 or r1 then spil it */
426         for (j = 0 ; j < lrsym->nRegs ; j++ ) 
427             if (lrsym->regs[j] == r0 ||
428                 lrsym->regs[j] == r1 ) {
429                 spillThis (lrsym);
430                 break;
431             }
432     }
433
434 }
435
436 /*-----------------------------------------------------------------*/
437 /* createStackSpil - create a location on the stack to spil        */
438 /*-----------------------------------------------------------------*/
439 static symbol *createStackSpil (symbol *sym)
440 {
441     symbol *sloc= NULL;
442     int useXstack, model, noOverlay;
443     int stackAuto;
444
445     /* first go try and find a free one that is already 
446        existing on the stack */
447     if (applyToSet(_G.stackSpil,isFree,&sloc, sym)) {
448         /* found a free one : just update & return */
449         sym->usl.spillLoc = sloc;
450         sym->stackSpil= 1;
451         sloc->isFree = 0;
452         addSetHead(&sloc->usl.itmpStack,sym);
453         return sym;
454     }
455
456     /* could not then have to create one , this is the hard part
457        we need to allocate this on the stack : this is really a
458        hack!! but cannot think of anything better at this time */
459         
460     sprintf(buffer,"sloc%d",_G.slocNum++);
461     sloc = newiTemp(buffer);
462
463     /* set the type to the spilling symbol */
464     sloc->type = copyLinkChain(sym->type);
465     sloc->etype = getSpec(sloc->type);
466     SPEC_SCLS(sloc->etype) = S_AUTO ;    
467     SPEC_EXTR(sloc->etype) = 0;
468
469     /* we don't allow it to be allocated`
470        onto the external stack since : so we
471        temporarily turn it off ; we also
472        turn off memory model to prevent
473        the spil from going to the external storage
474        and turn off overlaying 
475     */
476     
477     useXstack = options.useXstack;
478     model = options.model;
479     noOverlay = options.noOverlay;
480     stackAuto = options.stackAuto;
481     options.noOverlay = 1;
482     options.model = options.useXstack = 0;
483
484     allocLocal(sloc);
485
486     options.useXstack = useXstack;
487     options.model     = model;
488     options.noOverlay = noOverlay;
489     options.stackAuto = stackAuto;
490     sloc->isref = 1; /* to prevent compiler warning */
491     
492     /* if it is on the stack then update the stack */
493     if (IN_STACK(sloc->etype)) {
494         currFunc->stack += getSize(sloc->type);
495         _G.stackExtend += getSize(sloc->type);
496     } else
497         _G.dataExtend += getSize(sloc->type);
498
499     /* add it to the _G.stackSpil set */
500     addSetHead(&_G.stackSpil,sloc);
501     sym->usl.spillLoc = sloc;
502     sym->stackSpil = 1;
503     
504     /* add it to the set of itempStack set 
505        of the spill location */
506     addSetHead(&sloc->usl.itmpStack,sym);
507     return sym;
508 }
509
510 /*-----------------------------------------------------------------*/
511 /* isSpiltOnStack - returns true if the spil location is on stack  */
512 /*-----------------------------------------------------------------*/
513 static bool isSpiltOnStack (symbol *sym)
514 {
515     link *etype;
516
517     if (!sym)
518         return FALSE ;
519     
520     if (!sym->isspilt)
521         return FALSE ;
522
523 /*     if (sym->_G.stackSpil) */
524 /*      return TRUE; */
525     
526     if (!sym->usl.spillLoc)
527         return FALSE;
528
529     etype = getSpec(sym->usl.spillLoc->type);
530     if (IN_STACK(etype))
531         return TRUE;
532
533     return FALSE ;
534 }
535
536 /*-----------------------------------------------------------------*/
537 /* spillThis - spils a specific operand                            */
538 /*-----------------------------------------------------------------*/
539 static void spillThis (symbol *sym)
540 {
541     int i;
542     /* if this is rematerializable or has a spillLocation
543        we are okay, else we need to create a spillLocation
544        for it */
545     if (!(sym->remat || sym->usl.spillLoc)) 
546         createStackSpil (sym);
547     
548
549     /* mark it has spilt & put it in the spilt set */
550     sym->isspilt = 1;
551     _G.spiltSet = bitVectSetBit(_G.spiltSet,sym->key);
552        
553     bitVectUnSetBit(_G.regAssigned,sym->key);
554
555     for (i = 0 ; i < sym->nRegs ; i++)
556
557         if (sym->regs[i]) {
558             freeReg(sym->regs[i]);
559             sym->regs[i] = NULL;
560         }
561     
562     /* if spilt on stack then free up r0 & r1 
563        if they could have been assigned to some
564        LIVE ranges */
565     if (!mcs51_ptrRegReq && isSpiltOnStack(sym)) {
566         mcs51_ptrRegReq++ ;
567         spillLRWithPtrReg(sym);
568     }
569
570     if (sym->usl.spillLoc && !sym->remat)
571         sym->usl.spillLoc->allocreq = 1;
572     return;
573 }
574
575 /*-----------------------------------------------------------------*/
576 /* selectSpil - select a iTemp to spil : rather a simple procedure */
577 /*-----------------------------------------------------------------*/
578 static symbol *selectSpil (iCode *ic, eBBlock *ebp, symbol *forSym)
579 {
580     bitVect *lrcs= NULL ; 
581     set *selectS ;
582     symbol *sym;
583
584     /* get the spillable live ranges */
585     lrcs = computeSpillable (ic);
586
587     /* get all live ranges that are rematerizable */
588     if ((selectS = liveRangesWith(lrcs,rematable,ebp,ic))) {
589
590         /* return the least used of these */
591         return leastUsedLR(selectS);
592     }
593
594     /* get live ranges with spillLocations in direct space */
595     if ((selectS = liveRangesWith(lrcs,directSpilLoc,ebp,ic))) {
596         sym = leastUsedLR(selectS);
597         strcpy(sym->rname,(sym->usl.spillLoc->rname[0] ? 
598                            sym->usl.spillLoc->rname : 
599                            sym->usl.spillLoc->name)); 
600         sym->spildir = 1;
601         /* mark it as allocation required */
602         sym->usl.spillLoc->allocreq = 1;
603         return sym;
604     }
605
606     /* if the symbol is local to the block then */        
607     if (forSym->liveTo < ebp->lSeq ) {       
608
609         /* check if there are any live ranges allocated
610            to registers that are not used in this block */
611         if (!_G.blockSpil && (selectS = liveRangesWith(lrcs,notUsedInBlock,ebp,ic))) {
612             sym = leastUsedLR(selectS);
613             /* if this is not rematerializable */
614             if (!sym->remat) {
615                 _G.blockSpil++;
616                 sym->blockSpil = 1;
617             }
618             return sym;
619         } 
620
621         /* check if there are any live ranges that not
622            used in the remainder of the block */
623         if (!_G.blockSpil && (selectS = liveRangesWith(lrcs,notUsedInRemaining,ebp,ic))) {
624             sym = leastUsedLR (selectS);
625             if (!sym->remat) {
626                 sym->remainSpil = 1;
627                 _G.blockSpil++;
628             }
629             return sym;
630         }
631     }   
632
633     /* find live ranges with spillocation && not used as pointers */
634     if ((selectS = liveRangesWith(lrcs,hasSpilLocnoUptr,ebp,ic))) {
635        
636         sym =  leastUsedLR(selectS);
637         /* mark this as allocation required */
638         sym->usl.spillLoc->allocreq = 1;
639         return sym;
640     }
641
642     /* find live ranges with spillocation */
643     if ((selectS = liveRangesWith(lrcs,hasSpilLoc,ebp,ic))) {
644         
645         sym = leastUsedLR(selectS);
646         sym->usl.spillLoc->allocreq = 1;
647         return sym;
648     }
649
650     /* couldn't find then we need to create a spil
651        location on the stack , for which one? the least
652        used ofcourse */
653     if ((selectS = liveRangesWith(lrcs,noSpilLoc,ebp,ic))) {
654         
655         /* return a created spil location */
656         sym = createStackSpil(leastUsedLR(selectS));
657         sym->usl.spillLoc->allocreq = 1;
658         return sym;
659     }
660     
661     /* this is an extreme situation we will spill
662        this one : happens very rarely but it does happen */
663     spillThis ( forSym );
664     return forSym ;
665    
666 }
667
668 /*-----------------------------------------------------------------*/
669 /* spilSomething - spil some variable & mark registers as free     */
670 /*-----------------------------------------------------------------*/
671 static bool spilSomething (iCode *ic, eBBlock *ebp, symbol *forSym)
672 {
673     symbol *ssym;
674     int i ;
675
676     /* get something we can spil */
677     ssym = selectSpil(ic,ebp,forSym);
678     
679     /* mark it as spilt */
680     ssym->isspilt = 1;
681     _G.spiltSet = bitVectSetBit(_G.spiltSet,ssym->key);
682     
683     /* mark it as not register assigned &
684        take it away from the set */   
685     bitVectUnSetBit(_G.regAssigned,ssym->key);
686  
687     /* mark the registers as free */    
688     for (i = 0 ; i < ssym->nRegs ;i++ )
689         if (ssym->regs[i])
690             freeReg(ssym->regs[i]);
691      
692     /* if spilt on stack then free up r0 & r1 
693        if they could have been assigned to as gprs */
694     if (!mcs51_ptrRegReq && isSpiltOnStack(ssym) ) {
695         mcs51_ptrRegReq++ ;
696         spillLRWithPtrReg(ssym);
697     }
698
699     /* if this was a block level spil then insert push & pop 
700        at the start & end of block respectively */
701     if (ssym->blockSpil) {
702         iCode *nic = newiCode(IPUSH,operandFromSymbol(ssym),NULL);
703         /* add push to the start of the block */
704         addiCodeToeBBlock(ebp,nic,( ebp->sch->op == LABEL ? 
705                                     ebp->sch->next : ebp->sch));
706         nic = newiCode(IPOP,operandFromSymbol(ssym),NULL);
707         /* add pop to the end of the block */
708         addiCodeToeBBlock(ebp,nic,NULL);
709     }       
710
711     /* if spilt because not used in the remainder of the
712        block then add a push before this instruction and
713        a pop at the end of the block */
714     if (ssym->remainSpil) {
715
716         iCode *nic = newiCode(IPUSH,operandFromSymbol(ssym),NULL);
717         /* add push just before this instruction */
718         addiCodeToeBBlock(ebp,nic,ic);
719                                     
720         nic = newiCode(IPOP,operandFromSymbol(ssym),NULL);
721         /* add pop to the end of the block */
722         addiCodeToeBBlock(ebp,nic,NULL);    
723     }
724
725     if (ssym == forSym )
726         return FALSE ;
727     else
728         return TRUE ;
729 }
730
731 /*-----------------------------------------------------------------*/
732 /* getRegPtr - will try for PTR if not a GPR type if not spil      */
733 /*-----------------------------------------------------------------*/
734 regs *getRegPtr (iCode *ic, eBBlock *ebp, symbol *sym)
735 {
736     regs *reg;
737
738  tryAgain:
739     /* try for a ptr type */
740     if ((reg = allocReg(REG_PTR))) 
741         return reg;    
742
743     /* try for gpr type */
744     if ((reg = allocReg(REG_GPR)))        
745         return reg;    
746
747     /* we have to spil */
748     if (!spilSomething (ic,ebp,sym))
749         return NULL ;
750
751     /* this looks like an infinite loop but 
752        in really selectSpil will abort  */
753     goto tryAgain ;    
754 }
755
756 /*-----------------------------------------------------------------*/
757 /* getRegGpr - will try for GPR if not spil                        */
758 /*-----------------------------------------------------------------*/
759 static regs *getRegGpr (iCode *ic, eBBlock *ebp,symbol *sym)
760 {
761     regs *reg;
762
763  tryAgain:
764     /* try for gpr type */
765     if ((reg = allocReg(REG_GPR)))        
766         return reg;    
767
768     if (!mcs51_ptrRegReq)
769         if ((reg = allocReg(REG_PTR)))
770             return reg ;
771         
772     /* we have to spil */
773     if (!spilSomething (ic,ebp,sym))
774         return NULL ;
775
776     /* this looks like an infinite loop but 
777        in really selectSpil will abort  */
778     goto tryAgain ;    
779 }
780
781 /*-----------------------------------------------------------------*/
782 /* symHasReg - symbol has a given register                         */
783 /*-----------------------------------------------------------------*/
784 static bool symHasReg(symbol *sym,regs *reg)
785 {
786     int i;
787
788     for ( i = 0 ; i < sym->nRegs ; i++)
789         if (sym->regs[i] == reg)
790             return TRUE;
791             
792     return FALSE;
793 }
794
795 /*-----------------------------------------------------------------*/
796 /* deassignLRs - check the live to and if they have registers & are*/
797 /*               not spilt then free up the registers              */
798 /*-----------------------------------------------------------------*/
799 static void deassignLRs (iCode *ic, eBBlock *ebp)
800 {
801     symbol *sym;
802     int k;
803     symbol *result;
804
805     for (sym = hTabFirstItem(liveRanges,&k); sym;
806          sym = hTabNextItem(liveRanges,&k)) {
807         
808         symbol *psym= NULL;
809         /* if it does not end here */
810         if (sym->liveTo > ic->seq )
811             continue ;
812
813         /* if it was spilt on stack then we can 
814            mark the stack spil location as free */
815         if (sym->isspilt ) {
816             if (sym->stackSpil) {
817                 sym->usl.spillLoc->isFree = 1;
818                 sym->stackSpil = 0;
819             }
820             continue ;
821         }
822         
823         if (!bitVectBitValue(_G.regAssigned,sym->key))
824             continue;
825         
826         /* special case check if this is an IFX &
827            the privious one was a pop and the 
828            previous one was not spilt then keep track
829            of the symbol */     
830         if (ic->op == IFX && ic->prev &&
831             ic->prev->op == IPOP && 
832             !ic->prev->parmPush  &&
833             !OP_SYMBOL(IC_LEFT(ic->prev))->isspilt) 
834             psym = OP_SYMBOL(IC_LEFT(ic->prev));
835
836         if (sym->nRegs) {
837             int i = 0;
838             
839             bitVectUnSetBit(_G.regAssigned,sym->key);
840
841             /* if the result of this one needs registers
842                and does not have it then assign it right
843                away */
844             if (IC_RESULT(ic) &&
845                 !  (SKIP_IC2(ic) ||               /* not a special icode */
846                     ic->op == JUMPTABLE ||
847                     ic->op == IFX ||
848                     ic->op == IPUSH ||
849                     ic->op == IPOP ||
850                     ic->op == RETURN ||
851                     POINTER_SET(ic))     &&             
852                 (result = OP_SYMBOL(IC_RESULT(ic))) && /* has a result */
853                 result->liveTo > ic->seq &&            /* and will live beyond this */
854                 result->liveTo <= ebp->lSeq &&         /* does not go beyond this block */
855                 result->regType == sym->regType &&     /* same register types */
856                 result->nRegs            &&            /* which needs registers */
857                 ! result->isspilt        &&            /* and does not already have them */
858                 ! result->remat          &&
859                 ! bitVectBitValue(_G.regAssigned,result->key) &&
860                 /* the number of free regs + number of regs in this LR
861                    can accomodate the what result Needs */
862                 ((nfreeRegsType(result->regType) +
863                   sym->nRegs) >= result->nRegs)
864                 ) {
865                 
866                 for (i = 0 ; i < max(sym->nRegs,result->nRegs) ; i++)
867                     if (i < sym->nRegs )
868                         result->regs[i] = sym->regs[i] ;
869                     else
870                         result->regs[i] = getRegGpr (ic,ebp,result);
871
872                 _G.regAssigned = bitVectSetBit(_G.regAssigned,result->key);
873                 
874             }                   
875             
876             /* free the remaining */
877             for (; i < sym->nRegs ; i++) {
878                 if (psym) {
879                     if (!symHasReg(psym,sym->regs[i]))
880                         freeReg(sym->regs[i]);
881                 } else
882                     freeReg(sym->regs[i]);
883             }
884         }
885     }
886 }
887
888
889 /*-----------------------------------------------------------------*/
890 /* reassignLR - reassign this to registers                         */
891 /*-----------------------------------------------------------------*/
892 static void reassignLR (operand *op)
893 {
894     symbol *sym = OP_SYMBOL(op);
895     int i;
896
897     /* not spilt any more */     
898     sym->isspilt = sym->blockSpil  = sym->remainSpil = 0;
899     bitVectUnSetBit(_G.spiltSet,sym->key);
900       
901     _G.regAssigned = bitVectSetBit(_G.regAssigned,sym->key);
902
903     _G.blockSpil--;
904
905     for (i=0;i<sym->nRegs;i++)
906         sym->regs[i]->isFree = 0;
907 }
908
909 /*-----------------------------------------------------------------*/
910 /* willCauseSpill - determines if allocating will cause a spill    */
911 /*-----------------------------------------------------------------*/
912 static int willCauseSpill ( int nr, int rt)
913 {
914     /* first check if there are any avlb registers
915        of te type required */
916     if (rt == REG_PTR) {
917         /* special case for pointer type 
918            if pointer type not avlb then 
919            check for type gpr */
920         if (nFreeRegs(rt) >= nr)
921             return 0;
922         if (nFreeRegs(REG_GPR) >= nr)
923             return 0;
924     } else {
925         if (mcs51_ptrRegReq) {
926             if (nFreeRegs(rt) >= nr)
927                 return 0;
928         } else {
929             if (nFreeRegs(REG_PTR) +
930                 nFreeRegs(REG_GPR) >= nr)
931                 return 0;
932         }
933     }
934
935     /* it will cause a spil */
936     return 1;
937 }
938
939 /*-----------------------------------------------------------------*/
940 /* positionRegs - the allocator can allocate same registers to res-*/
941 /* ult and operand, if this happens make sure they are in the same */
942 /* position as the operand otherwise chaos results                 */
943 /*-----------------------------------------------------------------*/
944 static void positionRegs (symbol *result, symbol *opsym, int lineno)
945 {
946         int count = min(result->nRegs,opsym->nRegs);
947         int i , j = 0, shared = 0;
948
949         /* if the result has been spilt then cannot share */
950         if (opsym->isspilt)
951                 return ;
952  again:
953         shared = 0;
954         /* first make sure that they actually share */
955         for ( i = 0 ; i < count; i++ ) {
956                 for (j = 0 ; j < count ; j++ ) {
957                         if (result->regs[i] == opsym->regs[j] && i !=j) {
958                                 shared = 1;
959                                 goto xchgPositions;
960                         }
961                 }
962         }
963  xchgPositions:
964         if (shared) {
965                 regs *tmp = result->regs[i];
966                 result->regs[i] = result->regs[j];
967                 result->regs[j] = tmp;          
968                 goto again;
969         }
970 }
971
972 /*-----------------------------------------------------------------*/
973 /* serialRegAssign - serially allocate registers to the variables  */
974 /*-----------------------------------------------------------------*/
975 static void serialRegAssign (eBBlock **ebbs, int count)
976 {
977     int i;
978
979     /* for all blocks */
980     for (i = 0; i < count ; i++ ) {
981         
982         iCode *ic;
983         
984         if (ebbs[i]->noPath &&
985             (ebbs[i]->entryLabel != entryLabel &&
986              ebbs[i]->entryLabel != returnLabel ))
987             continue ;
988
989         /* of all instructions do */
990         for (ic = ebbs[i]->sch ; ic ; ic = ic->next) {
991          
992             /* if this is an ipop that means some live
993                range will have to be assigned again */
994             if (ic->op == IPOP)
995                 reassignLR (IC_LEFT(ic));
996
997             /* if result is present && is a true symbol */
998             if (IC_RESULT(ic) && ic->op != IFX &&
999                 IS_TRUE_SYMOP(IC_RESULT(ic)))
1000                 OP_SYMBOL(IC_RESULT(ic))->allocreq = 1;
1001
1002             /* take away registers from live
1003                ranges that end at this instruction */      
1004             deassignLRs (ic, ebbs[i]) ;         
1005                     
1006             /* some don't need registers */
1007             if (SKIP_IC2(ic) ||
1008                 ic->op == JUMPTABLE ||
1009                 ic->op == IFX ||
1010                 ic->op == IPUSH ||
1011                 ic->op == IPOP ||
1012                 (IC_RESULT(ic) &&POINTER_SET(ic)) )
1013                 continue;   
1014             
1015             /* now we need to allocate registers
1016                only for the result */
1017             if (IC_RESULT(ic)) {
1018                 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
1019                 bitVect *spillable;
1020                 int willCS ;
1021                 int j;
1022                 int ptrRegSet = 0;
1023                                
1024                 /* if it does not need or is spilt 
1025                    or is already assigned to registers
1026                    or will not live beyond this instructions */
1027                 if (!sym->nRegs      || 
1028                     sym->isspilt     || 
1029                     bitVectBitValue(_G.regAssigned,sym->key) ||
1030                     sym->liveTo <= ic->seq)
1031                     continue ;
1032
1033                 /* if some liverange has been spilt at the block level
1034                    and this one live beyond this block then spil this
1035                    to be safe */
1036                 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq) {
1037                     spillThis (sym);
1038                     continue ;
1039                 }
1040                 /* if trying to allocate this will cause
1041                    a spill and there is nothing to spill 
1042                    or this one is rematerializable then
1043                    spill this one */
1044                 willCS = willCauseSpill(sym->nRegs,sym->regType);
1045                 spillable = computeSpillable(ic);
1046                 if ( sym->remat ||                  
1047                     (willCS  && bitVectIsZero(spillable) ) ) {
1048
1049                     spillThis (sym) ;
1050                     continue ;
1051
1052                 }
1053
1054                 /* if it has a spillocation & is used less than
1055                    all other live ranges then spill this */
1056                 if ( willCS && sym->usl.spillLoc ) {
1057
1058                     symbol *leastUsed = 
1059                         leastUsedLR(liveRangesWith (spillable ,
1060                                                     allLRs,
1061                                                     ebbs[i],
1062                                                     ic));
1063                     if (leastUsed && 
1064                         leastUsed->used > sym->used) {
1065                         spillThis (sym);
1066                         continue;
1067                     }
1068                 }               
1069                 
1070                 /* if we need ptr regs for the right side
1071                    then mark it */
1072                 if (POINTER_GET(ic) && getSize(OP_SYMBOL(IC_LEFT(ic))->type) 
1073                     <= PTRSIZE) 
1074                 {
1075                     mcs51_ptrRegReq++;
1076                     ptrRegSet = 1;
1077                 }
1078                 /* else we assign registers to it */            
1079                 _G.regAssigned = bitVectSetBit(_G.regAssigned,sym->key);
1080
1081                 for (j = 0 ; j < sym->nRegs ;j++ ) {
1082                     if (sym->regType == REG_PTR)
1083                         sym->regs[j] = getRegPtr(ic,ebbs[i],sym);
1084                     else
1085                         sym->regs[j] = getRegGpr(ic,ebbs[i],sym);
1086
1087                     /* if the allocation falied which means
1088                        this was spilt then break */
1089                     if (!sym->regs[j])
1090                         break;
1091                 }
1092                 /* if it shares registers with operands make sure
1093                    that they are in the same position */
1094                 if (IC_LEFT(ic) && IS_SYMOP(IC_LEFT(ic)) &&
1095                     OP_SYMBOL(IC_LEFT(ic))->nRegs  && ic->op != '=')
1096                         positionRegs(OP_SYMBOL(IC_RESULT(ic)),
1097                                      OP_SYMBOL(IC_LEFT(ic)),ic->lineno);
1098                 /* do the same for the right operand */
1099                 if (IC_RIGHT(ic) && IS_SYMOP(IC_RIGHT(ic)) &&
1100                     OP_SYMBOL(IC_RIGHT(ic))->nRegs && ic->op != '=')
1101                         positionRegs(OP_SYMBOL(IC_RESULT(ic)),
1102                                      OP_SYMBOL(IC_RIGHT(ic)),ic->lineno);
1103                 
1104                 if (ptrRegSet) {
1105                     mcs51_ptrRegReq--;
1106                     ptrRegSet = 0;
1107                 }
1108                                 
1109             }       
1110         }
1111     }
1112 }
1113
1114 /*-----------------------------------------------------------------*/
1115 /* rUmaskForOp :- returns register mask for an operand             */
1116 /*-----------------------------------------------------------------*/
1117 static bitVect *rUmaskForOp (operand *op)
1118 {
1119     bitVect *rumask;
1120     symbol *sym;
1121     int j;
1122     
1123     /* only temporaries are assigned registers */
1124     if (!IS_ITEMP(op)) 
1125         return NULL;
1126
1127     sym = OP_SYMBOL(op);
1128     
1129     /* if spilt or no registers assigned to it
1130        then nothing */
1131     if (sym->isspilt || !sym->nRegs)
1132         return NULL;
1133
1134     rumask = newBitVect(mcs51_nRegs);
1135
1136     for (j = 0; j < sym->nRegs; j++) {
1137         rumask = bitVectSetBit(rumask,
1138                                sym->regs[j]->rIdx);
1139     }
1140
1141     return rumask;
1142 }
1143
1144 /*-----------------------------------------------------------------*/
1145 /* regsUsedIniCode :- returns bit vector of registers used in iCode*/
1146 /*-----------------------------------------------------------------*/
1147 static bitVect *regsUsedIniCode (iCode *ic)
1148 {
1149     bitVect *rmask = newBitVect(mcs51_nRegs);
1150
1151     /* do the special cases first */
1152     if (ic->op == IFX ) {
1153         rmask = bitVectUnion(rmask,
1154                              rUmaskForOp(IC_COND(ic)));
1155         goto ret;
1156     }
1157
1158     /* for the jumptable */
1159     if (ic->op == JUMPTABLE) {
1160         rmask = bitVectUnion(rmask,
1161                              rUmaskForOp(IC_JTCOND(ic)));
1162
1163         goto ret;
1164     }
1165
1166     /* of all other cases */
1167     if (IC_LEFT(ic)) 
1168         rmask = bitVectUnion(rmask,
1169                              rUmaskForOp(IC_LEFT(ic)));
1170         
1171     
1172     if (IC_RIGHT(ic))
1173         rmask = bitVectUnion(rmask,
1174                              rUmaskForOp(IC_RIGHT(ic)));
1175
1176     if (IC_RESULT(ic))
1177         rmask = bitVectUnion(rmask,
1178                              rUmaskForOp(IC_RESULT(ic)));
1179
1180  ret:
1181     return rmask;
1182 }
1183
1184 /*-----------------------------------------------------------------*/
1185 /* createRegMask - for each instruction will determine the regsUsed*/
1186 /*-----------------------------------------------------------------*/
1187 static void createRegMask (eBBlock **ebbs, int count)
1188 {
1189     int i;
1190
1191     /* for all blocks */
1192     for (i = 0; i < count ; i++ ) {
1193         iCode *ic ;
1194
1195         if ( ebbs[i]->noPath &&
1196              ( ebbs[i]->entryLabel != entryLabel &&
1197                ebbs[i]->entryLabel != returnLabel ))
1198             continue ;
1199
1200         /* for all instructions */
1201         for ( ic = ebbs[i]->sch ; ic ; ic = ic->next ) {
1202             
1203             int j;
1204
1205             if (SKIP_IC2(ic) || !ic->rlive)
1206                 continue ;
1207             
1208             /* first mark the registers used in this
1209                instruction */
1210             ic->rUsed = regsUsedIniCode(ic);
1211             _G.funcrUsed = bitVectUnion(_G.funcrUsed,ic->rUsed);
1212
1213             /* now create the register mask for those 
1214                registers that are in use : this is a
1215                super set of ic->rUsed */
1216             ic->rMask = newBitVect(mcs51_nRegs+1);
1217
1218             /* for all live Ranges alive at this point */
1219             for (j = 1; j < ic->rlive->size; j++ ) {
1220                 symbol *sym;
1221                 int k;
1222
1223                 /* if not alive then continue */
1224                 if (!bitVectBitValue(ic->rlive,j))
1225                     continue ;
1226
1227                 /* find the live range we are interested in */
1228                 if (!(sym = hTabItemWithKey(liveRanges,j))) {
1229                     werror (E_INTERNAL_ERROR,__FILE__,__LINE__,
1230                             "createRegMask cannot find live range");
1231                     exit(0);
1232                 }
1233
1234                 /* if no register assigned to it */
1235                 if (!sym->nRegs || sym->isspilt)
1236                     continue ;
1237
1238                 /* for all the registers allocated to it */
1239                 for (k = 0 ; k < sym->nRegs ;k++)
1240                     if (sym->regs[k])
1241                         ic->rMask =
1242                             bitVectSetBit(ic->rMask,sym->regs[k]->rIdx);
1243             }
1244         }
1245     }
1246 }
1247
1248 /*-----------------------------------------------------------------*/
1249 /* rematStr - returns the rematerialized string for a remat var    */
1250 /*-----------------------------------------------------------------*/
1251 static char *rematStr (symbol *sym)
1252 {
1253     char *s = buffer;   
1254     iCode *ic = sym->rematiCode;    
1255
1256     while (1) {
1257
1258         /* if plus or minus print the right hand side */
1259         if (ic->op == '+' || ic->op == '-') {
1260             sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
1261                     ic->op );
1262             s += strlen(s);
1263             ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
1264             continue ;
1265         }
1266
1267         /* we reached the end */
1268         sprintf(s,"%s",OP_SYMBOL(IC_LEFT(ic))->rname);
1269         break;
1270     }
1271
1272     return buffer ;
1273 }
1274
1275 /*-----------------------------------------------------------------*/
1276 /* regTypeNum - computes the type & number of registers required   */
1277 /*-----------------------------------------------------------------*/
1278 static void regTypeNum ()
1279 {
1280     symbol *sym;
1281     int k;
1282     iCode *ic;
1283
1284     /* for each live range do */
1285     for ( sym = hTabFirstItem(liveRanges,&k); sym ;
1286           sym = hTabNextItem(liveRanges,&k)) {
1287
1288         /* if used zero times then no registers needed */
1289         if ((sym->liveTo - sym->liveFrom) == 0)
1290             continue ;
1291
1292
1293         /* if the live range is a temporary */
1294         if (sym->isitmp) {
1295
1296             /* if the type is marked as a conditional */
1297             if (sym->regType == REG_CND)
1298                 continue ;
1299
1300             /* if used in return only then we don't 
1301                need registers */
1302             if (sym->ruonly || sym->accuse) {
1303                 if (IS_AGGREGATE(sym->type) || sym->isptr)
1304                     sym->type = aggrToPtr(sym->type,FALSE);
1305                 continue ;
1306             }
1307             
1308             /* if the symbol has only one definition &
1309                that definition is a get_pointer and the
1310                pointer we are getting is rematerializable and
1311                in "data" space */
1312                
1313             if (bitVectnBitsOn(sym->defs) == 1 &&
1314                 (ic = hTabItemWithKey(iCodehTab,
1315                                       bitVectFirstBit(sym->defs))) &&
1316                 POINTER_GET(ic) && 
1317                 !IS_BITVAR(sym->etype)) {
1318                 
1319                                 
1320                 /* if remat in data space */
1321                 if (OP_SYMBOL(IC_LEFT(ic))->remat &&
1322                     DCL_TYPE(aggrToPtr(sym->type,FALSE)) == POINTER) {
1323                 
1324                     /* create a psuedo symbol & force a spil */
1325                     symbol *psym = newSymbol(rematStr(OP_SYMBOL(IC_LEFT(ic))),1);
1326                     psym->type = sym->type;
1327                     psym->etype = sym->etype;
1328                     strcpy(psym->rname,psym->name);
1329                     sym->isspilt = 1;
1330                     sym->usl.spillLoc = psym;
1331                     continue ;
1332                 }
1333
1334                 /* if in data space or idata space then try to
1335                    allocate pointer register */
1336                    
1337             }
1338                 
1339             /* if not then we require registers */
1340             sym->nRegs = ((IS_AGGREGATE(sym->type) || sym->isptr ) ?
1341                           getSize(sym->type = aggrToPtr(sym->type,FALSE)) :
1342                           getSize(sym->type));
1343
1344             if (sym->nRegs > 4) {
1345                 fprintf(stderr,"allocated more than 4 or 0 registers for type ");
1346                 printTypeChain(sym->type,stderr);fprintf(stderr,"\n");
1347             }
1348             
1349             /* determine the type of register required */
1350             if (sym->nRegs == 1   && 
1351                 IS_PTR(sym->type) && 
1352                 sym->uptr) 
1353                 sym->regType = REG_PTR ;            
1354             else 
1355                 sym->regType = REG_GPR ;
1356             
1357         } else 
1358             /* for the first run we don't provide */
1359             /* registers for true symbols we will */
1360             /* see how things go                  */
1361             sym->nRegs = 0 ;    
1362     }
1363     
1364 }
1365
1366 /*-----------------------------------------------------------------*/
1367 /* freeAllRegs - mark all registers as free                        */
1368 /*-----------------------------------------------------------------*/
1369 static void freeAllRegs()
1370 {
1371     int i;
1372
1373     for (i=0;i< mcs51_nRegs;i++ )
1374         regs8051[i].isFree = 1;
1375 }
1376
1377 /*-----------------------------------------------------------------*/
1378 /* deallocStackSpil - this will set the stack pointer back         */
1379 /*-----------------------------------------------------------------*/
1380 static DEFSETFUNC(deallocStackSpil)
1381 {
1382     symbol *sym = item;
1383
1384     deallocLocal(sym);
1385     return 0;
1386 }
1387
1388 /*-----------------------------------------------------------------*/
1389 /* farSpacePackable - returns the packable icode for far variables */
1390 /*-----------------------------------------------------------------*/
1391 static iCode *farSpacePackable (iCode *ic)
1392 {
1393     iCode *dic ;
1394
1395     /* go thru till we find a definition for the
1396        symbol on the right */
1397     for ( dic = ic->prev ; dic ; dic = dic->prev) {
1398                 
1399         /* if the definition is a call then no */
1400         if ((dic->op == CALL || dic->op == PCALL) &&
1401             IC_RESULT(dic)->key == IC_RIGHT(ic)->key) {
1402             return NULL;
1403         }
1404         
1405         /* if shift by unknown amount then not */
1406         if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
1407             IC_RESULT(dic)->key == IC_RIGHT(ic)->key)
1408             return NULL;
1409
1410         /* if pointer get and size > 1 */
1411         if (POINTER_GET(dic) &&
1412             getSize(aggrToPtr(operandType(IC_LEFT(dic)),FALSE)) > 1)
1413             return NULL ;
1414
1415         if (POINTER_SET(dic) &&
1416             getSize(aggrToPtr(operandType(IC_RESULT(dic)),FALSE)) > 1)
1417             return NULL ;
1418
1419         /* if any three is a true symbol in far space */
1420         if (IC_RESULT(dic) &&
1421             IS_TRUE_SYMOP(IC_RESULT(dic)) &&
1422             isOperandInFarSpace(IC_RESULT(dic)))         
1423             return NULL;
1424
1425         if (IC_RIGHT(dic) &&
1426             IS_TRUE_SYMOP(IC_RIGHT(dic)) &&
1427             isOperandInFarSpace(IC_RIGHT(dic)) &&
1428             !isOperandEqual(IC_RIGHT(dic),IC_RESULT(ic)))
1429             return NULL;
1430
1431         if (IC_LEFT(dic) &&
1432             IS_TRUE_SYMOP(IC_LEFT(dic)) &&
1433             isOperandInFarSpace(IC_LEFT(dic)) &&
1434             !isOperandEqual(IC_LEFT(dic),IC_RESULT(ic)))
1435             return NULL;
1436         
1437         if (isOperandEqual(IC_RIGHT(ic),IC_RESULT(dic))) {
1438             if ( (dic->op == LEFT_OP  ||
1439                   dic->op == RIGHT_OP ||
1440                   dic->op == '-') &&
1441                  IS_OP_LITERAL(IC_RIGHT(dic)))
1442                 return NULL;
1443             else
1444                 return dic;
1445         }
1446     }
1447
1448     return NULL;
1449 }
1450
1451 /*-----------------------------------------------------------------*/
1452 /* packRegsForAssign - register reduction for assignment           */
1453 /*-----------------------------------------------------------------*/
1454 static int packRegsForAssign (iCode *ic,eBBlock *ebp)
1455 {
1456     iCode *dic, *sic;
1457     
1458     if (
1459 /*      !IS_TRUE_SYMOP(IC_RESULT(ic)) ||            */
1460         !IS_ITEMP(IC_RIGHT(ic))       ||        
1461         OP_LIVETO(IC_RIGHT(ic)) > ic->seq ||
1462         OP_SYMBOL(IC_RIGHT(ic))->isind)
1463         return 0;
1464         
1465     /* if the true symbol is defined in far space or on stack
1466        then we should not since this will increase register pressure */
1467     if (isOperandInFarSpace(IC_RESULT(ic))) {
1468         if ((dic = farSpacePackable(ic)))
1469             goto pack;
1470         else
1471             return 0;
1472         
1473     }
1474     /* find the definition of iTempNN scanning backwards if we find a 
1475        a use of the true symbol in before we find the definition then 
1476        we cannot */     
1477     for ( dic = ic->prev ; dic ; dic = dic->prev) {
1478
1479         /* if there is a function call and this is
1480            a parameter & not my parameter then don't pack it */
1481         if ( (dic->op == CALL || dic->op == PCALL) &&
1482              (OP_SYMBOL(IC_RESULT(ic))->_isparm &&
1483               !OP_SYMBOL(IC_RESULT(ic))->ismyparm)) {
1484             dic = NULL;
1485             break;
1486         }
1487
1488         if (SKIP_IC2(dic))
1489             continue;
1490
1491         if (IS_TRUE_SYMOP(IC_RESULT(dic)) &&
1492             IS_OP_VOLATILE(IC_RESULT(dic))) {
1493                 dic = NULL;
1494                 break;
1495         }
1496
1497         if (IS_SYMOP(IC_RESULT(dic)) &&
1498             IC_RESULT(dic)->key == IC_RIGHT(ic)->key) {
1499             if (POINTER_SET(dic))
1500                 dic = NULL;
1501
1502             break;          
1503         }
1504
1505         if (IS_SYMOP(IC_RIGHT(dic)) && 
1506             (IC_RIGHT(dic)->key == IC_RESULT(ic)->key ||
1507              IC_RIGHT(dic)->key == IC_RIGHT(ic)->key)) {
1508             dic = NULL;
1509             break;
1510         }
1511         
1512         if (IS_SYMOP(IC_LEFT(dic)) && 
1513             (IC_LEFT(dic)->key == IC_RESULT(ic)->key ||
1514              IC_LEFT(dic)->key == IC_RIGHT(ic)->key)) {
1515             dic = NULL;
1516             break;
1517         }
1518
1519         if (POINTER_SET(dic) && 
1520             IC_RESULT(dic)->key == IC_RESULT(ic)->key ) {
1521             dic = NULL ;
1522             break;
1523         }
1524     }
1525     
1526     if (!dic)
1527         return 0 ; /* did not find */
1528             
1529     /* if the result is on stack or iaccess then it must be
1530        the same atleast one of the operands */
1531     if (OP_SYMBOL(IC_RESULT(ic))->onStack  || 
1532         OP_SYMBOL(IC_RESULT(ic))->iaccess ) {
1533         
1534         /* the operation has only one symbol
1535            operator then we can pack */
1536         if ((IC_LEFT(dic) && !IS_SYMOP(IC_LEFT(dic))) ||
1537             (IC_RIGHT(dic) && !IS_SYMOP(IC_RIGHT(dic))))
1538             goto pack;
1539
1540         if (!((IC_LEFT(dic) &&
1541              IC_RESULT(ic)->key == IC_LEFT(dic)->key) ||
1542               (IC_RIGHT(dic) &&
1543                IC_RESULT(ic)->key == IC_RIGHT(dic)->key)))
1544             return 0;                
1545     }
1546 pack:
1547     /* found the definition */
1548     /* replace the result with the result of */
1549     /* this assignment and remove this assignment */
1550     IC_RESULT(dic) = IC_RESULT(ic) ;
1551
1552     if (IS_ITEMP(IC_RESULT(dic)) && OP_SYMBOL(IC_RESULT(dic))->liveFrom > dic->seq) {
1553             OP_SYMBOL(IC_RESULT(dic))->liveFrom = dic->seq;
1554     }
1555     /* delete from liverange table also 
1556        delete from all the points inbetween and the new
1557        one */
1558     for ( sic = dic; sic != ic ; sic = sic->next ) {    
1559         bitVectUnSetBit(sic->rlive,IC_RESULT(ic)->key);
1560         if (IS_ITEMP(IC_RESULT(dic)))
1561             bitVectSetBit(sic->rlive,IC_RESULT(dic)->key);
1562     }
1563         
1564     remiCodeFromeBBlock(ebp,ic);
1565     hTabDeleteItem (&iCodehTab,ic->key,ic,DELETE_ITEM,NULL);
1566     return 1;
1567     
1568 }
1569
1570 /*-----------------------------------------------------------------*/
1571 /* findAssignToSym : scanning backwards looks for first assig found*/
1572 /*-----------------------------------------------------------------*/
1573 static iCode *findAssignToSym (operand *op,iCode *ic)
1574 {
1575     iCode *dic;
1576
1577     for (dic = ic->prev ; dic ; dic = dic->prev) {
1578         
1579         /* if definition by assignment */
1580         if (dic->op == '='                 && 
1581             !POINTER_SET(dic)              &&
1582             IC_RESULT(dic)->key == op->key
1583 /*          &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) */
1584             ) {    
1585
1586             /* we are interested only if defined in far space */
1587             /* or in stack space in case of + & - */
1588
1589             /* if assigned to a non-symbol then return
1590                true */
1591             if (!IS_SYMOP(IC_RIGHT(dic)))
1592                 break ;
1593
1594             /* if the symbol is in far space then
1595                we should not */
1596             if (isOperandInFarSpace(IC_RIGHT(dic)))
1597                 return NULL ;
1598
1599             /* for + & - operations make sure that
1600                if it is on the stack it is the same
1601                as one of the three operands */
1602             if ((ic->op == '+' || ic->op == '-') &&
1603                 OP_SYMBOL(IC_RIGHT(dic))->onStack) {
1604
1605                 if ( IC_RESULT(ic)->key != IC_RIGHT(dic)->key &&
1606                      IC_LEFT(ic)->key   != IC_RIGHT(dic)->key &&
1607                      IC_RIGHT(ic)->key  != IC_RIGHT(dic)->key)
1608                     return NULL;
1609             }           
1610
1611             break ;
1612                 
1613         }
1614
1615         /* if we find an usage then we cannot delete it */
1616         if (IC_LEFT(dic) && IC_LEFT(dic)->key == op->key)
1617             return NULL;
1618             
1619         if (IC_RIGHT(dic) && IC_RIGHT(dic)->key == op->key)
1620             return NULL;
1621
1622         if (POINTER_SET(dic) && IC_RESULT(dic)->key == op->key)
1623             return NULL;
1624     }
1625
1626     /* now make sure that the right side of dic
1627        is not defined between ic & dic */       
1628     if (dic) {
1629         iCode *sic = dic->next ;
1630
1631         for (; sic != ic ; sic = sic->next)
1632             if (IC_RESULT(sic) &&
1633                 IC_RESULT(sic)->key == IC_RIGHT(dic)->key)
1634                 return NULL;
1635     }
1636
1637     return dic;
1638         
1639         
1640 }
1641
1642 /*-----------------------------------------------------------------*/
1643 /* packRegsForSupport :- reduce some registers for support calls   */
1644 /*-----------------------------------------------------------------*/
1645 static int packRegsForSupport (iCode *ic, eBBlock *ebp)
1646 {
1647     int change = 0 ;
1648     /* for the left & right operand :- look to see if the
1649        left was assigned a true symbol in far space in that
1650        case replace them */
1651     if (IS_ITEMP(IC_LEFT(ic)) && 
1652         OP_SYMBOL(IC_LEFT(ic))->liveTo <= ic->seq) {
1653         iCode *dic = findAssignToSym(IC_LEFT(ic),ic);
1654         iCode *sic;
1655
1656         if (!dic)
1657             goto right ;
1658
1659         /* found it we need to remove it from the
1660            block */
1661         for ( sic = dic; sic != ic ; sic = sic->next )
1662             bitVectUnSetBit(sic->rlive,IC_LEFT(ic)->key);
1663
1664         IC_LEFT(ic)->operand.symOperand =
1665             IC_RIGHT(dic)->operand.symOperand;
1666         IC_LEFT(ic)->key = IC_RIGHT(dic)->operand.symOperand->key;
1667         remiCodeFromeBBlock(ebp,dic);
1668         hTabDeleteItem (&iCodehTab,dic->key,dic,DELETE_ITEM,NULL);
1669         change++;      
1670     }
1671     
1672     /* do the same for the right operand */
1673  right:    
1674     if (!change && 
1675         IS_ITEMP(IC_RIGHT(ic)) &&
1676         OP_SYMBOL(IC_RIGHT(ic))->liveTo <= ic->seq) {
1677         iCode *dic = findAssignToSym(IC_RIGHT(ic),ic);
1678         iCode *sic;
1679         
1680         if (!dic)
1681             return change ;
1682
1683         /* if this is a subtraction & the result
1684            is a true symbol in far space then don't pack */
1685         if (ic->op == '-' && IS_TRUE_SYMOP(IC_RESULT(dic))) {
1686             link *etype =getSpec(operandType(IC_RESULT(dic)));
1687             if (IN_FARSPACE(SPEC_OCLS(etype)))
1688                 return change ;
1689         }
1690         /* found it we need to remove it from the
1691            block */
1692         for ( sic = dic; sic != ic ; sic = sic->next )
1693             bitVectUnSetBit(sic->rlive,IC_RIGHT(ic)->key);
1694         
1695         IC_RIGHT(ic)->operand.symOperand =
1696             IC_RIGHT(dic)->operand.symOperand;
1697         IC_RIGHT(ic)->key = IC_RIGHT(dic)->operand.symOperand->key;
1698         
1699         remiCodeFromeBBlock(ebp,dic);
1700         hTabDeleteItem (&iCodehTab,dic->key,dic,DELETE_ITEM,NULL);
1701         change ++;
1702     }
1703    
1704     return change ;
1705 }
1706
1707 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
1708
1709
1710 /*-----------------------------------------------------------------*/
1711 /* packRegsForOneuse : - will reduce some registers for single Use */ 
1712 /*-----------------------------------------------------------------*/
1713 static iCode *packRegsForOneuse (iCode *ic, operand *op , eBBlock *ebp)
1714 {
1715     bitVect *uses ;
1716     iCode *dic, *sic;
1717
1718     /* if returning a literal then do nothing */
1719     if (!IS_SYMOP(op))
1720         return NULL;
1721     
1722     /* only upto 2 bytes since we cannot predict
1723        the usage of b, & acc */
1724     if (getSize(operandType(op)) > 2 && 
1725         ic->op != RETURN             &&
1726         ic->op != SEND)
1727         return NULL;
1728
1729     /* this routine will mark the a symbol as used in one 
1730        instruction use only && if the defintion is local 
1731        (ie. within the basic block) && has only one definition &&
1732        that definiion is either a return value from a 
1733        function or does not contain any variables in
1734        far space */
1735     uses = bitVectCopy(OP_USES(op));
1736     bitVectUnSetBit(uses,ic->key); /* take away this iCode */
1737     if (!bitVectIsZero(uses)) /* has other uses */
1738         return NULL ;
1739     
1740     /* if it has only one defintion */
1741     if (bitVectnBitsOn(OP_DEFS(op)) > 1)
1742         return NULL ; /* has more than one definition */
1743
1744     /* get the that definition */
1745     if (!(dic = 
1746           hTabItemWithKey(iCodehTab,
1747                           bitVectFirstBit(OP_DEFS(op)))))
1748         return NULL ;
1749
1750     /* found the definition now check if it is local */
1751     if (dic->seq < ebp->fSeq ||
1752         dic->seq > ebp->lSeq)
1753         return NULL ; /* non-local */
1754
1755     /* now check if it is the return from
1756        a function call */
1757     if (dic->op == CALL || dic->op == PCALL ) {
1758         if (ic->op != SEND && ic->op != RETURN) {
1759             OP_SYMBOL(op)->ruonly = 1;
1760             return dic;
1761         }
1762         dic = dic->next ;
1763     }
1764         
1765     
1766     /* otherwise check that the definition does
1767        not contain any symbols in far space */
1768     if (isOperandInFarSpace(IC_LEFT(dic))  ||
1769         isOperandInFarSpace(IC_RIGHT(dic)) ||
1770         IS_OP_RUONLY(IC_LEFT(ic))          ||
1771         IS_OP_RUONLY(IC_RIGHT(ic)) )        {
1772         return NULL;
1773     }
1774     
1775     /* if pointer set then make sure the pointer
1776        is one byte */
1777     if (POINTER_SET(dic) && 
1778         !IS_DATA_PTR(aggrToPtr(operandType(IC_RESULT(dic)),FALSE)))
1779         return NULL ;
1780
1781     if (POINTER_GET(dic) && 
1782         !IS_DATA_PTR(aggrToPtr(operandType(IC_LEFT(dic)),FALSE)))
1783         return NULL ;
1784     
1785     sic = dic;
1786
1787     /* also make sure the intervenening instructions
1788        don't have any thing in far space */
1789     for (dic = dic->next ; dic && dic != ic ; dic = dic->next) {
1790                 
1791         /* if there is an intervening function call then no */
1792         if (dic->op == CALL || dic->op == PCALL)
1793                 return NULL;
1794         /* if pointer set then make sure the pointer
1795            is one byte */
1796         if (POINTER_SET(dic) && 
1797             !IS_DATA_PTR(aggrToPtr(operandType(IC_RESULT(dic)),FALSE)))
1798             return NULL ;
1799         
1800         if (POINTER_GET(dic) && 
1801             !IS_DATA_PTR(aggrToPtr(operandType(IC_LEFT(dic)),FALSE)))
1802             return NULL ;
1803
1804         /* if address of & the result is remat the okay */
1805         if (dic->op == ADDRESS_OF &&
1806             OP_SYMBOL(IC_RESULT(dic))->remat)
1807             continue ;
1808            
1809         /* if operand has size of three or more & this
1810            operation is a '*','/' or '%' then 'b' may
1811            cause a problem */
1812         if (( dic->op == '%' || dic->op == '/' || dic->op == '*') &&
1813             getSize(operandType(op)) >= 3)
1814                 return NULL;
1815
1816         /* if left or right or result is in far space */
1817         if (isOperandInFarSpace(IC_LEFT(dic))   ||
1818             isOperandInFarSpace(IC_RIGHT(dic))  ||
1819             isOperandInFarSpace(IC_RESULT(dic)) ||
1820             IS_OP_RUONLY(IC_LEFT(dic))          ||
1821             IS_OP_RUONLY(IC_RIGHT(dic))         ||
1822             IS_OP_RUONLY(IC_RESULT(dic))            ) {
1823             return NULL;
1824         }
1825     }
1826                 
1827     OP_SYMBOL(op)->ruonly = 1;
1828     return sic;
1829         
1830 }
1831
1832 /*-----------------------------------------------------------------*/
1833 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
1834 /*-----------------------------------------------------------------*/
1835 static bool isBitwiseOptimizable (iCode *ic)
1836 {
1837     link *ltype = getSpec(operandType(IC_LEFT(ic)));
1838     link *rtype = getSpec(operandType(IC_RIGHT(ic)));
1839
1840     /* bitwise operations are considered optimizable
1841        under the following conditions (Jean-Louis VERN) 
1842        
1843        x & lit
1844        bit & bit
1845        bit & x
1846        bit ^ bit
1847        bit ^ x
1848        x   ^ lit
1849        x   | lit
1850        bit | bit
1851        bit | x
1852     */    
1853     if ( IS_LITERAL(rtype) ||
1854          (IS_BITVAR(ltype) && IN_BITSPACE(SPEC_OCLS(ltype))))
1855         return TRUE ;
1856     else
1857         return FALSE ;    
1858 }
1859
1860 /*-----------------------------------------------------------------*/
1861 /* packRegsForAccUse - pack registers for acc use                  */
1862 /*-----------------------------------------------------------------*/
1863 static void packRegsForAccUse (iCode *ic)
1864 {
1865     iCode *uic;
1866     
1867     /* if + or - then it has to be one byte result */
1868     if ((ic->op == '+' || ic->op == '-')
1869         && getSize(operandType(IC_RESULT(ic))) > 1)
1870         return ;
1871     
1872     /* if shift operation make sure right side is not a literal */
1873     if (ic->op == RIGHT_OP  &&
1874         ( isOperandLiteral(IC_RIGHT(ic)) ||
1875           getSize(operandType(IC_RESULT(ic))) > 1))
1876         return ;
1877         
1878     if (ic->op == LEFT_OP &&        
1879         ( isOperandLiteral(IC_RIGHT(ic)) ||
1880           getSize(operandType(IC_RESULT(ic))) > 1))
1881         return ;
1882         
1883         
1884     /* has only one definition */
1885     if (bitVectnBitsOn(OP_DEFS(IC_RESULT(ic))) > 1)
1886         return ;
1887
1888     /* has only one use */
1889     if (bitVectnBitsOn(OP_USES(IC_RESULT(ic))) > 1)
1890         return ;
1891
1892     /* and the usage immediately follows this iCode */
1893     if (!(uic = hTabItemWithKey(iCodehTab,
1894                                 bitVectFirstBit(OP_USES(IC_RESULT(ic))))))
1895         return ;
1896
1897     if (ic->next != uic)
1898         return ;
1899     
1900     /* if it is a conditional branch then we definitely can */
1901     if (uic->op == IFX  ) 
1902         goto accuse;
1903
1904     if ( uic->op == JUMPTABLE )
1905         return ;
1906
1907     /* if the usage is not is an assignment
1908        or an arithmetic / bitwise / shift operation then not */
1909     if (POINTER_SET(uic) && 
1910         getSize(aggrToPtr(operandType(IC_RESULT(uic)),FALSE)) > 1)
1911         return;
1912
1913     if (uic->op != '=' && 
1914         !IS_ARITHMETIC_OP(uic) &&
1915         !IS_BITWISE_OP(uic)    &&
1916         uic->op != LEFT_OP &&
1917         uic->op != RIGHT_OP )
1918         return;
1919
1920     /* if used in ^ operation then make sure right is not a 
1921        literl */
1922     if (uic->op == '^' && isOperandLiteral(IC_RIGHT(uic)))
1923         return ;
1924
1925     /* if shift operation make sure right side is not a literal */
1926     if (uic->op == RIGHT_OP  &&
1927         ( isOperandLiteral(IC_RIGHT(uic)) ||
1928           getSize(operandType(IC_RESULT(uic))) > 1))
1929         return ;
1930
1931     if (uic->op == LEFT_OP &&        
1932         ( isOperandLiteral(IC_RIGHT(uic)) ||
1933           getSize(operandType(IC_RESULT(uic))) > 1))
1934         return ;
1935             
1936     /* make sure that the result of this icode is not on the
1937        stack, since acc is used to compute stack offset */
1938     if (IS_TRUE_SYMOP(IC_RESULT(uic)) &&
1939         OP_SYMBOL(IC_RESULT(uic))->onStack)
1940         return ;
1941
1942     /* if either one of them in far space then we cannot */
1943     if ((IS_TRUE_SYMOP(IC_LEFT(uic)) &&
1944          isOperandInFarSpace(IC_LEFT(uic))) ||
1945         (IS_TRUE_SYMOP(IC_RIGHT(uic)) &&
1946          isOperandInFarSpace(IC_RIGHT(uic))))
1947         return ;
1948
1949     /* if the usage has only one operand then we can */
1950     if (IC_LEFT(uic) == NULL ||
1951         IC_RIGHT(uic) == NULL) 
1952         goto accuse;
1953
1954     /* make sure this is on the left side if not
1955        a '+' since '+' is commutative */
1956     if (ic->op != '+' &&
1957         IC_LEFT(uic)->key != IC_RESULT(ic)->key)
1958         return;
1959
1960     /* if one of them is a literal then we can */
1961     if ((IC_LEFT(uic) && IS_OP_LITERAL(IC_LEFT(uic))) ||
1962         (IC_RIGHT(uic) && IS_OP_LITERAL(IC_RIGHT(uic)))) {
1963         OP_SYMBOL(IC_RESULT(ic))->accuse = 1;
1964         return ;
1965     }
1966
1967     /* if the other one is not on stack then we can */
1968     if (IC_LEFT(uic)->key == IC_RESULT(ic)->key &&
1969         (IS_ITEMP(IC_RIGHT(uic)) ||
1970          (IS_TRUE_SYMOP(IC_RIGHT(uic)) &&
1971           !OP_SYMBOL(IC_RIGHT(uic))->onStack))) 
1972         goto accuse;
1973     
1974     if (IC_RIGHT(uic)->key == IC_RESULT(ic)->key &&
1975         (IS_ITEMP(IC_LEFT(uic)) ||
1976          (IS_TRUE_SYMOP(IC_LEFT(uic)) &&
1977           !OP_SYMBOL(IC_LEFT(uic))->onStack))) 
1978         goto accuse ;
1979
1980     return ;
1981
1982  accuse:
1983     OP_SYMBOL(IC_RESULT(ic))->accuse = 1;
1984     
1985         
1986 }
1987
1988 /*-----------------------------------------------------------------*/
1989 /* packForPush - hueristics to reduce iCode for pushing            */
1990 /*-----------------------------------------------------------------*/
1991 static void packForPush(iCode *ic, eBBlock *ebp)
1992 {
1993     iCode *dic;
1994
1995     if (ic->op != IPUSH || !IS_ITEMP(IC_LEFT(ic)))
1996         return ;
1997
1998     /* must have only definition & one usage */
1999     if (bitVectnBitsOn(OP_DEFS(IC_LEFT(ic))) != 1 ||
2000         bitVectnBitsOn(OP_USES(IC_LEFT(ic))) != 1 )     
2001         return ;
2002     
2003     /* find the definition */
2004     if (!(dic = hTabItemWithKey(iCodehTab,
2005                                 bitVectFirstBit(OP_DEFS(IC_LEFT(ic))))))
2006         return ;
2007
2008     if (dic->op != '=' || POINTER_SET(dic))
2009         return;
2010
2011     /* we now we know that it has one & only one def & use
2012        and the that the definition is an assignment */
2013     IC_LEFT(ic) = IC_RIGHT(dic);
2014
2015     remiCodeFromeBBlock(ebp,dic);
2016     hTabDeleteItem (&iCodehTab,dic->key,dic,DELETE_ITEM,NULL);
2017 }
2018
2019 /*-----------------------------------------------------------------*/
2020 /* packRegisters - does some transformations to reduce register    */
2021 /*                   pressure                                      */
2022 /*-----------------------------------------------------------------*/
2023 static void packRegisters (eBBlock *ebp)
2024 {
2025     iCode *ic ;
2026     int change = 0 ;
2027     
2028     while (1) {
2029
2030         change = 0;
2031         
2032         /* look for assignments of the form */
2033         /* iTempNN = TRueSym (someoperation) SomeOperand */
2034         /*       ....                       */
2035         /* TrueSym := iTempNN:1             */
2036         for ( ic = ebp->sch ; ic ; ic = ic->next ) {
2037             
2038             
2039             /* find assignment of the form TrueSym := iTempNN:1 */
2040             if (ic->op == '=' && !POINTER_SET(ic))
2041                 change += packRegsForAssign(ic,ebp);
2042         }
2043
2044         if (!change)
2045             break;
2046     }
2047     
2048     for ( ic = ebp->sch ; ic ; ic = ic->next ) {
2049                 
2050         /* if this is an itemp & result of a address of a true sym 
2051            then mark this as rematerialisable   */
2052         if (ic->op == ADDRESS_OF && 
2053             IS_ITEMP(IC_RESULT(ic)) &&
2054             IS_TRUE_SYMOP(IC_LEFT(ic)) &&
2055             bitVectnBitsOn(OP_DEFS(IC_RESULT(ic))) == 1 &&
2056             !OP_SYMBOL(IC_LEFT(ic))->onStack ) {
2057
2058             OP_SYMBOL(IC_RESULT(ic))->remat = 1;
2059             OP_SYMBOL(IC_RESULT(ic))->rematiCode = ic;
2060             OP_SYMBOL(IC_RESULT(ic))->usl.spillLoc = NULL;
2061
2062         }
2063         
2064         /* if straight assignment then carry remat flag if
2065            this is the only definition */
2066         if (ic->op == '='    && 
2067             !POINTER_SET(ic) &&
2068             IS_SYMOP(IC_RIGHT(ic)) && 
2069             OP_SYMBOL(IC_RIGHT(ic))->remat &&
2070             bitVectnBitsOn(OP_SYMBOL(IC_RESULT(ic))->defs) <= 1) {
2071
2072             OP_SYMBOL(IC_RESULT(ic))->remat = 
2073                 OP_SYMBOL(IC_RIGHT(ic))->remat;
2074             OP_SYMBOL(IC_RESULT(ic))->rematiCode = 
2075                 OP_SYMBOL(IC_RIGHT(ic))->rematiCode ;
2076         }
2077
2078         /* if this is a +/- operation with a rematerizable 
2079            then mark this as rematerializable as well only
2080            if the literal value is within the range -255 and + 255
2081            the assembler cannot handle it other wise */
2082         if ((ic->op == '+' || ic->op == '-') &&
2083
2084             (IS_SYMOP(IC_LEFT(ic)) && 
2085              IS_ITEMP(IC_RESULT(ic)) &&
2086              OP_SYMBOL(IC_LEFT(ic))->remat &&
2087              bitVectnBitsOn(OP_DEFS(IC_RESULT(ic))) == 1 &&
2088              IS_OP_LITERAL(IC_RIGHT(ic))) ) {
2089
2090             int i = operandLitValue(IC_RIGHT(ic));
2091             if ( i < 255 && i > -255) {
2092                 OP_SYMBOL(IC_RESULT(ic))->remat = 1;
2093                 OP_SYMBOL(IC_RESULT(ic))->rematiCode = ic;
2094                 OP_SYMBOL(IC_RESULT(ic))->usl.spillLoc = NULL;
2095             }
2096         }
2097
2098         /* mark the pointer usages */
2099         if (POINTER_SET(ic))
2100             OP_SYMBOL(IC_RESULT(ic))->uptr = 1;
2101
2102         if (POINTER_GET(ic))
2103             OP_SYMBOL(IC_LEFT(ic))->uptr = 1;
2104         
2105         if (!SKIP_IC2(ic)) {
2106             /* if we are using a symbol on the stack
2107                then we should say mcs51_ptrRegReq */
2108             if (ic->op == IFX && IS_SYMOP(IC_COND(ic)))
2109                 mcs51_ptrRegReq += ((OP_SYMBOL(IC_COND(ic))->onStack ||
2110                                OP_SYMBOL(IC_COND(ic))->iaccess) ? 1 : 0);
2111             else
2112                 if (ic->op == JUMPTABLE && IS_SYMOP(IC_JTCOND(ic)))
2113                     mcs51_ptrRegReq += ((OP_SYMBOL(IC_JTCOND(ic))->onStack ||
2114                                    OP_SYMBOL(IC_JTCOND(ic))->iaccess) ? 1 : 0);
2115                 else {
2116                     if (IS_SYMOP(IC_LEFT(ic)))
2117                         mcs51_ptrRegReq += ((OP_SYMBOL(IC_LEFT(ic))->onStack ||
2118                                        OP_SYMBOL(IC_LEFT(ic))->iaccess) ? 1 : 0);
2119                     if (IS_SYMOP(IC_RIGHT(ic)))
2120                         mcs51_ptrRegReq += ((OP_SYMBOL(IC_RIGHT(ic))->onStack ||
2121                                        OP_SYMBOL(IC_RIGHT(ic))->iaccess) ? 1 : 0);
2122                     if (IS_SYMOP(IC_RESULT(ic)))
2123                         mcs51_ptrRegReq += ((OP_SYMBOL(IC_RESULT(ic))->onStack ||
2124                                        OP_SYMBOL(IC_RESULT(ic))->iaccess) ? 1 : 0);    
2125                 }
2126         }
2127
2128         /* if the condition of an if instruction
2129            is defined in the previous instruction then
2130            mark the itemp as a conditional */
2131         if ((IS_CONDITIONAL(ic) ||
2132              ( ( ic->op == BITWISEAND      ||
2133                  ic->op == '|'             ||
2134                  ic->op == '^' ) &&
2135                isBitwiseOptimizable(ic))) &&        
2136             ic->next && ic->next->op == IFX &&
2137             isOperandEqual(IC_RESULT(ic),IC_COND(ic->next)) &&
2138             OP_SYMBOL(IC_RESULT(ic))->liveTo <= ic->next->seq) {
2139             
2140             OP_SYMBOL(IC_RESULT(ic))->regType = REG_CND;            
2141             continue ;
2142         }
2143         
2144         /* reduce for support function calls */
2145         if (ic->supportRtn || ic->op == '+' || ic->op == '-' )
2146             packRegsForSupport (ic,ebp);        
2147         
2148         /* some cases the redundant moves can
2149            can be eliminated for return statements */
2150         if ((ic->op == RETURN || ic->op == SEND) &&
2151             !isOperandInFarSpace(IC_LEFT(ic))    &&
2152             !options.model)
2153             packRegsForOneuse (ic,IC_LEFT(ic),ebp);     
2154
2155         /* if pointer set & left has a size more than
2156            one and right is not in far space */
2157         if (POINTER_SET(ic)                    &&
2158             !isOperandInFarSpace(IC_RIGHT(ic)) &&
2159             !OP_SYMBOL(IC_RESULT(ic))->remat   &&
2160             !IS_OP_RUONLY(IC_RIGHT(ic))        &&
2161             getSize(aggrToPtr(operandType(IC_RESULT(ic)),FALSE)) > 1 )
2162
2163             packRegsForOneuse (ic,IC_RESULT(ic),ebp);
2164
2165         /* if pointer get */
2166         if (POINTER_GET(ic)                    &&
2167             !isOperandInFarSpace(IC_RESULT(ic))&&
2168             !OP_SYMBOL(IC_LEFT(ic))->remat     &&
2169             !IS_OP_RUONLY(IC_RESULT(ic))         &&
2170             getSize(aggrToPtr(operandType(IC_LEFT(ic)),FALSE)) > 1 )
2171
2172             packRegsForOneuse (ic,IC_LEFT(ic),ebp);
2173
2174
2175         /* if this is cast for intergral promotion then
2176            check if only use of  the definition of the 
2177            operand being casted/ if yes then replace
2178            the result of that arithmetic operation with 
2179            this result and get rid of the cast */
2180         if (ic->op == CAST) {
2181             link *fromType = operandType(IC_RIGHT(ic));
2182             link *toType = operandType(IC_LEFT(ic));
2183
2184             if (IS_INTEGRAL(fromType) && IS_INTEGRAL(toType) &&
2185                 getSize(fromType) != getSize(toType) ) {
2186
2187                 iCode *dic = packRegsForOneuse(ic,IC_RIGHT(ic),ebp);
2188                 if (dic) {
2189                     if (IS_ARITHMETIC_OP(dic)) {
2190                         IC_RESULT(dic) = IC_RESULT(ic);
2191                         remiCodeFromeBBlock(ebp,ic);
2192                         hTabDeleteItem (&iCodehTab,ic->key,ic,DELETE_ITEM,NULL);
2193                         ic = ic->prev;
2194                     } else
2195                         OP_SYMBOL(IC_RIGHT(ic))->ruonly =  0;
2196                 }               
2197             } else {
2198                 
2199                 /* if the type from and type to are the same
2200                    then if this is the only use then packit */
2201                 if (checkType(operandType(IC_RIGHT(ic)),
2202                               operandType(IC_LEFT(ic))) == 1) {
2203                     iCode *dic = packRegsForOneuse (ic,IC_RIGHT(ic),ebp);
2204                     if (dic) {
2205                         IC_RESULT(dic) = IC_RESULT(ic);
2206                         remiCodeFromeBBlock(ebp,ic);
2207                         hTabDeleteItem (&iCodehTab,ic->key,ic,DELETE_ITEM,NULL);
2208                         ic = ic->prev;
2209                     }
2210                 }
2211             }
2212         }
2213         
2214         /* pack for PUSH 
2215            iTempNN := (some variable in farspace) V1
2216            push iTempNN ;
2217            -------------
2218            push V1
2219         */
2220         if (ic->op == IPUSH ) {
2221             packForPush(ic,ebp);
2222         }
2223           
2224         
2225         /* pack registers for accumulator use, when the
2226            result of an arithmetic or bit wise operation
2227            has only one use, that use is immediately following
2228            the defintion and the using iCode has only one
2229            operand or has two operands but one is literal &
2230            the result of that operation is not on stack then
2231            we can leave the result of this operation in acc:b
2232            combination */
2233         if ((IS_ARITHMETIC_OP(ic) 
2234              
2235              || IS_BITWISE_OP(ic) 
2236              
2237              || ic->op == LEFT_OP || ic->op == RIGHT_OP
2238              
2239              ) &&
2240             IS_ITEMP(IC_RESULT(ic)) &&
2241             getSize(operandType(IC_RESULT(ic))) <= 2)
2242
2243             packRegsForAccUse (ic);
2244
2245     }
2246 }
2247   
2248 /*-----------------------------------------------------------------*/
2249 /* assignRegisters - assigns registers to each live range as need  */
2250 /*-----------------------------------------------------------------*/
2251 void mcs51_assignRegisters (eBBlock **ebbs, int count)
2252 {
2253     iCode *ic;
2254     int i ;
2255
2256     setToNull((void *)&_G.funcrUsed);
2257     mcs51_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
2258     /* if not register extentions then reduce number
2259        of registers */
2260     if (options.regExtend)
2261         mcs51_nRegs = 13;
2262     else
2263         mcs51_nRegs = 8;
2264
2265     /* change assignments this will remove some
2266        live ranges reducing some register pressure */
2267     for (i = 0 ; i < count ;i++ )
2268         packRegisters (ebbs[i]);
2269     
2270     if (options.dump_pack)
2271         dumpEbbsToFileExt(".dumppack",ebbs,count);
2272
2273     /* first determine for each live range the number of 
2274        registers & the type of registers required for each */
2275     regTypeNum ();
2276     
2277     /* and serially allocate registers */ 
2278     serialRegAssign(ebbs,count);
2279
2280     /* if stack was extended then tell the user */
2281     if (_G.stackExtend) {
2282 /*      werror(W_TOOMANY_SPILS,"stack", */
2283 /*             _G.stackExtend,currFunc->name,""); */
2284         _G.stackExtend = 0 ;
2285     }
2286
2287     if (_G.dataExtend) {
2288 /*      werror(W_TOOMANY_SPILS,"data space", */
2289 /*             _G.dataExtend,currFunc->name,""); */
2290         _G.dataExtend = 0 ;
2291     }  
2292
2293     /* after that create the register mask
2294        for each of the instruction */
2295     createRegMask (ebbs,count);
2296
2297     /* redo that offsets for stacked automatic variables */
2298     redoStackOffsets ();
2299
2300     if (options.dump_rassgn)
2301         dumpEbbsToFileExt(".dumprassgn",ebbs,count);
2302
2303     /* now get back the chain */
2304     ic = iCodeLabelOptimize(iCodeFromeBBlock (ebbs,count));
2305
2306
2307     gen51Code(ic);
2308
2309     /* free up any _G.stackSpil locations allocated */   
2310     applyToSet(_G.stackSpil,deallocStackSpil);
2311     _G.slocNum = 0;
2312     setToNull((void **)&_G.stackSpil);
2313     setToNull((void **)&_G.spiltSet);
2314     /* mark all registers as free */
2315     freeAllRegs();
2316
2317     return ;
2318 }