Fixed bug #483124
[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                             /* if this is local to this block then we might find a block spil */
1223                             if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
1224                                 spillThis (sym);
1225                                 continue;
1226                             }
1227                         }
1228                     }
1229                 }
1230
1231               /* if we need ptr regs for the right side
1232                  then mark it */
1233               if (POINTER_GET (ic) && IS_SYMOP (IC_LEFT (ic))
1234                   && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
1235                   <= (unsigned) PTRSIZE)
1236                 {
1237                   ds390_ptrRegReq++;
1238                   ptrRegSet = 1;
1239                 }
1240               /* else we assign registers to it */
1241               _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1242               _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key);
1243
1244               for (j = 0; j < sym->nRegs; j++)
1245                 {
1246                   if (sym->regType == REG_PTR)
1247                     sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
1248                   else
1249                     sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
1250
1251                   /* if the allocation falied which means
1252                      this was spilt then break */
1253                   if (!sym->regs[j])
1254                     break;
1255                 }
1256               /* if it shares registers with operands make sure
1257                  that they are in the same position */
1258               if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
1259                   OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
1260                 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1261                               OP_SYMBOL (IC_LEFT (ic)));
1262               /* do the same for the right operand */
1263               if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
1264                   OP_SYMBOL (IC_RIGHT (ic))->nRegs)
1265                 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1266                               OP_SYMBOL (IC_RIGHT (ic)));
1267
1268               if (ptrRegSet)
1269                 {
1270                   ds390_ptrRegReq--;
1271                   ptrRegSet = 0;
1272                 }
1273
1274             }
1275         }
1276     }
1277 }
1278
1279 /*-----------------------------------------------------------------*/
1280 /* fillGaps - Try to fill in the Gaps left by Pass1                */
1281 /*-----------------------------------------------------------------*/
1282 static void fillGaps()
1283 {
1284     symbol *sym =NULL;
1285     int key =0;    
1286     
1287     if (getenv("DISABLE_FILL_GAPS")) return;
1288     /* look for livernages that was spilt by the allocator */
1289     for (sym = hTabFirstItem(liveRanges,&key) ; sym ; 
1290          sym = hTabNextItem(liveRanges,&key)) {
1291
1292         int i;
1293         int pdone = 0;
1294
1295         if (!sym->spillA || !sym->clashes || sym->remat) continue ;
1296         
1297         /* find the liveRanges this one clashes with, that are
1298            still assigned to registers & mark the registers as used*/
1299         for ( i = 0 ; i < sym->clashes->size ; i ++) {
1300             int k;
1301             symbol *clr;
1302
1303             if (bitVectBitValue(sym->clashes,i) == 0 ||    /* those that clash with this */
1304                 bitVectBitValue(_G.totRegAssigned,i) == 0) /* and are still assigned to registers */
1305                 continue ;
1306
1307             assert (clr = hTabItemWithKey(liveRanges,i));
1308          
1309             /* mark these registers as used */
1310             for (k = 0 ; k < clr->nRegs ; k++ ) 
1311                 useReg(clr->regs[k]);
1312         }
1313
1314         if (willCauseSpill(sym->nRegs,sym->regType)) {
1315             /* NOPE :( clear all registers & and continue */
1316             freeAllRegs();
1317             continue ;
1318         }
1319
1320         /* THERE IS HOPE !!!! */
1321         for (i=0; i < sym->nRegs ; i++ ) {
1322             if (sym->regType == REG_PTR)
1323                 sym->regs[i] = getRegPtrNoSpil ();
1324             else
1325                 sym->regs[i] = getRegGprNoSpil ();                
1326         }
1327
1328         /* for all its definitions check if the registers
1329            allocated needs positioning NOTE: we can position
1330            only ONCE if more than One positioning required 
1331            then give up */
1332         sym->isspilt = 0;
1333         for (i = 0 ; i < sym->defs->size ; i++ ) {
1334             if (bitVectBitValue(sym->defs,i)) {
1335                 iCode *ic;
1336                 if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
1337                 if (SKIP_IC(ic)) continue;
1338                 assert(isSymbolEqual(sym,OP_SYMBOL(IC_RESULT(ic)))); /* just making sure */
1339                 /* if left is assigned to registers */
1340                 if (IS_SYMOP(IC_LEFT(ic)) && 
1341                     bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_LEFT(ic))->key)) {
1342                     pdone += positionRegs(sym,OP_SYMBOL(IC_LEFT(ic)));
1343                 }
1344                 if (IS_SYMOP(IC_RIGHT(ic)) && 
1345                     bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RIGHT(ic))->key)) {
1346                     pdone += positionRegs(sym,OP_SYMBOL(IC_RIGHT(ic)));
1347                 }
1348                 if (pdone > 1) break;
1349             }
1350         }
1351         /* had to position more than once GIVE UP */
1352         if (pdone > 1) {
1353             /* UNDO all the changes we made to try this */
1354             sym->isspilt = 0;
1355             for (i=0; i < sym->nRegs ; i++ ) {
1356                 sym->regs[i] = NULL;
1357             }
1358             freeAllRegs();
1359             printf("Fill Gap gave up due to positioning for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN");
1360             continue ;      
1361         }
1362         printf("FILLED GAP for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN");
1363         _G.totRegAssigned = bitVectSetBit(_G.totRegAssigned,sym->key);
1364         sym->isspilt = sym->spillA = 0 ;
1365         sym->usl.spillLoc->allocreq--;
1366         freeAllRegs();
1367     }
1368 }
1369
1370 /*-----------------------------------------------------------------*/
1371 /* rUmaskForOp :- returns register mask for an operand             */
1372 /*-----------------------------------------------------------------*/
1373 static bitVect *
1374 rUmaskForOp (operand * op)
1375 {
1376   bitVect *rumask;
1377   symbol *sym;
1378   int j;
1379
1380   /* only temporaries are assigned registers */
1381   if (!IS_ITEMP (op))
1382     return NULL;
1383
1384   sym = OP_SYMBOL (op);
1385
1386   /* if spilt or no registers assigned to it
1387      then nothing */
1388   if (sym->isspilt || !sym->nRegs)
1389     return NULL;
1390
1391   rumask = newBitVect (ds390_nRegs);
1392
1393   for (j = 0; j < sym->nRegs; j++)
1394     {
1395       rumask = bitVectSetBit (rumask,
1396                               sym->regs[j]->rIdx);
1397     }
1398
1399   return rumask;
1400 }
1401
1402 /*-----------------------------------------------------------------*/
1403 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
1404 /*-----------------------------------------------------------------*/
1405 static bitVect *
1406 regsUsedIniCode (iCode * ic)
1407 {
1408   bitVect *rmask = newBitVect (ds390_nRegs);
1409
1410   /* do the special cases first */
1411   if (ic->op == IFX)
1412     {
1413       rmask = bitVectUnion (rmask,
1414                             rUmaskForOp (IC_COND (ic)));
1415       goto ret;
1416     }
1417
1418   /* for the jumptable */
1419   if (ic->op == JUMPTABLE)
1420     {
1421       rmask = bitVectUnion (rmask,
1422                             rUmaskForOp (IC_JTCOND (ic)));
1423
1424       goto ret;
1425     }
1426
1427   /* of all other cases */
1428   if (IC_LEFT (ic))
1429     rmask = bitVectUnion (rmask,
1430                           rUmaskForOp (IC_LEFT (ic)));
1431
1432
1433   if (IC_RIGHT (ic))
1434     rmask = bitVectUnion (rmask,
1435                           rUmaskForOp (IC_RIGHT (ic)));
1436
1437   if (IC_RESULT (ic))
1438     rmask = bitVectUnion (rmask,
1439                           rUmaskForOp (IC_RESULT (ic)));
1440
1441 ret:
1442   return rmask;
1443 }
1444
1445 /*-----------------------------------------------------------------*/
1446 /* createRegMask - for each instruction will determine the regsUsed */
1447 /*-----------------------------------------------------------------*/
1448 static void
1449 createRegMask (eBBlock ** ebbs, int count)
1450 {
1451   int i;
1452
1453   /* for all blocks */
1454   for (i = 0; i < count; i++)
1455     {
1456       iCode *ic;
1457
1458       if (ebbs[i]->noPath &&
1459           (ebbs[i]->entryLabel != entryLabel &&
1460            ebbs[i]->entryLabel != returnLabel))
1461         continue;
1462
1463       /* for all instructions */
1464       for (ic = ebbs[i]->sch; ic; ic = ic->next)
1465         {
1466
1467           int j;
1468
1469           if (SKIP_IC2 (ic) || !ic->rlive)
1470             continue;
1471
1472           /* first mark the registers used in this
1473              instruction */
1474           ic->rUsed = regsUsedIniCode (ic);
1475           _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
1476
1477           /* now create the register mask for those 
1478              registers that are in use : this is a
1479              super set of ic->rUsed */
1480           ic->rMask = newBitVect (ds390_nRegs + 1);
1481
1482           /* for all live Ranges alive at this point */
1483           for (j = 1; j < ic->rlive->size; j++)
1484             {
1485               symbol *sym;
1486               int k;
1487
1488               /* if not alive then continue */
1489               if (!bitVectBitValue (ic->rlive, j))
1490                 continue;
1491
1492               /* find the live range we are interested in */
1493               if (!(sym = hTabItemWithKey (liveRanges, j)))
1494                 {
1495                   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1496                           "createRegMask cannot find live range");
1497                   exit (0);
1498                 }
1499               
1500               /* special case for ruonly */
1501               if (sym->ruonly && sym->liveFrom != sym->liveTo) {
1502                   int size = getSize(sym->type);
1503                   int j = DPL_IDX;
1504                   for (k = 0 ; k < size; k++ )
1505                       ic->rMask = bitVectSetBit (ic->rMask, j++);
1506                   continue ;
1507               }
1508               /* if no register assigned to it */
1509               if (!sym->nRegs || sym->isspilt)
1510                 continue;
1511
1512               /* for all the registers allocated to it */
1513               for (k = 0; k < sym->nRegs; k++)
1514                 if (sym->regs[k])
1515                   ic->rMask =
1516                     bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
1517             }
1518         }
1519     }
1520 }
1521
1522 /*-----------------------------------------------------------------*/
1523 /* rematStr - returns the rematerialized string for a remat var    */
1524 /*-----------------------------------------------------------------*/
1525 static char *
1526 rematStr (symbol * sym)
1527 {
1528   char *s = buffer;
1529   iCode *ic = sym->rematiCode;
1530
1531   while (1)
1532     {
1533
1534       /* if plus or minus print the right hand side */
1535       if (ic->op == '+' || ic->op == '-')
1536         {
1537           sprintf (s, "0x%04x %c ", (int) operandLitValue (IC_RIGHT (ic)),
1538                    ic->op);
1539           s += strlen (s);
1540           ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1541           continue;
1542         }
1543       /* cast then continue */
1544       if (IS_CAST_ICODE(ic)) {
1545           ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
1546           continue;
1547       }
1548       /* we reached the end */
1549       sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
1550       break;
1551     }
1552
1553   return buffer;
1554 }
1555
1556 /*-----------------------------------------------------------------*/
1557 /* regTypeNum - computes the type & number of registers required   */
1558 /*-----------------------------------------------------------------*/
1559 static void
1560 regTypeNum ()
1561 {
1562   symbol *sym;
1563   int k;
1564   iCode *ic;
1565
1566   /* for each live range do */
1567   for (sym = hTabFirstItem (liveRanges, &k); sym;
1568        sym = hTabNextItem (liveRanges, &k))
1569     {
1570
1571       /* if used zero times then no registers needed */
1572       if ((sym->liveTo - sym->liveFrom) == 0)
1573         continue;
1574
1575
1576       /* if the live range is a temporary */
1577       if (sym->isitmp)
1578         {
1579
1580           /* if the type is marked as a conditional */
1581           if (sym->regType == REG_CND)
1582             continue;
1583
1584           /* if used in return only then we don't 
1585              need registers */
1586           if (sym->ruonly || sym->accuse)
1587             {
1588               if (IS_AGGREGATE (sym->type) || sym->isptr)
1589                 sym->type = aggrToPtr (sym->type, FALSE);
1590               continue;
1591             }
1592
1593           /* if the symbol has only one definition &
1594              that definition is a get_pointer and the
1595              pointer we are getting is rematerializable and
1596              in "data" space */
1597
1598           if (bitVectnBitsOn (sym->defs) == 1 &&
1599               (ic = hTabItemWithKey (iCodehTab,
1600                                      bitVectFirstBit (sym->defs))) &&
1601               POINTER_GET (ic) &&
1602               !sym->noSpilLoc &&
1603               !IS_BITVAR (sym->etype))
1604             {
1605
1606
1607               /* if remat in data space */
1608               if (OP_SYMBOL (IC_LEFT (ic))->remat &&
1609                   !IS_CAST_ICODE(OP_SYMBOL (IC_LEFT (ic))->rematiCode) &&
1610                   DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER)
1611                 {
1612
1613                   /* create a psuedo symbol & force a spil */
1614                   symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
1615                   psym->type = sym->type;
1616                   psym->etype = sym->etype;
1617                   strcpy (psym->rname, psym->name);
1618                   sym->isspilt = 1;
1619                   sym->usl.spillLoc = psym;
1620                   continue;
1621                 }
1622
1623               /* if in data space or idata space then try to
1624                  allocate pointer register */
1625
1626             }
1627
1628           /* if not then we require registers */
1629           sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
1630                         getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1631                         getSize (sym->type));
1632
1633           if (sym->nRegs > 4)
1634             {
1635               fprintf (stderr, "allocated more than 4 or 0 registers for type ");
1636               printTypeChain (sym->type, stderr);
1637               fprintf (stderr, "\n");
1638             }
1639
1640           /* determine the type of register required */
1641           if (sym->nRegs == 1 &&
1642               IS_PTR (sym->type) &&
1643               sym->uptr)
1644             sym->regType = REG_PTR;
1645           else
1646             sym->regType = REG_GPR;
1647
1648         }
1649       else
1650         /* for the first run we don't provide */
1651         /* registers for true symbols we will */
1652         /* see how things go                  */
1653         sym->nRegs = 0;
1654     }
1655
1656 }
1657
1658 /*-----------------------------------------------------------------*/
1659 /* freeAllRegs - mark all registers as free                        */
1660 /*-----------------------------------------------------------------*/
1661 static void
1662 freeAllRegs ()
1663 {
1664   int i;
1665
1666   for (i = 0; i < ds390_nRegs; i++)
1667     regs390[i].isFree = 1;
1668 }
1669
1670 /*-----------------------------------------------------------------*/
1671 /* deallocStackSpil - this will set the stack pointer back         */
1672 /*-----------------------------------------------------------------*/
1673 static
1674 DEFSETFUNC (deallocStackSpil)
1675 {
1676   symbol *sym = item;
1677
1678   deallocLocal (sym);
1679   return 0;
1680 }
1681
1682 /*-----------------------------------------------------------------*/
1683 /* farSpacePackable - returns the packable icode for far variables */
1684 /*-----------------------------------------------------------------*/
1685 static iCode *
1686 farSpacePackable (iCode * ic)
1687 {
1688   iCode *dic;
1689
1690   /* go thru till we find a definition for the
1691      symbol on the right */
1692   for (dic = ic->prev; dic; dic = dic->prev)
1693     {
1694
1695       /* if the definition is a call then no */
1696       if ((dic->op == CALL || dic->op == PCALL) &&
1697           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1698         {
1699           return NULL;
1700         }
1701
1702       /* if shift by unknown amount then not */
1703       if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
1704           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1705         return NULL;
1706
1707       /* if pointer get and size > 1 */
1708       if (POINTER_GET (dic) &&
1709           getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
1710         return NULL;
1711
1712       if (POINTER_SET (dic) &&
1713           getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
1714         return NULL;
1715
1716       /* if any three is a true symbol in far space */
1717       if (IC_RESULT (dic) &&
1718           IS_TRUE_SYMOP (IC_RESULT (dic)) &&
1719           isOperandInFarSpace (IC_RESULT (dic)))
1720         return NULL;
1721
1722       if (IC_RIGHT (dic) &&
1723           IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
1724           isOperandInFarSpace (IC_RIGHT (dic)) &&
1725           !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
1726         return NULL;
1727
1728       if (IC_LEFT (dic) &&
1729           IS_TRUE_SYMOP (IC_LEFT (dic)) &&
1730           isOperandInFarSpace (IC_LEFT (dic)) &&
1731           !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
1732         return NULL;
1733
1734       if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
1735         {
1736           if ((dic->op == LEFT_OP ||
1737                dic->op == RIGHT_OP ||
1738                dic->op == '-') &&
1739               IS_OP_LITERAL (IC_RIGHT (dic)))
1740             return NULL;
1741           else
1742             return dic;
1743         }
1744     }
1745
1746   return NULL;
1747 }
1748
1749 /*-----------------------------------------------------------------*/
1750 /* packRegsForAssign - register reduction for assignment           */
1751 /*-----------------------------------------------------------------*/
1752 static int
1753 packRegsForAssign (iCode * ic, eBBlock * ebp)
1754 {
1755   iCode *dic, *sic;
1756
1757   if (!IS_ITEMP (IC_RIGHT (ic)) ||
1758       OP_SYMBOL (IC_RIGHT (ic))->isind ||
1759       OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
1760     {
1761       return 0;
1762     }
1763
1764   /* if the true symbol is defined in far space or on stack
1765      then we should not since this will increase register pressure */
1766 #if 0
1767   if (isOperandInFarSpace (IC_RESULT (ic)))
1768     {
1769       if ((dic = farSpacePackable (ic)))
1770         goto pack;
1771       else
1772         return 0;
1773     }
1774 #else
1775   if (isOperandInFarSpace(IC_RESULT(ic)) && !farSpacePackable(ic)) {
1776     return 0;
1777   }
1778 #endif
1779
1780   /* find the definition of iTempNN scanning backwards if we find a 
1781      a use of the true symbol in before we find the definition then 
1782      we cannot */
1783   for (dic = ic->prev; dic; dic = dic->prev)
1784     {
1785       /* if there is a function call then don't pack it */
1786       if ((dic->op == CALL || dic->op == PCALL))
1787         {
1788           dic = NULL;
1789           break;
1790         }
1791
1792       if (SKIP_IC2 (dic))
1793         continue;
1794
1795       if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
1796           IS_OP_VOLATILE (IC_RESULT (dic)))
1797         {
1798           dic = NULL;
1799           break;
1800         }
1801
1802       if (IS_SYMOP (IC_RESULT (dic)) &&
1803           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1804         {
1805           if (POINTER_SET (dic))
1806             dic = NULL;
1807
1808           break;
1809         }
1810
1811       if (IS_SYMOP (IC_RIGHT (dic)) &&
1812           (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
1813            IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
1814         {
1815           dic = NULL;
1816           break;
1817         }
1818
1819       if (IS_SYMOP (IC_LEFT (dic)) &&
1820           (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
1821            IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
1822         {
1823           dic = NULL;
1824           break;
1825         }
1826
1827       if (POINTER_SET (dic) &&
1828           IC_RESULT (dic)->key == IC_RESULT (ic)->key)
1829         {
1830           dic = NULL;
1831           break;
1832         }
1833     }
1834
1835   if (!dic)
1836     return 0;                   /* did not find */
1837
1838   /* if the result is on stack or iaccess then it must be
1839      the same atleast one of the operands */
1840   if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
1841       OP_SYMBOL (IC_RESULT (ic))->iaccess)
1842     {
1843
1844       /* the operation has only one symbol
1845          operator then we can pack */
1846       if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
1847           (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
1848         goto pack;
1849
1850       if (!((IC_LEFT (dic) &&
1851              IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
1852             (IC_RIGHT (dic) &&
1853              IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
1854         return 0;
1855     }
1856 pack:
1857   /* found the definition */
1858   /* replace the result with the result of */
1859   /* this assignment and remove this assignment */
1860   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1861   IC_RESULT (dic) = IC_RESULT (ic);
1862
1863   if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
1864     {
1865       OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
1866     }
1867   /* delete from liverange table also 
1868      delete from all the points inbetween and the new
1869      one */
1870   for (sic = dic; sic != ic; sic = sic->next)
1871     {
1872       bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
1873       if (IS_ITEMP (IC_RESULT (dic)))
1874         bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
1875     }
1876
1877   remiCodeFromeBBlock (ebp, ic);
1878   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
1879   hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
1880   OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
1881   return 1;
1882
1883 }
1884
1885 /*-----------------------------------------------------------------*/
1886 /* findAssignToSym : scanning backwards looks for first assig found */
1887 /*-----------------------------------------------------------------*/
1888 static iCode *
1889 findAssignToSym (operand * op, iCode * ic)
1890 {
1891   iCode *dic;
1892
1893   for (dic = ic->prev; dic; dic = dic->prev)
1894     {
1895
1896       /* if definition by assignment */
1897       if (dic->op == '=' &&
1898           !POINTER_SET (dic) &&
1899           IC_RESULT (dic)->key == op->key
1900 /*          &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) */
1901         )
1902         {
1903
1904           /* we are interested only if defined in far space */
1905           /* or in stack space in case of + & - */
1906
1907           /* if assigned to a non-symbol then return
1908              FALSE */
1909           if (!IS_SYMOP (IC_RIGHT (dic)))
1910             return NULL;
1911
1912           /* if the symbol is in far space then
1913              we should not */
1914           if (isOperandInFarSpace (IC_RIGHT (dic)))
1915             return NULL;
1916
1917           /* for + & - operations make sure that
1918              if it is on the stack it is the same
1919              as one of the three operands */
1920           if ((ic->op == '+' || ic->op == '-') &&
1921               OP_SYMBOL (IC_RIGHT (dic))->onStack)
1922             {
1923
1924               if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
1925                   IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
1926                   IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
1927                 return NULL;
1928             }
1929
1930           break;
1931
1932         }
1933
1934       /* if we find an usage then we cannot delete it */
1935       if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
1936         return NULL;
1937
1938       if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
1939         return NULL;
1940
1941       if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
1942         return NULL;
1943     }
1944
1945   /* now make sure that the right side of dic
1946      is not defined between ic & dic */
1947   if (dic)
1948     {
1949       iCode *sic = dic->next;
1950
1951       for (; sic != ic; sic = sic->next)
1952         if (IC_RESULT (sic) &&
1953             IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
1954           return NULL;
1955     }
1956
1957   return dic;
1958
1959
1960 }
1961
1962 /*-----------------------------------------------------------------*/
1963 /* packRegsForSupport :- reduce some registers for support calls   */
1964 /*-----------------------------------------------------------------*/
1965 static int
1966 packRegsForSupport (iCode * ic, eBBlock * ebp)
1967 {
1968   int change = 0;
1969   /* for the left & right operand :- look to see if the
1970      left was assigned a true symbol in far space in that
1971      case replace them */
1972   if (IS_ITEMP (IC_LEFT (ic)) &&
1973       OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
1974     {
1975       iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
1976       iCode *sic;
1977
1978       if (!dic)
1979         goto right;
1980
1981       /* found it we need to remove it from the
1982          block */
1983       for (sic = dic; sic != ic; sic = sic->next)
1984         bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
1985
1986       IC_LEFT (ic)->operand.symOperand =
1987         IC_RIGHT (dic)->operand.symOperand;
1988       IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
1989       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1990       remiCodeFromeBBlock (ebp, dic);
1991       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1992       change++;
1993     }
1994
1995   /* do the same for the right operand */
1996 right:
1997   if (!change &&
1998       IS_ITEMP (IC_RIGHT (ic)) &&
1999       OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2000     {
2001       iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2002       iCode *sic;
2003
2004       if (!dic)
2005         return change;
2006
2007       /* if this is a subtraction & the result
2008          is a true symbol in far space then don't pack */
2009       if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
2010         {
2011           sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
2012           if (IN_FARSPACE (SPEC_OCLS (etype)))
2013             return change;
2014         }
2015       /* found it we need to remove it from the
2016          block */
2017       for (sic = dic; sic != ic; sic = sic->next)
2018         bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
2019
2020       IC_RIGHT (ic)->operand.symOperand =
2021         IC_RIGHT (dic)->operand.symOperand;
2022       IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2023
2024       remiCodeFromeBBlock (ebp, dic);
2025       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2026       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2027       change++;
2028     }
2029
2030   return change;
2031 }
2032
2033 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
2034
2035
2036 /*-----------------------------------------------------------------*/
2037 /* packRegsDPTRuse : - will reduce some registers for single Use */
2038 /*-----------------------------------------------------------------*/
2039 static iCode *
2040 packRegsDPTRuse (iCode * lic, operand * op, eBBlock * ebp)
2041 {
2042     /* go thru entire liveRange of this variable & check for
2043        other possible usage of DPTR , if we don't find it the
2044        assign this to DPTR (ruonly)
2045     */
2046     int i, key;
2047     symbol *sym;
2048     iCode *ic, *dic;
2049     sym_link *type, *etype;
2050     
2051     if (!IS_SYMOP(op) || !IS_ITEMP(op)) return NULL;
2052     if (OP_SYMBOL(op)->remat || OP_SYMBOL(op)->ruonly) return NULL; 
2053
2054     /* first check if any overlapping liverange has already been
2055        assigned to DPTR */
2056     if (OP_SYMBOL(op)->clashes) {
2057         for (i = 0 ; i < OP_SYMBOL(op)->clashes->size ; i++ ) {
2058             if (bitVectBitValue(OP_SYMBOL(op)->clashes,i)) {
2059                 sym = hTabItemWithKey(liveRanges,i);
2060                 if (sym->ruonly) return NULL ;
2061             }
2062         }
2063     }
2064
2065     /* no then go thru this guys live range */
2066     dic = ic = hTabFirstItemWK(iCodeSeqhTab,OP_SYMBOL(op)->liveFrom);
2067     for (; ic && ic->seq <= OP_SYMBOL(op)->liveTo;
2068          ic = hTabNextItem(iCodeSeqhTab,&key)) {
2069
2070         if (SKIP_IC3(ic)) continue;
2071
2072         /* if PCALL cannot be sure give up */
2073         if (ic->op == PCALL) return NULL;
2074
2075         /* if CALL then make sure it is VOID || return value not used */
2076         if (ic->op == CALL) {
2077             if (OP_SYMBOL(IC_RESULT(ic))->liveTo == 
2078                 OP_SYMBOL(IC_RESULT(ic))->liveFrom) continue ;
2079             etype = getSpec(type = operandType(IC_RESULT(ic)));
2080             if (getSize(type) == 0) continue ;
2081             return NULL ;
2082         }
2083
2084         /* special case of add with a [remat] */
2085         if (ic->op == '+' && 
2086             OP_SYMBOL(IC_LEFT(ic))->remat &&
2087             !isOperandInFarSpace(IC_RIGHT(ic))) continue ;
2088
2089         /* special case */
2090         /* pointerGet */
2091         if (POINTER_GET(ic) && isOperandEqual(IC_RESULT(ic),op) &&
2092             getSize(operandType(IC_LEFT(ic))) > 1) return NULL ;
2093
2094         if (POINTER_SET(ic) && isOperandEqual(IC_RIGHT(ic),op) &&
2095             getSize(operandType(IC_RESULT(ic))) > 1) return NULL;
2096
2097         /* general case */
2098         if (IC_RESULT(ic) && IS_SYMOP(IC_RESULT(ic)) && 
2099             !isOperandEqual(IC_RESULT(ic),op) &&
2100             (isOperandInFarSpace(IC_RESULT(ic)) || 
2101              OP_SYMBOL(IC_RESULT(ic))->ruonly   ||
2102              OP_SYMBOL(IC_RESULT(ic))->onStack)) return NULL;
2103
2104         if (IC_RIGHT(ic) && IS_SYMOP(IC_RIGHT(ic)) && 
2105             !isOperandEqual(IC_RIGHT(ic),op) &&
2106             (OP_SYMBOL(IC_RIGHT(ic))->liveTo > ic->seq || 
2107              IS_TRUE_SYMOP(IC_RIGHT(ic))               ||
2108              OP_SYMBOL(IC_RIGHT(ic))->ruonly) &&
2109             (isOperandInFarSpace(IC_RIGHT(ic)) || 
2110              OP_SYMBOL(IC_RIGHT(ic))->onStack)) return NULL;
2111
2112         if (IC_LEFT(ic) && IS_SYMOP(IC_LEFT(ic)) && 
2113             !isOperandEqual(IC_LEFT(ic),op) &&
2114             (OP_SYMBOL(IC_LEFT(ic))->liveTo > ic->seq || 
2115              IS_TRUE_SYMOP(IC_LEFT(ic))               ||
2116              OP_SYMBOL(IC_LEFT(ic))->ruonly) &&
2117             (isOperandInFarSpace(IC_LEFT(ic)) || 
2118              OP_SYMBOL(IC_LEFT(ic))->onStack)) return NULL;
2119         
2120         if (IC_LEFT(ic) && IC_RIGHT(ic) && 
2121             IS_ITEMP(IC_LEFT(ic)) && IS_ITEMP(IC_RIGHT(ic)) &&
2122             isOperandInFarSpace(IC_LEFT(ic)) && isOperandInFarSpace(IC_RIGHT(ic)))
2123             return NULL;
2124     }
2125     OP_SYMBOL(op)->ruonly = 1;
2126     return dic;
2127 }
2128
2129 /*-----------------------------------------------------------------*/
2130 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
2131 /*-----------------------------------------------------------------*/
2132 static bool
2133 isBitwiseOptimizable (iCode * ic)
2134 {
2135   sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
2136   sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
2137
2138   /* bitwise operations are considered optimizable
2139      under the following conditions (Jean-Louis VERN) 
2140
2141      x & lit
2142      bit & bit
2143      bit & x
2144      bit ^ bit
2145      bit ^ x
2146      x   ^ lit
2147      x   | lit
2148      bit | bit
2149      bit | x
2150    */
2151   if ( IS_LITERAL (rtype) ||
2152       (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
2153     return TRUE;
2154   else
2155     return FALSE;
2156 }
2157
2158 /*-----------------------------------------------------------------*/
2159 /* packRegsForAccUse - pack registers for acc use                  */
2160 /*-----------------------------------------------------------------*/
2161 static void
2162 packRegsForAccUse (iCode * ic)
2163 {
2164   iCode *uic;
2165
2166   /* if this is an aggregate, e.g. a one byte char array */
2167   if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
2168     return;
2169   }
2170
2171   /* if + or - then it has to be one byte result */
2172   if ((ic->op == '+' || ic->op == '-')
2173       && getSize (operandType (IC_RESULT (ic))) > 1)
2174     return;
2175
2176   /* if shift operation make sure right side is not a literal */
2177   if (ic->op == RIGHT_OP &&
2178       (isOperandLiteral (IC_RIGHT (ic)) ||
2179        getSize (operandType (IC_RESULT (ic))) > 1))
2180     return;
2181
2182   if (ic->op == LEFT_OP &&
2183       (isOperandLiteral (IC_RIGHT (ic)) ||
2184        getSize (operandType (IC_RESULT (ic))) > 1))
2185     return;
2186
2187   if (IS_BITWISE_OP (ic) &&
2188       getSize (operandType (IC_RESULT (ic))) > 1)
2189     return;
2190
2191
2192   /* has only one definition */
2193   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
2194     return;
2195
2196   /* has only one use */
2197   if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
2198     return;
2199
2200   /* and the usage immediately follows this iCode */
2201   if (!(uic = hTabItemWithKey (iCodehTab,
2202                                bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
2203     return;
2204
2205   if (ic->next != uic)
2206     return;
2207
2208   /* if it is a conditional branch then we definitely can */
2209   if (uic->op == IFX)
2210     goto accuse;
2211
2212   if (uic->op == JUMPTABLE)
2213     return;
2214
2215   /* if the usage is not is an assignment
2216      or an arithmetic / bitwise / shift operation then not */
2217   if (POINTER_SET (uic) &&
2218       getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
2219     return;
2220
2221   if (uic->op != '=' &&
2222       !IS_ARITHMETIC_OP (uic) &&
2223       !IS_BITWISE_OP (uic) &&
2224       uic->op != LEFT_OP &&
2225       uic->op != RIGHT_OP)
2226     return;
2227
2228   /* if used in ^ operation then make sure right is not a 
2229      literl */
2230   if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
2231     return;
2232
2233   /* if shift operation make sure right side is not a literal */
2234   if (uic->op == RIGHT_OP &&
2235       (isOperandLiteral (IC_RIGHT (uic)) ||
2236        getSize (operandType (IC_RESULT (uic))) > 1))
2237     return;
2238
2239   if (uic->op == LEFT_OP &&
2240       (isOperandLiteral (IC_RIGHT (uic)) ||
2241        getSize (operandType (IC_RESULT (uic))) > 1))
2242     return;
2243
2244   /* make sure that the result of this icode is not on the
2245      stack, since acc is used to compute stack offset */
2246 #if 0
2247   if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
2248       OP_SYMBOL (IC_RESULT (uic))->onStack)
2249     return;
2250 #else
2251   ifSymbolOnStack(IC_RESULT(uic))
2252     return;
2253 #endif
2254
2255   /* if either one of them in far space then we cannot */
2256   if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
2257        isOperandInFarSpace (IC_LEFT (uic))) ||
2258       (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
2259        isOperandInFarSpace (IC_RIGHT (uic))))
2260     return;
2261
2262   /* if the usage has only one operand then we can */
2263   if (IC_LEFT (uic) == NULL ||
2264       IC_RIGHT (uic) == NULL)
2265     goto accuse;
2266
2267   /* make sure this is on the left side if not
2268      a '+' since '+' is commutative */
2269   if (ic->op != '+' &&
2270       IC_LEFT (uic)->key != IC_RESULT (ic)->key)
2271     return;
2272
2273 #if 0
2274   // this is too dangerous and need further restrictions
2275   // see bug #447547
2276
2277   /* if one of them is a literal then we can */
2278   if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
2279       (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
2280     {
2281       OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2282       return;
2283     }
2284 #endif
2285
2286   /* if the other one is not on stack then we can */
2287   if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
2288       (IS_ITEMP (IC_RIGHT (uic)) ||
2289        (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
2290         !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
2291     goto accuse;
2292
2293   if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
2294       (IS_ITEMP (IC_LEFT (uic)) ||
2295        (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
2296         !OP_SYMBOL (IC_LEFT (uic))->onStack)))
2297     goto accuse;
2298
2299   return;
2300
2301 accuse:
2302   OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2303
2304
2305 }
2306
2307 /*-----------------------------------------------------------------*/
2308 /* packForPush - hueristics to reduce iCode for pushing            */
2309 /*-----------------------------------------------------------------*/
2310 static void
2311 packForPush (iCode * ic, eBBlock * ebp)
2312 {
2313   iCode *dic, *lic;
2314   bitVect *dbv;
2315
2316   if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
2317     return;
2318
2319   /* must have only definition & one usage */
2320   if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
2321       bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
2322     return;
2323
2324   /* find the definition */
2325   if (!(dic = hTabItemWithKey (iCodehTab,
2326                                bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
2327     return;
2328
2329   if (dic->op != '=' || POINTER_SET (dic))
2330     return;
2331
2332   /* make sure the right side does not have any definitions
2333      inbetween */
2334   dbv = OP_DEFS(IC_RIGHT(dic));
2335   for (lic = ic; lic && lic != dic ; lic = lic->prev) {
2336           if (bitVectBitValue(dbv,lic->key)) return ;
2337   }
2338   /* make sure they have the same type */
2339   {
2340     sym_link *itype=operandType(IC_LEFT(ic));
2341     sym_link *ditype=operandType(IC_RIGHT(dic));
2342
2343     if (SPEC_USIGN(itype)!=SPEC_USIGN(ditype) ||
2344         SPEC_LONG(itype)!=SPEC_LONG(ditype))
2345       return;
2346   }
2347   /* extend the live range of replaced operand if needed */
2348   if (OP_SYMBOL(IC_RIGHT(dic))->liveTo < ic->seq) {
2349           OP_SYMBOL(IC_RIGHT(dic))->liveTo = ic->seq;
2350   }
2351   /* we now we know that it has one & only one def & use
2352      and the that the definition is an assignment */
2353   IC_LEFT (ic) = IC_RIGHT (dic);
2354
2355   remiCodeFromeBBlock (ebp, dic);
2356   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2357   hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2358 }
2359
2360 /*-----------------------------------------------------------------*/
2361 /* packRegisters - does some transformations to reduce register    */
2362 /*                   pressure                                      */
2363 /*-----------------------------------------------------------------*/
2364 static void
2365 packRegisters (eBBlock * ebp)
2366 {
2367   iCode *ic;
2368   int change = 0;
2369
2370   while (1)
2371     {
2372
2373       change = 0;
2374
2375       /* look for assignments of the form */
2376       /* iTempNN = TRueSym (someoperation) SomeOperand */
2377       /*       ....                       */
2378       /* TrueSym := iTempNN:1             */
2379       for (ic = ebp->sch; ic; ic = ic->next)
2380         {
2381
2382
2383           /* find assignment of the form TrueSym := iTempNN:1 */
2384           if (ic->op == '=' && !POINTER_SET (ic))
2385             change += packRegsForAssign (ic, ebp);
2386         }
2387
2388       if (!change)
2389         break;
2390     }
2391
2392   for (ic = ebp->sch; ic; ic = ic->next)
2393     {
2394
2395       /* if this is an itemp & result of a address of a true sym 
2396          then mark this as rematerialisable   */
2397       if (ic->op == ADDRESS_OF &&
2398           IS_ITEMP (IC_RESULT (ic)) &&
2399           IS_TRUE_SYMOP (IC_LEFT (ic)) &&
2400           bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2401           !OP_SYMBOL (IC_LEFT (ic))->onStack)
2402         {
2403
2404           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2405           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2406           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2407
2408         }
2409
2410       /* if straight assignment then carry remat flag if
2411          this is the only definition */
2412       if (ic->op == '=' &&
2413           !POINTER_SET (ic) &&
2414           IS_SYMOP (IC_RIGHT (ic)) &&
2415           OP_SYMBOL (IC_RIGHT (ic))->remat &&
2416           !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode) &&
2417           bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
2418         {
2419
2420           OP_SYMBOL (IC_RESULT (ic))->remat =
2421             OP_SYMBOL (IC_RIGHT (ic))->remat;
2422           OP_SYMBOL (IC_RESULT (ic))->rematiCode =
2423             OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
2424         }
2425       
2426       /* if cast to a generic pointer & the pointer being
2427          cast is remat, then we can remat this cast as well */
2428       if (ic->op == CAST && 
2429           IS_SYMOP(IC_RIGHT(ic)) &&
2430           OP_SYMBOL(IC_RIGHT(ic))->remat ) {
2431               sym_link *to_type = operandType(IC_LEFT(ic));
2432               sym_link *from_type = operandType(IC_RIGHT(ic));
2433               if (IS_GENPTR(to_type) && IS_PTR(from_type)) {                  
2434                       OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2435                       OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2436                       OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2437               }
2438       }
2439
2440       /* if this is a +/- operation with a rematerizable 
2441          then mark this as rematerializable as well */
2442       if ((ic->op == '+' || ic->op == '-') &&
2443           (IS_SYMOP (IC_LEFT (ic)) &&
2444            IS_ITEMP (IC_RESULT (ic)) &&
2445            OP_SYMBOL (IC_LEFT (ic))->remat &&
2446            (!IS_SYMOP (IC_RIGHT (ic)) || !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode)) &&
2447            bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2448            IS_OP_LITERAL (IC_RIGHT (ic))))
2449         {
2450
2451           //int i = operandLitValue(IC_RIGHT(ic));
2452           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2453           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2454           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2455         }
2456
2457       /* mark the pointer usages */
2458       if (POINTER_SET (ic))
2459         OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
2460
2461       if (POINTER_GET (ic))
2462         OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
2463
2464       if (!SKIP_IC2 (ic))
2465         {
2466           /* if we are using a symbol on the stack
2467              then we should say ds390_ptrRegReq */
2468           if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
2469                   ds390_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ? !options.stack10bit : 0) +
2470                                       OP_SYMBOL (IC_COND (ic))->iaccess);
2471           else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
2472                   ds390_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ? !options.stack10bit : 0) +
2473                                       OP_SYMBOL (IC_JTCOND (ic))->iaccess);
2474           else
2475             {
2476               if (IS_SYMOP (IC_LEFT (ic)))
2477                       ds390_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ? !options.stack10bit : 0) +
2478                                           OP_SYMBOL (IC_LEFT (ic))->iaccess);
2479               if (IS_SYMOP (IC_RIGHT (ic)))
2480                       ds390_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ? !options.stack10bit : 0) +
2481                                           OP_SYMBOL (IC_RIGHT (ic))->iaccess);
2482               if (IS_SYMOP (IC_RESULT (ic)))
2483                       ds390_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ? !options.stack10bit : 0) +
2484                                           OP_SYMBOL (IC_RESULT (ic))->iaccess);
2485             }
2486         }
2487
2488 #if 0
2489       /* if the condition of an if instruction
2490          is defined in the previous instruction then
2491          mark the itemp as a conditional */
2492       if ((IS_CONDITIONAL (ic) ||
2493            (IS_BITWISE_OP(ic) && isBitwiseOptimizable(ic))) &&
2494           ic->next && ic->next->op == IFX &&
2495           isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
2496           OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2497         {
2498
2499           OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
2500           continue;
2501         }
2502 #else
2503       /* if the condition of an if instruction
2504          is defined in the previous instruction and
2505          this is the only usage then
2506          mark the itemp as a conditional */
2507       if ((IS_CONDITIONAL (ic) ||
2508            (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic))) &&
2509           ic->next && ic->next->op == IFX &&
2510           bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
2511           isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
2512           OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2513         {
2514           OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
2515           continue;
2516         }
2517 #endif
2518
2519       /* reduce for support function calls */
2520       if (ic->supportRtn || ic->op == '+' || ic->op == '-')
2521         packRegsForSupport (ic, ebp);
2522
2523       /* some cases the redundant moves can
2524          can be eliminated for return statements */
2525       if ((ic->op == RETURN || ic->op == SEND) &&         
2526           !isOperandInFarSpace (IC_LEFT (ic)) &&
2527           !options.model) {
2528          
2529           packRegsDPTRuse (ic, IC_LEFT (ic), ebp);
2530       }
2531
2532       if ((ic->op == CALL && getSize(operandType(IC_RESULT(ic))) <= 4)) {
2533           packRegsDPTRuse (ic, IC_RESULT (ic), ebp);      
2534       }
2535
2536       /* if pointer set & left has a size more than
2537          one and right is not in far space */
2538       if (POINTER_SET (ic) &&
2539           !isOperandInFarSpace (IC_RIGHT (ic)) &&
2540           !OP_SYMBOL (IC_RESULT (ic))->remat &&
2541           !IS_OP_RUONLY (IC_RIGHT (ic)) &&
2542           getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1) {
2543           
2544           packRegsDPTRuse (ic, IC_RESULT (ic), ebp);
2545       }
2546
2547       /* if pointer get */
2548       if (POINTER_GET (ic) &&
2549           !isOperandInFarSpace (IC_RESULT (ic)) &&
2550           !OP_SYMBOL (IC_LEFT (ic))->remat &&
2551           !IS_OP_RUONLY (IC_RESULT (ic)) &&
2552           getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1) {
2553
2554           packRegsDPTRuse (ic, IC_LEFT (ic), ebp);
2555       }
2556
2557       /* if this is cast for intergral promotion then
2558          check if only use of  the definition of the 
2559          operand being casted/ if yes then replace
2560          the result of that arithmetic operation with 
2561          this result and get rid of the cast */
2562       if (ic->op == CAST)
2563         {
2564           sym_link *fromType = operandType (IC_RIGHT (ic));
2565           sym_link *toType = operandType (IC_LEFT (ic));
2566
2567           if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
2568               getSize (fromType) != getSize (toType) &&
2569               SPEC_USIGN (fromType) == SPEC_USIGN (toType))
2570             {
2571
2572               iCode *dic = packRegsDPTRuse (ic, IC_RIGHT (ic), ebp);
2573               if (dic)
2574                 {
2575                   if (IS_ARITHMETIC_OP (dic))
2576                     {
2577                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2578                       IC_RESULT (dic) = IC_RESULT (ic);
2579                       remiCodeFromeBBlock (ebp, ic);
2580                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2581                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2582                       OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2583                       ic = ic->prev;
2584                     }
2585                   else
2586                     OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
2587                 }
2588             }
2589           else
2590             {
2591
2592               /* if the type from and type to are the same
2593                  then if this is the only use then packit */
2594               if (compareType (operandType (IC_RIGHT (ic)),
2595                              operandType (IC_LEFT (ic))) == 1)
2596                 {
2597                   iCode *dic = packRegsDPTRuse (ic, IC_RIGHT (ic), ebp);
2598                   if (dic)
2599                     {
2600                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2601                       IC_RESULT (dic) = IC_RESULT (ic);
2602                       remiCodeFromeBBlock (ebp, ic);
2603                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2604                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2605                       OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2606                       ic = ic->prev;
2607                     }
2608                 }
2609             }
2610         }
2611
2612       /* pack for PUSH 
2613          iTempNN := (some variable in farspace) V1
2614          push iTempNN ;
2615          -------------
2616          push V1
2617        */
2618       if (ic->op == IPUSH)
2619         {
2620           packForPush (ic, ebp);
2621         }
2622
2623
2624       /* pack registers for accumulator use, when the
2625          result of an arithmetic or bit wise operation
2626          has only one use, that use is immediately following
2627          the defintion and the using iCode has only one
2628          operand or has two operands but one is literal &
2629          the result of that operation is not on stack then
2630          we can leave the result of this operation in acc:b
2631          combination */
2632       if ((IS_ARITHMETIC_OP (ic)
2633            || IS_CONDITIONAL(ic)
2634            || IS_BITWISE_OP (ic)
2635            || ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == CALL
2636            || (ic->op == ADDRESS_OF && isOperandOnStack (IC_LEFT (ic)))
2637           ) &&
2638           IS_ITEMP (IC_RESULT (ic)) &&
2639           getSize (operandType (IC_RESULT (ic))) <= 2)
2640
2641         packRegsForAccUse (ic);
2642       
2643     }
2644 }
2645
2646 /*-----------------------------------------------------------------*/
2647 /* assignRegisters - assigns registers to each live range as need  */
2648 /*-----------------------------------------------------------------*/
2649 void
2650 ds390_assignRegisters (eBBlock ** ebbs, int count)
2651 {
2652   iCode *ic;
2653   int i;
2654
2655   setToNull ((void *) &_G.funcrUsed);  
2656   setToNull ((void *) &_G.regAssigned);  
2657   setToNull ((void *) &_G.totRegAssigned);  
2658   setToNull ((void *) &_G.funcrUsed);  
2659   ds390_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
2660   ds390_nRegs = 18;
2661   if (options.model != MODEL_FLAT24) options.stack10bit = 0;
2662   /* change assignments this will remove some
2663      live ranges reducing some register pressure */
2664   for (i = 0; i < count; i++)
2665     packRegisters (ebbs[i]);
2666
2667   if (options.dump_pack)
2668     dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
2669
2670   /* first determine for each live range the number of 
2671      registers & the type of registers required for each */
2672   regTypeNum ();
2673
2674   /* and serially allocate registers */
2675   serialRegAssign (ebbs, count);
2676
2677   ds390_nRegs = 8;
2678   freeAllRegs ();
2679   fillGaps();
2680   ds390_nRegs = 18;
2681
2682   /* if stack was extended then tell the user */
2683   if (_G.stackExtend)
2684     {
2685 /*      werror(W_TOOMANY_SPILS,"stack", */
2686 /*             _G.stackExtend,currFunc->name,""); */
2687       _G.stackExtend = 0;
2688     }
2689
2690   if (_G.dataExtend)
2691     {
2692 /*      werror(W_TOOMANY_SPILS,"data space", */
2693 /*             _G.dataExtend,currFunc->name,""); */
2694       _G.dataExtend = 0;
2695     }
2696
2697   /* after that create the register mask
2698      for each of the instruction */
2699   createRegMask (ebbs, count);
2700
2701   /* redo that offsets for stacked automatic variables */
2702   redoStackOffsets ();
2703
2704   if (options.dump_rassgn) {
2705     dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
2706     dumpLiveRanges (DUMP_LRANGE, liveRanges);
2707   }
2708
2709   /* do the overlaysegment stuff SDCCmem.c */
2710   doOverlays (ebbs, count);
2711
2712   /* now get back the chain */
2713   ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
2714
2715
2716   gen390Code (ic);
2717
2718   /* free up any _G.stackSpil locations allocated */
2719   applyToSet (_G.stackSpil, deallocStackSpil);
2720   _G.slocNum = 0;
2721   setToNull ((void **) &_G.stackSpil);
2722   setToNull ((void **) &_G.spiltSet);
2723   /* mark all registers as free */
2724   ds390_nRegs = 8;
2725   freeAllRegs ();
2726
2727   return;
2728 }