Yet another reg alloc bug uncovered by ds390
[fw/sdcc] / src / ds390 / 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 gen390Code(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 ds390_ptrRegReq; /* one byte pointer register required */
55
56 /* 8051 registers */
57 regs regs390[] = 
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 ds390_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 < ds390_nRegs ; i++ ) {
86
87         /* if type is given as 0 then any
88            free register will do */
89         if (!type &&
90             regs390[i].isFree ) {
91             regs390[i].isFree = 0;
92             if (currFunc)
93                 currFunc->regsUsed = 
94                     bitVectSetBit(currFunc->regsUsed,i);
95             return &regs390[i];
96         }
97         /* other wise look for specific type
98            of register */
99         if (regs390[i].isFree && 
100             regs390[i].type == type) {
101             regs390[i].isFree = 0;
102             if (currFunc)
103                 currFunc->regsUsed = 
104                     bitVectSetBit(currFunc->regsUsed,i);
105             return &regs390[i];
106         }
107     }
108     return NULL;
109 }
110
111 /*-----------------------------------------------------------------*/
112 /* ds390_regWithIdx - returns pointer to register wit index number       */
113 /*-----------------------------------------------------------------*/
114 regs *ds390_regWithIdx (int idx)
115 {
116     int i ;
117     
118     for (i=0;i < ds390_nRegs;i++)
119         if (regs390[i].rIdx == idx)
120             return &regs390[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 < ds390_nRegs; i++ )
145         if (regs390[i].isFree && regs390[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 = ds390_regWithIdx(R0_IDX);
409     r1 = ds390_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) = options.model ? S_XDATA : 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        and turn off overlaying 
483     */
484     
485     useXstack = options.useXstack;
486     model = options.model;
487     noOverlay = options.noOverlay;
488     options.noOverlay = 1;
489     
490     /* options.model = options.useXstack = 0; */
491
492     allocLocal(sloc);
493
494     options.useXstack = useXstack;
495     options.model     = model;
496     options.noOverlay = noOverlay;
497     sloc->isref = 1; /* to prevent compiler warning */
498     
499     /* if it is on the stack then update the stack */
500     if (IN_STACK(sloc->etype)) {
501         currFunc->stack += getSize(sloc->type);
502         _G.stackExtend += getSize(sloc->type);
503     } else
504         _G.dataExtend += getSize(sloc->type);
505
506     /* add it to the _G.stackSpil set */
507     addSetHead(&_G.stackSpil,sloc);
508     sym->usl.spillLoc = sloc;
509     sym->stackSpil = 1;
510     
511     /* add it to the set of itempStack set 
512        of the spill location */
513     addSetHead(&sloc->usl.itmpStack,sym);
514     return sym;
515 }
516
517 /*-----------------------------------------------------------------*/
518 /* isSpiltOnStack - returns true if the spil location is on stack  */
519 /*-----------------------------------------------------------------*/
520 static bool isSpiltOnStack (symbol *sym)
521 {
522     link *etype;
523
524     if (!sym)
525         return FALSE ;
526     
527     if (!sym->isspilt)
528         return FALSE ;
529
530 /*     if (sym->_G.stackSpil) */
531 /*      return TRUE; */
532     
533     if (!sym->usl.spillLoc)
534         return FALSE;
535
536     etype = getSpec(sym->usl.spillLoc->type);
537     if (IN_STACK(etype))
538         return TRUE;
539
540     return FALSE ;
541 }
542
543 /*-----------------------------------------------------------------*/
544 /* spillThis - spils a specific operand                            */
545 /*-----------------------------------------------------------------*/
546 static void spillThis (symbol *sym)
547 {
548     int i;
549     /* if this is rematerializable or has a spillLocation
550        we are okay, else we need to create a spillLocation
551        for it */
552     if (!(sym->remat || sym->usl.spillLoc)) 
553         createStackSpil (sym);
554     
555
556     /* mark it has spilt & put it in the spilt set */
557     sym->isspilt = 1;
558     _G.spiltSet = bitVectSetBit(_G.spiltSet,sym->key);
559        
560     bitVectUnSetBit(_G.regAssigned,sym->key);
561
562     for (i = 0 ; i < sym->nRegs ; i++)
563
564         if (sym->regs[i]) {
565             freeReg(sym->regs[i]);
566             sym->regs[i] = NULL;
567         }
568     
569     /* if spilt on stack then free up r0 & r1 
570        if they could have been assigned to some
571        LIVE ranges */
572     if (!ds390_ptrRegReq && isSpiltOnStack(sym)) {
573         ds390_ptrRegReq++ ;
574         spillLRWithPtrReg(sym);
575     }
576
577     if (sym->usl.spillLoc && !sym->remat)
578         sym->usl.spillLoc->allocreq = 1;
579     return;
580 }
581
582 /*-----------------------------------------------------------------*/
583 /* selectSpil - select a iTemp to spil : rather a simple procedure */
584 /*-----------------------------------------------------------------*/
585 static symbol *selectSpil (iCode *ic, eBBlock *ebp, symbol *forSym)
586 {
587     bitVect *lrcs= NULL ; 
588     set *selectS ;
589     symbol *sym;
590
591     /* get the spillable live ranges */
592     lrcs = computeSpillable (ic);
593
594     /* get all live ranges that are rematerizable */
595     if ((selectS = liveRangesWith(lrcs,rematable,ebp,ic))) {
596
597         /* return the least used of these */
598         return leastUsedLR(selectS);
599     }
600
601     /* get live ranges with spillLocations in direct space */
602     if ((selectS = liveRangesWith(lrcs,directSpilLoc,ebp,ic))) {
603         sym = leastUsedLR(selectS);
604         strcpy(sym->rname,(sym->usl.spillLoc->rname[0] ? 
605                            sym->usl.spillLoc->rname : 
606                            sym->usl.spillLoc->name)); 
607         sym->spildir = 1;
608         /* mark it as allocation required */
609         sym->usl.spillLoc->allocreq = 1;
610         return sym;
611     }
612
613     /* if the symbol is local to the block then */
614     if (forSym->liveTo < ebp->lSeq) {       
615
616         /* check if there are any live ranges allocated
617            to registers that are not used in this block */
618         if (!_G.blockSpil && (selectS = liveRangesWith(lrcs,notUsedInBlock,ebp,ic))) {
619             sym = leastUsedLR(selectS);
620             /* if this is not rematerializable */
621             if (!sym->remat) {
622                 _G.blockSpil++;
623                 sym->blockSpil = 1;
624             }
625             return sym;
626         } 
627
628         /* check if there are any live ranges that not
629            used in the remainder of the block */
630         if (!_G.blockSpil && (selectS = liveRangesWith(lrcs,notUsedInRemaining,ebp,ic))) {
631             sym = leastUsedLR (selectS);
632             if (sym != forSym) {
633                 if (!sym->remat) {
634                     sym->remainSpil = 1;
635                     _G.blockSpil++;
636                 }
637                 return sym;
638             }
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 static 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     _G.spiltSet = bitVectSetBit(_G.spiltSet,ssym->key);
691     
692     /* mark it as not register assigned &
693        take it away from the set */   
694     bitVectUnSetBit(_G.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 (!ds390_ptrRegReq && isSpiltOnStack(ssym) ) {
704         ds390_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 static 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 static 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 (!ds390_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 static 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(_G.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(_G.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(_G.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 < 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                 _G.regAssigned = bitVectSetBit(_G.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 static 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(_G.spiltSet,sym->key);
909       
910     _G.regAssigned = bitVectSetBit(_G.regAssigned,sym->key);
911
912     _G.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 static 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 (ds390_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 static 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(_G.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 (_G.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) 
1082                     <= PTRSIZE) 
1083                 {
1084                     ds390_ptrRegReq++;
1085                     ptrRegSet = 1;
1086                 }
1087                 /* else we assign registers to it */            
1088                 _G.regAssigned = bitVectSetBit(_G.regAssigned,sym->key);
1089
1090                 for (j = 0 ; j < sym->nRegs ;j++ ) {
1091                     if (sym->regType == REG_PTR)
1092                         sym->regs[j] = getRegPtr(ic,ebbs[i],sym);
1093                     else
1094                         sym->regs[j] = getRegGpr(ic,ebbs[i],sym);
1095
1096                     /* if the allocation falied which means
1097                        this was spilt then break */
1098                     if (!sym->regs[j])
1099                         break;
1100                 }
1101                 /* if it shares registers with operands make sure
1102                    that they are in the same position */
1103                 if (IC_LEFT(ic) && IS_SYMOP(IC_LEFT(ic)) &&
1104                     OP_SYMBOL(IC_LEFT(ic))->nRegs  && ic->op != '=')
1105                         positionRegs(OP_SYMBOL(IC_RESULT(ic)),
1106                                      OP_SYMBOL(IC_LEFT(ic)),ic->lineno);
1107                 /* do the same for the right operand */
1108                 if (IC_RIGHT(ic) && IS_SYMOP(IC_RIGHT(ic)) &&
1109                     OP_SYMBOL(IC_RIGHT(ic))->nRegs)
1110                         positionRegs(OP_SYMBOL(IC_RESULT(ic)),
1111                                      OP_SYMBOL(IC_RIGHT(ic)),ic->lineno);
1112                 
1113                 if (ptrRegSet) {
1114                     ds390_ptrRegReq--;
1115                     ptrRegSet = 0;
1116                 }
1117                                 
1118             }       
1119         }
1120     }
1121 }
1122
1123 /*-----------------------------------------------------------------*/
1124 /* rUmaskForOp :- returns register mask for an operand             */
1125 /*-----------------------------------------------------------------*/
1126 static bitVect *rUmaskForOp (operand *op)
1127 {
1128     bitVect *rumask;
1129     symbol *sym;
1130     int j;
1131     
1132     /* only temporaries are assigned registers */
1133     if (!IS_ITEMP(op)) 
1134         return NULL;
1135
1136     sym = OP_SYMBOL(op);
1137     
1138     /* if spilt or no registers assigned to it
1139        then nothing */
1140     if (sym->isspilt || !sym->nRegs)
1141         return NULL;
1142
1143     rumask = newBitVect(ds390_nRegs);
1144
1145     for (j = 0; j < sym->nRegs; j++) {  
1146         rumask = bitVectSetBit(rumask,
1147                                sym->regs[j]->rIdx);
1148     }
1149
1150     return rumask;
1151 }
1152
1153 /*-----------------------------------------------------------------*/
1154 /* regsUsedIniCode :- returns bit vector of registers used in iCode*/
1155 /*-----------------------------------------------------------------*/
1156 static bitVect *regsUsedIniCode (iCode *ic)
1157 {
1158     bitVect *rmask = newBitVect(ds390_nRegs);
1159
1160     /* do the special cases first */
1161     if (ic->op == IFX ) {
1162         rmask = bitVectUnion(rmask,
1163                              rUmaskForOp(IC_COND(ic)));
1164         goto ret;
1165     }
1166
1167     /* for the jumptable */
1168     if (ic->op == JUMPTABLE) {
1169         rmask = bitVectUnion(rmask,
1170                              rUmaskForOp(IC_JTCOND(ic)));
1171
1172         goto ret;
1173     }
1174
1175     /* of all other cases */
1176     if (IC_LEFT(ic)) 
1177         rmask = bitVectUnion(rmask,
1178                              rUmaskForOp(IC_LEFT(ic)));
1179         
1180     
1181     if (IC_RIGHT(ic))
1182         rmask = bitVectUnion(rmask,
1183                              rUmaskForOp(IC_RIGHT(ic)));
1184
1185     if (IC_RESULT(ic))
1186         rmask = bitVectUnion(rmask,
1187                              rUmaskForOp(IC_RESULT(ic)));
1188
1189  ret:
1190     return rmask;
1191 }
1192
1193 /*-----------------------------------------------------------------*/
1194 /* createRegMask - for each instruction will determine the regsUsed*/
1195 /*-----------------------------------------------------------------*/
1196 static void createRegMask (eBBlock **ebbs, int count)
1197 {
1198     int i;
1199
1200     /* for all blocks */
1201     for (i = 0; i < count ; i++ ) {
1202         iCode *ic ;
1203
1204         if ( ebbs[i]->noPath &&
1205              ( ebbs[i]->entryLabel != entryLabel &&
1206                ebbs[i]->entryLabel != returnLabel ))
1207             continue ;
1208
1209         /* for all instructions */
1210         for ( ic = ebbs[i]->sch ; ic ; ic = ic->next ) {
1211             
1212             int j;
1213
1214             if (SKIP_IC2(ic) || !ic->rlive)
1215                 continue ;
1216             
1217             /* first mark the registers used in this
1218                instruction */
1219             ic->rUsed = regsUsedIniCode(ic);
1220             _G.funcrUsed = bitVectUnion(_G.funcrUsed,ic->rUsed);
1221
1222             /* now create the register mask for those 
1223                registers that are in use : this is a
1224                super set of ic->rUsed */
1225             ic->rMask = newBitVect(ds390_nRegs+1);
1226
1227             /* for all live Ranges alive at this point */
1228             for (j = 1; j < ic->rlive->size; j++ ) {
1229                 symbol *sym;
1230                 int k;
1231
1232                 /* if not alive then continue */
1233                 if (!bitVectBitValue(ic->rlive,j))
1234                     continue ;
1235
1236                 /* find the live range we are interested in */
1237                 if (!(sym = hTabItemWithKey(liveRanges,j))) {
1238                     werror (E_INTERNAL_ERROR,__FILE__,__LINE__,
1239                             "createRegMask cannot find live range");
1240                     exit(0);
1241                 }
1242
1243                 /* if no register assigned to it */
1244                 if (!sym->nRegs || sym->isspilt)
1245                     continue ;
1246
1247                 /* for all the registers allocated to it */
1248                 for (k = 0 ; k < sym->nRegs ;k++)
1249                     if (sym->regs[k])
1250                         ic->rMask =
1251                             bitVectSetBit(ic->rMask,sym->regs[k]->rIdx);
1252             }
1253         }
1254     }
1255 }
1256
1257 /*-----------------------------------------------------------------*/
1258 /* rematStr - returns the rematerialized string for a remat var    */
1259 /*-----------------------------------------------------------------*/
1260 static char *rematStr (symbol *sym)
1261 {
1262     char *s = buffer;   
1263     iCode *ic = sym->rematiCode;    
1264
1265     while (1) {
1266
1267         /* if plus or minus print the right hand side */
1268         if (ic->op == '+' || ic->op == '-') {
1269             sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
1270                     ic->op );
1271             s += strlen(s);
1272             ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
1273             continue ;
1274         }
1275
1276         /* we reached the end */
1277         sprintf(s,"%s",OP_SYMBOL(IC_LEFT(ic))->rname);
1278         break;
1279     }
1280
1281     return buffer ;
1282 }
1283
1284 /*-----------------------------------------------------------------*/
1285 /* regTypeNum - computes the type & number of registers required   */
1286 /*-----------------------------------------------------------------*/
1287 static void regTypeNum ()
1288 {
1289     symbol *sym;
1290     int k;
1291     iCode *ic;
1292
1293     /* for each live range do */
1294     for ( sym = hTabFirstItem(liveRanges,&k); sym ;
1295           sym = hTabNextItem(liveRanges,&k)) {
1296
1297         /* if used zero times then no registers needed */
1298         if ((sym->liveTo - sym->liveFrom) == 0)
1299             continue ;
1300
1301
1302         /* if the live range is a temporary */
1303         if (sym->isitmp) {
1304
1305             /* if the type is marked as a conditional */
1306             if (sym->regType == REG_CND)
1307                 continue ;
1308
1309             /* if used in return only then we don't 
1310                need registers */
1311             if (sym->ruonly || sym->accuse) {
1312                 if (IS_AGGREGATE(sym->type) || sym->isptr)
1313                     sym->type = aggrToPtr(sym->type,FALSE);
1314                 continue ;
1315             }
1316             
1317             /* if the symbol has only one definition &
1318                that definition is a get_pointer and the
1319                pointer we are getting is rematerializable and
1320                in "data" space */
1321                
1322             if (bitVectnBitsOn(sym->defs) == 1 &&
1323                 (ic = hTabItemWithKey(iCodehTab,
1324                                       bitVectFirstBit(sym->defs))) &&
1325                 POINTER_GET(ic) && 
1326                 !IS_BITVAR(sym->etype)) {
1327                 
1328                                 
1329                 /* if remat in data space */
1330                 if (OP_SYMBOL(IC_LEFT(ic))->remat &&
1331                     // sym->type &&
1332                     DCL_TYPE(aggrToPtr(sym->type,FALSE)) == POINTER) {
1333                 
1334                     /* create a psuedo symbol & force a spil */
1335                     symbol *psym = newSymbol(rematStr(OP_SYMBOL(IC_LEFT(ic))),1);
1336                     psym->type = sym->type;
1337                     psym->etype = sym->etype;
1338                     strcpy(psym->rname,psym->name);
1339                     sym->isspilt = 1;
1340                     sym->usl.spillLoc = psym;
1341                     continue ;
1342                 }
1343
1344                 /* if in data space or idata space then try to
1345                    allocate pointer register */
1346                    
1347             }
1348                 
1349             /* if not then we require registers */
1350             sym->nRegs = ((IS_AGGREGATE(sym->type) || sym->isptr ) ?
1351                           getSize(sym->type = aggrToPtr(sym->type,FALSE)) :
1352                           getSize(sym->type));
1353
1354             if (sym->nRegs > 4) {
1355                 fprintf(stderr,"allocated more than 4 or 0 registers for type ");
1356                 printTypeChain(sym->type,stderr);fprintf(stderr,"\n");
1357             }
1358             
1359             /* determine the type of register required */
1360             if (sym->nRegs == 1   && 
1361                 IS_PTR(sym->type) && 
1362                 sym->uptr) 
1363                 sym->regType = REG_PTR ;            
1364             else 
1365                 sym->regType = REG_GPR ;
1366             
1367         } else 
1368             /* for the first run we don't provide */
1369             /* registers for true symbols we will */
1370             /* see how things go                  */
1371             sym->nRegs = 0 ;    
1372     }
1373     
1374 }
1375
1376 /*-----------------------------------------------------------------*/
1377 /* freeAllRegs - mark all registers as free                        */
1378 /*-----------------------------------------------------------------*/
1379 static void freeAllRegs()
1380 {
1381     int i;
1382
1383     for (i=0;i< ds390_nRegs;i++ )
1384         regs390[i].isFree = 1;
1385 }
1386
1387 /*-----------------------------------------------------------------*/
1388 /* deallocStackSpil - this will set the stack pointer back         */
1389 /*-----------------------------------------------------------------*/
1390 static DEFSETFUNC(deallocStackSpil)
1391 {
1392     symbol *sym = item;
1393
1394     deallocLocal(sym);
1395     return 0;
1396 }
1397
1398 /*-----------------------------------------------------------------*/
1399 /* farSpacePackable - returns the packable icode for far variables */
1400 /*-----------------------------------------------------------------*/
1401 static iCode *farSpacePackable (iCode *ic)
1402 {
1403     iCode *dic ;
1404
1405     /* go thru till we find a definition for the
1406        symbol on the right */
1407     for ( dic = ic->prev ; dic ; dic = dic->prev) {
1408                 
1409         /* if the definition is a call then no */
1410         if ((dic->op == CALL || dic->op == PCALL) &&
1411             IC_RESULT(dic)->key == IC_RIGHT(ic)->key) {
1412             return NULL;
1413         }
1414         
1415         /* if shift by unknown amount then not */
1416         if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
1417             IC_RESULT(dic)->key == IC_RIGHT(ic)->key)
1418             return NULL;
1419
1420         /* if pointer get and size > 1 */
1421         if (POINTER_GET(dic) &&
1422             getSize(aggrToPtr(operandType(IC_LEFT(dic)),FALSE)) > 1)
1423             return NULL ;
1424
1425         if (POINTER_SET(dic) &&
1426             getSize(aggrToPtr(operandType(IC_RESULT(dic)),FALSE)) > 1)
1427             return NULL ;
1428
1429         /* if any three is a true symbol in far space */
1430         if (IC_RESULT(dic) &&
1431             IS_TRUE_SYMOP(IC_RESULT(dic)) &&
1432             isOperandInFarSpace(IC_RESULT(dic)))         
1433             return NULL;
1434
1435         if (IC_RIGHT(dic) &&
1436             IS_TRUE_SYMOP(IC_RIGHT(dic)) &&
1437             isOperandInFarSpace(IC_RIGHT(dic)) &&
1438             !isOperandEqual(IC_RIGHT(dic),IC_RESULT(ic)))
1439             return NULL;
1440
1441         if (IC_LEFT(dic) &&
1442             IS_TRUE_SYMOP(IC_LEFT(dic)) &&
1443             isOperandInFarSpace(IC_LEFT(dic)) &&
1444             !isOperandEqual(IC_LEFT(dic),IC_RESULT(ic)))
1445             return NULL;
1446         
1447         if (isOperandEqual(IC_RIGHT(ic),IC_RESULT(dic))) {
1448             if ( (dic->op == LEFT_OP  ||
1449                   dic->op == RIGHT_OP ||
1450                   dic->op == '-') &&
1451                  IS_OP_LITERAL(IC_RIGHT(dic)))
1452                 return NULL;
1453             else
1454                 return dic;
1455         }
1456     }
1457
1458     return NULL;
1459 }
1460
1461 /*-----------------------------------------------------------------*/
1462 /* packRegsForAssign - register reduction for assignment           */
1463 /*-----------------------------------------------------------------*/
1464 static int packRegsForAssign (iCode *ic,eBBlock *ebp)
1465 {
1466     iCode *dic, *sic;
1467     
1468     if (!IS_ITEMP(IC_RIGHT(ic))       ||        
1469         OP_SYMBOL(IC_RIGHT(ic))->isind ||
1470         OP_LIVETO(IC_RIGHT(ic)) > ic->seq) {
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 the result is on stack or iaccess then it must be
1539        the same atleast one of the operands */
1540     if (OP_SYMBOL(IC_RESULT(ic))->onStack  || 
1541         OP_SYMBOL(IC_RESULT(ic))->iaccess ) {
1542         
1543         /* the operation has only one symbol
1544            operator then we can pack */
1545         if ((IC_LEFT(dic) && !IS_SYMOP(IC_LEFT(dic))) ||
1546             (IC_RIGHT(dic) && !IS_SYMOP(IC_RIGHT(dic))))
1547             goto pack;
1548
1549         if (!((IC_LEFT(dic) &&
1550              IC_RESULT(ic)->key == IC_LEFT(dic)->key) ||
1551               (IC_RIGHT(dic) &&
1552                IC_RESULT(ic)->key == IC_RIGHT(dic)->key)))
1553             return 0;                
1554     }
1555 pack:
1556     /* found the definition */
1557     /* replace the result with the result of */
1558     /* this assignment and remove this assignment */
1559     IC_RESULT(dic) = IC_RESULT(ic) ;
1560
1561     if (IS_ITEMP(IC_RESULT(dic)) && OP_SYMBOL(IC_RESULT(dic))->liveFrom > dic->seq) {
1562             OP_SYMBOL(IC_RESULT(dic))->liveFrom = dic->seq;
1563     }
1564     /* delete from liverange table also 
1565        delete from all the points inbetween and the new
1566        one */
1567     for ( sic = dic; sic != ic ; sic = sic->next ) {    
1568         bitVectUnSetBit(sic->rlive,IC_RESULT(ic)->key);
1569         if (IS_ITEMP(IC_RESULT(dic)))
1570             bitVectSetBit(sic->rlive,IC_RESULT(dic)->key);
1571     }
1572         
1573     remiCodeFromeBBlock(ebp,ic);
1574     hTabDeleteItem (&iCodehTab,ic->key,ic,DELETE_ITEM,NULL);
1575     OP_DEFS(IC_RESULT(dic)) = bitVectSetBit(OP_DEFS(IC_RESULT(dic)),dic->key);
1576     return 1;
1577     
1578 }
1579
1580 /*-----------------------------------------------------------------*/
1581 /* findAssignToSym : scanning backwards looks for first assig found*/
1582 /*-----------------------------------------------------------------*/
1583 static iCode *findAssignToSym (operand *op,iCode *ic)
1584 {
1585     iCode *dic;
1586
1587     for (dic = ic->prev ; dic ; dic = dic->prev) {
1588         
1589         /* if definition by assignment */
1590         if (dic->op == '='                 && 
1591             !POINTER_SET(dic)              &&
1592             IC_RESULT(dic)->key == op->key
1593 /*          &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) */
1594             ) {    
1595
1596             /* we are interested only if defined in far space */
1597             /* or in stack space in case of + & - */
1598
1599             /* if assigned to a non-symbol then return
1600                true */
1601             if (!IS_SYMOP(IC_RIGHT(dic)))
1602                 break ;
1603
1604             /* if the symbol is in far space then
1605                we should not */
1606             if (isOperandInFarSpace(IC_RIGHT(dic)))
1607                 return NULL ;
1608
1609             /* for + & - operations make sure that
1610                if it is on the stack it is the same
1611                as one of the three operands */
1612             if ((ic->op == '+' || ic->op == '-') &&
1613                 OP_SYMBOL(IC_RIGHT(dic))->onStack) {
1614
1615                 if ( IC_RESULT(ic)->key != IC_RIGHT(dic)->key &&
1616                      IC_LEFT(ic)->key   != IC_RIGHT(dic)->key &&
1617                      IC_RIGHT(ic)->key  != IC_RIGHT(dic)->key)
1618                     return NULL;
1619             }           
1620
1621             break ;
1622                 
1623         }
1624
1625         /* if we find an usage then we cannot delete it */
1626         if (IC_LEFT(dic) && IC_LEFT(dic)->key == op->key)
1627             return NULL;
1628             
1629         if (IC_RIGHT(dic) && IC_RIGHT(dic)->key == op->key)
1630             return NULL;
1631
1632         if (POINTER_SET(dic) && IC_RESULT(dic)->key == op->key)
1633             return NULL;
1634     }
1635
1636     /* now make sure that the right side of dic
1637        is not defined between ic & dic */       
1638     if (dic) {
1639         iCode *sic = dic->next ;
1640
1641         for (; sic != ic ; sic = sic->next)
1642             if (IC_RESULT(sic) &&
1643                 IC_RESULT(sic)->key == IC_RIGHT(dic)->key)
1644                 return NULL;
1645     }
1646
1647     return dic;
1648         
1649         
1650 }
1651
1652 /*-----------------------------------------------------------------*/
1653 /* packRegsForSupport :- reduce some registers for support calls   */
1654 /*-----------------------------------------------------------------*/
1655 static int packRegsForSupport (iCode *ic, eBBlock *ebp)
1656 {
1657     int change = 0 ;
1658     /* for the left & right operand :- look to see if the
1659        left was assigned a true symbol in far space in that
1660        case replace them */
1661     if (IS_ITEMP(IC_LEFT(ic)) && 
1662         OP_SYMBOL(IC_LEFT(ic))->liveTo <= ic->seq) {
1663         iCode *dic = findAssignToSym(IC_LEFT(ic),ic);
1664         iCode *sic;
1665
1666         if (!dic)
1667             goto right ;
1668
1669         /* found it we need to remove it from the
1670            block */
1671         for ( sic = dic; sic != ic ; sic = sic->next )
1672             bitVectUnSetBit(sic->rlive,IC_LEFT(ic)->key);
1673
1674         IC_LEFT(ic)->operand.symOperand =
1675             IC_RIGHT(dic)->operand.symOperand;
1676         IC_LEFT(ic)->key = IC_RIGHT(dic)->operand.symOperand->key;
1677         remiCodeFromeBBlock(ebp,dic);
1678         hTabDeleteItem (&iCodehTab,dic->key,dic,DELETE_ITEM,NULL);
1679         change++;      
1680     }
1681     
1682     /* do the same for the right operand */
1683  right:    
1684     if (!change && 
1685         IS_ITEMP(IC_RIGHT(ic)) &&
1686         OP_SYMBOL(IC_RIGHT(ic))->liveTo <= ic->seq) {
1687         iCode *dic = findAssignToSym(IC_RIGHT(ic),ic);
1688         iCode *sic;
1689         
1690         if (!dic)
1691             return change ;
1692
1693         /* if this is a subtraction & the result
1694            is a true symbol in far space then don't pack */
1695         if (ic->op == '-' && IS_TRUE_SYMOP(IC_RESULT(dic))) {
1696             link *etype =getSpec(operandType(IC_RESULT(dic)));
1697             if (IN_FARSPACE(SPEC_OCLS(etype)))
1698                 return change ;
1699         }
1700         /* found it we need to remove it from the
1701            block */
1702         for ( sic = dic; sic != ic ; sic = sic->next )
1703             bitVectUnSetBit(sic->rlive,IC_RIGHT(ic)->key);
1704         
1705         IC_RIGHT(ic)->operand.symOperand =
1706             IC_RIGHT(dic)->operand.symOperand;
1707         IC_RIGHT(ic)->key = IC_RIGHT(dic)->operand.symOperand->key;
1708         
1709         remiCodeFromeBBlock(ebp,dic);
1710         hTabDeleteItem (&iCodehTab,dic->key,dic,DELETE_ITEM,NULL);
1711         change ++;
1712     }
1713    
1714     return change ;
1715 }
1716
1717 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
1718
1719
1720 /*-----------------------------------------------------------------*/
1721 /* packRegsForOneuse : - will reduce some registers for single Use */ 
1722 /*-----------------------------------------------------------------*/
1723 static iCode *packRegsForOneuse (iCode *ic, operand *op , eBBlock *ebp)
1724 {
1725     bitVect *uses ;
1726     iCode *dic, *sic;
1727
1728     /* if returning a literal then do nothing */
1729     if (!IS_SYMOP(op))
1730         return NULL;
1731     
1732     /* only upto 2 bytes since we cannot predict
1733        the usage of b, & acc */
1734     if (getSize(operandType(op)) >  (fReturnSize_390 - 2) &&
1735         ic->op != RETURN             &&
1736         ic->op != SEND               &&
1737         !POINTER_SET(ic)             &&
1738         !POINTER_GET(ic))
1739         return NULL;
1740
1741     /* this routine will mark the a symbol as used in one 
1742        instruction use only && if the defintion is local 
1743        (ie. within the basic block) && has only one definition &&
1744        that definiion is either a return value from a 
1745        function or does not contain any variables in
1746        far space */
1747     uses = bitVectCopy(OP_USES(op));
1748     bitVectUnSetBit(uses,ic->key); /* take away this iCode */
1749     if (!bitVectIsZero(uses)) /* has other uses */
1750         return NULL ;
1751     
1752     /* if it has only one defintion */
1753     if (bitVectnBitsOn(OP_DEFS(op)) > 1)
1754         return NULL ; /* has more than one definition */
1755
1756     /* get the that definition */
1757     if (!(dic = 
1758           hTabItemWithKey(iCodehTab,
1759                           bitVectFirstBit(OP_DEFS(op)))))
1760         return NULL ;
1761
1762     /* found the definition now check if it is local */
1763     if (dic->seq < ebp->fSeq ||
1764         dic->seq > ebp->lSeq)
1765         return NULL ; /* non-local */
1766
1767     /* now check if it is the return from
1768        a function call */
1769     if (dic->op == CALL || dic->op == PCALL ) {
1770         if (ic->op != SEND && ic->op != RETURN) {
1771             OP_SYMBOL(op)->ruonly = 1;
1772             return dic;
1773         }
1774         dic = dic->next ;
1775     }
1776         
1777     
1778     /* otherwise check that the definition does
1779        not contain any symbols in far space */
1780     if (isOperandInFarSpace(IC_LEFT(dic))  ||
1781         isOperandInFarSpace(IC_RIGHT(dic)) ||
1782         IS_OP_RUONLY(IC_LEFT(ic))          ||
1783         IS_OP_RUONLY(IC_RIGHT(ic)) )        {
1784         return NULL;
1785     }
1786     
1787     /* if pointer set then make sure the pointer
1788        is one byte */
1789     if (POINTER_SET(dic) && 
1790         !IS_DATA_PTR(aggrToPtr(operandType(IC_RESULT(dic)),FALSE)))
1791         return NULL ;
1792
1793     if (POINTER_GET(dic) && 
1794         !IS_DATA_PTR(aggrToPtr(operandType(IC_LEFT(dic)),FALSE)))
1795         return NULL ;
1796     
1797     sic = dic;
1798
1799     /* also make sure the intervenening instructions
1800        don't have any thing in far space */
1801     for (dic = dic->next ; dic && dic != ic ; dic = dic->next) {
1802                 
1803         /* if there is an intervening function call then no */
1804         if (dic->op == CALL || dic->op == PCALL)
1805                 return NULL;
1806         /* if pointer set then make sure the pointer
1807            is one byte */
1808         if (POINTER_SET(dic) && 
1809             !IS_DATA_PTR(aggrToPtr(operandType(IC_RESULT(dic)),FALSE)))
1810             return NULL ;
1811         
1812         if (POINTER_GET(dic) && 
1813             !IS_DATA_PTR(aggrToPtr(operandType(IC_LEFT(dic)),FALSE)))
1814             return NULL ;
1815
1816         /* if address of & the result is remat the okay */
1817         if (dic->op == ADDRESS_OF &&
1818             OP_SYMBOL(IC_RESULT(dic))->remat)
1819             continue ;
1820            
1821         /* if operand has size of three or more & this
1822            operation is a '*','/' or '%' then 'b' may
1823            cause a problem */
1824         if (( dic->op == '%' || dic->op == '/' || dic->op == '*') &&
1825             getSize(operandType(op)) >= 3)
1826                 return NULL;
1827
1828         /* if left or right or result is in far space */
1829         if (isOperandInFarSpace(IC_LEFT(dic))   ||
1830             isOperandInFarSpace(IC_RIGHT(dic))  ||
1831             isOperandInFarSpace(IC_RESULT(dic)) ||
1832             IS_OP_RUONLY(IC_LEFT(dic))          ||
1833             IS_OP_RUONLY(IC_RIGHT(dic))         ||
1834             IS_OP_RUONLY(IC_RESULT(dic))            ) {
1835             return NULL;
1836         }
1837     }
1838                 
1839     OP_SYMBOL(op)->ruonly = 1;
1840     return sic;
1841         
1842 }
1843
1844 /*-----------------------------------------------------------------*/
1845 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
1846 /*-----------------------------------------------------------------*/
1847 static bool isBitwiseOptimizable (iCode *ic)
1848 {
1849     link *ltype = getSpec(operandType(IC_LEFT(ic)));
1850     link *rtype = getSpec(operandType(IC_RIGHT(ic)));
1851
1852     /* bitwise operations are considered optimizable
1853        under the following conditions (Jean-Louis VERN) 
1854        
1855        x & lit
1856        bit & bit
1857        bit & x
1858        bit ^ bit
1859        bit ^ x
1860        x   ^ lit
1861        x   | lit
1862        bit | bit
1863        bit | x
1864     */    
1865     if ( IS_LITERAL(rtype) ||
1866          (IS_BITVAR(ltype) && IN_BITSPACE(SPEC_OCLS(ltype))))
1867         return TRUE ;
1868     else
1869         return FALSE ;    
1870 }
1871
1872 /*-----------------------------------------------------------------*/
1873 /* packRegsForAccUse - pack registers for acc use                  */
1874 /*-----------------------------------------------------------------*/
1875 static void packRegsForAccUse (iCode *ic)
1876 {
1877     iCode *uic;
1878     
1879     /* if + or - then it has to be one byte result */
1880     if ((ic->op == '+' || ic->op == '-')
1881         && getSize(operandType(IC_RESULT(ic))) > 1)
1882         return ;
1883     
1884     /* if shift operation make sure right side is not a literal */
1885     if (ic->op == RIGHT_OP  &&
1886         ( isOperandLiteral(IC_RIGHT(ic)) ||
1887           getSize(operandType(IC_RESULT(ic))) > 1))
1888         return ;
1889         
1890     if (ic->op == LEFT_OP &&        
1891         ( isOperandLiteral(IC_RIGHT(ic)) ||
1892           getSize(operandType(IC_RESULT(ic))) > 1))
1893         return ;
1894         
1895     if (IS_BITWISE_OP(ic) &&
1896         getSize(operandType(IC_RESULT(ic))) > 1)
1897         return ;
1898             
1899         
1900     /* has only one definition */
1901     if (bitVectnBitsOn(OP_DEFS(IC_RESULT(ic))) > 1)
1902         return ;
1903
1904     /* has only one use */
1905     if (bitVectnBitsOn(OP_USES(IC_RESULT(ic))) > 1)
1906         return ;
1907
1908     /* and the usage immediately follows this iCode */
1909     if (!(uic = hTabItemWithKey(iCodehTab,
1910                                 bitVectFirstBit(OP_USES(IC_RESULT(ic))))))
1911         return ;
1912
1913     if (ic->next != uic)
1914         return ;
1915     
1916     /* if it is a conditional branch then we definitely can */
1917     if (uic->op == IFX  ) 
1918         goto accuse;
1919
1920     if ( uic->op == JUMPTABLE )
1921         return ;
1922
1923     /* if the usage is not is an assignment
1924        or an arithmetic / bitwise / shift operation then not */
1925     if (POINTER_SET(uic) && 
1926         getSize(aggrToPtr(operandType(IC_RESULT(uic)),FALSE)) > 1)
1927         return;
1928
1929     if (uic->op != '=' && 
1930         !IS_ARITHMETIC_OP(uic) &&
1931         !IS_BITWISE_OP(uic)    &&
1932         uic->op != LEFT_OP &&
1933         uic->op != RIGHT_OP )
1934         return;
1935
1936     /* if used in ^ operation then make sure right is not a 
1937        literl */
1938     if (uic->op == '^' && isOperandLiteral(IC_RIGHT(uic)))
1939         return ;
1940
1941     /* if shift operation make sure right side is not a literal */
1942     if (uic->op == RIGHT_OP  &&
1943         ( isOperandLiteral(IC_RIGHT(uic)) ||
1944           getSize(operandType(IC_RESULT(uic))) > 1))
1945         return ;
1946
1947     if (uic->op == LEFT_OP &&        
1948         ( isOperandLiteral(IC_RIGHT(uic)) ||
1949           getSize(operandType(IC_RESULT(uic))) > 1))
1950         return ;
1951             
1952     /* make sure that the result of this icode is not on the
1953        stack, since acc is used to compute stack offset */
1954     if (IS_TRUE_SYMOP(IC_RESULT(uic)) &&
1955         OP_SYMBOL(IC_RESULT(uic))->onStack)
1956         return ;
1957
1958     /* if either one of them in far space then we cannot */
1959     if ((IS_TRUE_SYMOP(IC_LEFT(uic)) &&
1960          isOperandInFarSpace(IC_LEFT(uic))) ||
1961         (IS_TRUE_SYMOP(IC_RIGHT(uic)) &&
1962          isOperandInFarSpace(IC_RIGHT(uic))))
1963         return ;
1964
1965     /* if the usage has only one operand then we can */
1966     if (IC_LEFT(uic) == NULL ||
1967         IC_RIGHT(uic) == NULL) 
1968         goto accuse;
1969
1970     /* make sure this is on the left side if not
1971        a '+' since '+' is commutative */
1972     if (ic->op != '+' &&
1973         IC_LEFT(uic)->key != IC_RESULT(ic)->key)
1974         return;
1975
1976     /* if one of them is a literal then we can */
1977     if ((IC_LEFT(uic) && IS_OP_LITERAL(IC_LEFT(uic))) ||
1978         (IC_RIGHT(uic) && IS_OP_LITERAL(IC_RIGHT(uic)))) {
1979         OP_SYMBOL(IC_RESULT(ic))->accuse = 1;
1980         return ;
1981     }
1982
1983     /* if the other one is not on stack then we can */
1984     if (IC_LEFT(uic)->key == IC_RESULT(ic)->key &&
1985         (IS_ITEMP(IC_RIGHT(uic)) ||
1986          (IS_TRUE_SYMOP(IC_RIGHT(uic)) &&
1987           !OP_SYMBOL(IC_RIGHT(uic))->onStack))) 
1988         goto accuse;
1989     
1990     if (IC_RIGHT(uic)->key == IC_RESULT(ic)->key &&
1991         (IS_ITEMP(IC_LEFT(uic)) ||
1992          (IS_TRUE_SYMOP(IC_LEFT(uic)) &&
1993           !OP_SYMBOL(IC_LEFT(uic))->onStack))) 
1994         goto accuse ;
1995
1996     return ;
1997
1998  accuse:
1999     OP_SYMBOL(IC_RESULT(ic))->accuse = 1;
2000     
2001         
2002 }
2003
2004 /*-----------------------------------------------------------------*/
2005 /* packForPush - hueristics to reduce iCode for pushing            */
2006 /*-----------------------------------------------------------------*/
2007 static void packForPush(iCode *ic, eBBlock *ebp)
2008 {
2009     iCode *dic;
2010
2011     if (ic->op != IPUSH || !IS_ITEMP(IC_LEFT(ic)))
2012         return ;
2013
2014     /* must have only definition & one usage */
2015     if (bitVectnBitsOn(OP_DEFS(IC_LEFT(ic))) != 1 ||
2016         bitVectnBitsOn(OP_USES(IC_LEFT(ic))) != 1 )     
2017         return ;
2018     
2019     /* find the definition */
2020     if (!(dic = hTabItemWithKey(iCodehTab,
2021                                 bitVectFirstBit(OP_DEFS(IC_LEFT(ic))))))
2022         return ;
2023
2024     if (dic->op != '=' || POINTER_SET(dic))
2025         return;
2026
2027     /* we now we know that it has one & only one def & use
2028        and the that the definition is an assignment */
2029     IC_LEFT(ic) = IC_RIGHT(dic);
2030
2031     remiCodeFromeBBlock(ebp,dic);
2032     hTabDeleteItem (&iCodehTab,dic->key,dic,DELETE_ITEM,NULL);
2033 }
2034
2035 /*-----------------------------------------------------------------*/
2036 /* packRegisters - does some transformations to reduce register    */
2037 /*                   pressure                                      */
2038 /*-----------------------------------------------------------------*/
2039 static void packRegisters (eBBlock *ebp)
2040 {
2041     iCode *ic ;
2042     int change = 0 ;
2043     
2044     while (1) {
2045
2046         change = 0;
2047         
2048         /* look for assignments of the form */
2049         /* iTempNN = TRueSym (someoperation) SomeOperand */
2050         /*       ....                       */
2051         /* TrueSym := iTempNN:1             */
2052         for ( ic = ebp->sch ; ic ; ic = ic->next ) {
2053             
2054             
2055             /* find assignment of the form TrueSym := iTempNN:1 */
2056             if (ic->op == '=' && !POINTER_SET(ic))
2057                 change += packRegsForAssign(ic,ebp);
2058         }
2059
2060         if (!change)
2061             break;
2062     }
2063     
2064     for ( ic = ebp->sch ; ic ; ic = ic->next ) {
2065                 
2066         /* if this is an itemp & result of a address of a true sym 
2067            then mark this as rematerialisable   */
2068         if (ic->op == ADDRESS_OF && 
2069             IS_ITEMP(IC_RESULT(ic)) &&
2070             IS_TRUE_SYMOP(IC_LEFT(ic)) &&
2071             bitVectnBitsOn(OP_DEFS(IC_RESULT(ic))) == 1 &&
2072             !OP_SYMBOL(IC_LEFT(ic))->onStack ) {
2073
2074             OP_SYMBOL(IC_RESULT(ic))->remat = 1;
2075             OP_SYMBOL(IC_RESULT(ic))->rematiCode = ic;
2076             OP_SYMBOL(IC_RESULT(ic))->usl.spillLoc = NULL;
2077
2078         }
2079         
2080         /* if straight assignment then carry remat flag if
2081            this is the only definition */
2082         if (ic->op == '='    && 
2083             !POINTER_SET(ic) &&
2084             IS_SYMOP(IC_RIGHT(ic)) && 
2085             OP_SYMBOL(IC_RIGHT(ic))->remat &&
2086             bitVectnBitsOn(OP_SYMBOL(IC_RESULT(ic))->defs) <= 1) {
2087
2088             OP_SYMBOL(IC_RESULT(ic))->remat = 
2089                 OP_SYMBOL(IC_RIGHT(ic))->remat;
2090             OP_SYMBOL(IC_RESULT(ic))->rematiCode = 
2091                 OP_SYMBOL(IC_RIGHT(ic))->rematiCode ;
2092         }
2093
2094         /* if this is a +/- operation with a rematerizable 
2095            then mark this as rematerializable as well */
2096         if ((ic->op == '+' || ic->op == '-') &&
2097             (IS_SYMOP(IC_LEFT(ic)) && 
2098              IS_ITEMP(IC_RESULT(ic)) &&
2099              OP_SYMBOL(IC_LEFT(ic))->remat &&
2100              bitVectnBitsOn(OP_DEFS(IC_RESULT(ic))) == 1 &&
2101              IS_OP_LITERAL(IC_RIGHT(ic))) ) {
2102
2103             int i = operandLitValue(IC_RIGHT(ic));
2104             OP_SYMBOL(IC_RESULT(ic))->remat = 1;
2105             OP_SYMBOL(IC_RESULT(ic))->rematiCode = ic;
2106             OP_SYMBOL(IC_RESULT(ic))->usl.spillLoc = NULL;
2107         }
2108
2109         /* mark the pointer usages */
2110         if (POINTER_SET(ic))
2111             OP_SYMBOL(IC_RESULT(ic))->uptr = 1;
2112
2113         if (POINTER_GET(ic))
2114             OP_SYMBOL(IC_LEFT(ic))->uptr = 1;
2115         
2116         if (!SKIP_IC2(ic)) {
2117             /* if we are using a symbol on the stack
2118                then we should say ds390_ptrRegReq */
2119             if (ic->op == IFX && IS_SYMOP(IC_COND(ic)))
2120                 ds390_ptrRegReq += ((OP_SYMBOL(IC_COND(ic))->onStack ||
2121                                OP_SYMBOL(IC_COND(ic))->iaccess) ? 1 : 0);
2122             else
2123                 if (ic->op == JUMPTABLE && IS_SYMOP(IC_JTCOND(ic)))
2124                     ds390_ptrRegReq += ((OP_SYMBOL(IC_JTCOND(ic))->onStack ||
2125                                    OP_SYMBOL(IC_JTCOND(ic))->iaccess) ? 1 : 0);
2126                 else {
2127                     if (IS_SYMOP(IC_LEFT(ic)))
2128                         ds390_ptrRegReq += ((OP_SYMBOL(IC_LEFT(ic))->onStack ||
2129                                        OP_SYMBOL(IC_LEFT(ic))->iaccess) ? 1 : 0);
2130                     if (IS_SYMOP(IC_RIGHT(ic)))
2131                         ds390_ptrRegReq += ((OP_SYMBOL(IC_RIGHT(ic))->onStack ||
2132                                        OP_SYMBOL(IC_RIGHT(ic))->iaccess) ? 1 : 0);
2133                     if (IS_SYMOP(IC_RESULT(ic)))
2134                         ds390_ptrRegReq += ((OP_SYMBOL(IC_RESULT(ic))->onStack ||
2135                                        OP_SYMBOL(IC_RESULT(ic))->iaccess) ? 1 : 0);    
2136                 }
2137         }
2138
2139         /* if the condition of an if instruction
2140            is defined in the previous instruction then
2141            mark the itemp as a conditional */
2142         if ((IS_CONDITIONAL(ic) ||
2143              ( ( ic->op == BITWISEAND      ||
2144                  ic->op == '|'             ||
2145                  ic->op == '^' ) &&
2146                isBitwiseOptimizable(ic))) &&        
2147             ic->next && ic->next->op == IFX &&
2148             isOperandEqual(IC_RESULT(ic),IC_COND(ic->next)) &&
2149             OP_SYMBOL(IC_RESULT(ic))->liveTo <= ic->next->seq) {
2150             
2151             OP_SYMBOL(IC_RESULT(ic))->regType = REG_CND;            
2152             continue ;
2153         }
2154         
2155         /* reduce for support function calls */
2156         if (ic->supportRtn || ic->op == '+' || ic->op == '-' )
2157             packRegsForSupport (ic,ebp);        
2158         
2159         /* some cases the redundant moves can
2160            can be eliminated for return statements */
2161         if ((ic->op == RETURN || ic->op == SEND) &&
2162             !isOperandInFarSpace(IC_LEFT(ic))    &&
2163             !options.model)
2164             packRegsForOneuse (ic,IC_LEFT(ic),ebp);     
2165
2166         /* if pointer set & left has a size more than
2167            one and right is not in far space */
2168         if (POINTER_SET(ic)                    &&
2169             !isOperandInFarSpace(IC_RIGHT(ic)) &&
2170             !OP_SYMBOL(IC_RESULT(ic))->remat   &&
2171             !IS_OP_RUONLY(IC_RIGHT(ic))        &&
2172             getSize(aggrToPtr(operandType(IC_RESULT(ic)),FALSE)) > 1 )
2173
2174             packRegsForOneuse (ic,IC_RESULT(ic),ebp);
2175
2176         /* if pointer get */
2177         if (POINTER_GET(ic)                    &&
2178             !isOperandInFarSpace(IC_RESULT(ic))&&
2179             !OP_SYMBOL(IC_LEFT(ic))->remat     &&
2180             !IS_OP_RUONLY(IC_RESULT(ic))         &&
2181             getSize(aggrToPtr(operandType(IC_LEFT(ic)),FALSE)) > 1 )
2182
2183             packRegsForOneuse (ic,IC_LEFT(ic),ebp);
2184
2185
2186         /* if this is cast for intergral promotion then
2187            check if only use of  the definition of the 
2188            operand being casted/ if yes then replace
2189            the result of that arithmetic operation with 
2190            this result and get rid of the cast */
2191         if (ic->op == CAST) {
2192             link *fromType = operandType(IC_RIGHT(ic));
2193             link *toType = operandType(IC_LEFT(ic));
2194
2195             if (IS_INTEGRAL(fromType) && IS_INTEGRAL(toType) &&
2196                 getSize(fromType) != getSize(toType) ) {
2197
2198                 iCode *dic = packRegsForOneuse(ic,IC_RIGHT(ic),ebp);
2199                 if (dic) {
2200                     if (IS_ARITHMETIC_OP(dic)) {
2201                         IC_RESULT(dic) = IC_RESULT(ic);
2202                         remiCodeFromeBBlock(ebp,ic);
2203                         hTabDeleteItem (&iCodehTab,ic->key,ic,DELETE_ITEM,NULL);
2204                         OP_DEFS(IC_RESULT(dic)) = bitVectSetBit(OP_DEFS(IC_RESULT(dic)),dic->key);
2205                         ic = ic->prev;
2206                     } else
2207                         OP_SYMBOL(IC_RIGHT(ic))->ruonly =  0;
2208                 }               
2209             } else {
2210                 
2211                 /* if the type from and type to are the same
2212                    then if this is the only use then packit */
2213                 if (checkType(operandType(IC_RIGHT(ic)),
2214                               operandType(IC_LEFT(ic))) == 1) {
2215                     iCode *dic = packRegsForOneuse (ic,IC_RIGHT(ic),ebp);
2216                     if (dic) {
2217                         IC_RESULT(dic) = IC_RESULT(ic);
2218                         remiCodeFromeBBlock(ebp,ic);
2219                         hTabDeleteItem (&iCodehTab,ic->key,ic,DELETE_ITEM,NULL);
2220                         OP_DEFS(IC_RESULT(dic)) = bitVectSetBit(OP_DEFS(IC_RESULT(dic)),dic->key);
2221                         ic = ic->prev;
2222                     }
2223                 }
2224             }
2225         }
2226         
2227         /* pack for PUSH 
2228            iTempNN := (some variable in farspace) V1
2229            push iTempNN ;
2230            -------------
2231            push V1
2232         */
2233         if (ic->op == IPUSH ) {
2234             packForPush(ic,ebp);
2235         }
2236           
2237         
2238         /* pack registers for accumulator use, when the
2239            result of an arithmetic or bit wise operation
2240            has only one use, that use is immediately following
2241            the defintion and the using iCode has only one
2242            operand or has two operands but one is literal &
2243            the result of that operation is not on stack then
2244            we can leave the result of this operation in acc:b
2245            combination */
2246         if ((IS_ARITHMETIC_OP(ic) 
2247              
2248              || IS_BITWISE_OP(ic) 
2249              
2250              || ic->op == LEFT_OP || ic->op == RIGHT_OP
2251              
2252              ) &&
2253             IS_ITEMP(IC_RESULT(ic)) &&
2254             getSize(operandType(IC_RESULT(ic))) <= 2)
2255
2256             packRegsForAccUse (ic);
2257
2258     }
2259 }
2260   
2261 /*-----------------------------------------------------------------*/
2262 /* assignRegisters - assigns registers to each live range as need  */
2263 /*-----------------------------------------------------------------*/
2264 void ds390_assignRegisters (eBBlock **ebbs, int count)
2265 {
2266     iCode *ic;
2267     int i ;
2268
2269     setToNull((void *)&_G.funcrUsed);
2270     ds390_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
2271     /* if not register extentions then reduce number
2272        of registers */
2273     if (options.regExtend)
2274         ds390_nRegs = 13;
2275     else
2276         ds390_nRegs = 8;
2277
2278     /* change assignments this will remove some
2279        live ranges reducing some register pressure */
2280     for (i = 0 ; i < count ;i++ )
2281         packRegisters (ebbs[i]);
2282     
2283     if (options.dump_pack)
2284         dumpEbbsToFileExt(".dumppack",ebbs,count);
2285
2286     /* first determine for each live range the number of 
2287        registers & the type of registers required for each */
2288     regTypeNum ();
2289     
2290     /* and serially allocate registers */ 
2291     serialRegAssign(ebbs,count);
2292
2293     /* if stack was extended then tell the user */
2294     if (_G.stackExtend) {
2295 /*      werror(W_TOOMANY_SPILS,"stack", */
2296 /*             _G.stackExtend,currFunc->name,""); */
2297         _G.stackExtend = 0 ;
2298     }
2299
2300     if (_G.dataExtend) {
2301 /*      werror(W_TOOMANY_SPILS,"data space", */
2302 /*             _G.dataExtend,currFunc->name,""); */
2303         _G.dataExtend = 0 ;
2304     }  
2305
2306     /* after that create the register mask
2307        for each of the instruction */
2308     createRegMask (ebbs,count);
2309
2310     /* redo that offsets for stacked automatic variables */
2311     redoStackOffsets ();
2312
2313     if (options.dump_rassgn)
2314         dumpEbbsToFileExt(".dumprassgn",ebbs,count);
2315
2316     /* do the overlaysegment stuff SDCCmem.c */
2317     doOverlays(ebbs,count);
2318
2319     /* now get back the chain */
2320     ic = iCodeLabelOptimize(iCodeFromeBBlock (ebbs,count));
2321
2322
2323     gen390Code(ic);
2324
2325     /* free up any _G.stackSpil locations allocated */   
2326     applyToSet(_G.stackSpil,deallocStackSpil);
2327     _G.slocNum = 0;
2328     setToNull((void **)&_G.stackSpil);
2329     setToNull((void **)&_G.spiltSet);
2330     /* mark all registers as free */
2331     freeAllRegs();
2332
2333     return ;
2334 }