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