Fixed mixed type compares and conversions
[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                   <= (unsigned int) 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 #if 0 // jwk 20010410
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 #else
1637       /* if there is a function call then don't pack it */
1638       if ((dic->op == CALL || dic->op == PCALL))
1639         {
1640           dic = NULL;
1641           break;
1642         }
1643 #endif
1644
1645       if (SKIP_IC2 (dic))
1646         continue;
1647
1648       if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
1649           IS_OP_VOLATILE (IC_RESULT (dic)))
1650         {
1651           dic = NULL;
1652           break;
1653         }
1654
1655       if (IS_SYMOP (IC_RESULT (dic)) &&
1656           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1657         {
1658           if (POINTER_SET (dic))
1659             dic = NULL;
1660
1661           break;
1662         }
1663
1664       if (IS_SYMOP (IC_RIGHT (dic)) &&
1665           (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
1666            IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
1667         {
1668           dic = NULL;
1669           break;
1670         }
1671
1672       if (IS_SYMOP (IC_LEFT (dic)) &&
1673           (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
1674            IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
1675         {
1676           dic = NULL;
1677           break;
1678         }
1679
1680       if (POINTER_SET (dic) &&
1681           IC_RESULT (dic)->key == IC_RESULT (ic)->key)
1682         {
1683           dic = NULL;
1684           break;
1685         }
1686     }
1687
1688   if (!dic)
1689     return 0;                   /* did not find */
1690
1691   /* if assignment then check that right is not a bit */
1692   if (ASSIGNMENT (dic) && !POINTER_SET (dic))
1693     {
1694       sym_link *etype = operandType (IC_RIGHT (dic));
1695       if (IS_BITFIELD (etype))
1696         return 0;
1697     }
1698   /* if the result is on stack or iaccess then it must be
1699      the same atleast one of the operands */
1700   if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
1701       OP_SYMBOL (IC_RESULT (ic))->iaccess)
1702     {
1703
1704       /* the operation has only one symbol
1705          operator then we can pack */
1706       if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
1707           (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
1708         goto pack;
1709
1710       if (!((IC_LEFT (dic) &&
1711              IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
1712             (IC_RIGHT (dic) &&
1713              IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
1714         return 0;
1715     }
1716 pack:
1717   /* found the definition */
1718   /* replace the result with the result of */
1719   /* this assignment and remove this assignment */
1720   IC_RESULT (dic) = IC_RESULT (ic);
1721
1722   if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
1723     {
1724       OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
1725     }
1726   /* delete from liverange table also 
1727      delete from all the points inbetween and the new
1728      one */
1729   for (sic = dic; sic != ic; sic = sic->next)
1730     {
1731       bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
1732       if (IS_ITEMP (IC_RESULT (dic)))
1733         bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
1734     }
1735
1736   remiCodeFromeBBlock (ebp, ic);
1737   hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
1738   OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
1739   return 1;
1740
1741 }
1742
1743 /*-----------------------------------------------------------------*/
1744 /* findAssignToSym : scanning backwards looks for first assig found */
1745 /*-----------------------------------------------------------------*/
1746 static iCode *
1747 findAssignToSym (operand * op, iCode * ic)
1748 {
1749   iCode *dic;
1750
1751   for (dic = ic->prev; dic; dic = dic->prev)
1752     {
1753
1754       /* if definition by assignment */
1755       if (dic->op == '=' &&
1756           !POINTER_SET (dic) &&
1757           IC_RESULT (dic)->key == op->key
1758 /*          &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) */
1759         )
1760         {
1761
1762           /* we are interested only if defined in far space */
1763           /* or in stack space in case of + & - */
1764
1765           /* if assigned to a non-symbol then return
1766              true */
1767           if (!IS_SYMOP (IC_RIGHT (dic)))
1768             break;
1769
1770           /* if the symbol is in far space then
1771              we should not */
1772           if (isOperandInFarSpace (IC_RIGHT (dic)))
1773             return NULL;
1774
1775           /* for + & - operations make sure that
1776              if it is on the stack it is the same
1777              as one of the three operands */
1778           if ((ic->op == '+' || ic->op == '-') &&
1779               OP_SYMBOL (IC_RIGHT (dic))->onStack)
1780             {
1781
1782               if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
1783                   IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
1784                   IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
1785                 return NULL;
1786             }
1787
1788           break;
1789
1790         }
1791
1792       /* if we find an usage then we cannot delete it */
1793       if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
1794         return NULL;
1795
1796       if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
1797         return NULL;
1798
1799       if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
1800         return NULL;
1801     }
1802
1803   /* now make sure that the right side of dic
1804      is not defined between ic & dic */
1805   if (dic)
1806     {
1807       iCode *sic = dic->next;
1808
1809       for (; sic != ic; sic = sic->next)
1810         if (IC_RESULT (sic) &&
1811             IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
1812           return NULL;
1813     }
1814
1815   return dic;
1816
1817
1818 }
1819
1820 /*-----------------------------------------------------------------*/
1821 /* packRegsForSupport :- reduce some registers for support calls   */
1822 /*-----------------------------------------------------------------*/
1823 static int
1824 packRegsForSupport (iCode * ic, eBBlock * ebp)
1825 {
1826   int change = 0;
1827   /* for the left & right operand :- look to see if the
1828      left was assigned a true symbol in far space in that
1829      case replace them */
1830
1831   if (IS_ITEMP (IC_LEFT (ic)) &&
1832       OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
1833     {
1834       iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
1835       iCode *sic;
1836
1837       if (!dic)
1838         goto right;
1839
1840       /* found it we need to remove it from the
1841          block */
1842       for (sic = dic; sic != ic; sic = sic->next)
1843         bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
1844
1845       IC_LEFT (ic)->operand.symOperand =
1846         IC_RIGHT (dic)->operand.symOperand;
1847       IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
1848       remiCodeFromeBBlock (ebp, dic);
1849       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1850       change++;
1851     }
1852
1853   /* do the same for the right operand */
1854  right:
1855   if (!change &&
1856       IS_ITEMP (IC_RIGHT (ic)) &&
1857       OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
1858     {
1859       iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
1860       iCode *sic;
1861
1862       if (!dic)
1863         return change;
1864
1865       /* if this is a subtraction & the result
1866          is a true symbol in far space then don't pack */
1867       if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
1868         {
1869           sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
1870           if (IN_FARSPACE (SPEC_OCLS (etype)))
1871             return change;
1872         }
1873       /* found it we need to remove it from the
1874          block */
1875       for (sic = dic; sic != ic; sic = sic->next)
1876         bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
1877
1878       IC_RIGHT (ic)->operand.symOperand =
1879         IC_RIGHT (dic)->operand.symOperand;
1880       IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
1881
1882       remiCodeFromeBBlock (ebp, dic);
1883       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1884       change++;
1885     }
1886
1887   return change;
1888 }
1889
1890 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
1891
1892
1893 /*-----------------------------------------------------------------*/
1894 /* packRegsForOneuse : - will reduce some registers for single Use */
1895 /*-----------------------------------------------------------------*/
1896 static iCode *
1897 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
1898 {
1899   bitVect *uses;
1900   iCode *dic, *sic;
1901
1902   /* if returning a literal then do nothing */
1903   if (!IS_SYMOP (op))
1904     return NULL;
1905
1906   /* only upto 2 bytes since we cannot predict
1907      the usage of b, & acc */
1908   if (getSize (operandType (op)) > (fReturnSizeMCS51 - 2) &&
1909       ic->op != RETURN &&
1910       ic->op != SEND &&
1911       !POINTER_SET (ic) &&
1912       !POINTER_GET (ic))
1913     return NULL;
1914
1915   /* this routine will mark the a symbol as used in one 
1916      instruction use only && if the defintion is local 
1917      (ie. within the basic block) && has only one definition &&
1918      that definiion is either a return value from a 
1919      function or does not contain any variables in
1920      far space */
1921   uses = bitVectCopy (OP_USES (op));
1922   bitVectUnSetBit (uses, ic->key);      /* take away this iCode */
1923   if (!bitVectIsZero (uses))    /* has other uses */
1924     return NULL;
1925
1926   /* if it has only one defintion */
1927   if (bitVectnBitsOn (OP_DEFS (op)) > 1)
1928     return NULL;                /* has more than one definition */
1929
1930   /* get that definition */
1931   if (!(dic =
1932         hTabItemWithKey (iCodehTab,
1933                          bitVectFirstBit (OP_DEFS (op)))))
1934     return NULL;
1935
1936   /* found the definition now check if it is local */
1937   if (dic->seq < ebp->fSeq ||
1938       dic->seq > ebp->lSeq)
1939     return NULL;                /* non-local */
1940
1941   /* now check if it is the return from
1942      a function call */
1943   if (dic->op == CALL || dic->op == PCALL)
1944     {
1945       if (ic->op != SEND && ic->op != RETURN)
1946         {
1947           OP_SYMBOL (op)->ruonly = 1;
1948           return dic;
1949         }
1950       dic = dic->next;
1951     }
1952
1953
1954   /* otherwise check that the definition does
1955      not contain any symbols in far space */
1956   if (isOperandInFarSpace (IC_LEFT (dic)) ||
1957       isOperandInFarSpace (IC_RIGHT (dic)) ||
1958       IS_OP_RUONLY (IC_LEFT (ic)) ||
1959       IS_OP_RUONLY (IC_RIGHT (ic)))
1960     {
1961       return NULL;
1962     }
1963
1964   /* if pointer set then make sure the pointer
1965      is one byte */
1966   if (POINTER_SET (dic) &&
1967       !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
1968     return NULL;
1969
1970   if (POINTER_GET (dic) &&
1971       !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
1972     return NULL;
1973
1974   sic = dic;
1975
1976   /* also make sure the intervenening instructions
1977      don't have any thing in far space */
1978   for (dic = dic->next; dic && dic != ic && sic != ic; dic = dic->next)
1979     {
1980
1981       /* if there is an intervening function call then no */
1982       if (dic->op == CALL || dic->op == PCALL)
1983         return NULL;
1984       /* if pointer set then make sure the pointer
1985          is one byte */
1986       if (POINTER_SET (dic) &&
1987           !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
1988         return NULL;
1989
1990       if (POINTER_GET (dic) &&
1991           !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
1992         return NULL;
1993
1994       /* if address of & the result is remat the okay */
1995       if (dic->op == ADDRESS_OF &&
1996           OP_SYMBOL (IC_RESULT (dic))->remat)
1997         continue;
1998
1999       /* if operand has size of three or more & this
2000          operation is a '*','/' or '%' then 'b' may
2001          cause a problem */
2002       if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
2003           getSize (operandType (op)) >= 3)
2004         return NULL;
2005
2006       /* if left or right or result is in far space */
2007       if (isOperandInFarSpace (IC_LEFT (dic)) ||
2008           isOperandInFarSpace (IC_RIGHT (dic)) ||
2009           isOperandInFarSpace (IC_RESULT (dic)) ||
2010           IS_OP_RUONLY (IC_LEFT (dic)) ||
2011           IS_OP_RUONLY (IC_RIGHT (dic)) ||
2012           IS_OP_RUONLY (IC_RESULT (dic)))
2013         {
2014           return NULL;
2015         }
2016       /* if left or right or result is on stack */
2017       if (isOperandOnStack(IC_LEFT(dic)) ||
2018           isOperandOnStack(IC_RIGHT(dic)) ||
2019           isOperandOnStack(IC_RESULT(dic))) {
2020         return NULL;
2021       }
2022     }
2023
2024   OP_SYMBOL (op)->ruonly = 1;
2025   return sic;
2026
2027 }
2028
2029 /*-----------------------------------------------------------------*/
2030 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
2031 /*-----------------------------------------------------------------*/
2032 static bool
2033 isBitwiseOptimizable (iCode * ic)
2034 {
2035   sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
2036
2037   /* bitwise operations are considered optimizable
2038      under the following conditions (Jean-Louis VERN) 
2039
2040      bit & bit
2041      bit & x
2042      bit ^ bit
2043      bit ^ x
2044      bit | bit
2045      bit | x
2046    */
2047   if ((IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
2048     return TRUE;
2049   else
2050     return FALSE;
2051 }
2052
2053 /*-----------------------------------------------------------------*/
2054 /* packRegsForAccUse - pack registers for acc use                  */
2055 /*-----------------------------------------------------------------*/
2056 static void
2057 packRegsForAccUse (iCode * ic)
2058 {
2059   iCode *uic;
2060
2061   /* if + or - then it has to be one byte result */
2062   if ((ic->op == '+' || ic->op == '-')
2063       && getSize (operandType (IC_RESULT (ic))) > 1)
2064     return;
2065
2066   /* if shift operation make sure right side is not a literal */
2067   if (ic->op == RIGHT_OP &&
2068       (isOperandLiteral (IC_RIGHT (ic)) ||
2069        getSize (operandType (IC_RESULT (ic))) > 1))
2070     return;
2071
2072   if (ic->op == LEFT_OP &&
2073       (isOperandLiteral (IC_RIGHT (ic)) ||
2074        getSize (operandType (IC_RESULT (ic))) > 1))
2075     return;
2076
2077   if (IS_BITWISE_OP (ic) &&
2078       getSize (operandType (IC_RESULT (ic))) > 1)
2079     return;
2080
2081
2082   /* has only one definition */
2083   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
2084     return;
2085
2086   /* has only one use */
2087   if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
2088     return;
2089
2090   /* and the usage immediately follows this iCode */
2091   if (!(uic = hTabItemWithKey (iCodehTab,
2092                                bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
2093     return;
2094
2095   if (ic->next != uic)
2096     return;
2097
2098   /* if it is a conditional branch then we definitely can */
2099   if (uic->op == IFX)
2100     goto accuse;
2101
2102   if (uic->op == JUMPTABLE)
2103     return;
2104
2105   /* if the usage is not is an assignment
2106      or an arithmetic / bitwise / shift operation then not */
2107   if (POINTER_SET (uic) &&
2108       getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
2109     return;
2110
2111   if (uic->op != '=' &&
2112       !IS_ARITHMETIC_OP (uic) &&
2113       !IS_BITWISE_OP (uic) &&
2114       uic->op != LEFT_OP &&
2115       uic->op != RIGHT_OP)
2116     return;
2117
2118   /* if used in ^ operation then make sure right is not a 
2119      literl */
2120   if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
2121     return;
2122
2123   /* if shift operation make sure right side is not a literal */
2124   if (uic->op == RIGHT_OP &&
2125       (isOperandLiteral (IC_RIGHT (uic)) ||
2126        getSize (operandType (IC_RESULT (uic))) > 1))
2127     return;
2128
2129   if (uic->op == LEFT_OP &&
2130       (isOperandLiteral (IC_RIGHT (uic)) ||
2131        getSize (operandType (IC_RESULT (uic))) > 1))
2132     return;
2133
2134   /* make sure that the result of this icode is not on the
2135      stack, since acc is used to compute stack offset */
2136   if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
2137       OP_SYMBOL (IC_RESULT (uic))->onStack)
2138     return;
2139
2140   /* if either one of them in far space then we cannot */
2141   if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
2142        isOperandInFarSpace (IC_LEFT (uic))) ||
2143       (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
2144        isOperandInFarSpace (IC_RIGHT (uic))))
2145     return;
2146
2147   /* if the usage has only one operand then we can */
2148   if (IC_LEFT (uic) == NULL ||
2149       IC_RIGHT (uic) == NULL)
2150     goto accuse;
2151
2152   /* make sure this is on the left side if not
2153      a '+' since '+' is commutative */
2154   if (ic->op != '+' &&
2155       IC_LEFT (uic)->key != IC_RESULT (ic)->key)
2156     return;
2157
2158   /* if one of them is a literal then we can */
2159   if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
2160       (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
2161     {
2162       OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2163       return;
2164     }
2165
2166   /* if the other one is not on stack then we can */
2167   if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
2168       (IS_ITEMP (IC_RIGHT (uic)) ||
2169        (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
2170         !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
2171     goto accuse;
2172
2173   if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
2174       (IS_ITEMP (IC_LEFT (uic)) ||
2175        (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
2176         !OP_SYMBOL (IC_LEFT (uic))->onStack)))
2177     goto accuse;
2178
2179   return;
2180
2181 accuse:
2182   OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2183
2184
2185 }
2186
2187 /*-----------------------------------------------------------------*/
2188 /* packForPush - hueristics to reduce iCode for pushing            */
2189 /*-----------------------------------------------------------------*/
2190 static void
2191 packForPush (iCode * ic, eBBlock * ebp)
2192 {
2193   iCode *dic, *lic;
2194   bitVect *dbv;
2195
2196   if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
2197     return;
2198
2199   /* must have only definition & one usage */
2200   if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
2201       bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
2202     return;
2203
2204   /* find the definition */
2205   if (!(dic = hTabItemWithKey (iCodehTab,
2206                                bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
2207     return;
2208
2209   if (dic->op != '=' || POINTER_SET (dic))
2210     return;
2211
2212   /* make sure the right side does not have any definitions
2213      inbetween */
2214   dbv = OP_DEFS(IC_RIGHT(dic));
2215   for (lic = ic; lic && lic != dic ; lic = lic->prev) {
2216     if (bitVectBitValue(dbv,lic->key)) 
2217       return ;
2218   }
2219   /* we now we know that it has one & only one def & use
2220      and the that the definition is an assignment */
2221   IC_LEFT (ic) = IC_RIGHT (dic);
2222
2223   remiCodeFromeBBlock (ebp, dic);
2224   hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2225 }
2226
2227 /*-----------------------------------------------------------------*/
2228 /* packRegisters - does some transformations to reduce register    */
2229 /*                   pressure                                      */
2230 /*-----------------------------------------------------------------*/
2231 static void
2232 packRegisters (eBBlock * ebp)
2233 {
2234   iCode *ic;
2235   int change = 0;
2236
2237   while (1)
2238     {
2239
2240       change = 0;
2241
2242       /* look for assignments of the form */
2243       /* iTempNN = TRueSym (someoperation) SomeOperand */
2244       /*       ....                       */
2245       /* TrueSym := iTempNN:1             */
2246       for (ic = ebp->sch; ic; ic = ic->next)
2247         {
2248           /* find assignment of the form TrueSym := iTempNN:1 */
2249           if (ic->op == '=' && !POINTER_SET (ic))
2250             change += packRegsForAssign (ic, ebp);
2251         }
2252
2253       if (!change)
2254         break;
2255     }
2256
2257   for (ic = ebp->sch; ic; ic = ic->next)
2258     {
2259       /* if this is an itemp & result of a address of a true sym 
2260          then mark this as rematerialisable   */
2261       if (ic->op == ADDRESS_OF &&
2262           IS_ITEMP (IC_RESULT (ic)) &&
2263           IS_TRUE_SYMOP (IC_LEFT (ic)) &&
2264           bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2265           !OP_SYMBOL (IC_LEFT (ic))->onStack)
2266         {
2267
2268           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2269           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2270           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2271
2272         }
2273
2274       /* if straight assignment then carry remat flag if
2275          this is the only definition */
2276       if (ic->op == '=' &&
2277           !POINTER_SET (ic) &&
2278           IS_SYMOP (IC_RIGHT (ic)) &&
2279           OP_SYMBOL (IC_RIGHT (ic))->remat &&
2280           bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
2281         {
2282
2283           OP_SYMBOL (IC_RESULT (ic))->remat =
2284             OP_SYMBOL (IC_RIGHT (ic))->remat;
2285           OP_SYMBOL (IC_RESULT (ic))->rematiCode =
2286             OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
2287         }
2288
2289       /* if this is a +/- operation with a rematerizable 
2290          then mark this as rematerializable as well */
2291       if ((ic->op == '+' || ic->op == '-') &&
2292           (IS_SYMOP (IC_LEFT (ic)) &&
2293            IS_ITEMP (IC_RESULT (ic)) &&
2294            OP_SYMBOL (IC_LEFT (ic))->remat &&
2295            bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2296            IS_OP_LITERAL (IC_RIGHT (ic))))
2297         {
2298           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2299           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2300           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2301         }
2302
2303       /* mark the pointer usages */
2304       if (POINTER_SET (ic))
2305         OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
2306
2307       if (POINTER_GET (ic))
2308         OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
2309
2310       if (!SKIP_IC2 (ic))
2311         {
2312           /* if we are using a symbol on the stack
2313              then we should say mcs51_ptrRegReq */
2314           if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
2315             mcs51_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
2316                                  OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
2317           else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
2318             mcs51_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
2319                               OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
2320           else
2321             {
2322               if (IS_SYMOP (IC_LEFT (ic)))
2323                 mcs51_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
2324                                 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
2325               if (IS_SYMOP (IC_RIGHT (ic)))
2326                 mcs51_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
2327                                OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
2328               if (IS_SYMOP (IC_RESULT (ic)))
2329                 mcs51_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
2330                               OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
2331             }
2332         }
2333
2334       /* if the condition of an if instruction
2335          is defined in the previous instruction then
2336          mark the itemp as a conditional */
2337       if ((IS_CONDITIONAL (ic) ||
2338            (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic))) &&
2339           ic->next && ic->next->op == IFX &&
2340           isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
2341           OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2342         {
2343           OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
2344           continue;
2345         }
2346
2347       /* reduce for support function calls */
2348       if (ic->supportRtn || ic->op == '+' || ic->op == '-')
2349         packRegsForSupport (ic, ebp);
2350
2351       /* some cases the redundant moves can
2352          can be eliminated for return statements */
2353       if ((ic->op == RETURN || ic->op == SEND) &&
2354           !isOperandInFarSpace (IC_LEFT (ic)) &&
2355           options.model == MODEL_SMALL) {
2356         if (0 && options.stackAuto) {
2357           /* we should check here if acc will be clobbered for stack
2358              offset calculations */
2359         } else {
2360           packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2361         }
2362       }
2363
2364       /* if pointer set & left has a size more than
2365          one and right is not in far space */
2366       if (POINTER_SET (ic) &&
2367           !isOperandInFarSpace (IC_RIGHT (ic)) &&
2368           !OP_SYMBOL (IC_RESULT (ic))->remat &&
2369           !IS_OP_RUONLY (IC_RIGHT (ic)) &&
2370           getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
2371
2372         packRegsForOneuse (ic, IC_RESULT (ic), ebp);
2373
2374       /* if pointer get */
2375       if (POINTER_GET (ic) &&
2376           !isOperandInFarSpace (IC_RESULT (ic)) &&
2377           !OP_SYMBOL (IC_LEFT (ic))->remat &&
2378           !IS_OP_RUONLY (IC_RESULT (ic)) &&
2379           getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
2380
2381         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2382
2383
2384       /* if this is cast for intergral promotion then
2385          check if only use of  the definition of the 
2386          operand being casted/ if yes then replace
2387          the result of that arithmetic operation with 
2388          this result and get rid of the cast */
2389       if (ic->op == CAST)
2390         {
2391           sym_link *fromType = operandType (IC_RIGHT (ic));
2392           sym_link *toType = operandType (IC_LEFT (ic));
2393
2394           if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
2395               getSize (fromType) != getSize (toType) &&
2396               SPEC_USIGN (fromType) == SPEC_USIGN (toType))
2397             {
2398
2399               iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2400               if (dic)
2401                 {
2402                   if (IS_ARITHMETIC_OP (dic))
2403                     {
2404                       IC_RESULT (dic) = IC_RESULT (ic);
2405                       remiCodeFromeBBlock (ebp, ic);
2406                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2407                       OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2408                       ic = ic->prev;
2409                     }
2410                   else
2411                     OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
2412                 }
2413             }
2414           else
2415             {
2416
2417               /* if the type from and type to are the same
2418                  then if this is the only use then packit */
2419               if (checkType (operandType (IC_RIGHT (ic)),
2420                              operandType (IC_LEFT (ic))) == 1)
2421                 {
2422                   iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2423                   if (dic)
2424                     {
2425                       IC_RESULT (dic) = IC_RESULT (ic);
2426                       remiCodeFromeBBlock (ebp, ic);
2427                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2428                       OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2429                       ic = ic->prev;
2430                     }
2431                 }
2432             }
2433         }
2434
2435       /* pack for PUSH 
2436          iTempNN := (some variable in farspace) V1
2437          push iTempNN ;
2438          -------------
2439          push V1
2440        */
2441       if (ic->op == IPUSH)
2442         {
2443           packForPush (ic, ebp);
2444         }
2445
2446
2447       /* pack registers for accumulator use, when the
2448          result of an arithmetic or bit wise operation
2449          has only one use, that use is immediately following
2450          the defintion and the using iCode has only one
2451          operand or has two operands but one is literal &
2452          the result of that operation is not on stack then
2453          we can leave the result of this operation in acc:b
2454          combination */
2455       if ((IS_ARITHMETIC_OP (ic)
2456            || IS_BITWISE_OP (ic)
2457            || ic->op == LEFT_OP || ic->op == RIGHT_OP
2458            || (ic->op == ADDRESS_OF && isOperandOnStack (IC_LEFT (ic)))
2459           ) &&
2460           IS_ITEMP (IC_RESULT (ic)) &&
2461           getSize (operandType (IC_RESULT (ic))) <= 2)
2462
2463         packRegsForAccUse (ic);
2464     }
2465 }
2466
2467 /*-----------------------------------------------------------------*/
2468 /* assignRegisters - assigns registers to each live range as need  */
2469 /*-----------------------------------------------------------------*/
2470 void
2471 mcs51_assignRegisters (eBBlock ** ebbs, int count)
2472 {
2473   iCode *ic;
2474   int i;
2475
2476   setToNull ((void *) &_G.funcrUsed);
2477   mcs51_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
2478   /* if not register extentions then reduce number
2479      of registers */
2480   if (options.regExtend)
2481     mcs51_nRegs = 13;
2482   else
2483     mcs51_nRegs = 8;
2484
2485   /* change assignments this will remove some
2486      live ranges reducing some register pressure */
2487   for (i = 0; i < count; i++)
2488     packRegisters (ebbs[i]);
2489
2490   if (options.dump_pack)
2491     dumpEbbsToFileExt (".dumppack", ebbs, count);
2492
2493   /* first determine for each live range the number of 
2494      registers & the type of registers required for each */
2495   regTypeNum ();
2496
2497   /* and serially allocate registers */
2498   serialRegAssign (ebbs, count);
2499
2500   /* if stack was extended then tell the user */
2501   if (_G.stackExtend)
2502     {
2503 /*      werror(W_TOOMANY_SPILS,"stack", */
2504 /*             _G.stackExtend,currFunc->name,""); */
2505       _G.stackExtend = 0;
2506     }
2507
2508   if (_G.dataExtend)
2509     {
2510 /*      werror(W_TOOMANY_SPILS,"data space", */
2511 /*             _G.dataExtend,currFunc->name,""); */
2512       _G.dataExtend = 0;
2513     }
2514
2515   /* after that create the register mask
2516      for each of the instruction */
2517   createRegMask (ebbs, count);
2518
2519   /* redo that offsets for stacked automatic variables */
2520   redoStackOffsets ();
2521
2522   if (options.dump_rassgn)
2523     {
2524       dumpEbbsToFileExt (".dumprassgn", ebbs, count);
2525       dumpLiveRanges (".dumplrange", liveRanges);
2526     }
2527
2528   /* do the overlaysegment stuff SDCCmem.c */
2529   doOverlays (ebbs, count);
2530
2531   /* now get back the chain */
2532   ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
2533
2534
2535   gen51Code (ic);
2536
2537   /* free up any _G.stackSpil locations allocated */
2538   applyToSet (_G.stackSpil, deallocStackSpil);
2539   _G.slocNum = 0;
2540   setToNull ((void **) &_G.stackSpil);
2541   setToNull ((void **) &_G.spiltSet);
2542   /* mark all registers as free */
2543   freeAllRegs ();
2544
2545   return;
2546 }