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