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