Keep uses & defs bitVectors updated during pack* operations
[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 (bitVectBitValue(sym->clashes,fsym->key)) return 0;
397     }
398
399   return 1;
400 }
401
402 /*-----------------------------------------------------------------*/
403 /* isFree - will return 1 if the a free spil location is found     */
404 /*-----------------------------------------------------------------*/
405 static
406 DEFSETFUNC (isFree)
407 {
408   symbol *sym = item;
409   V_ARG (symbol **, sloc);
410   V_ARG (symbol *, fsym);
411
412   /* if already found */
413   if (*sloc)
414     return 0;
415
416   /* if it is free && and the itmp assigned to
417      this does not have any overlapping live ranges
418      with the one currently being assigned and
419      the size can be accomodated  */
420   if (sym->isFree &&
421       noOverLap (sym->usl.itmpStack, fsym) &&
422       getSize (sym->type) >= getSize (fsym->type))
423     {
424       *sloc = sym;
425       return 1;
426     }
427
428   return 0;
429 }
430
431 /*-----------------------------------------------------------------*/
432 /* spillLRWithPtrReg :- will spil those live ranges which use PTR  */
433 /*-----------------------------------------------------------------*/
434 static void
435 spillLRWithPtrReg (symbol * forSym)
436 {
437   symbol *lrsym;
438   regs *r0, *r1;
439   int k;
440
441   if (!_G.regAssigned ||
442       bitVectIsZero (_G.regAssigned))
443     return;
444
445   r0 = mcs51_regWithIdx (R0_IDX);
446   r1 = mcs51_regWithIdx (R1_IDX);
447
448   /* for all live ranges */
449   for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
450        lrsym = hTabNextItem (liveRanges, &k))
451     {
452       int j;
453
454       /* if no registers assigned to it or spilt */
455       /* if it does not overlap with this then 
456          not need to spill it */
457
458       if (lrsym->isspilt || !lrsym->nRegs ||
459           (lrsym->liveTo < forSym->liveFrom))
460         continue;
461
462       /* go thru the registers : if it is either
463          r0 or r1 then spil it */
464       for (j = 0; j < lrsym->nRegs; j++)
465         if (lrsym->regs[j] == r0 ||
466             lrsym->regs[j] == r1)
467           {
468             spillThis (lrsym);
469             break;
470           }
471     }
472
473 }
474
475 /*-----------------------------------------------------------------*/
476 /* createStackSpil - create a location on the stack to spil        */
477 /*-----------------------------------------------------------------*/
478 static symbol *
479 createStackSpil (symbol * sym)
480 {
481   symbol *sloc = NULL;
482   int useXstack, model;
483
484   char slocBuffer[30];
485
486   /* first go try and find a free one that is already 
487      existing on the stack */
488   if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
489     {
490       /* found a free one : just update & return */
491       sym->usl.spillLoc = sloc;
492       sym->stackSpil = 1;
493       sloc->isFree = 0;
494       addSetHead (&sloc->usl.itmpStack, sym);
495       return sym;
496     }
497
498   /* could not then have to create one , this is the hard part
499      we need to allocate this on the stack : this is really a
500      hack!! but cannot think of anything better at this time */
501
502   if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
503     {
504       fprintf (stderr, "***Internal error: slocBuffer overflowed: %s:%d\n",
505                __FILE__, __LINE__);
506       exit (1);
507     }
508
509   sloc = newiTemp (slocBuffer);
510
511   /* set the type to the spilling symbol */
512   sloc->type = copyLinkChain (sym->type);
513   sloc->etype = getSpec (sloc->type);
514   SPEC_SCLS (sloc->etype) = S_DATA;
515   SPEC_EXTR (sloc->etype) = 0;
516   SPEC_STAT (sloc->etype) = 0;
517
518   /* we don't allow it to be allocated`
519      onto the external stack since : so we
520      temporarily turn it off ; we also
521      turn off memory model to prevent
522      the spil from going to the external storage
523    */
524
525   useXstack = options.useXstack;
526   model = options.model;
527 /*     noOverlay = options.noOverlay; */
528 /*     options.noOverlay = 1; */
529   options.model = options.useXstack = 0;
530
531   allocLocal (sloc);
532
533   options.useXstack = useXstack;
534   options.model = model;
535 /*     options.noOverlay = noOverlay; */
536   sloc->isref = 1;              /* to prevent compiler warning */
537
538   /* if it is on the stack then update the stack */
539   if (IN_STACK (sloc->etype))
540     {
541       currFunc->stack += getSize (sloc->type);
542       _G.stackExtend += getSize (sloc->type);
543     }
544   else
545     _G.dataExtend += getSize (sloc->type);
546
547   /* add it to the _G.stackSpil set */
548   addSetHead (&_G.stackSpil, sloc);
549   sym->usl.spillLoc = sloc;
550   sym->stackSpil = 1;
551
552   /* add it to the set of itempStack set 
553      of the spill location */
554   addSetHead (&sloc->usl.itmpStack, sym);
555   return sym;
556 }
557
558 /*-----------------------------------------------------------------*/
559 /* isSpiltOnStack - returns true if the spil location is on stack  */
560 /*-----------------------------------------------------------------*/
561 static bool
562 isSpiltOnStack (symbol * sym)
563 {
564   sym_link *etype;
565
566   if (!sym)
567     return FALSE;
568
569   if (!sym->isspilt)
570     return FALSE;
571
572 /*     if (sym->_G.stackSpil) */
573 /*      return TRUE; */
574
575   if (!sym->usl.spillLoc)
576     return FALSE;
577
578   etype = getSpec (sym->usl.spillLoc->type);
579   if (IN_STACK (etype))
580     return TRUE;
581
582   return FALSE;
583 }
584
585 /*-----------------------------------------------------------------*/
586 /* spillThis - spils a specific operand                            */
587 /*-----------------------------------------------------------------*/
588 static void
589 spillThis (symbol * sym)
590 {
591   int i;
592   /* if this is rematerializable or has a spillLocation
593      we are okay, else we need to create a spillLocation
594      for it */
595   if (!(sym->remat || sym->usl.spillLoc))
596     createStackSpil (sym);
597
598
599   /* mark it has spilt & put it in the spilt set */
600   sym->isspilt = 1;
601   _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
602
603   bitVectUnSetBit (_G.regAssigned, sym->key);
604
605   for (i = 0; i < sym->nRegs; i++)
606
607     if (sym->regs[i])
608       {
609         freeReg (sym->regs[i]);
610         sym->regs[i] = NULL;
611       }
612
613   /* if spilt on stack then free up r0 & r1 
614      if they could have been assigned to some
615      LIVE ranges */
616   if (!mcs51_ptrRegReq && isSpiltOnStack (sym))
617     {
618       mcs51_ptrRegReq++;
619       spillLRWithPtrReg (sym);
620     }
621
622   if (sym->usl.spillLoc && !sym->remat)
623     sym->usl.spillLoc->allocreq = 1;
624   return;
625 }
626
627 /*-----------------------------------------------------------------*/
628 /* selectSpil - select a iTemp to spil : rather a simple procedure */
629 /*-----------------------------------------------------------------*/
630 static symbol *
631 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
632 {
633   bitVect *lrcs = NULL;
634   set *selectS;
635   symbol *sym;
636
637   /* get the spillable live ranges */
638   lrcs = computeSpillable (ic);
639
640   /* get all live ranges that are rematerizable */
641   if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
642     {
643
644       /* return the least used of these */
645       return leastUsedLR (selectS);
646     }
647
648   /* get live ranges with spillLocations in direct space */
649   if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
650     {
651       sym = leastUsedLR (selectS);
652       strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
653                            sym->usl.spillLoc->rname :
654                            sym->usl.spillLoc->name));
655       sym->spildir = 1;
656       /* mark it as allocation required */
657       sym->usl.spillLoc->allocreq = 1;
658       return sym;
659     }
660
661   /* if the symbol is local to the block then */
662   if (forSym->liveTo < ebp->lSeq)
663     {
664
665       /* check if there are any live ranges allocated
666          to registers that are not used in this block */
667       if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
668         {
669           sym = leastUsedLR (selectS);
670           /* if this is not rematerializable */
671           if (!sym->remat)
672             {
673               _G.blockSpil++;
674               sym->blockSpil = 1;
675             }
676           return sym;
677         }
678
679       /* check if there are any live ranges that not
680          used in the remainder of the block */
681       if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
682         {
683           sym = leastUsedLR (selectS);
684           if (sym != forSym)
685             {
686               if (!sym->remat)
687                 {
688                   sym->remainSpil = 1;
689                   _G.blockSpil++;
690                 }
691               return sym;
692             }
693         }
694     }
695
696   /* find live ranges with spillocation && not used as pointers */
697   if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
698     {
699
700       sym = leastUsedLR (selectS);
701       /* mark this as allocation required */
702       sym->usl.spillLoc->allocreq = 1;
703       return sym;
704     }
705
706   /* find live ranges with spillocation */
707   if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
708     {
709
710       sym = leastUsedLR (selectS);
711       sym->usl.spillLoc->allocreq = 1;
712       return sym;
713     }
714
715   /* couldn't find then we need to create a spil
716      location on the stack , for which one? the least
717      used ofcourse */
718   if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
719     {
720
721       /* return a created spil location */
722       sym = createStackSpil (leastUsedLR (selectS));
723       sym->usl.spillLoc->allocreq = 1;
724       return sym;
725     }
726
727   /* this is an extreme situation we will spill
728      this one : happens very rarely but it does happen */
729   spillThis (forSym);
730   return forSym;
731
732 }
733
734 /*-----------------------------------------------------------------*/
735 /* spilSomething - spil some variable & mark registers as free     */
736 /*-----------------------------------------------------------------*/
737 static bool
738 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
739 {
740   symbol *ssym;
741   int i;
742
743   /* get something we can spil */
744   ssym = selectSpil (ic, ebp, forSym);
745
746   /* mark it as spilt */
747   ssym->isspilt = 1;
748   _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
749
750   /* mark it as not register assigned &
751      take it away from the set */
752   bitVectUnSetBit (_G.regAssigned, ssym->key);
753
754   /* mark the registers as free */
755   for (i = 0; i < ssym->nRegs; i++)
756     if (ssym->regs[i])
757       freeReg (ssym->regs[i]);
758
759   /* if spilt on stack then free up r0 & r1 
760      if they could have been assigned to as gprs */
761   if (!mcs51_ptrRegReq && isSpiltOnStack (ssym))
762     {
763       mcs51_ptrRegReq++;
764       spillLRWithPtrReg (ssym);
765     }
766
767   /* if this was a block level spil then insert push & pop 
768      at the start & end of block respectively */
769   if (ssym->blockSpil)
770     {
771       iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
772       /* add push to the start of the block */
773       addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
774                                     ebp->sch->next : ebp->sch));
775       nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
776       /* add pop to the end of the block */
777       addiCodeToeBBlock (ebp, nic, NULL);
778     }
779
780   /* if spilt because not used in the remainder of the
781      block then add a push before this instruction and
782      a pop at the end of the block */
783   if (ssym->remainSpil)
784     {
785
786       iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
787       /* add push just before this instruction */
788       addiCodeToeBBlock (ebp, nic, ic);
789
790       nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
791       /* add pop to the end of the block */
792       addiCodeToeBBlock (ebp, nic, NULL);
793     }
794
795   if (ssym == forSym)
796     return FALSE;
797   else
798     return TRUE;
799 }
800
801 /*-----------------------------------------------------------------*/
802 /* getRegPtr - will try for PTR if not a GPR type if not spil      */
803 /*-----------------------------------------------------------------*/
804 static regs *
805 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
806 {
807   regs *reg;
808
809 tryAgain:
810   /* try for a ptr type */
811   if ((reg = allocReg (REG_PTR)))
812     return reg;
813
814   /* try for gpr type */
815   if ((reg = allocReg (REG_GPR)))
816     return reg;
817
818   /* we have to spil */
819   if (!spilSomething (ic, ebp, sym))
820     return NULL;
821
822   /* this looks like an infinite loop but 
823      in really selectSpil will abort  */
824   goto tryAgain;
825 }
826
827 /*-----------------------------------------------------------------*/
828 /* getRegGpr - will try for GPR if not spil                        */
829 /*-----------------------------------------------------------------*/
830 static regs *
831 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
832 {
833   regs *reg;
834
835 tryAgain:
836   /* try for gpr type */
837   if ((reg = allocReg (REG_GPR)))
838     return reg;
839
840   if (!mcs51_ptrRegReq)
841     if ((reg = allocReg (REG_PTR)))
842       return reg;
843
844   /* we have to spil */
845   if (!spilSomething (ic, ebp, sym))
846     return NULL;
847
848   /* this looks like an infinite loop but 
849      in really selectSpil will abort  */
850   goto tryAgain;
851 }
852
853 /*-----------------------------------------------------------------*/
854 /* symHasReg - symbol has a given register                         */
855 /*-----------------------------------------------------------------*/
856 static bool
857 symHasReg (symbol * sym, regs * reg)
858 {
859   int i;
860
861   for (i = 0; i < sym->nRegs; i++)
862     if (sym->regs[i] == reg)
863       return TRUE;
864
865   return FALSE;
866 }
867
868 /*-----------------------------------------------------------------*/
869 /* deassignLRs - check the live to and if they have registers & are */
870 /*               not spilt then free up the registers              */
871 /*-----------------------------------------------------------------*/
872 static void
873 deassignLRs (iCode * ic, eBBlock * ebp)
874 {
875   symbol *sym;
876   int k;
877   symbol *result;
878
879   for (sym = hTabFirstItem (liveRanges, &k); sym;
880        sym = hTabNextItem (liveRanges, &k))
881     {
882
883       symbol *psym = NULL;
884       /* if it does not end here */
885       if (sym->liveTo > ic->seq)
886         continue;
887
888       /* if it was spilt on stack then we can 
889          mark the stack spil location as free */
890       if (sym->isspilt)
891         {
892           if (sym->stackSpil)
893             {
894               sym->usl.spillLoc->isFree = 1;
895               sym->stackSpil = 0;
896             }
897           continue;
898         }
899
900       if (!bitVectBitValue (_G.regAssigned, sym->key))
901         continue;
902
903       /* special case check if this is an IFX &
904          the privious one was a pop and the 
905          previous one was not spilt then keep track
906          of the symbol */
907       if (ic->op == IFX && ic->prev &&
908           ic->prev->op == IPOP &&
909           !ic->prev->parmPush &&
910           !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
911         psym = OP_SYMBOL (IC_LEFT (ic->prev));
912
913       if (sym->nRegs)
914         {
915           int i = 0;
916
917           bitVectUnSetBit (_G.regAssigned, sym->key);
918
919           /* if the result of this one needs registers
920              and does not have it then assign it right
921              away */
922           if (IC_RESULT (ic) &&
923               !(SKIP_IC2 (ic) ||        /* not a special icode */
924                 ic->op == JUMPTABLE ||
925                 ic->op == IFX ||
926                 ic->op == IPUSH ||
927                 ic->op == IPOP ||
928                 ic->op == RETURN ||
929                 POINTER_SET (ic)) &&
930               (result = OP_SYMBOL (IC_RESULT (ic))) &&  /* has a result */
931               result->liveTo > ic->seq &&       /* and will live beyond this */
932               result->liveTo <= ebp->lSeq &&    /* does not go beyond this block */
933               result->regType == sym->regType &&        /* same register types */
934               result->nRegs &&  /* which needs registers */
935               !result->isspilt &&       /* and does not already have them */
936               !result->remat &&
937               !bitVectBitValue (_G.regAssigned, result->key) &&
938           /* the number of free regs + number of regs in this LR
939              can accomodate the what result Needs */
940               ((nfreeRegsType (result->regType) +
941                 sym->nRegs) >= result->nRegs)
942             )
943             {
944
945               for (i = 0; i < result->nRegs; i++)
946                 if (i < sym->nRegs)
947                   result->regs[i] = sym->regs[i];
948                 else
949                   result->regs[i] = getRegGpr (ic, ebp, result);
950
951               _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
952
953             }
954
955           /* free the remaining */
956           for (; i < sym->nRegs; i++)
957             {
958               if (psym)
959                 {
960                   if (!symHasReg (psym, sym->regs[i]))
961                     freeReg (sym->regs[i]);
962                 }
963               else
964                 freeReg (sym->regs[i]);
965             }
966         }
967     }
968 }
969
970
971 /*-----------------------------------------------------------------*/
972 /* reassignLR - reassign this to registers                         */
973 /*-----------------------------------------------------------------*/
974 static void
975 reassignLR (operand * op)
976 {
977   symbol *sym = OP_SYMBOL (op);
978   int i;
979
980   /* not spilt any more */
981   sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
982   bitVectUnSetBit (_G.spiltSet, sym->key);
983
984   _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
985
986   _G.blockSpil--;
987
988   for (i = 0; i < sym->nRegs; i++)
989     sym->regs[i]->isFree = 0;
990 }
991
992 /*-----------------------------------------------------------------*/
993 /* willCauseSpill - determines if allocating will cause a spill    */
994 /*-----------------------------------------------------------------*/
995 static int
996 willCauseSpill (int nr, int rt)
997 {
998   /* first check if there are any avlb registers
999      of te type required */
1000   if (rt == REG_PTR)
1001     {
1002       /* special case for pointer type 
1003          if pointer type not avlb then 
1004          check for type gpr */
1005       if (nFreeRegs (rt) >= nr)
1006         return 0;
1007       if (nFreeRegs (REG_GPR) >= nr)
1008         return 0;
1009     }
1010   else
1011     {
1012       if (mcs51_ptrRegReq)
1013         {
1014           if (nFreeRegs (rt) >= nr)
1015             return 0;
1016         }
1017       else
1018         {
1019           if (nFreeRegs (REG_PTR) +
1020               nFreeRegs (REG_GPR) >= nr)
1021             return 0;
1022         }
1023     }
1024
1025   /* it will cause a spil */
1026   return 1;
1027 }
1028
1029 /*-----------------------------------------------------------------*/
1030 /* positionRegs - the allocator can allocate same registers to res- */
1031 /* ult and operand, if this happens make sure they are in the same */
1032 /* position as the operand otherwise chaos results                 */
1033 /*-----------------------------------------------------------------*/
1034 static void
1035 positionRegs (symbol * result, symbol * opsym, int lineno)
1036 {
1037   int count = min (result->nRegs, opsym->nRegs);
1038   int i, j = 0, shared = 0;
1039
1040   /* if the result has been spilt then cannot share */
1041   if (opsym->isspilt)
1042     return;
1043 again:
1044   shared = 0;
1045   /* first make sure that they actually share */
1046   for (i = 0; i < count; i++)
1047     {
1048       for (j = 0; j < count; j++)
1049         {
1050           if (result->regs[i] == opsym->regs[j] && i != j)
1051             {
1052               shared = 1;
1053               goto xchgPositions;
1054             }
1055         }
1056     }
1057 xchgPositions:
1058   if (shared)
1059     {
1060       regs *tmp = result->regs[i];
1061       result->regs[i] = result->regs[j];
1062       result->regs[j] = tmp;
1063       goto again;
1064     }
1065 }
1066
1067 /*-----------------------------------------------------------------*/
1068 /* serialRegAssign - serially allocate registers to the variables  */
1069 /*-----------------------------------------------------------------*/
1070 static void
1071 serialRegAssign (eBBlock ** ebbs, int count)
1072 {
1073     int i;
1074
1075     /* for all blocks */
1076     for (i = 0; i < count; i++) {
1077
1078         iCode *ic;
1079
1080         if (ebbs[i]->noPath &&
1081             (ebbs[i]->entryLabel != entryLabel &&
1082              ebbs[i]->entryLabel != returnLabel))
1083             continue;
1084
1085         /* of all instructions do */
1086         for (ic = ebbs[i]->sch; ic; ic = ic->next) {
1087
1088             /* if this is an ipop that means some live
1089                range will have to be assigned again */
1090             if (ic->op == IPOP)
1091                 reassignLR (IC_LEFT (ic));
1092
1093             /* if result is present && is a true symbol */
1094             if (IC_RESULT (ic) && ic->op != IFX &&
1095                 IS_TRUE_SYMOP (IC_RESULT (ic)))
1096                 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
1097
1098             /* take away registers from live
1099                ranges that end at this instruction */
1100             deassignLRs (ic, ebbs[i]);
1101
1102             /* some don't need registers */
1103             if (SKIP_IC2 (ic) ||
1104                 ic->op == JUMPTABLE ||
1105                 ic->op == IFX ||
1106                 ic->op == IPUSH ||
1107                 ic->op == IPOP ||
1108                 (IC_RESULT (ic) && POINTER_SET (ic)))
1109                 continue;
1110
1111             /* now we need to allocate registers
1112                only for the result */
1113             if (IC_RESULT (ic)) {
1114                 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
1115                 bitVect *spillable;
1116                 int willCS;
1117                 int j;
1118                 int ptrRegSet = 0;
1119
1120                 /* if it does not need or is spilt 
1121                    or is already assigned to registers
1122                    or will not live beyond this instructions */
1123                 if (!sym->nRegs ||
1124                     sym->isspilt ||
1125                     bitVectBitValue (_G.regAssigned, sym->key) ||
1126                     sym->liveTo <= ic->seq)
1127                     continue;
1128
1129                 /* if some liverange has been spilt at the block level
1130                    and this one live beyond this block then spil this
1131                    to be safe */
1132                 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq) {
1133                     spillThis (sym);
1134                     continue;
1135                 }
1136                 /* if trying to allocate this will cause
1137                    a spill and there is nothing to spill 
1138                    or this one is rematerializable then
1139                    spill this one */
1140                 willCS = willCauseSpill (sym->nRegs, sym->regType);
1141                 spillable = computeSpillable (ic);
1142                 if (sym->remat || (willCS && bitVectIsZero (spillable))) {                    
1143                     spillThis (sym);
1144                     continue;                 
1145                 }
1146
1147                 /* if it has a spillocation & is used less than
1148                    all other live ranges then spill this */
1149                 if (willCS) {
1150                     if (sym->usl.spillLoc) {
1151                         symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
1152                                                                          allLRs, ebbs[i], ic));
1153                         if (leastUsed && leastUsed->used > sym->used) {
1154                             spillThis (sym);
1155                             continue;
1156                         }
1157                     } else {
1158                         /* if none of the liveRanges have a spillLocation then better
1159                            to spill this one than anything else already assigned to registers */
1160                         if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
1161                             /* if this is local to this block then we might find a block spil */
1162                             if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
1163                                 spillThis (sym);
1164                                 continue;
1165                             }
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       /* cast then continue */
1387       if (IS_CAST_ICODE(ic)) {
1388           ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
1389           continue;
1390       }
1391       /* we reached the end */
1392       sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
1393       break;
1394     }
1395
1396   return buffer;
1397 }
1398
1399 /*-----------------------------------------------------------------*/
1400 /* regTypeNum - computes the type & number of registers required   */
1401 /*-----------------------------------------------------------------*/
1402 static void
1403 regTypeNum (eBBlock *ebbs)
1404 {
1405   symbol *sym;
1406   int k;
1407   iCode *ic;
1408
1409   /* for each live range do */
1410   for (sym = hTabFirstItem (liveRanges, &k); sym;
1411        sym = hTabNextItem (liveRanges, &k))
1412     {
1413
1414       /* if used zero times then no registers needed */
1415       if ((sym->liveTo - sym->liveFrom) == 0)
1416         continue;
1417
1418
1419       /* if the live range is a temporary */
1420       if (sym->isitmp)
1421         {
1422
1423           /* if the type is marked as a conditional */
1424           if (sym->regType == REG_CND)
1425             continue;
1426
1427           /* if used in return only then we don't 
1428              need registers */
1429           if (sym->ruonly || sym->accuse)
1430             {
1431               if (IS_AGGREGATE (sym->type) || sym->isptr)
1432                 sym->type = aggrToPtr (sym->type, FALSE);
1433               continue;
1434             }
1435
1436           /* if the symbol has only one definition &
1437              that definition is a get_pointer and the
1438              pointer we are getting is rematerializable and
1439              in "data" space */
1440
1441           if (bitVectnBitsOn (sym->defs) == 1 &&
1442               (ic = hTabItemWithKey (iCodehTab,
1443                                      bitVectFirstBit (sym->defs))) &&
1444               POINTER_GET (ic) &&
1445               !sym->noSpilLoc &&
1446               !IS_BITVAR (sym->etype))
1447             {
1448
1449
1450               /* if remat in data space */
1451               if (OP_SYMBOL (IC_LEFT (ic))->remat &&
1452                   !IS_CAST_ICODE(OP_SYMBOL (IC_LEFT (ic))->rematiCode) &&
1453                   DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER)
1454                 {
1455                   /* create a psuedo symbol & force a spil */
1456                   symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
1457                   psym->type = sym->type;
1458                   psym->etype = sym->etype;
1459                   strcpy (psym->rname, psym->name);
1460                   sym->isspilt = 1;
1461                   sym->usl.spillLoc = psym;
1462 #if 0 // an alternative fix for bug #480076
1463                   /* now this is a useless assignment to itself */
1464                   remiCodeFromeBBlock (ebbs, ic);
1465 #else
1466                   /* now this really is an assignment to itself, make it so;
1467                      it will be optimized out later */
1468                   ic->op='=';
1469                   IC_RIGHT(ic)=IC_RESULT(ic);
1470                   IC_LEFT(ic)=NULL;
1471 #endif
1472                   continue;
1473                 }
1474
1475               /* if in data space or idata space then try to
1476                  allocate pointer register */
1477
1478             }
1479
1480           /* if not then we require registers */
1481           sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
1482                         getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1483                         getSize (sym->type));
1484
1485           if (sym->nRegs > 4)
1486             {
1487               fprintf (stderr, "allocated more than 4 or 0 registers for type ");
1488               printTypeChain (sym->type, stderr);
1489               fprintf (stderr, "\n");
1490             }
1491
1492           /* determine the type of register required */
1493           if (sym->nRegs == 1 &&
1494               IS_PTR (sym->type) &&
1495               sym->uptr)
1496             sym->regType = REG_PTR;
1497           else
1498             sym->regType = REG_GPR;
1499
1500         }
1501       else
1502         /* for the first run we don't provide */
1503         /* registers for true symbols we will */
1504         /* see how things go                  */
1505         sym->nRegs = 0;
1506     }
1507
1508 }
1509
1510 /*-----------------------------------------------------------------*/
1511 /* freeAllRegs - mark all registers as free                        */
1512 /*-----------------------------------------------------------------*/
1513 static void
1514 freeAllRegs ()
1515 {
1516   int i;
1517
1518   for (i = 0; i < mcs51_nRegs; i++)
1519     regs8051[i].isFree = 1;
1520 }
1521
1522 /*-----------------------------------------------------------------*/
1523 /* deallocStackSpil - this will set the stack pointer back         */
1524 /*-----------------------------------------------------------------*/
1525 static
1526 DEFSETFUNC (deallocStackSpil)
1527 {
1528   symbol *sym = item;
1529
1530   deallocLocal (sym);
1531   return 0;
1532 }
1533
1534 /*-----------------------------------------------------------------*/
1535 /* farSpacePackable - returns the packable icode for far variables */
1536 /*-----------------------------------------------------------------*/
1537 static iCode *
1538 farSpacePackable (iCode * ic)
1539 {
1540   iCode *dic;
1541
1542   /* go thru till we find a definition for the
1543      symbol on the right */
1544   for (dic = ic->prev; dic; dic = dic->prev)
1545     {
1546       /* if the definition is a call then no */
1547       if ((dic->op == CALL || dic->op == PCALL) &&
1548           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1549         {
1550           return NULL;
1551         }
1552
1553       /* if shift by unknown amount then not */
1554       if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
1555           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1556         return NULL;
1557
1558       /* if pointer get and size > 1 */
1559       if (POINTER_GET (dic) &&
1560           getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
1561         return NULL;
1562
1563       if (POINTER_SET (dic) &&
1564           getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
1565         return NULL;
1566
1567       /* if any three is a true symbol in far space */
1568       if (IC_RESULT (dic) &&
1569           IS_TRUE_SYMOP (IC_RESULT (dic)) &&
1570           isOperandInFarSpace (IC_RESULT (dic)))
1571         return NULL;
1572
1573       if (IC_RIGHT (dic) &&
1574           IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
1575           isOperandInFarSpace (IC_RIGHT (dic)) &&
1576           !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
1577         return NULL;
1578
1579       if (IC_LEFT (dic) &&
1580           IS_TRUE_SYMOP (IC_LEFT (dic)) &&
1581           isOperandInFarSpace (IC_LEFT (dic)) &&
1582           !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
1583         return NULL;
1584
1585       if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
1586         {
1587           if ((dic->op == LEFT_OP ||
1588                dic->op == RIGHT_OP ||
1589                dic->op == '-') &&
1590               IS_OP_LITERAL (IC_RIGHT (dic)))
1591             return NULL;
1592           else
1593             return dic;
1594         }
1595     }
1596
1597   return NULL;
1598 }
1599
1600 /*-----------------------------------------------------------------*/
1601 /* packRegsForAssign - register reduction for assignment           */
1602 /*-----------------------------------------------------------------*/
1603 static int
1604 packRegsForAssign (iCode * ic, eBBlock * ebp)
1605 {
1606   iCode *dic, *sic;
1607   //sym_link *etype = operandType (IC_RIGHT (ic));
1608
1609   if (!IS_ITEMP (IC_RIGHT (ic)) ||
1610       OP_SYMBOL (IC_RIGHT (ic))->isind ||
1611       OP_LIVETO (IC_RIGHT (ic)) > ic->seq
1612       /* why? || IS_BITFIELD (etype) */ )
1613     {
1614       return 0;
1615     }
1616
1617   /* if the true symbol is defined in far space or on stack
1618      then we should not since this will increase register pressure */
1619   if (isOperandInFarSpace(IC_RESULT(ic)) && !farSpacePackable(ic)) {
1620     return 0;
1621   }
1622
1623   /* find the definition of iTempNN scanning backwards if we find a 
1624      a use of the true symbol in before we find the definition then 
1625      we cannot */
1626   for (dic = ic->prev; dic; dic = dic->prev)
1627     {
1628       /* if there is a function call then don't pack it */
1629       if ((dic->op == CALL || dic->op == PCALL))
1630         {
1631           dic = NULL;
1632           break;
1633         }
1634
1635       if (SKIP_IC2 (dic))
1636         continue;
1637
1638       if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
1639           IS_OP_VOLATILE (IC_RESULT (dic)))
1640         {
1641           dic = NULL;
1642           break;
1643         }
1644
1645       if (IS_SYMOP (IC_RESULT (dic)) &&
1646           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1647         {
1648           if (POINTER_SET (dic))
1649             dic = NULL;
1650
1651           break;
1652         }
1653
1654       if (IS_SYMOP (IC_RIGHT (dic)) &&
1655           (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
1656            IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
1657         {
1658           dic = NULL;
1659           break;
1660         }
1661
1662       if (IS_SYMOP (IC_LEFT (dic)) &&
1663           (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
1664            IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
1665         {
1666           dic = NULL;
1667           break;
1668         }
1669
1670       if (POINTER_SET (dic) &&
1671           IC_RESULT (dic)->key == IC_RESULT (ic)->key)
1672         {
1673           dic = NULL;
1674           break;
1675         }
1676     }
1677
1678   if (!dic)
1679     return 0;                   /* did not find */
1680
1681   /* if assignment then check that right is not a bit */
1682   if (ASSIGNMENT (dic) && !POINTER_SET (dic))
1683     {
1684       sym_link *etype = operandType (IC_RIGHT (dic));
1685       if (IS_BITFIELD (etype))
1686         return 0;
1687     }
1688   /* if the result is on stack or iaccess then it must be
1689      the same atleast one of the operands */
1690   if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
1691       OP_SYMBOL (IC_RESULT (ic))->iaccess)
1692     {
1693
1694       /* the operation has only one symbol
1695          operator then we can pack */
1696       if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
1697           (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
1698         goto pack;
1699
1700       if (!((IC_LEFT (dic) &&
1701              IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
1702             (IC_RIGHT (dic) &&
1703              IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
1704         return 0;
1705     }
1706 pack:
1707   /* found the definition */
1708   /* replace the result with the result of */
1709   /* this assignment and remove this assignment */
1710   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1711   IC_RESULT (dic) = IC_RESULT (ic);
1712
1713   if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
1714     {
1715       OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
1716     }
1717   /* delete from liverange table also 
1718      delete from all the points inbetween and the new
1719      one */
1720   for (sic = dic; sic != ic; sic = sic->next)
1721     {
1722       bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
1723       if (IS_ITEMP (IC_RESULT (dic)))
1724         bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
1725     }
1726
1727   remiCodeFromeBBlock (ebp, ic);
1728   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
1729   hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
1730   OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
1731   return 1;
1732
1733 }
1734
1735 /*-----------------------------------------------------------------*/
1736 /* findAssignToSym : scanning backwards looks for first assig found */
1737 /*-----------------------------------------------------------------*/
1738 static iCode *
1739 findAssignToSym (operand * op, iCode * ic)
1740 {
1741   iCode *dic;
1742
1743   for (dic = ic->prev; dic; dic = dic->prev)
1744     {
1745
1746       /* if definition by assignment */
1747       if (dic->op == '=' &&
1748           !POINTER_SET (dic) &&
1749           IC_RESULT (dic)->key == op->key
1750 /*          &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) */
1751         )
1752         {
1753
1754           /* we are interested only if defined in far space */
1755           /* or in stack space in case of + & - */
1756
1757           /* if assigned to a non-symbol then return
1758              FALSE */
1759           if (!IS_SYMOP (IC_RIGHT (dic)))
1760             return NULL;
1761
1762           /* if the symbol is in far space then
1763              we should not */
1764           if (isOperandInFarSpace (IC_RIGHT (dic)))
1765             return NULL;
1766
1767           /* for + & - operations make sure that
1768              if it is on the stack it is the same
1769              as one of the three operands */
1770           if ((ic->op == '+' || ic->op == '-') &&
1771               OP_SYMBOL (IC_RIGHT (dic))->onStack)
1772             {
1773
1774               if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
1775                   IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
1776                   IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
1777                 return NULL;
1778             }
1779
1780           break;
1781
1782         }
1783
1784       /* if we find an usage then we cannot delete it */
1785       if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
1786         return NULL;
1787
1788       if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
1789         return NULL;
1790
1791       if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
1792         return NULL;
1793     }
1794
1795   /* now make sure that the right side of dic
1796      is not defined between ic & dic */
1797   if (dic)
1798     {
1799       iCode *sic = dic->next;
1800
1801       for (; sic != ic; sic = sic->next)
1802         if (IC_RESULT (sic) &&
1803             IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
1804           return NULL;
1805     }
1806
1807   return dic;
1808
1809
1810 }
1811
1812 /*-----------------------------------------------------------------*/
1813 /* packRegsForSupport :- reduce some registers for support calls   */
1814 /*-----------------------------------------------------------------*/
1815 static int
1816 packRegsForSupport (iCode * ic, eBBlock * ebp)
1817 {
1818   int change = 0;
1819   iCode *dic, *sic;
1820
1821   /* for the left & right operand :- look to see if the
1822      left was assigned a true symbol in far space in that
1823      case replace them */
1824
1825   if (IS_ITEMP (IC_LEFT (ic)) &&
1826       OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
1827     {
1828       dic = findAssignToSym (IC_LEFT (ic), ic);
1829
1830       if (!dic)
1831         goto right;
1832
1833       /* found it we need to remove it from the
1834          block */
1835       for (sic = dic; sic != ic; sic = sic->next)
1836         bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
1837
1838       OP_SYMBOL(IC_LEFT (ic))=OP_SYMBOL(IC_RIGHT (dic));
1839       IC_LEFT (ic)->key = OP_SYMBOL(IC_RIGHT (dic))->key;
1840       remiCodeFromeBBlock (ebp, dic);
1841       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1842       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1843       change++;
1844     }
1845
1846   /* do the same for the right operand */
1847  right:
1848   if (!change &&
1849       IS_ITEMP (IC_RIGHT (ic)) &&
1850       OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
1851     {
1852       iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
1853       iCode *sic;
1854
1855       if (!dic)
1856         return change;
1857
1858       /* if this is a subtraction & the result
1859          is a true symbol in far space then don't pack */
1860       if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
1861         {
1862           sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
1863           if (IN_FARSPACE (SPEC_OCLS (etype)))
1864             return change;
1865         }
1866       /* found it we need to remove it from the
1867          block */
1868       for (sic = dic; sic != ic; sic = sic->next)
1869         bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
1870
1871       IC_RIGHT (ic)->operand.symOperand =
1872         IC_RIGHT (dic)->operand.symOperand;
1873       IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
1874
1875       remiCodeFromeBBlock (ebp, dic);
1876       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1877       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1878       change++;
1879     }
1880
1881   return change;
1882 }
1883
1884 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
1885
1886
1887 /*-----------------------------------------------------------------*/
1888 /* packRegsForOneuse : - will reduce some registers for single Use */
1889 /*-----------------------------------------------------------------*/
1890 static iCode *
1891 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
1892 {
1893   bitVect *uses;
1894   iCode *dic, *sic;
1895
1896   /* if returning a literal then do nothing */
1897   if (!IS_SYMOP (op))
1898     return NULL;
1899
1900   /* only upto 2 bytes since we cannot predict
1901      the usage of b, & acc */
1902   if (getSize (operandType (op)) > (fReturnSizeMCS51 - 2))
1903     return NULL;
1904
1905   if (ic->op != RETURN &&
1906       ic->op != SEND &&
1907       !POINTER_SET (ic) &&
1908       !POINTER_GET (ic))
1909     return NULL;
1910   
1911   /* this routine will mark the a symbol as used in one 
1912      instruction use only && if the defintion is local 
1913      (ie. within the basic block) && has only one definition &&
1914      that definiion is either a return value from a 
1915      function or does not contain any variables in
1916      far space */
1917   uses = bitVectCopy (OP_USES (op));
1918   bitVectUnSetBit (uses, ic->key);      /* take away this iCode */
1919   if (!bitVectIsZero (uses))    /* has other uses */
1920     return NULL;
1921
1922   /* if it has only one defintion */
1923   if (bitVectnBitsOn (OP_DEFS (op)) > 1)
1924     return NULL;                /* has more than one definition */
1925
1926   /* get that definition */
1927   if (!(dic =
1928         hTabItemWithKey (iCodehTab,
1929                          bitVectFirstBit (OP_DEFS (op)))))
1930     return NULL;
1931
1932   /* if that only usage is a cast */
1933   if (dic->op == CAST) {
1934     /* to a bigger type */
1935     if (getSize(OP_SYM_TYPE(IC_RESULT(dic))) > 
1936         getSize(OP_SYM_TYPE(IC_RIGHT(dic)))) {
1937       /* than we can not, since we cannot predict the usage of b & acc */
1938       return NULL;
1939     }
1940   }
1941
1942   /* found the definition now check if it is local */
1943   if (dic->seq < ebp->fSeq ||
1944       dic->seq > ebp->lSeq)
1945     return NULL;                /* non-local */
1946
1947   /* now check if it is the return from
1948      a function call */
1949   if (dic->op == CALL || dic->op == PCALL)
1950     {
1951       if (ic->op != SEND && ic->op != RETURN)
1952         {
1953           OP_SYMBOL (op)->ruonly = 1;
1954           return dic;
1955         }
1956       dic = dic->next;
1957     }
1958
1959
1960   /* otherwise check that the definition does
1961      not contain any symbols in far space */
1962   if (isOperandInFarSpace (IC_LEFT (dic)) ||
1963       isOperandInFarSpace (IC_RIGHT (dic)) ||
1964       IS_OP_RUONLY (IC_LEFT (ic)) ||
1965       IS_OP_RUONLY (IC_RIGHT (ic)))
1966     {
1967       return NULL;
1968     }
1969
1970   /* if pointer set then make sure the pointer
1971      is one byte */
1972   if (POINTER_SET (dic) &&
1973       !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
1974     return NULL;
1975
1976   if (POINTER_GET (dic) &&
1977       !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
1978     return NULL;
1979
1980   sic = dic;
1981
1982   /* also make sure the intervenening instructions
1983      don't have any thing in far space */
1984   for (dic = dic->next; dic && dic != ic && sic != ic; dic = dic->next)
1985     {
1986
1987       /* if there is an intervening function call then no */
1988       if (dic->op == CALL || dic->op == PCALL)
1989         return NULL;
1990       /* if pointer set then make sure the pointer
1991          is one byte */
1992       if (POINTER_SET (dic) &&
1993           !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
1994         return NULL;
1995
1996       if (POINTER_GET (dic) &&
1997           !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
1998         return NULL;
1999
2000       /* if address of & the result is remat the okay */
2001       if (dic->op == ADDRESS_OF &&
2002           OP_SYMBOL (IC_RESULT (dic))->remat)
2003         continue;
2004
2005       /* if operand has size of three or more & this
2006          operation is a '*','/' or '%' then 'b' may
2007          cause a problem */
2008       if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
2009           getSize (operandType (op)) >= 3)
2010         return NULL;
2011
2012       /* if left or right or result is in far space */
2013       if (isOperandInFarSpace (IC_LEFT (dic)) ||
2014           isOperandInFarSpace (IC_RIGHT (dic)) ||
2015           isOperandInFarSpace (IC_RESULT (dic)) ||
2016           IS_OP_RUONLY (IC_LEFT (dic)) ||
2017           IS_OP_RUONLY (IC_RIGHT (dic)) ||
2018           IS_OP_RUONLY (IC_RESULT (dic)))
2019         {
2020           return NULL;
2021         }
2022       /* if left or right or result is on stack */
2023       if (isOperandOnStack(IC_LEFT(dic)) ||
2024           isOperandOnStack(IC_RIGHT(dic)) ||
2025           isOperandOnStack(IC_RESULT(dic))) {
2026         return NULL;
2027       }
2028     }
2029
2030   OP_SYMBOL (op)->ruonly = 1;
2031   return sic;
2032
2033 }
2034
2035 /*-----------------------------------------------------------------*/
2036 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
2037 /*-----------------------------------------------------------------*/
2038 static bool
2039 isBitwiseOptimizable (iCode * ic)
2040 {
2041   sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
2042   sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
2043
2044   /* bitwise operations are considered optimizable
2045      under the following conditions (Jean-Louis VERN) 
2046
2047      x & lit
2048      bit & bit
2049      bit & x
2050      bit ^ bit
2051      bit ^ x
2052      x   ^ lit
2053      x   | lit
2054      bit | bit
2055      bit | x
2056   */
2057   if (IS_LITERAL(rtype) ||
2058       (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
2059     return TRUE;
2060   else
2061     return FALSE;
2062 }
2063
2064 /*-----------------------------------------------------------------*/
2065 /* packRegsForAccUse - pack registers for acc use                  */
2066 /*-----------------------------------------------------------------*/
2067 static void
2068 packRegsForAccUse (iCode * ic)
2069 {
2070   iCode *uic;
2071
2072   /* if this is an aggregate, e.g. a one byte char array */
2073   if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
2074     return;
2075   }
2076
2077   /* if + or - then it has to be one byte result */
2078   if ((ic->op == '+' || ic->op == '-')
2079       && getSize (operandType (IC_RESULT (ic))) > 1)
2080     return;
2081
2082   /* if shift operation make sure right side is not a literal */
2083   if (ic->op == RIGHT_OP &&
2084       (isOperandLiteral (IC_RIGHT (ic)) ||
2085        getSize (operandType (IC_RESULT (ic))) > 1))
2086     return;
2087
2088   if (ic->op == LEFT_OP &&
2089       (isOperandLiteral (IC_RIGHT (ic)) ||
2090        getSize (operandType (IC_RESULT (ic))) > 1))
2091     return;
2092
2093   if (IS_BITWISE_OP (ic) &&
2094       getSize (operandType (IC_RESULT (ic))) > 1)
2095     return;
2096
2097
2098   /* has only one definition */
2099   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
2100     return;
2101
2102   /* has only one use */
2103   if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
2104     return;
2105
2106   /* and the usage immediately follows this iCode */
2107   if (!(uic = hTabItemWithKey (iCodehTab,
2108                                bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
2109     return;
2110
2111   if (ic->next != uic)
2112     return;
2113
2114   /* if it is a conditional branch then we definitely can */
2115   if (uic->op == IFX)
2116     goto accuse;
2117
2118   if (uic->op == JUMPTABLE)
2119     return;
2120
2121   /* if the usage is not is an assignment
2122      or an arithmetic / bitwise / shift operation then not */
2123   if (POINTER_SET (uic) &&
2124       getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
2125     return;
2126
2127   if (uic->op != '=' &&
2128       !IS_ARITHMETIC_OP (uic) &&
2129       !IS_BITWISE_OP (uic) &&
2130       uic->op != LEFT_OP &&
2131       uic->op != RIGHT_OP)
2132     return;
2133
2134   /* if used in ^ operation then make sure right is not a 
2135      literl */
2136   if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
2137     return;
2138
2139   /* if shift operation make sure right side is not a literal */
2140   if (uic->op == RIGHT_OP &&
2141       (isOperandLiteral (IC_RIGHT (uic)) ||
2142        getSize (operandType (IC_RESULT (uic))) > 1))
2143     return;
2144
2145   if (uic->op == LEFT_OP &&
2146       (isOperandLiteral (IC_RIGHT (uic)) ||
2147        getSize (operandType (IC_RESULT (uic))) > 1))
2148     return;
2149
2150   /* make sure that the result of this icode is not on the
2151      stack, since acc is used to compute stack offset */
2152   if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
2153       OP_SYMBOL (IC_RESULT (uic))->onStack)
2154     return;
2155
2156   /* if either one of them in far space then we cannot */
2157   if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
2158        isOperandInFarSpace (IC_LEFT (uic))) ||
2159       (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
2160        isOperandInFarSpace (IC_RIGHT (uic))))
2161     return;
2162
2163   /* if the usage has only one operand then we can */
2164   if (IC_LEFT (uic) == NULL ||
2165       IC_RIGHT (uic) == NULL)
2166     goto accuse;
2167
2168   /* make sure this is on the left side if not
2169      a '+' since '+' is commutative */
2170   if (ic->op != '+' &&
2171       IC_LEFT (uic)->key != IC_RESULT (ic)->key)
2172     return;
2173
2174 #if 0
2175   // this is too dangerous and need further restrictions
2176   // see bug #447547
2177
2178   /* if one of them is a literal then we can */
2179   if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
2180       (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
2181     {
2182       OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2183       return;
2184     }
2185 #endif
2186
2187   /* if the other one is not on stack then we can */
2188   if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
2189       (IS_ITEMP (IC_RIGHT (uic)) ||
2190        (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
2191         !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
2192     goto accuse;
2193
2194   if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
2195       (IS_ITEMP (IC_LEFT (uic)) ||
2196        (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
2197         !OP_SYMBOL (IC_LEFT (uic))->onStack)))
2198     goto accuse;
2199
2200   return;
2201
2202 accuse:
2203   OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2204
2205
2206 }
2207
2208 /*-----------------------------------------------------------------*/
2209 /* packForPush - hueristics to reduce iCode for pushing            */
2210 /*-----------------------------------------------------------------*/
2211 static void
2212 packForPush (iCode * ic, eBBlock * ebp)
2213 {
2214   iCode *dic, *lic;
2215   bitVect *dbv;
2216
2217   if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
2218     return;
2219
2220   /* must have only definition & one usage */
2221   if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
2222       bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
2223     return;
2224
2225   /* find the definition */
2226   if (!(dic = hTabItemWithKey (iCodehTab,
2227                                bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
2228     return;
2229
2230   if (dic->op != '=' || POINTER_SET (dic))
2231     return;
2232
2233   /* make sure the right side does not have any definitions
2234      inbetween */
2235   dbv = OP_DEFS(IC_RIGHT(dic));
2236   for (lic = ic; lic && lic != dic ; lic = lic->prev) {
2237     if (bitVectBitValue(dbv,lic->key)) 
2238       return ;
2239   }
2240   /* make sure they have the same type */
2241   {
2242     sym_link *itype=operandType(IC_LEFT(ic));
2243     sym_link *ditype=operandType(IC_RIGHT(dic));
2244
2245     if (SPEC_USIGN(itype)!=SPEC_USIGN(ditype) ||
2246         SPEC_LONG(itype)!=SPEC_LONG(ditype))
2247       return;
2248   }
2249   /* extend the live range of replaced operand if needed */
2250   if (OP_SYMBOL(IC_RIGHT(dic))->liveTo < ic->seq) {
2251           OP_SYMBOL(IC_RIGHT(dic))->liveTo = ic->seq;
2252   }
2253   /* we now we know that it has one & only one def & use
2254      and the that the definition is an assignment */
2255   IC_LEFT (ic) = IC_RIGHT (dic);
2256    
2257   remiCodeFromeBBlock (ebp, dic);
2258   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2259   hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2260 }
2261
2262 /*-----------------------------------------------------------------*/
2263 /* packRegisters - does some transformations to reduce register    */
2264 /*                   pressure                                      */
2265 /*-----------------------------------------------------------------*/
2266 static void
2267 packRegisters (eBBlock * ebp)
2268 {
2269   iCode *ic;
2270   int change = 0;
2271
2272   while (1)
2273     {
2274
2275       change = 0;
2276
2277       /* look for assignments of the form */
2278       /* iTempNN = TRueSym (someoperation) SomeOperand */
2279       /*       ....                       */
2280       /* TrueSym := iTempNN:1             */
2281       for (ic = ebp->sch; ic; ic = ic->next)
2282         {
2283           /* find assignment of the form TrueSym := iTempNN:1 */
2284           if (ic->op == '=' && !POINTER_SET (ic))
2285             change += packRegsForAssign (ic, ebp);
2286         }
2287
2288       if (!change)
2289         break;
2290     }
2291
2292   for (ic = ebp->sch; ic; ic = ic->next)
2293     {
2294       /* if this is an itemp & result of an address of a true sym 
2295          then mark this as rematerialisable   */
2296       if (ic->op == ADDRESS_OF &&
2297           IS_ITEMP (IC_RESULT (ic)) &&
2298           IS_TRUE_SYMOP (IC_LEFT (ic)) &&
2299           bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2300           !OP_SYMBOL (IC_LEFT (ic))->onStack)
2301         {
2302
2303           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2304           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2305           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2306
2307         }
2308
2309       /* if straight assignment then carry remat flag if
2310          this is the only definition */
2311       if (ic->op == '=' &&
2312           !POINTER_SET (ic) &&
2313           IS_SYMOP (IC_RIGHT (ic)) &&
2314           OP_SYMBOL (IC_RIGHT (ic))->remat &&
2315           !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode) &&
2316           bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
2317         {
2318
2319           OP_SYMBOL (IC_RESULT (ic))->remat =
2320             OP_SYMBOL (IC_RIGHT (ic))->remat;
2321           OP_SYMBOL (IC_RESULT (ic))->rematiCode =
2322             OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
2323         }
2324
2325       /* if cast to a generic pointer & the pointer being
2326          cast is remat, then we can remat this cast as well */
2327       if (ic->op == CAST && 
2328           IS_SYMOP(IC_RIGHT(ic)) &&
2329           OP_SYMBOL(IC_RIGHT(ic))->remat ) {
2330               sym_link *to_type = operandType(IC_LEFT(ic));
2331               sym_link *from_type = operandType(IC_RIGHT(ic));
2332               if (IS_GENPTR(to_type) && IS_PTR(from_type)) {                  
2333                       OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2334                       OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2335                       OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2336               }
2337       }
2338
2339       /* if this is a +/- operation with a rematerizable 
2340          then mark this as rematerializable as well */
2341       if ((ic->op == '+' || ic->op == '-') &&
2342           (IS_SYMOP (IC_LEFT (ic)) &&
2343            IS_ITEMP (IC_RESULT (ic)) &&
2344            IS_OP_LITERAL (IC_RIGHT (ic))) &&
2345            OP_SYMBOL (IC_LEFT (ic))->remat &&
2346           (!IS_SYMOP (IC_RIGHT (ic)) || !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode)) &&
2347            bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1)
2348         {
2349           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2350           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2351           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2352         }
2353
2354       /* mark the pointer usages */
2355       if (POINTER_SET (ic))
2356         OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
2357
2358       if (POINTER_GET (ic))
2359         OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
2360
2361       if (!SKIP_IC2 (ic))
2362         {
2363           /* if we are using a symbol on the stack
2364              then we should say mcs51_ptrRegReq */
2365           if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
2366             mcs51_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
2367                                  OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
2368           else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
2369             mcs51_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
2370                               OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
2371           else
2372             {
2373               if (IS_SYMOP (IC_LEFT (ic)))
2374                 mcs51_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
2375                                 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
2376               if (IS_SYMOP (IC_RIGHT (ic)))
2377                 mcs51_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
2378                                OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
2379               if (IS_SYMOP (IC_RESULT (ic)))
2380                 mcs51_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
2381                               OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
2382             }
2383         }
2384
2385       /* if the condition of an if instruction
2386          is defined in the previous instruction and
2387          this is the only usage then
2388          mark the itemp as a conditional */
2389       if ((IS_CONDITIONAL (ic) ||
2390            (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic))) &&
2391           ic->next && ic->next->op == IFX &&
2392           bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
2393           isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
2394           OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2395         {
2396           OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
2397           continue;
2398         }
2399
2400       /* reduce for support function calls */
2401       if (ic->supportRtn || ic->op == '+' || ic->op == '-')
2402         packRegsForSupport (ic, ebp);
2403
2404       /* some cases the redundant moves can
2405          can be eliminated for return statements */
2406       if ((ic->op == RETURN || ic->op == SEND) &&
2407           !isOperandInFarSpace (IC_LEFT (ic)) &&
2408           options.model == MODEL_SMALL) {
2409         if (0 && options.stackAuto) {
2410           /* we should check here if acc will be clobbered for stack
2411              offset calculations */
2412         } else {
2413           packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2414         }
2415       }
2416
2417       /* if pointer set & left has a size more than
2418          one and right is not in far space */
2419       if (POINTER_SET (ic) &&
2420           !isOperandInFarSpace (IC_RIGHT (ic)) &&
2421           !OP_SYMBOL (IC_RESULT (ic))->remat &&
2422           !IS_OP_RUONLY (IC_RIGHT (ic)) &&
2423           getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
2424
2425         packRegsForOneuse (ic, IC_RESULT (ic), ebp);
2426
2427       /* if pointer get */
2428       if (POINTER_GET (ic) &&
2429           !isOperandInFarSpace (IC_RESULT (ic)) &&
2430           !OP_SYMBOL (IC_LEFT (ic))->remat &&
2431           !IS_OP_RUONLY (IC_RESULT (ic)) &&
2432           getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
2433
2434         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2435
2436
2437       /* if this is cast for intergral promotion then
2438          check if only use of  the definition of the 
2439          operand being casted/ if yes then replace
2440          the result of that arithmetic operation with 
2441          this result and get rid of the cast */
2442       if (ic->op == CAST)
2443         {
2444           sym_link *fromType = operandType (IC_RIGHT (ic));
2445           sym_link *toType = operandType (IC_LEFT (ic));
2446
2447           if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
2448               getSize (fromType) != getSize (toType) &&
2449               SPEC_USIGN (fromType) == SPEC_USIGN (toType))
2450             {
2451
2452               iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2453               if (dic)
2454                 {
2455                   if (IS_ARITHMETIC_OP (dic))
2456                     {                  
2457                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2458                       IC_RESULT (dic) = IC_RESULT (ic);
2459                       remiCodeFromeBBlock (ebp, ic);
2460                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2461                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2462                       OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2463                       ic = ic->prev;
2464                     }
2465                   else
2466                     OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
2467                 }
2468             }
2469           else
2470             {
2471
2472               /* if the type from and type to are the same
2473                  then if this is the only use then packit */
2474               if (compareType (operandType (IC_RIGHT (ic)),
2475                              operandType (IC_LEFT (ic))) == 1)
2476                 {
2477                   iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2478                   if (dic)
2479                     {
2480                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2481                       IC_RESULT (dic) = IC_RESULT (ic);
2482                       remiCodeFromeBBlock (ebp, ic);
2483                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2484                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2485                       OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2486                       ic = ic->prev;
2487                     }
2488                 }
2489             }
2490         }
2491
2492       /* pack for PUSH 
2493          iTempNN := (some variable in farspace) V1
2494          push iTempNN ;
2495          -------------
2496          push V1
2497        */
2498       if (ic->op == IPUSH)
2499         {
2500           packForPush (ic, ebp);
2501         }
2502
2503
2504       /* pack registers for accumulator use, when the
2505          result of an arithmetic or bit wise operation
2506          has only one use, that use is immediately following
2507          the defintion and the using iCode has only one
2508          operand or has two operands but one is literal &
2509          the result of that operation is not on stack then
2510          we can leave the result of this operation in acc:b
2511          combination */
2512       if ((IS_ARITHMETIC_OP (ic)
2513            || IS_CONDITIONAL(ic)
2514            || IS_BITWISE_OP (ic)
2515            || ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == CALL
2516            || (ic->op == ADDRESS_OF && isOperandOnStack (IC_LEFT (ic)))
2517           ) &&
2518           IS_ITEMP (IC_RESULT (ic)) &&
2519           getSize (operandType (IC_RESULT (ic))) <= 2)
2520
2521         packRegsForAccUse (ic);
2522     }
2523 }
2524
2525 /*-----------------------------------------------------------------*/
2526 /* assignRegisters - assigns registers to each live range as need  */
2527 /*-----------------------------------------------------------------*/
2528 void
2529 mcs51_assignRegisters (eBBlock ** ebbs, int count)
2530 {
2531   iCode *ic;
2532   int i;
2533
2534   setToNull ((void *) &_G.funcrUsed);
2535   mcs51_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
2536   mcs51_nRegs = 8;
2537
2538   /* change assignments this will remove some
2539      live ranges reducing some register pressure */
2540   for (i = 0; i < count; i++)
2541     packRegisters (ebbs[i]);
2542
2543   if (options.dump_pack)
2544     dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
2545
2546   /* first determine for each live range the number of 
2547      registers & the type of registers required for each */
2548   regTypeNum (*ebbs);
2549
2550   /* and serially allocate registers */
2551   serialRegAssign (ebbs, count);
2552
2553   /* if stack was extended then tell the user */
2554   if (_G.stackExtend)
2555     {
2556 /*      werror(W_TOOMANY_SPILS,"stack", */
2557 /*             _G.stackExtend,currFunc->name,""); */
2558       _G.stackExtend = 0;
2559     }
2560
2561   if (_G.dataExtend)
2562     {
2563 /*      werror(W_TOOMANY_SPILS,"data space", */
2564 /*             _G.dataExtend,currFunc->name,""); */
2565       _G.dataExtend = 0;
2566     }
2567
2568   /* after that create the register mask
2569      for each of the instruction */
2570   createRegMask (ebbs, count);
2571
2572   /* redo that offsets for stacked automatic variables */
2573   redoStackOffsets ();
2574
2575   if (options.dump_rassgn)
2576     {
2577       dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
2578       dumpLiveRanges (DUMP_LRANGE, liveRanges);
2579     }
2580
2581   /* do the overlaysegment stuff SDCCmem.c */
2582   doOverlays (ebbs, count);
2583
2584   /* now get back the chain */
2585   ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
2586
2587   gen51Code (ic);
2588
2589   /* free up any _G.stackSpil locations allocated */
2590   applyToSet (_G.stackSpil, deallocStackSpil);
2591   _G.slocNum = 0;
2592   setToNull ((void **) &_G.stackSpil);
2593   setToNull ((void **) &_G.spiltSet);
2594   /* mark all registers as free */
2595   freeAllRegs ();
2596
2597   return;
2598 }