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