- added return 0 statements after assert() to make compiler happy
[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
575   /* mark it has spilt & put it in the spilt set */
576   sym->isspilt = sym->spillA = 1;
577   _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
578
579   bitVectUnSetBit (_G.regAssigned, sym->key);
580   bitVectUnSetBit (_G.totRegAssigned, sym->key);
581
582   for (i = 0; i < sym->nRegs; i++)
583
584     if (sym->regs[i])
585       {
586         freeReg (sym->regs[i]);
587         sym->regs[i] = NULL;
588       }
589
590   /* if spilt on stack then free up r0 & r1 
591      if they could have been assigned to some
592      LIVE ranges */
593   if (!mcs51_ptrRegReq && isSpiltOnStack (sym))
594     {
595       mcs51_ptrRegReq++;
596       spillLRWithPtrReg (sym);
597     }
598
599   if (sym->usl.spillLoc && !sym->remat)
600     sym->usl.spillLoc->allocreq++;
601   return;
602 }
603
604 /*-----------------------------------------------------------------*/
605 /* selectSpil - select a iTemp to spil : rather a simple procedure */
606 /*-----------------------------------------------------------------*/
607 static symbol *
608 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
609 {
610   bitVect *lrcs = NULL;
611   set *selectS;
612   symbol *sym;
613
614   /* get the spillable live ranges */
615   lrcs = computeSpillable (ic);
616
617   /* get all live ranges that are rematerizable */
618   if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
619     {
620
621       /* return the least used of these */
622       return leastUsedLR (selectS);
623     }
624
625   /* get live ranges with spillLocations in direct space */
626   if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
627     {
628       sym = leastUsedLR (selectS);
629       strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
630                            sym->usl.spillLoc->rname :
631                            sym->usl.spillLoc->name));
632       sym->spildir = 1;
633       /* mark it as allocation required */
634       sym->usl.spillLoc->allocreq++;
635       return sym;
636     }
637
638   /* if the symbol is local to the block then */
639   if (forSym->liveTo < ebp->lSeq)
640     {
641
642       /* check if there are any live ranges allocated
643          to registers that are not used in this block */
644       if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
645         {
646           sym = leastUsedLR (selectS);
647           /* if this is not rematerializable */
648           if (!sym->remat)
649             {
650               _G.blockSpil++;
651               sym->blockSpil = 1;
652             }
653           return sym;
654         }
655
656       /* check if there are any live ranges that not
657          used in the remainder of the block */
658       if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
659         {
660           sym = leastUsedLR (selectS);
661           if (sym != forSym)
662             {
663               if (!sym->remat)
664                 {
665                   sym->remainSpil = 1;
666                   _G.blockSpil++;
667                 }
668               return sym;
669             }
670         }
671     }
672
673   /* find live ranges with spillocation && not used as pointers */
674   if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
675     {
676
677       sym = leastUsedLR (selectS);
678       /* mark this as allocation required */
679       sym->usl.spillLoc->allocreq++;
680       return sym;
681     }
682
683   /* find live ranges with spillocation */
684   if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
685     {
686
687       sym = leastUsedLR (selectS);
688       sym->usl.spillLoc->allocreq++;
689       return sym;
690     }
691
692   /* couldn't find then we need to create a spil
693      location on the stack , for which one? the least
694      used ofcourse */
695   if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
696     {
697
698       /* return a created spil location */
699       sym = createStackSpil (leastUsedLR (selectS));
700       sym->usl.spillLoc->allocreq++;
701       return sym;
702     }
703
704   /* this is an extreme situation we will spill
705      this one : happens very rarely but it does happen */
706   spillThis (forSym);
707   return forSym;
708
709 }
710
711 /*-----------------------------------------------------------------*/
712 /* spilSomething - spil some variable & mark registers as free     */
713 /*-----------------------------------------------------------------*/
714 static bool
715 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
716 {
717   symbol *ssym;
718   int i;
719
720   /* get something we can spil */
721   ssym = selectSpil (ic, ebp, forSym);
722
723   /* mark it as spilt */
724   ssym->isspilt = ssym->spillA = 1;
725   _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
726
727   /* mark it as not register assigned &
728      take it away from the set */
729   bitVectUnSetBit (_G.regAssigned, ssym->key);
730   bitVectUnSetBit (_G.totRegAssigned, ssym->key);
731
732   /* mark the registers as free */
733   for (i = 0; i < ssym->nRegs; i++)
734     if (ssym->regs[i])
735       freeReg (ssym->regs[i]);
736
737   /* if spilt on stack then free up r0 & r1 
738      if they could have been assigned to as gprs */
739   if (!mcs51_ptrRegReq && isSpiltOnStack (ssym))
740     {
741       mcs51_ptrRegReq++;
742       spillLRWithPtrReg (ssym);
743     }
744
745   /* if this was a block level spil then insert push & pop 
746      at the start & end of block respectively */
747   if (ssym->blockSpil)
748     {
749       iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
750       /* add push to the start of the block */
751       addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
752                                     ebp->sch->next : ebp->sch));
753       nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
754       /* add pop to the end of the block */
755       addiCodeToeBBlock (ebp, nic, NULL);
756     }
757
758   /* if spilt because not used in the remainder of the
759      block then add a push before this instruction and
760      a pop at the end of the block */
761   if (ssym->remainSpil)
762     {
763
764       iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
765       /* add push just before this instruction */
766       addiCodeToeBBlock (ebp, nic, ic);
767
768       nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
769       /* add pop to the end of the block */
770       addiCodeToeBBlock (ebp, nic, NULL);
771     }
772
773   if (ssym == forSym)
774     return FALSE;
775   else
776     return TRUE;
777 }
778
779 /*-----------------------------------------------------------------*/
780 /* getRegPtr - will try for PTR if not a GPR type if not spil      */
781 /*-----------------------------------------------------------------*/
782 static regs *
783 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
784 {
785   regs *reg;
786
787 tryAgain:
788   /* try for a ptr type */
789   if ((reg = allocReg (REG_PTR)))
790     return reg;
791
792   /* try for gpr type */
793   if ((reg = allocReg (REG_GPR)))
794     return reg;
795
796   /* we have to spil */
797   if (!spilSomething (ic, ebp, sym))
798     return NULL;
799
800   /* this looks like an infinite loop but 
801      in really selectSpil will abort  */
802   goto tryAgain;
803 }
804
805 /*-----------------------------------------------------------------*/
806 /* getRegGpr - will try for GPR if not spil                        */
807 /*-----------------------------------------------------------------*/
808 static regs *
809 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
810 {
811   regs *reg;
812
813 tryAgain:
814   /* try for gpr type */
815   if ((reg = allocReg (REG_GPR)))
816     return reg;
817
818   if (!mcs51_ptrRegReq)
819     if ((reg = allocReg (REG_PTR)))
820       return reg;
821
822   /* we have to spil */
823   if (!spilSomething (ic, ebp, sym))
824     return NULL;
825
826   /* this looks like an infinite loop but 
827      in really selectSpil will abort  */
828   goto tryAgain;
829 }
830
831 /*-----------------------------------------------------------------*/
832 /* getRegPtrNoSpil - get it cannot split                           */
833 /*-----------------------------------------------------------------*/
834 static regs *getRegPtrNoSpil()
835 {
836   regs *reg;
837
838   /* try for a ptr type */
839   if ((reg = allocReg (REG_PTR)))
840     return reg;
841
842   /* try for gpr type */
843   if ((reg = allocReg (REG_GPR)))
844     return reg;
845
846   assert(0);
847
848   /* just to make the compiler happy */
849   return 0;
850 }
851
852 /*-----------------------------------------------------------------*/
853 /* getRegGprNoSpil - get it cannot split                           */
854 /*-----------------------------------------------------------------*/
855 static regs *getRegGprNoSpil()
856 {
857
858   regs *reg;
859   if ((reg = allocReg (REG_GPR)))
860     return reg;
861
862   if (!mcs51_ptrRegReq)
863     if ((reg = allocReg (REG_PTR)))
864       return reg;
865
866   assert(0);
867
868   /* just to make the compiler happy */
869   return 0;
870 }
871
872 /*-----------------------------------------------------------------*/
873 /* symHasReg - symbol has a given register                         */
874 /*-----------------------------------------------------------------*/
875 static bool
876 symHasReg (symbol * sym, regs * reg)
877 {
878   int i;
879
880   for (i = 0; i < sym->nRegs; i++)
881     if (sym->regs[i] == reg)
882       return TRUE;
883
884   return FALSE;
885 }
886
887 /*-----------------------------------------------------------------*/
888 /* deassignLRs - check the live to and if they have registers & are */
889 /*               not spilt then free up the registers              */
890 /*-----------------------------------------------------------------*/
891 static void
892 deassignLRs (iCode * ic, eBBlock * ebp)
893 {
894   symbol *sym;
895   int k;
896   symbol *result;
897
898   for (sym = hTabFirstItem (liveRanges, &k); sym;
899        sym = hTabNextItem (liveRanges, &k))
900     {
901
902       symbol *psym = NULL;
903       /* if it does not end here */
904       if (sym->liveTo > ic->seq)
905         continue;
906
907       /* if it was spilt on stack then we can 
908          mark the stack spil location as free */
909       if (sym->isspilt)
910         {
911           if (sym->stackSpil)
912             {
913               sym->usl.spillLoc->isFree = 1;
914               sym->stackSpil = 0;
915             }
916           continue;
917         }
918
919       if (!bitVectBitValue (_G.regAssigned, sym->key))
920         continue;
921
922       /* special case check if this is an IFX &
923          the privious one was a pop and the 
924          previous one was not spilt then keep track
925          of the symbol */
926       if (ic->op == IFX && ic->prev &&
927           ic->prev->op == IPOP &&
928           !ic->prev->parmPush &&
929           !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
930         psym = OP_SYMBOL (IC_LEFT (ic->prev));
931
932       if (sym->nRegs)
933         {
934           int i = 0;
935
936           bitVectUnSetBit (_G.regAssigned, sym->key);
937
938           /* if the result of this one needs registers
939              and does not have it then assign it right
940              away */
941           if (IC_RESULT (ic) &&
942               !(SKIP_IC2 (ic) ||        /* not a special icode */
943                 ic->op == JUMPTABLE ||
944                 ic->op == IFX ||
945                 ic->op == IPUSH ||
946                 ic->op == IPOP ||
947                 ic->op == RETURN ||
948                 POINTER_SET (ic)) &&
949               (result = OP_SYMBOL (IC_RESULT (ic))) &&  /* has a result */
950               result->liveTo > ic->seq &&       /* and will live beyond this */
951               result->liveTo <= ebp->lSeq &&    /* does not go beyond this block */
952               result->regType == sym->regType &&        /* same register types */
953               result->nRegs &&  /* which needs registers */
954               !result->isspilt &&       /* and does not already have them */
955               !result->remat &&
956               !bitVectBitValue (_G.regAssigned, result->key) &&
957           /* the number of free regs + number of regs in this LR
958              can accomodate the what result Needs */
959               ((nfreeRegsType (result->regType) +
960                 sym->nRegs) >= result->nRegs)
961             )
962             {
963
964               for (i = 0; i < result->nRegs; i++)
965                 if (i < sym->nRegs)
966                   result->regs[i] = sym->regs[i];
967                 else
968                   result->regs[i] = getRegGpr (ic, ebp, result);
969
970               _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
971               _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, result->key);
972
973             }
974
975           /* free the remaining */
976           for (; i < sym->nRegs; i++)
977             {
978               if (psym)
979                 {
980                   if (!symHasReg (psym, sym->regs[i]))
981                     freeReg (sym->regs[i]);
982                 }
983               else
984                 freeReg (sym->regs[i]);
985             }
986         }
987     }
988 }
989
990
991 /*-----------------------------------------------------------------*/
992 /* reassignLR - reassign this to registers                         */
993 /*-----------------------------------------------------------------*/
994 static void
995 reassignLR (operand * op)
996 {
997   symbol *sym = OP_SYMBOL (op);
998   int i;
999
1000   /* not spilt any more */
1001   sym->isspilt = sym->spillA = sym->blockSpil = sym->remainSpil = 0;
1002   bitVectUnSetBit (_G.spiltSet, sym->key);
1003
1004   _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1005   _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key);
1006
1007   _G.blockSpil--;
1008
1009   for (i = 0; i < sym->nRegs; i++)
1010     sym->regs[i]->isFree = 0;
1011 }
1012
1013 /*-----------------------------------------------------------------*/
1014 /* willCauseSpill - determines if allocating will cause a spill    */
1015 /*-----------------------------------------------------------------*/
1016 static int
1017 willCauseSpill (int nr, int rt)
1018 {
1019   /* first check if there are any avlb registers
1020      of te type required */
1021   if (rt == REG_PTR)
1022     {
1023       /* special case for pointer type 
1024          if pointer type not avlb then 
1025          check for type gpr */
1026       if (nFreeRegs (rt) >= nr)
1027         return 0;
1028       if (nFreeRegs (REG_GPR) >= nr)
1029         return 0;
1030     }
1031   else
1032     {
1033       if (mcs51_ptrRegReq)
1034         {
1035           if (nFreeRegs (rt) >= nr)
1036             return 0;
1037         }
1038       else
1039         {
1040           if (nFreeRegs (REG_PTR) +
1041               nFreeRegs (REG_GPR) >= nr)
1042             return 0;
1043         }
1044     }
1045
1046   /* it will cause a spil */
1047   return 1;
1048 }
1049
1050 /*-----------------------------------------------------------------*/
1051 /* positionRegs - the allocator can allocate same registers to res- */
1052 /* ult and operand, if this happens make sure they are in the same */
1053 /* position as the operand otherwise chaos results                 */
1054 /*-----------------------------------------------------------------*/
1055 static int
1056 positionRegs (symbol * result, symbol * opsym)
1057 {
1058   int count = min (result->nRegs, opsym->nRegs);
1059   int i, j = 0, shared = 0;
1060   int change = 0;
1061
1062   /* if the result has been spilt then cannot share */
1063   if (opsym->isspilt)
1064     return 0;
1065 again:
1066   shared = 0;
1067   /* first make sure that they actually share */
1068   for (i = 0; i < count; i++)
1069     {
1070       for (j = 0; j < count; j++)
1071         {
1072           if (result->regs[i] == opsym->regs[j] && i != j)
1073             {
1074               shared = 1;
1075               goto xchgPositions;
1076             }
1077         }
1078     }
1079 xchgPositions:
1080   if (shared)
1081     {
1082       regs *tmp = result->regs[i];
1083       result->regs[i] = result->regs[j];
1084       result->regs[j] = tmp;
1085       change ++;
1086       goto again;
1087     }
1088   return change;
1089 }
1090
1091 /*-----------------------------------------------------------------*/
1092 /* serialRegAssign - serially allocate registers to the variables  */
1093 /*-----------------------------------------------------------------*/
1094 static void
1095 serialRegAssign (eBBlock ** ebbs, int count)
1096 {
1097     int i;
1098
1099     /* for all blocks */
1100     for (i = 0; i < count; i++) {
1101
1102         iCode *ic;
1103
1104         if (ebbs[i]->noPath &&
1105             (ebbs[i]->entryLabel != entryLabel &&
1106              ebbs[i]->entryLabel != returnLabel))
1107             continue;
1108
1109         /* of all instructions do */
1110         for (ic = ebbs[i]->sch; ic; ic = ic->next) {
1111
1112             /* if this is an ipop that means some live
1113                range will have to be assigned again */
1114             if (ic->op == IPOP)
1115                 reassignLR (IC_LEFT (ic));
1116
1117             /* if result is present && is a true symbol */
1118             if (IC_RESULT (ic) && ic->op != IFX &&
1119                 IS_TRUE_SYMOP (IC_RESULT (ic)))
1120                 OP_SYMBOL (IC_RESULT (ic))->allocreq++;
1121
1122             /* take away registers from live
1123                ranges that end at this instruction */
1124             deassignLRs (ic, ebbs[i]);
1125
1126             /* some don't need registers */
1127             if (SKIP_IC2 (ic) ||
1128                 ic->op == JUMPTABLE ||
1129                 ic->op == IFX ||
1130                 ic->op == IPUSH ||
1131                 ic->op == IPOP ||
1132                 (IC_RESULT (ic) && POINTER_SET (ic)))
1133                 continue;
1134
1135             /* now we need to allocate registers
1136                only for the result */
1137             if (IC_RESULT (ic)) {
1138                 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
1139                 bitVect *spillable;
1140                 int willCS;
1141                 int j;
1142                 int ptrRegSet = 0;
1143
1144                 /* if it does not need or is spilt 
1145                    or is already assigned to registers
1146                    or will not live beyond this instructions */
1147                 if (!sym->nRegs ||
1148                     sym->isspilt ||
1149                     bitVectBitValue (_G.regAssigned, sym->key) ||
1150                     sym->liveTo <= ic->seq)
1151                     continue;
1152
1153                 /* if some liverange has been spilt at the block level
1154                    and this one live beyond this block then spil this
1155                    to be safe */
1156                 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq) {
1157                     spillThis (sym);
1158                     continue;
1159                 }
1160                 /* if trying to allocate this will cause
1161                    a spill and there is nothing to spill 
1162                    or this one is rematerializable then
1163                    spill this one */
1164                 willCS = willCauseSpill (sym->nRegs, sym->regType);
1165                 spillable = computeSpillable (ic);
1166                 if (sym->remat || (willCS && bitVectIsZero (spillable))) {                    
1167                     spillThis (sym);
1168                     continue;                 
1169                 }
1170
1171                 /* if it has a spillocation & is used less than
1172                    all other live ranges then spill this */
1173                 if (willCS) {
1174                     if (sym->usl.spillLoc) {
1175                         symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
1176                                                                          allLRs, ebbs[i], ic));
1177                         if (leastUsed && leastUsed->used > sym->used) {
1178                             spillThis (sym);
1179                             continue;
1180                         }
1181                     } else {
1182                         /* if none of the liveRanges have a spillLocation then better
1183                            to spill this one than anything else already assigned to registers */
1184                         if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
1185                             /* if this is local to this block then we might find a block spil */
1186                             if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
1187                                 spillThis (sym);
1188                                 continue;
1189                             }
1190                         }
1191                     }
1192                 }
1193                 /* if we need ptr regs for the right side
1194                    then mark it */
1195                 if (POINTER_GET (ic) && IS_SYMOP (IC_LEFT (ic))
1196                     && getSize (OP_SYMBOL (IC_LEFT (ic))->type) <= (unsigned int) PTRSIZE) {
1197                     mcs51_ptrRegReq++;
1198                     ptrRegSet = 1;
1199                 }
1200                 /* else we assign registers to it */
1201                 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1202                 _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key);
1203
1204                 for (j = 0; j < sym->nRegs; j++) {
1205                     if (sym->regType == REG_PTR)
1206                         sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
1207                     else
1208                         sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
1209
1210                     /* if the allocation failed which means
1211                        this was spilt then break */
1212                     if (!sym->regs[j]) {
1213                       break;
1214                     }
1215                 }
1216
1217                 /* if it shares registers with operands make sure
1218                    that they are in the same position */
1219                 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
1220                     OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=') {
1221                     positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1222                                   OP_SYMBOL (IC_LEFT (ic)));
1223                 }
1224                 /* do the same for the right operand */
1225                 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
1226                     OP_SYMBOL (IC_RIGHT (ic))->nRegs) {
1227                     positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1228                                   OP_SYMBOL (IC_RIGHT (ic)));
1229                 }
1230
1231                 if (ptrRegSet) {
1232                     mcs51_ptrRegReq--;
1233                     ptrRegSet = 0;
1234                 }
1235
1236             }
1237         }
1238     }
1239 }
1240
1241 /*-----------------------------------------------------------------*/
1242 /* fillGaps - Try to fill in the Gaps left by Pass1                */
1243 /*-----------------------------------------------------------------*/
1244 static void fillGaps()
1245 {
1246     symbol *sym =NULL;
1247     int key =0;    
1248     
1249     if (getenv("DISABLE_FILL_GAPS")) return;
1250     
1251     /* look for livernages that was spilt by the allocator */
1252     for (sym = hTabFirstItem(liveRanges,&key) ; sym ; 
1253          sym = hTabNextItem(liveRanges,&key)) {
1254
1255         int i;
1256         int pdone = 0;
1257
1258         if (!sym->spillA || !sym->clashes || sym->remat) continue ;
1259
1260         /* find the liveRanges this one clashes with, that are
1261            still assigned to registers & mark the registers as used*/
1262         for ( i = 0 ; i < sym->clashes->size ; i ++) {
1263             int k;
1264             symbol *clr;
1265
1266             if (bitVectBitValue(sym->clashes,i) == 0 ||    /* those that clash with this */
1267                 bitVectBitValue(_G.totRegAssigned,i) == 0) /* and are still assigned to registers */
1268                 continue ;
1269
1270             assert (clr = hTabItemWithKey(liveRanges,i));
1271          
1272             /* mark these registers as used */
1273             for (k = 0 ; k < clr->nRegs ; k++ ) 
1274                 useReg(clr->regs[k]);
1275         }
1276
1277         if (willCauseSpill(sym->nRegs,sym->regType)) {
1278             /* NOPE :( clear all registers & and continue */
1279             freeAllRegs();
1280             continue ;
1281         }
1282
1283         /* THERE IS HOPE !!!! */
1284         for (i=0; i < sym->nRegs ; i++ ) {
1285             if (sym->regType == REG_PTR)
1286                 sym->regs[i] = getRegPtrNoSpil ();
1287             else
1288                 sym->regs[i] = getRegGprNoSpil ();                
1289         }
1290
1291         /* for all its definitions check if the registers
1292            allocated needs positioning NOTE: we can position
1293            only ONCE if more than One positioning required 
1294            then give up */
1295         sym->isspilt = 0;
1296         for (i = 0 ; i < sym->defs->size ; i++ ) {
1297             if (bitVectBitValue(sym->defs,i)) {
1298                 iCode *ic;
1299                 if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
1300                 if (SKIP_IC(ic)) continue;
1301                 assert(isSymbolEqual(sym,OP_SYMBOL(IC_RESULT(ic)))); /* just making sure */
1302                 /* if left is assigned to registers */
1303                 if (IS_SYMOP(IC_LEFT(ic)) && 
1304                     bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_LEFT(ic))->key)) {
1305                     pdone += positionRegs(sym,OP_SYMBOL(IC_LEFT(ic)));
1306                 }
1307                 if (IS_SYMOP(IC_RIGHT(ic)) && 
1308                     bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RIGHT(ic))->key)) {
1309                     pdone += positionRegs(sym,OP_SYMBOL(IC_RIGHT(ic)));
1310                 }
1311                 if (pdone > 1) break;
1312             }
1313         }
1314         for (i = 0 ; i < sym->uses->size ; i++ ) {
1315             if (bitVectBitValue(sym->uses,i)) {
1316                 iCode *ic;
1317                 if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
1318                 if (SKIP_IC(ic)) continue;
1319                 if (!IS_ASSIGN_ICODE(ic)) continue ;
1320
1321                 /* if result is assigned to registers */
1322                 if (IS_SYMOP(IC_RESULT(ic)) && 
1323                     bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RESULT(ic))->key)) {
1324                     pdone += positionRegs(sym,OP_SYMBOL(IC_RESULT(ic)));
1325                 }
1326                 if (pdone > 1) break;
1327             }
1328         }
1329         /* had to position more than once GIVE UP */
1330         if (pdone > 1) {
1331             /* UNDO all the changes we made to try this */
1332             sym->isspilt = 1;
1333             for (i=0; i < sym->nRegs ; i++ ) {
1334                     sym->regs[i] = NULL;
1335             }
1336             freeAllRegs();
1337             D(printf ("Fill Gap gave up due to positioning for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN"));
1338             continue ;      
1339         }
1340         D(printf ("FILLED GAP for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN"));
1341         _G.totRegAssigned = bitVectSetBit(_G.totRegAssigned,sym->key);
1342         sym->isspilt = sym->spillA = 0 ;
1343         sym->usl.spillLoc->allocreq--;
1344         freeAllRegs();
1345     }
1346 }
1347
1348 /*-----------------------------------------------------------------*/
1349 /* rUmaskForOp :- returns register mask for an operand             */
1350 /*-----------------------------------------------------------------*/
1351 bitVect *
1352 mcs51_rUmaskForOp (operand * op)
1353 {
1354   bitVect *rumask;
1355   symbol *sym;
1356   int j;
1357
1358   /* only temporaries are assigned registers */
1359   if (!IS_ITEMP (op))
1360     return NULL;
1361
1362   sym = OP_SYMBOL (op);
1363
1364   /* if spilt or no registers assigned to it
1365      then nothing */
1366   if (sym->isspilt || !sym->nRegs)
1367     return NULL;
1368
1369   rumask = newBitVect (mcs51_nRegs);
1370
1371   for (j = 0; j < sym->nRegs; j++)
1372     {
1373       rumask = bitVectSetBit (rumask,
1374                               sym->regs[j]->rIdx);
1375     }
1376
1377   return rumask;
1378 }
1379
1380 /*-----------------------------------------------------------------*/
1381 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
1382 /*-----------------------------------------------------------------*/
1383 static bitVect *
1384 regsUsedIniCode (iCode * ic)
1385 {
1386   bitVect *rmask = newBitVect (mcs51_nRegs);
1387
1388   /* do the special cases first */
1389   if (ic->op == IFX)
1390     {
1391       rmask = bitVectUnion (rmask,
1392                             mcs51_rUmaskForOp (IC_COND (ic)));
1393       goto ret;
1394     }
1395
1396   /* for the jumptable */
1397   if (ic->op == JUMPTABLE)
1398     {
1399       rmask = bitVectUnion (rmask,
1400                             mcs51_rUmaskForOp (IC_JTCOND (ic)));
1401
1402       goto ret;
1403     }
1404
1405   /* of all other cases */
1406   if (IC_LEFT (ic))
1407     rmask = bitVectUnion (rmask,
1408                           mcs51_rUmaskForOp (IC_LEFT (ic)));
1409
1410
1411   if (IC_RIGHT (ic))
1412     rmask = bitVectUnion (rmask,
1413                           mcs51_rUmaskForOp (IC_RIGHT (ic)));
1414
1415   if (IC_RESULT (ic))
1416     rmask = bitVectUnion (rmask,
1417                           mcs51_rUmaskForOp (IC_RESULT (ic)));
1418
1419 ret:
1420   return rmask;
1421 }
1422
1423 /*-----------------------------------------------------------------*/
1424 /* createRegMask - for each instruction will determine the regsUsed */
1425 /*-----------------------------------------------------------------*/
1426 static void
1427 createRegMask (eBBlock ** ebbs, int count)
1428 {
1429   int i;
1430
1431   /* for all blocks */
1432   for (i = 0; i < count; i++)
1433     {
1434       iCode *ic;
1435
1436       if (ebbs[i]->noPath &&
1437           (ebbs[i]->entryLabel != entryLabel &&
1438            ebbs[i]->entryLabel != returnLabel))
1439         continue;
1440
1441       /* for all instructions */
1442       for (ic = ebbs[i]->sch; ic; ic = ic->next)
1443         {
1444
1445           int j;
1446
1447           if (SKIP_IC2 (ic) || !ic->rlive)
1448             continue;
1449
1450           /* first mark the registers used in this
1451              instruction */
1452           ic->rUsed = regsUsedIniCode (ic);
1453           _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
1454
1455           /* now create the register mask for those 
1456              registers that are in use : this is a
1457              super set of ic->rUsed */
1458           ic->rMask = newBitVect (mcs51_nRegs + 1);
1459
1460           /* for all live Ranges alive at this point */
1461           for (j = 1; j < ic->rlive->size; j++)
1462             {
1463               symbol *sym;
1464               int k;
1465
1466               /* if not alive then continue */
1467               if (!bitVectBitValue (ic->rlive, j))
1468                 continue;
1469
1470               /* find the live range we are interested in */
1471               if (!(sym = hTabItemWithKey (liveRanges, j)))
1472                 {
1473                   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1474                           "createRegMask cannot find live range");
1475                   exit (0);
1476                 }
1477
1478               /* if no register assigned to it */
1479               if (!sym->nRegs || sym->isspilt)
1480                 continue;
1481
1482               /* for all the registers allocated to it */
1483               for (k = 0; k < sym->nRegs; k++)
1484                 if (sym->regs[k])
1485                   ic->rMask =
1486                     bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
1487             }
1488         }
1489     }
1490 }
1491
1492 /*-----------------------------------------------------------------*/
1493 /* rematStr - returns the rematerialized string for a remat var    */
1494 /*-----------------------------------------------------------------*/
1495 static char *
1496 rematStr (symbol * sym)
1497 {
1498   char *s = buffer;
1499   iCode *ic = sym->rematiCode;
1500
1501   while (1)
1502     {
1503
1504       /* if plus or minus print the right hand side */
1505       if (ic->op == '+' || ic->op == '-')
1506         {
1507           sprintf (s, "0x%04x %c ", (int) operandLitValue (IC_RIGHT (ic)),
1508                    ic->op);
1509           s += strlen (s);
1510           ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1511           continue;
1512         }
1513
1514       /* cast then continue */
1515       if (IS_CAST_ICODE(ic)) {
1516           ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
1517           continue;
1518       }
1519       /* we reached the end */
1520       sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
1521       break;
1522     }
1523
1524   return buffer;
1525 }
1526
1527 /*-----------------------------------------------------------------*/
1528 /* regTypeNum - computes the type & number of registers required   */
1529 /*-----------------------------------------------------------------*/
1530 static void
1531 regTypeNum (eBBlock *ebbs)
1532 {
1533   symbol *sym;
1534   int k;
1535   iCode *ic;
1536
1537   /* for each live range do */
1538   for (sym = hTabFirstItem (liveRanges, &k); sym;
1539        sym = hTabNextItem (liveRanges, &k))
1540     {
1541
1542       /* if used zero times then no registers needed */
1543       if ((sym->liveTo - sym->liveFrom) == 0)
1544         continue;
1545
1546
1547       /* if the live range is a temporary */
1548       if (sym->isitmp)
1549         {
1550
1551           /* if the type is marked as a conditional */
1552           if (sym->regType == REG_CND)
1553             continue;
1554
1555           /* if used in return only then we don't 
1556              need registers */
1557           if (sym->ruonly || sym->accuse)
1558             {
1559               if (IS_AGGREGATE (sym->type) || sym->isptr)
1560                 sym->type = aggrToPtr (sym->type, FALSE);
1561               continue;
1562             }
1563
1564           /* if the symbol has only one definition &
1565              that definition is a get_pointer */
1566           if (bitVectnBitsOn (sym->defs) == 1 &&
1567               (ic = hTabItemWithKey (iCodehTab,
1568                                      bitVectFirstBit (sym->defs))) &&
1569               POINTER_GET (ic) &&
1570               !sym->noSpilLoc &&
1571               !IS_BITVAR (sym->etype))
1572             {
1573
1574
1575               /* and that pointer is remat in data space */
1576               if (OP_SYMBOL (IC_LEFT (ic))->remat &&
1577                   !IS_CAST_ICODE(OP_SYMBOL (IC_LEFT (ic))->rematiCode) &&
1578                   DCL_TYPE (aggrToPtr (operandType(IC_LEFT(ic)), FALSE)) == POINTER)
1579                 {
1580                   /* create a psuedo symbol & force a spil */
1581                   symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
1582                   psym->type = sym->type;
1583                   psym->etype = sym->etype;
1584                   strcpy (psym->rname, psym->name);
1585                   sym->isspilt = 1;
1586                   sym->usl.spillLoc = psym;
1587 #if 0 // an alternative fix for bug #480076
1588                   /* now this is a useless assignment to itself */
1589                   remiCodeFromeBBlock (ebbs, ic);
1590 #else
1591                   /* now this really is an assignment to itself, make it so;
1592                      it will be optimized out later */
1593                   ic->op='=';
1594                   IC_RIGHT(ic)=IC_RESULT(ic);
1595                   IC_LEFT(ic)=NULL;
1596 #endif
1597                   continue;
1598                 }
1599
1600               /* if in data space or idata space then try to
1601                  allocate pointer register */
1602
1603             }
1604
1605           /* if not then we require registers */
1606           sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
1607                         getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1608                         getSize (sym->type));
1609
1610           if (sym->nRegs > 4)
1611             {
1612               fprintf (stderr, "allocated more than 4 or 0 registers for type ");
1613               printTypeChain (sym->type, stderr);
1614               fprintf (stderr, "\n");
1615             }
1616
1617           /* determine the type of register required */
1618           if (sym->nRegs == 1 &&
1619               IS_PTR (sym->type) &&
1620               sym->uptr)
1621             sym->regType = REG_PTR;
1622           else
1623             sym->regType = REG_GPR;
1624
1625         }
1626       else
1627         /* for the first run we don't provide */
1628         /* registers for true symbols we will */
1629         /* see how things go                  */
1630         sym->nRegs = 0;
1631     }
1632
1633 }
1634
1635 /*-----------------------------------------------------------------*/
1636 /* freeAllRegs - mark all registers as free                        */
1637 /*-----------------------------------------------------------------*/
1638 static void
1639 freeAllRegs ()
1640 {
1641   int i;
1642
1643   for (i = 0; i < mcs51_nRegs; i++)
1644     regs8051[i].isFree = 1;
1645 }
1646
1647 /*-----------------------------------------------------------------*/
1648 /* deallocStackSpil - this will set the stack pointer back         */
1649 /*-----------------------------------------------------------------*/
1650 static
1651 DEFSETFUNC (deallocStackSpil)
1652 {
1653   symbol *sym = item;
1654
1655   deallocLocal (sym);
1656   return 0;
1657 }
1658
1659 /*-----------------------------------------------------------------*/
1660 /* farSpacePackable - returns the packable icode for far variables */
1661 /*-----------------------------------------------------------------*/
1662 static iCode *
1663 farSpacePackable (iCode * ic)
1664 {
1665   iCode *dic;
1666
1667   /* go thru till we find a definition for the
1668      symbol on the right */
1669   for (dic = ic->prev; dic; dic = dic->prev)
1670     {
1671       /* if the definition is a call then no */
1672       if ((dic->op == CALL || dic->op == PCALL) &&
1673           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1674         {
1675           return NULL;
1676         }
1677
1678       /* if shift by unknown amount then not */
1679       if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
1680           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1681         return NULL;
1682
1683       /* if pointer get and size > 1 */
1684       if (POINTER_GET (dic) &&
1685           getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
1686         return NULL;
1687
1688       if (POINTER_SET (dic) &&
1689           getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
1690         return NULL;
1691
1692       /* if any three is a true symbol in far space */
1693       if (IC_RESULT (dic) &&
1694           IS_TRUE_SYMOP (IC_RESULT (dic)) &&
1695           isOperandInFarSpace (IC_RESULT (dic)))
1696         return NULL;
1697
1698       if (IC_RIGHT (dic) &&
1699           IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
1700           isOperandInFarSpace (IC_RIGHT (dic)) &&
1701           !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
1702         return NULL;
1703
1704       if (IC_LEFT (dic) &&
1705           IS_TRUE_SYMOP (IC_LEFT (dic)) &&
1706           isOperandInFarSpace (IC_LEFT (dic)) &&
1707           !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
1708         return NULL;
1709
1710       if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
1711         {
1712           if ((dic->op == LEFT_OP ||
1713                dic->op == RIGHT_OP ||
1714                dic->op == '-') &&
1715               IS_OP_LITERAL (IC_RIGHT (dic)))
1716             return NULL;
1717           else
1718             return dic;
1719         }
1720     }
1721
1722   return NULL;
1723 }
1724
1725 /*-----------------------------------------------------------------*/
1726 /* packRegsForAssign - register reduction for assignment           */
1727 /*-----------------------------------------------------------------*/
1728 static int
1729 packRegsForAssign (iCode * ic, eBBlock * ebp)
1730 {
1731   iCode *dic, *sic;
1732   //sym_link *etype = operandType (IC_RIGHT (ic));
1733
1734   if (!IS_ITEMP (IC_RIGHT (ic)) ||
1735       OP_SYMBOL (IC_RIGHT (ic))->isind ||
1736       OP_LIVETO (IC_RIGHT (ic)) > ic->seq
1737       /* why? || IS_BITFIELD (etype) */ )
1738     {
1739       return 0;
1740     }
1741
1742   /* if the true symbol is defined in far space or on stack
1743      then we should not since this will increase register pressure */
1744   if (isOperandInFarSpace(IC_RESULT(ic)) && !farSpacePackable(ic)) {
1745     return 0;
1746   }
1747
1748   /* find the definition of iTempNN scanning backwards if we find a 
1749      a use of the true symbol in before we find the definition then 
1750      we cannot */
1751   for (dic = ic->prev; dic; dic = dic->prev)
1752     {
1753       /* if there is a function call then don't pack it */
1754       if ((dic->op == CALL || dic->op == PCALL))
1755         {
1756           dic = NULL;
1757           break;
1758         }
1759
1760       if (SKIP_IC2 (dic))
1761         continue;
1762
1763       if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
1764           IS_OP_VOLATILE (IC_RESULT (dic)))
1765         {
1766           dic = NULL;
1767           break;
1768         }
1769
1770       if (IS_SYMOP (IC_RESULT (dic)) &&
1771           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1772         {
1773           if (POINTER_SET (dic))
1774             dic = NULL;
1775
1776           break;
1777         }
1778
1779       if (IS_SYMOP (IC_RIGHT (dic)) &&
1780           (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
1781            IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
1782         {
1783           dic = NULL;
1784           break;
1785         }
1786
1787       if (IS_SYMOP (IC_LEFT (dic)) &&
1788           (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
1789            IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
1790         {
1791           dic = NULL;
1792           break;
1793         }
1794
1795       if (POINTER_SET (dic) &&
1796           IC_RESULT (dic)->key == IC_RESULT (ic)->key)
1797         {
1798           dic = NULL;
1799           break;
1800         }
1801     }
1802
1803   if (!dic)
1804     return 0;                   /* did not find */
1805
1806   /* if assignment then check that right is not a bit */
1807   if (ASSIGNMENT (dic) && !POINTER_SET (dic))
1808     {
1809       sym_link *etype = operandType (IC_RIGHT (dic));
1810       if (IS_BITFIELD (etype))
1811         return 0;
1812     }
1813   /* if the result is on stack or iaccess then it must be
1814      the same atleast one of the operands */
1815   if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
1816       OP_SYMBOL (IC_RESULT (ic))->iaccess)
1817     {
1818
1819       /* the operation has only one symbol
1820          operator then we can pack */
1821       if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
1822           (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
1823         goto pack;
1824
1825       if (!((IC_LEFT (dic) &&
1826              IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
1827             (IC_RIGHT (dic) &&
1828              IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
1829         return 0;
1830     }
1831 pack:
1832   /* found the definition */
1833   /* replace the result with the result of */
1834   /* this assignment and remove this assignment */
1835   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1836   IC_RESULT (dic) = IC_RESULT (ic);
1837
1838   if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
1839     {
1840       OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
1841     }
1842   /* delete from liverange table also 
1843      delete from all the points inbetween and the new
1844      one */
1845   for (sic = dic; sic != ic; sic = sic->next)
1846     {
1847       bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
1848       if (IS_ITEMP (IC_RESULT (dic)))
1849         bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
1850     }
1851
1852   remiCodeFromeBBlock (ebp, ic);
1853   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
1854   hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
1855   OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
1856   return 1;
1857
1858 }
1859
1860 /*-----------------------------------------------------------------*/
1861 /* findAssignToSym : scanning backwards looks for first assig found */
1862 /*-----------------------------------------------------------------*/
1863 static iCode *
1864 findAssignToSym (operand * op, iCode * ic)
1865 {
1866   iCode *dic;
1867
1868   for (dic = ic->prev; dic; dic = dic->prev)
1869     {
1870
1871       /* if definition by assignment */
1872       if (dic->op == '=' &&
1873           !POINTER_SET (dic) &&
1874           IC_RESULT (dic)->key == op->key
1875 /*          &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) */
1876         )
1877         {
1878
1879           /* we are interested only if defined in far space */
1880           /* or in stack space in case of + & - */
1881
1882           /* if assigned to a non-symbol then return
1883              FALSE */
1884           if (!IS_SYMOP (IC_RIGHT (dic)))
1885             return NULL;
1886
1887           /* if the symbol is in far space then
1888              we should not */
1889           if (isOperandInFarSpace (IC_RIGHT (dic)))
1890             return NULL;
1891
1892           /* for + & - operations make sure that
1893              if it is on the stack it is the same
1894              as one of the three operands */
1895           if ((ic->op == '+' || ic->op == '-') &&
1896               OP_SYMBOL (IC_RIGHT (dic))->onStack)
1897             {
1898
1899               if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
1900                   IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
1901                   IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
1902                 return NULL;
1903             }
1904
1905           break;
1906
1907         }
1908
1909       /* if we find an usage then we cannot delete it */
1910       if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
1911         return NULL;
1912
1913       if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
1914         return NULL;
1915
1916       if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
1917         return NULL;
1918     }
1919
1920   /* now make sure that the right side of dic
1921      is not defined between ic & dic */
1922   if (dic)
1923     {
1924       iCode *sic = dic->next;
1925
1926       for (; sic != ic; sic = sic->next)
1927         if (IC_RESULT (sic) &&
1928             IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
1929           return NULL;
1930     }
1931
1932   return dic;
1933
1934
1935 }
1936
1937 /*-----------------------------------------------------------------*/
1938 /* packRegsForSupport :- reduce some registers for support calls   */
1939 /*-----------------------------------------------------------------*/
1940 static int
1941 packRegsForSupport (iCode * ic, eBBlock * ebp)
1942 {
1943   int change = 0;
1944   iCode *dic, *sic;
1945
1946   /* for the left & right operand :- look to see if the
1947      left was assigned a true symbol in far space in that
1948      case replace them */
1949
1950   if (IS_ITEMP (IC_LEFT (ic)) &&
1951       OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
1952     {
1953       dic = findAssignToSym (IC_LEFT (ic), ic);
1954
1955       if (!dic)
1956         goto right;
1957
1958       /* found it we need to remove it from the
1959          block */
1960       for (sic = dic; sic != ic; sic = sic->next) {
1961         bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
1962         sic->rlive = bitVectSetBit (sic->rlive, IC_RIGHT (dic)->key);
1963       }
1964
1965       OP_SYMBOL(IC_LEFT (ic))=OP_SYMBOL(IC_RIGHT (dic));
1966       OP_SYMBOL(IC_LEFT(ic))->liveTo = ic->seq;
1967       IC_LEFT (ic)->key = OP_SYMBOL(IC_RIGHT (dic))->key;
1968       remiCodeFromeBBlock (ebp, dic);
1969       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1970       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1971       change++;
1972     }
1973
1974   /* do the same for the right operand */
1975  right:
1976   if (!change &&
1977       IS_ITEMP (IC_RIGHT (ic)) &&
1978       OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
1979     {
1980       iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
1981       iCode *sic;
1982
1983       if (!dic)
1984         return change;
1985
1986       /* if this is a subtraction & the result
1987          is a true symbol in far space then don't pack */
1988       if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
1989         {
1990           sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
1991           if (IN_FARSPACE (SPEC_OCLS (etype)))
1992             return change;
1993         }
1994       /* found it we need to remove it from the
1995          block */
1996       for (sic = dic; sic != ic; sic = sic->next) {
1997         bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
1998         sic->rlive = bitVectSetBit (sic->rlive, IC_RIGHT (dic)->key);
1999       }
2000
2001       IC_RIGHT (ic)->operand.symOperand =
2002         IC_RIGHT (dic)->operand.symOperand;
2003       OP_SYMBOL(IC_RIGHT(ic))->liveTo = ic->seq;
2004       IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2005
2006       remiCodeFromeBBlock (ebp, dic);
2007       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2008       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2009       change++;
2010     }
2011
2012   return change;
2013 }
2014
2015 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
2016
2017
2018 /*-----------------------------------------------------------------*/
2019 /* packRegsForOneuse : - will reduce some registers for single Use */
2020 /*-----------------------------------------------------------------*/
2021 static iCode *
2022 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
2023 {
2024   bitVect *uses;
2025   iCode *dic, *sic;
2026
2027   /* if returning a literal then do nothing */
2028   if (!IS_SYMOP (op))
2029     return NULL;
2030
2031   /* only upto 2 bytes since we cannot predict
2032      the usage of b, & acc */
2033   if (getSize (operandType (op)) > (fReturnSizeMCS51 - 2))
2034     return NULL;
2035
2036   if (ic->op != RETURN &&
2037       ic->op != SEND &&
2038       !POINTER_SET (ic) &&
2039       !POINTER_GET (ic))
2040     return NULL;
2041   
2042   if (ic->op == SEND && ic->argreg != 1) return NULL;
2043
2044   /* this routine will mark the a symbol as used in one 
2045      instruction use only && if the defintion is local 
2046      (ie. within the basic block) && has only one definition &&
2047      that definiion is either a return value from a 
2048      function or does not contain any variables in
2049      far space */
2050   uses = bitVectCopy (OP_USES (op));
2051   bitVectUnSetBit (uses, ic->key);      /* take away this iCode */
2052   if (!bitVectIsZero (uses))    /* has other uses */
2053     return NULL;
2054
2055   /* if it has only one defintion */
2056   if (bitVectnBitsOn (OP_DEFS (op)) > 1)
2057     return NULL;                /* has more than one definition */
2058
2059   /* get that definition */
2060   if (!(dic =
2061         hTabItemWithKey (iCodehTab,
2062                          bitVectFirstBit (OP_DEFS (op)))))
2063     return NULL;
2064
2065   /* if that only usage is a cast */
2066   if (dic->op == CAST) {
2067     /* to a bigger type */
2068     if (getSize(OP_SYM_TYPE(IC_RESULT(dic))) > 
2069         getSize(OP_SYM_TYPE(IC_RIGHT(dic)))) {
2070       /* than we can not, since we cannot predict the usage of b & acc */
2071       return NULL;
2072     }
2073   }
2074
2075   /* found the definition now check if it is local */
2076   if (dic->seq < ebp->fSeq ||
2077       dic->seq > ebp->lSeq)
2078     return NULL;                /* non-local */
2079
2080   /* now check if it is the return from
2081      a function call */
2082   if (dic->op == CALL || dic->op == PCALL)
2083     {
2084       if (ic->op != SEND && ic->op != RETURN &&
2085           !POINTER_SET(ic) && !POINTER_GET(ic))
2086         {
2087           OP_SYMBOL (op)->ruonly = 1;
2088           return dic;
2089         }
2090       dic = dic->next;
2091     }
2092
2093
2094   /* otherwise check that the definition does
2095      not contain any symbols in far space */
2096   if (isOperandInFarSpace (IC_LEFT (dic)) ||
2097       isOperandInFarSpace (IC_RIGHT (dic)) ||
2098       IS_OP_RUONLY (IC_LEFT (ic)) ||
2099       IS_OP_RUONLY (IC_RIGHT (ic)))
2100     {
2101       return NULL;
2102     }
2103
2104   /* if pointer set then make sure the pointer
2105      is one byte */
2106   if (POINTER_SET (dic) &&
2107       !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2108     return NULL;
2109
2110   if (POINTER_GET (dic) &&
2111       !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2112     return NULL;
2113
2114   sic = dic;
2115
2116   /* also make sure the intervenening instructions
2117      don't have any thing in far space */
2118   for (dic = dic->next; dic && dic != ic && sic != ic; dic = dic->next)
2119     {
2120
2121       /* if there is an intervening function call then no */
2122       if (dic->op == CALL || dic->op == PCALL)
2123         return NULL;
2124       /* if pointer set then make sure the pointer
2125          is one byte */
2126       if (POINTER_SET (dic) &&
2127           !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2128         return NULL;
2129
2130       if (POINTER_GET (dic) &&
2131           !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2132         return NULL;
2133
2134       /* if address of & the result is remat the okay */
2135       if (dic->op == ADDRESS_OF &&
2136           OP_SYMBOL (IC_RESULT (dic))->remat)
2137         continue;
2138
2139       /* if operand has size of three or more & this
2140          operation is a '*','/' or '%' then 'b' may
2141          cause a problem */
2142       if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
2143           getSize (operandType (op)) >= 3)
2144         return NULL;
2145
2146       /* if left or right or result is in far space */
2147       if (isOperandInFarSpace (IC_LEFT (dic)) ||
2148           isOperandInFarSpace (IC_RIGHT (dic)) ||
2149           isOperandInFarSpace (IC_RESULT (dic)) ||
2150           IS_OP_RUONLY (IC_LEFT (dic)) ||
2151           IS_OP_RUONLY (IC_RIGHT (dic)) ||
2152           IS_OP_RUONLY (IC_RESULT (dic)))
2153         {
2154           return NULL;
2155         }
2156       /* if left or right or result is on stack */
2157       if (isOperandOnStack(IC_LEFT(dic)) ||
2158           isOperandOnStack(IC_RIGHT(dic)) ||
2159           isOperandOnStack(IC_RESULT(dic))) {
2160         return NULL;
2161       }
2162     }
2163
2164   OP_SYMBOL (op)->ruonly = 1;
2165   return sic;
2166
2167 }
2168
2169 /*-----------------------------------------------------------------*/
2170 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
2171 /*-----------------------------------------------------------------*/
2172 static bool
2173 isBitwiseOptimizable (iCode * ic)
2174 {
2175   sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
2176   sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
2177
2178   /* bitwise operations are considered optimizable
2179      under the following conditions (Jean-Louis VERN) 
2180
2181      x & lit
2182      bit & bit
2183      bit & x
2184      bit ^ bit
2185      bit ^ x
2186      x   ^ lit
2187      x   | lit
2188      bit | bit
2189      bit | x
2190   */
2191   if (IS_LITERAL(rtype) ||
2192       (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
2193     return TRUE;
2194   else
2195     return FALSE;
2196 }
2197
2198 /*-----------------------------------------------------------------*/
2199 /* packRegsForAccUse - pack registers for acc use                  */
2200 /*-----------------------------------------------------------------*/
2201 static void
2202 packRegsForAccUse (iCode * ic)
2203 {
2204   iCode *uic;
2205
2206   /* if this is an aggregate, e.g. a one byte char array */
2207   if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
2208     return;
2209   }
2210
2211   /* if we are calling a reentrant function that has stack parameters */
2212   if (ic->op == CALL &&
2213        IFFUNC_ISREENT(operandType(IC_LEFT(ic))) &&
2214        FUNC_HASSTACKPARM(operandType(IC_LEFT(ic))))
2215       return;
2216
2217   if (ic->op == PCALL &&
2218        IFFUNC_ISREENT(operandType(IC_LEFT(ic))->next) &&
2219        FUNC_HASSTACKPARM(operandType(IC_LEFT(ic))->next))
2220       return;
2221
2222   /* if + or - then it has to be one byte result */
2223   if ((ic->op == '+' || ic->op == '-')
2224       && getSize (operandType (IC_RESULT (ic))) > 1)
2225     return;
2226
2227   /* if shift operation make sure right side is not a literal */
2228   if (ic->op == RIGHT_OP &&
2229       (isOperandLiteral (IC_RIGHT (ic)) ||
2230        getSize (operandType (IC_RESULT (ic))) > 1))
2231     return;
2232
2233   if (ic->op == LEFT_OP &&
2234       (isOperandLiteral (IC_RIGHT (ic)) ||
2235        getSize (operandType (IC_RESULT (ic))) > 1))
2236     return;
2237
2238   if (IS_BITWISE_OP (ic) &&
2239       getSize (operandType (IC_RESULT (ic))) > 1)
2240     return;
2241
2242
2243   /* has only one definition */
2244   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
2245     return;
2246
2247   /* has only one use */
2248   if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
2249     return;
2250
2251   /* and the usage immediately follows this iCode */
2252   if (!(uic = hTabItemWithKey (iCodehTab,
2253                                bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
2254     return;
2255
2256   if (ic->next != uic)
2257     return;
2258
2259   /* if it is a conditional branch then we definitely can */
2260   if (uic->op == IFX)
2261     goto accuse;
2262
2263   if (uic->op == JUMPTABLE)
2264     return;
2265
2266   /* if the usage is not is an assignment
2267      or an arithmetic / bitwise / shift operation then not */
2268   if (POINTER_SET (uic) &&
2269       getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
2270     return;
2271
2272   if (uic->op != '=' &&
2273       !IS_ARITHMETIC_OP (uic) &&
2274       !IS_BITWISE_OP (uic) &&
2275       uic->op != LEFT_OP &&
2276       uic->op != RIGHT_OP)
2277     return;
2278
2279   /* if used in ^ operation then make sure right is not a 
2280      literl */
2281   if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
2282     return;
2283
2284   /* if shift operation make sure right side is not a literal */
2285   if (uic->op == RIGHT_OP &&
2286       (isOperandLiteral (IC_RIGHT (uic)) ||
2287        getSize (operandType (IC_RESULT (uic))) > 1))
2288     return;
2289
2290   if (uic->op == LEFT_OP &&
2291       (isOperandLiteral (IC_RIGHT (uic)) ||
2292        getSize (operandType (IC_RESULT (uic))) > 1))
2293     return;
2294
2295   /* make sure that the result of this icode is not on the
2296      stack, since acc is used to compute stack offset */
2297 #if 0
2298   if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
2299       OP_SYMBOL (IC_RESULT (uic))->onStack)
2300     return;
2301 #else
2302   if (isOperandOnStack(IC_RESULT(uic)))
2303     return;
2304 #endif
2305
2306   /* if either one of them in far space then we cannot */
2307   if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
2308        isOperandInFarSpace (IC_LEFT (uic))) ||
2309       (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
2310        isOperandInFarSpace (IC_RIGHT (uic))))
2311     return;
2312
2313   /* if the usage has only one operand then we can */
2314   if (IC_LEFT (uic) == NULL ||
2315       IC_RIGHT (uic) == NULL)
2316     goto accuse;
2317
2318   /* make sure this is on the left side if not
2319      a '+' since '+' is commutative */
2320   if (ic->op != '+' &&
2321       IC_LEFT (uic)->key != IC_RESULT (ic)->key)
2322     return;
2323
2324 #if 0
2325   // this is too dangerous and need further restrictions
2326   // see bug #447547
2327
2328   /* if one of them is a literal then we can */
2329   if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
2330       (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
2331     {
2332       OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2333       return;
2334     }
2335 #endif
2336
2337   /* if the other one is not on stack then we can */
2338   if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
2339       (IS_ITEMP (IC_RIGHT (uic)) ||
2340        (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
2341         !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
2342     goto accuse;
2343
2344   if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
2345       (IS_ITEMP (IC_LEFT (uic)) ||
2346        (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
2347         !OP_SYMBOL (IC_LEFT (uic))->onStack)))
2348     goto accuse;
2349
2350   return;
2351
2352 accuse:
2353   OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2354
2355
2356 }
2357
2358 /*-----------------------------------------------------------------*/
2359 /* packForPush - hueristics to reduce iCode for pushing            */
2360 /*-----------------------------------------------------------------*/
2361 static void
2362 packForPush (iCode * ic, eBBlock * ebp)
2363 {
2364   iCode *dic, *lic;
2365   bitVect *dbv;
2366
2367   if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
2368     return;
2369
2370   /* must have only definition & one usage */
2371   if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
2372       bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
2373     return;
2374
2375   /* find the definition */
2376   if (!(dic = hTabItemWithKey (iCodehTab,
2377                                bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
2378     return;
2379
2380   if (dic->op != '=' || POINTER_SET (dic))
2381     return;
2382
2383   /* make sure the right side does not have any definitions
2384      inbetween */
2385   dbv = OP_DEFS(IC_RIGHT(dic));
2386   for (lic = ic; lic && lic != dic ; lic = lic->prev) {
2387     if (bitVectBitValue(dbv,lic->key)) 
2388       return ;
2389   }
2390   /* make sure they have the same type */
2391   {
2392     sym_link *itype=operandType(IC_LEFT(ic));
2393     sym_link *ditype=operandType(IC_RIGHT(dic));
2394
2395     if (SPEC_USIGN(itype)!=SPEC_USIGN(ditype) ||
2396         SPEC_LONG(itype)!=SPEC_LONG(ditype))
2397       return;
2398   }
2399   /* extend the live range of replaced operand if needed */
2400   if (OP_SYMBOL(IC_RIGHT(dic))->liveTo < ic->seq) {
2401           OP_SYMBOL(IC_RIGHT(dic))->liveTo = ic->seq;
2402   }
2403   /* we now we know that it has one & only one def & use
2404      and the that the definition is an assignment */
2405   IC_LEFT (ic) = IC_RIGHT (dic);
2406    
2407   remiCodeFromeBBlock (ebp, dic);
2408   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2409   hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2410 }
2411
2412 /*-----------------------------------------------------------------*/
2413 /* packRegisters - does some transformations to reduce register    */
2414 /*                   pressure                                      */
2415 /*-----------------------------------------------------------------*/
2416 static void
2417 packRegisters (eBBlock * ebp)
2418 {
2419   iCode *ic;
2420   int change = 0;
2421
2422   while (1)
2423     {
2424
2425       change = 0;
2426
2427       /* look for assignments of the form */
2428       /* iTempNN = TRueSym (someoperation) SomeOperand */
2429       /*       ....                       */
2430       /* TrueSym := iTempNN:1             */
2431       for (ic = ebp->sch; ic; ic = ic->next)
2432         {
2433           /* find assignment of the form TrueSym := iTempNN:1 */
2434           if (ic->op == '=' && !POINTER_SET (ic))
2435             change += packRegsForAssign (ic, ebp);
2436         }
2437
2438       if (!change)
2439         break;
2440     }
2441
2442   for (ic = ebp->sch; ic; ic = ic->next)
2443     {
2444       /* if this is an itemp & result of an address of a true sym 
2445          then mark this as rematerialisable   */
2446       if (ic->op == ADDRESS_OF &&
2447           IS_ITEMP (IC_RESULT (ic)) &&
2448           IS_TRUE_SYMOP (IC_LEFT (ic)) &&
2449           bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2450           !OP_SYMBOL (IC_LEFT (ic))->onStack)
2451         {
2452
2453           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2454           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2455           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2456
2457         }
2458
2459       /* if straight assignment then carry remat flag if
2460          this is the only definition */
2461       if (ic->op == '=' &&
2462           !POINTER_SET (ic) &&
2463           IS_SYMOP (IC_RIGHT (ic)) &&
2464           OP_SYMBOL (IC_RIGHT (ic))->remat &&
2465           !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode) &&
2466           bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
2467         {
2468
2469           OP_SYMBOL (IC_RESULT (ic))->remat =
2470             OP_SYMBOL (IC_RIGHT (ic))->remat;
2471           OP_SYMBOL (IC_RESULT (ic))->rematiCode =
2472             OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
2473         }
2474
2475       /* if cast to a generic pointer & the pointer being
2476          cast is remat, then we can remat this cast as well */
2477       if (ic->op == CAST && 
2478           IS_SYMOP(IC_RIGHT(ic)) &&
2479           OP_SYMBOL(IC_RIGHT(ic))->remat ) {
2480               sym_link *to_type = operandType(IC_LEFT(ic));
2481               sym_link *from_type = operandType(IC_RIGHT(ic));
2482               if (IS_GENPTR(to_type) && IS_PTR(from_type)) {                  
2483                       OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2484                       OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2485                       OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2486               }
2487       }
2488
2489       /* if this is a +/- operation with a rematerizable 
2490          then mark this as rematerializable as well */
2491       if ((ic->op == '+' || ic->op == '-') &&
2492           (IS_SYMOP (IC_LEFT (ic)) &&
2493            IS_ITEMP (IC_RESULT (ic)) &&
2494            IS_OP_LITERAL (IC_RIGHT (ic))) &&
2495            OP_SYMBOL (IC_LEFT (ic))->remat &&
2496           (!IS_SYMOP (IC_RIGHT (ic)) || !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode)) &&
2497            bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1)
2498         {
2499           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2500           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2501           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2502         }
2503
2504       /* mark the pointer usages */
2505       if (POINTER_SET (ic))
2506         OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
2507
2508       if (POINTER_GET (ic))
2509         OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
2510
2511       if (!SKIP_IC2 (ic))
2512         {
2513           /* if we are using a symbol on the stack
2514              then we should say mcs51_ptrRegReq */
2515           if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
2516             mcs51_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
2517                                  OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
2518           else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
2519             mcs51_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
2520                               OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
2521           else
2522             {
2523               if (IS_SYMOP (IC_LEFT (ic)))
2524                 mcs51_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
2525                                 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
2526               if (IS_SYMOP (IC_RIGHT (ic)))
2527                 mcs51_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
2528                                OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
2529               if (IS_SYMOP (IC_RESULT (ic)))
2530                 mcs51_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
2531                               OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
2532             }
2533         }
2534
2535       /* if the condition of an if instruction
2536          is defined in the previous instruction and
2537          this is the only usage then
2538          mark the itemp as a conditional */
2539       if ((IS_CONDITIONAL (ic) ||
2540            (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic))) &&
2541           ic->next && ic->next->op == IFX &&
2542           bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
2543           isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
2544           OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2545         {
2546           OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
2547           continue;
2548         }
2549
2550       /* reduce for support function calls */
2551       if (ic->supportRtn || ic->op == '+' || ic->op == '-')
2552         packRegsForSupport (ic, ebp);
2553
2554       /* some cases the redundant moves can
2555          can be eliminated for return statements */
2556       if ((ic->op == RETURN || (ic->op == SEND && ic->argreg == 1)) &&
2557           !isOperandInFarSpace (IC_LEFT (ic)) &&
2558           options.model == MODEL_SMALL) {
2559         if (0 && options.stackAuto) {
2560           /* we should check here if acc will be clobbered for stack
2561              offset calculations */
2562         } else {
2563           packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2564         }
2565       }
2566
2567       /* if pointer set & left has a size more than
2568          one and right is not in far space */
2569       if (POINTER_SET (ic) &&
2570           !isOperandInFarSpace (IC_RIGHT (ic)) &&
2571           !OP_SYMBOL (IC_RESULT (ic))->remat &&
2572           !IS_OP_RUONLY (IC_RIGHT (ic)) &&
2573           getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
2574
2575         packRegsForOneuse (ic, IC_RESULT (ic), ebp);
2576
2577       /* if pointer get */
2578       if (POINTER_GET (ic) &&
2579           !isOperandInFarSpace (IC_RESULT (ic)) &&
2580           !OP_SYMBOL (IC_LEFT (ic))->remat &&
2581           !IS_OP_RUONLY (IC_RESULT (ic)) &&
2582           getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
2583
2584         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2585
2586
2587       /* if this is cast for intergral promotion then
2588          check if only use of  the definition of the 
2589          operand being casted/ if yes then replace
2590          the result of that arithmetic operation with 
2591          this result and get rid of the cast */
2592       if (ic->op == CAST)
2593         {
2594           sym_link *fromType = operandType (IC_RIGHT (ic));
2595           sym_link *toType = operandType (IC_LEFT (ic));
2596
2597           if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
2598               getSize (fromType) != getSize (toType) &&
2599               SPEC_USIGN (fromType) == SPEC_USIGN (toType))
2600             {
2601
2602               iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2603               if (dic)
2604                 {
2605                   if (IS_ARITHMETIC_OP (dic))
2606                     {                  
2607                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2608                       IC_RESULT (dic) = IC_RESULT (ic);
2609                       remiCodeFromeBBlock (ebp, ic);
2610                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2611                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2612                       OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2613                       ic = ic->prev;
2614                     }
2615                   else
2616                     OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
2617                 }
2618             }
2619           else
2620             {
2621
2622               /* if the type from and type to are the same
2623                  then if this is the only use then packit */
2624               if (compareType (operandType (IC_RIGHT (ic)),
2625                              operandType (IC_LEFT (ic))) == 1)
2626                 {
2627                   iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2628                   if (dic)
2629                     {
2630                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2631                       IC_RESULT (dic) = IC_RESULT (ic);
2632                       remiCodeFromeBBlock (ebp, ic);
2633                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2634                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2635                       OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2636                       ic = ic->prev;
2637                     }
2638                 }
2639             }
2640         }
2641
2642       /* pack for PUSH 
2643          iTempNN := (some variable in farspace) V1
2644          push iTempNN ;
2645          -------------
2646          push V1
2647        */
2648       if (ic->op == IPUSH)
2649         {
2650           packForPush (ic, ebp);
2651         }
2652
2653
2654       /* pack registers for accumulator use, when the
2655          result of an arithmetic or bit wise operation
2656          has only one use, that use is immediately following
2657          the defintion and the using iCode has only one
2658          operand or has two operands but one is literal &
2659          the result of that operation is not on stack then
2660          we can leave the result of this operation in acc:b
2661          combination */
2662       if ((IS_ARITHMETIC_OP (ic)
2663            || IS_CONDITIONAL(ic)
2664            || IS_BITWISE_OP (ic)
2665            || ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == CALL
2666            || (ic->op == ADDRESS_OF && isOperandOnStack (IC_LEFT (ic)))
2667           ) &&
2668           IS_ITEMP (IC_RESULT (ic)) &&
2669           getSize (operandType (IC_RESULT (ic))) <= 2)
2670
2671         packRegsForAccUse (ic);
2672     }
2673 }
2674
2675 /*-----------------------------------------------------------------*/
2676 /* assignRegisters - assigns registers to each live range as need  */
2677 /*-----------------------------------------------------------------*/
2678 void
2679 mcs51_assignRegisters (eBBlock ** ebbs, int count)
2680 {
2681   iCode *ic;
2682   int i;
2683
2684   setToNull ((void *) &_G.funcrUsed);
2685   setToNull ((void *) &_G.totRegAssigned);
2686   mcs51_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
2687   mcs51_nRegs = 8;
2688
2689   /* change assignments this will remove some
2690      live ranges reducing some register pressure */
2691   for (i = 0; i < count; i++)
2692     packRegisters (ebbs[i]);
2693
2694   if (options.dump_pack)
2695     dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
2696
2697   /* first determine for each live range the number of 
2698      registers & the type of registers required for each */
2699   regTypeNum (*ebbs);
2700
2701   /* and serially allocate registers */
2702   serialRegAssign (ebbs, count);
2703
2704   freeAllRegs ();
2705   fillGaps();
2706
2707   /* if stack was extended then tell the user */
2708   if (_G.stackExtend)
2709     {
2710 /*      werror(W_TOOMANY_SPILS,"stack", */
2711 /*             _G.stackExtend,currFunc->name,""); */
2712       _G.stackExtend = 0;
2713     }
2714
2715   if (_G.dataExtend)
2716     {
2717 /*      werror(W_TOOMANY_SPILS,"data space", */
2718 /*             _G.dataExtend,currFunc->name,""); */
2719       _G.dataExtend = 0;
2720     }
2721
2722   /* after that create the register mask
2723      for each of the instruction */
2724   createRegMask (ebbs, count);
2725
2726   /* redo that offsets for stacked automatic variables */
2727   redoStackOffsets ();
2728
2729   if (options.dump_rassgn)
2730     {
2731       dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
2732       dumpLiveRanges (DUMP_LRANGE, liveRanges);
2733     }
2734
2735   /* do the overlaysegment stuff SDCCmem.c */
2736   doOverlays (ebbs, count);
2737
2738   /* now get back the chain */
2739   ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
2740
2741   gen51Code (ic);
2742
2743   /* free up any _G.stackSpil locations allocated */
2744   applyToSet (_G.stackSpil, deallocStackSpil);
2745   _G.slocNum = 0;
2746   setToNull ((void **) &_G.stackSpil);
2747   setToNull ((void **) &_G.spiltSet);
2748   /* mark all registers as free */
2749   freeAllRegs ();
2750
2751   return;
2752 }