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