slocs are not statics
[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                             spillThis (sym);
1162                             continue;
1163                         }
1164                     }
1165                 }
1166                 /* if we need ptr regs for the right side
1167                    then mark it */
1168                 if (POINTER_GET (ic) && IS_SYMOP (IC_LEFT (ic))
1169                     && getSize (OP_SYMBOL (IC_LEFT (ic))->type) <= (unsigned int) PTRSIZE) {
1170                     mcs51_ptrRegReq++;
1171                     ptrRegSet = 1;
1172                 }
1173                 /* else we assign registers to it */
1174                 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1175
1176                 for (j = 0; j < sym->nRegs; j++) {
1177                     if (sym->regType == REG_PTR)
1178                         sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
1179                     else
1180                         sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
1181
1182                     /* if the allocation failed which means
1183                        this was spilt then break */
1184                     if (!sym->regs[j]) {
1185                       if (j) {
1186                         fprintf (stderr, "%d reg(s) lost in %s:%d\n",
1187                                  j, __FILE__,__LINE__);
1188                       }
1189                       break;
1190                     }
1191                 }
1192
1193                 /* if it shares registers with operands make sure
1194                    that they are in the same position */
1195                 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
1196                     OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=') {
1197                     positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1198                                   OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
1199                 }
1200                 /* do the same for the right operand */
1201                 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
1202                     OP_SYMBOL (IC_RIGHT (ic))->nRegs) {
1203                     positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1204                                   OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
1205                 }
1206
1207                 if (ptrRegSet) {
1208                     mcs51_ptrRegReq--;
1209                     ptrRegSet = 0;
1210                 }
1211
1212             }
1213         }
1214     }
1215 }
1216
1217 /*-----------------------------------------------------------------*/
1218 /* rUmaskForOp :- returns register mask for an operand             */
1219 /*-----------------------------------------------------------------*/
1220 bitVect *
1221 mcs51_rUmaskForOp (operand * op)
1222 {
1223   bitVect *rumask;
1224   symbol *sym;
1225   int j;
1226
1227   /* only temporaries are assigned registers */
1228   if (!IS_ITEMP (op))
1229     return NULL;
1230
1231   sym = OP_SYMBOL (op);
1232
1233   /* if spilt or no registers assigned to it
1234      then nothing */
1235   if (sym->isspilt || !sym->nRegs)
1236     return NULL;
1237
1238   rumask = newBitVect (mcs51_nRegs);
1239
1240   for (j = 0; j < sym->nRegs; j++)
1241     {
1242       rumask = bitVectSetBit (rumask,
1243                               sym->regs[j]->rIdx);
1244     }
1245
1246   return rumask;
1247 }
1248
1249 /*-----------------------------------------------------------------*/
1250 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
1251 /*-----------------------------------------------------------------*/
1252 static bitVect *
1253 regsUsedIniCode (iCode * ic)
1254 {
1255   bitVect *rmask = newBitVect (mcs51_nRegs);
1256
1257   /* do the special cases first */
1258   if (ic->op == IFX)
1259     {
1260       rmask = bitVectUnion (rmask,
1261                             mcs51_rUmaskForOp (IC_COND (ic)));
1262       goto ret;
1263     }
1264
1265   /* for the jumptable */
1266   if (ic->op == JUMPTABLE)
1267     {
1268       rmask = bitVectUnion (rmask,
1269                             mcs51_rUmaskForOp (IC_JTCOND (ic)));
1270
1271       goto ret;
1272     }
1273
1274   /* of all other cases */
1275   if (IC_LEFT (ic))
1276     rmask = bitVectUnion (rmask,
1277                           mcs51_rUmaskForOp (IC_LEFT (ic)));
1278
1279
1280   if (IC_RIGHT (ic))
1281     rmask = bitVectUnion (rmask,
1282                           mcs51_rUmaskForOp (IC_RIGHT (ic)));
1283
1284   if (IC_RESULT (ic))
1285     rmask = bitVectUnion (rmask,
1286                           mcs51_rUmaskForOp (IC_RESULT (ic)));
1287
1288 ret:
1289   return rmask;
1290 }
1291
1292 /*-----------------------------------------------------------------*/
1293 /* createRegMask - for each instruction will determine the regsUsed */
1294 /*-----------------------------------------------------------------*/
1295 static void
1296 createRegMask (eBBlock ** ebbs, int count)
1297 {
1298   int i;
1299
1300   /* for all blocks */
1301   for (i = 0; i < count; i++)
1302     {
1303       iCode *ic;
1304
1305       if (ebbs[i]->noPath &&
1306           (ebbs[i]->entryLabel != entryLabel &&
1307            ebbs[i]->entryLabel != returnLabel))
1308         continue;
1309
1310       /* for all instructions */
1311       for (ic = ebbs[i]->sch; ic; ic = ic->next)
1312         {
1313
1314           int j;
1315
1316           if (SKIP_IC2 (ic) || !ic->rlive)
1317             continue;
1318
1319           /* first mark the registers used in this
1320              instruction */
1321           ic->rUsed = regsUsedIniCode (ic);
1322           _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
1323
1324           /* now create the register mask for those 
1325              registers that are in use : this is a
1326              super set of ic->rUsed */
1327           ic->rMask = newBitVect (mcs51_nRegs + 1);
1328
1329           /* for all live Ranges alive at this point */
1330           for (j = 1; j < ic->rlive->size; j++)
1331             {
1332               symbol *sym;
1333               int k;
1334
1335               /* if not alive then continue */
1336               if (!bitVectBitValue (ic->rlive, j))
1337                 continue;
1338
1339               /* find the live range we are interested in */
1340               if (!(sym = hTabItemWithKey (liveRanges, j)))
1341                 {
1342                   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1343                           "createRegMask cannot find live range");
1344                   exit (0);
1345                 }
1346
1347               /* if no register assigned to it */
1348               if (!sym->nRegs || sym->isspilt)
1349                 continue;
1350
1351               /* for all the registers allocated to it */
1352               for (k = 0; k < sym->nRegs; k++)
1353                 if (sym->regs[k])
1354                   ic->rMask =
1355                     bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
1356             }
1357         }
1358     }
1359 }
1360
1361 /*-----------------------------------------------------------------*/
1362 /* rematStr - returns the rematerialized string for a remat var    */
1363 /*-----------------------------------------------------------------*/
1364 static char *
1365 rematStr (symbol * sym)
1366 {
1367   char *s = buffer;
1368   iCode *ic = sym->rematiCode;
1369
1370   while (1)
1371     {
1372
1373       /* if plus or minus print the right hand side */
1374       if (ic->op == '+' || ic->op == '-')
1375         {
1376           sprintf (s, "0x%04x %c ", (int) operandLitValue (IC_RIGHT (ic)),
1377                    ic->op);
1378           s += strlen (s);
1379           ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1380           continue;
1381         }
1382
1383       /* cast then continue */
1384       if (IS_CAST_ICODE(ic)) {
1385           ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
1386           continue;
1387       }
1388       /* we reached the end */
1389       sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
1390       break;
1391     }
1392
1393   return buffer;
1394 }
1395
1396 /*-----------------------------------------------------------------*/
1397 /* regTypeNum - computes the type & number of registers required   */
1398 /*-----------------------------------------------------------------*/
1399 static void
1400 regTypeNum ()
1401 {
1402   symbol *sym;
1403   int k;
1404   iCode *ic;
1405
1406   /* for each live range do */
1407   for (sym = hTabFirstItem (liveRanges, &k); sym;
1408        sym = hTabNextItem (liveRanges, &k))
1409     {
1410
1411       /* if used zero times then no registers needed */
1412       if ((sym->liveTo - sym->liveFrom) == 0)
1413         continue;
1414
1415
1416       /* if the live range is a temporary */
1417       if (sym->isitmp)
1418         {
1419
1420           /* if the type is marked as a conditional */
1421           if (sym->regType == REG_CND)
1422             continue;
1423
1424           /* if used in return only then we don't 
1425              need registers */
1426           if (sym->ruonly || sym->accuse)
1427             {
1428               if (IS_AGGREGATE (sym->type) || sym->isptr)
1429                 sym->type = aggrToPtr (sym->type, FALSE);
1430               continue;
1431             }
1432
1433           /* if the symbol has only one definition &
1434              that definition is a get_pointer and the
1435              pointer we are getting is rematerializable and
1436              in "data" space */
1437
1438           if (bitVectnBitsOn (sym->defs) == 1 &&
1439               (ic = hTabItemWithKey (iCodehTab,
1440                                      bitVectFirstBit (sym->defs))) &&
1441               POINTER_GET (ic) &&
1442               !sym->noSpilLoc &&
1443               !IS_BITVAR (sym->etype))
1444             {
1445
1446
1447               /* if remat in data space */
1448               if (OP_SYMBOL (IC_LEFT (ic))->remat &&
1449                   !IS_CAST_ICODE(OP_SYMBOL (IC_LEFT (ic))->rematiCode) &&
1450                   DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER)
1451                 {
1452
1453                   /* create a psuedo symbol & force a spil */
1454                   symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
1455                   psym->type = sym->type;
1456                   psym->etype = sym->etype;
1457                   strcpy (psym->rname, psym->name);
1458                   sym->isspilt = 1;
1459                   sym->usl.spillLoc = psym;
1460                   continue;
1461                 }
1462
1463               /* if in data space or idata space then try to
1464                  allocate pointer register */
1465
1466             }
1467
1468           /* if not then we require registers */
1469           sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
1470                         getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1471                         getSize (sym->type));
1472
1473           if (sym->nRegs > 4)
1474             {
1475               fprintf (stderr, "allocated more than 4 or 0 registers for type ");
1476               printTypeChain (sym->type, stderr);
1477               fprintf (stderr, "\n");
1478             }
1479
1480           /* determine the type of register required */
1481           if (sym->nRegs == 1 &&
1482               IS_PTR (sym->type) &&
1483               sym->uptr)
1484             sym->regType = REG_PTR;
1485           else
1486             sym->regType = REG_GPR;
1487
1488         }
1489       else
1490         /* for the first run we don't provide */
1491         /* registers for true symbols we will */
1492         /* see how things go                  */
1493         sym->nRegs = 0;
1494     }
1495
1496 }
1497
1498 /*-----------------------------------------------------------------*/
1499 /* freeAllRegs - mark all registers as free                        */
1500 /*-----------------------------------------------------------------*/
1501 static void
1502 freeAllRegs ()
1503 {
1504   int i;
1505
1506   for (i = 0; i < mcs51_nRegs; i++)
1507     regs8051[i].isFree = 1;
1508 }
1509
1510 /*-----------------------------------------------------------------*/
1511 /* deallocStackSpil - this will set the stack pointer back         */
1512 /*-----------------------------------------------------------------*/
1513 static
1514 DEFSETFUNC (deallocStackSpil)
1515 {
1516   symbol *sym = item;
1517
1518   deallocLocal (sym);
1519   return 0;
1520 }
1521
1522 /*-----------------------------------------------------------------*/
1523 /* farSpacePackable - returns the packable icode for far variables */
1524 /*-----------------------------------------------------------------*/
1525 static iCode *
1526 farSpacePackable (iCode * ic)
1527 {
1528   iCode *dic;
1529
1530   /* go thru till we find a definition for the
1531      symbol on the right */
1532   for (dic = ic->prev; dic; dic = dic->prev)
1533     {
1534       /* if the definition is a call then no */
1535       if ((dic->op == CALL || dic->op == PCALL) &&
1536           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1537         {
1538           return NULL;
1539         }
1540
1541       /* if shift by unknown amount then not */
1542       if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
1543           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1544         return NULL;
1545
1546       /* if pointer get and size > 1 */
1547       if (POINTER_GET (dic) &&
1548           getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
1549         return NULL;
1550
1551       if (POINTER_SET (dic) &&
1552           getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
1553         return NULL;
1554
1555       /* if any three is a true symbol in far space */
1556       if (IC_RESULT (dic) &&
1557           IS_TRUE_SYMOP (IC_RESULT (dic)) &&
1558           isOperandInFarSpace (IC_RESULT (dic)))
1559         return NULL;
1560
1561       if (IC_RIGHT (dic) &&
1562           IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
1563           isOperandInFarSpace (IC_RIGHT (dic)) &&
1564           !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
1565         return NULL;
1566
1567       if (IC_LEFT (dic) &&
1568           IS_TRUE_SYMOP (IC_LEFT (dic)) &&
1569           isOperandInFarSpace (IC_LEFT (dic)) &&
1570           !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
1571         return NULL;
1572
1573       if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
1574         {
1575           if ((dic->op == LEFT_OP ||
1576                dic->op == RIGHT_OP ||
1577                dic->op == '-') &&
1578               IS_OP_LITERAL (IC_RIGHT (dic)))
1579             return NULL;
1580           else
1581             return dic;
1582         }
1583     }
1584
1585   return NULL;
1586 }
1587
1588 /*-----------------------------------------------------------------*/
1589 /* packRegsForAssign - register reduction for assignment           */
1590 /*-----------------------------------------------------------------*/
1591 static int
1592 packRegsForAssign (iCode * ic, eBBlock * ebp)
1593 {
1594   iCode *dic, *sic;
1595   //sym_link *etype = operandType (IC_RIGHT (ic));
1596
1597   if (!IS_ITEMP (IC_RIGHT (ic)) ||
1598       OP_SYMBOL (IC_RIGHT (ic))->isind ||
1599       OP_LIVETO (IC_RIGHT (ic)) > ic->seq
1600       /* why? || IS_BITFIELD (etype) */ )
1601     {
1602       return 0;
1603     }
1604
1605   /* if the true symbol is defined in far space or on stack
1606      then we should not since this will increase register pressure */
1607   if (isOperandInFarSpace(IC_RESULT(ic)) && !farSpacePackable(ic)) {
1608     return 0;
1609   }
1610
1611   /* find the definition of iTempNN scanning backwards if we find a 
1612      a use of the true symbol in before we find the definition then 
1613      we cannot */
1614   for (dic = ic->prev; dic; dic = dic->prev)
1615     {
1616       /* if there is a function call then don't pack it */
1617       if ((dic->op == CALL || dic->op == PCALL))
1618         {
1619           dic = NULL;
1620           break;
1621         }
1622
1623       if (SKIP_IC2 (dic))
1624         continue;
1625
1626       if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
1627           IS_OP_VOLATILE (IC_RESULT (dic)))
1628         {
1629           dic = NULL;
1630           break;
1631         }
1632
1633       if (IS_SYMOP (IC_RESULT (dic)) &&
1634           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1635         {
1636           if (POINTER_SET (dic))
1637             dic = NULL;
1638
1639           break;
1640         }
1641
1642       if (IS_SYMOP (IC_RIGHT (dic)) &&
1643           (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
1644            IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
1645         {
1646           dic = NULL;
1647           break;
1648         }
1649
1650       if (IS_SYMOP (IC_LEFT (dic)) &&
1651           (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
1652            IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
1653         {
1654           dic = NULL;
1655           break;
1656         }
1657
1658       if (POINTER_SET (dic) &&
1659           IC_RESULT (dic)->key == IC_RESULT (ic)->key)
1660         {
1661           dic = NULL;
1662           break;
1663         }
1664     }
1665
1666   if (!dic)
1667     return 0;                   /* did not find */
1668
1669   /* if assignment then check that right is not a bit */
1670   if (ASSIGNMENT (dic) && !POINTER_SET (dic))
1671     {
1672       sym_link *etype = operandType (IC_RIGHT (dic));
1673       if (IS_BITFIELD (etype))
1674         return 0;
1675     }
1676   /* if the result is on stack or iaccess then it must be
1677      the same atleast one of the operands */
1678   if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
1679       OP_SYMBOL (IC_RESULT (ic))->iaccess)
1680     {
1681
1682       /* the operation has only one symbol
1683          operator then we can pack */
1684       if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
1685           (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
1686         goto pack;
1687
1688       if (!((IC_LEFT (dic) &&
1689              IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
1690             (IC_RIGHT (dic) &&
1691              IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
1692         return 0;
1693     }
1694 pack:
1695   /* found the definition */
1696   /* replace the result with the result of */
1697   /* this assignment and remove this assignment */
1698   IC_RESULT (dic) = IC_RESULT (ic);
1699
1700   if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
1701     {
1702       OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
1703     }
1704   /* delete from liverange table also 
1705      delete from all the points inbetween and the new
1706      one */
1707   for (sic = dic; sic != ic; sic = sic->next)
1708     {
1709       bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
1710       if (IS_ITEMP (IC_RESULT (dic)))
1711         bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
1712     }
1713
1714   remiCodeFromeBBlock (ebp, ic);
1715   hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
1716   OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
1717   return 1;
1718
1719 }
1720
1721 /*-----------------------------------------------------------------*/
1722 /* findAssignToSym : scanning backwards looks for first assig found */
1723 /*-----------------------------------------------------------------*/
1724 static iCode *
1725 findAssignToSym (operand * op, iCode * ic)
1726 {
1727   iCode *dic;
1728
1729   for (dic = ic->prev; dic; dic = dic->prev)
1730     {
1731
1732       /* if definition by assignment */
1733       if (dic->op == '=' &&
1734           !POINTER_SET (dic) &&
1735           IC_RESULT (dic)->key == op->key
1736 /*          &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) */
1737         )
1738         {
1739
1740           /* we are interested only if defined in far space */
1741           /* or in stack space in case of + & - */
1742
1743           /* if assigned to a non-symbol then return
1744              FALSE */
1745           if (!IS_SYMOP (IC_RIGHT (dic)))
1746             return NULL;
1747
1748           /* if the symbol is in far space then
1749              we should not */
1750           if (isOperandInFarSpace (IC_RIGHT (dic)))
1751             return NULL;
1752
1753           /* for + & - operations make sure that
1754              if it is on the stack it is the same
1755              as one of the three operands */
1756           if ((ic->op == '+' || ic->op == '-') &&
1757               OP_SYMBOL (IC_RIGHT (dic))->onStack)
1758             {
1759
1760               if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
1761                   IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
1762                   IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
1763                 return NULL;
1764             }
1765
1766           break;
1767
1768         }
1769
1770       /* if we find an usage then we cannot delete it */
1771       if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
1772         return NULL;
1773
1774       if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
1775         return NULL;
1776
1777       if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
1778         return NULL;
1779     }
1780
1781   /* now make sure that the right side of dic
1782      is not defined between ic & dic */
1783   if (dic)
1784     {
1785       iCode *sic = dic->next;
1786
1787       for (; sic != ic; sic = sic->next)
1788         if (IC_RESULT (sic) &&
1789             IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
1790           return NULL;
1791     }
1792
1793   return dic;
1794
1795
1796 }
1797
1798 /*-----------------------------------------------------------------*/
1799 /* packRegsForSupport :- reduce some registers for support calls   */
1800 /*-----------------------------------------------------------------*/
1801 static int
1802 packRegsForSupport (iCode * ic, eBBlock * ebp)
1803 {
1804   int change = 0;
1805   iCode *dic, *sic;
1806
1807   /* for the left & right operand :- look to see if the
1808      left was assigned a true symbol in far space in that
1809      case replace them */
1810
1811   if (IS_ITEMP (IC_LEFT (ic)) &&
1812       OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
1813     {
1814       dic = findAssignToSym (IC_LEFT (ic), ic);
1815
1816       if (!dic)
1817         goto right;
1818
1819       /* found it we need to remove it from the
1820          block */
1821       for (sic = dic; sic != ic; sic = sic->next)
1822         bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
1823
1824       OP_SYMBOL(IC_LEFT (ic))=OP_SYMBOL(IC_RIGHT (dic));
1825       IC_LEFT (ic)->key = OP_SYMBOL(IC_RIGHT (dic))->key;
1826       remiCodeFromeBBlock (ebp, dic);
1827       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1828       change++;
1829     }
1830
1831   /* do the same for the right operand */
1832  right:
1833   if (!change &&
1834       IS_ITEMP (IC_RIGHT (ic)) &&
1835       OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
1836     {
1837       iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
1838       iCode *sic;
1839
1840       if (!dic)
1841         return change;
1842
1843       /* if this is a subtraction & the result
1844          is a true symbol in far space then don't pack */
1845       if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
1846         {
1847           sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
1848           if (IN_FARSPACE (SPEC_OCLS (etype)))
1849             return change;
1850         }
1851       /* found it we need to remove it from the
1852          block */
1853       for (sic = dic; sic != ic; sic = sic->next)
1854         bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
1855
1856       IC_RIGHT (ic)->operand.symOperand =
1857         IC_RIGHT (dic)->operand.symOperand;
1858       IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
1859
1860       remiCodeFromeBBlock (ebp, dic);
1861       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1862       change++;
1863     }
1864
1865   return change;
1866 }
1867
1868 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
1869
1870
1871 /*-----------------------------------------------------------------*/
1872 /* packRegsForOneuse : - will reduce some registers for single Use */
1873 /*-----------------------------------------------------------------*/
1874 static iCode *
1875 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
1876 {
1877   bitVect *uses;
1878   iCode *dic, *sic;
1879
1880   /* if returning a literal then do nothing */
1881   if (!IS_SYMOP (op))
1882     return NULL;
1883
1884   /* only upto 2 bytes since we cannot predict
1885      the usage of b, & acc */
1886   if (getSize (operandType (op)) > (fReturnSizeMCS51 - 2))
1887     return NULL;
1888
1889   if (ic->op != RETURN &&
1890       ic->op != SEND &&
1891       !POINTER_SET (ic) &&
1892       !POINTER_GET (ic))
1893     return NULL;
1894   
1895   /* this routine will mark the a symbol as used in one 
1896      instruction use only && if the defintion is local 
1897      (ie. within the basic block) && has only one definition &&
1898      that definiion is either a return value from a 
1899      function or does not contain any variables in
1900      far space */
1901   uses = bitVectCopy (OP_USES (op));
1902   bitVectUnSetBit (uses, ic->key);      /* take away this iCode */
1903   if (!bitVectIsZero (uses))    /* has other uses */
1904     return NULL;
1905
1906   /* if it has only one defintion */
1907   if (bitVectnBitsOn (OP_DEFS (op)) > 1)
1908     return NULL;                /* has more than one definition */
1909
1910   /* get that definition */
1911   if (!(dic =
1912         hTabItemWithKey (iCodehTab,
1913                          bitVectFirstBit (OP_DEFS (op)))))
1914     return NULL;
1915
1916   /* if that only usage is a cast */
1917   if (dic->op == CAST) {
1918     /* to a bigger type */
1919     if (getSize(OP_SYM_TYPE(IC_RESULT(dic))) > 
1920         getSize(OP_SYM_TYPE(IC_RIGHT(dic)))) {
1921       /* than we can not, since we cannot predict the usage of b & acc */
1922       return NULL;
1923     }
1924   }
1925
1926   /* found the definition now check if it is local */
1927   if (dic->seq < ebp->fSeq ||
1928       dic->seq > ebp->lSeq)
1929     return NULL;                /* non-local */
1930
1931   /* now check if it is the return from
1932      a function call */
1933   if (dic->op == CALL || dic->op == PCALL)
1934     {
1935       if (ic->op != SEND && ic->op != RETURN)
1936         {
1937           OP_SYMBOL (op)->ruonly = 1;
1938           return dic;
1939         }
1940       dic = dic->next;
1941     }
1942
1943
1944   /* otherwise check that the definition does
1945      not contain any symbols in far space */
1946   if (isOperandInFarSpace (IC_LEFT (dic)) ||
1947       isOperandInFarSpace (IC_RIGHT (dic)) ||
1948       IS_OP_RUONLY (IC_LEFT (ic)) ||
1949       IS_OP_RUONLY (IC_RIGHT (ic)))
1950     {
1951       return NULL;
1952     }
1953
1954   /* if pointer set then make sure the pointer
1955      is one byte */
1956   if (POINTER_SET (dic) &&
1957       !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
1958     return NULL;
1959
1960   if (POINTER_GET (dic) &&
1961       !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
1962     return NULL;
1963
1964   sic = dic;
1965
1966   /* also make sure the intervenening instructions
1967      don't have any thing in far space */
1968   for (dic = dic->next; dic && dic != ic && sic != ic; dic = dic->next)
1969     {
1970
1971       /* if there is an intervening function call then no */
1972       if (dic->op == CALL || dic->op == PCALL)
1973         return NULL;
1974       /* if pointer set then make sure the pointer
1975          is one byte */
1976       if (POINTER_SET (dic) &&
1977           !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
1978         return NULL;
1979
1980       if (POINTER_GET (dic) &&
1981           !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
1982         return NULL;
1983
1984       /* if address of & the result is remat the okay */
1985       if (dic->op == ADDRESS_OF &&
1986           OP_SYMBOL (IC_RESULT (dic))->remat)
1987         continue;
1988
1989       /* if operand has size of three or more & this
1990          operation is a '*','/' or '%' then 'b' may
1991          cause a problem */
1992       if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
1993           getSize (operandType (op)) >= 3)
1994         return NULL;
1995
1996       /* if left or right or result is in far space */
1997       if (isOperandInFarSpace (IC_LEFT (dic)) ||
1998           isOperandInFarSpace (IC_RIGHT (dic)) ||
1999           isOperandInFarSpace (IC_RESULT (dic)) ||
2000           IS_OP_RUONLY (IC_LEFT (dic)) ||
2001           IS_OP_RUONLY (IC_RIGHT (dic)) ||
2002           IS_OP_RUONLY (IC_RESULT (dic)))
2003         {
2004           return NULL;
2005         }
2006       /* if left or right or result is on stack */
2007       if (isOperandOnStack(IC_LEFT(dic)) ||
2008           isOperandOnStack(IC_RIGHT(dic)) ||
2009           isOperandOnStack(IC_RESULT(dic))) {
2010         return NULL;
2011       }
2012     }
2013
2014   OP_SYMBOL (op)->ruonly = 1;
2015   return sic;
2016
2017 }
2018
2019 /*-----------------------------------------------------------------*/
2020 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
2021 /*-----------------------------------------------------------------*/
2022 static bool
2023 isBitwiseOptimizable (iCode * ic)
2024 {
2025   sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
2026   sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
2027
2028   /* bitwise operations are considered optimizable
2029      under the following conditions (Jean-Louis VERN) 
2030
2031      x & lit
2032      bit & bit
2033      bit & x
2034      bit ^ bit
2035      bit ^ x
2036      x   ^ lit
2037      x   | lit
2038      bit | bit
2039      bit | x
2040   */
2041   if (IS_LITERAL(rtype) ||
2042       (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
2043     return TRUE;
2044   else
2045     return FALSE;
2046 }
2047
2048 /*-----------------------------------------------------------------*/
2049 /* packRegsForAccUse - pack registers for acc use                  */
2050 /*-----------------------------------------------------------------*/
2051 static void
2052 packRegsForAccUse (iCode * ic)
2053 {
2054   iCode *uic;
2055
2056   /* if + or - then it has to be one byte result */
2057   if ((ic->op == '+' || ic->op == '-')
2058       && getSize (operandType (IC_RESULT (ic))) > 1)
2059     return;
2060
2061   /* if shift operation make sure right side is not a literal */
2062   if (ic->op == RIGHT_OP &&
2063       (isOperandLiteral (IC_RIGHT (ic)) ||
2064        getSize (operandType (IC_RESULT (ic))) > 1))
2065     return;
2066
2067   if (ic->op == LEFT_OP &&
2068       (isOperandLiteral (IC_RIGHT (ic)) ||
2069        getSize (operandType (IC_RESULT (ic))) > 1))
2070     return;
2071
2072   if (IS_BITWISE_OP (ic) &&
2073       getSize (operandType (IC_RESULT (ic))) > 1)
2074     return;
2075
2076
2077   /* has only one definition */
2078   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
2079     return;
2080
2081   /* has only one use */
2082   if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
2083     return;
2084
2085   /* and the usage immediately follows this iCode */
2086   if (!(uic = hTabItemWithKey (iCodehTab,
2087                                bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
2088     return;
2089
2090   if (ic->next != uic)
2091     return;
2092
2093   /* if it is a conditional branch then we definitely can */
2094   if (uic->op == IFX)
2095     goto accuse;
2096
2097   if (uic->op == JUMPTABLE)
2098     return;
2099
2100   /* if the usage is not is an assignment
2101      or an arithmetic / bitwise / shift operation then not */
2102   if (POINTER_SET (uic) &&
2103       getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
2104     return;
2105
2106   if (uic->op != '=' &&
2107       !IS_ARITHMETIC_OP (uic) &&
2108       !IS_BITWISE_OP (uic) &&
2109       uic->op != LEFT_OP &&
2110       uic->op != RIGHT_OP)
2111     return;
2112
2113   /* if used in ^ operation then make sure right is not a 
2114      literl */
2115   if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
2116     return;
2117
2118   /* if shift operation make sure right side is not a literal */
2119   if (uic->op == RIGHT_OP &&
2120       (isOperandLiteral (IC_RIGHT (uic)) ||
2121        getSize (operandType (IC_RESULT (uic))) > 1))
2122     return;
2123
2124   if (uic->op == LEFT_OP &&
2125       (isOperandLiteral (IC_RIGHT (uic)) ||
2126        getSize (operandType (IC_RESULT (uic))) > 1))
2127     return;
2128
2129   /* make sure that the result of this icode is not on the
2130      stack, since acc is used to compute stack offset */
2131   if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
2132       OP_SYMBOL (IC_RESULT (uic))->onStack)
2133     return;
2134
2135   /* if either one of them in far space then we cannot */
2136   if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
2137        isOperandInFarSpace (IC_LEFT (uic))) ||
2138       (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
2139        isOperandInFarSpace (IC_RIGHT (uic))))
2140     return;
2141
2142   /* if the usage has only one operand then we can */
2143   if (IC_LEFT (uic) == NULL ||
2144       IC_RIGHT (uic) == NULL)
2145     goto accuse;
2146
2147   /* make sure this is on the left side if not
2148      a '+' since '+' is commutative */
2149   if (ic->op != '+' &&
2150       IC_LEFT (uic)->key != IC_RESULT (ic)->key)
2151     return;
2152
2153 #if 0
2154   // this is too dangerous and need further restrictions
2155   // see bug #447547
2156
2157   /* if one of them is a literal then we can */
2158   if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
2159       (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
2160     {
2161       OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2162       return;
2163     }
2164 #endif
2165
2166   /* if the other one is not on stack then we can */
2167   if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
2168       (IS_ITEMP (IC_RIGHT (uic)) ||
2169        (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
2170         !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
2171     goto accuse;
2172
2173   if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
2174       (IS_ITEMP (IC_LEFT (uic)) ||
2175        (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
2176         !OP_SYMBOL (IC_LEFT (uic))->onStack)))
2177     goto accuse;
2178
2179   return;
2180
2181 accuse:
2182   OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2183
2184
2185 }
2186
2187 /*-----------------------------------------------------------------*/
2188 /* packForPush - hueristics to reduce iCode for pushing            */
2189 /*-----------------------------------------------------------------*/
2190 static void
2191 packForPush (iCode * ic, eBBlock * ebp)
2192 {
2193   iCode *dic, *lic;
2194   bitVect *dbv;
2195
2196   if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
2197     return;
2198
2199   /* must have only definition & one usage */
2200   if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
2201       bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
2202     return;
2203
2204   /* find the definition */
2205   if (!(dic = hTabItemWithKey (iCodehTab,
2206                                bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
2207     return;
2208
2209   if (dic->op != '=' || POINTER_SET (dic))
2210     return;
2211
2212   /* make sure the right side does not have any definitions
2213      inbetween */
2214   dbv = OP_DEFS(IC_RIGHT(dic));
2215   for (lic = ic; lic && lic != dic ; lic = lic->prev) {
2216     if (bitVectBitValue(dbv,lic->key)) 
2217       return ;
2218   }
2219   /* make sure they have the same type */
2220   {
2221     sym_link *itype=operandType(IC_LEFT(ic));
2222     sym_link *ditype=operandType(IC_RIGHT(dic));
2223
2224     if (SPEC_USIGN(itype)!=SPEC_USIGN(ditype) ||
2225         SPEC_LONG(itype)!=SPEC_LONG(ditype))
2226       return;
2227   }
2228   /* extend the live range of replaced operand if needed */
2229   if (OP_SYMBOL(IC_RIGHT(dic))->liveTo < ic->seq) {
2230           OP_SYMBOL(IC_RIGHT(dic))->liveTo = ic->seq;
2231   }
2232   /* we now we know that it has one & only one def & use
2233      and the that the definition is an assignment */
2234   IC_LEFT (ic) = IC_RIGHT (dic);
2235    
2236   remiCodeFromeBBlock (ebp, dic);
2237   hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2238 }
2239
2240 /*-----------------------------------------------------------------*/
2241 /* packRegisters - does some transformations to reduce register    */
2242 /*                   pressure                                      */
2243 /*-----------------------------------------------------------------*/
2244 static void
2245 packRegisters (eBBlock * ebp)
2246 {
2247   iCode *ic;
2248   int change = 0;
2249
2250   while (1)
2251     {
2252
2253       change = 0;
2254
2255       /* look for assignments of the form */
2256       /* iTempNN = TRueSym (someoperation) SomeOperand */
2257       /*       ....                       */
2258       /* TrueSym := iTempNN:1             */
2259       for (ic = ebp->sch; ic; ic = ic->next)
2260         {
2261           /* find assignment of the form TrueSym := iTempNN:1 */
2262           if (ic->op == '=' && !POINTER_SET (ic))
2263             change += packRegsForAssign (ic, ebp);
2264         }
2265
2266       if (!change)
2267         break;
2268     }
2269
2270   for (ic = ebp->sch; ic; ic = ic->next)
2271     {
2272       /* if this is an itemp & result of an address of a true sym 
2273          then mark this as rematerialisable   */
2274       if (ic->op == ADDRESS_OF &&
2275           IS_ITEMP (IC_RESULT (ic)) &&
2276           IS_TRUE_SYMOP (IC_LEFT (ic)) &&
2277           bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2278           !OP_SYMBOL (IC_LEFT (ic))->onStack)
2279         {
2280
2281           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2282           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2283           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2284
2285         }
2286
2287       /* if straight assignment then carry remat flag if
2288          this is the only definition */
2289       if (ic->op == '=' &&
2290           !POINTER_SET (ic) &&
2291           IS_SYMOP (IC_RIGHT (ic)) &&
2292           OP_SYMBOL (IC_RIGHT (ic))->remat &&
2293           !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode) &&
2294           bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
2295         {
2296
2297           OP_SYMBOL (IC_RESULT (ic))->remat =
2298             OP_SYMBOL (IC_RIGHT (ic))->remat;
2299           OP_SYMBOL (IC_RESULT (ic))->rematiCode =
2300             OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
2301         }
2302
2303       /* if cast to a generic pointer & the pointer being
2304          cast is remat, then we can remat this cast as well */
2305       if (ic->op == CAST && 
2306           IS_SYMOP(IC_RIGHT(ic)) &&
2307           OP_SYMBOL(IC_RIGHT(ic))->remat ) {
2308               sym_link *to_type = operandType(IC_LEFT(ic));
2309               sym_link *from_type = operandType(IC_RIGHT(ic));
2310               if (IS_GENPTR(to_type) && IS_PTR(from_type)) {                  
2311                       OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2312                       OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2313                       OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2314               }
2315       }
2316
2317       /* if this is a +/- operation with a rematerizable 
2318          then mark this as rematerializable as well */
2319       if ((ic->op == '+' || ic->op == '-') &&
2320           (IS_SYMOP (IC_LEFT (ic)) &&
2321            IS_ITEMP (IC_RESULT (ic)) &&
2322            IS_OP_LITERAL (IC_RIGHT (ic))) &&
2323            OP_SYMBOL (IC_LEFT (ic))->remat &&
2324           (!IS_SYMOP (IC_RIGHT (ic)) || !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode)) &&
2325            bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1)
2326         {
2327           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2328           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2329           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2330         }
2331
2332       /* mark the pointer usages */
2333       if (POINTER_SET (ic))
2334         OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
2335
2336       if (POINTER_GET (ic))
2337         OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
2338
2339       if (!SKIP_IC2 (ic))
2340         {
2341           /* if we are using a symbol on the stack
2342              then we should say mcs51_ptrRegReq */
2343           if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
2344             mcs51_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
2345                                  OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
2346           else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
2347             mcs51_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
2348                               OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
2349           else
2350             {
2351               if (IS_SYMOP (IC_LEFT (ic)))
2352                 mcs51_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
2353                                 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
2354               if (IS_SYMOP (IC_RIGHT (ic)))
2355                 mcs51_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
2356                                OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
2357               if (IS_SYMOP (IC_RESULT (ic)))
2358                 mcs51_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
2359                               OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
2360             }
2361         }
2362
2363       /* if the condition of an if instruction
2364          is defined in the previous instruction and
2365          this is the only usage then
2366          mark the itemp as a conditional */
2367       if ((IS_CONDITIONAL (ic) ||
2368            (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic))) &&
2369           ic->next && ic->next->op == IFX &&
2370           bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
2371           isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
2372           OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2373         {
2374           OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
2375           continue;
2376         }
2377
2378       /* reduce for support function calls */
2379       if (ic->supportRtn || ic->op == '+' || ic->op == '-')
2380         packRegsForSupport (ic, ebp);
2381
2382       /* some cases the redundant moves can
2383          can be eliminated for return statements */
2384       if ((ic->op == RETURN || ic->op == SEND) &&
2385           !isOperandInFarSpace (IC_LEFT (ic)) &&
2386           options.model == MODEL_SMALL) {
2387         if (0 && options.stackAuto) {
2388           /* we should check here if acc will be clobbered for stack
2389              offset calculations */
2390         } else {
2391           packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2392         }
2393       }
2394
2395       /* if pointer set & left has a size more than
2396          one and right is not in far space */
2397       if (POINTER_SET (ic) &&
2398           !isOperandInFarSpace (IC_RIGHT (ic)) &&
2399           !OP_SYMBOL (IC_RESULT (ic))->remat &&
2400           !IS_OP_RUONLY (IC_RIGHT (ic)) &&
2401           getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
2402
2403         packRegsForOneuse (ic, IC_RESULT (ic), ebp);
2404
2405       /* if pointer get */
2406       if (POINTER_GET (ic) &&
2407           !isOperandInFarSpace (IC_RESULT (ic)) &&
2408           !OP_SYMBOL (IC_LEFT (ic))->remat &&
2409           !IS_OP_RUONLY (IC_RESULT (ic)) &&
2410           getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
2411
2412         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2413
2414
2415       /* if this is cast for intergral promotion then
2416          check if only use of  the definition of the 
2417          operand being casted/ if yes then replace
2418          the result of that arithmetic operation with 
2419          this result and get rid of the cast */
2420       if (ic->op == CAST)
2421         {
2422           sym_link *fromType = operandType (IC_RIGHT (ic));
2423           sym_link *toType = operandType (IC_LEFT (ic));
2424
2425           if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
2426               getSize (fromType) != getSize (toType) &&
2427               SPEC_USIGN (fromType) == SPEC_USIGN (toType))
2428             {
2429
2430               iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2431               if (dic)
2432                 {
2433                   if (IS_ARITHMETIC_OP (dic))
2434                     {                  
2435                       IC_RESULT (dic) = IC_RESULT (ic);
2436                       remiCodeFromeBBlock (ebp, ic);
2437                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2438                       OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2439                       ic = ic->prev;
2440                     }
2441                   else
2442                     OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
2443                 }
2444             }
2445           else
2446             {
2447
2448               /* if the type from and type to are the same
2449                  then if this is the only use then packit */
2450               if (compareType (operandType (IC_RIGHT (ic)),
2451                              operandType (IC_LEFT (ic))) == 1)
2452                 {
2453                   iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2454                   if (dic)
2455                     {
2456                       IC_RESULT (dic) = IC_RESULT (ic);
2457                       remiCodeFromeBBlock (ebp, ic);
2458                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2459                       OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2460                       ic = ic->prev;
2461                     }
2462                 }
2463             }
2464         }
2465
2466       /* pack for PUSH 
2467          iTempNN := (some variable in farspace) V1
2468          push iTempNN ;
2469          -------------
2470          push V1
2471        */
2472       if (ic->op == IPUSH)
2473         {
2474           packForPush (ic, ebp);
2475         }
2476
2477
2478       /* pack registers for accumulator use, when the
2479          result of an arithmetic or bit wise operation
2480          has only one use, that use is immediately following
2481          the defintion and the using iCode has only one
2482          operand or has two operands but one is literal &
2483          the result of that operation is not on stack then
2484          we can leave the result of this operation in acc:b
2485          combination */
2486       if ((IS_ARITHMETIC_OP (ic)
2487            || IS_CONDITIONAL(ic)
2488            || IS_BITWISE_OP (ic)
2489            || ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == CALL
2490            || (ic->op == ADDRESS_OF && isOperandOnStack (IC_LEFT (ic)))
2491           ) &&
2492           IS_ITEMP (IC_RESULT (ic)) &&
2493           getSize (operandType (IC_RESULT (ic))) <= 2)
2494
2495         packRegsForAccUse (ic);
2496     }
2497 }
2498
2499 /*-----------------------------------------------------------------*/
2500 /* assignRegisters - assigns registers to each live range as need  */
2501 /*-----------------------------------------------------------------*/
2502 void
2503 mcs51_assignRegisters (eBBlock ** ebbs, int count)
2504 {
2505   iCode *ic;
2506   int i;
2507
2508   setToNull ((void *) &_G.funcrUsed);
2509   mcs51_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
2510   mcs51_nRegs = 8;
2511
2512   /* change assignments this will remove some
2513      live ranges reducing some register pressure */
2514   for (i = 0; i < count; i++)
2515     packRegisters (ebbs[i]);
2516
2517   if (options.dump_pack)
2518     dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
2519
2520   /* first determine for each live range the number of 
2521      registers & the type of registers required for each */
2522   regTypeNum ();
2523
2524   /* and serially allocate registers */
2525   serialRegAssign (ebbs, count);
2526
2527   /* if stack was extended then tell the user */
2528   if (_G.stackExtend)
2529     {
2530 /*      werror(W_TOOMANY_SPILS,"stack", */
2531 /*             _G.stackExtend,currFunc->name,""); */
2532       _G.stackExtend = 0;
2533     }
2534
2535   if (_G.dataExtend)
2536     {
2537 /*      werror(W_TOOMANY_SPILS,"data space", */
2538 /*             _G.dataExtend,currFunc->name,""); */
2539       _G.dataExtend = 0;
2540     }
2541
2542   /* after that create the register mask
2543      for each of the instruction */
2544   createRegMask (ebbs, count);
2545
2546   /* redo that offsets for stacked automatic variables */
2547   redoStackOffsets ();
2548
2549   if (options.dump_rassgn)
2550     {
2551       dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
2552       dumpLiveRanges (DUMP_LRANGE, liveRanges);
2553     }
2554
2555   /* do the overlaysegment stuff SDCCmem.c */
2556   doOverlays (ebbs, count);
2557
2558   /* now get back the chain */
2559   ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
2560
2561   gen51Code (ic);
2562
2563   /* free up any _G.stackSpil locations allocated */
2564   applyToSet (_G.stackSpil, deallocStackSpil);
2565   _G.slocNum = 0;
2566   setToNull ((void **) &_G.stackSpil);
2567   setToNull ((void **) &_G.spiltSet);
2568   /* mark all registers as free */
2569   freeAllRegs ();
2570
2571   return;
2572 }