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