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