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