See Changelog 1.204
[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 (IS_SYMOP (IC_LEFT (ic)) &&
1610                   OP_SYMBOL (IC_LEFT (ic))->remat &&
1611                   !IS_CAST_ICODE(OP_SYMBOL (IC_LEFT (ic))->rematiCode) &&
1612                   DCL_TYPE (aggrToPtr (operandType(IC_LEFT(ic)), FALSE)) == POINTER)
1613                 {
1614                   /* create a psuedo symbol & force a spil */
1615                   symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
1616                   psym->type = sym->type;
1617                   psym->etype = sym->etype;
1618                   strcpy (psym->rname, psym->name);
1619                   sym->isspilt = 1;
1620                   sym->usl.spillLoc = psym;
1621 #if 0 // an alternative fix for bug #480076
1622                   /* now this is a useless assignment to itself */
1623                   remiCodeFromeBBlock (ebbs, ic);
1624 #else
1625                   /* now this really is an assignment to itself, make it so;
1626                      it will be optimized out later */
1627                   ic->op='=';
1628                   ReplaceOpWithCheaperOp(&IC_RIGHT(ic), IC_RESULT(ic));
1629                   IC_LEFT(ic)=NULL;
1630 #endif
1631                   continue;
1632                 }
1633
1634               /* if in data space or idata space then try to
1635                  allocate pointer register */
1636
1637             }
1638
1639           /* if not then we require registers */
1640           sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
1641                         getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1642                         getSize (sym->type));
1643
1644           if (sym->nRegs > 4)
1645             {
1646               fprintf (stderr, "allocated more than 4 or 0 registers for type ");
1647               printTypeChain (sym->type, stderr);
1648               fprintf (stderr, "\n");
1649             }
1650
1651           /* determine the type of register required */
1652           if (sym->nRegs == 1 &&
1653               IS_PTR (sym->type) &&
1654               sym->uptr)
1655             sym->regType = REG_PTR;
1656           else
1657             sym->regType = REG_GPR;
1658
1659         }
1660       else
1661         /* for the first run we don't provide */
1662         /* registers for true symbols we will */
1663         /* see how things go                  */
1664         sym->nRegs = 0;
1665           }
1666
1667 }
1668
1669 /*-----------------------------------------------------------------*/
1670 /* freeAllRegs - mark all registers as free                        */
1671 /*-----------------------------------------------------------------*/
1672 static void
1673 freeAllRegs ()
1674 {
1675   int i;
1676
1677   for (i = 0; i < mcs51_nRegs; i++)
1678     regs8051[i].isFree = 1;
1679 }
1680
1681 /*-----------------------------------------------------------------*/
1682 /* deallocStackSpil - this will set the stack pointer back         */
1683 /*-----------------------------------------------------------------*/
1684 static
1685 DEFSETFUNC (deallocStackSpil)
1686 {
1687   symbol *sym = item;
1688
1689   deallocLocal (sym);
1690   return 0;
1691 }
1692
1693 /*-----------------------------------------------------------------*/
1694 /* farSpacePackable - returns the packable icode for far variables */
1695 /*-----------------------------------------------------------------*/
1696 static iCode *
1697 farSpacePackable (iCode * ic)
1698 {
1699   iCode *dic;
1700
1701   /* go thru till we find a definition for the
1702      symbol on the right */
1703   for (dic = ic->prev; dic; dic = dic->prev)
1704     {
1705       /* if the definition is a call then no */
1706       if ((dic->op == CALL || dic->op == PCALL) &&
1707           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1708         {
1709           return NULL;
1710         }
1711
1712       /* if shift by unknown amount then not */
1713       if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
1714           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1715         return NULL;
1716
1717       /* if pointer get and size > 1 */
1718       if (POINTER_GET (dic) &&
1719           getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
1720         return NULL;
1721
1722       if (POINTER_SET (dic) &&
1723           getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
1724         return NULL;
1725
1726       /* if any three is a true symbol in far space */
1727       if (IC_RESULT (dic) &&
1728           IS_TRUE_SYMOP (IC_RESULT (dic)) &&
1729           isOperandInFarSpace (IC_RESULT (dic)))
1730         return NULL;
1731
1732       if (IC_RIGHT (dic) &&
1733           IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
1734           isOperandInFarSpace (IC_RIGHT (dic)) &&
1735           !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
1736         return NULL;
1737
1738       if (IC_LEFT (dic) &&
1739           IS_TRUE_SYMOP (IC_LEFT (dic)) &&
1740           isOperandInFarSpace (IC_LEFT (dic)) &&
1741           !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
1742         return NULL;
1743
1744       if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
1745         {
1746           if ((dic->op == LEFT_OP ||
1747                dic->op == RIGHT_OP ||
1748                dic->op == '-') &&
1749               IS_OP_LITERAL (IC_RIGHT (dic)))
1750             return NULL;
1751           else
1752             return dic;
1753         }
1754     }
1755
1756   return NULL;
1757 }
1758
1759 /*-----------------------------------------------------------------*/
1760 /* packRegsForAssign - register reduction for assignment           */
1761 /*-----------------------------------------------------------------*/
1762 static int
1763 packRegsForAssign (iCode * ic, eBBlock * ebp)
1764 {
1765   iCode *dic, *sic;
1766
1767   if (!IS_ITEMP (IC_RIGHT (ic)) ||
1768       OP_SYMBOL (IC_RIGHT (ic))->isind ||
1769       OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
1770     {
1771       return 0;
1772     }
1773
1774
1775   /* if the true symbol is defined in far space or on stack
1776      then we should not since this will increase register pressure */
1777   if (isOperandInFarSpace(IC_RESULT(ic)) && !farSpacePackable(ic)) {
1778     return 0;
1779   }
1780
1781   /* find the definition of iTempNN scanning backwards if we find a 
1782      a use of the true symbol in before we find the definition then 
1783      we cannot */
1784   for (dic = ic->prev; dic; dic = dic->prev)
1785     {
1786       /* if there is a function call then don't pack it */
1787       if ((dic->op == CALL || dic->op == PCALL))
1788         {
1789           dic = NULL;
1790           break;
1791         }
1792
1793       if (SKIP_IC2 (dic))
1794         continue;
1795
1796       if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
1797           IS_OP_VOLATILE (IC_RESULT (dic)))
1798         {
1799           dic = NULL;
1800           break;
1801         }
1802
1803       if (IS_SYMOP (IC_RESULT (dic)) &&
1804           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1805         {
1806           if (POINTER_SET (dic))
1807             dic = NULL;
1808
1809           break;
1810         }
1811
1812       if (IS_SYMOP (IC_RIGHT (dic)) &&
1813           (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
1814            IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
1815         {
1816           dic = NULL;
1817           break;
1818         }
1819
1820       if (IS_SYMOP (IC_LEFT (dic)) &&
1821           (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
1822            IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
1823         {
1824           dic = NULL;
1825           break;
1826         }
1827
1828       if (POINTER_SET (dic) &&
1829           IC_RESULT (dic)->key == IC_RESULT (ic)->key)
1830         {
1831           dic = NULL;
1832           break;
1833         }
1834     }
1835
1836   if (!dic)
1837     return 0;                   /* did not find */
1838
1839   /* if assignment then check that right is not a bit */
1840   if (ASSIGNMENT (dic) && !POINTER_SET (dic))
1841     {
1842       sym_link *etype = operandType (IC_RIGHT (dic));
1843       if (IS_BITFIELD (etype))
1844         return 0;
1845     }
1846   /* if the result is on stack or iaccess then it must be
1847      the same atleast one of the operands */
1848   if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
1849       OP_SYMBOL (IC_RESULT (ic))->iaccess)
1850     {
1851
1852       /* the operation has only one symbol
1853          operator then we can pack */
1854       if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
1855           (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
1856         goto pack;
1857
1858       if (!((IC_LEFT (dic) &&
1859              IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
1860             (IC_RIGHT (dic) &&
1861              IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
1862         return 0;
1863     }
1864 pack:
1865   /* found the definition */
1866   /* replace the result with the result of */
1867   /* this assignment and remove this assignment */
1868   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1869   ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
1870
1871   if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
1872     {
1873       OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
1874     }
1875   // jwk: and the otherway around?
1876
1877   /* delete from liverange table also 
1878      delete from all the points inbetween and the new
1879      one */
1880   for (sic = dic; sic != ic; sic = sic->next)
1881     {
1882       bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
1883       if (IS_ITEMP (IC_RESULT (dic)))
1884         bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
1885     }
1886
1887   remiCodeFromeBBlock (ebp, ic);
1888   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
1889   hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
1890   OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
1891   return 1;
1892 }
1893
1894 /*------------------------------------------------------------------*/
1895 /* findAssignToSym : scanning backwards looks for first assig found */
1896 /*------------------------------------------------------------------*/
1897 static iCode *
1898 findAssignToSym (operand * op, iCode * ic)
1899 {
1900   iCode *dic;
1901
1902   /* This routine is used to find sequences like
1903      iTempAA = FOO;
1904      ...;  (intervening ops don't use iTempAA or modify FOO)
1905      blah = blah + iTempAA;
1906
1907      and eliminate the use of iTempAA, freeing up its register for
1908      other uses.
1909   */
1910      
1911
1912   for (dic = ic->prev; dic; dic = dic->prev)
1913     {
1914
1915       /* if definition by assignment */
1916       if (dic->op == '=' &&
1917           !POINTER_SET (dic) &&
1918           IC_RESULT (dic)->key == op->key
1919 /*          &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) */
1920         )
1921         break;  /* found where this temp was defined */
1922
1923       /* if we find an usage then we cannot delete it */
1924       if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
1925         return NULL;
1926
1927       if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
1928         return NULL;
1929
1930       if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
1931         return NULL;
1932     }
1933
1934   if (!dic)
1935     return NULL;   /* didn't find any assignment to op */
1936
1937   LRH(printf ("findAssignToSym: %s\n", OP_SYMBOL(IC_RESULT(dic))->name));
1938   /* we are interested only if defined in far space */
1939   /* or in stack space in case of + & - */
1940   
1941   /* if assigned to a non-symbol then don't repack regs */
1942   if (!IS_SYMOP (IC_RIGHT (dic)))
1943     return NULL;
1944   
1945   /* if the symbol is volatile then we should not */
1946   if (isOperandVolatile (IC_RIGHT (dic), TRUE))
1947     return NULL;
1948   /* XXX TODO --- should we be passing FALSE to isOperandVolatile()?
1949      What does it mean for an iTemp to be volatile, anyway? Passing
1950      TRUE is more cautious but may prevent possible optimizations */
1951
1952   /* if the symbol is in far space then we should not */
1953   if (isOperandInFarSpace (IC_RIGHT (dic)))
1954     return NULL;
1955   
1956   /* for + & - operations make sure that
1957      if it is on the stack it is the same
1958      as one of the three operands */
1959   if ((ic->op == '+' || ic->op == '-') &&
1960       OP_SYMBOL (IC_RIGHT (dic))->onStack)
1961     {
1962       
1963       if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
1964           IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
1965           IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
1966         return NULL;
1967     }
1968   
1969   /* now make sure that the right side of dic
1970      is not defined between ic & dic */
1971   if (dic)
1972     {
1973       iCode *sic = dic->next;
1974
1975       for (; sic != ic; sic = sic->next)
1976         if (IC_RESULT (sic) &&
1977             IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
1978           return NULL;
1979     }
1980
1981   return dic;
1982 }
1983
1984 /*-----------------------------------------------------------------*/
1985 /* reassignAliasedSym - used by packRegsForSupport to replace      */
1986 /*                      redundant iTemp with equivalent symbol     */
1987 /*-----------------------------------------------------------------*/
1988 static void
1989 reassignAliasedSym (eBBlock *ebp, iCode *assignment, iCode *use, operand *op)
1990 {
1991   iCode *ic;
1992   unsigned oldSymKey, newSymKey;
1993
1994   oldSymKey = op->key;
1995   newSymKey = IC_RIGHT(assignment)->key;
1996
1997   /* only track live ranges of compiler-generated temporaries */
1998   if (!IS_ITEMP(IC_RIGHT(assignment)))
1999     newSymKey = 0;
2000
2001   /* update the live-value bitmaps */
2002   for (ic = assignment; ic != use; ic = ic->next) {
2003     bitVectUnSetBit (ic->rlive, oldSymKey);
2004     if (newSymKey != 0)
2005       ic->rlive = bitVectSetBit (ic->rlive, newSymKey);
2006   }
2007
2008   /* update the sym of the used operand */
2009   OP_SYMBOL(op) = OP_SYMBOL(IC_RIGHT(assignment));
2010   op->key = OP_SYMBOL(op)->key;
2011
2012   /* update the sym's liverange */
2013   if ( OP_LIVETO(op) < ic->seq )
2014     setToRange(op, ic->seq, FALSE);
2015
2016   /* remove the assignment iCode now that its result is unused */
2017   remiCodeFromeBBlock (ebp, assignment);
2018   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(assignment))->defs, assignment->key);
2019   hTabDeleteItem (&iCodehTab, assignment->key, assignment, DELETE_ITEM, NULL);
2020 }
2021   
2022
2023 /*-----------------------------------------------------------------*/
2024 /* packRegsForSupport :- reduce some registers for support calls   */
2025 /*-----------------------------------------------------------------*/
2026 static int
2027 packRegsForSupport (iCode * ic, eBBlock * ebp)
2028 {
2029   iCode *dic;
2030   
2031   /* for the left & right operand :- look to see if the
2032      left was assigned a true symbol in far space in that
2033      case replace them */
2034
2035   if (IS_ITEMP (IC_LEFT (ic)) &&
2036       OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2037     {
2038       dic = findAssignToSym (IC_LEFT (ic), ic);
2039
2040       if (dic)
2041         {
2042           /* found it we need to remove it from the block */
2043           reassignAliasedSym (ebp, dic, ic, IC_LEFT(ic));
2044           return 1;
2045         }
2046     }
2047
2048   /* do the same for the right operand */
2049   if (IS_ITEMP (IC_RIGHT (ic)) &&
2050       OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2051     {
2052       iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2053
2054       if (dic)
2055         {
2056           /* if this is a subtraction & the result
2057              is a true symbol in far space then don't pack */
2058           if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
2059             {
2060               sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
2061               if (IN_FARSPACE (SPEC_OCLS (etype)))
2062                 return 0;
2063             }
2064           /* found it we need to remove it from the
2065              block */
2066           reassignAliasedSym (ebp, dic, ic, IC_RIGHT(ic));
2067           
2068           return 1;
2069         }
2070     }
2071
2072   return 0;
2073 }
2074
2075 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
2076
2077
2078 /*-----------------------------------------------------------------*/
2079 /* packRegsForOneuse : - will reduce some registers for single Use */
2080 /*-----------------------------------------------------------------*/
2081 static iCode *
2082 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
2083 {
2084   bitVect *uses;
2085   iCode *dic, *sic;
2086
2087   /* if returning a literal then do nothing */
2088   if (!IS_SYMOP (op))
2089     return NULL;
2090
2091   /* only upto 2 bytes since we cannot predict
2092      the usage of b, & acc */
2093   if (getSize (operandType (op)) > (fReturnSizeMCS51 - 2))
2094     return NULL;
2095
2096   if (ic->op != RETURN &&
2097       ic->op != SEND &&
2098       !POINTER_SET (ic) &&
2099       !POINTER_GET (ic))
2100     return NULL;
2101   
2102   if (ic->op == SEND && ic->argreg != 1) return NULL;
2103
2104   /* this routine will mark the a symbol as used in one 
2105      instruction use only && if the defintion is local 
2106      (ie. within the basic block) && has only one definition &&
2107      that definiion is either a return value from a 
2108      function or does not contain any variables in
2109      far space */
2110   uses = bitVectCopy (OP_USES (op));
2111   bitVectUnSetBit (uses, ic->key);      /* take away this iCode */
2112   if (!bitVectIsZero (uses))    /* has other uses */
2113     return NULL;
2114
2115   /* if it has only one defintion */
2116   if (bitVectnBitsOn (OP_DEFS (op)) > 1)
2117     return NULL;                /* has more than one definition */
2118
2119   /* get that definition */
2120   if (!(dic =
2121         hTabItemWithKey (iCodehTab,
2122                          bitVectFirstBit (OP_DEFS (op)))))
2123     return NULL;
2124
2125   LRH(printf ("packRegsForOneUse: %s\n", OP_SYMBOL(op)->name));
2126   /* if that only usage is a cast */
2127   if (dic->op == CAST) {
2128     /* to a bigger type */
2129     if (getSize(OP_SYM_TYPE(IC_RESULT(dic))) > 
2130         getSize(OP_SYM_TYPE(IC_RIGHT(dic)))) {
2131       /* than we can not, since we cannot predict the usage of b & acc */
2132       return NULL;
2133     }
2134   }
2135
2136   /* found the definition now check if it is local */
2137   if (dic->seq < ebp->fSeq ||
2138       dic->seq > ebp->lSeq)
2139     return NULL;                /* non-local */
2140
2141   /* now check if it is the return from
2142      a function call */
2143   if (dic->op == CALL || dic->op == PCALL)
2144     {
2145       if (ic->op != SEND && ic->op != RETURN &&
2146           !POINTER_SET(ic) && !POINTER_GET(ic))
2147         {
2148           OP_SYMBOL (op)->ruonly = 1;
2149           return dic;
2150         }
2151       dic = dic->next;
2152     }
2153
2154
2155   /* otherwise check that the definition does
2156      not contain any symbols in far space */
2157   if (isOperandInFarSpace (IC_LEFT (dic)) ||
2158       isOperandInFarSpace (IC_RIGHT (dic)) ||
2159       IS_OP_RUONLY (IC_LEFT (ic)) ||
2160       IS_OP_RUONLY (IC_RIGHT (ic)))
2161     {
2162       return NULL;
2163     }
2164
2165   /* if pointer set then make sure the pointer
2166      is one byte */
2167   if (POINTER_SET (dic) &&
2168       !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2169     return NULL;
2170
2171   if (POINTER_GET (dic) &&
2172       !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2173     return NULL;
2174
2175   sic = dic;
2176
2177   /* also make sure the intervenening instructions
2178      don't have any thing in far space */
2179   for (dic = dic->next; dic && dic != ic && sic != ic; dic = dic->next)
2180     {
2181
2182       /* if there is an intervening function call then no */
2183       if (dic->op == CALL || dic->op == PCALL)
2184         return NULL;
2185       /* if pointer set then make sure the pointer
2186          is one byte */
2187       if (POINTER_SET (dic) &&
2188           !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2189         return NULL;
2190
2191       if (POINTER_GET (dic) &&
2192           !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2193         return NULL;
2194
2195       /* if address of & the result is remat the okay */
2196       if (dic->op == ADDRESS_OF &&
2197           OP_SYMBOL (IC_RESULT (dic))->remat)
2198         continue;
2199
2200       /* if operand has size of three or more & this
2201          operation is a '*','/' or '%' then 'b' may
2202          cause a problem */
2203       if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
2204           getSize (operandType (op)) >= 3)
2205         return NULL;
2206
2207       /* if left or right or result is in far space */
2208       if (isOperandInFarSpace (IC_LEFT (dic)) ||
2209           isOperandInFarSpace (IC_RIGHT (dic)) ||
2210           isOperandInFarSpace (IC_RESULT (dic)) ||
2211           IS_OP_RUONLY (IC_LEFT (dic)) ||
2212           IS_OP_RUONLY (IC_RIGHT (dic)) ||
2213           IS_OP_RUONLY (IC_RESULT (dic)))
2214         {
2215           return NULL;
2216         }
2217       /* if left or right or result is on stack */
2218       if (isOperandOnStack(IC_LEFT(dic)) ||
2219           isOperandOnStack(IC_RIGHT(dic)) ||
2220           isOperandOnStack(IC_RESULT(dic))) {
2221         return NULL;
2222       }
2223     }
2224
2225   OP_SYMBOL (op)->ruonly = 1;
2226   return sic;
2227 }
2228
2229 /*-----------------------------------------------------------------*/
2230 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
2231 /*-----------------------------------------------------------------*/
2232 static bool
2233 isBitwiseOptimizable (iCode * ic)
2234 {
2235   sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
2236   sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
2237
2238   /* bitwise operations are considered optimizable
2239      under the following conditions (Jean-Louis VERN) 
2240
2241      x & lit
2242      bit & bit
2243      bit & x
2244      bit ^ bit
2245      bit ^ x
2246      x   ^ lit
2247      x   | lit
2248      bit | bit
2249      bit | x
2250   */
2251   if (IS_LITERAL(rtype) ||
2252       (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
2253     return TRUE;
2254   else
2255     return FALSE;
2256 }
2257
2258 /*-----------------------------------------------------------------*/
2259 /* isCommutativeOp - tests whether this op cares what order its    */
2260 /*                   operands are in                               */
2261 /*-----------------------------------------------------------------*/
2262 bool isCommutativeOp(unsigned int op)
2263 {
2264   if (op == '+' || op == '*' || op == EQ_OP ||
2265       op == '^' || op == '|' || op == BITWISEAND)
2266     return TRUE;
2267   else
2268     return FALSE;
2269 }
2270
2271 /*-----------------------------------------------------------------*/
2272 /* operandUsesAcc - determines whether the code generated for this */
2273 /*                  operand will have to use the accumulator       */
2274 /*-----------------------------------------------------------------*/
2275 bool operandUsesAcc(operand *op)
2276 {
2277   if (!op)
2278     return FALSE;
2279
2280   if (IS_SYMOP(op)) {
2281     symbol *sym = OP_SYMBOL(op);
2282     memmap *symspace;
2283
2284     if (sym->accuse)
2285       return TRUE;  /* duh! */
2286
2287     if (IN_STACK(sym->etype) || sym->onStack ||
2288         (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
2289       return TRUE;  /* acc is used to calc stack offset */
2290
2291     if (IS_ITEMP(op))
2292       {
2293         if (SPIL_LOC(op)) {
2294           sym = SPIL_LOC(op);  /* if spilled, look at spill location */
2295         } else {
2296           return FALSE;  /* more checks? */
2297         }
2298       }
2299
2300     symspace = SPEC_OCLS(sym->etype);
2301
2302     if (sym->iaccess && symspace->paged)
2303       return TRUE;  /* must fetch paged indirect sym via accumulator */
2304     
2305     if (IN_BITSPACE(symspace))
2306       return TRUE;  /* fetching bit vars uses the accumulator */
2307     
2308     if (IN_FARSPACE(symspace) || IN_CODESPACE(symspace)) 
2309       return TRUE;  /* fetched via accumulator and dptr */
2310   }
2311
2312   return FALSE;
2313 }
2314
2315 /*-----------------------------------------------------------------*/
2316 /* packRegsForAccUse - pack registers for acc use                  */
2317 /*-----------------------------------------------------------------*/
2318 static void
2319 packRegsForAccUse (iCode * ic)
2320 {
2321   iCode *uic;
2322
2323   /* if this is an aggregate, e.g. a one byte char array */
2324   if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
2325     return;
2326   }
2327
2328   /* if we are calling a reentrant function that has stack parameters */
2329   if (ic->op == CALL &&
2330        IFFUNC_ISREENT(operandType(IC_LEFT(ic))) &&
2331        FUNC_HASSTACKPARM(operandType(IC_LEFT(ic))))
2332       return;
2333
2334   if (ic->op == PCALL &&
2335        IFFUNC_ISREENT(operandType(IC_LEFT(ic))->next) &&
2336        FUNC_HASSTACKPARM(operandType(IC_LEFT(ic))->next))
2337       return;
2338
2339   /* if + or - then it has to be one byte result */
2340   if ((ic->op == '+' || ic->op == '-')
2341       && getSize (operandType (IC_RESULT (ic))) > 1)
2342     return;
2343
2344   /* if shift operation make sure right side is not a literal */
2345   if (ic->op == RIGHT_OP &&
2346       (isOperandLiteral (IC_RIGHT (ic)) ||
2347        getSize (operandType (IC_RESULT (ic))) > 1))
2348     return;
2349
2350   if (ic->op == LEFT_OP &&
2351       (isOperandLiteral (IC_RIGHT (ic)) ||
2352        getSize (operandType (IC_RESULT (ic))) > 1))
2353     return;
2354
2355   if (IS_BITWISE_OP (ic) &&
2356       getSize (operandType (IC_RESULT (ic))) > 1)
2357     return;
2358
2359
2360   /* has only one definition */
2361   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
2362     return;
2363
2364   /* has only one use */
2365   if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
2366     return;
2367
2368   /* and the usage immediately follows this iCode */
2369   if (!(uic = hTabItemWithKey (iCodehTab,
2370                                bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
2371     return;
2372
2373   if (ic->next != uic)
2374     return;
2375
2376   /* if it is a conditional branch then we definitely can */
2377   if (uic->op == IFX)
2378     goto accuse;
2379
2380   if (uic->op == JUMPTABLE)
2381     return;
2382
2383   if (POINTER_SET (uic) &&
2384       getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
2385     return;
2386
2387   /* if the usage is not is an assignment
2388      or an arithmetic / bitwise / shift operation then not */
2389   if (uic->op != '=' &&
2390       !IS_ARITHMETIC_OP (uic) &&
2391       !IS_BITWISE_OP (uic) &&
2392       uic->op != LEFT_OP &&
2393       uic->op != RIGHT_OP)
2394     return;
2395
2396   /* if used in ^ operation then make sure right is not a 
2397      literal (WIML: Why is this?) */
2398   if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
2399     return;
2400
2401   /* if shift operation make sure right side is not a literal */
2402   /* WIML: Why is this? */
2403   if (uic->op == RIGHT_OP &&
2404       (isOperandLiteral (IC_RIGHT (uic)) ||
2405        getSize (operandType (IC_RESULT (uic))) > 1))
2406     return;
2407   if (uic->op == LEFT_OP &&
2408       (isOperandLiteral (IC_RIGHT (uic)) ||
2409        getSize (operandType (IC_RESULT (uic))) > 1))
2410     return;
2411
2412   /* make sure that the result of this icode is not on the
2413      stack, since acc is used to compute stack offset */
2414 #if 0
2415   if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
2416       OP_SYMBOL (IC_RESULT (uic))->onStack)
2417     return;
2418 #else
2419   if (isOperandOnStack(IC_RESULT(uic)))
2420     return;
2421 #endif
2422
2423   /* if the usage has only one operand then we can */
2424   if (IC_LEFT (uic) == NULL ||
2425       IC_RIGHT (uic) == NULL)
2426     goto accuse;
2427
2428   /* if the other operand uses the accumulator then we cannot */
2429   if ( (IC_LEFT(uic)->key == IC_RESULT(ic)->key &&
2430         operandUsesAcc(IC_RIGHT(uic))) ||
2431        (IC_RIGHT(uic)->key == IC_RESULT(ic)->key &&
2432         operandUsesAcc(IC_LEFT(uic))) ) 
2433     return;
2434
2435   /* make sure this is on the left side if not commutative */
2436   /* except for '-', which has been written to be able to
2437      handle reversed operands */
2438   if (!(isCommutativeOp(ic->op) || ic->op == '-') &&
2439        IC_LEFT (uic)->key != IC_RESULT (ic)->key)
2440     return;
2441
2442 #if 0
2443   // this is too dangerous and need further restrictions
2444   // see bug #447547
2445
2446   /* if one of them is a literal then we can */
2447   if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
2448       (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
2449     {
2450       OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2451       return;
2452     }
2453 #endif
2454
2455 accuse:
2456   OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2457
2458 }
2459
2460 /*-----------------------------------------------------------------*/
2461 /* packForPush - hueristics to reduce iCode for pushing            */
2462 /*-----------------------------------------------------------------*/
2463 static void
2464 packForPush (iCode * ic, eBBlock ** ebpp, int blockno)
2465 {
2466   iCode *dic, *lic;
2467   bitVect *dbv;
2468   struct eBBlock * ebp=ebpp[blockno];
2469
2470   if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
2471     return;
2472
2473   /* must have only definition & one usage */
2474   if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
2475       bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
2476     return;
2477
2478   /* find the definition */
2479   if (!(dic = hTabItemWithKey (iCodehTab,
2480                                bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
2481     return;
2482
2483   if (dic->op != '=' || POINTER_SET (dic))
2484     return;
2485
2486   if (dic->seq < ebp->fSeq) { // Evelyn did this
2487     int i;
2488     for (i=0; i<blockno; i++) {
2489       if (dic->seq >= ebpp[i]->fSeq && dic->seq <= ebpp[i]->lSeq) {
2490         ebp=ebpp[i];
2491         break;
2492       }
2493     }
2494     wassert (i!=blockno); // no way to recover from here
2495   }
2496
2497   if (IS_SYMOP(IC_RIGHT(dic))) {
2498     /* make sure the right side does not have any definitions
2499        inbetween */
2500     dbv = OP_DEFS(IC_RIGHT(dic));
2501     for (lic = ic; lic && lic != dic ; lic = lic->prev) {
2502       if (bitVectBitValue(dbv,lic->key)) 
2503         return ;
2504     }
2505     /* make sure they have the same type */
2506     {
2507       sym_link *itype=operandType(IC_LEFT(ic));
2508       sym_link *ditype=operandType(IC_RIGHT(dic));
2509       
2510       if (SPEC_USIGN(itype)!=SPEC_USIGN(ditype) ||
2511           SPEC_LONG(itype)!=SPEC_LONG(ditype))
2512         return;
2513     }
2514     /* extend the live range of replaced operand if needed */
2515     if (OP_SYMBOL(IC_RIGHT(dic))->liveTo < ic->seq) {
2516       OP_SYMBOL(IC_RIGHT(dic))->liveTo = ic->seq;
2517     }
2518     bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2519   } 
2520
2521   /* we now we know that it has one & only one def & use
2522      and the that the definition is an assignment */
2523   ReplaceOpWithCheaperOp(&IC_LEFT (ic), IC_RIGHT (dic));
2524   remiCodeFromeBBlock (ebp, dic);
2525   hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2526 }
2527
2528 /*-----------------------------------------------------------------*/
2529 /* packRegisters - does some transformations to reduce register    */
2530 /*                   pressure                                      */
2531 /*-----------------------------------------------------------------*/
2532 static void
2533 packRegisters (eBBlock ** ebpp, int blockno)
2534 {
2535   iCode *ic;
2536   int change = 0;
2537   eBBlock *ebp=ebpp[blockno];
2538
2539   while (1)
2540     {
2541
2542       change = 0;
2543
2544       /* look for assignments of the form */
2545       /* iTempNN = TRueSym (someoperation) SomeOperand */
2546       /*       ....                       */
2547       /* TrueSym := iTempNN:1             */
2548       for (ic = ebp->sch; ic; ic = ic->next)
2549         {
2550           /* find assignment of the form TrueSym := iTempNN:1 */
2551           if (ic->op == '=' && !POINTER_SET (ic))
2552             change += packRegsForAssign (ic, ebp);
2553         }
2554
2555       if (!change)
2556         break;
2557     }
2558
2559   for (ic = ebp->sch; ic; ic = ic->next)
2560     {
2561       /* if this is an itemp & result of an address of a true sym 
2562          then mark this as rematerialisable   */
2563       if (ic->op == ADDRESS_OF &&
2564           IS_ITEMP (IC_RESULT (ic)) &&
2565           IS_TRUE_SYMOP (IC_LEFT (ic)) &&
2566           bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2567           !OP_SYMBOL (IC_LEFT (ic))->onStack)
2568         {
2569
2570           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2571           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2572           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2573
2574         }
2575
2576       /* if straight assignment then carry remat flag if
2577          this is the only definition */
2578       if (ic->op == '=' &&
2579           !POINTER_SET (ic) &&
2580           IS_SYMOP (IC_RIGHT (ic)) &&
2581           OP_SYMBOL (IC_RIGHT (ic))->remat &&
2582           !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode) &&
2583           bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
2584         {
2585
2586           OP_SYMBOL (IC_RESULT (ic))->remat =
2587             OP_SYMBOL (IC_RIGHT (ic))->remat;
2588           OP_SYMBOL (IC_RESULT (ic))->rematiCode =
2589             OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
2590         }
2591
2592       /* if cast to a generic pointer & the pointer being
2593          cast is remat, then we can remat this cast as well */
2594       if (ic->op == CAST && 
2595           IS_SYMOP(IC_RIGHT(ic)) &&
2596           OP_SYMBOL(IC_RIGHT(ic))->remat ) {
2597               sym_link *to_type = operandType(IC_LEFT(ic));
2598               sym_link *from_type = operandType(IC_RIGHT(ic));
2599               if (IS_GENPTR(to_type) && IS_PTR(from_type)) {                  
2600                       OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2601                       OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2602                       OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2603               }
2604       }
2605
2606       /* if this is a +/- operation with a rematerizable 
2607          then mark this as rematerializable as well */
2608       if ((ic->op == '+' || ic->op == '-') &&
2609           (IS_SYMOP (IC_LEFT (ic)) &&
2610            IS_ITEMP (IC_RESULT (ic)) &&
2611            IS_OP_LITERAL (IC_RIGHT (ic))) &&
2612            OP_SYMBOL (IC_LEFT (ic))->remat &&
2613           (!IS_SYMOP (IC_RIGHT (ic)) || !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode)) &&
2614            bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1)
2615         {
2616           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2617           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2618           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2619         }
2620
2621       /* mark the pointer usages */
2622       if (POINTER_SET (ic))
2623         OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
2624
2625       if (POINTER_GET (ic) &&
2626           IS_SYMOP(IC_LEFT (ic)))
2627         OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
2628
2629       if (!SKIP_IC2 (ic))
2630         {
2631           /* if we are using a symbol on the stack
2632              then we should say mcs51_ptrRegReq */
2633           if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
2634             mcs51_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
2635                                  OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
2636           else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
2637             mcs51_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
2638                               OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
2639           else
2640             {
2641               if (IS_SYMOP (IC_LEFT (ic)))
2642                 mcs51_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
2643                                 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
2644               if (IS_SYMOP (IC_RIGHT (ic)))
2645                 mcs51_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
2646                                OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
2647               if (IS_SYMOP (IC_RESULT (ic)))
2648                 mcs51_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
2649                               OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
2650             }
2651         }
2652
2653       /* if the condition of an if instruction
2654          is defined in the previous instruction and
2655          this is the only usage then
2656          mark the itemp as a conditional */
2657       if ((IS_CONDITIONAL (ic) ||
2658            (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic))) &&
2659           ic->next && ic->next->op == IFX &&
2660           bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
2661           isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
2662           OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2663         {
2664           OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
2665           continue;
2666         }
2667
2668       /* reduce for support function calls */
2669       if (ic->supportRtn || ic->op == '+' || ic->op == '-')
2670         packRegsForSupport (ic, ebp);
2671
2672       /* some cases the redundant moves can
2673          can be eliminated for return statements */
2674       if ((ic->op == RETURN || (ic->op == SEND && ic->argreg == 1)) &&
2675           !isOperandInFarSpace (IC_LEFT (ic)) &&
2676           options.model == MODEL_SMALL) {
2677         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2678       }
2679
2680       /* if pointer set & left has a size more than
2681          one and right is not in far space */
2682       if (POINTER_SET (ic) &&
2683           !isOperandInFarSpace (IC_RIGHT (ic)) &&
2684           !OP_SYMBOL (IC_RESULT (ic))->remat &&
2685           !IS_OP_RUONLY (IC_RIGHT (ic)) &&
2686           getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
2687         packRegsForOneuse (ic, IC_RESULT (ic), ebp);
2688
2689       /* if pointer get */
2690       if (POINTER_GET (ic) &&
2691           IS_SYMOP (IC_LEFT (ic)) &&
2692           !isOperandInFarSpace (IC_RESULT (ic)) &&
2693           !OP_SYMBOL (IC_LEFT (ic))->remat &&
2694           !IS_OP_RUONLY (IC_RESULT (ic)) &&
2695           getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
2696         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2697
2698
2699       /* if this is cast for intergral promotion then
2700          check if only use of  the definition of the 
2701          operand being casted/ if yes then replace
2702          the result of that arithmetic operation with 
2703          this result and get rid of the cast */
2704       if (ic->op == CAST)
2705         {
2706           sym_link *fromType = operandType (IC_RIGHT (ic));
2707           sym_link *toType = operandType (IC_LEFT (ic));
2708
2709           if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
2710               getSize (fromType) != getSize (toType) &&
2711               SPEC_USIGN (fromType) == SPEC_USIGN (toType))
2712             {
2713
2714               iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2715               if (dic)
2716                 {
2717                   if (IS_ARITHMETIC_OP (dic))
2718                     {                  
2719                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2720                       ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
2721                       remiCodeFromeBBlock (ebp, ic);
2722                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2723                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2724                       OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2725                       ic = ic->prev;
2726                     }
2727                   else
2728                     OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
2729                 }
2730             }
2731           else
2732             {
2733
2734               /* if the type from and type to are the same
2735                  then if this is the only use then packit */
2736               if (compareType (operandType (IC_RIGHT (ic)),
2737                              operandType (IC_LEFT (ic))) == 1)
2738                 {
2739                   iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2740                   if (dic)
2741                     {
2742                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2743                       ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
2744                       remiCodeFromeBBlock (ebp, ic);
2745                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2746                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2747                       OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2748                       ic = ic->prev;
2749                     }
2750                 }
2751             }
2752         }
2753
2754       /* pack for PUSH 
2755          iTempNN := (some variable in farspace) V1
2756          push iTempNN ;
2757          -------------
2758          push V1
2759        */
2760       if (ic->op == IPUSH)
2761         {
2762           packForPush (ic, ebpp, blockno);
2763         }
2764
2765
2766       /* pack registers for accumulator use, when the
2767          result of an arithmetic or bit wise operation
2768          has only one use, that use is immediately following
2769          the defintion and the using iCode has only one
2770          operand or has two operands but one is literal &
2771          the result of that operation is not on stack then
2772          we can leave the result of this operation in acc:b
2773          combination */
2774       if ((IS_ARITHMETIC_OP (ic)
2775            || IS_CONDITIONAL(ic)
2776            || IS_BITWISE_OP (ic)
2777            || ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == CALL
2778            || (ic->op == ADDRESS_OF && isOperandOnStack (IC_LEFT (ic)))
2779           ) &&
2780           IS_ITEMP (IC_RESULT (ic)) &&
2781           getSize (operandType (IC_RESULT (ic))) <= 2)
2782
2783         packRegsForAccUse (ic);
2784     }
2785 }
2786
2787 /*-----------------------------------------------------------------*/
2788 /* assignRegisters - assigns registers to each live range as need  */
2789 /*-----------------------------------------------------------------*/
2790 void
2791 mcs51_assignRegisters (eBBlock ** ebbs, int count)
2792 {
2793   iCode *ic;
2794   int i;
2795
2796   setToNull ((void *) &_G.funcrUsed);
2797   setToNull ((void *) &_G.totRegAssigned);
2798   mcs51_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
2799   mcs51_nRegs = 8;
2800
2801   /* change assignments this will remove some
2802      live ranges reducing some register pressure */
2803   for (i = 0; i < count; i++)
2804     packRegisters (ebbs, i);
2805
2806   if (options.dump_pack)
2807     dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
2808
2809   /* first determine for each live range the number of 
2810      registers & the type of registers required for each */
2811   regTypeNum (*ebbs);
2812
2813   /* and serially allocate registers */
2814   serialRegAssign (ebbs, count);
2815
2816   freeAllRegs ();
2817   fillGaps();
2818
2819   /* if stack was extended then tell the user */
2820   if (_G.stackExtend)
2821     {
2822 /*      werror(W_TOOMANY_SPILS,"stack", */
2823 /*             _G.stackExtend,currFunc->name,""); */
2824       _G.stackExtend = 0;
2825     }
2826
2827   if (_G.dataExtend)
2828     {
2829 /*      werror(W_TOOMANY_SPILS,"data space", */
2830 /*             _G.dataExtend,currFunc->name,""); */
2831       _G.dataExtend = 0;
2832     }
2833
2834   /* after that create the register mask
2835      for each of the instruction */
2836   createRegMask (ebbs, count);
2837
2838   /* redo that offsets for stacked automatic variables */
2839   redoStackOffsets ();
2840
2841   if (options.dump_rassgn)
2842     {
2843       dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
2844       dumpLiveRanges (DUMP_LRANGE, liveRanges);
2845     }
2846
2847   /* do the overlaysegment stuff SDCCmem.c */
2848   doOverlays (ebbs, count);
2849
2850   /* now get back the chain */
2851   ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
2852
2853   gen51Code (ic);
2854
2855   /* free up any _G.stackSpil locations allocated */
2856   applyToSet (_G.stackSpil, deallocStackSpil);
2857   _G.slocNum = 0;
2858   setToNull ((void **) &_G.stackSpil);
2859   setToNull ((void **) &_G.spiltSet);
2860   /* mark all registers as free */
2861   freeAllRegs ();
2862
2863   return;
2864 }