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