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