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