8d7f6556abbf2b2751692400d97f1a6c67851840
[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 it has a spillocation & is used less than
1242                    all other live ranges then spill this */
1243                 if (willCS) {
1244                     if (sym->usl.spillLoc) {
1245                         symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
1246                                                                          allLRs, ebbs[i], ic));
1247                         if (leastUsed && leastUsed->used > sym->used) {
1248                             spillThis (sym);
1249                             continue;
1250                         }
1251                     } else {
1252                         /* if none of the liveRanges have a spillLocation then better
1253                            to spill this one than anything else already assigned to registers */
1254                         if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
1255                             /* if this is local to this block then we might find a block spil */
1256                             if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
1257                                 spillThis (sym);
1258                                 continue;
1259                             }
1260                         }
1261                     }
1262                 }
1263                 /* if we need ptr regs for the right side
1264                    then mark it */
1265                 if (POINTER_GET (ic) && IS_SYMOP (IC_LEFT (ic))
1266                     && getSize (OP_SYMBOL (IC_LEFT (ic))->type) <= (unsigned int) PTRSIZE) {
1267                     mcs51_ptrRegReq++;
1268                     ptrRegSet = 1;
1269                 }
1270                 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic))
1271                     && SPEC_OCLS(OP_SYMBOL (IC_LEFT (ic))->etype) == idata) {
1272                     mcs51_ptrRegReq++;
1273                     ptrRegSet = 1;
1274                 }
1275                 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic))
1276                     && SPEC_OCLS(OP_SYMBOL (IC_RIGHT (ic))->etype) == idata) {
1277                     mcs51_ptrRegReq++;
1278                     ptrRegSet = 1;
1279                 }
1280                 
1281                 /* else we assign registers to it */
1282                 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1283                 _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key);
1284
1285                 for (j = 0; j < sym->nRegs; j++) {
1286                     sym->regs[j] = NULL;
1287                     if (sym->regType == REG_PTR)
1288                         sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
1289                     else
1290                       {
1291                         if (ic->op == CAST && IS_SYMOP (IC_RIGHT (ic)))
1292                           {
1293                             symbol * right = OP_SYMBOL (IC_RIGHT (ic));
1294                             
1295                             if (right->regs[j])
1296                               sym->regs[j] = allocThisReg (right->regs[j]);
1297                           }
1298                         if (!sym->regs[j])
1299                           sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
1300                       }
1301
1302                     /* if the allocation failed which means
1303                        this was spilt then break */
1304                     if (!sym->regs[j])
1305                       {
1306                         for (i=0; i < sym->nRegs ; i++ )
1307                           sym->regs[i] = NULL;
1308                         break;
1309                       }
1310                 }
1311                 
1312                 if (!POINTER_SET(ic) && !POINTER_GET(ic)) {
1313                     /* if it shares registers with operands make sure
1314                        that they are in the same position */
1315                     if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
1316                         OP_SYMBOL (IC_LEFT (ic))->nRegs) {
1317                         positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1318                                       OP_SYMBOL (IC_LEFT (ic)));
1319                     }
1320                     /* do the same for the right operand */
1321                     if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
1322                         OP_SYMBOL (IC_RIGHT (ic))->nRegs) {
1323                         positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1324                                       OP_SYMBOL (IC_RIGHT (ic)));
1325                     }
1326                 }
1327
1328                 if (ptrRegSet) {
1329                     mcs51_ptrRegReq--;
1330                     ptrRegSet = 0;
1331                 }
1332
1333             }
1334         }
1335     }
1336
1337     /* Check for and fix any problems with uninitialized operands */
1338     for (i = 0; i < count; i++)
1339       {
1340         iCode *ic;
1341
1342         if (ebbs[i]->noPath &&
1343             (ebbs[i]->entryLabel != entryLabel &&
1344              ebbs[i]->entryLabel != returnLabel))
1345             continue;
1346
1347         for (ic = ebbs[i]->sch; ic; ic = ic->next)
1348           {
1349             if (SKIP_IC2 (ic))
1350               continue;
1351
1352             if (ic->op == IFX)
1353               {
1354                 verifyRegsAssigned (IC_COND (ic), ic);
1355                 continue;
1356               }
1357
1358             if (ic->op == JUMPTABLE)
1359               {
1360                 verifyRegsAssigned (IC_JTCOND (ic), ic);
1361                 continue;
1362               }
1363
1364             verifyRegsAssigned (IC_RESULT (ic), ic);
1365             verifyRegsAssigned (IC_LEFT (ic), ic);
1366             verifyRegsAssigned (IC_RIGHT (ic), ic);
1367           }
1368       }    
1369 }
1370
1371 /*-----------------------------------------------------------------*/
1372 /* fillGaps - Try to fill in the Gaps left by Pass1                */
1373 /*-----------------------------------------------------------------*/
1374 static void fillGaps()
1375 {
1376     symbol *sym =NULL;
1377     int key =0;
1378     int pass;
1379     iCode *ic = NULL;
1380     
1381     if (getenv("DISABLE_FILL_GAPS")) return;
1382     
1383     /* look for livernages that was spilt by the allocator */
1384     for (sym = hTabFirstItem(liveRanges,&key) ; sym ; 
1385          sym = hTabNextItem(liveRanges,&key)) {
1386
1387         int i;
1388         int pdone = 0;
1389
1390         if (!sym->spillA || !sym->clashes || sym->remat) continue ;
1391
1392         /* find the liveRanges this one clashes with, that are
1393            still assigned to registers & mark the registers as used*/
1394         for ( i = 0 ; i < sym->clashes->size ; i ++) {
1395             int k;
1396             symbol *clr;
1397
1398             if (bitVectBitValue(sym->clashes,i) == 0 ||    /* those that clash with this */
1399                 bitVectBitValue(_G.totRegAssigned,i) == 0) /* and are still assigned to registers */
1400                 continue ;
1401
1402                 clr = hTabItemWithKey(liveRanges,i);
1403             assert(clr);
1404
1405             /* mark these registers as used */
1406             for (k = 0 ; k < clr->nRegs ; k++ ) 
1407                 useReg(clr->regs[k]);
1408         }
1409
1410         if (willCauseSpill(sym->nRegs,sym->regType)) {
1411             /* NOPE :( clear all registers & and continue */
1412             freeAllRegs();
1413             continue ;
1414         }
1415
1416         ic = NULL;          
1417         for (i = 0 ; i < sym->defs->size ; i++ )
1418           {
1419             if (bitVectBitValue(sym->defs,i))
1420               {
1421                 if (!(ic = hTabItemWithKey(iCodehTab,i)))
1422                   continue;
1423                 if (ic->op == CAST)
1424                   break;
1425               }
1426           }
1427
1428         D(printf("Atemping fillGaps on %s: [",sym->name));
1429         /* THERE IS HOPE !!!! */
1430         for (i=0; i < sym->nRegs ; i++ ) {
1431             if (sym->regType == REG_PTR)
1432                 sym->regs[i] = getRegPtrNoSpil ();
1433             else
1434               {
1435                 sym->regs[i] = NULL;
1436                 if (ic && ic->op == CAST && IS_SYMOP (IC_RIGHT (ic)))
1437                   {
1438                     symbol * right = OP_SYMBOL (IC_RIGHT (ic));
1439                     
1440                     if (right->regs[i])
1441                       sym->regs[i] = allocThisReg (right->regs[i]);
1442                   }
1443                 if (!sym->regs[i])
1444                   sym->regs[i] = getRegGprNoSpil ();
1445               }
1446             D(printf("%s ", sym->regs[i]->name));
1447         }
1448         D(printf("]\n"));
1449
1450         /* For all its definitions check if the registers
1451            allocated needs positioning NOTE: we can position
1452            only ONCE if more than One positioning required 
1453            then give up.
1454            We may need to perform the checks twice; once to
1455            position the registers as needed, the second to
1456            verify any register repositioning is still
1457            compatible.
1458           */
1459         sym->isspilt = 0;
1460         for (pass=0; pass<2; pass++) {
1461             D(printf(" checking definitions\n"));
1462             for (i = 0 ; i < sym->defs->size ; i++ ) {
1463                 if (bitVectBitValue(sym->defs,i)) {
1464                     if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
1465                     D(printf("  ic->seq = %d\n", ic->seq));
1466                     if (SKIP_IC(ic)) continue;
1467                     assert(isSymbolEqual(sym,OP_SYMBOL(IC_RESULT(ic)))); /* just making sure */
1468                     /* if left is assigned to registers */
1469                     if (IS_SYMOP(IC_LEFT(ic)))
1470                       {
1471                         D(printf("   left = "));
1472                         D(printOperand(IC_LEFT(ic),NULL));
1473                       }
1474                     if (IS_SYMOP(IC_LEFT(ic)) && 
1475                       bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_LEFT(ic))->key)) {
1476                         pdone += (positionRegs(sym,OP_SYMBOL(IC_LEFT(ic)))>0);
1477                     }
1478                     if (IS_SYMOP(IC_RIGHT(ic)))
1479                       {
1480                         D(printf("   right = "));
1481                         D(printOperand(IC_RIGHT(ic),NULL));
1482                       }
1483                     if (IS_SYMOP(IC_RIGHT(ic)) && 
1484                       bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RIGHT(ic))->key)) {
1485                         pdone += (positionRegs(sym,OP_SYMBOL(IC_RIGHT(ic)))>0);
1486                     }
1487                     D(printf("   pdone = %d\n", pdone));
1488                     if (pdone > 1) break;
1489                 }
1490             }
1491             D(printf(" checking uses\n"));
1492             for (i = 0 ; i < sym->uses->size ; i++ ) {
1493                 if (bitVectBitValue(sym->uses,i)) {
1494                     iCode *ic;
1495                     if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
1496                     D(printf("  ic->seq = %d\n", ic->seq));
1497                     if (SKIP_IC(ic)) continue;
1498                     if (POINTER_SET(ic) || POINTER_GET(ic)) continue ;
1499
1500                     /* if result is assigned to registers */
1501                     if (IS_SYMOP(IC_RESULT(ic)))
1502                       {
1503                         D(printf("   result = "));
1504                         D(printOperand(IC_RESULT(ic),NULL));
1505                       }
1506                     if (IS_SYMOP(IC_RESULT(ic)) && 
1507                         bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RESULT(ic))->key)) {
1508                         pdone += (positionRegs(sym,OP_SYMBOL(IC_RESULT(ic)))>0);
1509                     }
1510                     D(printf("   pdone = %d\n", pdone));
1511                     if (pdone > 1) break;
1512                 }
1513             }
1514             if (pdone == 0) break; /* second pass only if regs repositioned */
1515             if (pdone > 1) break;
1516         }
1517         D(printf(" sym->regs = ["));
1518         for (i=0; i < sym->nRegs ; i++ )
1519           D(printf("%s ", sym->regs[i]->name));
1520         D(printf("]\n"));
1521         /* had to position more than once GIVE UP */
1522         if (pdone > 1) {
1523             /* UNDO all the changes we made to try this */
1524             sym->isspilt = 1;
1525             for (i=0; i < sym->nRegs ; i++ ) {
1526                     sym->regs[i] = NULL;
1527             }
1528             freeAllRegs();
1529             D(printf ("Fill Gap gave up due to positioning for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN"));
1530             continue ;      
1531         }
1532         D(printf ("FILLED GAP for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN"));
1533         
1534         _G.totRegAssigned = bitVectSetBit(_G.totRegAssigned,sym->key);
1535         sym->isspilt = sym->spillA = 0 ;
1536         sym->usl.spillLoc->allocreq--;
1537         freeAllRegs();
1538     }
1539 }
1540
1541 /*-----------------------------------------------------------------*/
1542 /* rUmaskForOp :- returns register mask for an operand             */
1543 /*-----------------------------------------------------------------*/
1544 bitVect *
1545 mcs51_rUmaskForOp (operand * op)
1546 {
1547   bitVect *rumask;
1548   symbol *sym;
1549   int j;
1550
1551   /* only temporaries are assigned registers */
1552   if (!IS_ITEMP (op))
1553     return NULL;
1554
1555   sym = OP_SYMBOL (op);
1556
1557   /* if spilt or no registers assigned to it
1558      then nothing */
1559   if (sym->isspilt || !sym->nRegs)
1560     return NULL;
1561
1562   rumask = newBitVect (mcs51_nRegs);
1563
1564   for (j = 0; j < sym->nRegs; j++)
1565     {
1566       if (sym->regs[j]) /* EEP - debug */
1567       rumask = bitVectSetBit (rumask,
1568                               sym->regs[j]->rIdx);
1569     }
1570
1571   return rumask;
1572 }
1573
1574 /*-----------------------------------------------------------------*/
1575 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
1576 /*-----------------------------------------------------------------*/
1577 static bitVect *
1578 regsUsedIniCode (iCode * ic)
1579 {
1580   bitVect *rmask = newBitVect (mcs51_nRegs);
1581
1582   /* do the special cases first */
1583   if (ic->op == IFX)
1584     {
1585       rmask = bitVectUnion (rmask,
1586                             mcs51_rUmaskForOp (IC_COND (ic)));
1587       goto ret;
1588     }
1589
1590   /* for the jumptable */
1591   if (ic->op == JUMPTABLE)
1592     {
1593       rmask = bitVectUnion (rmask,
1594                             mcs51_rUmaskForOp (IC_JTCOND (ic)));
1595
1596       goto ret;
1597     }
1598
1599   /* of all other cases */
1600   if (IC_LEFT (ic))
1601     rmask = bitVectUnion (rmask,
1602                           mcs51_rUmaskForOp (IC_LEFT (ic)));
1603
1604
1605   if (IC_RIGHT (ic))
1606     rmask = bitVectUnion (rmask,
1607                           mcs51_rUmaskForOp (IC_RIGHT (ic)));
1608
1609   if (IC_RESULT (ic))
1610     rmask = bitVectUnion (rmask,
1611                           mcs51_rUmaskForOp (IC_RESULT (ic)));
1612
1613 ret:
1614   return rmask;
1615 }
1616
1617 /*-----------------------------------------------------------------*/
1618 /* createRegMask - for each instruction will determine the regsUsed */
1619 /*-----------------------------------------------------------------*/
1620 static void
1621 createRegMask (eBBlock ** ebbs, int count)
1622 {
1623   int i;
1624
1625   /* for all blocks */
1626   for (i = 0; i < count; i++)
1627     {
1628       iCode *ic;
1629
1630       if (ebbs[i]->noPath &&
1631           (ebbs[i]->entryLabel != entryLabel &&
1632            ebbs[i]->entryLabel != returnLabel))
1633         continue;
1634
1635       /* for all instructions */
1636       for (ic = ebbs[i]->sch; ic; ic = ic->next)
1637         {
1638
1639           int j;
1640
1641           if (SKIP_IC2 (ic) || !ic->rlive)
1642             continue;
1643
1644           /* first mark the registers used in this
1645              instruction */
1646           ic->rUsed = regsUsedIniCode (ic);
1647           _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
1648
1649           /* now create the register mask for those 
1650              registers that are in use : this is a
1651              super set of ic->rUsed */
1652           ic->rMask = newBitVect (mcs51_nRegs + 1);
1653
1654           /* for all live Ranges alive at this point */
1655           for (j = 1; j < ic->rlive->size; j++)
1656             {
1657               symbol *sym;
1658               int k;
1659
1660               /* if not alive then continue */
1661               if (!bitVectBitValue (ic->rlive, j))
1662                 continue;
1663
1664               /* find the live range we are interested in */
1665               if (!(sym = hTabItemWithKey (liveRanges, j)))
1666                 {
1667                   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1668                           "createRegMask cannot find live range");
1669                   fprintf(stderr, "\tmissing live range: key=%d\n", j);
1670                   exit (0);
1671                 }
1672
1673               /* if no register assigned to it */
1674               if (!sym->nRegs || sym->isspilt)
1675                 continue;
1676
1677               /* for all the registers allocated to it */
1678               for (k = 0; k < sym->nRegs; k++)
1679                 if (sym->regs[k])
1680                   ic->rMask =
1681                     bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
1682             }
1683         }
1684     }
1685 }
1686
1687 /*-----------------------------------------------------------------*/
1688 /* rematStr - returns the rematerialized string for a remat var    */
1689 /*-----------------------------------------------------------------*/
1690 static char *
1691 rematStr (symbol * sym)
1692 {
1693   char *s = buffer;
1694   iCode *ic = sym->rematiCode;
1695
1696   while (1)
1697     {
1698
1699       /* if plus or minus print the right hand side */
1700       if (ic->op == '+' || ic->op == '-')
1701         {
1702           sprintf (s, "0x%04x %c ", (int) operandLitValue (IC_RIGHT (ic)),
1703                    ic->op);
1704           s += strlen (s);
1705           ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1706           continue;
1707         }
1708
1709       /* cast then continue */
1710       if (IS_CAST_ICODE(ic)) {
1711           ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
1712           continue;
1713       }
1714       /* we reached the end */
1715       sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
1716       break;
1717     }
1718
1719   return buffer;
1720 }
1721
1722 /*-----------------------------------------------------------------*/
1723 /* regTypeNum - computes the type & number of registers required   */
1724 /*-----------------------------------------------------------------*/
1725 static void
1726 regTypeNum (eBBlock *ebbs)
1727 {
1728   symbol *sym;
1729   int k;
1730   iCode *ic;
1731
1732   /* for each live range do */
1733   for (sym = hTabFirstItem (liveRanges, &k); sym;
1734        sym = hTabNextItem (liveRanges, &k))
1735     {
1736
1737       /* if used zero times then no registers needed */
1738       if ((sym->liveTo - sym->liveFrom) == 0)
1739         continue;
1740
1741
1742       /* if the live range is a temporary */
1743       if (sym->isitmp)
1744         {
1745
1746           /* if the type is marked as a conditional */
1747           if (sym->regType == REG_CND)
1748             continue;
1749
1750           /* if used in return only then we don't 
1751              need registers */
1752           if (sym->ruonly || sym->accuse)
1753             {
1754               if (IS_AGGREGATE (sym->type) || sym->isptr)
1755                 sym->type = aggrToPtr (sym->type, FALSE);
1756               continue;
1757             }
1758
1759           /* if the symbol has only one definition &
1760              that definition is a get_pointer */
1761           if (bitVectnBitsOn (sym->defs) == 1 &&
1762               (ic = hTabItemWithKey (iCodehTab,
1763                                      bitVectFirstBit (sym->defs))) &&
1764               POINTER_GET (ic) &&
1765               !IS_BITVAR (sym->etype) &&
1766               (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER))
1767             {
1768
1769               if (ptrPseudoSymSafe (sym, ic))
1770                 {
1771                   ptrPseudoSymConvert (sym, ic, rematStr (OP_SYMBOL (IC_LEFT (ic))));
1772                   continue;
1773                 }
1774
1775               /* if in data space or idata space then try to
1776                  allocate pointer register */
1777
1778             }
1779
1780           /* if not then we require registers */
1781           sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
1782                         getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1783                         getSize (sym->type));
1784
1785           if (sym->nRegs > 4)
1786             {
1787               fprintf (stderr, "allocated more than 4 or 0 registers for type ");
1788               printTypeChain (sym->type, stderr);
1789               fprintf (stderr, "\n");
1790             }
1791
1792           /* determine the type of register required */
1793           if (sym->nRegs == 1 &&
1794               IS_PTR (sym->type) &&
1795               sym->uptr)
1796             sym->regType = REG_PTR;
1797           else
1798             sym->regType = REG_GPR;
1799
1800         }
1801       else
1802         /* for the first run we don't provide */
1803         /* registers for true symbols we will */
1804         /* see how things go                  */
1805         sym->nRegs = 0;
1806           }
1807
1808 }
1809
1810 /*-----------------------------------------------------------------*/
1811 /* freeAllRegs - mark all registers as free                        */
1812 /*-----------------------------------------------------------------*/
1813 static void
1814 freeAllRegs ()
1815 {
1816   int i;
1817
1818   for (i = 0; i < mcs51_nRegs; i++)
1819     regs8051[i].isFree = 1;
1820 }
1821
1822 /*-----------------------------------------------------------------*/
1823 /* deallocStackSpil - this will set the stack pointer back         */
1824 /*-----------------------------------------------------------------*/
1825 static
1826 DEFSETFUNC (deallocStackSpil)
1827 {
1828   symbol *sym = item;
1829
1830   deallocLocal (sym);
1831   return 0;
1832 }
1833
1834 /*-----------------------------------------------------------------*/
1835 /* farSpacePackable - returns the packable icode for far variables */
1836 /*-----------------------------------------------------------------*/
1837 static iCode *
1838 farSpacePackable (iCode * ic)
1839 {
1840   iCode *dic;
1841
1842   /* go thru till we find a definition for the
1843      symbol on the right */
1844   for (dic = ic->prev; dic; dic = dic->prev)
1845     {
1846       /* if the definition is a call then no */
1847       if ((dic->op == CALL || dic->op == PCALL) &&
1848           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1849         {
1850           return NULL;
1851         }
1852
1853       /* if shift by unknown amount then not */
1854       if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
1855           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1856         return NULL;
1857
1858       /* if pointer get and size > 1 */
1859       if (POINTER_GET (dic) &&
1860           getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
1861         return NULL;
1862
1863       if (POINTER_SET (dic) &&
1864           getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
1865         return NULL;
1866
1867       if (dic->op == IFX)
1868         {
1869           if (IC_COND (dic) &&
1870               IS_TRUE_SYMOP (IC_COND (dic)) &&
1871               isOperandInFarSpace (IC_COND (dic)))
1872             return NULL;
1873         }
1874       else if (dic->op == JUMPTABLE)
1875         {
1876           if (IC_JTCOND (dic) &&
1877               IS_TRUE_SYMOP (IC_JTCOND (dic)) &&
1878               isOperandInFarSpace (IC_JTCOND (dic)))
1879             return NULL;
1880         }
1881       else
1882         {
1883           /* if any three is a true symbol in far space */
1884           if (IC_RESULT (dic) &&
1885               IS_TRUE_SYMOP (IC_RESULT (dic)) &&
1886               isOperandInFarSpace (IC_RESULT (dic)))
1887             return NULL;
1888
1889           if (IC_RIGHT (dic) &&
1890               IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
1891               isOperandInFarSpace (IC_RIGHT (dic)) &&
1892               !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
1893             return NULL;
1894
1895           if (IC_LEFT (dic) &&
1896               IS_TRUE_SYMOP (IC_LEFT (dic)) &&
1897               isOperandInFarSpace (IC_LEFT (dic)) &&
1898               !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
1899             return NULL;
1900         }
1901
1902       if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
1903         {
1904           if ((dic->op == LEFT_OP ||
1905                dic->op == RIGHT_OP ||
1906                dic->op == '-') &&
1907               IS_OP_LITERAL (IC_RIGHT (dic)))
1908             return NULL;
1909           else
1910             return dic;
1911         }
1912     }
1913
1914   return NULL;
1915 }
1916
1917 /*-----------------------------------------------------------------*/
1918 /* packRegsForAssign - register reduction for assignment           */
1919 /*-----------------------------------------------------------------*/
1920 static int
1921 packRegsForAssign (iCode * ic, eBBlock * ebp)
1922 {
1923   iCode *dic, *sic;
1924
1925   if (!IS_ITEMP (IC_RIGHT (ic)) ||
1926       OP_SYMBOL (IC_RIGHT (ic))->isind ||
1927       OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
1928     {
1929       return 0;
1930     }
1931
1932   /* if the true symbol is defined in far space or on stack
1933      then we should not since this will increase register pressure */
1934   if (isOperandInFarSpace(IC_RESULT(ic)) && !farSpacePackable(ic)) {
1935     return 0;
1936   }
1937
1938   /* find the definition of iTempNN scanning backwards if we find a 
1939      a use of the true symbol in before we find the definition then 
1940      we cannot */
1941   for (dic = ic->prev; dic; dic = dic->prev)
1942     {
1943       int crossedCall = 0;
1944       
1945       /* We can pack across a function call only if it's a local */
1946       /* variable or our parameter. Never pack global variables */
1947       /* or parameters to a function we call. */
1948       if ((dic->op == CALL || dic->op == PCALL))
1949         {
1950           if (!OP_SYMBOL (IC_RESULT (ic))->ismyparm
1951               && !OP_SYMBOL (IC_RESULT (ic))->islocal)
1952             {
1953               crossedCall = 1;
1954             }
1955         }
1956
1957       if (SKIP_IC2 (dic))
1958         continue;
1959
1960       if (dic->op == IFX)
1961         {
1962           if (IS_SYMOP (IC_COND (dic)) &&
1963               (IC_COND (dic)->key == IC_RESULT (ic)->key ||
1964                IC_COND (dic)->key == IC_RIGHT (ic)->key))
1965             {
1966               dic = NULL;
1967               break;
1968             }
1969         }
1970       else
1971         {
1972           if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
1973               IS_OP_VOLATILE (IC_RESULT (dic)))
1974             {
1975               dic = NULL;
1976               break;
1977             }
1978
1979           if (IS_SYMOP (IC_RESULT (dic)) &&
1980               IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1981             {
1982               if (POINTER_SET (dic))
1983                 dic = NULL;
1984
1985               break;
1986             }
1987
1988           if (IS_SYMOP (IC_RIGHT (dic)) &&
1989               (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
1990                IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
1991             {
1992               dic = NULL;
1993               break;
1994             }
1995
1996           if (IS_SYMOP (IC_LEFT (dic)) &&
1997               (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
1998                IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
1999             {
2000               dic = NULL;
2001               break;
2002             }
2003
2004           if (IS_SYMOP (IC_RESULT (dic)) &&
2005               IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2006             {
2007               dic = NULL;
2008               break;
2009             }
2010             
2011           if (crossedCall)
2012             {
2013               dic = NULL;
2014               break;
2015             }
2016           
2017         }
2018     }
2019
2020   if (!dic)
2021     return 0;                   /* did not find */
2022
2023   /* if assignment then check that right is not a bit */
2024   if (ASSIGNMENT (ic) && !POINTER_SET (ic))
2025     {
2026       sym_link *etype = operandType (IC_RESULT (dic));
2027       if (IS_BITFIELD (etype))
2028         {
2029           /* if result is a bit too then it's ok */
2030           etype = operandType (IC_RESULT (ic));
2031           if (!IS_BITFIELD (etype))
2032             {
2033               return 0;
2034             }
2035        }
2036     }
2037 #if 0
2038   /* if assignment then check that right is not a bit */
2039   if (ASSIGNMENT (dic) && !POINTER_SET (dic))
2040     {
2041       sym_link *etype = operandType (IC_RIGHT (dic));
2042       if (IS_BITFIELD (etype))
2043         {
2044           /* if result is a bit too then it's ok */
2045           etype = operandType (IC_RESULT (dic));
2046           if (!IS_BITFIELD (etype))
2047             return 0;
2048         }
2049     }
2050 #endif
2051   /* if the result is on stack or iaccess then it must be
2052      the same atleast one of the operands */
2053   if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2054       OP_SYMBOL (IC_RESULT (ic))->iaccess)
2055     {
2056
2057       /* the operation has only one symbol
2058          operator then we can pack */
2059       if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2060           (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2061         goto pack;
2062
2063       if (!((IC_LEFT (dic) &&
2064              IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2065             (IC_RIGHT (dic) &&
2066              IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2067         return 0;
2068     }
2069 pack:
2070   /* found the definition */
2071   /* replace the result with the result of */
2072   /* this assignment and remove this assignment */
2073   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2074   ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
2075
2076   if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2077     {
2078       OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2079     }
2080   // TODO: and the otherway around?
2081
2082   /* delete from liverange table also 
2083      delete from all the points inbetween and the new
2084      one */
2085   for (sic = dic; sic != ic; sic = sic->next)
2086     {
2087       bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2088       if (IS_ITEMP (IC_RESULT (dic)))
2089         bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2090     }
2091
2092   remiCodeFromeBBlock (ebp, ic);
2093   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2094   hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2095   OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2096   return 1;
2097 }
2098
2099 /*------------------------------------------------------------------*/
2100 /* findAssignToSym : scanning backwards looks for first assig found */
2101 /*------------------------------------------------------------------*/
2102 static iCode *
2103 findAssignToSym (operand * op, iCode * ic)
2104 {
2105   iCode *dic;
2106
2107   /* This routine is used to find sequences like
2108      iTempAA = FOO;
2109      ...;  (intervening ops don't use iTempAA or modify FOO)
2110      blah = blah + iTempAA;
2111
2112      and eliminate the use of iTempAA, freeing up its register for
2113      other uses.
2114   */
2115      
2116   for (dic = ic->prev; dic; dic = dic->prev)
2117     {
2118
2119       /* if definition by assignment */
2120       if (dic->op == '=' &&
2121           !POINTER_SET (dic) &&
2122           IC_RESULT (dic)->key == op->key
2123 /*          &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2124         )
2125         break;  /* found where this temp was defined */
2126
2127       /* if we find an usage then we cannot delete it */
2128       
2129       if (dic->op == IFX)
2130         {
2131           if (IC_COND (dic) && IC_COND (dic)->key == op->key)
2132             return NULL;
2133         }
2134       else if (dic->op == JUMPTABLE)
2135         {
2136           if (IC_JTCOND (dic) && IC_JTCOND (dic)->key == op->key)
2137             return NULL;
2138         }
2139       else
2140         {
2141           if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2142             return NULL;
2143
2144           if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2145             return NULL;
2146
2147           if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2148             return NULL;
2149         }
2150     }
2151
2152   if (!dic)
2153     return NULL;   /* didn't find any assignment to op */
2154
2155   /* we are interested only if defined in far space */
2156   /* or in stack space in case of + & - */
2157   
2158   /* if assigned to a non-symbol then don't repack regs */
2159   if (!IS_SYMOP (IC_RIGHT (dic)))
2160     return NULL;
2161   
2162   /* if the symbol is volatile then we should not */
2163   if (isOperandVolatile (IC_RIGHT (dic), TRUE))
2164     return NULL;
2165   /* XXX TODO --- should we be passing FALSE to isOperandVolatile()?
2166      What does it mean for an iTemp to be volatile, anyway? Passing
2167      TRUE is more cautious but may prevent possible optimizations */
2168
2169   /* if the symbol is in far space then we should not */
2170   if (isOperandInFarSpace (IC_RIGHT (dic)))
2171     return NULL;
2172   
2173   /* for + & - operations make sure that
2174      if it is on the stack it is the same
2175      as one of the three operands */
2176   if ((ic->op == '+' || ic->op == '-') &&
2177       OP_SYMBOL (IC_RIGHT (dic))->onStack)
2178     {
2179       
2180       if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2181           IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2182           IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2183         return NULL;
2184     }
2185   
2186   /* now make sure that the right side of dic
2187      is not defined between ic & dic */
2188   if (dic)
2189     {
2190       iCode *sic = dic->next;
2191
2192       for (; sic != ic; sic = sic->next)
2193         if (IC_RESULT (sic) &&
2194             IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2195           return NULL;
2196     }
2197
2198   return dic;
2199 }
2200
2201 /*-----------------------------------------------------------------*/
2202 /* reassignAliasedSym - used by packRegsForSupport to replace      */
2203 /*                      redundant iTemp with equivalent symbol     */
2204 /*-----------------------------------------------------------------*/
2205 static void
2206 reassignAliasedSym (eBBlock *ebp, iCode *assignment, iCode *use, operand *op)
2207 {
2208   iCode *ic;
2209   unsigned oldSymKey, newSymKey;
2210
2211   oldSymKey = op->key;
2212   newSymKey = IC_RIGHT(assignment)->key;
2213
2214   /* only track live ranges of compiler-generated temporaries */
2215   if (!IS_ITEMP(IC_RIGHT(assignment)))
2216     newSymKey = 0;
2217
2218   /* update the live-value bitmaps */
2219   for (ic = assignment; ic != use; ic = ic->next) {
2220     bitVectUnSetBit (ic->rlive, oldSymKey);
2221     if (newSymKey != 0)
2222       ic->rlive = bitVectSetBit (ic->rlive, newSymKey);
2223   }
2224
2225   /* update the sym of the used operand */
2226   OP_SYMBOL(op) = OP_SYMBOL(IC_RIGHT(assignment));
2227   op->key = OP_SYMBOL(op)->key;
2228   OP_SYMBOL(op)->accuse = 0;
2229   
2230   /* update the sym's liverange */
2231   if ( OP_LIVETO(op) < ic->seq )
2232     setToRange(op, ic->seq, FALSE);
2233
2234   /* remove the assignment iCode now that its result is unused */
2235   remiCodeFromeBBlock (ebp, assignment);
2236   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(assignment))->defs, assignment->key);
2237   hTabDeleteItem (&iCodehTab, assignment->key, assignment, DELETE_ITEM, NULL);
2238 }
2239   
2240
2241 /*-----------------------------------------------------------------*/
2242 /* packRegsForSupport :- reduce some registers for support calls   */
2243 /*-----------------------------------------------------------------*/
2244 static int
2245 packRegsForSupport (iCode * ic, eBBlock * ebp)
2246 {
2247   iCode *dic;
2248   
2249   /* for the left & right operand :- look to see if the
2250      left was assigned a true symbol in far space in that
2251      case replace them */
2252
2253   if (IS_ITEMP (IC_LEFT (ic)) &&
2254       OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2255     {
2256       dic = findAssignToSym (IC_LEFT (ic), ic);
2257
2258       if (dic)
2259         {
2260           /* found it we need to remove it from the block */
2261           reassignAliasedSym (ebp, dic, ic, IC_LEFT(ic));
2262           return 1;
2263         }
2264     }
2265
2266   /* do the same for the right operand */
2267   if (IS_ITEMP (IC_RIGHT (ic)) &&
2268       OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2269     {
2270       iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2271
2272       if (dic)
2273         {
2274           /* if this is a subtraction & the result
2275              is a true symbol in far space then don't pack */
2276           if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
2277             {
2278               sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
2279               if (IN_FARSPACE (SPEC_OCLS (etype)))
2280                 return 0;
2281             }
2282           /* found it we need to remove it from the
2283              block */
2284           reassignAliasedSym (ebp, dic, ic, IC_RIGHT(ic));
2285           
2286           return 1;
2287         }
2288     }
2289
2290   return 0;
2291 }
2292
2293 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
2294
2295
2296 /*-----------------------------------------------------------------*/
2297 /* packRegsForOneuse : - will reduce some registers for single Use */
2298 /*-----------------------------------------------------------------*/
2299 static iCode *
2300 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
2301 {
2302   bitVect *uses;
2303   iCode *dic, *sic;
2304
2305   /* if returning a literal then do nothing */
2306   if (!IS_SYMOP (op))
2307     return NULL;
2308
2309   /* only upto 2 bytes since we cannot predict
2310      the usage of b, & acc */
2311   if (getSize (operandType (op)) > (fReturnSizeMCS51 - 2))
2312     return NULL;
2313
2314   if (ic->op != RETURN &&
2315       ic->op != SEND &&
2316       !POINTER_SET (ic) &&
2317       !POINTER_GET (ic))
2318     return NULL;
2319   
2320   if (ic->op == SEND && ic->argreg != 1) return NULL;
2321
2322   /* this routine will mark the a symbol as used in one 
2323      instruction use only && if the defintion is local 
2324      (ie. within the basic block) && has only one definition &&
2325      that definiion is either a return value from a 
2326      function or does not contain any variables in
2327      far space */
2328   uses = bitVectCopy (OP_USES (op));
2329   bitVectUnSetBit (uses, ic->key);      /* take away this iCode */
2330   if (!bitVectIsZero (uses))    /* has other uses */
2331     return NULL;
2332
2333   /* if it has only one defintion */
2334   if (bitVectnBitsOn (OP_DEFS (op)) > 1)
2335     return NULL;                /* has more than one definition */
2336
2337   /* get that definition */
2338   if (!(dic =
2339         hTabItemWithKey (iCodehTab,
2340                          bitVectFirstBit (OP_DEFS (op)))))
2341     return NULL;
2342
2343   /* if that only usage is a cast */
2344   if (dic->op == CAST) {
2345     /* to a bigger type */
2346     if (getSize(OP_SYM_TYPE(IC_RESULT(dic))) > 
2347         getSize(OP_SYM_TYPE(IC_RIGHT(dic)))) {
2348       /* than we can not, since we cannot predict the usage of b & acc */
2349       return NULL;
2350     }
2351   }
2352
2353   /* found the definition now check if it is local */
2354   if (dic->seq < ebp->fSeq ||
2355       dic->seq > ebp->lSeq)
2356     return NULL;                /* non-local */
2357
2358   /* now check if it is the return from
2359      a function call */
2360   if (dic->op == CALL || dic->op == PCALL)
2361     {
2362       if (ic->op != SEND && ic->op != RETURN &&
2363           !POINTER_SET(ic) && !POINTER_GET(ic))
2364         {
2365           OP_SYMBOL (op)->ruonly = 1;
2366           return dic;
2367         }
2368       dic = dic->next;
2369     }
2370
2371
2372   /* otherwise check that the definition does
2373      not contain any symbols in far space */
2374   if (isOperandInFarSpace (IC_LEFT (dic)) ||
2375       isOperandInFarSpace (IC_RIGHT (dic)) ||
2376       IS_OP_RUONLY (IC_LEFT (ic)) ||
2377       IS_OP_RUONLY (IC_RIGHT (ic)))
2378     {
2379       return NULL;
2380     }
2381
2382   /* if pointer set then make sure the pointer
2383      is one byte */
2384   if (POINTER_SET (dic) &&
2385       !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2386     return NULL;
2387
2388   if (POINTER_GET (dic) &&
2389       !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2390     return NULL;
2391
2392   sic = dic;
2393
2394   /* also make sure the intervenening instructions
2395      don't have any thing in far space */
2396   for (dic = dic->next; dic && dic != ic && sic != ic; dic = dic->next)
2397     {
2398
2399       /* if there is an intervening function call then no */
2400       if (dic->op == CALL || dic->op == PCALL)
2401         return NULL;
2402       /* if pointer set then make sure the pointer
2403          is one byte */
2404       if (POINTER_SET (dic) &&
2405           !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2406         return NULL;
2407
2408       if (POINTER_GET (dic) &&
2409           !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2410         return NULL;
2411
2412       /* if address of & the result is remat the okay */
2413       if (dic->op == ADDRESS_OF &&
2414           OP_SYMBOL (IC_RESULT (dic))->remat)
2415         continue;
2416
2417       /* if operand has size of three or more & this
2418          operation is a '*','/' or '%' then 'b' may
2419          cause a problem */
2420       if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
2421           getSize (operandType (op)) >= 3)
2422         return NULL;
2423
2424       /* if left or right or result is in far space */
2425       if (isOperandInFarSpace (IC_LEFT (dic)) ||
2426           isOperandInFarSpace (IC_RIGHT (dic)) ||
2427           isOperandInFarSpace (IC_RESULT (dic)) ||
2428           IS_OP_RUONLY (IC_LEFT (dic)) ||
2429           IS_OP_RUONLY (IC_RIGHT (dic)) ||
2430           IS_OP_RUONLY (IC_RESULT (dic)))
2431         {
2432           return NULL;
2433         }
2434       /* if left or right or result is on stack */
2435       if (isOperandOnStack(IC_LEFT(dic)) ||
2436           isOperandOnStack(IC_RIGHT(dic)) ||
2437           isOperandOnStack(IC_RESULT(dic))) {
2438         return NULL;
2439       }
2440     }
2441
2442   OP_SYMBOL (op)->ruonly = 1;
2443   return sic;
2444 }
2445
2446 /*-----------------------------------------------------------------*/
2447 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
2448 /*-----------------------------------------------------------------*/
2449 static bool
2450 isBitwiseOptimizable (iCode * ic)
2451 {
2452   sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
2453   sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
2454
2455   /* bitwise operations are considered optimizable
2456      under the following conditions (Jean-Louis VERN) 
2457
2458      x & lit
2459      bit & bit
2460      bit & x
2461      bit ^ bit
2462      bit ^ x
2463      x   ^ lit
2464      x   | lit
2465      bit | bit
2466      bit | x
2467   */
2468   if (IS_LITERAL(rtype) ||
2469       (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
2470     return TRUE;
2471   else
2472     return FALSE;
2473 }
2474
2475 /*-----------------------------------------------------------------*/
2476 /* isCommutativeOp - tests whether this op cares what order its    */
2477 /*                   operands are in                               */
2478 /*-----------------------------------------------------------------*/
2479 bool isCommutativeOp(unsigned int op)
2480 {
2481   if (op == '+' || op == '*' || op == EQ_OP ||
2482       op == '^' || op == '|' || op == BITWISEAND)
2483     return TRUE;
2484   else
2485     return FALSE;
2486 }
2487
2488 /*-----------------------------------------------------------------*/
2489 /* operandUsesAcc - determines whether the code generated for this */
2490 /*                  operand will have to use the accumulator       */
2491 /*-----------------------------------------------------------------*/
2492 bool operandUsesAcc(operand *op)
2493 {
2494   if (!op)
2495     return FALSE;
2496
2497   if (IS_SYMOP(op)) {
2498     symbol *sym = OP_SYMBOL(op);
2499     memmap *symspace;
2500
2501     if (sym->accuse)
2502       return TRUE;  /* duh! */
2503
2504     if (IN_STACK(sym->etype) || sym->onStack ||
2505         (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
2506       return TRUE;  /* acc is used to calc stack offset */
2507
2508     if (IS_ITEMP(op))
2509       {
2510         if (SPIL_LOC(op)) {
2511           sym = SPIL_LOC(op);  /* if spilled, look at spill location */
2512         } else {
2513           return FALSE;  /* more checks? */
2514         }
2515       }
2516
2517     symspace = SPEC_OCLS(sym->etype);
2518
2519     if (sym->iaccess && symspace->paged)
2520       return TRUE;  /* must fetch paged indirect sym via accumulator */
2521     
2522     if (IN_BITSPACE(symspace))
2523       return TRUE;  /* fetching bit vars uses the accumulator */
2524     
2525     if (IN_FARSPACE(symspace) || IN_CODESPACE(symspace)) 
2526       return TRUE;  /* fetched via accumulator and dptr */
2527   }
2528
2529   return FALSE;
2530 }
2531
2532 /*-----------------------------------------------------------------*/
2533 /* packRegsForAccUse - pack registers for acc use                  */
2534 /*-----------------------------------------------------------------*/
2535 static void
2536 packRegsForAccUse (iCode * ic)
2537 {
2538   iCode *uic;
2539
2540   /* if this is an aggregate, e.g. a one byte char array */
2541   if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
2542     return;
2543   }
2544
2545   /* if we are calling a reentrant function that has stack parameters */
2546   if (ic->op == CALL &&
2547        IFFUNC_ISREENT(operandType(IC_LEFT(ic))) &&
2548        FUNC_HASSTACKPARM(operandType(IC_LEFT(ic))))
2549       return;
2550
2551   if (ic->op == PCALL &&
2552        IFFUNC_ISREENT(operandType(IC_LEFT(ic))->next) &&
2553        FUNC_HASSTACKPARM(operandType(IC_LEFT(ic))->next))
2554       return;
2555
2556   /* if + or - then it has to be one byte result */
2557   if ((ic->op == '+' || ic->op == '-')
2558       && getSize (operandType (IC_RESULT (ic))) > 1)
2559     return;
2560
2561   /* if shift operation make sure right side is not a literal */
2562   if (ic->op == RIGHT_OP &&
2563       (isOperandLiteral (IC_RIGHT (ic)) ||
2564        getSize (operandType (IC_RESULT (ic))) > 1))
2565     return;
2566
2567   if (ic->op == LEFT_OP &&
2568       (isOperandLiteral (IC_RIGHT (ic)) ||
2569        getSize (operandType (IC_RESULT (ic))) > 1))
2570     return;
2571
2572   if (IS_BITWISE_OP (ic) &&
2573       getSize (operandType (IC_RESULT (ic))) > 1)
2574     return;
2575
2576
2577   /* has only one definition */
2578   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
2579     return;
2580
2581   /* has only one use */
2582   if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
2583     return;
2584
2585   /* and the usage immediately follows this iCode */
2586   if (!(uic = hTabItemWithKey (iCodehTab,
2587                                bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
2588     return;
2589
2590   if (ic->next != uic)
2591     return;
2592
2593   /* if it is a conditional branch then we definitely can */
2594   if (uic->op == IFX)
2595     goto accuse;
2596
2597   if (uic->op == JUMPTABLE)
2598     return;
2599
2600   if (POINTER_SET (uic) &&
2601       getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
2602     return;
2603
2604   /* if the usage is not is an assignment
2605      or an arithmetic / bitwise / shift operation then not */
2606   if (uic->op != '=' &&
2607       !IS_ARITHMETIC_OP (uic) &&
2608       !IS_BITWISE_OP (uic) &&
2609       uic->op != LEFT_OP &&
2610       uic->op != RIGHT_OP)
2611     return;
2612
2613   /* if used in ^ operation then make sure right is not a 
2614      literal (WIML: Why is this?) */
2615   if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
2616     return;
2617
2618   /* if shift operation make sure right side is not a literal */
2619   /* WIML: Why is this? */
2620   if (uic->op == RIGHT_OP &&
2621       (isOperandLiteral (IC_RIGHT (uic)) ||
2622        getSize (operandType (IC_RESULT (uic))) > 1))
2623     return;
2624   if (uic->op == LEFT_OP &&
2625       (isOperandLiteral (IC_RIGHT (uic)) ||
2626        getSize (operandType (IC_RESULT (uic))) > 1))
2627     return;
2628
2629   /* make sure that the result of this icode is not on the
2630      stack, since acc is used to compute stack offset */
2631 #if 0
2632   if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
2633       OP_SYMBOL (IC_RESULT (uic))->onStack)
2634     return;
2635 #else
2636   if (isOperandOnStack(IC_RESULT(uic)))
2637     return;
2638 #endif
2639
2640   /* if the usage has only one operand then we can */
2641   if (IC_LEFT (uic) == NULL ||
2642       IC_RIGHT (uic) == NULL)
2643     goto accuse;
2644
2645   /* if the other operand uses the accumulator then we cannot */
2646   if ( (IC_LEFT(uic)->key == IC_RESULT(ic)->key &&
2647         operandUsesAcc(IC_RIGHT(uic))) ||
2648        (IC_RIGHT(uic)->key == IC_RESULT(ic)->key &&
2649         operandUsesAcc(IC_LEFT(uic))) ) 
2650     return;
2651
2652   /* make sure this is on the left side if not commutative */
2653   /* except for '-', which has been written to be able to
2654      handle reversed operands */
2655   if (!(isCommutativeOp(ic->op) || ic->op == '-') &&
2656        IC_LEFT (uic)->key != IC_RESULT (ic)->key)
2657     return;
2658
2659 #if 0
2660   // this is too dangerous and need further restrictions
2661   // see bug #447547
2662
2663   /* if one of them is a literal then we can */
2664   if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
2665       (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
2666     {
2667       OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2668       return;
2669     }
2670 #endif
2671
2672 accuse:
2673   OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2674
2675 }
2676
2677 /*-----------------------------------------------------------------*/
2678 /* packForPush - hueristics to reduce iCode for pushing            */
2679 /*-----------------------------------------------------------------*/
2680 static void
2681 packForPush (iCode * ic, eBBlock ** ebpp, int blockno)
2682 {
2683   iCode *dic, *lic;
2684   bitVect *dbv;
2685   struct eBBlock * ebp=ebpp[blockno];
2686
2687   if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
2688     return;
2689
2690   /* must have only definition & one usage */
2691   if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
2692       bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
2693     return;
2694
2695   /* find the definition */
2696   if (!(dic = hTabItemWithKey (iCodehTab,
2697                                bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
2698     return;
2699
2700   if (dic->op != '=' || POINTER_SET (dic))
2701     return;
2702
2703   if (dic->seq < ebp->fSeq) { // Evelyn did this
2704     int i;
2705     for (i=0; i<blockno; i++) {
2706       if (dic->seq >= ebpp[i]->fSeq && dic->seq <= ebpp[i]->lSeq) {
2707         ebp=ebpp[i];
2708         break;
2709       }
2710     }
2711     wassert (i!=blockno); // no way to recover from here
2712   }
2713
2714   if (IS_SYMOP(IC_RIGHT(dic))) {
2715     /* make sure the right side does not have any definitions
2716        inbetween */
2717     dbv = OP_DEFS(IC_RIGHT(dic));
2718     for (lic = ic; lic && lic != dic ; lic = lic->prev) {
2719       if (bitVectBitValue(dbv,lic->key)) 
2720         return ;
2721     }
2722     /* make sure they have the same type */
2723     if (IS_SPEC(operandType(IC_LEFT(ic))))
2724     {
2725       sym_link *itype=operandType(IC_LEFT(ic));
2726       sym_link *ditype=operandType(IC_RIGHT(dic));
2727       
2728       if (SPEC_USIGN(itype)!=SPEC_USIGN(ditype) ||
2729           SPEC_LONG(itype)!=SPEC_LONG(ditype))
2730         return;
2731     }
2732     /* extend the live range of replaced operand if needed */
2733     if (OP_SYMBOL(IC_RIGHT(dic))->liveTo < ic->seq) {
2734       OP_SYMBOL(IC_RIGHT(dic))->liveTo = ic->seq;
2735     }
2736     bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2737   } 
2738
2739   /* we now we know that it has one & only one def & use
2740      and the that the definition is an assignment */
2741   ReplaceOpWithCheaperOp(&IC_LEFT (ic), IC_RIGHT (dic));
2742   remiCodeFromeBBlock (ebp, dic);
2743   hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2744 }
2745
2746 /*-----------------------------------------------------------------*/
2747 /* packRegisters - does some transformations to reduce register    */
2748 /*                   pressure                                      */
2749 /*-----------------------------------------------------------------*/
2750 static void
2751 packRegisters (eBBlock ** ebpp, int blockno)
2752 {
2753   iCode *ic;
2754   int change = 0;
2755   eBBlock *ebp=ebpp[blockno];
2756
2757   while (1)
2758     {
2759
2760       change = 0;
2761
2762       /* look for assignments of the form */
2763       /* iTempNN = TRueSym (someoperation) SomeOperand */
2764       /*       ....                       */
2765       /* TrueSym := iTempNN:1             */
2766       for (ic = ebp->sch; ic; ic = ic->next)
2767         {
2768           /* find assignment of the form TrueSym := iTempNN:1 */
2769           if (ic->op == '=' && !POINTER_SET (ic))
2770             change += packRegsForAssign (ic, ebp);
2771         }
2772
2773       if (!change)
2774         break;
2775     }
2776
2777   for (ic = ebp->sch; ic; ic = ic->next)
2778     {
2779       /* if this is an itemp & result of an address of a true sym 
2780          then mark this as rematerialisable   */
2781       if (ic->op == ADDRESS_OF &&
2782           IS_ITEMP (IC_RESULT (ic)) &&
2783           IS_TRUE_SYMOP (IC_LEFT (ic)) &&
2784           bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2785           !OP_SYMBOL (IC_LEFT (ic))->onStack)
2786         {
2787
2788           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2789           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2790           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2791
2792         }
2793
2794       /* if straight assignment then carry remat flag if
2795          this is the only definition */
2796       if (ic->op == '=' &&
2797           !POINTER_SET (ic) &&
2798           IS_SYMOP (IC_RIGHT (ic)) &&
2799           OP_SYMBOL (IC_RIGHT (ic))->remat &&
2800           !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode) &&
2801           bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
2802         {
2803
2804           OP_SYMBOL (IC_RESULT (ic))->remat =
2805             OP_SYMBOL (IC_RIGHT (ic))->remat;
2806           OP_SYMBOL (IC_RESULT (ic))->rematiCode =
2807             OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
2808         }
2809
2810       /* if cast to a generic pointer & the pointer being
2811          cast is remat, then we can remat this cast as well */
2812       if (ic->op == CAST && 
2813           IS_SYMOP(IC_RIGHT(ic)) &&
2814           OP_SYMBOL(IC_RIGHT(ic))->remat &&
2815           bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1) {
2816               sym_link *to_type = operandType(IC_LEFT(ic));
2817               sym_link *from_type = operandType(IC_RIGHT(ic));
2818               if (IS_GENPTR(to_type) && IS_PTR(from_type)) {                  
2819                       OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2820                       OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2821                       OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2822               }
2823       }
2824
2825       /* if this is a +/- operation with a rematerizable 
2826          then mark this as rematerializable as well */
2827       if ((ic->op == '+' || ic->op == '-') &&
2828           (IS_SYMOP (IC_LEFT (ic)) &&
2829            IS_ITEMP (IC_RESULT (ic)) &&
2830            IS_OP_LITERAL (IC_RIGHT (ic))) &&
2831            OP_SYMBOL (IC_LEFT (ic))->remat &&
2832           (!IS_SYMOP (IC_RIGHT (ic)) || !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode)) &&
2833            bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1)
2834         {
2835           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2836           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2837           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2838         }
2839
2840       /* mark the pointer usages */
2841       if (POINTER_SET (ic))
2842         OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
2843
2844       if (POINTER_GET (ic) &&
2845           IS_SYMOP(IC_LEFT (ic)))
2846         OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
2847
2848       if (!SKIP_IC2 (ic))
2849         {
2850           /* if we are using a symbol on the stack
2851              then we should say mcs51_ptrRegReq */
2852           if (options.useXstack && ic->parmPush
2853               && (ic->op == IPUSH || ic->op == IPOP))
2854             mcs51_ptrRegReq++;
2855           if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
2856             mcs51_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
2857                                  OP_SYMBOL (IC_COND (ic))->iaccess ||
2858                                  SPEC_OCLS(OP_SYMBOL (IC_COND (ic))->etype) == idata) ? 1 : 0);
2859           else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
2860             mcs51_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
2861                               OP_SYMBOL (IC_JTCOND (ic))->iaccess ||
2862                               SPEC_OCLS(OP_SYMBOL (IC_JTCOND (ic))->etype) == idata) ? 1 : 0);
2863           else
2864             {
2865               if (IS_SYMOP (IC_LEFT (ic)))
2866                 mcs51_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
2867                                 OP_SYMBOL (IC_LEFT (ic))->iaccess ||
2868                                 SPEC_OCLS(OP_SYMBOL (IC_LEFT (ic))->etype) == idata) ? 1 : 0);
2869               if (IS_SYMOP (IC_RIGHT (ic)))
2870                 mcs51_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
2871                                OP_SYMBOL (IC_RIGHT (ic))->iaccess ||
2872                                SPEC_OCLS(OP_SYMBOL (IC_RIGHT (ic))->etype) == idata) ? 1 : 0);
2873               if (IS_SYMOP (IC_RESULT (ic)))
2874                 mcs51_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
2875                               OP_SYMBOL (IC_RESULT (ic))->iaccess ||
2876                               SPEC_OCLS(OP_SYMBOL (IC_RESULT (ic))->etype) == idata) ? 1 : 0);
2877               if (POINTER_GET (ic) && IS_SYMOP (IC_LEFT (ic))
2878                   && getSize (OP_SYMBOL (IC_LEFT (ic))->type) <= (unsigned int) PTRSIZE)
2879                 mcs51_ptrRegReq ++;
2880               if (POINTER_SET (ic) && IS_SYMOP (IC_RESULT (ic))
2881                   && getSize (OP_SYMBOL (IC_RESULT (ic))->type) <= (unsigned int) PTRSIZE)
2882                 mcs51_ptrRegReq ++;
2883             }
2884         }
2885
2886       /* if the condition of an if instruction
2887          is defined in the previous instruction and
2888          this is the only usage then
2889          mark the itemp as a conditional */
2890       if ((IS_CONDITIONAL (ic) ||
2891            (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic))) &&
2892           ic->next && ic->next->op == IFX &&
2893           bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
2894           isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
2895           OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2896         {
2897           OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
2898           continue;
2899         }
2900
2901       /* reduce for support function calls */
2902       if (ic->supportRtn || ic->op == '+' || ic->op == '-')
2903         packRegsForSupport (ic, ebp);
2904
2905       /* some cases the redundant moves can
2906          can be eliminated for return statements */
2907       if ((ic->op == RETURN || (ic->op == SEND && ic->argreg == 1)) &&
2908           !isOperandInFarSpace (IC_LEFT (ic)) &&
2909           options.model == MODEL_SMALL) {
2910         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2911       }
2912
2913       /* if pointer set & left has a size more than
2914          one and right is not in far space */
2915       if (POINTER_SET (ic) &&
2916           !isOperandInFarSpace (IC_RIGHT (ic)) &&
2917           !OP_SYMBOL (IC_RESULT (ic))->remat &&
2918           !IS_OP_RUONLY (IC_RIGHT (ic)) &&
2919           getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
2920         packRegsForOneuse (ic, IC_RESULT (ic), ebp);
2921
2922       /* if pointer get */
2923       if (POINTER_GET (ic) &&
2924           IS_SYMOP (IC_LEFT (ic)) &&
2925           !isOperandInFarSpace (IC_RESULT (ic)) &&
2926           !OP_SYMBOL (IC_LEFT (ic))->remat &&
2927           !IS_OP_RUONLY (IC_RESULT (ic)) &&
2928           getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
2929         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2930
2931
2932       /* if this is cast for intergral promotion then
2933          check if only use of  the definition of the 
2934          operand being casted/ if yes then replace
2935          the result of that arithmetic operation with 
2936          this result and get rid of the cast */
2937       if (ic->op == CAST)
2938         {
2939           sym_link *fromType = operandType (IC_RIGHT (ic));
2940           sym_link *toType = operandType (IC_LEFT (ic));
2941
2942           if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
2943               getSize (fromType) != getSize (toType) &&
2944               SPEC_USIGN (fromType) == SPEC_USIGN (toType))
2945             {
2946
2947               iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2948               if (dic)
2949                 {
2950                   if (IS_ARITHMETIC_OP (dic))
2951                     {                  
2952                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2953                       ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
2954                       remiCodeFromeBBlock (ebp, ic);
2955                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2956                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2957                       OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2958                       ic = ic->prev;
2959                     }
2960                   else
2961                     OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
2962                 }
2963             }
2964           else
2965             {
2966
2967               /* if the type from and type to are the same
2968                  then if this is the only use then packit */
2969               if (compareType (operandType (IC_RIGHT (ic)),
2970                              operandType (IC_LEFT (ic))) == 1)
2971                 {
2972                   iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2973                   if (dic)
2974                     {
2975                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2976                       ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
2977                       remiCodeFromeBBlock (ebp, ic);
2978                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2979                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2980                       OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2981                       ic = ic->prev;
2982                     }
2983                 }
2984             }
2985         }
2986
2987       /* pack for PUSH 
2988          iTempNN := (some variable in farspace) V1
2989          push iTempNN ;
2990          -------------
2991          push V1
2992        */
2993       if (ic->op == IPUSH)
2994         {
2995           packForPush (ic, ebpp, blockno);
2996         }
2997
2998
2999       /* pack registers for accumulator use, when the
3000          result of an arithmetic or bit wise operation
3001          has only one use, that use is immediately following
3002          the defintion and the using iCode has only one
3003          operand or has two operands but one is literal &
3004          the result of that operation is not on stack then
3005          we can leave the result of this operation in acc:b
3006          combination */
3007       if ((IS_ARITHMETIC_OP (ic)
3008            || IS_CONDITIONAL(ic)
3009            || IS_BITWISE_OP (ic)
3010            || ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == CALL
3011            || (ic->op == ADDRESS_OF && isOperandOnStack (IC_LEFT (ic)))
3012           ) &&
3013           IS_ITEMP (IC_RESULT (ic)) &&
3014           getSize (operandType (IC_RESULT (ic))) <= 2)
3015
3016         packRegsForAccUse (ic);
3017     }
3018 }
3019
3020 /*-----------------------------------------------------------------*/
3021 /* assignRegisters - assigns registers to each live range as need  */
3022 /*-----------------------------------------------------------------*/
3023 void
3024 mcs51_assignRegisters (eBBlock ** ebbs, int count)
3025 {
3026   iCode *ic;
3027   int i;
3028
3029   setToNull ((void *) &_G.funcrUsed);
3030   setToNull ((void *) &_G.regAssigned);
3031   setToNull ((void *) &_G.totRegAssigned);
3032   mcs51_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3033   mcs51_nRegs = 8;
3034
3035   /* change assignments this will remove some
3036      live ranges reducing some register pressure */
3037   
3038   for (i = 0; i < count; i++)
3039     packRegisters (ebbs, i);
3040
3041   /* liveranges probably changed by register packing
3042      so we compute them again */
3043   recomputeLiveRanges (ebbs, count);
3044
3045   if (options.dump_pack)
3046     dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3047
3048   /* first determine for each live range the number of 
3049      registers & the type of registers required for each */
3050   regTypeNum (*ebbs);
3051
3052   /* and serially allocate registers */
3053   serialRegAssign (ebbs, count);
3054
3055   freeAllRegs ();
3056   //setToNull ((void *) &_G.regAssigned);
3057   //setToNull ((void *) &_G.totRegAssigned);
3058   fillGaps();
3059
3060   /* if stack was extended then tell the user */
3061   if (_G.stackExtend)
3062     {
3063 /*      werror(W_TOOMANY_SPILS,"stack", */
3064 /*             _G.stackExtend,currFunc->name,""); */
3065       _G.stackExtend = 0;
3066     }
3067
3068   if (_G.dataExtend)
3069     {
3070 /*      werror(W_TOOMANY_SPILS,"data space", */
3071 /*             _G.dataExtend,currFunc->name,""); */
3072       _G.dataExtend = 0;
3073     }
3074
3075   /* after that create the register mask
3076      for each of the instruction */
3077   createRegMask (ebbs, count);
3078
3079   /* redo that offsets for stacked automatic variables */
3080   if (currFunc) {
3081     redoStackOffsets ();
3082   }
3083
3084   /* make sure r0 & r1 are flagged as used if they might be used */
3085   /* as pointers */
3086   if (currFunc && mcs51_ptrRegReq)
3087     {
3088       currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, R0_IDX);
3089       currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, R1_IDX);
3090     }
3091
3092   if (options.dump_rassgn)
3093     {
3094       dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3095       dumpLiveRanges (DUMP_LRANGE, liveRanges);
3096     }
3097
3098   /* do the overlaysegment stuff SDCCmem.c */
3099   doOverlays (ebbs, count);
3100
3101   /* now get back the chain */
3102   ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3103
3104   gen51Code (ic);
3105
3106   /* free up any _G.stackSpil locations allocated */
3107   applyToSet (_G.stackSpil, deallocStackSpil);
3108   _G.slocNum = 0;
3109   setToNull ((void *) &_G.stackSpil);
3110   setToNull ((void *) &_G.spiltSet);
3111   /* mark all registers as free */
3112   freeAllRegs ();
3113
3114   return;
3115 }