Remove icodes from the iCodeHashTable when
[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_SYMOP(IC_RESULT(dic)) &&
1490             IC_RESULT(dic)->key == IC_RIGHT(ic)->key) {
1491             if (POINTER_SET(dic))
1492                 dic = NULL;
1493
1494             break;          
1495         }
1496
1497         if (IS_SYMOP(IC_RIGHT(dic)) && 
1498             (IC_RIGHT(dic)->key == IC_RESULT(ic)->key ||
1499              IC_RIGHT(dic)->key == IC_RIGHT(ic)->key)) {
1500             dic = NULL;
1501             break;
1502         }
1503         
1504         if (IS_SYMOP(IC_LEFT(dic)) && 
1505             (IC_LEFT(dic)->key == IC_RESULT(ic)->key ||
1506              IC_LEFT(dic)->key == IC_RIGHT(ic)->key)) {
1507             dic = NULL;
1508             break;
1509         }
1510
1511         if (POINTER_SET(dic) && 
1512             IC_RESULT(dic)->key == IC_RESULT(ic)->key ) {
1513             dic = NULL ;
1514             break;
1515         }
1516     }
1517     
1518     if (!dic)
1519         return 0 ; /* did not find */
1520             
1521     /* if the result is on stack or iaccess then it must be
1522        the same atleast one of the operands */
1523     if (OP_SYMBOL(IC_RESULT(ic))->onStack  || 
1524         OP_SYMBOL(IC_RESULT(ic))->iaccess ) {
1525         
1526         /* the operation has only one symbol
1527            operator then we can pack */
1528         if ((IC_LEFT(dic) && !IS_SYMOP(IC_LEFT(dic))) ||
1529             (IC_RIGHT(dic) && !IS_SYMOP(IC_RIGHT(dic))))
1530             goto pack;
1531
1532         if (!((IC_LEFT(dic) &&
1533              IC_RESULT(ic)->key == IC_LEFT(dic)->key) ||
1534               (IC_RIGHT(dic) &&
1535                IC_RESULT(ic)->key == IC_RIGHT(dic)->key)))
1536             return 0;                
1537     }
1538 pack:
1539     /* found the definition */
1540     /* replace the result with the result of */
1541     /* this assignment and remove this assignment */
1542     IC_RESULT(dic) = IC_RESULT(ic) ;
1543
1544     if (IS_ITEMP(IC_RESULT(dic)) && OP_SYMBOL(IC_RESULT(dic))->liveFrom > dic->seq) {
1545             OP_SYMBOL(IC_RESULT(dic))->liveFrom = dic->seq;
1546     }
1547     /* delete from liverange table also 
1548        delete from all the points inbetween and the new
1549        one */
1550     for ( sic = dic; sic != ic ; sic = sic->next ) {    
1551         bitVectUnSetBit(sic->rlive,IC_RESULT(ic)->key);
1552         if (IS_ITEMP(IC_RESULT(dic)))
1553             bitVectSetBit(sic->rlive,IC_RESULT(dic)->key);
1554     }
1555         
1556     remiCodeFromeBBlock(ebp,ic);
1557     hTabDeleteItem (&iCodehTab,ic->key,ic,DELETE_ITEM,NULL);
1558     return 1;
1559     
1560 }
1561
1562 /*-----------------------------------------------------------------*/
1563 /* findAssignToSym : scanning backwards looks for first assig found*/
1564 /*-----------------------------------------------------------------*/
1565 static iCode *findAssignToSym (operand *op,iCode *ic)
1566 {
1567     iCode *dic;
1568
1569     for (dic = ic->prev ; dic ; dic = dic->prev) {
1570         
1571         /* if definition by assignment */
1572         if (dic->op == '='                 && 
1573             !POINTER_SET(dic)              &&
1574             IC_RESULT(dic)->key == op->key
1575 /*          &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) */
1576             ) {    
1577
1578             /* we are interested only if defined in far space */
1579             /* or in stack space in case of + & - */
1580
1581             /* if assigned to a non-symbol then return
1582                true */
1583             if (!IS_SYMOP(IC_RIGHT(dic)))
1584                 break ;
1585
1586             /* if the symbol is in far space then
1587                we should not */
1588             if (isOperandInFarSpace(IC_RIGHT(dic)))
1589                 return NULL ;
1590
1591             /* for + & - operations make sure that
1592                if it is on the stack it is the same
1593                as one of the three operands */
1594             if ((ic->op == '+' || ic->op == '-') &&
1595                 OP_SYMBOL(IC_RIGHT(dic))->onStack) {
1596
1597                 if ( IC_RESULT(ic)->key != IC_RIGHT(dic)->key &&
1598                      IC_LEFT(ic)->key   != IC_RIGHT(dic)->key &&
1599                      IC_RIGHT(ic)->key  != IC_RIGHT(dic)->key)
1600                     return NULL;
1601             }           
1602
1603             break ;
1604                 
1605         }
1606
1607         /* if we find an usage then we cannot delete it */
1608         if (IC_LEFT(dic) && IC_LEFT(dic)->key == op->key)
1609             return NULL;
1610             
1611         if (IC_RIGHT(dic) && IC_RIGHT(dic)->key == op->key)
1612             return NULL;
1613
1614         if (POINTER_SET(dic) && IC_RESULT(dic)->key == op->key)
1615             return NULL;
1616     }
1617
1618     /* now make sure that the right side of dic
1619        is not defined between ic & dic */       
1620     if (dic) {
1621         iCode *sic = dic->next ;
1622
1623         for (; sic != ic ; sic = sic->next)
1624             if (IC_RESULT(sic) &&
1625                 IC_RESULT(sic)->key == IC_RIGHT(dic)->key)
1626                 return NULL;
1627     }
1628
1629     return dic;
1630         
1631         
1632 }
1633
1634 /*-----------------------------------------------------------------*/
1635 /* packRegsForSupport :- reduce some registers for support calls   */
1636 /*-----------------------------------------------------------------*/
1637 static int packRegsForSupport (iCode *ic, eBBlock *ebp)
1638 {
1639     int change = 0 ;
1640     /* for the left & right operand :- look to see if the
1641        left was assigned a true symbol in far space in that
1642        case replace them */
1643     if (IS_ITEMP(IC_LEFT(ic)) && 
1644         OP_SYMBOL(IC_LEFT(ic))->liveTo <= ic->seq) {
1645         iCode *dic = findAssignToSym(IC_LEFT(ic),ic);
1646         iCode *sic;
1647
1648         if (!dic)
1649             goto right ;
1650
1651         /* found it we need to remove it from the
1652            block */
1653         for ( sic = dic; sic != ic ; sic = sic->next )
1654             bitVectUnSetBit(sic->rlive,IC_LEFT(ic)->key);
1655
1656         IC_LEFT(ic)->operand.symOperand =
1657             IC_RIGHT(dic)->operand.symOperand;
1658         IC_LEFT(ic)->key = IC_RIGHT(dic)->operand.symOperand->key;
1659         remiCodeFromeBBlock(ebp,dic);
1660         hTabDeleteItem (&iCodehTab,dic->key,dic,DELETE_ITEM,NULL);
1661         change++;      
1662     }
1663     
1664     /* do the same for the right operand */
1665  right:    
1666     if (!change && 
1667         IS_ITEMP(IC_RIGHT(ic)) &&
1668         OP_SYMBOL(IC_RIGHT(ic))->liveTo <= ic->seq) {
1669         iCode *dic = findAssignToSym(IC_RIGHT(ic),ic);
1670         iCode *sic;
1671         
1672         if (!dic)
1673             return change ;
1674
1675         /* if this is a subtraction & the result
1676            is a true symbol in far space then don't pack */
1677         if (ic->op == '-' && IS_TRUE_SYMOP(IC_RESULT(dic))) {
1678             link *etype =getSpec(operandType(IC_RESULT(dic)));
1679             if (IN_FARSPACE(SPEC_OCLS(etype)))
1680                 return change ;
1681         }
1682         /* found it we need to remove it from the
1683            block */
1684         for ( sic = dic; sic != ic ; sic = sic->next )
1685             bitVectUnSetBit(sic->rlive,IC_RIGHT(ic)->key);
1686         
1687         IC_RIGHT(ic)->operand.symOperand =
1688             IC_RIGHT(dic)->operand.symOperand;
1689         IC_RIGHT(ic)->key = IC_RIGHT(dic)->operand.symOperand->key;
1690         
1691         remiCodeFromeBBlock(ebp,dic);
1692         hTabDeleteItem (&iCodehTab,dic->key,dic,DELETE_ITEM,NULL);
1693         change ++;
1694     }
1695    
1696     return change ;
1697 }
1698
1699 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
1700
1701
1702 /*-----------------------------------------------------------------*/
1703 /* packRegsForOneuse : - will reduce some registers for single Use */ 
1704 /*-----------------------------------------------------------------*/
1705 static iCode *packRegsForOneuse (iCode *ic, operand *op , eBBlock *ebp)
1706 {
1707     bitVect *uses ;
1708     iCode *dic, *sic;
1709
1710     /* if returning a literal then do nothing */
1711     if (!IS_SYMOP(op))
1712         return NULL;
1713     
1714     /* only upto 2 bytes since we cannot predict
1715        the usage of b, & acc */
1716     if (getSize(operandType(op)) > 2 && 
1717         ic->op != RETURN             &&
1718         ic->op != SEND)
1719         return NULL;
1720
1721     /* this routine will mark the a symbol as used in one 
1722        instruction use only && if the defintion is local 
1723        (ie. within the basic block) && has only one definition &&
1724        that definiion is either a return value from a 
1725        function or does not contain any variables in
1726        far space */
1727     uses = bitVectCopy(OP_USES(op));
1728     bitVectUnSetBit(uses,ic->key); /* take away this iCode */
1729     if (!bitVectIsZero(uses)) /* has other uses */
1730         return NULL ;
1731     
1732     /* if it has only one defintion */
1733     if (bitVectnBitsOn(OP_DEFS(op)) > 1)
1734         return NULL ; /* has more than one definition */
1735
1736     /* get the that definition */
1737     if (!(dic = 
1738           hTabItemWithKey(iCodehTab,
1739                           bitVectFirstBit(OP_DEFS(op)))))
1740         return NULL ;
1741
1742     /* found the definition now check if it is local */
1743     if (dic->seq < ebp->fSeq ||
1744         dic->seq > ebp->lSeq)
1745         return NULL ; /* non-local */
1746
1747     /* now check if it is the return from
1748        a function call */
1749     if (dic->op == CALL || dic->op == PCALL ) {
1750         if (ic->op != SEND && ic->op != RETURN) {
1751             OP_SYMBOL(op)->ruonly = 1;
1752             return dic;
1753         }
1754         dic = dic->next ;
1755     }
1756         
1757     
1758     /* otherwise check that the definition does
1759        not contain any symbols in far space */
1760     if (isOperandInFarSpace(IC_LEFT(dic))  ||
1761         isOperandInFarSpace(IC_RIGHT(dic)) ||
1762         IS_OP_RUONLY(IC_LEFT(ic))          ||
1763         IS_OP_RUONLY(IC_RIGHT(ic)) )        {
1764         return NULL;
1765     }
1766     
1767     /* if pointer set then make sure the pointer
1768        is one byte */
1769     if (POINTER_SET(dic) && 
1770         !IS_DATA_PTR(aggrToPtr(operandType(IC_RESULT(dic)),FALSE)))
1771         return NULL ;
1772
1773     if (POINTER_GET(dic) && 
1774         !IS_DATA_PTR(aggrToPtr(operandType(IC_LEFT(dic)),FALSE)))
1775         return NULL ;
1776     
1777     sic = dic;
1778
1779     /* also make sure the intervenening instructions
1780        don't have any thing in far space */
1781     for (dic = dic->next ; dic && dic != ic ; dic = dic->next) {
1782                 
1783         /* if there is an intervening function call then no */
1784         if (dic->op == CALL || dic->op == PCALL)
1785                 return NULL;
1786         /* if pointer set then make sure the pointer
1787            is one byte */
1788         if (POINTER_SET(dic) && 
1789             !IS_DATA_PTR(aggrToPtr(operandType(IC_RESULT(dic)),FALSE)))
1790             return NULL ;
1791         
1792         if (POINTER_GET(dic) && 
1793             !IS_DATA_PTR(aggrToPtr(operandType(IC_LEFT(dic)),FALSE)))
1794             return NULL ;
1795
1796         /* if address of & the result is remat the okay */
1797         if (dic->op == ADDRESS_OF &&
1798             OP_SYMBOL(IC_RESULT(dic))->remat)
1799             continue ;
1800            
1801         /* if operand has size of three or more & this
1802            operation is a '*','/' or '%' then 'b' may
1803            cause a problem */
1804         if (( dic->op == '%' || dic->op == '/' || dic->op == '*') &&
1805             getSize(aggrToPtr(operandType(op),FALSE)) >= 3)
1806                 return NULL;
1807
1808         /* if left or right or result is in far space */
1809         if (isOperandInFarSpace(IC_LEFT(dic))   ||
1810             isOperandInFarSpace(IC_RIGHT(dic))  ||
1811             isOperandInFarSpace(IC_RESULT(dic)) ||
1812             IS_OP_RUONLY(IC_LEFT(dic))          ||
1813             IS_OP_RUONLY(IC_RIGHT(dic))         ||
1814             IS_OP_RUONLY(IC_RESULT(dic))            ) {
1815             return NULL;
1816         }
1817     }
1818                 
1819     OP_SYMBOL(op)->ruonly = 1;
1820     return sic;
1821         
1822 }
1823
1824 /*-----------------------------------------------------------------*/
1825 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
1826 /*-----------------------------------------------------------------*/
1827 static bool isBitwiseOptimizable (iCode *ic)
1828 {
1829     link *ltype = getSpec(operandType(IC_LEFT(ic)));
1830     link *rtype = getSpec(operandType(IC_RIGHT(ic)));
1831
1832     /* bitwise operations are considered optimizable
1833        under the following conditions (Jean-Louis VERN) 
1834        
1835        x & lit
1836        bit & bit
1837        bit & x
1838        bit ^ bit
1839        bit ^ x
1840        x   ^ lit
1841        x   | lit
1842        bit | bit
1843        bit | x
1844     */    
1845     if ( IS_LITERAL(rtype) ||
1846          (IS_BITVAR(ltype) && IN_BITSPACE(SPEC_OCLS(ltype))))
1847         return TRUE ;
1848     else
1849         return FALSE ;    
1850 }
1851
1852 /*-----------------------------------------------------------------*/
1853 /* packRegsForAccUse - pack registers for acc use                  */
1854 /*-----------------------------------------------------------------*/
1855 static void packRegsForAccUse (iCode *ic)
1856 {
1857     iCode *uic;
1858     
1859     /* if + or - then it has to be one byte result */
1860     if ((ic->op == '+' || ic->op == '-')
1861         && getSize(operandType(IC_RESULT(ic))) > 1)
1862         return ;
1863     
1864     /* if shift operation make sure right side is not a literal */
1865     if (ic->op == RIGHT_OP  &&
1866         ( isOperandLiteral(IC_RIGHT(ic)) ||
1867           getSize(operandType(IC_RESULT(ic))) > 1))
1868         return ;
1869         
1870     if (ic->op == LEFT_OP &&        
1871         ( isOperandLiteral(IC_RIGHT(ic)) ||
1872           getSize(operandType(IC_RESULT(ic))) > 1))
1873         return ;
1874         
1875         
1876     /* has only one definition */
1877     if (bitVectnBitsOn(OP_DEFS(IC_RESULT(ic))) > 1)
1878         return ;
1879
1880     /* has only one use */
1881     if (bitVectnBitsOn(OP_USES(IC_RESULT(ic))) > 1)
1882         return ;
1883
1884     /* and the usage immediately follows this iCode */
1885     if (!(uic = hTabItemWithKey(iCodehTab,
1886                                 bitVectFirstBit(OP_USES(IC_RESULT(ic))))))
1887         return ;
1888
1889     if (ic->next != uic)
1890         return ;
1891     
1892     /* if it is a conditional branch then we definitely can */
1893     if (uic->op == IFX  ) 
1894         goto accuse;
1895
1896     if ( uic->op == JUMPTABLE )
1897         return ;
1898
1899     /* if the usage is not is an assignment
1900        or an arithmetic / bitwise / shift operation then not */
1901     if (POINTER_SET(uic) && 
1902         getSize(aggrToPtr(operandType(IC_RESULT(uic)),FALSE)) > 1)
1903         return;
1904
1905     if (uic->op != '=' && 
1906         !IS_ARITHMETIC_OP(uic) &&
1907         !IS_BITWISE_OP(uic)    &&
1908         uic->op != LEFT_OP &&
1909         uic->op != RIGHT_OP )
1910         return;
1911
1912     /* if used in ^ operation then make sure right is not a 
1913        literl */
1914     if (uic->op == '^' && isOperandLiteral(IC_RIGHT(uic)))
1915         return ;
1916
1917     /* if shift operation make sure right side is not a literal */
1918     if (uic->op == RIGHT_OP  &&
1919         ( isOperandLiteral(IC_RIGHT(uic)) ||
1920           getSize(operandType(IC_RESULT(uic))) > 1))
1921         return ;
1922
1923     if (uic->op == LEFT_OP &&        
1924         ( isOperandLiteral(IC_RIGHT(uic)) ||
1925           getSize(operandType(IC_RESULT(uic))) > 1))
1926         return ;
1927             
1928     /* make sure that the result of this icode is not on the
1929        stack, since acc is used to compute stack offset */
1930     if (IS_TRUE_SYMOP(IC_RESULT(uic)) &&
1931         OP_SYMBOL(IC_RESULT(uic))->onStack)
1932         return ;
1933
1934     /* if either one of them in far space then we cannot */
1935     if ((IS_TRUE_SYMOP(IC_LEFT(uic)) &&
1936          isOperandInFarSpace(IC_LEFT(uic))) ||
1937         (IS_TRUE_SYMOP(IC_RIGHT(uic)) &&
1938          isOperandInFarSpace(IC_RIGHT(uic))))
1939         return ;
1940
1941     /* if the usage has only one operand then we can */
1942     if (IC_LEFT(uic) == NULL ||
1943         IC_RIGHT(uic) == NULL) 
1944         goto accuse;
1945
1946     /* make sure this is on the left side if not
1947        a '+' since '+' is commutative */
1948     if (ic->op != '+' &&
1949         IC_LEFT(uic)->key != IC_RESULT(ic)->key)
1950         return;
1951
1952     /* if one of them is a literal then we can */
1953     if ((IC_LEFT(uic) && IS_OP_LITERAL(IC_LEFT(uic))) ||
1954         (IC_RIGHT(uic) && IS_OP_LITERAL(IC_RIGHT(uic)))) {
1955         OP_SYMBOL(IC_RESULT(ic))->accuse = 1;
1956         return ;
1957     }
1958
1959     /* if the other one is not on stack then we can */
1960     if (IC_LEFT(uic)->key == IC_RESULT(ic)->key &&
1961         (IS_ITEMP(IC_RIGHT(uic)) ||
1962          (IS_TRUE_SYMOP(IC_RIGHT(uic)) &&
1963           !OP_SYMBOL(IC_RIGHT(uic))->onStack))) 
1964         goto accuse;
1965     
1966     if (IC_RIGHT(uic)->key == IC_RESULT(ic)->key &&
1967         (IS_ITEMP(IC_LEFT(uic)) ||
1968          (IS_TRUE_SYMOP(IC_LEFT(uic)) &&
1969           !OP_SYMBOL(IC_LEFT(uic))->onStack))) 
1970         goto accuse ;
1971
1972     return ;
1973
1974  accuse:
1975     OP_SYMBOL(IC_RESULT(ic))->accuse = 1;
1976     
1977         
1978 }
1979
1980 /*-----------------------------------------------------------------*/
1981 /* packForPush - hueristics to reduce iCode for pushing            */
1982 /*-----------------------------------------------------------------*/
1983 static void packForPush(iCode *ic, eBBlock *ebp)
1984 {
1985     iCode *dic;
1986
1987     if (ic->op != IPUSH || !IS_ITEMP(IC_LEFT(ic)))
1988         return ;
1989
1990     /* must have only definition & one usage */
1991     if (bitVectnBitsOn(OP_DEFS(IC_LEFT(ic))) != 1 ||
1992         bitVectnBitsOn(OP_USES(IC_LEFT(ic))) != 1 )     
1993         return ;
1994     
1995     /* find the definition */
1996     if (!(dic = hTabItemWithKey(iCodehTab,
1997                                 bitVectFirstBit(OP_DEFS(IC_LEFT(ic))))))
1998         return ;
1999
2000     if (dic->op != '=' || POINTER_SET(dic) || IS_ITEMP(IC_RESULT(dic)))
2001         return;
2002
2003     /* we now we know that it has one & only one def & use
2004        and the that the definition is an assignment */
2005     IC_LEFT(ic) = IC_RIGHT(dic);
2006
2007     remiCodeFromeBBlock(ebp,dic);
2008     hTabDeleteItem (&iCodehTab,dic->key,dic,DELETE_ITEM,NULL);
2009 }
2010
2011 /*-----------------------------------------------------------------*/
2012 /* packRegisters - does some transformations to reduce register    */
2013 /*                   pressure                                      */
2014 /*-----------------------------------------------------------------*/
2015 static void packRegisters (eBBlock *ebp)
2016 {
2017     iCode *ic ;
2018     int change = 0 ;
2019     
2020     while (1) {
2021
2022         change = 0;
2023         
2024         /* look for assignments of the form */
2025         /* iTempNN = TRueSym (someoperation) SomeOperand */
2026         /*       ....                       */
2027         /* TrueSym := iTempNN:1             */
2028         for ( ic = ebp->sch ; ic ; ic = ic->next ) {
2029             
2030             
2031             /* find assignment of the form TrueSym := iTempNN:1 */
2032             if (ic->op == '=' && !POINTER_SET(ic))
2033                 change += packRegsForAssign(ic,ebp);
2034         }
2035
2036         if (!change)
2037             break;
2038     }
2039     
2040     for ( ic = ebp->sch ; ic ; ic = ic->next ) {
2041                 
2042         /* if this is an itemp & result of a address of a true sym 
2043            then mark this as rematerialisable   */
2044         if (ic->op == ADDRESS_OF && 
2045             IS_ITEMP(IC_RESULT(ic)) &&
2046             IS_TRUE_SYMOP(IC_LEFT(ic)) &&
2047             bitVectnBitsOn(OP_DEFS(IC_RESULT(ic))) == 1 &&
2048             !OP_SYMBOL(IC_LEFT(ic))->onStack ) {
2049
2050             OP_SYMBOL(IC_RESULT(ic))->remat = 1;
2051             OP_SYMBOL(IC_RESULT(ic))->rematiCode = ic;
2052             OP_SYMBOL(IC_RESULT(ic))->usl.spillLoc = NULL;
2053
2054         }
2055         
2056         /* if straight assignment then carry remat flag if
2057            this is the only definition */
2058         if (ic->op == '='    && 
2059             !POINTER_SET(ic) &&
2060             IS_SYMOP(IC_RIGHT(ic)) && 
2061             OP_SYMBOL(IC_RIGHT(ic))->remat &&
2062             bitVectnBitsOn(OP_SYMBOL(IC_RESULT(ic))->defs) <= 1) {
2063
2064             OP_SYMBOL(IC_RESULT(ic))->remat = 
2065                 OP_SYMBOL(IC_RIGHT(ic))->remat;
2066             OP_SYMBOL(IC_RESULT(ic))->rematiCode = 
2067                 OP_SYMBOL(IC_RIGHT(ic))->rematiCode ;
2068         }
2069
2070         /* if this is a +/- operation with a rematerizable 
2071            then mark this as rematerializable as well only
2072            if the literal value is within the range -255 and + 255
2073            the assembler cannot handle it other wise */
2074         if ((ic->op == '+' || ic->op == '-') &&
2075
2076             (IS_SYMOP(IC_LEFT(ic)) && 
2077              IS_ITEMP(IC_RESULT(ic)) &&
2078              OP_SYMBOL(IC_LEFT(ic))->remat &&
2079              bitVectnBitsOn(OP_DEFS(IC_RESULT(ic))) == 1 &&
2080              IS_OP_LITERAL(IC_RIGHT(ic))) ) {
2081
2082             int i = operandLitValue(IC_RIGHT(ic));
2083             if ( i < 255 && i > -255) {
2084                 OP_SYMBOL(IC_RESULT(ic))->remat = 1;
2085                 OP_SYMBOL(IC_RESULT(ic))->rematiCode = ic;
2086                 OP_SYMBOL(IC_RESULT(ic))->usl.spillLoc = NULL;
2087             }
2088         }
2089
2090         /* mark the pointer usages */
2091         if (POINTER_SET(ic))
2092             OP_SYMBOL(IC_RESULT(ic))->uptr = 1;
2093
2094         if (POINTER_GET(ic))
2095             OP_SYMBOL(IC_LEFT(ic))->uptr = 1;
2096         
2097         if (!SKIP_IC2(ic)) {
2098             /* if we are using a symbol on the stack
2099                then we should say mcs51_ptrRegReq */
2100             if (ic->op == IFX && IS_SYMOP(IC_COND(ic)))
2101                 mcs51_ptrRegReq += ((OP_SYMBOL(IC_COND(ic))->onStack ||
2102                                OP_SYMBOL(IC_COND(ic))->iaccess) ? 1 : 0);
2103             else
2104                 if (ic->op == JUMPTABLE && IS_SYMOP(IC_JTCOND(ic)))
2105                     mcs51_ptrRegReq += ((OP_SYMBOL(IC_JTCOND(ic))->onStack ||
2106                                    OP_SYMBOL(IC_JTCOND(ic))->iaccess) ? 1 : 0);
2107                 else {
2108                     if (IS_SYMOP(IC_LEFT(ic)))
2109                         mcs51_ptrRegReq += ((OP_SYMBOL(IC_LEFT(ic))->onStack ||
2110                                        OP_SYMBOL(IC_LEFT(ic))->iaccess) ? 1 : 0);
2111                     if (IS_SYMOP(IC_RIGHT(ic)))
2112                         mcs51_ptrRegReq += ((OP_SYMBOL(IC_RIGHT(ic))->onStack ||
2113                                        OP_SYMBOL(IC_RIGHT(ic))->iaccess) ? 1 : 0);
2114                     if (IS_SYMOP(IC_RESULT(ic)))
2115                         mcs51_ptrRegReq += ((OP_SYMBOL(IC_RESULT(ic))->onStack ||
2116                                        OP_SYMBOL(IC_RESULT(ic))->iaccess) ? 1 : 0);    
2117                 }
2118         }
2119
2120         /* if the condition of an if instruction
2121            is defined in the previous instruction then
2122            mark the itemp as a conditional */
2123         if ((IS_CONDITIONAL(ic) ||
2124              ( ( ic->op == BITWISEAND      ||
2125                  ic->op == '|'             ||
2126                  ic->op == '^' ) &&
2127                isBitwiseOptimizable(ic))) &&        
2128             ic->next && ic->next->op == IFX &&
2129             isOperandEqual(IC_RESULT(ic),IC_COND(ic->next)) &&
2130             OP_SYMBOL(IC_RESULT(ic))->liveTo <= ic->next->seq) {
2131             
2132             OP_SYMBOL(IC_RESULT(ic))->regType = REG_CND;            
2133             continue ;
2134         }
2135         
2136         /* reduce for support function calls */
2137         if (ic->supportRtn || ic->op == '+' || ic->op == '-' )
2138             packRegsForSupport (ic,ebp);        
2139         
2140         /* some cases the redundant moves can
2141            can be eliminated for return statements */
2142         if ((ic->op == RETURN || ic->op == SEND) &&
2143             !isOperandInFarSpace(IC_LEFT(ic))    &&
2144             !options.model)
2145             packRegsForOneuse (ic,IC_LEFT(ic),ebp);     
2146
2147         /* if pointer set & left has a size more than
2148            one and right is not in far space */
2149         if (POINTER_SET(ic)                    &&
2150             !isOperandInFarSpace(IC_RIGHT(ic)) &&
2151             !OP_SYMBOL(IC_RESULT(ic))->remat   &&
2152             !IS_OP_RUONLY(IC_RIGHT(ic))        &&
2153             getSize(aggrToPtr(operandType(IC_RESULT(ic)),FALSE)) > 1 )
2154
2155             packRegsForOneuse (ic,IC_RESULT(ic),ebp);
2156
2157         /* if pointer get */
2158         if (POINTER_GET(ic)                    &&
2159             !isOperandInFarSpace(IC_RESULT(ic))&&
2160             !OP_SYMBOL(IC_LEFT(ic))->remat     &&
2161             !IS_OP_RUONLY(IC_RESULT(ic))         &&
2162             getSize(aggrToPtr(operandType(IC_LEFT(ic)),FALSE)) > 1 )
2163
2164             packRegsForOneuse (ic,IC_LEFT(ic),ebp);
2165
2166
2167         /* if this is cast for intergral promotion then
2168            check if only use of  the definition of the 
2169            operand being casted/ if yes then replace
2170            the result of that arithmetic operation with 
2171            this result and get rid of the cast */
2172         if (ic->op == CAST) {
2173             link *fromType = operandType(IC_RIGHT(ic));
2174             link *toType = operandType(IC_LEFT(ic));
2175
2176             if (IS_INTEGRAL(fromType) && IS_INTEGRAL(toType) &&
2177                 getSize(fromType) != getSize(toType) ) {
2178
2179                 iCode *dic = packRegsForOneuse(ic,IC_RIGHT(ic),ebp);
2180                 if (dic) {
2181                     if (IS_ARITHMETIC_OP(dic)) {
2182                         IC_RESULT(dic) = IC_RESULT(ic);
2183                         remiCodeFromeBBlock(ebp,ic);
2184                         hTabDeleteItem (&iCodehTab,ic->key,ic,DELETE_ITEM,NULL);
2185                         ic = ic->prev;
2186                     } else
2187                         OP_SYMBOL(IC_RIGHT(ic))->ruonly =  0;
2188                 }               
2189             } else {
2190                 
2191                 /* if the type from and type to are the same
2192                    then if this is the only use then packit */
2193                 if (checkType(operandType(IC_RIGHT(ic)),
2194                               operandType(IC_LEFT(ic))) == 1) {
2195                     iCode *dic = packRegsForOneuse (ic,IC_RIGHT(ic),ebp);
2196                     if (dic) {
2197                         IC_RESULT(dic) = IC_RESULT(ic);
2198                         remiCodeFromeBBlock(ebp,ic);
2199                         hTabDeleteItem (&iCodehTab,ic->key,ic,DELETE_ITEM,NULL);
2200                         ic = ic->prev;
2201                     }
2202                 }
2203             }
2204         }
2205         
2206         /* pack for PUSH 
2207            iTempNN := (some variable in farspace) V1
2208            push iTempNN ;
2209            -------------
2210            push V1
2211         */
2212         if (ic->op == IPUSH ) {
2213             packForPush(ic,ebp);
2214         }
2215           
2216         
2217         /* pack registers for accumulator use, when the
2218            result of an arithmetic or bit wise operation
2219            has only one use, that use is immediately following
2220            the defintion and the using iCode has only one
2221            operand or has two operands but one is literal &
2222            the result of that operation is not on stack then
2223            we can leave the result of this operation in acc:b
2224            combination */
2225         if ((IS_ARITHMETIC_OP(ic) 
2226              
2227              || IS_BITWISE_OP(ic) 
2228              
2229              || ic->op == LEFT_OP || ic->op == RIGHT_OP
2230              
2231              ) &&
2232             IS_ITEMP(IC_RESULT(ic)) &&
2233             getSize(operandType(IC_RESULT(ic))) <= 2)
2234
2235             packRegsForAccUse (ic);
2236
2237     }
2238 }
2239   
2240 /*-----------------------------------------------------------------*/
2241 /* assignRegisters - assigns registers to each live range as need  */
2242 /*-----------------------------------------------------------------*/
2243 void mcs51_assignRegisters (eBBlock **ebbs, int count)
2244 {
2245     iCode *ic;
2246     int i ;
2247
2248     setToNull((void *)&_G.funcrUsed);
2249     mcs51_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
2250     /* if not register extentions then reduce number
2251        of registers */
2252     if (options.regExtend)
2253         mcs51_nRegs = 13;
2254     else
2255         mcs51_nRegs = 8;
2256
2257     /* change assignments this will remove some
2258        live ranges reducing some register pressure */
2259     for (i = 0 ; i < count ;i++ )
2260         packRegisters (ebbs[i]);
2261     
2262     if (options.dump_pack)
2263         dumpEbbsToFileExt(".dumppack",ebbs,count);
2264
2265     /* first determine for each live range the number of 
2266        registers & the type of registers required for each */
2267     regTypeNum ();
2268     
2269     /* and serially allocate registers */ 
2270     serialRegAssign(ebbs,count);
2271
2272     /* if stack was extended then tell the user */
2273     if (_G.stackExtend) {
2274 /*      werror(W_TOOMANY_SPILS,"stack", */
2275 /*             _G.stackExtend,currFunc->name,""); */
2276         _G.stackExtend = 0 ;
2277     }
2278
2279     if (_G.dataExtend) {
2280 /*      werror(W_TOOMANY_SPILS,"data space", */
2281 /*             _G.dataExtend,currFunc->name,""); */
2282         _G.dataExtend = 0 ;
2283     }  
2284
2285     /* after that create the register mask
2286        for each of the instruction */
2287     createRegMask (ebbs,count);
2288
2289     /* redo that offsets for stacked automatic variables */
2290     redoStackOffsets ();
2291
2292     if (options.dump_rassgn)
2293         dumpEbbsToFileExt(".dumprassgn",ebbs,count);
2294
2295     /* now get back the chain */
2296     ic = iCodeLabelOptimize(iCodeFromeBBlock (ebbs,count));
2297
2298
2299     gen51Code(ic);
2300
2301     /* free up any _G.stackSpil locations allocated */   
2302     applyToSet(_G.stackSpil,deallocStackSpil);
2303     _G.slocNum = 0;
2304     setToNull((void **)&_G.stackSpil);
2305     setToNull((void **)&_G.spiltSet);
2306     /* mark all registers as free */
2307     freeAllRegs();
2308
2309     return ;
2310 }