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