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