* src/mcs51/ralloc.c (packRegsForAssign): fixed bug #930931, fixed check for bitfields
[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 (ic) && !POINTER_SET (ic))
1993     {
1994       sym_link *etype = operandType (IC_RESULT (dic));
1995       if (IS_BITFIELD (etype))
1996         {
1997           /* if result is a bit too then it's ok */
1998           etype = operandType (IC_RESULT (ic));
1999           if (!IS_BITFIELD (etype))
2000             {
2001               return 0;
2002             }
2003        }
2004     }
2005 #if 0
2006   /* if assignment then check that right is not a bit */
2007   if (ASSIGNMENT (dic) && !POINTER_SET (dic))
2008     {
2009       sym_link *etype = operandType (IC_RIGHT (dic));
2010       if (IS_BITFIELD (etype))
2011         {
2012           /* if result is a bit too then it's ok */
2013           etype = operandType (IC_RESULT (dic));
2014           if (!IS_BITFIELD (etype))
2015             return 0;
2016         }
2017     }
2018 #endif
2019   /* if the result is on stack or iaccess then it must be
2020      the same atleast one of the operands */
2021   if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2022       OP_SYMBOL (IC_RESULT (ic))->iaccess)
2023     {
2024
2025       /* the operation has only one symbol
2026          operator then we can pack */
2027       if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2028           (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2029         goto pack;
2030
2031       if (!((IC_LEFT (dic) &&
2032              IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2033             (IC_RIGHT (dic) &&
2034              IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2035         return 0;
2036     }
2037 pack:
2038   /* found the definition */
2039   /* replace the result with the result of */
2040   /* this assignment and remove this assignment */
2041   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2042   ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
2043
2044   if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2045     {
2046       OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2047     }
2048   // TODO: and the otherway around?
2049
2050   /* delete from liverange table also 
2051      delete from all the points inbetween and the new
2052      one */
2053   for (sic = dic; sic != ic; sic = sic->next)
2054     {
2055       bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2056       if (IS_ITEMP (IC_RESULT (dic)))
2057         bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2058     }
2059
2060   remiCodeFromeBBlock (ebp, ic);
2061   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2062   hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2063   OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2064   return 1;
2065 }
2066
2067 /*------------------------------------------------------------------*/
2068 /* findAssignToSym : scanning backwards looks for first assig found */
2069 /*------------------------------------------------------------------*/
2070 static iCode *
2071 findAssignToSym (operand * op, iCode * ic)
2072 {
2073   iCode *dic;
2074
2075   /* This routine is used to find sequences like
2076      iTempAA = FOO;
2077      ...;  (intervening ops don't use iTempAA or modify FOO)
2078      blah = blah + iTempAA;
2079
2080      and eliminate the use of iTempAA, freeing up its register for
2081      other uses.
2082   */
2083      
2084   for (dic = ic->prev; dic; dic = dic->prev)
2085     {
2086
2087       /* if definition by assignment */
2088       if (dic->op == '=' &&
2089           !POINTER_SET (dic) &&
2090           IC_RESULT (dic)->key == op->key
2091 /*          &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2092         )
2093         break;  /* found where this temp was defined */
2094
2095       /* if we find an usage then we cannot delete it */
2096       
2097       if (dic->op == IFX)
2098         {
2099           if (IC_COND (dic) && IC_COND (dic)->key == op->key)
2100             return NULL;
2101         }
2102       else if (dic->op == JUMPTABLE)
2103         {
2104           if (IC_JTCOND (dic) && IC_JTCOND (dic)->key == op->key)
2105             return NULL;
2106         }
2107       else
2108         {
2109           if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2110             return NULL;
2111
2112           if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2113             return NULL;
2114
2115           if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2116             return NULL;
2117         }
2118     }
2119
2120   if (!dic)
2121     return NULL;   /* didn't find any assignment to op */
2122
2123   /* we are interested only if defined in far space */
2124   /* or in stack space in case of + & - */
2125   
2126   /* if assigned to a non-symbol then don't repack regs */
2127   if (!IS_SYMOP (IC_RIGHT (dic)))
2128     return NULL;
2129   
2130   /* if the symbol is volatile then we should not */
2131   if (isOperandVolatile (IC_RIGHT (dic), TRUE))
2132     return NULL;
2133   /* XXX TODO --- should we be passing FALSE to isOperandVolatile()?
2134      What does it mean for an iTemp to be volatile, anyway? Passing
2135      TRUE is more cautious but may prevent possible optimizations */
2136
2137   /* if the symbol is in far space then we should not */
2138   if (isOperandInFarSpace (IC_RIGHT (dic)))
2139     return NULL;
2140   
2141   /* for + & - operations make sure that
2142      if it is on the stack it is the same
2143      as one of the three operands */
2144   if ((ic->op == '+' || ic->op == '-') &&
2145       OP_SYMBOL (IC_RIGHT (dic))->onStack)
2146     {
2147       
2148       if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2149           IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2150           IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2151         return NULL;
2152     }
2153   
2154   /* now make sure that the right side of dic
2155      is not defined between ic & dic */
2156   if (dic)
2157     {
2158       iCode *sic = dic->next;
2159
2160       for (; sic != ic; sic = sic->next)
2161         if (IC_RESULT (sic) &&
2162             IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2163           return NULL;
2164     }
2165
2166   return dic;
2167 }
2168
2169 /*-----------------------------------------------------------------*/
2170 /* reassignAliasedSym - used by packRegsForSupport to replace      */
2171 /*                      redundant iTemp with equivalent symbol     */
2172 /*-----------------------------------------------------------------*/
2173 static void
2174 reassignAliasedSym (eBBlock *ebp, iCode *assignment, iCode *use, operand *op)
2175 {
2176   iCode *ic;
2177   unsigned oldSymKey, newSymKey;
2178
2179   oldSymKey = op->key;
2180   newSymKey = IC_RIGHT(assignment)->key;
2181
2182   /* only track live ranges of compiler-generated temporaries */
2183   if (!IS_ITEMP(IC_RIGHT(assignment)))
2184     newSymKey = 0;
2185
2186   /* update the live-value bitmaps */
2187   for (ic = assignment; ic != use; ic = ic->next) {
2188     bitVectUnSetBit (ic->rlive, oldSymKey);
2189     if (newSymKey != 0)
2190       ic->rlive = bitVectSetBit (ic->rlive, newSymKey);
2191   }
2192
2193   /* update the sym of the used operand */
2194   OP_SYMBOL(op) = OP_SYMBOL(IC_RIGHT(assignment));
2195   op->key = OP_SYMBOL(op)->key;
2196   OP_SYMBOL(op)->accuse = 0;
2197   
2198   /* update the sym's liverange */
2199   if ( OP_LIVETO(op) < ic->seq )
2200     setToRange(op, ic->seq, FALSE);
2201
2202   /* remove the assignment iCode now that its result is unused */
2203   remiCodeFromeBBlock (ebp, assignment);
2204   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(assignment))->defs, assignment->key);
2205   hTabDeleteItem (&iCodehTab, assignment->key, assignment, DELETE_ITEM, NULL);
2206 }
2207   
2208
2209 /*-----------------------------------------------------------------*/
2210 /* packRegsForSupport :- reduce some registers for support calls   */
2211 /*-----------------------------------------------------------------*/
2212 static int
2213 packRegsForSupport (iCode * ic, eBBlock * ebp)
2214 {
2215   iCode *dic;
2216   
2217   /* for the left & right operand :- look to see if the
2218      left was assigned a true symbol in far space in that
2219      case replace them */
2220
2221   if (IS_ITEMP (IC_LEFT (ic)) &&
2222       OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2223     {
2224       dic = findAssignToSym (IC_LEFT (ic), ic);
2225
2226       if (dic)
2227         {
2228           /* found it we need to remove it from the block */
2229           reassignAliasedSym (ebp, dic, ic, IC_LEFT(ic));
2230           return 1;
2231         }
2232     }
2233
2234   /* do the same for the right operand */
2235   if (IS_ITEMP (IC_RIGHT (ic)) &&
2236       OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2237     {
2238       iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2239
2240       if (dic)
2241         {
2242           /* if this is a subtraction & the result
2243              is a true symbol in far space then don't pack */
2244           if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
2245             {
2246               sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
2247               if (IN_FARSPACE (SPEC_OCLS (etype)))
2248                 return 0;
2249             }
2250           /* found it we need to remove it from the
2251              block */
2252           reassignAliasedSym (ebp, dic, ic, IC_RIGHT(ic));
2253           
2254           return 1;
2255         }
2256     }
2257
2258   return 0;
2259 }
2260
2261 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
2262
2263
2264 /*-----------------------------------------------------------------*/
2265 /* packRegsForOneuse : - will reduce some registers for single Use */
2266 /*-----------------------------------------------------------------*/
2267 static iCode *
2268 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
2269 {
2270   bitVect *uses;
2271   iCode *dic, *sic;
2272
2273   /* if returning a literal then do nothing */
2274   if (!IS_SYMOP (op))
2275     return NULL;
2276
2277   /* only upto 2 bytes since we cannot predict
2278      the usage of b, & acc */
2279   if (getSize (operandType (op)) > (fReturnSizeMCS51 - 2))
2280     return NULL;
2281
2282   if (ic->op != RETURN &&
2283       ic->op != SEND &&
2284       !POINTER_SET (ic) &&
2285       !POINTER_GET (ic))
2286     return NULL;
2287   
2288   if (ic->op == SEND && ic->argreg != 1) return NULL;
2289
2290   /* this routine will mark the a symbol as used in one 
2291      instruction use only && if the defintion is local 
2292      (ie. within the basic block) && has only one definition &&
2293      that definiion is either a return value from a 
2294      function or does not contain any variables in
2295      far space */
2296   uses = bitVectCopy (OP_USES (op));
2297   bitVectUnSetBit (uses, ic->key);      /* take away this iCode */
2298   if (!bitVectIsZero (uses))    /* has other uses */
2299     return NULL;
2300
2301   /* if it has only one defintion */
2302   if (bitVectnBitsOn (OP_DEFS (op)) > 1)
2303     return NULL;                /* has more than one definition */
2304
2305   /* get that definition */
2306   if (!(dic =
2307         hTabItemWithKey (iCodehTab,
2308                          bitVectFirstBit (OP_DEFS (op)))))
2309     return NULL;
2310
2311   /* if that only usage is a cast */
2312   if (dic->op == CAST) {
2313     /* to a bigger type */
2314     if (getSize(OP_SYM_TYPE(IC_RESULT(dic))) > 
2315         getSize(OP_SYM_TYPE(IC_RIGHT(dic)))) {
2316       /* than we can not, since we cannot predict the usage of b & acc */
2317       return NULL;
2318     }
2319   }
2320
2321   /* found the definition now check if it is local */
2322   if (dic->seq < ebp->fSeq ||
2323       dic->seq > ebp->lSeq)
2324     return NULL;                /* non-local */
2325
2326   /* now check if it is the return from
2327      a function call */
2328   if (dic->op == CALL || dic->op == PCALL)
2329     {
2330       if (ic->op != SEND && ic->op != RETURN &&
2331           !POINTER_SET(ic) && !POINTER_GET(ic))
2332         {
2333           OP_SYMBOL (op)->ruonly = 1;
2334           return dic;
2335         }
2336       dic = dic->next;
2337     }
2338
2339
2340   /* otherwise check that the definition does
2341      not contain any symbols in far space */
2342   if (isOperandInFarSpace (IC_LEFT (dic)) ||
2343       isOperandInFarSpace (IC_RIGHT (dic)) ||
2344       IS_OP_RUONLY (IC_LEFT (ic)) ||
2345       IS_OP_RUONLY (IC_RIGHT (ic)))
2346     {
2347       return NULL;
2348     }
2349
2350   /* if pointer set then make sure the pointer
2351      is one byte */
2352   if (POINTER_SET (dic) &&
2353       !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2354     return NULL;
2355
2356   if (POINTER_GET (dic) &&
2357       !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2358     return NULL;
2359
2360   sic = dic;
2361
2362   /* also make sure the intervenening instructions
2363      don't have any thing in far space */
2364   for (dic = dic->next; dic && dic != ic && sic != ic; dic = dic->next)
2365     {
2366
2367       /* if there is an intervening function call then no */
2368       if (dic->op == CALL || dic->op == PCALL)
2369         return NULL;
2370       /* if pointer set then make sure the pointer
2371          is one byte */
2372       if (POINTER_SET (dic) &&
2373           !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2374         return NULL;
2375
2376       if (POINTER_GET (dic) &&
2377           !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2378         return NULL;
2379
2380       /* if address of & the result is remat the okay */
2381       if (dic->op == ADDRESS_OF &&
2382           OP_SYMBOL (IC_RESULT (dic))->remat)
2383         continue;
2384
2385       /* if operand has size of three or more & this
2386          operation is a '*','/' or '%' then 'b' may
2387          cause a problem */
2388       if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
2389           getSize (operandType (op)) >= 3)
2390         return NULL;
2391
2392       /* if left or right or result is in far space */
2393       if (isOperandInFarSpace (IC_LEFT (dic)) ||
2394           isOperandInFarSpace (IC_RIGHT (dic)) ||
2395           isOperandInFarSpace (IC_RESULT (dic)) ||
2396           IS_OP_RUONLY (IC_LEFT (dic)) ||
2397           IS_OP_RUONLY (IC_RIGHT (dic)) ||
2398           IS_OP_RUONLY (IC_RESULT (dic)))
2399         {
2400           return NULL;
2401         }
2402       /* if left or right or result is on stack */
2403       if (isOperandOnStack(IC_LEFT(dic)) ||
2404           isOperandOnStack(IC_RIGHT(dic)) ||
2405           isOperandOnStack(IC_RESULT(dic))) {
2406         return NULL;
2407       }
2408     }
2409
2410   OP_SYMBOL (op)->ruonly = 1;
2411   return sic;
2412 }
2413
2414 /*-----------------------------------------------------------------*/
2415 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
2416 /*-----------------------------------------------------------------*/
2417 static bool
2418 isBitwiseOptimizable (iCode * ic)
2419 {
2420   sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
2421   sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
2422
2423   /* bitwise operations are considered optimizable
2424      under the following conditions (Jean-Louis VERN) 
2425
2426      x & lit
2427      bit & bit
2428      bit & x
2429      bit ^ bit
2430      bit ^ x
2431      x   ^ lit
2432      x   | lit
2433      bit | bit
2434      bit | x
2435   */
2436   if (IS_LITERAL(rtype) ||
2437       (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
2438     return TRUE;
2439   else
2440     return FALSE;
2441 }
2442
2443 /*-----------------------------------------------------------------*/
2444 /* isCommutativeOp - tests whether this op cares what order its    */
2445 /*                   operands are in                               */
2446 /*-----------------------------------------------------------------*/
2447 bool isCommutativeOp(unsigned int op)
2448 {
2449   if (op == '+' || op == '*' || op == EQ_OP ||
2450       op == '^' || op == '|' || op == BITWISEAND)
2451     return TRUE;
2452   else
2453     return FALSE;
2454 }
2455
2456 /*-----------------------------------------------------------------*/
2457 /* operandUsesAcc - determines whether the code generated for this */
2458 /*                  operand will have to use the accumulator       */
2459 /*-----------------------------------------------------------------*/
2460 bool operandUsesAcc(operand *op)
2461 {
2462   if (!op)
2463     return FALSE;
2464
2465   if (IS_SYMOP(op)) {
2466     symbol *sym = OP_SYMBOL(op);
2467     memmap *symspace;
2468
2469     if (sym->accuse)
2470       return TRUE;  /* duh! */
2471
2472     if (IN_STACK(sym->etype) || sym->onStack ||
2473         (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
2474       return TRUE;  /* acc is used to calc stack offset */
2475
2476     if (IS_ITEMP(op))
2477       {
2478         if (SPIL_LOC(op)) {
2479           sym = SPIL_LOC(op);  /* if spilled, look at spill location */
2480         } else {
2481           return FALSE;  /* more checks? */
2482         }
2483       }
2484
2485     symspace = SPEC_OCLS(sym->etype);
2486
2487     if (sym->iaccess && symspace->paged)
2488       return TRUE;  /* must fetch paged indirect sym via accumulator */
2489     
2490     if (IN_BITSPACE(symspace))
2491       return TRUE;  /* fetching bit vars uses the accumulator */
2492     
2493     if (IN_FARSPACE(symspace) || IN_CODESPACE(symspace)) 
2494       return TRUE;  /* fetched via accumulator and dptr */
2495   }
2496
2497   return FALSE;
2498 }
2499
2500 /*-----------------------------------------------------------------*/
2501 /* packRegsForAccUse - pack registers for acc use                  */
2502 /*-----------------------------------------------------------------*/
2503 static void
2504 packRegsForAccUse (iCode * ic)
2505 {
2506   iCode *uic;
2507
2508   /* if this is an aggregate, e.g. a one byte char array */
2509   if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
2510     return;
2511   }
2512
2513   /* if we are calling a reentrant function that has stack parameters */
2514   if (ic->op == CALL &&
2515        IFFUNC_ISREENT(operandType(IC_LEFT(ic))) &&
2516        FUNC_HASSTACKPARM(operandType(IC_LEFT(ic))))
2517       return;
2518
2519   if (ic->op == PCALL &&
2520        IFFUNC_ISREENT(operandType(IC_LEFT(ic))->next) &&
2521        FUNC_HASSTACKPARM(operandType(IC_LEFT(ic))->next))
2522       return;
2523
2524   /* if + or - then it has to be one byte result */
2525   if ((ic->op == '+' || ic->op == '-')
2526       && getSize (operandType (IC_RESULT (ic))) > 1)
2527     return;
2528
2529   /* if shift operation make sure right side is not a literal */
2530   if (ic->op == RIGHT_OP &&
2531       (isOperandLiteral (IC_RIGHT (ic)) ||
2532        getSize (operandType (IC_RESULT (ic))) > 1))
2533     return;
2534
2535   if (ic->op == LEFT_OP &&
2536       (isOperandLiteral (IC_RIGHT (ic)) ||
2537        getSize (operandType (IC_RESULT (ic))) > 1))
2538     return;
2539
2540   if (IS_BITWISE_OP (ic) &&
2541       getSize (operandType (IC_RESULT (ic))) > 1)
2542     return;
2543
2544
2545   /* has only one definition */
2546   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
2547     return;
2548
2549   /* has only one use */
2550   if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
2551     return;
2552
2553   /* and the usage immediately follows this iCode */
2554   if (!(uic = hTabItemWithKey (iCodehTab,
2555                                bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
2556     return;
2557
2558   if (ic->next != uic)
2559     return;
2560
2561   /* if it is a conditional branch then we definitely can */
2562   if (uic->op == IFX)
2563     goto accuse;
2564
2565   if (uic->op == JUMPTABLE)
2566     return;
2567
2568   if (POINTER_SET (uic) &&
2569       getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
2570     return;
2571
2572   /* if the usage is not is an assignment
2573      or an arithmetic / bitwise / shift operation then not */
2574   if (uic->op != '=' &&
2575       !IS_ARITHMETIC_OP (uic) &&
2576       !IS_BITWISE_OP (uic) &&
2577       uic->op != LEFT_OP &&
2578       uic->op != RIGHT_OP)
2579     return;
2580
2581   /* if used in ^ operation then make sure right is not a 
2582      literal (WIML: Why is this?) */
2583   if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
2584     return;
2585
2586   /* if shift operation make sure right side is not a literal */
2587   /* WIML: Why is this? */
2588   if (uic->op == RIGHT_OP &&
2589       (isOperandLiteral (IC_RIGHT (uic)) ||
2590        getSize (operandType (IC_RESULT (uic))) > 1))
2591     return;
2592   if (uic->op == LEFT_OP &&
2593       (isOperandLiteral (IC_RIGHT (uic)) ||
2594        getSize (operandType (IC_RESULT (uic))) > 1))
2595     return;
2596
2597   /* make sure that the result of this icode is not on the
2598      stack, since acc is used to compute stack offset */
2599 #if 0
2600   if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
2601       OP_SYMBOL (IC_RESULT (uic))->onStack)
2602     return;
2603 #else
2604   if (isOperandOnStack(IC_RESULT(uic)))
2605     return;
2606 #endif
2607
2608   /* if the usage has only one operand then we can */
2609   if (IC_LEFT (uic) == NULL ||
2610       IC_RIGHT (uic) == NULL)
2611     goto accuse;
2612
2613   /* if the other operand uses the accumulator then we cannot */
2614   if ( (IC_LEFT(uic)->key == IC_RESULT(ic)->key &&
2615         operandUsesAcc(IC_RIGHT(uic))) ||
2616        (IC_RIGHT(uic)->key == IC_RESULT(ic)->key &&
2617         operandUsesAcc(IC_LEFT(uic))) ) 
2618     return;
2619
2620   /* make sure this is on the left side if not commutative */
2621   /* except for '-', which has been written to be able to
2622      handle reversed operands */
2623   if (!(isCommutativeOp(ic->op) || ic->op == '-') &&
2624        IC_LEFT (uic)->key != IC_RESULT (ic)->key)
2625     return;
2626
2627 #if 0
2628   // this is too dangerous and need further restrictions
2629   // see bug #447547
2630
2631   /* if one of them is a literal then we can */
2632   if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
2633       (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
2634     {
2635       OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2636       return;
2637     }
2638 #endif
2639
2640 accuse:
2641   OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2642
2643 }
2644
2645 /*-----------------------------------------------------------------*/
2646 /* packForPush - hueristics to reduce iCode for pushing            */
2647 /*-----------------------------------------------------------------*/
2648 static void
2649 packForPush (iCode * ic, eBBlock ** ebpp, int blockno)
2650 {
2651   iCode *dic, *lic;
2652   bitVect *dbv;
2653   struct eBBlock * ebp=ebpp[blockno];
2654
2655   if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
2656     return;
2657
2658   /* must have only definition & one usage */
2659   if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
2660       bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
2661     return;
2662
2663   /* find the definition */
2664   if (!(dic = hTabItemWithKey (iCodehTab,
2665                                bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
2666     return;
2667
2668   if (dic->op != '=' || POINTER_SET (dic))
2669     return;
2670
2671   if (dic->seq < ebp->fSeq) { // Evelyn did this
2672     int i;
2673     for (i=0; i<blockno; i++) {
2674       if (dic->seq >= ebpp[i]->fSeq && dic->seq <= ebpp[i]->lSeq) {
2675         ebp=ebpp[i];
2676         break;
2677       }
2678     }
2679     wassert (i!=blockno); // no way to recover from here
2680   }
2681
2682   if (IS_SYMOP(IC_RIGHT(dic))) {
2683     /* make sure the right side does not have any definitions
2684        inbetween */
2685     dbv = OP_DEFS(IC_RIGHT(dic));
2686     for (lic = ic; lic && lic != dic ; lic = lic->prev) {
2687       if (bitVectBitValue(dbv,lic->key)) 
2688         return ;
2689     }
2690     /* make sure they have the same type */
2691     if (IS_SPEC(operandType(IC_LEFT(ic))))
2692     {
2693       sym_link *itype=operandType(IC_LEFT(ic));
2694       sym_link *ditype=operandType(IC_RIGHT(dic));
2695       
2696       if (SPEC_USIGN(itype)!=SPEC_USIGN(ditype) ||
2697           SPEC_LONG(itype)!=SPEC_LONG(ditype))
2698         return;
2699     }
2700     /* extend the live range of replaced operand if needed */
2701     if (OP_SYMBOL(IC_RIGHT(dic))->liveTo < ic->seq) {
2702       OP_SYMBOL(IC_RIGHT(dic))->liveTo = ic->seq;
2703     }
2704     bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2705   } 
2706
2707   /* we now we know that it has one & only one def & use
2708      and the that the definition is an assignment */
2709   ReplaceOpWithCheaperOp(&IC_LEFT (ic), IC_RIGHT (dic));
2710   remiCodeFromeBBlock (ebp, dic);
2711   hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2712 }
2713
2714 /*-----------------------------------------------------------------*/
2715 /* packRegisters - does some transformations to reduce register    */
2716 /*                   pressure                                      */
2717 /*-----------------------------------------------------------------*/
2718 static void
2719 packRegisters (eBBlock ** ebpp, int blockno)
2720 {
2721   iCode *ic;
2722   int change = 0;
2723   eBBlock *ebp=ebpp[blockno];
2724
2725   while (1)
2726     {
2727
2728       change = 0;
2729
2730       /* look for assignments of the form */
2731       /* iTempNN = TRueSym (someoperation) SomeOperand */
2732       /*       ....                       */
2733       /* TrueSym := iTempNN:1             */
2734       for (ic = ebp->sch; ic; ic = ic->next)
2735         {
2736           /* find assignment of the form TrueSym := iTempNN:1 */
2737           if (ic->op == '=' && !POINTER_SET (ic))
2738             change += packRegsForAssign (ic, ebp);
2739         }
2740
2741       if (!change)
2742         break;
2743     }
2744
2745   for (ic = ebp->sch; ic; ic = ic->next)
2746     {
2747       /* if this is an itemp & result of an address of a true sym 
2748          then mark this as rematerialisable   */
2749       if (ic->op == ADDRESS_OF &&
2750           IS_ITEMP (IC_RESULT (ic)) &&
2751           IS_TRUE_SYMOP (IC_LEFT (ic)) &&
2752           bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2753           !OP_SYMBOL (IC_LEFT (ic))->onStack)
2754         {
2755
2756           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2757           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2758           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2759
2760         }
2761
2762       /* if straight assignment then carry remat flag if
2763          this is the only definition */
2764       if (ic->op == '=' &&
2765           !POINTER_SET (ic) &&
2766           IS_SYMOP (IC_RIGHT (ic)) &&
2767           OP_SYMBOL (IC_RIGHT (ic))->remat &&
2768           !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode) &&
2769           bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
2770         {
2771
2772           OP_SYMBOL (IC_RESULT (ic))->remat =
2773             OP_SYMBOL (IC_RIGHT (ic))->remat;
2774           OP_SYMBOL (IC_RESULT (ic))->rematiCode =
2775             OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
2776         }
2777
2778       /* if cast to a generic pointer & the pointer being
2779          cast is remat, then we can remat this cast as well */
2780       if (ic->op == CAST && 
2781           IS_SYMOP(IC_RIGHT(ic)) &&
2782           OP_SYMBOL(IC_RIGHT(ic))->remat &&
2783           bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1) {
2784               sym_link *to_type = operandType(IC_LEFT(ic));
2785               sym_link *from_type = operandType(IC_RIGHT(ic));
2786               if (IS_GENPTR(to_type) && IS_PTR(from_type)) {                  
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
2793       /* if this is a +/- operation with a rematerizable 
2794          then mark this as rematerializable as well */
2795       if ((ic->op == '+' || ic->op == '-') &&
2796           (IS_SYMOP (IC_LEFT (ic)) &&
2797            IS_ITEMP (IC_RESULT (ic)) &&
2798            IS_OP_LITERAL (IC_RIGHT (ic))) &&
2799            OP_SYMBOL (IC_LEFT (ic))->remat &&
2800           (!IS_SYMOP (IC_RIGHT (ic)) || !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode)) &&
2801            bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1)
2802         {
2803           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2804           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2805           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2806         }
2807
2808       /* mark the pointer usages */
2809       if (POINTER_SET (ic))
2810         OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
2811
2812       if (POINTER_GET (ic) &&
2813           IS_SYMOP(IC_LEFT (ic)))
2814         OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
2815
2816       if (!SKIP_IC2 (ic))
2817         {
2818           /* if we are using a symbol on the stack
2819              then we should say mcs51_ptrRegReq */
2820           if (options.useXstack && ic->parmPush
2821               && (ic->op == IPUSH || ic->op == IPOP))
2822             mcs51_ptrRegReq++;
2823           if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
2824             mcs51_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
2825                                  OP_SYMBOL (IC_COND (ic))->iaccess ||
2826                                  SPEC_OCLS(OP_SYMBOL (IC_COND (ic))->etype) == idata) ? 1 : 0);
2827           else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
2828             mcs51_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
2829                               OP_SYMBOL (IC_JTCOND (ic))->iaccess ||
2830                               SPEC_OCLS(OP_SYMBOL (IC_JTCOND (ic))->etype) == idata) ? 1 : 0);
2831           else
2832             {
2833               if (IS_SYMOP (IC_LEFT (ic)))
2834                 mcs51_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
2835                                 OP_SYMBOL (IC_LEFT (ic))->iaccess ||
2836                                 SPEC_OCLS(OP_SYMBOL (IC_LEFT (ic))->etype) == idata) ? 1 : 0);
2837               if (IS_SYMOP (IC_RIGHT (ic)))
2838                 mcs51_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
2839                                OP_SYMBOL (IC_RIGHT (ic))->iaccess ||
2840                                SPEC_OCLS(OP_SYMBOL (IC_RIGHT (ic))->etype) == idata) ? 1 : 0);
2841               if (IS_SYMOP (IC_RESULT (ic)))
2842                 mcs51_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
2843                               OP_SYMBOL (IC_RESULT (ic))->iaccess ||
2844                               SPEC_OCLS(OP_SYMBOL (IC_RESULT (ic))->etype) == idata) ? 1 : 0);
2845               if (POINTER_GET (ic) && IS_SYMOP (IC_LEFT (ic))
2846                   && getSize (OP_SYMBOL (IC_LEFT (ic))->type) <= (unsigned int) PTRSIZE)
2847                 mcs51_ptrRegReq ++;
2848               if (POINTER_SET (ic) && IS_SYMOP (IC_RESULT (ic))
2849                   && getSize (OP_SYMBOL (IC_RESULT (ic))->type) <= (unsigned int) PTRSIZE)
2850                 mcs51_ptrRegReq ++;
2851             }
2852         }
2853
2854       /* if the condition of an if instruction
2855          is defined in the previous instruction and
2856          this is the only usage then
2857          mark the itemp as a conditional */
2858       if ((IS_CONDITIONAL (ic) ||
2859            (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic))) &&
2860           ic->next && ic->next->op == IFX &&
2861           bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
2862           isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
2863           OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2864         {
2865           OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
2866           continue;
2867         }
2868
2869       /* reduce for support function calls */
2870       if (ic->supportRtn || ic->op == '+' || ic->op == '-')
2871         packRegsForSupport (ic, ebp);
2872
2873       /* some cases the redundant moves can
2874          can be eliminated for return statements */
2875       if ((ic->op == RETURN || (ic->op == SEND && ic->argreg == 1)) &&
2876           !isOperandInFarSpace (IC_LEFT (ic)) &&
2877           options.model == MODEL_SMALL) {
2878         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2879       }
2880
2881       /* if pointer set & left has a size more than
2882          one and right is not in far space */
2883       if (POINTER_SET (ic) &&
2884           !isOperandInFarSpace (IC_RIGHT (ic)) &&
2885           !OP_SYMBOL (IC_RESULT (ic))->remat &&
2886           !IS_OP_RUONLY (IC_RIGHT (ic)) &&
2887           getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
2888         packRegsForOneuse (ic, IC_RESULT (ic), ebp);
2889
2890       /* if pointer get */
2891       if (POINTER_GET (ic) &&
2892           IS_SYMOP (IC_LEFT (ic)) &&
2893           !isOperandInFarSpace (IC_RESULT (ic)) &&
2894           !OP_SYMBOL (IC_LEFT (ic))->remat &&
2895           !IS_OP_RUONLY (IC_RESULT (ic)) &&
2896           getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
2897         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2898
2899
2900       /* if this is cast for intergral promotion then
2901          check if only use of  the definition of the 
2902          operand being casted/ if yes then replace
2903          the result of that arithmetic operation with 
2904          this result and get rid of the cast */
2905       if (ic->op == CAST)
2906         {
2907           sym_link *fromType = operandType (IC_RIGHT (ic));
2908           sym_link *toType = operandType (IC_LEFT (ic));
2909
2910           if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
2911               getSize (fromType) != getSize (toType) &&
2912               SPEC_USIGN (fromType) == SPEC_USIGN (toType))
2913             {
2914
2915               iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2916               if (dic)
2917                 {
2918                   if (IS_ARITHMETIC_OP (dic))
2919                     {                  
2920                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2921                       ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
2922                       remiCodeFromeBBlock (ebp, ic);
2923                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2924                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2925                       OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2926                       ic = ic->prev;
2927                     }
2928                   else
2929                     OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
2930                 }
2931             }
2932           else
2933             {
2934
2935               /* if the type from and type to are the same
2936                  then if this is the only use then packit */
2937               if (compareType (operandType (IC_RIGHT (ic)),
2938                              operandType (IC_LEFT (ic))) == 1)
2939                 {
2940                   iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2941                   if (dic)
2942                     {
2943                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2944                       ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
2945                       remiCodeFromeBBlock (ebp, ic);
2946                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2947                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2948                       OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2949                       ic = ic->prev;
2950                     }
2951                 }
2952             }
2953         }
2954
2955       /* pack for PUSH 
2956          iTempNN := (some variable in farspace) V1
2957          push iTempNN ;
2958          -------------
2959          push V1
2960        */
2961       if (ic->op == IPUSH)
2962         {
2963           packForPush (ic, ebpp, blockno);
2964         }
2965
2966
2967       /* pack registers for accumulator use, when the
2968          result of an arithmetic or bit wise operation
2969          has only one use, that use is immediately following
2970          the defintion and the using iCode has only one
2971          operand or has two operands but one is literal &
2972          the result of that operation is not on stack then
2973          we can leave the result of this operation in acc:b
2974          combination */
2975       if ((IS_ARITHMETIC_OP (ic)
2976            || IS_CONDITIONAL(ic)
2977            || IS_BITWISE_OP (ic)
2978            || ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == CALL
2979            || (ic->op == ADDRESS_OF && isOperandOnStack (IC_LEFT (ic)))
2980           ) &&
2981           IS_ITEMP (IC_RESULT (ic)) &&
2982           getSize (operandType (IC_RESULT (ic))) <= 2)
2983
2984         packRegsForAccUse (ic);
2985     }
2986 }
2987
2988 /*-----------------------------------------------------------------*/
2989 /* assignRegisters - assigns registers to each live range as need  */
2990 /*-----------------------------------------------------------------*/
2991 void
2992 mcs51_assignRegisters (eBBlock ** ebbs, int count)
2993 {
2994   iCode *ic;
2995   int i;
2996
2997   setToNull ((void *) &_G.funcrUsed);
2998   setToNull ((void *) &_G.regAssigned);
2999   setToNull ((void *) &_G.totRegAssigned);
3000   mcs51_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3001   mcs51_nRegs = 8;
3002
3003   /* change assignments this will remove some
3004      live ranges reducing some register pressure */
3005   
3006   for (i = 0; i < count; i++)
3007     packRegisters (ebbs, i);
3008
3009   /* liveranges probably changed by register packing
3010      so we compute them again */
3011   recomputeLiveRanges (ebbs, count);
3012
3013   if (options.dump_pack)
3014     dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3015
3016   /* first determine for each live range the number of 
3017      registers & the type of registers required for each */
3018   regTypeNum (*ebbs);
3019
3020   /* and serially allocate registers */
3021   serialRegAssign (ebbs, count);
3022
3023   freeAllRegs ();
3024   //setToNull ((void *) &_G.regAssigned);
3025   //setToNull ((void *) &_G.totRegAssigned);
3026   fillGaps();
3027
3028   /* if stack was extended then tell the user */
3029   if (_G.stackExtend)
3030     {
3031 /*      werror(W_TOOMANY_SPILS,"stack", */
3032 /*             _G.stackExtend,currFunc->name,""); */
3033       _G.stackExtend = 0;
3034     }
3035
3036   if (_G.dataExtend)
3037     {
3038 /*      werror(W_TOOMANY_SPILS,"data space", */
3039 /*             _G.dataExtend,currFunc->name,""); */
3040       _G.dataExtend = 0;
3041     }
3042
3043   /* after that create the register mask
3044      for each of the instruction */
3045   createRegMask (ebbs, count);
3046
3047   /* redo that offsets for stacked automatic variables */
3048   if (currFunc) {
3049     redoStackOffsets ();
3050   }
3051
3052   /* make sure r0 & r1 are flagged as used if they might be used */
3053   /* as pointers */
3054   if (currFunc && mcs51_ptrRegReq)
3055     {
3056       currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, R0_IDX);
3057       currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, R1_IDX);
3058     }
3059
3060   if (options.dump_rassgn)
3061     {
3062       dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3063       dumpLiveRanges (DUMP_LRANGE, liveRanges);
3064     }
3065
3066   /* do the overlaysegment stuff SDCCmem.c */
3067   doOverlays (ebbs, count);
3068
3069   /* now get back the chain */
3070   ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3071
3072   gen51Code (ic);
3073
3074   /* free up any _G.stackSpil locations allocated */
3075   applyToSet (_G.stackSpil, deallocStackSpil);
3076   _G.slocNum = 0;
3077   setToNull ((void *) &_G.stackSpil);
3078   setToNull ((void *) &_G.spiltSet);
3079   /* mark all registers as free */
3080   freeAllRegs ();
3081
3082   return;
3083 }