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