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