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