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