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