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