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