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