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