fixed the multiple assignement bug with one in far space
[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   if (IS_ITEMP (IC_LEFT (ic)) &&
1823       OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
1824     {
1825       iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
1826       iCode *sic;
1827
1828       if (!dic)
1829         goto right;
1830
1831       /* found it we need to remove it from the
1832          block */
1833       for (sic = dic; sic != ic; sic = sic->next)
1834         bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
1835
1836       IC_LEFT (ic)->operand.symOperand =
1837         IC_RIGHT (dic)->operand.symOperand;
1838       IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
1839       remiCodeFromeBBlock (ebp, dic);
1840       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1841       change++;
1842     }
1843
1844   /* do the same for the right operand */
1845 right:
1846   if (!change &&
1847       IS_ITEMP (IC_RIGHT (ic)) &&
1848       OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
1849     {
1850       iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
1851       iCode *sic;
1852
1853       if (!dic)
1854         return change;
1855
1856       /* if this is a subtraction & the result
1857          is a true symbol in far space then don't pack */
1858       if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
1859         {
1860           sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
1861           if (IN_FARSPACE (SPEC_OCLS (etype)))
1862             return change;
1863         }
1864       /* found it we need to remove it from the
1865          block */
1866       for (sic = dic; sic != ic; sic = sic->next)
1867         bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
1868
1869       IC_RIGHT (ic)->operand.symOperand =
1870         IC_RIGHT (dic)->operand.symOperand;
1871       IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
1872
1873       remiCodeFromeBBlock (ebp, dic);
1874       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1875       change++;
1876     }
1877
1878   return change;
1879 }
1880
1881 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
1882
1883
1884 /*-----------------------------------------------------------------*/
1885 /* packRegsForOneuse : - will reduce some registers for single Use */
1886 /*-----------------------------------------------------------------*/
1887 static iCode *
1888 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
1889 {
1890   bitVect *uses;
1891   iCode *dic, *sic;
1892
1893   /* if returning a literal then do nothing */
1894   if (!IS_SYMOP (op))
1895     return NULL;
1896
1897   /* only upto 2 bytes since we cannot predict
1898      the usage of b, & acc */
1899   if (getSize (operandType (op)) > (fReturnSizeMCS51 - 2) &&
1900       ic->op != RETURN &&
1901       ic->op != SEND &&
1902       !POINTER_SET (ic) &&
1903       !POINTER_GET (ic))
1904     return NULL;
1905
1906   /* this routine will mark the a symbol as used in one 
1907      instruction use only && if the defintion is local 
1908      (ie. within the basic block) && has only one definition &&
1909      that definiion is either a return value from a 
1910      function or does not contain any variables in
1911      far space */
1912   uses = bitVectCopy (OP_USES (op));
1913   bitVectUnSetBit (uses, ic->key);      /* take away this iCode */
1914   if (!bitVectIsZero (uses))    /* has other uses */
1915     return NULL;
1916
1917   /* if it has only one defintion */
1918   if (bitVectnBitsOn (OP_DEFS (op)) > 1)
1919     return NULL;                /* has more than one definition */
1920
1921   /* get that definition */
1922   if (!(dic =
1923         hTabItemWithKey (iCodehTab,
1924                          bitVectFirstBit (OP_DEFS (op)))))
1925     return NULL;
1926
1927   /* found the definition now check if it is local */
1928   if (dic->seq < ebp->fSeq ||
1929       dic->seq > ebp->lSeq)
1930     return NULL;                /* non-local */
1931
1932   /* now check if it is the return from
1933      a function call */
1934   if (dic->op == CALL || dic->op == PCALL)
1935     {
1936       if (ic->op != SEND && ic->op != RETURN)
1937         {
1938           OP_SYMBOL (op)->ruonly = 1;
1939           return dic;
1940         }
1941       dic = dic->next;
1942     }
1943
1944
1945   /* otherwise check that the definition does
1946      not contain any symbols in far space */
1947   if (isOperandInFarSpace (IC_LEFT (dic)) ||
1948       isOperandInFarSpace (IC_RIGHT (dic)) ||
1949       IS_OP_RUONLY (IC_LEFT (ic)) ||
1950       IS_OP_RUONLY (IC_RIGHT (ic)))
1951     {
1952       return NULL;
1953     }
1954
1955   /* if pointer set then make sure the pointer
1956      is one byte */
1957   if (POINTER_SET (dic) &&
1958       !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
1959     return NULL;
1960
1961   if (POINTER_GET (dic) &&
1962       !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
1963     return NULL;
1964
1965   sic = dic;
1966
1967   /* also make sure the intervenening instructions
1968      don't have any thing in far space */
1969   for (dic = dic->next; dic && dic != ic && sic != ic; dic = dic->next)
1970     {
1971
1972       /* if there is an intervening function call then no */
1973       if (dic->op == CALL || dic->op == PCALL)
1974         return NULL;
1975       /* if pointer set then make sure the pointer
1976          is one byte */
1977       if (POINTER_SET (dic) &&
1978           !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
1979         return NULL;
1980
1981       if (POINTER_GET (dic) &&
1982           !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
1983         return NULL;
1984
1985       /* if address of & the result is remat the okay */
1986       if (dic->op == ADDRESS_OF &&
1987           OP_SYMBOL (IC_RESULT (dic))->remat)
1988         continue;
1989
1990       /* if operand has size of three or more & this
1991          operation is a '*','/' or '%' then 'b' may
1992          cause a problem */
1993       if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
1994           getSize (operandType (op)) >= 3)
1995         return NULL;
1996
1997       /* if left or right or result is in far space */
1998       if (isOperandInFarSpace (IC_LEFT (dic)) ||
1999           isOperandInFarSpace (IC_RIGHT (dic)) ||
2000           isOperandInFarSpace (IC_RESULT (dic)) ||
2001           IS_OP_RUONLY (IC_LEFT (dic)) ||
2002           IS_OP_RUONLY (IC_RIGHT (dic)) ||
2003           IS_OP_RUONLY (IC_RESULT (dic)))
2004         {
2005           return NULL;
2006         }
2007       /* if left or right or result is on stack */
2008       if (isOperandOnStack(IC_LEFT(dic)) ||
2009           isOperandOnStack(IC_RIGHT(dic)) ||
2010           isOperandOnStack(IC_RESULT(dic))) {
2011         return NULL;
2012       }
2013     }
2014
2015   OP_SYMBOL (op)->ruonly = 1;
2016   return sic;
2017
2018 }
2019
2020 /*-----------------------------------------------------------------*/
2021 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
2022 /*-----------------------------------------------------------------*/
2023 static bool
2024 isBitwiseOptimizable (iCode * ic)
2025 {
2026   sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
2027   // jwk sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
2028
2029   /* bitwise operations are considered optimizable
2030      under the following conditions (Jean-Louis VERN) 
2031
2032      x & lit   <== jwk: should be x && lit
2033      bit & bit
2034      bit & x
2035      bit ^ bit
2036      bit ^ x
2037      x   ^ lit <== jwk: should be x ^^ lit
2038      x   | lit <== jwk: should be x || lit
2039      bit | bit
2040      bit | x
2041    */
2042   if ( /* jwk IS_LITERAL (rtype) || */
2043       (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
2044     return TRUE;
2045   else
2046     return FALSE;
2047 }
2048
2049 /*-----------------------------------------------------------------*/
2050 /* packRegsForAccUse - pack registers for acc use                  */
2051 /*-----------------------------------------------------------------*/
2052 static void
2053 packRegsForAccUse (iCode * ic)
2054 {
2055   iCode *uic;
2056
2057   /* if + or - then it has to be one byte result */
2058   if ((ic->op == '+' || ic->op == '-')
2059       && getSize (operandType (IC_RESULT (ic))) > 1)
2060     return;
2061
2062   /* if shift operation make sure right side is not a literal */
2063   if (ic->op == RIGHT_OP &&
2064       (isOperandLiteral (IC_RIGHT (ic)) ||
2065        getSize (operandType (IC_RESULT (ic))) > 1))
2066     return;
2067
2068   if (ic->op == LEFT_OP &&
2069       (isOperandLiteral (IC_RIGHT (ic)) ||
2070        getSize (operandType (IC_RESULT (ic))) > 1))
2071     return;
2072
2073   if (IS_BITWISE_OP (ic) &&
2074       getSize (operandType (IC_RESULT (ic))) > 1)
2075     return;
2076
2077
2078   /* has only one definition */
2079   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
2080     return;
2081
2082   /* has only one use */
2083   if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
2084     return;
2085
2086   /* and the usage immediately follows this iCode */
2087   if (!(uic = hTabItemWithKey (iCodehTab,
2088                                bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
2089     return;
2090
2091   if (ic->next != uic)
2092     return;
2093
2094   /* if it is a conditional branch then we definitely can */
2095   if (uic->op == IFX)
2096     goto accuse;
2097
2098   if (uic->op == JUMPTABLE)
2099     return;
2100
2101   /* if the usage is not is an assignment
2102      or an arithmetic / bitwise / shift operation then not */
2103   if (POINTER_SET (uic) &&
2104       getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
2105     return;
2106
2107   if (uic->op != '=' &&
2108       !IS_ARITHMETIC_OP (uic) &&
2109       !IS_BITWISE_OP (uic) &&
2110       uic->op != LEFT_OP &&
2111       uic->op != RIGHT_OP)
2112     return;
2113
2114   /* if used in ^ operation then make sure right is not a 
2115      literl */
2116   if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
2117     return;
2118
2119   /* if shift operation make sure right side is not a literal */
2120   if (uic->op == RIGHT_OP &&
2121       (isOperandLiteral (IC_RIGHT (uic)) ||
2122        getSize (operandType (IC_RESULT (uic))) > 1))
2123     return;
2124
2125   if (uic->op == LEFT_OP &&
2126       (isOperandLiteral (IC_RIGHT (uic)) ||
2127        getSize (operandType (IC_RESULT (uic))) > 1))
2128     return;
2129
2130   /* make sure that the result of this icode is not on the
2131      stack, since acc is used to compute stack offset */
2132   if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
2133       OP_SYMBOL (IC_RESULT (uic))->onStack)
2134     return;
2135
2136   /* if either one of them in far space then we cannot */
2137   if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
2138        isOperandInFarSpace (IC_LEFT (uic))) ||
2139       (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
2140        isOperandInFarSpace (IC_RIGHT (uic))))
2141     return;
2142
2143   /* if the usage has only one operand then we can */
2144   if (IC_LEFT (uic) == NULL ||
2145       IC_RIGHT (uic) == NULL)
2146     goto accuse;
2147
2148   /* make sure this is on the left side if not
2149      a '+' since '+' is commutative */
2150   if (ic->op != '+' &&
2151       IC_LEFT (uic)->key != IC_RESULT (ic)->key)
2152     return;
2153
2154   /* if one of them is a literal then we can */
2155   if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
2156       (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
2157     {
2158       OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2159       return;
2160     }
2161
2162   /* if the other one is not on stack then we can */
2163   if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
2164       (IS_ITEMP (IC_RIGHT (uic)) ||
2165        (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
2166         !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
2167     goto accuse;
2168
2169   if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
2170       (IS_ITEMP (IC_LEFT (uic)) ||
2171        (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
2172         !OP_SYMBOL (IC_LEFT (uic))->onStack)))
2173     goto accuse;
2174
2175   return;
2176
2177 accuse:
2178   OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2179
2180
2181 }
2182
2183 /*-----------------------------------------------------------------*/
2184 /* packForPush - hueristics to reduce iCode for pushing            */
2185 /*-----------------------------------------------------------------*/
2186 static void
2187 packForPush (iCode * ic, eBBlock * ebp)
2188 {
2189   iCode *dic, *lic;
2190   bitVect *dbv;
2191
2192   if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
2193     return;
2194
2195   /* must have only definition & one usage */
2196   if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
2197       bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
2198     return;
2199
2200   /* find the definition */
2201   if (!(dic = hTabItemWithKey (iCodehTab,
2202                                bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
2203     return;
2204
2205   if (dic->op != '=' || POINTER_SET (dic))
2206     return;
2207
2208   /* make sure the right side does not have any definitions
2209      inbetween */
2210   dbv = OP_DEFS(IC_RIGHT(dic));
2211   for (lic = ic; lic && lic != dic ; lic = lic->prev) {
2212     if (bitVectBitValue(dbv,lic->key)) 
2213       return ;
2214   }
2215   /* we now we know that it has one & only one def & use
2216      and the that the definition is an assignment */
2217   IC_LEFT (ic) = IC_RIGHT (dic);
2218
2219   remiCodeFromeBBlock (ebp, dic);
2220   hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2221 }
2222
2223 /*-----------------------------------------------------------------*/
2224 /* packRegisters - does some transformations to reduce register    */
2225 /*                   pressure                                      */
2226 /*-----------------------------------------------------------------*/
2227 static void
2228 packRegisters (eBBlock * ebp)
2229 {
2230   iCode *ic;
2231   int change = 0;
2232
2233   while (1)
2234     {
2235
2236       change = 0;
2237
2238       /* look for assignments of the form */
2239       /* iTempNN = TRueSym (someoperation) SomeOperand */
2240       /*       ....                       */
2241       /* TrueSym := iTempNN:1             */
2242       for (ic = ebp->sch; ic; ic = ic->next)
2243         {
2244           /* find assignment of the form TrueSym := iTempNN:1 */
2245           if (ic->op == '=' && !POINTER_SET (ic))
2246             change += packRegsForAssign (ic, ebp);
2247         }
2248
2249       if (!change)
2250         break;
2251     }
2252
2253   for (ic = ebp->sch; ic; ic = ic->next)
2254     {
2255
2256       /* if this is an itemp & result of a address of a true sym 
2257          then mark this as rematerialisable   */
2258       if (ic->op == ADDRESS_OF &&
2259           IS_ITEMP (IC_RESULT (ic)) &&
2260           IS_TRUE_SYMOP (IC_LEFT (ic)) &&
2261           bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2262           !OP_SYMBOL (IC_LEFT (ic))->onStack)
2263         {
2264
2265           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2266           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2267           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2268
2269         }
2270
2271       /* if straight assignment then carry remat flag if
2272          this is the only definition */
2273       if (ic->op == '=' &&
2274           !POINTER_SET (ic) &&
2275           IS_SYMOP (IC_RIGHT (ic)) &&
2276           OP_SYMBOL (IC_RIGHT (ic))->remat &&
2277           bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
2278         {
2279
2280           OP_SYMBOL (IC_RESULT (ic))->remat =
2281             OP_SYMBOL (IC_RIGHT (ic))->remat;
2282           OP_SYMBOL (IC_RESULT (ic))->rematiCode =
2283             OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
2284         }
2285
2286       /* if this is a +/- operation with a rematerizable 
2287          then mark this as rematerializable as well */
2288       if ((ic->op == '+' || ic->op == '-') &&
2289           (IS_SYMOP (IC_LEFT (ic)) &&
2290            IS_ITEMP (IC_RESULT (ic)) &&
2291            OP_SYMBOL (IC_LEFT (ic))->remat &&
2292            bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2293            IS_OP_LITERAL (IC_RIGHT (ic))))
2294         {
2295
2296           //int i = operandLitValue (IC_RIGHT (ic));
2297           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2298           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2299           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2300         }
2301
2302       /* mark the pointer usages */
2303       if (POINTER_SET (ic))
2304         OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
2305
2306       if (POINTER_GET (ic))
2307         OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
2308
2309       if (!SKIP_IC2 (ic))
2310         {
2311           /* if we are using a symbol on the stack
2312              then we should say mcs51_ptrRegReq */
2313           if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
2314             mcs51_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
2315                                  OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
2316           else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
2317             mcs51_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
2318                               OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
2319           else
2320             {
2321               if (IS_SYMOP (IC_LEFT (ic)))
2322                 mcs51_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
2323                                 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
2324               if (IS_SYMOP (IC_RIGHT (ic)))
2325                 mcs51_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
2326                                OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
2327               if (IS_SYMOP (IC_RESULT (ic)))
2328                 mcs51_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
2329                               OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
2330             }
2331         }
2332
2333       /* if the condition of an if instruction
2334          is defined in the previous instruction then
2335          mark the itemp as a conditional */
2336       if ((IS_CONDITIONAL (ic) ||
2337            (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic))) &&
2338           ic->next && ic->next->op == IFX &&
2339           isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
2340           OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2341         {
2342           OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
2343           continue;
2344         }
2345
2346       /* reduce for support function calls */
2347       if (ic->supportRtn || ic->op == '+' || ic->op == '-')
2348         packRegsForSupport (ic, ebp);
2349
2350       /* some cases the redundant moves can
2351          can be eliminated for return statements */
2352       if ((ic->op == RETURN || ic->op == SEND) &&
2353           !isOperandInFarSpace (IC_LEFT (ic)) &&
2354           options.model == MODEL_SMALL) {
2355         if (0 && options.stackAuto) {
2356           /* we should check here if acc will be clobbered for stack
2357              offset calculations */
2358         } else {
2359           packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2360         }
2361       }
2362
2363       /* if pointer set & left has a size more than
2364          one and right is not in far space */
2365       if (POINTER_SET (ic) &&
2366           !isOperandInFarSpace (IC_RIGHT (ic)) &&
2367           !OP_SYMBOL (IC_RESULT (ic))->remat &&
2368           !IS_OP_RUONLY (IC_RIGHT (ic)) &&
2369           getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
2370
2371         packRegsForOneuse (ic, IC_RESULT (ic), ebp);
2372
2373       /* if pointer get */
2374       if (POINTER_GET (ic) &&
2375           !isOperandInFarSpace (IC_RESULT (ic)) &&
2376           !OP_SYMBOL (IC_LEFT (ic))->remat &&
2377           !IS_OP_RUONLY (IC_RESULT (ic)) &&
2378           getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
2379
2380         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2381
2382
2383       /* if this is cast for intergral promotion then
2384          check if only use of  the definition of the 
2385          operand being casted/ if yes then replace
2386          the result of that arithmetic operation with 
2387          this result and get rid of the cast */
2388       if (ic->op == CAST)
2389         {
2390           sym_link *fromType = operandType (IC_RIGHT (ic));
2391           sym_link *toType = operandType (IC_LEFT (ic));
2392
2393           if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
2394               getSize (fromType) != getSize (toType) &&
2395               SPEC_USIGN (fromType) == SPEC_USIGN (toType))
2396             {
2397
2398               iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2399               if (dic)
2400                 {
2401                   if (IS_ARITHMETIC_OP (dic))
2402                     {
2403                       IC_RESULT (dic) = IC_RESULT (ic);
2404                       remiCodeFromeBBlock (ebp, ic);
2405                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2406                       OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2407                       ic = ic->prev;
2408                     }
2409                   else
2410                     OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
2411                 }
2412             }
2413           else
2414             {
2415
2416               /* if the type from and type to are the same
2417                  then if this is the only use then packit */
2418               if (checkType (operandType (IC_RIGHT (ic)),
2419                              operandType (IC_LEFT (ic))) == 1)
2420                 {
2421                   iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2422                   if (dic)
2423                     {
2424                       IC_RESULT (dic) = IC_RESULT (ic);
2425                       remiCodeFromeBBlock (ebp, ic);
2426                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2427                       OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2428                       ic = ic->prev;
2429                     }
2430                 }
2431             }
2432         }
2433
2434       /* pack for PUSH 
2435          iTempNN := (some variable in farspace) V1
2436          push iTempNN ;
2437          -------------
2438          push V1
2439        */
2440       if (ic->op == IPUSH)
2441         {
2442           packForPush (ic, ebp);
2443         }
2444
2445
2446       /* pack registers for accumulator use, when the
2447          result of an arithmetic or bit wise operation
2448          has only one use, that use is immediately following
2449          the defintion and the using iCode has only one
2450          operand or has two operands but one is literal &
2451          the result of that operation is not on stack then
2452          we can leave the result of this operation in acc:b
2453          combination */
2454       if ((IS_ARITHMETIC_OP (ic)
2455            || IS_BITWISE_OP (ic)
2456            || ic->op == LEFT_OP || ic->op == RIGHT_OP
2457            || (ic->op == ADDRESS_OF && isOperandOnStack (IC_LEFT (ic)))
2458           ) &&
2459           IS_ITEMP (IC_RESULT (ic)) &&
2460           getSize (operandType (IC_RESULT (ic))) <= 2)
2461
2462         packRegsForAccUse (ic);
2463
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 }