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