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