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