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