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