small fixes
[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 && sym->usl.spillLoc)
1153                 {
1154
1155                   symbol *leastUsed =
1156                   leastUsedLR (liveRangesWith (spillable,
1157                                                allLRs,
1158                                                ebbs[i],
1159                                                ic));
1160                   if (leastUsed &&
1161                       leastUsed->used > sym->used)
1162                     {
1163                       spillThis (sym);
1164                       continue;
1165                     }
1166                 }
1167
1168               /* if we need ptr regs for the right side
1169                  then mark it */
1170               if (POINTER_GET (ic) && IS_SYMOP (IC_LEFT (ic))
1171                   && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
1172                   <= (unsigned) PTRSIZE)
1173                 {
1174                   ds390_ptrRegReq++;
1175                   ptrRegSet = 1;
1176                 }
1177               /* else we assign registers to it */
1178               _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1179
1180               for (j = 0; j < sym->nRegs; j++)
1181                 {
1182                   if (sym->regType == REG_PTR)
1183                     sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
1184                   else
1185                     sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
1186
1187                   /* if the allocation falied which means
1188                      this was spilt then break */
1189                   if (!sym->regs[j])
1190                     break;
1191                 }
1192               /* if it shares registers with operands make sure
1193                  that they are in the same position */
1194               if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
1195                   OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
1196                 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1197                               OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
1198               /* do the same for the right operand */
1199               if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
1200                   OP_SYMBOL (IC_RIGHT (ic))->nRegs)
1201                 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1202                               OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
1203
1204               if (ptrRegSet)
1205                 {
1206                   ds390_ptrRegReq--;
1207                   ptrRegSet = 0;
1208                 }
1209
1210             }
1211         }
1212     }
1213 }
1214
1215 /*-----------------------------------------------------------------*/
1216 /* rUmaskForOp :- returns register mask for an operand             */
1217 /*-----------------------------------------------------------------*/
1218 static bitVect *
1219 rUmaskForOp (operand * op)
1220 {
1221   bitVect *rumask;
1222   symbol *sym;
1223   int j;
1224
1225   /* only temporaries are assigned registers */
1226   if (!IS_ITEMP (op))
1227     return NULL;
1228
1229   sym = OP_SYMBOL (op);
1230
1231   /* if spilt or no registers assigned to it
1232      then nothing */
1233   if (sym->isspilt || !sym->nRegs)
1234     return NULL;
1235
1236   rumask = newBitVect (ds390_nRegs);
1237
1238   for (j = 0; j < sym->nRegs; j++)
1239     {
1240       rumask = bitVectSetBit (rumask,
1241                               sym->regs[j]->rIdx);
1242     }
1243
1244   return rumask;
1245 }
1246
1247 /*-----------------------------------------------------------------*/
1248 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
1249 /*-----------------------------------------------------------------*/
1250 static bitVect *
1251 regsUsedIniCode (iCode * ic)
1252 {
1253   bitVect *rmask = newBitVect (ds390_nRegs);
1254
1255   /* do the special cases first */
1256   if (ic->op == IFX)
1257     {
1258       rmask = bitVectUnion (rmask,
1259                             rUmaskForOp (IC_COND (ic)));
1260       goto ret;
1261     }
1262
1263   /* for the jumptable */
1264   if (ic->op == JUMPTABLE)
1265     {
1266       rmask = bitVectUnion (rmask,
1267                             rUmaskForOp (IC_JTCOND (ic)));
1268
1269       goto ret;
1270     }
1271
1272   /* of all other cases */
1273   if (IC_LEFT (ic))
1274     rmask = bitVectUnion (rmask,
1275                           rUmaskForOp (IC_LEFT (ic)));
1276
1277
1278   if (IC_RIGHT (ic))
1279     rmask = bitVectUnion (rmask,
1280                           rUmaskForOp (IC_RIGHT (ic)));
1281
1282   if (IC_RESULT (ic))
1283     rmask = bitVectUnion (rmask,
1284                           rUmaskForOp (IC_RESULT (ic)));
1285
1286 ret:
1287   return rmask;
1288 }
1289
1290 /*-----------------------------------------------------------------*/
1291 /* createRegMask - for each instruction will determine the regsUsed */
1292 /*-----------------------------------------------------------------*/
1293 static void
1294 createRegMask (eBBlock ** ebbs, int count)
1295 {
1296   int i;
1297
1298   /* for all blocks */
1299   for (i = 0; i < count; i++)
1300     {
1301       iCode *ic;
1302
1303       if (ebbs[i]->noPath &&
1304           (ebbs[i]->entryLabel != entryLabel &&
1305            ebbs[i]->entryLabel != returnLabel))
1306         continue;
1307
1308       /* for all instructions */
1309       for (ic = ebbs[i]->sch; ic; ic = ic->next)
1310         {
1311
1312           int j;
1313
1314           if (SKIP_IC2 (ic) || !ic->rlive)
1315             continue;
1316
1317           /* first mark the registers used in this
1318              instruction */
1319           ic->rUsed = regsUsedIniCode (ic);
1320           _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
1321
1322           /* now create the register mask for those 
1323              registers that are in use : this is a
1324              super set of ic->rUsed */
1325           ic->rMask = newBitVect (ds390_nRegs + 1);
1326
1327           /* for all live Ranges alive at this point */
1328           for (j = 1; j < ic->rlive->size; j++)
1329             {
1330               symbol *sym;
1331               int k;
1332
1333               /* if not alive then continue */
1334               if (!bitVectBitValue (ic->rlive, j))
1335                 continue;
1336
1337               /* find the live range we are interested in */
1338               if (!(sym = hTabItemWithKey (liveRanges, j)))
1339                 {
1340                   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1341                           "createRegMask cannot find live range");
1342                   exit (0);
1343                 }
1344
1345               /* if no register assigned to it */
1346               if (!sym->nRegs || sym->isspilt)
1347                 continue;
1348
1349               /* for all the registers allocated to it */
1350               for (k = 0; k < sym->nRegs; k++)
1351                 if (sym->regs[k])
1352                   ic->rMask =
1353                     bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
1354             }
1355         }
1356     }
1357 }
1358
1359 /*-----------------------------------------------------------------*/
1360 /* rematStr - returns the rematerialized string for a remat var    */
1361 /*-----------------------------------------------------------------*/
1362 static char *
1363 rematStr (symbol * sym)
1364 {
1365   char *s = buffer;
1366   iCode *ic = sym->rematiCode;
1367
1368   while (1)
1369     {
1370
1371       /* if plus or minus print the right hand side */
1372       if (ic->op == '+' || ic->op == '-')
1373         {
1374           sprintf (s, "0x%04x %c ", (int) operandLitValue (IC_RIGHT (ic)),
1375                    ic->op);
1376           s += strlen (s);
1377           ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1378           continue;
1379         }
1380
1381       /* we reached the end */
1382       sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
1383       break;
1384     }
1385
1386   return buffer;
1387 }
1388
1389 /*-----------------------------------------------------------------*/
1390 /* regTypeNum - computes the type & number of registers required   */
1391 /*-----------------------------------------------------------------*/
1392 static void
1393 regTypeNum ()
1394 {
1395   symbol *sym;
1396   int k;
1397   iCode *ic;
1398
1399   /* for each live range do */
1400   for (sym = hTabFirstItem (liveRanges, &k); sym;
1401        sym = hTabNextItem (liveRanges, &k))
1402     {
1403
1404       /* if used zero times then no registers needed */
1405       if ((sym->liveTo - sym->liveFrom) == 0)
1406         continue;
1407
1408
1409       /* if the live range is a temporary */
1410       if (sym->isitmp)
1411         {
1412
1413           /* if the type is marked as a conditional */
1414           if (sym->regType == REG_CND)
1415             continue;
1416
1417           /* if used in return only then we don't 
1418              need registers */
1419           if (sym->ruonly || sym->accuse)
1420             {
1421               if (IS_AGGREGATE (sym->type) || sym->isptr)
1422                 sym->type = aggrToPtr (sym->type, FALSE);
1423               continue;
1424             }
1425
1426           /* if the symbol has only one definition &
1427              that definition is a get_pointer and the
1428              pointer we are getting is rematerializable and
1429              in "data" space */
1430
1431           if (bitVectnBitsOn (sym->defs) == 1 &&
1432               (ic = hTabItemWithKey (iCodehTab,
1433                                      bitVectFirstBit (sym->defs))) &&
1434               POINTER_GET (ic) &&
1435               !IS_BITVAR (sym->etype))
1436             {
1437
1438
1439               /* if remat in data space */
1440               if (OP_SYMBOL (IC_LEFT (ic))->remat &&
1441               // sym->type &&
1442                   DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER)
1443                 {
1444
1445                   /* create a psuedo symbol & force a spil */
1446                   symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
1447                   psym->type = sym->type;
1448                   psym->etype = sym->etype;
1449                   strcpy (psym->rname, psym->name);
1450                   sym->isspilt = 1;
1451                   sym->usl.spillLoc = psym;
1452                   continue;
1453                 }
1454
1455               /* if in data space or idata space then try to
1456                  allocate pointer register */
1457
1458             }
1459
1460           /* if not then we require registers */
1461           sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
1462                         getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1463                         getSize (sym->type));
1464
1465           if (sym->nRegs > 4)
1466             {
1467               fprintf (stderr, "allocated more than 4 or 0 registers for type ");
1468               printTypeChain (sym->type, stderr);
1469               fprintf (stderr, "\n");
1470             }
1471
1472           /* determine the type of register required */
1473           if (sym->nRegs == 1 &&
1474               IS_PTR (sym->type) &&
1475               sym->uptr)
1476             sym->regType = REG_PTR;
1477           else
1478             sym->regType = REG_GPR;
1479
1480         }
1481       else
1482         /* for the first run we don't provide */
1483         /* registers for true symbols we will */
1484         /* see how things go                  */
1485         sym->nRegs = 0;
1486     }
1487
1488 }
1489
1490 /*-----------------------------------------------------------------*/
1491 /* freeAllRegs - mark all registers as free                        */
1492 /*-----------------------------------------------------------------*/
1493 static void
1494 freeAllRegs ()
1495 {
1496   int i;
1497
1498   for (i = 0; i < ds390_nRegs; i++)
1499     regs390[i].isFree = 1;
1500 }
1501
1502 /*-----------------------------------------------------------------*/
1503 /* deallocStackSpil - this will set the stack pointer back         */
1504 /*-----------------------------------------------------------------*/
1505 static
1506 DEFSETFUNC (deallocStackSpil)
1507 {
1508   symbol *sym = item;
1509
1510   deallocLocal (sym);
1511   return 0;
1512 }
1513
1514 /*-----------------------------------------------------------------*/
1515 /* farSpacePackable - returns the packable icode for far variables */
1516 /*-----------------------------------------------------------------*/
1517 static iCode *
1518 farSpacePackable (iCode * ic)
1519 {
1520   iCode *dic;
1521
1522   /* go thru till we find a definition for the
1523      symbol on the right */
1524   for (dic = ic->prev; dic; dic = dic->prev)
1525     {
1526
1527       /* if the definition is a call then no */
1528       if ((dic->op == CALL || dic->op == PCALL) &&
1529           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1530         {
1531           return NULL;
1532         }
1533
1534       /* if shift by unknown amount then not */
1535       if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
1536           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1537         return NULL;
1538
1539       /* if pointer get and size > 1 */
1540       if (POINTER_GET (dic) &&
1541           getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
1542         return NULL;
1543
1544       if (POINTER_SET (dic) &&
1545           getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
1546         return NULL;
1547
1548       /* if any three is a true symbol in far space */
1549       if (IC_RESULT (dic) &&
1550           IS_TRUE_SYMOP (IC_RESULT (dic)) &&
1551           isOperandInFarSpace (IC_RESULT (dic)))
1552         return NULL;
1553
1554       if (IC_RIGHT (dic) &&
1555           IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
1556           isOperandInFarSpace (IC_RIGHT (dic)) &&
1557           !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
1558         return NULL;
1559
1560       if (IC_LEFT (dic) &&
1561           IS_TRUE_SYMOP (IC_LEFT (dic)) &&
1562           isOperandInFarSpace (IC_LEFT (dic)) &&
1563           !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
1564         return NULL;
1565
1566       if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
1567         {
1568           if ((dic->op == LEFT_OP ||
1569                dic->op == RIGHT_OP ||
1570                dic->op == '-') &&
1571               IS_OP_LITERAL (IC_RIGHT (dic)))
1572             return NULL;
1573           else
1574             return dic;
1575         }
1576     }
1577
1578   return NULL;
1579 }
1580
1581 /*-----------------------------------------------------------------*/
1582 /* packRegsForAssign - register reduction for assignment           */
1583 /*-----------------------------------------------------------------*/
1584 static int
1585 packRegsForAssign (iCode * ic, eBBlock * ebp)
1586 {
1587   iCode *dic, *sic;
1588
1589   if (!IS_ITEMP (IC_RIGHT (ic)) ||
1590       OP_SYMBOL (IC_RIGHT (ic))->isind ||
1591       OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
1592     {
1593       return 0;
1594     }
1595
1596   /* if the true symbol is defined in far space or on stack
1597      then we should not since this will increase register pressure */
1598 #if 0
1599   if (isOperandInFarSpace (IC_RESULT (ic)))
1600     {
1601       if ((dic = farSpacePackable (ic)))
1602         goto pack;
1603       else
1604         return 0;
1605     }
1606 #else
1607   if (isOperandInFarSpace(IC_RESULT(ic)) && !farSpacePackable(ic)) {
1608     return 0;
1609   }
1610 #endif
1611
1612   /* find the definition of iTempNN scanning backwards if we find a 
1613      a use of the true symbol in before we find the definition then 
1614      we cannot */
1615   for (dic = ic->prev; dic; dic = dic->prev)
1616     {
1617 #if 0 // jwk 20010410, the JanVanBelle case
1618       /* if there is a function call and this is
1619          a parameter & not my parameter then don't pack it */
1620       if ((dic->op == CALL || dic->op == PCALL) &&
1621           (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
1622            !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
1623         {
1624           dic = NULL;
1625           break;
1626         }
1627 #else
1628       /* if there is a function call then don't pack it */
1629       if ((dic->op == CALL || dic->op == PCALL))
1630         {
1631           dic = NULL;
1632           break;
1633         }
1634 #endif
1635
1636       if (SKIP_IC2 (dic))
1637         continue;
1638
1639       if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
1640           IS_OP_VOLATILE (IC_RESULT (dic)))
1641         {
1642           dic = NULL;
1643           break;
1644         }
1645
1646       if (IS_SYMOP (IC_RESULT (dic)) &&
1647           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1648         {
1649           if (POINTER_SET (dic))
1650             dic = NULL;
1651
1652           break;
1653         }
1654
1655       if (IS_SYMOP (IC_RIGHT (dic)) &&
1656           (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
1657            IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
1658         {
1659           dic = NULL;
1660           break;
1661         }
1662
1663       if (IS_SYMOP (IC_LEFT (dic)) &&
1664           (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
1665            IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
1666         {
1667           dic = NULL;
1668           break;
1669         }
1670
1671       if (POINTER_SET (dic) &&
1672           IC_RESULT (dic)->key == IC_RESULT (ic)->key)
1673         {
1674           dic = NULL;
1675           break;
1676         }
1677     }
1678
1679   if (!dic)
1680     return 0;                   /* did not find */
1681
1682   /* if the result is on stack or iaccess then it must be
1683      the same atleast one of the operands */
1684   if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
1685       OP_SYMBOL (IC_RESULT (ic))->iaccess)
1686     {
1687
1688       /* the operation has only one symbol
1689          operator then we can pack */
1690       if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
1691           (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
1692         goto pack;
1693
1694       if (!((IC_LEFT (dic) &&
1695              IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
1696             (IC_RIGHT (dic) &&
1697              IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
1698         return 0;
1699     }
1700 pack:
1701   /* found the definition */
1702   /* replace the result with the result of */
1703   /* this assignment and remove this assignment */
1704   IC_RESULT (dic) = IC_RESULT (ic);
1705
1706   if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
1707     {
1708       OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
1709     }
1710   /* delete from liverange table also 
1711      delete from all the points inbetween and the new
1712      one */
1713   for (sic = dic; sic != ic; sic = sic->next)
1714     {
1715       bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
1716       if (IS_ITEMP (IC_RESULT (dic)))
1717         bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
1718     }
1719
1720   remiCodeFromeBBlock (ebp, ic);
1721   hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
1722   OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
1723   return 1;
1724
1725 }
1726
1727 /*-----------------------------------------------------------------*/
1728 /* findAssignToSym : scanning backwards looks for first assig found */
1729 /*-----------------------------------------------------------------*/
1730 static iCode *
1731 findAssignToSym (operand * op, iCode * ic)
1732 {
1733   iCode *dic;
1734
1735   for (dic = ic->prev; dic; dic = dic->prev)
1736     {
1737
1738       /* if definition by assignment */
1739       if (dic->op == '=' &&
1740           !POINTER_SET (dic) &&
1741           IC_RESULT (dic)->key == op->key
1742 /*          &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) */
1743         )
1744         {
1745
1746           /* we are interested only if defined in far space */
1747           /* or in stack space in case of + & - */
1748
1749           /* if assigned to a non-symbol then return
1750              true */
1751           if (!IS_SYMOP (IC_RIGHT (dic)))
1752             break;
1753
1754           /* if the symbol is in far space then
1755              we should not */
1756           if (isOperandInFarSpace (IC_RIGHT (dic)))
1757             return NULL;
1758
1759           /* for + & - operations make sure that
1760              if it is on the stack it is the same
1761              as one of the three operands */
1762           if ((ic->op == '+' || ic->op == '-') &&
1763               OP_SYMBOL (IC_RIGHT (dic))->onStack)
1764             {
1765
1766               if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
1767                   IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
1768                   IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
1769                 return NULL;
1770             }
1771
1772           break;
1773
1774         }
1775
1776       /* if we find an usage then we cannot delete it */
1777       if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
1778         return NULL;
1779
1780       if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
1781         return NULL;
1782
1783       if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
1784         return NULL;
1785     }
1786
1787   /* now make sure that the right side of dic
1788      is not defined between ic & dic */
1789   if (dic)
1790     {
1791       iCode *sic = dic->next;
1792
1793       for (; sic != ic; sic = sic->next)
1794         if (IC_RESULT (sic) &&
1795             IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
1796           return NULL;
1797     }
1798
1799   return dic;
1800
1801
1802 }
1803
1804 /*-----------------------------------------------------------------*/
1805 /* packRegsForSupport :- reduce some registers for support calls   */
1806 /*-----------------------------------------------------------------*/
1807 static int
1808 packRegsForSupport (iCode * ic, eBBlock * ebp)
1809 {
1810   int change = 0;
1811   /* for the left & right operand :- look to see if the
1812      left was assigned a true symbol in far space in that
1813      case replace them */
1814   if (IS_ITEMP (IC_LEFT (ic)) &&
1815       OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
1816     {
1817       iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
1818       iCode *sic;
1819
1820       if (!dic)
1821         goto right;
1822
1823       /* found it we need to remove it from the
1824          block */
1825       for (sic = dic; sic != ic; sic = sic->next)
1826         bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
1827
1828       IC_LEFT (ic)->operand.symOperand =
1829         IC_RIGHT (dic)->operand.symOperand;
1830       IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
1831       remiCodeFromeBBlock (ebp, dic);
1832       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1833       change++;
1834     }
1835
1836   /* do the same for the right operand */
1837 right:
1838   if (!change &&
1839       IS_ITEMP (IC_RIGHT (ic)) &&
1840       OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
1841     {
1842       iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
1843       iCode *sic;
1844
1845       if (!dic)
1846         return change;
1847
1848       /* if this is a subtraction & the result
1849          is a true symbol in far space then don't pack */
1850       if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
1851         {
1852           sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
1853           if (IN_FARSPACE (SPEC_OCLS (etype)))
1854             return change;
1855         }
1856       /* found it we need to remove it from the
1857          block */
1858       for (sic = dic; sic != ic; sic = sic->next)
1859         bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
1860
1861       IC_RIGHT (ic)->operand.symOperand =
1862         IC_RIGHT (dic)->operand.symOperand;
1863       IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
1864
1865       remiCodeFromeBBlock (ebp, dic);
1866       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1867       change++;
1868     }
1869
1870   return change;
1871 }
1872
1873 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
1874
1875
1876 /*-----------------------------------------------------------------*/
1877 /* packRegsForOneuse : - will reduce some registers for single Use */
1878 /*-----------------------------------------------------------------*/
1879 static iCode *
1880 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
1881 {
1882 #if 1
1883
1884   /* I can't figure out how to make this safe yet. */
1885   if ((int)ic+(int)op+(int)ebp) {
1886     return 0;
1887   } else {
1888     return 0;
1889   }
1890   return NULL;
1891
1892 #else
1893   bitVect *uses;
1894   iCode *dic, *sic;
1895
1896   /* if returning a literal then do nothing */
1897   if (!IS_SYMOP (op))
1898     return NULL;
1899
1900   /* only upto 2 bytes since we cannot predict
1901      the usage of b, & acc */
1902   if (getSize (operandType (op)) > (fReturnSizeDS390 - 2) &&
1903       ic->op != RETURN &&
1904       ic->op != SEND &&
1905       !POINTER_SET (ic) &&
1906       !POINTER_GET (ic))
1907     return NULL;
1908
1909   /* this routine will mark the a symbol as used in one 
1910      instruction use only && if the defintion is local 
1911      (ie. within the basic block) && has only one definition &&
1912      that definiion is either a return value from a 
1913      function or does not contain any variables in
1914      far space */
1915   uses = bitVectCopy (OP_USES (op));
1916   bitVectUnSetBit (uses, ic->key);      /* take away this iCode */
1917   if (!bitVectIsZero (uses))    /* has other uses */
1918     return NULL;
1919
1920   /* if it has only one defintion */
1921   if (bitVectnBitsOn (OP_DEFS (op)) > 1)
1922     return NULL;                /* has more than one definition */
1923
1924   /* get the that definition */
1925   if (!(dic =
1926         hTabItemWithKey (iCodehTab,
1927                          bitVectFirstBit (OP_DEFS (op)))))
1928     return NULL;
1929
1930   /* found the definition now check if it is local */
1931   if (dic->seq < ebp->fSeq ||
1932       dic->seq > ebp->lSeq)
1933     return NULL;                /* non-local */
1934
1935   /* now check if it is the return from
1936      a function call */
1937   if (dic->op == CALL || dic->op == PCALL)
1938     {
1939       if (ic->op != SEND && ic->op != RETURN)
1940         {
1941           OP_SYMBOL (op)->ruonly = 1;
1942           return dic;
1943         }
1944       dic = dic->next;
1945     }
1946
1947
1948   /* otherwise check that the definition does
1949      not contain any symbols in far space */
1950   if (isOperandInFarSpace (IC_LEFT (dic)) ||
1951       isOperandInFarSpace (IC_RIGHT (dic)) ||
1952       IS_OP_RUONLY (IC_LEFT (ic)) ||
1953       IS_OP_RUONLY (IC_RIGHT (ic)))
1954     {
1955       return NULL;
1956     }
1957
1958   /* if pointer set then make sure the pointer
1959      is one byte */
1960   if (POINTER_SET (dic) &&
1961       !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
1962     return NULL;
1963
1964   if (POINTER_GET (dic) &&
1965       !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
1966     return NULL;
1967
1968   sic = dic;
1969
1970   /* also make sure the intervenening instructions
1971      don't have any thing in far space */
1972   for (dic = dic->next; dic && dic != ic; dic = dic->next)
1973     {
1974
1975       /* if there is an intervening function call then no */
1976       if (dic->op == CALL || dic->op == PCALL)
1977         return NULL;
1978       /* if pointer set then make sure the pointer
1979          is one byte */
1980       if (POINTER_SET (dic) &&
1981           !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
1982         return NULL;
1983
1984       if (POINTER_GET (dic) &&
1985           !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
1986         return NULL;
1987
1988       /* if address of & the result is remat the okay */
1989       if (dic->op == ADDRESS_OF &&
1990           OP_SYMBOL (IC_RESULT (dic))->remat)
1991         continue;
1992
1993       /* if operand has size of three or more & this
1994          operation is a '*','/' or '%' then 'b' may
1995          cause a problem */
1996       if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
1997           getSize (operandType (op)) >= 3)
1998         return NULL;
1999
2000       /* if left or right or result is in far space */
2001       if (isOperandInFarSpace (IC_LEFT (dic)) ||
2002           isOperandInFarSpace (IC_RIGHT (dic)) ||
2003           isOperandInFarSpace (IC_RESULT (dic)) ||
2004           IS_OP_RUONLY (IC_LEFT (dic)) ||
2005           IS_OP_RUONLY (IC_RIGHT (dic)) ||
2006           IS_OP_RUONLY (IC_RESULT (dic)))
2007         {
2008           return NULL;
2009         }
2010     }
2011
2012   OP_SYMBOL (op)->ruonly = 1;
2013   return sic;
2014 #endif
2015 }
2016
2017 /*-----------------------------------------------------------------*/
2018 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
2019 /*-----------------------------------------------------------------*/
2020 static bool
2021 isBitwiseOptimizable (iCode * ic)
2022 {
2023   sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
2024   sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
2025
2026   /* bitwise operations are considered optimizable
2027      under the following conditions (Jean-Louis VERN) 
2028
2029      x & lit
2030      bit & bit
2031      bit & x
2032      bit ^ bit
2033      bit ^ x
2034      x   ^ lit
2035      x   | lit
2036      bit | bit
2037      bit | x
2038    */
2039   if ( IS_LITERAL (rtype) ||
2040       (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
2041     return TRUE;
2042   else
2043     return FALSE;
2044 }
2045
2046 /*-----------------------------------------------------------------*/
2047 /* packRegsForAccUse - pack registers for acc use                  */
2048 /*-----------------------------------------------------------------*/
2049 static void
2050 packRegsForAccUse (iCode * ic)
2051 {
2052   iCode *uic;
2053
2054   /* if + or - then it has to be one byte result */
2055   if ((ic->op == '+' || ic->op == '-')
2056       && getSize (operandType (IC_RESULT (ic))) > 1)
2057     return;
2058
2059   /* if shift operation make sure right side is not a literal */
2060   if (ic->op == RIGHT_OP &&
2061       (isOperandLiteral (IC_RIGHT (ic)) ||
2062        getSize (operandType (IC_RESULT (ic))) > 1))
2063     return;
2064
2065   if (ic->op == LEFT_OP &&
2066       (isOperandLiteral (IC_RIGHT (ic)) ||
2067        getSize (operandType (IC_RESULT (ic))) > 1))
2068     return;
2069
2070   if (IS_BITWISE_OP (ic) &&
2071       getSize (operandType (IC_RESULT (ic))) > 1)
2072     return;
2073
2074
2075   /* has only one definition */
2076   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
2077     return;
2078
2079   /* has only one use */
2080   if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
2081     return;
2082
2083   /* and the usage immediately follows this iCode */
2084   if (!(uic = hTabItemWithKey (iCodehTab,
2085                                bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
2086     return;
2087
2088   if (ic->next != uic)
2089     return;
2090
2091   /* if it is a conditional branch then we definitely can */
2092   if (uic->op == IFX)
2093     goto accuse;
2094
2095   if (uic->op == JUMPTABLE)
2096     return;
2097
2098   /* if the usage is not is an assignment
2099      or an arithmetic / bitwise / shift operation then not */
2100   if (POINTER_SET (uic) &&
2101       getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
2102     return;
2103
2104   if (uic->op != '=' &&
2105       !IS_ARITHMETIC_OP (uic) &&
2106       !IS_BITWISE_OP (uic) &&
2107       uic->op != LEFT_OP &&
2108       uic->op != RIGHT_OP)
2109     return;
2110
2111   /* if used in ^ operation then make sure right is not a 
2112      literl */
2113   if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
2114     return;
2115
2116   /* if shift operation make sure right side is not a literal */
2117   if (uic->op == RIGHT_OP &&
2118       (isOperandLiteral (IC_RIGHT (uic)) ||
2119        getSize (operandType (IC_RESULT (uic))) > 1))
2120     return;
2121
2122   if (uic->op == LEFT_OP &&
2123       (isOperandLiteral (IC_RIGHT (uic)) ||
2124        getSize (operandType (IC_RESULT (uic))) > 1))
2125     return;
2126
2127   /* make sure that the result of this icode is not on the
2128      stack, since acc is used to compute stack offset */
2129   if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
2130       OP_SYMBOL (IC_RESULT (uic))->onStack)
2131     return;
2132
2133   /* if either one of them in far space then we cannot */
2134   if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
2135        isOperandInFarSpace (IC_LEFT (uic))) ||
2136       (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
2137        isOperandInFarSpace (IC_RIGHT (uic))))
2138     return;
2139
2140   /* if the usage has only one operand then we can */
2141   if (IC_LEFT (uic) == NULL ||
2142       IC_RIGHT (uic) == NULL)
2143     goto accuse;
2144
2145   /* make sure this is on the left side if not
2146      a '+' since '+' is commutative */
2147   if (ic->op != '+' &&
2148       IC_LEFT (uic)->key != IC_RESULT (ic)->key)
2149     return;
2150
2151   /* if one of them is a literal then we can */
2152   if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
2153       (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
2154     {
2155       OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2156       return;
2157     }
2158
2159   /* if the other one is not on stack then we can */
2160   if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
2161       (IS_ITEMP (IC_RIGHT (uic)) ||
2162        (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
2163         !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
2164     goto accuse;
2165
2166   if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
2167       (IS_ITEMP (IC_LEFT (uic)) ||
2168        (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
2169         !OP_SYMBOL (IC_LEFT (uic))->onStack)))
2170     goto accuse;
2171
2172   return;
2173
2174 accuse:
2175   OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2176
2177
2178 }
2179
2180 /*-----------------------------------------------------------------*/
2181 /* packForPush - hueristics to reduce iCode for pushing            */
2182 /*-----------------------------------------------------------------*/
2183 static void
2184 packForPush (iCode * ic, eBBlock * ebp)
2185 {
2186   iCode *dic, *lic;
2187   bitVect *dbv;
2188
2189   if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
2190     return;
2191
2192   /* must have only definition & one usage */
2193   if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
2194       bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
2195     return;
2196
2197   /* find the definition */
2198   if (!(dic = hTabItemWithKey (iCodehTab,
2199                                bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
2200     return;
2201
2202   if (dic->op != '=' || POINTER_SET (dic))
2203     return;
2204
2205   /* make sure the right side does not have any definitions
2206      inbetween */
2207   dbv = OP_DEFS(IC_RIGHT(dic));
2208   for (lic = ic; lic != dic ; lic = lic->prev) {
2209           if (bitVectBitValue(dbv,lic->key)) return ;
2210   }
2211
2212   /* we now we know that it has one & only one def & use
2213      and the that the definition is an assignment */
2214   IC_LEFT (ic) = IC_RIGHT (dic);
2215
2216   remiCodeFromeBBlock (ebp, dic);
2217   hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2218 }
2219
2220 /*-----------------------------------------------------------------*/
2221 /* packRegisters - does some transformations to reduce register    */
2222 /*                   pressure                                      */
2223 /*-----------------------------------------------------------------*/
2224 static void
2225 packRegisters (eBBlock * ebp)
2226 {
2227   iCode *ic;
2228   int change = 0;
2229
2230   while (1)
2231     {
2232
2233       change = 0;
2234
2235       /* look for assignments of the form */
2236       /* iTempNN = TRueSym (someoperation) SomeOperand */
2237       /*       ....                       */
2238       /* TrueSym := iTempNN:1             */
2239       for (ic = ebp->sch; ic; ic = ic->next)
2240         {
2241
2242
2243           /* find assignment of the form TrueSym := iTempNN:1 */
2244           if (ic->op == '=' && !POINTER_SET (ic))
2245             change += packRegsForAssign (ic, ebp);
2246         }
2247
2248       if (!change)
2249         break;
2250     }
2251
2252   for (ic = ebp->sch; ic; ic = ic->next)
2253     {
2254
2255       /* if this is an itemp & result of a address of a true sym 
2256          then mark this as rematerialisable   */
2257       if (ic->op == ADDRESS_OF &&
2258           IS_ITEMP (IC_RESULT (ic)) &&
2259           IS_TRUE_SYMOP (IC_LEFT (ic)) &&
2260           bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2261           !OP_SYMBOL (IC_LEFT (ic))->onStack)
2262         {
2263
2264           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2265           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2266           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2267
2268         }
2269
2270       /* if straight assignment then carry remat flag if
2271          this is the only definition */
2272       if (ic->op == '=' &&
2273           !POINTER_SET (ic) &&
2274           IS_SYMOP (IC_RIGHT (ic)) &&
2275           OP_SYMBOL (IC_RIGHT (ic))->remat &&
2276           bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
2277         {
2278
2279           OP_SYMBOL (IC_RESULT (ic))->remat =
2280             OP_SYMBOL (IC_RIGHT (ic))->remat;
2281           OP_SYMBOL (IC_RESULT (ic))->rematiCode =
2282             OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
2283         }
2284
2285       /* if this is a +/- operation with a rematerizable 
2286          then mark this as rematerializable as well */
2287       if ((ic->op == '+' || ic->op == '-') &&
2288           (IS_SYMOP (IC_LEFT (ic)) &&
2289            IS_ITEMP (IC_RESULT (ic)) &&
2290            OP_SYMBOL (IC_LEFT (ic))->remat &&
2291            bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2292            IS_OP_LITERAL (IC_RIGHT (ic))))
2293         {
2294
2295           //int i = operandLitValue(IC_RIGHT(ic));
2296           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2297           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2298           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2299         }
2300
2301       /* mark the pointer usages */
2302       if (POINTER_SET (ic))
2303         OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
2304
2305       if (POINTER_GET (ic))
2306         OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
2307
2308       if (!SKIP_IC2 (ic))
2309         {
2310           /* if we are using a symbol on the stack
2311              then we should say ds390_ptrRegReq */
2312           if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
2313             ds390_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
2314                                  OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
2315           else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
2316             ds390_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
2317                               OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
2318           else
2319             {
2320               if (IS_SYMOP (IC_LEFT (ic)))
2321                 ds390_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
2322                                 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
2323               if (IS_SYMOP (IC_RIGHT (ic)))
2324                 ds390_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
2325                                OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
2326               if (IS_SYMOP (IC_RESULT (ic)))
2327                 ds390_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
2328                               OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
2329             }
2330         }
2331
2332 #if 0
2333       /* if the condition of an if instruction
2334          is defined in the previous instruction then
2335          mark the itemp as a conditional */
2336       if ((IS_CONDITIONAL (ic) ||
2337            (IS_BITWISE_OP(ic) && isBitwiseOptimizable(ic))) &&
2338           ic->next && ic->next->op == IFX &&
2339           isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
2340           OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2341         {
2342
2343           OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
2344           continue;
2345         }
2346 #else
2347       /* if the condition of an if instruction
2348          is defined in the previous instruction and
2349          this is the only usage then
2350          mark the itemp as a conditional */
2351       if ((IS_CONDITIONAL (ic) ||
2352            (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic))) &&
2353           ic->next && ic->next->op == IFX &&
2354           bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
2355           isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
2356           OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2357         {
2358           OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
2359           continue;
2360         }
2361 #endif
2362
2363       /* reduce for support function calls */
2364       if (ic->supportRtn || ic->op == '+' || ic->op == '-')
2365         packRegsForSupport (ic, ebp);
2366
2367       /* some cases the redundant moves can
2368          can be eliminated for return statements */
2369       if ((ic->op == RETURN || ic->op == SEND) &&
2370           !isOperandInFarSpace (IC_LEFT (ic)) &&
2371           !options.model)
2372         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2373
2374       /* if pointer set & left has a size more than
2375          one and right is not in far space */
2376       if (POINTER_SET (ic) &&
2377           !isOperandInFarSpace (IC_RIGHT (ic)) &&
2378           !OP_SYMBOL (IC_RESULT (ic))->remat &&
2379           !IS_OP_RUONLY (IC_RIGHT (ic)) &&
2380           getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
2381
2382         packRegsForOneuse (ic, IC_RESULT (ic), ebp);
2383
2384       /* if pointer get */
2385       if (POINTER_GET (ic) &&
2386           !isOperandInFarSpace (IC_RESULT (ic)) &&
2387           !OP_SYMBOL (IC_LEFT (ic))->remat &&
2388           !IS_OP_RUONLY (IC_RESULT (ic)) &&
2389           getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
2390
2391         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2392
2393
2394       /* if this is cast for intergral promotion then
2395          check if only use of  the definition of the 
2396          operand being casted/ if yes then replace
2397          the result of that arithmetic operation with 
2398          this result and get rid of the cast */
2399       if (ic->op == CAST)
2400         {
2401           sym_link *fromType = operandType (IC_RIGHT (ic));
2402           sym_link *toType = operandType (IC_LEFT (ic));
2403
2404           if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
2405               getSize (fromType) != getSize (toType) &&
2406               SPEC_USIGN (fromType) == SPEC_USIGN (toType))
2407             {
2408
2409               iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2410               if (dic)
2411                 {
2412                   if (IS_ARITHMETIC_OP (dic))
2413                     {
2414                       IC_RESULT (dic) = IC_RESULT (ic);
2415                       remiCodeFromeBBlock (ebp, ic);
2416                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2417                       OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2418                       ic = ic->prev;
2419                     }
2420                   else
2421                     OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
2422                 }
2423             }
2424           else
2425             {
2426
2427               /* if the type from and type to are the same
2428                  then if this is the only use then packit */
2429               if (checkType (operandType (IC_RIGHT (ic)),
2430                              operandType (IC_LEFT (ic))) == 1)
2431                 {
2432                   iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2433                   if (dic)
2434                     {
2435                       IC_RESULT (dic) = IC_RESULT (ic);
2436                       remiCodeFromeBBlock (ebp, ic);
2437                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2438                       OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2439                       ic = ic->prev;
2440                     }
2441                 }
2442             }
2443         }
2444
2445       /* pack for PUSH 
2446          iTempNN := (some variable in farspace) V1
2447          push iTempNN ;
2448          -------------
2449          push V1
2450        */
2451       if (ic->op == IPUSH)
2452         {
2453           packForPush (ic, ebp);
2454         }
2455
2456
2457       /* pack registers for accumulator use, when the
2458          result of an arithmetic or bit wise operation
2459          has only one use, that use is immediately following
2460          the defintion and the using iCode has only one
2461          operand or has two operands but one is literal &
2462          the result of that operation is not on stack then
2463          we can leave the result of this operation in acc:b
2464          combination */
2465       if ((IS_ARITHMETIC_OP (ic)
2466
2467            || IS_BITWISE_OP (ic)
2468
2469            || ic->op == LEFT_OP || ic->op == RIGHT_OP
2470
2471           ) &&
2472           IS_ITEMP (IC_RESULT (ic)) &&
2473           getSize (operandType (IC_RESULT (ic))) <= 2)
2474
2475         packRegsForAccUse (ic);
2476
2477     }
2478 }
2479
2480 /*-----------------------------------------------------------------*/
2481 /* assignRegisters - assigns registers to each live range as need  */
2482 /*-----------------------------------------------------------------*/
2483 void
2484 ds390_assignRegisters (eBBlock ** ebbs, int count)
2485 {
2486   iCode *ic;
2487   int i;
2488
2489   setToNull ((void *) &_G.funcrUsed);
2490   ds390_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
2491   /* if not register extentions then reduce number
2492      of registers */
2493   if (options.regExtend)
2494     ds390_nRegs = 13;
2495   else
2496     ds390_nRegs = 8;
2497
2498   /* change assignments this will remove some
2499      live ranges reducing some register pressure */
2500   for (i = 0; i < count; i++)
2501     packRegisters (ebbs[i]);
2502
2503   if (options.dump_pack)
2504     dumpEbbsToFileExt (".dumppack", ebbs, count);
2505
2506   /* first determine for each live range the number of 
2507      registers & the type of registers required for each */
2508   regTypeNum ();
2509
2510   /* and serially allocate registers */
2511   serialRegAssign (ebbs, count);
2512
2513   /* if stack was extended then tell the user */
2514   if (_G.stackExtend)
2515     {
2516 /*      werror(W_TOOMANY_SPILS,"stack", */
2517 /*             _G.stackExtend,currFunc->name,""); */
2518       _G.stackExtend = 0;
2519     }
2520
2521   if (_G.dataExtend)
2522     {
2523 /*      werror(W_TOOMANY_SPILS,"data space", */
2524 /*             _G.dataExtend,currFunc->name,""); */
2525       _G.dataExtend = 0;
2526     }
2527
2528   /* after that create the register mask
2529      for each of the instruction */
2530   createRegMask (ebbs, count);
2531
2532   /* redo that offsets for stacked automatic variables */
2533   redoStackOffsets ();
2534
2535   if (options.dump_rassgn)
2536     dumpEbbsToFileExt (".dumprassgn", ebbs, count);
2537
2538   /* do the overlaysegment stuff SDCCmem.c */
2539   doOverlays (ebbs, count);
2540
2541   /* now get back the chain */
2542   ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
2543
2544
2545   gen390Code (ic);
2546
2547   /* free up any _G.stackSpil locations allocated */
2548   applyToSet (_G.stackSpil, deallocStackSpil);
2549   _G.slocNum = 0;
2550   setToNull ((void **) &_G.stackSpil);
2551   setToNull ((void **) &_G.spiltSet);
2552   /* mark all registers as free */
2553   freeAllRegs ();
2554
2555   return;
2556 }