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