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