]> git.gag.com Git - fw/sdcc/blob - src/mcs51/ralloc.c
Minor bug fixes
[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) < 2) {
1073                     mcs51_ptrRegReq++;
1074                     ptrRegSet = 1;
1075                 }
1076                 /* else we assign registers to it */            
1077                 _G.regAssigned = bitVectSetBit(_G.regAssigned,sym->key);
1078
1079                 for (j = 0 ; j < sym->nRegs ;j++ ) {
1080                     if (sym->regType == REG_PTR)
1081                         sym->regs[j] = getRegPtr(ic,ebbs[i],sym);
1082                     else
1083                         sym->regs[j] = getRegGpr(ic,ebbs[i],sym);
1084
1085                     /* if the allocation falied which means
1086                        this was spilt then break */
1087                     if (!sym->regs[j])
1088                         break;
1089                 }
1090                 /* if it shares registers with operands make sure
1091                    that they are in the same position */
1092                 if (IC_LEFT(ic) && IS_SYMOP(IC_LEFT(ic)) &&
1093                     OP_SYMBOL(IC_LEFT(ic))->nRegs  && ic->op != '=')
1094                         positionRegs(OP_SYMBOL(IC_RESULT(ic)),
1095                                      OP_SYMBOL(IC_LEFT(ic)),ic->lineno);
1096                 /* do the same for the right operand */
1097                 if (IC_RIGHT(ic) && IS_SYMOP(IC_RIGHT(ic)) &&
1098                     OP_SYMBOL(IC_RIGHT(ic))->nRegs && ic->op != '=')
1099                         positionRegs(OP_SYMBOL(IC_RESULT(ic)),
1100                                      OP_SYMBOL(IC_RIGHT(ic)),ic->lineno);
1101                 
1102                 if (ptrRegSet) {
1103                     mcs51_ptrRegReq--;
1104                     ptrRegSet = 0;
1105                 }
1106                                 
1107             }       
1108         }
1109     }
1110 }
1111
1112 /*-----------------------------------------------------------------*/
1113 /* rUmaskForOp :- returns register mask for an operand             */
1114 /*-----------------------------------------------------------------*/
1115 static bitVect *rUmaskForOp (operand *op)
1116 {
1117     bitVect *rumask;
1118     symbol *sym;
1119     int j;
1120     
1121     /* only temporaries are assigned registers */
1122     if (!IS_ITEMP(op)) 
1123         return NULL;
1124
1125     sym = OP_SYMBOL(op);
1126     
1127     /* if spilt or no registers assigned to it
1128        then nothing */
1129     if (sym->isspilt || !sym->nRegs)
1130         return NULL;
1131
1132     rumask = newBitVect(mcs51_nRegs);
1133
1134     for (j = 0; j < sym->nRegs; j++) {
1135         rumask = bitVectSetBit(rumask,
1136                                sym->regs[j]->rIdx);
1137     }
1138
1139     return rumask;
1140 }
1141
1142 /*-----------------------------------------------------------------*/
1143 /* regsUsedIniCode :- returns bit vector of registers used in iCode*/
1144 /*-----------------------------------------------------------------*/
1145 static bitVect *regsUsedIniCode (iCode *ic)
1146 {
1147     bitVect *rmask = newBitVect(mcs51_nRegs);
1148
1149     /* do the special cases first */
1150     if (ic->op == IFX ) {
1151         rmask = bitVectUnion(rmask,
1152                              rUmaskForOp(IC_COND(ic)));
1153         goto ret;
1154     }
1155
1156     /* for the jumptable */
1157     if (ic->op == JUMPTABLE) {
1158         rmask = bitVectUnion(rmask,
1159                              rUmaskForOp(IC_JTCOND(ic)));
1160
1161         goto ret;
1162     }
1163
1164     /* of all other cases */
1165     if (IC_LEFT(ic)) 
1166         rmask = bitVectUnion(rmask,
1167                              rUmaskForOp(IC_LEFT(ic)));
1168         
1169     
1170     if (IC_RIGHT(ic))
1171         rmask = bitVectUnion(rmask,
1172                              rUmaskForOp(IC_RIGHT(ic)));
1173
1174     if (IC_RESULT(ic))
1175         rmask = bitVectUnion(rmask,
1176                              rUmaskForOp(IC_RESULT(ic)));
1177
1178  ret:
1179     return rmask;
1180 }
1181
1182 /*-----------------------------------------------------------------*/
1183 /* createRegMask - for each instruction will determine the regsUsed*/
1184 /*-----------------------------------------------------------------*/
1185 static void createRegMask (eBBlock **ebbs, int count)
1186 {
1187     int i;
1188
1189     /* for all blocks */
1190     for (i = 0; i < count ; i++ ) {
1191         iCode *ic ;
1192
1193         if ( ebbs[i]->noPath &&
1194              ( ebbs[i]->entryLabel != entryLabel &&
1195                ebbs[i]->entryLabel != returnLabel ))
1196             continue ;
1197
1198         /* for all instructions */
1199         for ( ic = ebbs[i]->sch ; ic ; ic = ic->next ) {
1200             
1201             int j;
1202
1203             if (SKIP_IC2(ic) || !ic->rlive)
1204                 continue ;
1205             
1206             /* first mark the registers used in this
1207                instruction */
1208             ic->rUsed = regsUsedIniCode(ic);
1209             _G.funcrUsed = bitVectUnion(_G.funcrUsed,ic->rUsed);
1210
1211             /* now create the register mask for those 
1212                registers that are in use : this is a
1213                super set of ic->rUsed */
1214             ic->rMask = newBitVect(mcs51_nRegs+1);
1215
1216             /* for all live Ranges alive at this point */
1217             for (j = 1; j < ic->rlive->size; j++ ) {
1218                 symbol *sym;
1219                 int k;
1220
1221                 /* if not alive then continue */
1222                 if (!bitVectBitValue(ic->rlive,j))
1223                     continue ;
1224
1225                 /* find the live range we are interested in */
1226                 if (!(sym = hTabItemWithKey(liveRanges,j))) {
1227                     werror (E_INTERNAL_ERROR,__FILE__,__LINE__,
1228                             "createRegMask cannot find live range");
1229                     exit(0);
1230                 }
1231
1232                 /* if no register assigned to it */
1233                 if (!sym->nRegs || sym->isspilt)
1234                     continue ;
1235
1236                 /* for all the registers allocated to it */
1237                 for (k = 0 ; k < sym->nRegs ;k++)
1238                     if (sym->regs[k])
1239                         ic->rMask =
1240                             bitVectSetBit(ic->rMask,sym->regs[k]->rIdx);
1241             }
1242         }
1243     }
1244 }
1245
1246 /*-----------------------------------------------------------------*/
1247 /* rematStr - returns the rematerialized string for a remat var    */
1248 /*-----------------------------------------------------------------*/
1249 static char *rematStr (symbol *sym)
1250 {
1251     char *s = buffer;   
1252     iCode *ic = sym->rematiCode;    
1253
1254     while (1) {
1255
1256         /* if plus or minus print the right hand side */
1257         if (ic->op == '+' || ic->op == '-') {
1258             sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
1259                     ic->op );
1260             s += strlen(s);
1261             ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
1262             continue ;
1263         }
1264
1265         /* we reached the end */
1266         sprintf(s,"%s",OP_SYMBOL(IC_LEFT(ic))->rname);
1267         break;
1268     }
1269
1270     return buffer ;
1271 }
1272
1273 /*-----------------------------------------------------------------*/
1274 /* regTypeNum - computes the type & number of registers required   */
1275 /*-----------------------------------------------------------------*/
1276 static void regTypeNum ()
1277 {
1278     symbol *sym;
1279     int k;
1280     iCode *ic;
1281
1282     /* for each live range do */
1283     for ( sym = hTabFirstItem(liveRanges,&k); sym ;
1284           sym = hTabNextItem(liveRanges,&k)) {
1285
1286         /* if used zero times then no registers needed */
1287         if ((sym->liveTo - sym->liveFrom) == 0)
1288             continue ;
1289
1290
1291         /* if the live range is a temporary */
1292         if (sym->isitmp) {
1293
1294             /* if the type is marked as a conditional */
1295             if (sym->regType == REG_CND)
1296                 continue ;
1297
1298             /* if used in return only then we don't 
1299                need registers */
1300             if (sym->ruonly || sym->accuse) {
1301                 if (IS_AGGREGATE(sym->type) || sym->isptr)
1302                     sym->type = aggrToPtr(sym->type,FALSE);
1303                 continue ;
1304             }
1305             
1306             /* if the symbol has only one definition &
1307                that definition is a get_pointer and the
1308                pointer we are getting is rematerializable and
1309                in "data" space */
1310                
1311             if (bitVectnBitsOn(sym->defs) == 1 &&
1312                 (ic = hTabItemWithKey(iCodehTab,
1313                                       bitVectFirstBit(sym->defs))) &&
1314                 POINTER_GET(ic) && 
1315                 !IS_BITVAR(sym->etype)) {
1316                 
1317                                 
1318                 /* if remat in data space */
1319                 if (OP_SYMBOL(IC_LEFT(ic))->remat &&
1320                     DCL_TYPE(aggrToPtr(sym->type,FALSE)) == POINTER) {
1321                 
1322                     /* create a psuedo symbol & force a spil */
1323                     symbol *psym = newSymbol(rematStr(OP_SYMBOL(IC_LEFT(ic))),1);
1324                     psym->type = sym->type;
1325                     psym->etype = sym->etype;
1326                     strcpy(psym->rname,psym->name);
1327                     sym->isspilt = 1;
1328                     sym->usl.spillLoc = psym;
1329                     continue ;
1330                 }
1331
1332                 /* if in data space or idata space then try to
1333                    allocate pointer register */
1334                    
1335             }
1336                 
1337             /* if not then we require registers */
1338             sym->nRegs = ((IS_AGGREGATE(sym->type) || sym->isptr ) ?
1339                           getSize(sym->type = aggrToPtr(sym->type,FALSE)) :
1340                           getSize(sym->type));
1341
1342             if (sym->nRegs > 4) {
1343                 fprintf(stderr,"allocated more than 4 or 0 registers for type ");
1344                 printTypeChain(sym->type,stderr);fprintf(stderr,"\n");
1345             }
1346             
1347             /* determine the type of register required */
1348             if (sym->nRegs == 1   && 
1349                 IS_PTR(sym->type) && 
1350                 sym->uptr) 
1351                 sym->regType = REG_PTR ;            
1352             else 
1353                 sym->regType = REG_GPR ;
1354             
1355         } else 
1356             /* for the first run we don't provide */
1357             /* registers for true symbols we will */
1358             /* see how things go                  */
1359             sym->nRegs = 0 ;    
1360     }
1361     
1362 }
1363
1364 /*-----------------------------------------------------------------*/
1365 /* freeAllRegs - mark all registers as free                        */
1366 /*-----------------------------------------------------------------*/
1367 static void freeAllRegs()
1368 {
1369     int i;
1370
1371     for (i=0;i< mcs51_nRegs;i++ )
1372         regs8051[i].isFree = 1;
1373 }
1374
1375 /*-----------------------------------------------------------------*/
1376 /* deallocStackSpil - this will set the stack pointer back         */
1377 /*-----------------------------------------------------------------*/
1378 static DEFSETFUNC(deallocStackSpil)
1379 {
1380     symbol *sym = item;
1381
1382     deallocLocal(sym);
1383     return 0;
1384 }
1385
1386 /*-----------------------------------------------------------------*/
1387 /* farSpacePackable - returns the packable icode for far variables */
1388 /*-----------------------------------------------------------------*/
1389 static iCode *farSpacePackable (iCode *ic)
1390 {
1391     iCode *dic ;
1392
1393     /* go thru till we find a definition for the
1394        symbol on the right */
1395     for ( dic = ic->prev ; dic ; dic = dic->prev) {
1396                 
1397         /* if the definition is a call then no */
1398         if ((dic->op == CALL || dic->op == PCALL) &&
1399             IC_RESULT(dic)->key == IC_RIGHT(ic)->key) {
1400             return NULL;
1401         }
1402         
1403         /* if shift by unknown amount then not */
1404         if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
1405             IC_RESULT(dic)->key == IC_RIGHT(ic)->key)
1406             return NULL;
1407
1408         /* if pointer get and size > 1 */
1409         if (POINTER_GET(dic) &&
1410             getSize(aggrToPtr(operandType(IC_LEFT(dic)),FALSE)) > 1)
1411             return NULL ;
1412
1413         if (POINTER_SET(dic) &&
1414             getSize(aggrToPtr(operandType(IC_RESULT(dic)),FALSE)) > 1)
1415             return NULL ;
1416
1417         /* if any three is a true symbol in far space */
1418         if (IC_RESULT(dic) &&
1419             IS_TRUE_SYMOP(IC_RESULT(dic)) &&
1420             isOperandInFarSpace(IC_RESULT(dic)))         
1421             return NULL;
1422
1423         if (IC_RIGHT(dic) &&
1424             IS_TRUE_SYMOP(IC_RIGHT(dic)) &&
1425             isOperandInFarSpace(IC_RIGHT(dic)) &&
1426             !isOperandEqual(IC_RIGHT(dic),IC_RESULT(ic)))
1427             return NULL;
1428
1429         if (IC_LEFT(dic) &&
1430             IS_TRUE_SYMOP(IC_LEFT(dic)) &&
1431             isOperandInFarSpace(IC_LEFT(dic)) &&
1432             !isOperandEqual(IC_LEFT(dic),IC_RESULT(ic)))
1433             return NULL;
1434         
1435         if (isOperandEqual(IC_RIGHT(ic),IC_RESULT(dic))) {
1436             if ( (dic->op == LEFT_OP  ||
1437                   dic->op == RIGHT_OP ||
1438                   dic->op == '-') &&
1439                  IS_OP_LITERAL(IC_RIGHT(dic)))
1440                 return NULL;
1441             else
1442                 return dic;
1443         }
1444     }
1445
1446     return NULL;
1447 }
1448
1449 /*-----------------------------------------------------------------*/
1450 /* packRegsForAssign - register reduction for assignment           */
1451 /*-----------------------------------------------------------------*/
1452 static int packRegsForAssign (iCode *ic,eBBlock *ebp)
1453 {
1454     iCode *dic, *sic;
1455     
1456     if (
1457 /*      !IS_TRUE_SYMOP(IC_RESULT(ic)) ||            */
1458         !IS_ITEMP(IC_RIGHT(ic))       ||        
1459         OP_LIVETO(IC_RIGHT(ic)) > ic->seq ||
1460         OP_SYMBOL(IC_RIGHT(ic))->isind)
1461         return 0;
1462         
1463     /* if the true symbol is defined in far space or on stack
1464        then we should not since this will increase register pressure */
1465     if (isOperandInFarSpace(IC_RESULT(ic))) {
1466         if ((dic = farSpacePackable(ic)))
1467             goto pack;
1468         else
1469             return 0;
1470         
1471     }
1472     /* find the definition of iTempNN scanning backwards if we find a 
1473        a use of the true symbol in before we find the definition then 
1474        we cannot */     
1475     for ( dic = ic->prev ; dic ; dic = dic->prev) {
1476
1477         /* if there is a function call and this is
1478            a parameter & not my parameter then don't pack it */
1479         if ( (dic->op == CALL || dic->op == PCALL) &&
1480              (OP_SYMBOL(IC_RESULT(ic))->_isparm &&
1481               !OP_SYMBOL(IC_RESULT(ic))->ismyparm)) {
1482             dic = NULL;
1483             break;
1484         }
1485
1486         if (SKIP_IC2(dic))
1487             continue;
1488
1489         if (IS_TRUE_SYMOP(IC_RESULT(dic)) &&
1490             IS_OP_VOLATILE(IC_RESULT(dic))) {
1491                 dic = NULL;
1492                 break;
1493         }
1494
1495         if (IS_SYMOP(IC_RESULT(dic)) &&
1496             IC_RESULT(dic)->key == IC_RIGHT(ic)->key) {
1497             if (POINTER_SET(dic))
1498                 dic = NULL;
1499
1500             break;          
1501         }
1502
1503         if (IS_SYMOP(IC_RIGHT(dic)) && 
1504             (IC_RIGHT(dic)->key == IC_RESULT(ic)->key ||
1505              IC_RIGHT(dic)->key == IC_RIGHT(ic)->key)) {
1506             dic = NULL;
1507             break;
1508         }
1509         
1510         if (IS_SYMOP(IC_LEFT(dic)) && 
1511             (IC_LEFT(dic)->key == IC_RESULT(ic)->key ||
1512              IC_LEFT(dic)->key == IC_RIGHT(ic)->key)) {
1513             dic = NULL;
1514             break;
1515         }
1516
1517         if (POINTER_SET(dic) && 
1518             IC_RESULT(dic)->key == IC_RESULT(ic)->key ) {
1519             dic = NULL ;
1520             break;
1521         }
1522     }
1523     
1524     if (!dic)
1525         return 0 ; /* did not find */
1526             
1527     /* if the result is on stack or iaccess then it must be
1528        the same atleast one of the operands */
1529     if (OP_SYMBOL(IC_RESULT(ic))->onStack  || 
1530         OP_SYMBOL(IC_RESULT(ic))->iaccess ) {
1531         
1532         /* the operation has only one symbol
1533            operator then we can pack */
1534         if ((IC_LEFT(dic) && !IS_SYMOP(IC_LEFT(dic))) ||
1535             (IC_RIGHT(dic) && !IS_SYMOP(IC_RIGHT(dic))))
1536             goto pack;
1537
1538         if (!((IC_LEFT(dic) &&
1539              IC_RESULT(ic)->key == IC_LEFT(dic)->key) ||
1540               (IC_RIGHT(dic) &&
1541                IC_RESULT(ic)->key == IC_RIGHT(dic)->key)))
1542             return 0;                
1543     }
1544 pack:
1545     /* found the definition */
1546     /* replace the result with the result of */
1547     /* this assignment and remove this assignment */
1548     IC_RESULT(dic) = IC_RESULT(ic) ;
1549
1550     if (IS_ITEMP(IC_RESULT(dic)) && OP_SYMBOL(IC_RESULT(dic))->liveFrom > dic->seq) {
1551             OP_SYMBOL(IC_RESULT(dic))->liveFrom = dic->seq;
1552     }
1553     /* delete from liverange table also 
1554        delete from all the points inbetween and the new
1555        one */
1556     for ( sic = dic; sic != ic ; sic = sic->next ) {    
1557         bitVectUnSetBit(sic->rlive,IC_RESULT(ic)->key);
1558         if (IS_ITEMP(IC_RESULT(dic)))
1559             bitVectSetBit(sic->rlive,IC_RESULT(dic)->key);
1560     }
1561         
1562     remiCodeFromeBBlock(ebp,ic);
1563     hTabDeleteItem (&iCodehTab,ic->key,ic,DELETE_ITEM,NULL);
1564     return 1;
1565     
1566 }
1567
1568 /*-----------------------------------------------------------------*/
1569 /* findAssignToSym : scanning backwards looks for first assig found*/
1570 /*-----------------------------------------------------------------*/
1571 static iCode *findAssignToSym (operand *op,iCode *ic)
1572 {
1573     iCode *dic;
1574
1575     for (dic = ic->prev ; dic ; dic = dic->prev) {
1576         
1577         /* if definition by assignment */
1578         if (dic->op == '='                 && 
1579             !POINTER_SET(dic)              &&
1580             IC_RESULT(dic)->key == op->key
1581 /*          &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) */
1582             ) {    
1583
1584             /* we are interested only if defined in far space */
1585             /* or in stack space in case of + & - */
1586
1587             /* if assigned to a non-symbol then return
1588                true */
1589             if (!IS_SYMOP(IC_RIGHT(dic)))
1590                 break ;
1591
1592             /* if the symbol is in far space then
1593                we should not */
1594             if (isOperandInFarSpace(IC_RIGHT(dic)))
1595                 return NULL ;
1596
1597             /* for + & - operations make sure that
1598                if it is on the stack it is the same
1599                as one of the three operands */
1600             if ((ic->op == '+' || ic->op == '-') &&
1601                 OP_SYMBOL(IC_RIGHT(dic))->onStack) {
1602
1603                 if ( IC_RESULT(ic)->key != IC_RIGHT(dic)->key &&
1604                      IC_LEFT(ic)->key   != IC_RIGHT(dic)->key &&
1605                      IC_RIGHT(ic)->key  != IC_RIGHT(dic)->key)
1606                     return NULL;
1607             }           
1608
1609             break ;
1610                 
1611         }
1612
1613         /* if we find an usage then we cannot delete it */
1614         if (IC_LEFT(dic) && IC_LEFT(dic)->key == op->key)
1615             return NULL;
1616             
1617         if (IC_RIGHT(dic) && IC_RIGHT(dic)->key == op->key)
1618             return NULL;
1619
1620         if (POINTER_SET(dic) && IC_RESULT(dic)->key == op->key)
1621             return NULL;
1622     }
1623
1624     /* now make sure that the right side of dic
1625        is not defined between ic & dic */       
1626     if (dic) {
1627         iCode *sic = dic->next ;
1628
1629         for (; sic != ic ; sic = sic->next)
1630             if (IC_RESULT(sic) &&
1631                 IC_RESULT(sic)->key == IC_RIGHT(dic)->key)
1632                 return NULL;
1633     }
1634
1635     return dic;
1636         
1637         
1638 }
1639
1640 /*-----------------------------------------------------------------*/
1641 /* packRegsForSupport :- reduce some registers for support calls   */
1642 /*-----------------------------------------------------------------*/
1643 static int packRegsForSupport (iCode *ic, eBBlock *ebp)
1644 {
1645     int change = 0 ;
1646     /* for the left & right operand :- look to see if the
1647        left was assigned a true symbol in far space in that
1648        case replace them */
1649     if (IS_ITEMP(IC_LEFT(ic)) && 
1650         OP_SYMBOL(IC_LEFT(ic))->liveTo <= ic->seq) {
1651         iCode *dic = findAssignToSym(IC_LEFT(ic),ic);
1652         iCode *sic;
1653
1654         if (!dic)
1655             goto right ;
1656
1657         /* found it we need to remove it from the
1658            block */
1659         for ( sic = dic; sic != ic ; sic = sic->next )
1660             bitVectUnSetBit(sic->rlive,IC_LEFT(ic)->key);
1661
1662         IC_LEFT(ic)->operand.symOperand =
1663             IC_RIGHT(dic)->operand.symOperand;
1664         IC_LEFT(ic)->key = IC_RIGHT(dic)->operand.symOperand->key;
1665         remiCodeFromeBBlock(ebp,dic);
1666         hTabDeleteItem (&iCodehTab,dic->key,dic,DELETE_ITEM,NULL);
1667         change++;      
1668     }
1669     
1670     /* do the same for the right operand */
1671  right:    
1672     if (!change && 
1673         IS_ITEMP(IC_RIGHT(ic)) &&
1674         OP_SYMBOL(IC_RIGHT(ic))->liveTo <= ic->seq) {
1675         iCode *dic = findAssignToSym(IC_RIGHT(ic),ic);
1676         iCode *sic;
1677         
1678         if (!dic)
1679             return change ;
1680
1681         /* if this is a subtraction & the result
1682            is a true symbol in far space then don't pack */
1683         if (ic->op == '-' && IS_TRUE_SYMOP(IC_RESULT(dic))) {
1684             link *etype =getSpec(operandType(IC_RESULT(dic)));
1685             if (IN_FARSPACE(SPEC_OCLS(etype)))
1686                 return change ;
1687         }
1688         /* found it we need to remove it from the
1689            block */
1690         for ( sic = dic; sic != ic ; sic = sic->next )
1691             bitVectUnSetBit(sic->rlive,IC_RIGHT(ic)->key);
1692         
1693         IC_RIGHT(ic)->operand.symOperand =
1694             IC_RIGHT(dic)->operand.symOperand;
1695         IC_RIGHT(ic)->key = IC_RIGHT(dic)->operand.symOperand->key;
1696         
1697         remiCodeFromeBBlock(ebp,dic);
1698         hTabDeleteItem (&iCodehTab,dic->key,dic,DELETE_ITEM,NULL);
1699         change ++;
1700     }
1701    
1702     return change ;
1703 }
1704
1705 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
1706
1707
1708 /*-----------------------------------------------------------------*/
1709 /* packRegsForOneuse : - will reduce some registers for single Use */ 
1710 /*-----------------------------------------------------------------*/
1711 static iCode *packRegsForOneuse (iCode *ic, operand *op , eBBlock *ebp)
1712 {
1713     bitVect *uses ;
1714     iCode *dic, *sic;
1715
1716     /* if returning a literal then do nothing */
1717     if (!IS_SYMOP(op))
1718         return NULL;
1719     
1720     /* only upto 2 bytes since we cannot predict
1721        the usage of b, & acc */
1722     if (getSize(operandType(op)) > 2 && 
1723         ic->op != RETURN             &&
1724         ic->op != SEND)
1725         return NULL;
1726
1727     /* this routine will mark the a symbol as used in one 
1728        instruction use only && if the defintion is local 
1729        (ie. within the basic block) && has only one definition &&
1730        that definiion is either a return value from a 
1731        function or does not contain any variables in
1732        far space */
1733     uses = bitVectCopy(OP_USES(op));
1734     bitVectUnSetBit(uses,ic->key); /* take away this iCode */
1735     if (!bitVectIsZero(uses)) /* has other uses */
1736         return NULL ;
1737     
1738     /* if it has only one defintion */
1739     if (bitVectnBitsOn(OP_DEFS(op)) > 1)
1740         return NULL ; /* has more than one definition */
1741
1742     /* get the that definition */
1743     if (!(dic = 
1744           hTabItemWithKey(iCodehTab,
1745                           bitVectFirstBit(OP_DEFS(op)))))
1746         return NULL ;
1747
1748     /* found the definition now check if it is local */
1749     if (dic->seq < ebp->fSeq ||
1750         dic->seq > ebp->lSeq)
1751         return NULL ; /* non-local */
1752
1753     /* now check if it is the return from
1754        a function call */
1755     if (dic->op == CALL || dic->op == PCALL ) {
1756         if (ic->op != SEND && ic->op != RETURN) {
1757             OP_SYMBOL(op)->ruonly = 1;
1758             return dic;
1759         }
1760         dic = dic->next ;
1761     }
1762         
1763     
1764     /* otherwise check that the definition does
1765        not contain any symbols in far space */
1766     if (isOperandInFarSpace(IC_LEFT(dic))  ||
1767         isOperandInFarSpace(IC_RIGHT(dic)) ||
1768         IS_OP_RUONLY(IC_LEFT(ic))          ||
1769         IS_OP_RUONLY(IC_RIGHT(ic)) )        {
1770         return NULL;
1771     }
1772     
1773     /* if pointer set then make sure the pointer
1774        is one byte */
1775     if (POINTER_SET(dic) && 
1776         !IS_DATA_PTR(aggrToPtr(operandType(IC_RESULT(dic)),FALSE)))
1777         return NULL ;
1778
1779     if (POINTER_GET(dic) && 
1780         !IS_DATA_PTR(aggrToPtr(operandType(IC_LEFT(dic)),FALSE)))
1781         return NULL ;
1782     
1783     sic = dic;
1784
1785     /* also make sure the intervenening instructions
1786        don't have any thing in far space */
1787     for (dic = dic->next ; dic && dic != ic ; dic = dic->next) {
1788                 
1789         /* if there is an intervening function call then no */
1790         if (dic->op == CALL || dic->op == PCALL)
1791                 return NULL;
1792         /* if pointer set then make sure the pointer
1793            is one byte */
1794         if (POINTER_SET(dic) && 
1795             !IS_DATA_PTR(aggrToPtr(operandType(IC_RESULT(dic)),FALSE)))
1796             return NULL ;
1797         
1798         if (POINTER_GET(dic) && 
1799             !IS_DATA_PTR(aggrToPtr(operandType(IC_LEFT(dic)),FALSE)))
1800             return NULL ;
1801
1802         /* if address of & the result is remat the okay */
1803         if (dic->op == ADDRESS_OF &&
1804             OP_SYMBOL(IC_RESULT(dic))->remat)
1805             continue ;
1806            
1807         /* if operand has size of three or more & this
1808            operation is a '*','/' or '%' then 'b' may
1809            cause a problem */
1810         if (( dic->op == '%' || dic->op == '/' || dic->op == '*') &&
1811             getSize(operandType(op)) >= 3)
1812                 return NULL;
1813
1814         /* if left or right or result is in far space */
1815         if (isOperandInFarSpace(IC_LEFT(dic))   ||
1816             isOperandInFarSpace(IC_RIGHT(dic))  ||
1817             isOperandInFarSpace(IC_RESULT(dic)) ||
1818             IS_OP_RUONLY(IC_LEFT(dic))          ||
1819             IS_OP_RUONLY(IC_RIGHT(dic))         ||
1820             IS_OP_RUONLY(IC_RESULT(dic))            ) {
1821             return NULL;
1822         }
1823     }
1824                 
1825     OP_SYMBOL(op)->ruonly = 1;
1826     return sic;
1827         
1828 }
1829
1830 /*-----------------------------------------------------------------*/
1831 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
1832 /*-----------------------------------------------------------------*/
1833 static bool isBitwiseOptimizable (iCode *ic)
1834 {
1835     link *ltype = getSpec(operandType(IC_LEFT(ic)));
1836     link *rtype = getSpec(operandType(IC_RIGHT(ic)));
1837
1838     /* bitwise operations are considered optimizable
1839        under the following conditions (Jean-Louis VERN) 
1840        
1841        x & lit
1842        bit & bit
1843        bit & x
1844        bit ^ bit
1845        bit ^ x
1846        x   ^ lit
1847        x   | lit
1848        bit | bit
1849        bit | x
1850     */    
1851     if ( IS_LITERAL(rtype) ||
1852          (IS_BITVAR(ltype) && IN_BITSPACE(SPEC_OCLS(ltype))))
1853         return TRUE ;
1854     else
1855         return FALSE ;    
1856 }
1857
1858 /*-----------------------------------------------------------------*/
1859 /* packRegsForAccUse - pack registers for acc use                  */
1860 /*-----------------------------------------------------------------*/
1861 static void packRegsForAccUse (iCode *ic)
1862 {
1863     iCode *uic;
1864     
1865     /* if + or - then it has to be one byte result */
1866     if ((ic->op == '+' || ic->op == '-')
1867         && getSize(operandType(IC_RESULT(ic))) > 1)
1868         return ;
1869     
1870     /* if shift operation make sure right side is not a literal */
1871     if (ic->op == RIGHT_OP  &&
1872         ( isOperandLiteral(IC_RIGHT(ic)) ||
1873           getSize(operandType(IC_RESULT(ic))) > 1))
1874         return ;
1875         
1876     if (ic->op == LEFT_OP &&        
1877         ( isOperandLiteral(IC_RIGHT(ic)) ||
1878           getSize(operandType(IC_RESULT(ic))) > 1))
1879         return ;
1880         
1881         
1882     /* has only one definition */
1883     if (bitVectnBitsOn(OP_DEFS(IC_RESULT(ic))) > 1)
1884         return ;
1885
1886     /* has only one use */
1887     if (bitVectnBitsOn(OP_USES(IC_RESULT(ic))) > 1)
1888         return ;
1889
1890     /* and the usage immediately follows this iCode */
1891     if (!(uic = hTabItemWithKey(iCodehTab,
1892                                 bitVectFirstBit(OP_USES(IC_RESULT(ic))))))
1893         return ;
1894
1895     if (ic->next != uic)
1896         return ;
1897     
1898     /* if it is a conditional branch then we definitely can */
1899     if (uic->op == IFX  ) 
1900         goto accuse;
1901
1902     if ( uic->op == JUMPTABLE )
1903         return ;
1904
1905     /* if the usage is not is an assignment
1906        or an arithmetic / bitwise / shift operation then not */
1907     if (POINTER_SET(uic) && 
1908         getSize(aggrToPtr(operandType(IC_RESULT(uic)),FALSE)) > 1)
1909         return;
1910
1911     if (uic->op != '=' && 
1912         !IS_ARITHMETIC_OP(uic) &&
1913         !IS_BITWISE_OP(uic)    &&
1914         uic->op != LEFT_OP &&
1915         uic->op != RIGHT_OP )
1916         return;
1917
1918     /* if used in ^ operation then make sure right is not a 
1919        literl */
1920     if (uic->op == '^' && isOperandLiteral(IC_RIGHT(uic)))
1921         return ;
1922
1923     /* if shift operation make sure right side is not a literal */
1924     if (uic->op == RIGHT_OP  &&
1925         ( isOperandLiteral(IC_RIGHT(uic)) ||
1926           getSize(operandType(IC_RESULT(uic))) > 1))
1927         return ;
1928
1929     if (uic->op == LEFT_OP &&        
1930         ( isOperandLiteral(IC_RIGHT(uic)) ||
1931           getSize(operandType(IC_RESULT(uic))) > 1))
1932         return ;
1933             
1934     /* make sure that the result of this icode is not on the
1935        stack, since acc is used to compute stack offset */
1936     if (IS_TRUE_SYMOP(IC_RESULT(uic)) &&
1937         OP_SYMBOL(IC_RESULT(uic))->onStack)
1938         return ;
1939
1940     /* if either one of them in far space then we cannot */
1941     if ((IS_TRUE_SYMOP(IC_LEFT(uic)) &&
1942          isOperandInFarSpace(IC_LEFT(uic))) ||
1943         (IS_TRUE_SYMOP(IC_RIGHT(uic)) &&
1944          isOperandInFarSpace(IC_RIGHT(uic))))
1945         return ;
1946
1947     /* if the usage has only one operand then we can */
1948     if (IC_LEFT(uic) == NULL ||
1949         IC_RIGHT(uic) == NULL) 
1950         goto accuse;
1951
1952     /* make sure this is on the left side if not
1953        a '+' since '+' is commutative */
1954     if (ic->op != '+' &&
1955         IC_LEFT(uic)->key != IC_RESULT(ic)->key)
1956         return;
1957
1958     /* if one of them is a literal then we can */
1959     if ((IC_LEFT(uic) && IS_OP_LITERAL(IC_LEFT(uic))) ||
1960         (IC_RIGHT(uic) && IS_OP_LITERAL(IC_RIGHT(uic)))) {
1961         OP_SYMBOL(IC_RESULT(ic))->accuse = 1;
1962         return ;
1963     }
1964
1965     /* if the other one is not on stack then we can */
1966     if (IC_LEFT(uic)->key == IC_RESULT(ic)->key &&
1967         (IS_ITEMP(IC_RIGHT(uic)) ||
1968          (IS_TRUE_SYMOP(IC_RIGHT(uic)) &&
1969           !OP_SYMBOL(IC_RIGHT(uic))->onStack))) 
1970         goto accuse;
1971     
1972     if (IC_RIGHT(uic)->key == IC_RESULT(ic)->key &&
1973         (IS_ITEMP(IC_LEFT(uic)) ||
1974          (IS_TRUE_SYMOP(IC_LEFT(uic)) &&
1975           !OP_SYMBOL(IC_LEFT(uic))->onStack))) 
1976         goto accuse ;
1977
1978     return ;
1979
1980  accuse:
1981     OP_SYMBOL(IC_RESULT(ic))->accuse = 1;
1982     
1983         
1984 }
1985
1986 /*-----------------------------------------------------------------*/
1987 /* packForPush - hueristics to reduce iCode for pushing            */
1988 /*-----------------------------------------------------------------*/
1989 static void packForPush(iCode *ic, eBBlock *ebp)
1990 {
1991     iCode *dic;
1992
1993     if (ic->op != IPUSH || !IS_ITEMP(IC_LEFT(ic)))
1994         return ;
1995
1996     /* must have only definition & one usage */
1997     if (bitVectnBitsOn(OP_DEFS(IC_LEFT(ic))) != 1 ||
1998         bitVectnBitsOn(OP_USES(IC_LEFT(ic))) != 1 )     
1999         return ;
2000     
2001     /* find the definition */
2002     if (!(dic = hTabItemWithKey(iCodehTab,
2003                                 bitVectFirstBit(OP_DEFS(IC_LEFT(ic))))))
2004         return ;
2005
2006     if (dic->op != '=' || POINTER_SET(dic))
2007         return;
2008
2009     /* we now we know that it has one & only one def & use
2010        and the that the definition is an assignment */
2011     IC_LEFT(ic) = IC_RIGHT(dic);
2012
2013     remiCodeFromeBBlock(ebp,dic);
2014     hTabDeleteItem (&iCodehTab,dic->key,dic,DELETE_ITEM,NULL);
2015 }
2016
2017 /*-----------------------------------------------------------------*/
2018 /* packRegisters - does some transformations to reduce register    */
2019 /*                   pressure                                      */
2020 /*-----------------------------------------------------------------*/
2021 static void packRegisters (eBBlock *ebp)
2022 {
2023     iCode *ic ;
2024     int change = 0 ;
2025     
2026     while (1) {
2027
2028         change = 0;
2029         
2030         /* look for assignments of the form */
2031         /* iTempNN = TRueSym (someoperation) SomeOperand */
2032         /*       ....                       */
2033         /* TrueSym := iTempNN:1             */
2034         for ( ic = ebp->sch ; ic ; ic = ic->next ) {
2035             
2036             
2037             /* find assignment of the form TrueSym := iTempNN:1 */
2038             if (ic->op == '=' && !POINTER_SET(ic))
2039                 change += packRegsForAssign(ic,ebp);
2040         }
2041
2042         if (!change)
2043             break;
2044     }
2045     
2046     for ( ic = ebp->sch ; ic ; ic = ic->next ) {
2047                 
2048         /* if this is an itemp & result of a address of a true sym 
2049            then mark this as rematerialisable   */
2050         if (ic->op == ADDRESS_OF && 
2051             IS_ITEMP(IC_RESULT(ic)) &&
2052             IS_TRUE_SYMOP(IC_LEFT(ic)) &&
2053             bitVectnBitsOn(OP_DEFS(IC_RESULT(ic))) == 1 &&
2054             !OP_SYMBOL(IC_LEFT(ic))->onStack ) {
2055
2056             OP_SYMBOL(IC_RESULT(ic))->remat = 1;
2057             OP_SYMBOL(IC_RESULT(ic))->rematiCode = ic;
2058             OP_SYMBOL(IC_RESULT(ic))->usl.spillLoc = NULL;
2059
2060         }
2061         
2062         /* if straight assignment then carry remat flag if
2063            this is the only definition */
2064         if (ic->op == '='    && 
2065             !POINTER_SET(ic) &&
2066             IS_SYMOP(IC_RIGHT(ic)) && 
2067             OP_SYMBOL(IC_RIGHT(ic))->remat &&
2068             bitVectnBitsOn(OP_SYMBOL(IC_RESULT(ic))->defs) <= 1) {
2069
2070             OP_SYMBOL(IC_RESULT(ic))->remat = 
2071                 OP_SYMBOL(IC_RIGHT(ic))->remat;
2072             OP_SYMBOL(IC_RESULT(ic))->rematiCode = 
2073                 OP_SYMBOL(IC_RIGHT(ic))->rematiCode ;
2074         }
2075
2076         /* if this is a +/- operation with a rematerizable 
2077            then mark this as rematerializable as well only
2078            if the literal value is within the range -255 and + 255
2079            the assembler cannot handle it other wise */
2080         if ((ic->op == '+' || ic->op == '-') &&
2081
2082             (IS_SYMOP(IC_LEFT(ic)) && 
2083              IS_ITEMP(IC_RESULT(ic)) &&
2084              OP_SYMBOL(IC_LEFT(ic))->remat &&
2085              bitVectnBitsOn(OP_DEFS(IC_RESULT(ic))) == 1 &&
2086              IS_OP_LITERAL(IC_RIGHT(ic))) ) {
2087
2088             int i = operandLitValue(IC_RIGHT(ic));
2089             if ( i < 255 && i > -255) {
2090                 OP_SYMBOL(IC_RESULT(ic))->remat = 1;
2091                 OP_SYMBOL(IC_RESULT(ic))->rematiCode = ic;
2092                 OP_SYMBOL(IC_RESULT(ic))->usl.spillLoc = NULL;
2093             }
2094         }
2095
2096         /* mark the pointer usages */
2097         if (POINTER_SET(ic))
2098             OP_SYMBOL(IC_RESULT(ic))->uptr = 1;
2099
2100         if (POINTER_GET(ic))
2101             OP_SYMBOL(IC_LEFT(ic))->uptr = 1;
2102         
2103         if (!SKIP_IC2(ic)) {
2104             /* if we are using a symbol on the stack
2105                then we should say mcs51_ptrRegReq */
2106             if (ic->op == IFX && IS_SYMOP(IC_COND(ic)))
2107                 mcs51_ptrRegReq += ((OP_SYMBOL(IC_COND(ic))->onStack ||
2108                                OP_SYMBOL(IC_COND(ic))->iaccess) ? 1 : 0);
2109             else
2110                 if (ic->op == JUMPTABLE && IS_SYMOP(IC_JTCOND(ic)))
2111                     mcs51_ptrRegReq += ((OP_SYMBOL(IC_JTCOND(ic))->onStack ||
2112                                    OP_SYMBOL(IC_JTCOND(ic))->iaccess) ? 1 : 0);
2113                 else {
2114                     if (IS_SYMOP(IC_LEFT(ic)))
2115                         mcs51_ptrRegReq += ((OP_SYMBOL(IC_LEFT(ic))->onStack ||
2116                                        OP_SYMBOL(IC_LEFT(ic))->iaccess) ? 1 : 0);
2117                     if (IS_SYMOP(IC_RIGHT(ic)))
2118                         mcs51_ptrRegReq += ((OP_SYMBOL(IC_RIGHT(ic))->onStack ||
2119                                        OP_SYMBOL(IC_RIGHT(ic))->iaccess) ? 1 : 0);
2120                     if (IS_SYMOP(IC_RESULT(ic)))
2121                         mcs51_ptrRegReq += ((OP_SYMBOL(IC_RESULT(ic))->onStack ||
2122                                        OP_SYMBOL(IC_RESULT(ic))->iaccess) ? 1 : 0);    
2123                 }
2124         }
2125
2126         /* if the condition of an if instruction
2127            is defined in the previous instruction then
2128            mark the itemp as a conditional */
2129         if ((IS_CONDITIONAL(ic) ||
2130              ( ( ic->op == BITWISEAND      ||
2131                  ic->op == '|'             ||
2132                  ic->op == '^' ) &&
2133                isBitwiseOptimizable(ic))) &&        
2134             ic->next && ic->next->op == IFX &&
2135             isOperandEqual(IC_RESULT(ic),IC_COND(ic->next)) &&
2136             OP_SYMBOL(IC_RESULT(ic))->liveTo <= ic->next->seq) {
2137             
2138             OP_SYMBOL(IC_RESULT(ic))->regType = REG_CND;            
2139             continue ;
2140         }
2141         
2142         /* reduce for support function calls */
2143         if (ic->supportRtn || ic->op == '+' || ic->op == '-' )
2144             packRegsForSupport (ic,ebp);        
2145         
2146         /* some cases the redundant moves can
2147            can be eliminated for return statements */
2148         if ((ic->op == RETURN || ic->op == SEND) &&
2149             !isOperandInFarSpace(IC_LEFT(ic))    &&
2150             !options.model)
2151             packRegsForOneuse (ic,IC_LEFT(ic),ebp);     
2152
2153         /* if pointer set & left has a size more than
2154            one and right is not in far space */
2155         if (POINTER_SET(ic)                    &&
2156             !isOperandInFarSpace(IC_RIGHT(ic)) &&
2157             !OP_SYMBOL(IC_RESULT(ic))->remat   &&
2158             !IS_OP_RUONLY(IC_RIGHT(ic))        &&
2159             getSize(aggrToPtr(operandType(IC_RESULT(ic)),FALSE)) > 1 )
2160
2161             packRegsForOneuse (ic,IC_RESULT(ic),ebp);
2162
2163         /* if pointer get */
2164         if (POINTER_GET(ic)                    &&
2165             !isOperandInFarSpace(IC_RESULT(ic))&&
2166             !OP_SYMBOL(IC_LEFT(ic))->remat     &&
2167             !IS_OP_RUONLY(IC_RESULT(ic))         &&
2168             getSize(aggrToPtr(operandType(IC_LEFT(ic)),FALSE)) > 1 )
2169
2170             packRegsForOneuse (ic,IC_LEFT(ic),ebp);
2171
2172
2173         /* if this is cast for intergral promotion then
2174            check if only use of  the definition of the 
2175            operand being casted/ if yes then replace
2176            the result of that arithmetic operation with 
2177            this result and get rid of the cast */
2178         if (ic->op == CAST) {
2179             link *fromType = operandType(IC_RIGHT(ic));
2180             link *toType = operandType(IC_LEFT(ic));
2181
2182             if (IS_INTEGRAL(fromType) && IS_INTEGRAL(toType) &&
2183                 getSize(fromType) != getSize(toType) ) {
2184
2185                 iCode *dic = packRegsForOneuse(ic,IC_RIGHT(ic),ebp);
2186                 if (dic) {
2187                     if (IS_ARITHMETIC_OP(dic)) {
2188                         IC_RESULT(dic) = IC_RESULT(ic);
2189                         remiCodeFromeBBlock(ebp,ic);
2190                         hTabDeleteItem (&iCodehTab,ic->key,ic,DELETE_ITEM,NULL);
2191                         ic = ic->prev;
2192                     } else
2193                         OP_SYMBOL(IC_RIGHT(ic))->ruonly =  0;
2194                 }               
2195             } else {
2196                 
2197                 /* if the type from and type to are the same
2198                    then if this is the only use then packit */
2199                 if (checkType(operandType(IC_RIGHT(ic)),
2200                               operandType(IC_LEFT(ic))) == 1) {
2201                     iCode *dic = packRegsForOneuse (ic,IC_RIGHT(ic),ebp);
2202                     if (dic) {
2203                         IC_RESULT(dic) = IC_RESULT(ic);
2204                         remiCodeFromeBBlock(ebp,ic);
2205                         hTabDeleteItem (&iCodehTab,ic->key,ic,DELETE_ITEM,NULL);
2206                         ic = ic->prev;
2207                     }
2208                 }
2209             }
2210         }
2211         
2212         /* pack for PUSH 
2213            iTempNN := (some variable in farspace) V1
2214            push iTempNN ;
2215            -------------
2216            push V1
2217         */
2218         if (ic->op == IPUSH ) {
2219             packForPush(ic,ebp);
2220         }
2221           
2222         
2223         /* pack registers for accumulator use, when the
2224            result of an arithmetic or bit wise operation
2225            has only one use, that use is immediately following
2226            the defintion and the using iCode has only one
2227            operand or has two operands but one is literal &
2228            the result of that operation is not on stack then
2229            we can leave the result of this operation in acc:b
2230            combination */
2231         if ((IS_ARITHMETIC_OP(ic) 
2232              
2233              || IS_BITWISE_OP(ic) 
2234              
2235              || ic->op == LEFT_OP || ic->op == RIGHT_OP
2236              
2237              ) &&
2238             IS_ITEMP(IC_RESULT(ic)) &&
2239             getSize(operandType(IC_RESULT(ic))) <= 2)
2240
2241             packRegsForAccUse (ic);
2242
2243     }
2244 }
2245   
2246 /*-----------------------------------------------------------------*/
2247 /* assignRegisters - assigns registers to each live range as need  */
2248 /*-----------------------------------------------------------------*/
2249 void mcs51_assignRegisters (eBBlock **ebbs, int count)
2250 {
2251     iCode *ic;
2252     int i ;
2253
2254     setToNull((void *)&_G.funcrUsed);
2255     mcs51_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
2256     /* if not register extentions then reduce number
2257        of registers */
2258     if (options.regExtend)
2259         mcs51_nRegs = 13;
2260     else
2261         mcs51_nRegs = 8;
2262
2263     /* change assignments this will remove some
2264        live ranges reducing some register pressure */
2265     for (i = 0 ; i < count ;i++ )
2266         packRegisters (ebbs[i]);
2267     
2268     if (options.dump_pack)
2269         dumpEbbsToFileExt(".dumppack",ebbs,count);
2270
2271     /* first determine for each live range the number of 
2272        registers & the type of registers required for each */
2273     regTypeNum ();
2274     
2275     /* and serially allocate registers */ 
2276     serialRegAssign(ebbs,count);
2277
2278     /* if stack was extended then tell the user */
2279     if (_G.stackExtend) {
2280 /*      werror(W_TOOMANY_SPILS,"stack", */
2281 /*             _G.stackExtend,currFunc->name,""); */
2282         _G.stackExtend = 0 ;
2283     }
2284
2285     if (_G.dataExtend) {
2286 /*      werror(W_TOOMANY_SPILS,"data space", */
2287 /*             _G.dataExtend,currFunc->name,""); */
2288         _G.dataExtend = 0 ;
2289     }  
2290
2291     /* after that create the register mask
2292        for each of the instruction */
2293     createRegMask (ebbs,count);
2294
2295     /* redo that offsets for stacked automatic variables */
2296     redoStackOffsets ();
2297
2298     if (options.dump_rassgn)
2299         dumpEbbsToFileExt(".dumprassgn",ebbs,count);
2300
2301     /* now get back the chain */
2302     ic = iCodeLabelOptimize(iCodeFromeBBlock (ebbs,count));
2303
2304
2305     gen51Code(ic);
2306
2307     /* free up any _G.stackSpil locations allocated */   
2308     applyToSet(_G.stackSpil,deallocStackSpil);
2309     _G.slocNum = 0;
2310     setToNull((void **)&_G.stackSpil);
2311     setToNull((void **)&_G.spiltSet);
2312     /* mark all registers as free */
2313     freeAllRegs();
2314
2315     return ;
2316 }