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