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