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