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