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