fixed bug #845089
[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 #define D(x)
41
42 /* Global data */
43 static struct
44   {
45     bitVect *spiltSet;
46     set *stackSpil;
47     bitVect *regAssigned;
48     bitVect *totRegAssigned;    /* final set of LRs that got into registers */
49     short blockSpil;
50     int slocNum;
51     bitVect *funcrUsed;         /* registers used in a function */
52     int stackExtend;
53     int dataExtend;
54   }
55 _G;
56
57 /* Shared with gen.c */
58 int mcs51_ptrRegReq;            /* one byte pointer register required */
59
60 /* 8051 registers */
61 regs regs8051[] =
62 {
63
64   {REG_GPR, R2_IDX, REG_GPR, "r2", "ar2", "0", 2, 1},
65   {REG_GPR, R3_IDX, REG_GPR, "r3", "ar3", "0", 3, 1},
66   {REG_GPR, R4_IDX, REG_GPR, "r4", "ar4", "0", 4, 1},
67   {REG_GPR, R5_IDX, REG_GPR, "r5", "ar5", "0", 5, 1},
68   {REG_GPR, R6_IDX, REG_GPR, "r6", "ar6", "0", 6, 1},
69   {REG_GPR, R7_IDX, REG_GPR, "r7", "ar7", "0", 7, 1},
70   {REG_PTR, R0_IDX, REG_PTR, "r0", "ar0", "0", 0, 1},
71   {REG_PTR, R1_IDX, REG_PTR, "r1", "ar1", "0", 1, 1},
72   {REG_GPR, X8_IDX, REG_GPR, "x8", "x8", "xreg", 0, 1},
73   {REG_GPR, X9_IDX, REG_GPR, "x9", "x9", "xreg", 1, 1},
74   {REG_GPR, X10_IDX, REG_GPR, "x10", "x10", "xreg", 2, 1},
75   {REG_GPR, X11_IDX, REG_GPR, "x11", "x11", "xreg", 3, 1},
76   {REG_GPR, X12_IDX, REG_GPR, "x12", "x12", "xreg", 4, 1},
77   {REG_CND, CND_IDX, REG_CND, "C", "C", "xreg", 0, 1},
78 };
79 int mcs51_nRegs = 13;
80 static void spillThis (symbol *);
81 static void freeAllRegs ();
82
83 /*-----------------------------------------------------------------*/
84 /* allocReg - allocates register of given type                     */
85 /*-----------------------------------------------------------------*/
86 static regs *
87 allocReg (short type)
88 {
89   int i;
90
91   for (i = 0; i < mcs51_nRegs; i++)
92     {
93
94       /* if type is given as 0 then any
95          free register will do */
96       if (!type &&
97           regs8051[i].isFree)
98         {
99           regs8051[i].isFree = 0;
100           if (currFunc)
101             currFunc->regsUsed =
102               bitVectSetBit (currFunc->regsUsed, i);
103           return &regs8051[i];
104         }
105       /* other wise look for specific type
106          of register */
107       if (regs8051[i].isFree &&
108           regs8051[i].type == type)
109         {
110           regs8051[i].isFree = 0;
111           if (currFunc)
112             currFunc->regsUsed =
113               bitVectSetBit (currFunc->regsUsed, i);
114           return &regs8051[i];
115         }
116     }
117   return NULL;
118 }
119
120 /*-----------------------------------------------------------------*/
121 /* mcs51_regWithIdx - returns pointer to register wit index number       */
122 /*-----------------------------------------------------------------*/
123 regs *
124 mcs51_regWithIdx (int idx)
125 {
126   int i;
127
128   for (i = 0; i < mcs51_nRegs; i++)
129     if (regs8051[i].rIdx == idx)
130       return &regs8051[i];
131
132   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
133           "regWithIdx not found");
134   exit (1);
135 }
136
137 /*-----------------------------------------------------------------*/
138 /* freeReg - frees a register                                      */
139 /*-----------------------------------------------------------------*/
140 static void
141 freeReg (regs * reg)
142 {
143   if (!reg)
144     {
145       werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
146               "freeReg - Freeing NULL register");
147       exit (1);
148     }
149
150   reg->isFree = 1;
151 }
152
153
154 /*-----------------------------------------------------------------*/
155 /* nFreeRegs - returns number of free registers                    */
156 /*-----------------------------------------------------------------*/
157 static int
158 nFreeRegs (int type)
159 {
160   int i;
161   int nfr = 0;
162
163   for (i = 0; i < mcs51_nRegs; i++)
164     if (regs8051[i].isFree && regs8051[i].type == type)
165       nfr++;
166   return nfr;
167 }
168
169 /*-----------------------------------------------------------------*/
170 /* nfreeRegsType - free registers with type                         */
171 /*-----------------------------------------------------------------*/
172 static int
173 nfreeRegsType (int type)
174 {
175   int nfr;
176   if (type == REG_PTR)
177     {
178       if ((nfr = nFreeRegs (type)) == 0)
179         return nFreeRegs (REG_GPR);
180     }
181
182   return nFreeRegs (type);
183 }
184
185 /*-----------------------------------------------------------------*/
186 /* useReg - marks a register  as used                              */
187 /*-----------------------------------------------------------------*/
188 static void
189 useReg (regs * reg)
190 {
191   reg->isFree = 0;
192 }
193
194 /*-----------------------------------------------------------------*/
195 /* computeSpillable - given a point find the spillable live ranges */
196 /*-----------------------------------------------------------------*/
197 static bitVect *
198 computeSpillable (iCode * ic)
199 {
200   bitVect *spillable;
201
202   /* spillable live ranges are those that are live at this 
203      point . the following categories need to be subtracted
204      from this set. 
205      a) - those that are already spilt
206      b) - if being used by this one
207      c) - defined by this one */
208
209   spillable = bitVectCopy (ic->rlive);
210   spillable =
211     bitVectCplAnd (spillable, _G.spiltSet);     /* those already spilt */
212   spillable =
213     bitVectCplAnd (spillable, ic->uses);        /* used in this one */
214   bitVectUnSetBit (spillable, ic->defKey);
215   spillable = bitVectIntersect (spillable, _G.regAssigned);
216   return spillable;
217
218 }
219
220 /*-----------------------------------------------------------------*/
221 /* noSpilLoc - return true if a variable has no spil location      */
222 /*-----------------------------------------------------------------*/
223 static int
224 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
225 {
226   return (sym->usl.spillLoc ? 0 : 1);
227 }
228
229 /*-----------------------------------------------------------------*/
230 /* hasSpilLoc - will return 1 if the symbol has spil location      */
231 /*-----------------------------------------------------------------*/
232 static int
233 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
234 {
235   return (sym->usl.spillLoc ? 1 : 0);
236 }
237
238 /*-----------------------------------------------------------------*/
239 /* directSpilLoc - will return 1 if the splilocation is in direct  */
240 /*-----------------------------------------------------------------*/
241 static int
242 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
243 {
244   if (sym->usl.spillLoc &&
245       (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
246     return 1;
247   else
248     return 0;
249 }
250
251 /*-----------------------------------------------------------------*/
252 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
253 /*                    but is not used as a pointer                 */
254 /*-----------------------------------------------------------------*/
255 static int
256 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
257 {
258   return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
259 }
260
261 /*-----------------------------------------------------------------*/
262 /* rematable - will return 1 if the remat flag is set              */
263 /*-----------------------------------------------------------------*/
264 static int
265 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
266 {
267   return sym->remat;
268 }
269
270 /*-----------------------------------------------------------------*/
271 /* notUsedInRemaining - not used or defined in remain of the block */
272 /*-----------------------------------------------------------------*/
273 static int
274 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
275 {
276   return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
277           allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
278 }
279
280 /*-----------------------------------------------------------------*/
281 /* allLRs - return true for all                                    */
282 /*-----------------------------------------------------------------*/
283 static int
284 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
285 {
286   return 1;
287 }
288
289 /*-----------------------------------------------------------------*/
290 /* liveRangesWith - applies function to a given set of live range  */
291 /*-----------------------------------------------------------------*/
292 static set *
293 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
294                 eBBlock * ebp, iCode * ic)
295 {
296   set *rset = NULL;
297   int i;
298
299   if (!lrs || !lrs->size)
300     return NULL;
301
302   for (i = 1; i < lrs->size; i++)
303     {
304       symbol *sym;
305       if (!bitVectBitValue (lrs, i))
306         continue;
307
308       /* if we don't find it in the live range 
309          hash table we are in serious trouble */
310       if (!(sym = hTabItemWithKey (liveRanges, i)))
311         {
312           werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
313                   "liveRangesWith could not find liveRange");
314           exit (1);
315         }
316
317       if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
318         addSetHead (&rset, sym);
319     }
320
321   return rset;
322 }
323
324
325 /*-----------------------------------------------------------------*/
326 /* leastUsedLR - given a set determines which is the least used    */
327 /*-----------------------------------------------------------------*/
328 static symbol *
329 leastUsedLR (set * sset)
330 {
331   symbol *sym = NULL, *lsym = NULL;
332
333   sym = lsym = setFirstItem (sset);
334
335   if (!lsym)
336     return NULL;
337
338   for (; lsym; lsym = setNextItem (sset))
339     {
340
341       /* if usage is the same then prefer
342          the spill the smaller of the two */
343       if (lsym->used == sym->used)
344         if (getSize (lsym->type) < getSize (sym->type))
345           sym = lsym;
346
347       /* if less usage */
348       if (lsym->used < sym->used)
349         sym = lsym;
350
351     }
352
353   setToNull ((void *) &sset);
354   sym->blockSpil = 0;
355   return sym;
356 }
357
358 /*-----------------------------------------------------------------*/
359 /* noOverLap - will iterate through the list looking for over lap  */
360 /*-----------------------------------------------------------------*/
361 static int
362 noOverLap (set * itmpStack, symbol * fsym)
363 {
364   symbol *sym;
365
366
367   for (sym = setFirstItem (itmpStack); sym;
368        sym = setNextItem (itmpStack))
369     {
370         if (bitVectBitValue(sym->clashes,fsym->key)) return 0;
371     }
372
373   return 1;
374 }
375
376 /*-----------------------------------------------------------------*/
377 /* isFree - will return 1 if the a free spil location is found     */
378 /*-----------------------------------------------------------------*/
379 static
380 DEFSETFUNC (isFree)
381 {
382   symbol *sym = item;
383   V_ARG (symbol **, sloc);
384   V_ARG (symbol *, fsym);
385
386   /* if already found */
387   if (*sloc)
388     return 0;
389
390   /* if it is free && and the itmp assigned to
391      this does not have any overlapping live ranges
392      with the one currently being assigned and
393      the size can be accomodated  */
394   if (sym->isFree &&
395       noOverLap (sym->usl.itmpStack, fsym) &&
396       getSize (sym->type) >= getSize (fsym->type))
397     {
398       *sloc = sym;
399       return 1;
400     }
401
402   return 0;
403 }
404
405 /*-----------------------------------------------------------------*/
406 /* spillLRWithPtrReg :- will spil those live ranges which use PTR  */
407 /*-----------------------------------------------------------------*/
408 static void
409 spillLRWithPtrReg (symbol * forSym)
410 {
411   symbol *lrsym;
412   regs *r0, *r1;
413   int k;
414
415   if (!_G.regAssigned ||
416       bitVectIsZero (_G.regAssigned))
417     return;
418
419   r0 = mcs51_regWithIdx (R0_IDX);
420   r1 = mcs51_regWithIdx (R1_IDX);
421
422   /* for all live ranges */
423   for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
424        lrsym = hTabNextItem (liveRanges, &k))
425     {
426       int j;
427
428       /* if no registers assigned to it or spilt */
429       /* if it does not overlap with this then 
430          not need to spill it */
431
432       if (lrsym->isspilt || !lrsym->nRegs ||
433           (lrsym->liveTo < forSym->liveFrom))
434         continue;
435
436       /* go thru the registers : if it is either
437          r0 or r1 then spil it */
438       for (j = 0; j < lrsym->nRegs; j++)
439         if (lrsym->regs[j] == r0 ||
440             lrsym->regs[j] == r1)
441           {
442             spillThis (lrsym);
443             break;
444           }
445     }
446
447 }
448
449 /*-----------------------------------------------------------------*/
450 /* createStackSpil - create a location on the stack to spil        */
451 /*-----------------------------------------------------------------*/
452 static symbol *
453 createStackSpil (symbol * sym)
454 {
455   symbol *sloc = NULL;
456   int useXstack, model;
457
458   char slocBuffer[30];
459
460   /* first go try and find a free one that is already 
461      existing on the stack */
462   if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
463     {
464       /* found a free one : just update & return */
465       sym->usl.spillLoc = sloc;
466       sym->stackSpil = 1;
467       sloc->isFree = 0;
468       addSetHead (&sloc->usl.itmpStack, sym);
469       return sym;
470     }
471
472   /* could not then have to create one , this is the hard part
473      we need to allocate this on the stack : this is really a
474      hack!! but cannot think of anything better at this time */
475
476   if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
477     {
478       fprintf (stderr, "***Internal error: slocBuffer overflowed: %s:%d\n",
479                __FILE__, __LINE__);
480       exit (1);
481     }
482
483   sloc = newiTemp (slocBuffer);
484
485   /* set the type to the spilling symbol */
486   sloc->type = copyLinkChain (sym->type);
487   sloc->etype = getSpec (sloc->type);
488   SPEC_SCLS (sloc->etype) = S_DATA;
489   SPEC_EXTR (sloc->etype) = 0;
490   SPEC_STAT (sloc->etype) = 0;
491   SPEC_VOLATILE(sloc->etype) = 0;
492   SPEC_ABSA(sloc->etype) = 0;
493
494   /* we don't allow it to be allocated`
495      onto the external stack since : so we
496      temporarily turn it off ; we also
497      turn off memory model to prevent
498      the spil from going to the external storage
499    */
500
501   useXstack = options.useXstack;
502   model = options.model;
503 /*     noOverlay = options.noOverlay; */
504 /*     options.noOverlay = 1; */
505   options.model = options.useXstack = 0;
506
507   allocLocal (sloc);
508
509   options.useXstack = useXstack;
510   options.model = model;
511 /*     options.noOverlay = noOverlay; */
512   sloc->isref = 1;              /* to prevent compiler warning */
513
514   /* if it is on the stack then update the stack */
515   if (IN_STACK (sloc->etype))
516     {
517       currFunc->stack += getSize (sloc->type);
518       _G.stackExtend += getSize (sloc->type);
519     }
520   else
521     _G.dataExtend += getSize (sloc->type);
522
523   /* add it to the _G.stackSpil set */
524   addSetHead (&_G.stackSpil, sloc);
525   sym->usl.spillLoc = sloc;
526   sym->stackSpil = 1;
527
528   /* add it to the set of itempStack set 
529      of the spill location */
530   addSetHead (&sloc->usl.itmpStack, sym);
531   return sym;
532 }
533
534 /*-----------------------------------------------------------------*/
535 /* isSpiltOnStack - returns true if the spil location is on stack  */
536 /*-----------------------------------------------------------------*/
537 static bool
538 isSpiltOnStack (symbol * sym)
539 {
540   sym_link *etype;
541
542   if (!sym)
543     return FALSE;
544
545   if (!sym->isspilt)
546     return FALSE;
547
548 /*     if (sym->_G.stackSpil) */
549 /*      return TRUE; */
550
551   if (!sym->usl.spillLoc)
552     return FALSE;
553
554   etype = getSpec (sym->usl.spillLoc->type);
555   if (IN_STACK (etype))
556     return TRUE;
557
558   return FALSE;
559 }
560
561 /*-----------------------------------------------------------------*/
562 /* spillThis - spils a specific operand                            */
563 /*-----------------------------------------------------------------*/
564 static void
565 spillThis (symbol * sym)
566 {
567   int i;
568   /* if this is rematerializable or has a spillLocation
569      we are okay, else we need to create a spillLocation
570      for it */
571   if (!(sym->remat || sym->usl.spillLoc))
572     createStackSpil (sym);
573
574   /* mark it has spilt & put it in the spilt set */
575   sym->isspilt = sym->spillA = 1;
576   _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
577
578   bitVectUnSetBit (_G.regAssigned, sym->key);
579   bitVectUnSetBit (_G.totRegAssigned, sym->key);
580
581   for (i = 0; i < sym->nRegs; i++)
582
583     if (sym->regs[i])
584       {
585         freeReg (sym->regs[i]);
586         sym->regs[i] = NULL;
587       }
588
589   /* if spilt on stack then free up r0 & r1 
590      if they could have been assigned to some
591      LIVE ranges */
592   if (!mcs51_ptrRegReq && isSpiltOnStack (sym))
593     {
594       mcs51_ptrRegReq++;
595       spillLRWithPtrReg (sym);
596     }
597
598   if (sym->usl.spillLoc && !sym->remat)
599     sym->usl.spillLoc->allocreq++;
600   return;
601 }
602
603 /*-----------------------------------------------------------------*/
604 /* selectSpil - select a iTemp to spil : rather a simple procedure */
605 /*-----------------------------------------------------------------*/
606 static symbol *
607 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
608 {
609   bitVect *lrcs = NULL;
610   set *selectS;
611   symbol *sym;
612
613   /* get the spillable live ranges */
614   lrcs = computeSpillable (ic);
615
616   /* get all live ranges that are rematerizable */
617   if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
618     {
619
620       /* return the least used of these */
621       return leastUsedLR (selectS);
622     }
623
624   /* get live ranges with spillLocations in direct space */
625   if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
626     {
627       sym = leastUsedLR (selectS);
628       strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
629                            sym->usl.spillLoc->rname :
630                            sym->usl.spillLoc->name));
631       sym->spildir = 1;
632       /* mark it as allocation required */
633       sym->usl.spillLoc->allocreq++;
634       return sym;
635     }
636
637   /* if the symbol is local to the block then */
638   if (forSym->liveTo < ebp->lSeq)
639     {
640
641       /* check if there are any live ranges allocated
642          to registers that are not used in this block */
643       if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
644         {
645           sym = leastUsedLR (selectS);
646           /* if this is not rematerializable */
647           if (!sym->remat)
648             {
649               _G.blockSpil++;
650               sym->blockSpil = 1;
651             }
652           return sym;
653         }
654
655       /* check if there are any live ranges that not
656          used in the remainder of the block */
657       if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
658         {
659           sym = leastUsedLR (selectS);
660           if (sym != forSym)
661             {
662               if (!sym->remat)
663                 {
664                   sym->remainSpil = 1;
665                   _G.blockSpil++;
666                 }
667               return sym;
668             }
669         }
670     }
671
672   /* find live ranges with spillocation && not used as pointers */
673   if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
674     {
675
676       sym = leastUsedLR (selectS);
677       /* mark this as allocation required */
678       sym->usl.spillLoc->allocreq++;
679       return sym;
680     }
681
682   /* find live ranges with spillocation */
683   if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
684     {
685
686       sym = leastUsedLR (selectS);
687       sym->usl.spillLoc->allocreq++;
688       return sym;
689     }
690
691   /* couldn't find then we need to create a spil
692      location on the stack , for which one? the least
693      used ofcourse */
694   if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
695     {
696
697       /* return a created spil location */
698       sym = createStackSpil (leastUsedLR (selectS));
699       sym->usl.spillLoc->allocreq++;
700       return sym;
701     }
702
703   /* this is an extreme situation we will spill
704      this one : happens very rarely but it does happen */
705   spillThis (forSym);
706   return forSym;
707
708 }
709
710 /*-----------------------------------------------------------------*/
711 /* spilSomething - spil some variable & mark registers as free     */
712 /*-----------------------------------------------------------------*/
713 static bool
714 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
715 {
716   symbol *ssym;
717   int i;
718
719   /* get something we can spil */
720   ssym = selectSpil (ic, ebp, forSym);
721
722   /* mark it as spilt */
723   ssym->isspilt = ssym->spillA = 1;
724   _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
725
726   /* mark it as not register assigned &
727      take it away from the set */
728   bitVectUnSetBit (_G.regAssigned, ssym->key);
729   bitVectUnSetBit (_G.totRegAssigned, ssym->key);
730
731   /* mark the registers as free */
732   for (i = 0; i < ssym->nRegs; i++)
733     if (ssym->regs[i])
734       freeReg (ssym->regs[i]);
735
736   /* if spilt on stack then free up r0 & r1 
737      if they could have been assigned to as gprs */
738   if (!mcs51_ptrRegReq && isSpiltOnStack (ssym))
739     {
740       mcs51_ptrRegReq++;
741       spillLRWithPtrReg (ssym);
742     }
743
744   /* if this was a block level spil then insert push & pop 
745      at the start & end of block respectively */
746   if (ssym->blockSpil)
747     {
748       iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
749       /* add push to the start of the block */
750       addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
751                                     ebp->sch->next : ebp->sch));
752       nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
753       /* add pop to the end of the block */
754       addiCodeToeBBlock (ebp, nic, NULL);
755     }
756
757   /* if spilt because not used in the remainder of the
758      block then add a push before this instruction and
759      a pop at the end of the block */
760   if (ssym->remainSpil)
761     {
762
763       iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
764       /* add push just before this instruction */
765       addiCodeToeBBlock (ebp, nic, ic);
766
767       nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
768       /* add pop to the end of the block */
769       addiCodeToeBBlock (ebp, nic, NULL);
770     }
771
772   if (ssym == forSym)
773     return FALSE;
774   else
775     return TRUE;
776 }
777
778 /*-----------------------------------------------------------------*/
779 /* getRegPtr - will try for PTR if not a GPR type if not spil      */
780 /*-----------------------------------------------------------------*/
781 static regs *
782 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
783 {
784   regs *reg;
785
786 tryAgain:
787   /* try for a ptr type */
788   if ((reg = allocReg (REG_PTR)))
789     return reg;
790
791   /* try for gpr type */
792   if ((reg = allocReg (REG_GPR)))
793     return reg;
794
795   /* we have to spil */
796   if (!spilSomething (ic, ebp, sym))
797     return NULL;
798
799   /* this looks like an infinite loop but 
800      in really selectSpil will abort  */
801   goto tryAgain;
802 }
803
804 /*-----------------------------------------------------------------*/
805 /* getRegGpr - will try for GPR if not spil                        */
806 /*-----------------------------------------------------------------*/
807 static regs *
808 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
809 {
810   regs *reg;
811
812 tryAgain:
813   /* try for gpr type */
814   if ((reg = allocReg (REG_GPR)))
815     return reg;
816
817   if (!mcs51_ptrRegReq)
818     if ((reg = allocReg (REG_PTR)))
819       return reg;
820
821   /* we have to spil */
822   if (!spilSomething (ic, ebp, sym))
823     return NULL;
824
825   /* this looks like an infinite loop but 
826      in really selectSpil will abort  */
827   goto tryAgain;
828 }
829
830 /*-----------------------------------------------------------------*/
831 /* getRegPtrNoSpil - get it cannot split                           */
832 /*-----------------------------------------------------------------*/
833 static regs *getRegPtrNoSpil()
834 {
835   regs *reg;
836
837   /* try for a ptr type */
838   if ((reg = allocReg (REG_PTR)))
839     return reg;
840
841   /* try for gpr type */
842   if ((reg = allocReg (REG_GPR)))
843     return reg;
844
845   assert(0);
846
847   /* just to make the compiler happy */
848   return 0;
849 }
850
851 /*-----------------------------------------------------------------*/
852 /* getRegGprNoSpil - get it cannot split                           */
853 /*-----------------------------------------------------------------*/
854 static regs *getRegGprNoSpil()
855 {
856
857   regs *reg;
858   if ((reg = allocReg (REG_GPR)))
859     return reg;
860
861   if (!mcs51_ptrRegReq)
862     if ((reg = allocReg (REG_PTR)))
863       return reg;
864
865   assert(0);
866
867   /* just to make the compiler happy */
868   return 0;
869 }
870
871 /*-----------------------------------------------------------------*/
872 /* symHasReg - symbol has a given register                         */
873 /*-----------------------------------------------------------------*/
874 static bool
875 symHasReg (symbol * sym, regs * reg)
876 {
877   int i;
878
879   for (i = 0; i < sym->nRegs; i++)
880     if (sym->regs[i] == reg)
881       return TRUE;
882
883   return FALSE;
884 }
885
886 /*-----------------------------------------------------------------*/
887 /* deassignLRs - check the live to and if they have registers & are */
888 /*               not spilt then free up the registers              */
889 /*-----------------------------------------------------------------*/
890 static void
891 deassignLRs (iCode * ic, eBBlock * ebp)
892 {
893   symbol *sym;
894   int k;
895   symbol *result;
896
897   for (sym = hTabFirstItem (liveRanges, &k); sym;
898        sym = hTabNextItem (liveRanges, &k))
899     {
900
901       symbol *psym = NULL;
902       /* if it does not end here */
903       if (sym->liveTo > ic->seq)
904         continue;
905
906       /* if it was spilt on stack then we can 
907          mark the stack spil location as free */
908       if (sym->isspilt)
909         {
910           if (sym->stackSpil)
911             {
912               sym->usl.spillLoc->isFree = 1;
913               sym->stackSpil = 0;
914             }
915           continue;
916         }
917
918       if (!bitVectBitValue (_G.regAssigned, sym->key))
919         continue;
920
921       /* special case check if this is an IFX &
922          the privious one was a pop and the 
923          previous one was not spilt then keep track
924          of the symbol */
925       if (ic->op == IFX && ic->prev &&
926           ic->prev->op == IPOP &&
927           !ic->prev->parmPush &&
928           !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
929         psym = OP_SYMBOL (IC_LEFT (ic->prev));
930
931       if (sym->nRegs)
932         {
933           int i = 0;
934
935           bitVectUnSetBit (_G.regAssigned, sym->key);
936
937           /* if the result of this one needs registers
938              and does not have it then assign it right
939              away */
940           if (IC_RESULT (ic) &&
941               !(SKIP_IC2 (ic) ||        /* not a special icode */
942                 ic->op == JUMPTABLE ||
943                 ic->op == IFX ||
944                 ic->op == IPUSH ||
945                 ic->op == IPOP ||
946                 ic->op == RETURN ||
947                 POINTER_SET (ic)) &&
948               (result = OP_SYMBOL (IC_RESULT (ic))) &&  /* has a result */
949               result->liveTo > ic->seq &&       /* and will live beyond this */
950               result->liveTo <= ebp->lSeq &&    /* does not go beyond this block */
951               result->regType == sym->regType &&        /* same register types */
952               result->nRegs &&  /* which needs registers */
953               !result->isspilt &&       /* and does not already have them */
954               !result->remat &&
955               !bitVectBitValue (_G.regAssigned, result->key) &&
956           /* the number of free regs + number of regs in this LR
957              can accomodate the what result Needs */
958               ((nfreeRegsType (result->regType) +
959                 sym->nRegs) >= result->nRegs)
960             )
961             {
962
963               for (i = 0; i < result->nRegs; i++)
964                 if (i < sym->nRegs)
965                   result->regs[i] = sym->regs[i];
966                 else
967                   result->regs[i] = getRegGpr (ic, ebp, result);
968
969               _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
970               _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, result->key);
971
972             }
973
974           /* free the remaining */
975           for (; i < sym->nRegs; i++)
976             {
977               if (psym)
978                 {
979                   if (!symHasReg (psym, sym->regs[i]))
980                     freeReg (sym->regs[i]);
981                 }
982               else
983                 freeReg (sym->regs[i]);
984             }
985         }
986     }
987 }
988
989
990 /*-----------------------------------------------------------------*/
991 /* reassignLR - reassign this to registers                         */
992 /*-----------------------------------------------------------------*/
993 static void
994 reassignLR (operand * op)
995 {
996   symbol *sym = OP_SYMBOL (op);
997   int i;
998
999   /* not spilt any more */
1000   sym->isspilt = sym->spillA = sym->blockSpil = sym->remainSpil = 0;
1001   bitVectUnSetBit (_G.spiltSet, sym->key);
1002
1003   _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1004   _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key);
1005
1006   _G.blockSpil--;
1007
1008   for (i = 0; i < sym->nRegs; i++)
1009     sym->regs[i]->isFree = 0;
1010 }
1011
1012 /*-----------------------------------------------------------------*/
1013 /* willCauseSpill - determines if allocating will cause a spill    */
1014 /*-----------------------------------------------------------------*/
1015 static int
1016 willCauseSpill (int nr, int rt)
1017 {
1018   /* first check if there are any avlb registers
1019      of te type required */
1020   if (rt == REG_PTR)
1021     {
1022       /* special case for pointer type 
1023          if pointer type not avlb then 
1024          check for type gpr */
1025       if (nFreeRegs (rt) >= nr)
1026         return 0;
1027       if (nFreeRegs (REG_GPR) >= nr)
1028         return 0;
1029     }
1030   else
1031     {
1032       if (mcs51_ptrRegReq)
1033         {
1034           if (nFreeRegs (rt) >= nr)
1035             return 0;
1036         }
1037       else
1038         {
1039           if (nFreeRegs (REG_PTR) +
1040               nFreeRegs (REG_GPR) >= nr)
1041             return 0;
1042         }
1043     }
1044
1045   /* it will cause a spil */
1046   return 1;
1047 }
1048
1049 /*-----------------------------------------------------------------*/
1050 /* positionRegs - the allocator can allocate same registers to res- */
1051 /* ult and operand, if this happens make sure they are in the same */
1052 /* position as the operand otherwise chaos results                 */
1053 /*-----------------------------------------------------------------*/
1054 static int
1055 positionRegs (symbol * result, symbol * opsym)
1056 {
1057   int count = min (result->nRegs, opsym->nRegs);
1058   int i, j = 0, shared = 0;
1059   int change = 0;
1060
1061   /* if the result has been spilt then cannot share */
1062   if (opsym->isspilt)
1063     return 0;
1064 again:
1065   shared = 0;
1066   /* first make sure that they actually share */
1067   for (i = 0; i < count; i++)
1068     {
1069       for (j = 0; j < count; j++)
1070         {
1071           if (result->regs[i] == opsym->regs[j] && i != j)
1072             {
1073               shared = 1;
1074               goto xchgPositions;
1075             }
1076         }
1077     }
1078 xchgPositions:
1079   if (shared)
1080     {
1081       regs *tmp = result->regs[i];
1082       result->regs[i] = result->regs[j];
1083       result->regs[j] = tmp;
1084       change ++;
1085       goto again;
1086     }
1087   return change;
1088 }
1089
1090 /*-----------------------------------------------------------------*/
1091 /* serialRegAssign - serially allocate registers to the variables  */
1092 /*-----------------------------------------------------------------*/
1093 static void
1094 serialRegAssign (eBBlock ** ebbs, int count)
1095 {
1096     int i;
1097
1098     /* for all blocks */
1099     for (i = 0; i < count; i++) {
1100
1101         iCode *ic;
1102
1103         if (ebbs[i]->noPath &&
1104             (ebbs[i]->entryLabel != entryLabel &&
1105              ebbs[i]->entryLabel != returnLabel))
1106             continue;
1107
1108         /* of all instructions do */
1109         for (ic = ebbs[i]->sch; ic; ic = ic->next) {
1110 #if 1
1111             int reg;
1112
1113             // update the registers in use at the start of this icode
1114             for (reg=0; reg<mcs51_nRegs; reg++) {
1115               if (regs8051[reg].isFree) {
1116                 ic->riu &= ~(1<<regs8051[reg].offset);
1117               } else {
1118                 ic->riu |= (1<<regs8051[reg].offset);
1119               }
1120             }
1121 #endif
1122
1123             /* if this is an ipop that means some live
1124                range will have to be assigned again */
1125             if (ic->op == IPOP)
1126                 reassignLR (IC_LEFT (ic));
1127
1128             /* if result is present && is a true symbol */
1129             if (IC_RESULT (ic) && ic->op != IFX &&
1130                 IS_TRUE_SYMOP (IC_RESULT (ic)))
1131                 OP_SYMBOL (IC_RESULT (ic))->allocreq++;
1132
1133             /* take away registers from live
1134                ranges that end at this instruction */
1135             deassignLRs (ic, ebbs[i]);
1136
1137             /* some don't need registers */
1138             if (SKIP_IC2 (ic) ||
1139                 ic->op == JUMPTABLE ||
1140                 ic->op == IFX ||
1141                 ic->op == IPUSH ||
1142                 ic->op == IPOP ||
1143                 (IC_RESULT (ic) && POINTER_SET (ic)))
1144                 continue;
1145
1146             /* now we need to allocate registers
1147                only for the result */
1148             if (IC_RESULT (ic)) {
1149                 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
1150                 bitVect *spillable;
1151                 int willCS;
1152                 int j;
1153                 int ptrRegSet = 0;
1154
1155                 /* if it does not need or is spilt 
1156                    or is already assigned to registers
1157                    or will not live beyond this instructions */
1158                 if (!sym->nRegs ||
1159                     sym->isspilt ||
1160                     bitVectBitValue (_G.regAssigned, sym->key) ||
1161                     sym->liveTo <= ic->seq)
1162                     continue;
1163
1164                 /* if some liverange has been spilt at the block level
1165                    and this one live beyond this block then spil this
1166                    to be safe */
1167                 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq) {
1168                     spillThis (sym);
1169                     continue;
1170                 }
1171                 /* if trying to allocate this will cause
1172                    a spill and there is nothing to spill 
1173                    or this one is rematerializable then
1174                    spill this one */
1175                 willCS = willCauseSpill (sym->nRegs, sym->regType);
1176                 spillable = computeSpillable (ic);
1177                 if (sym->remat || (willCS && bitVectIsZero (spillable))) {                    
1178                     spillThis (sym);
1179                     continue;                 
1180                 }
1181
1182                 /* if it has a spillocation & is used less than
1183                    all other live ranges then spill this */
1184                 if (willCS) {
1185                     if (sym->usl.spillLoc) {
1186                         symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
1187                                                                          allLRs, ebbs[i], ic));
1188                         if (leastUsed && leastUsed->used > sym->used) {
1189                             spillThis (sym);
1190                             continue;
1191                         }
1192                     } else {
1193                         /* if none of the liveRanges have a spillLocation then better
1194                            to spill this one than anything else already assigned to registers */
1195                         if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
1196                             /* if this is local to this block then we might find a block spil */
1197                             if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
1198                                 spillThis (sym);
1199                                 continue;
1200                             }
1201                         }
1202                     }
1203                 }
1204                 /* if we need ptr regs for the right side
1205                    then mark it */
1206                 if (POINTER_GET (ic) && IS_SYMOP (IC_LEFT (ic))
1207                     && getSize (OP_SYMBOL (IC_LEFT (ic))->type) <= (unsigned int) PTRSIZE) {
1208                     mcs51_ptrRegReq++;
1209                     ptrRegSet = 1;
1210                 }
1211                 /* else we assign registers to it */
1212                 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1213                 _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key);
1214
1215                 for (j = 0; j < sym->nRegs; j++) {
1216                     if (sym->regType == REG_PTR)
1217                         sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
1218                     else
1219                         sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
1220
1221                     /* if the allocation failed which means
1222                        this was spilt then break */
1223                     if (!sym->regs[j]) {
1224                       break;
1225                     }
1226                 }
1227
1228                 if (!POINTER_SET(ic) && !POINTER_GET(ic)) {
1229                     /* if it shares registers with operands make sure
1230                        that they are in the same position */
1231                     if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
1232                         OP_SYMBOL (IC_LEFT (ic))->nRegs) {
1233                         positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1234                                       OP_SYMBOL (IC_LEFT (ic)));
1235                     }
1236                     /* do the same for the right operand */
1237                     if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
1238                         OP_SYMBOL (IC_RIGHT (ic))->nRegs) {
1239                         positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1240                                       OP_SYMBOL (IC_RIGHT (ic)));
1241                     }
1242                 }
1243
1244                 if (ptrRegSet) {
1245                     mcs51_ptrRegReq--;
1246                     ptrRegSet = 0;
1247                 }
1248
1249             }
1250         }
1251     }
1252 }
1253
1254 /*-----------------------------------------------------------------*/
1255 /* fillGaps - Try to fill in the Gaps left by Pass1                */
1256 /*-----------------------------------------------------------------*/
1257 static void fillGaps()
1258 {
1259     symbol *sym =NULL;
1260     int key =0;
1261     int pass;
1262     
1263     if (getenv("DISABLE_FILL_GAPS")) return;
1264     
1265     /* look for livernages that was spilt by the allocator */
1266     for (sym = hTabFirstItem(liveRanges,&key) ; sym ; 
1267          sym = hTabNextItem(liveRanges,&key)) {
1268
1269         int i;
1270         int pdone = 0;
1271
1272         if (!sym->spillA || !sym->clashes || sym->remat) continue ;
1273
1274         /* find the liveRanges this one clashes with, that are
1275            still assigned to registers & mark the registers as used*/
1276         for ( i = 0 ; i < sym->clashes->size ; i ++) {
1277             int k;
1278             symbol *clr;
1279
1280             if (bitVectBitValue(sym->clashes,i) == 0 ||    /* those that clash with this */
1281                 bitVectBitValue(_G.totRegAssigned,i) == 0) /* and are still assigned to registers */
1282                 continue ;
1283
1284                 clr = hTabItemWithKey(liveRanges,i);
1285             assert(clr);
1286          
1287             /* mark these registers as used */
1288             for (k = 0 ; k < clr->nRegs ; k++ ) 
1289                 useReg(clr->regs[k]);
1290         }
1291
1292         if (willCauseSpill(sym->nRegs,sym->regType)) {
1293             /* NOPE :( clear all registers & and continue */
1294             freeAllRegs();
1295             continue ;
1296         }
1297
1298         D(printf("Atemping fillGaps on %s: [",sym->name));
1299         /* THERE IS HOPE !!!! */
1300         for (i=0; i < sym->nRegs ; i++ ) {
1301             if (sym->regType == REG_PTR)
1302                 sym->regs[i] = getRegPtrNoSpil ();
1303             else
1304                 sym->regs[i] = getRegGprNoSpil ();                
1305             D(printf("%s ", sym->regs[i]->name));
1306         }
1307         D(printf("]\n"));
1308
1309         /* For all its definitions check if the registers
1310            allocated needs positioning NOTE: we can position
1311            only ONCE if more than One positioning required 
1312            then give up.
1313            We may need to perform the checks twice; once to
1314            position the registers as needed, the second to
1315            verify any register repositioning is still
1316            compatible.
1317           */
1318         sym->isspilt = 0;
1319         for (pass=0; pass<2; pass++) {
1320             D(printf(" checking definitions\n"));
1321             for (i = 0 ; i < sym->defs->size ; i++ ) {
1322                 if (bitVectBitValue(sym->defs,i)) {
1323                     iCode *ic;
1324                     if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
1325                     D(printf("  ic->seq = %d\n", ic->seq));
1326                     if (SKIP_IC(ic)) continue;
1327                     assert(isSymbolEqual(sym,OP_SYMBOL(IC_RESULT(ic)))); /* just making sure */
1328                     /* if left is assigned to registers */
1329                     if (IS_SYMOP(IC_LEFT(ic)))
1330                       {
1331                         D(printf("   left = "));
1332                         D(printOperand(IC_LEFT(ic),NULL));
1333                       }
1334                     if (IS_SYMOP(IC_LEFT(ic)) && 
1335                       bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_LEFT(ic))->key)) {
1336                         pdone += (positionRegs(sym,OP_SYMBOL(IC_LEFT(ic)))>0);
1337                     }
1338                     if (IS_SYMOP(IC_RIGHT(ic)))
1339                       {
1340                         D(printf("   right = "));
1341                         D(printOperand(IC_RIGHT(ic),NULL));
1342                       }
1343                     if (IS_SYMOP(IC_RIGHT(ic)) && 
1344                       bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RIGHT(ic))->key)) {
1345                         pdone += (positionRegs(sym,OP_SYMBOL(IC_RIGHT(ic)))>0);
1346                     }
1347                     D(printf("   pdone = %d\n", pdone));
1348                     if (pdone > 1) break;
1349                 }
1350             }
1351             D(printf(" checking uses\n"));
1352             for (i = 0 ; i < sym->uses->size ; i++ ) {
1353                 if (bitVectBitValue(sym->uses,i)) {
1354                     iCode *ic;
1355                     if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
1356                     D(printf("  ic->seq = %d\n", ic->seq));
1357                     if (SKIP_IC(ic)) continue;
1358                     if (POINTER_SET(ic) || POINTER_GET(ic)) continue ;
1359
1360                     /* if result is assigned to registers */
1361                     if (IS_SYMOP(IC_RESULT(ic)))
1362                       {
1363                         D(printf("   result = "));
1364                         D(printOperand(IC_RESULT(ic),NULL));
1365                       }
1366                     if (IS_SYMOP(IC_RESULT(ic)) && 
1367                         bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RESULT(ic))->key)) {
1368                         pdone += (positionRegs(sym,OP_SYMBOL(IC_RESULT(ic)))>0);
1369                     }
1370                     D(printf("   pdone = %d\n", pdone));
1371                     if (pdone > 1) break;
1372                 }
1373             }
1374             if (pdone == 0) break; /* second pass only if regs repositioned */
1375             if (pdone > 1) break;
1376         }
1377         D(printf(" sym->regs = ["));
1378         for (i=0; i < sym->nRegs ; i++ )
1379           D(printf("%s ", sym->regs[i]->name));
1380         D(printf("]\n"));
1381         /* had to position more than once GIVE UP */
1382         if (pdone > 1) {
1383             /* UNDO all the changes we made to try this */
1384             sym->isspilt = 1;
1385             for (i=0; i < sym->nRegs ; i++ ) {
1386                     sym->regs[i] = NULL;
1387             }
1388             freeAllRegs();
1389             D(printf ("Fill Gap gave up due to positioning for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN"));
1390             continue ;      
1391         }
1392         D(printf ("FILLED GAP for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN"));
1393         _G.totRegAssigned = bitVectSetBit(_G.totRegAssigned,sym->key);
1394         sym->isspilt = sym->spillA = 0 ;
1395         sym->usl.spillLoc->allocreq--;
1396         freeAllRegs();
1397     }
1398 }
1399
1400 /*-----------------------------------------------------------------*/
1401 /* rUmaskForOp :- returns register mask for an operand             */
1402 /*-----------------------------------------------------------------*/
1403 bitVect *
1404 mcs51_rUmaskForOp (operand * op)
1405 {
1406   bitVect *rumask;
1407   symbol *sym;
1408   int j;
1409
1410   /* only temporaries are assigned registers */
1411   if (!IS_ITEMP (op))
1412     return NULL;
1413
1414   sym = OP_SYMBOL (op);
1415
1416   /* if spilt or no registers assigned to it
1417      then nothing */
1418   if (sym->isspilt || !sym->nRegs)
1419     return NULL;
1420
1421   rumask = newBitVect (mcs51_nRegs);
1422
1423   for (j = 0; j < sym->nRegs; j++)
1424     {
1425       rumask = bitVectSetBit (rumask,
1426                               sym->regs[j]->rIdx);
1427     }
1428
1429   return rumask;
1430 }
1431
1432 /*-----------------------------------------------------------------*/
1433 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
1434 /*-----------------------------------------------------------------*/
1435 static bitVect *
1436 regsUsedIniCode (iCode * ic)
1437 {
1438   bitVect *rmask = newBitVect (mcs51_nRegs);
1439
1440   /* do the special cases first */
1441   if (ic->op == IFX)
1442     {
1443       rmask = bitVectUnion (rmask,
1444                             mcs51_rUmaskForOp (IC_COND (ic)));
1445       goto ret;
1446     }
1447
1448   /* for the jumptable */
1449   if (ic->op == JUMPTABLE)
1450     {
1451       rmask = bitVectUnion (rmask,
1452                             mcs51_rUmaskForOp (IC_JTCOND (ic)));
1453
1454       goto ret;
1455     }
1456
1457   /* of all other cases */
1458   if (IC_LEFT (ic))
1459     rmask = bitVectUnion (rmask,
1460                           mcs51_rUmaskForOp (IC_LEFT (ic)));
1461
1462
1463   if (IC_RIGHT (ic))
1464     rmask = bitVectUnion (rmask,
1465                           mcs51_rUmaskForOp (IC_RIGHT (ic)));
1466
1467   if (IC_RESULT (ic))
1468     rmask = bitVectUnion (rmask,
1469                           mcs51_rUmaskForOp (IC_RESULT (ic)));
1470
1471 ret:
1472   return rmask;
1473 }
1474
1475 /*-----------------------------------------------------------------*/
1476 /* createRegMask - for each instruction will determine the regsUsed */
1477 /*-----------------------------------------------------------------*/
1478 static void
1479 createRegMask (eBBlock ** ebbs, int count)
1480 {
1481   int i;
1482
1483   /* for all blocks */
1484   for (i = 0; i < count; i++)
1485     {
1486       iCode *ic;
1487
1488       if (ebbs[i]->noPath &&
1489           (ebbs[i]->entryLabel != entryLabel &&
1490            ebbs[i]->entryLabel != returnLabel))
1491         continue;
1492
1493       /* for all instructions */
1494       for (ic = ebbs[i]->sch; ic; ic = ic->next)
1495         {
1496
1497           int j;
1498
1499           if (SKIP_IC2 (ic) || !ic->rlive)
1500             continue;
1501
1502           /* first mark the registers used in this
1503              instruction */
1504           ic->rUsed = regsUsedIniCode (ic);
1505           _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
1506
1507           /* now create the register mask for those 
1508              registers that are in use : this is a
1509              super set of ic->rUsed */
1510           ic->rMask = newBitVect (mcs51_nRegs + 1);
1511
1512           /* for all live Ranges alive at this point */
1513           for (j = 1; j < ic->rlive->size; j++)
1514             {
1515               symbol *sym;
1516               int k;
1517
1518               /* if not alive then continue */
1519               if (!bitVectBitValue (ic->rlive, j))
1520                 continue;
1521
1522               /* find the live range we are interested in */
1523               if (!(sym = hTabItemWithKey (liveRanges, j)))
1524                 {
1525                   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1526                           "createRegMask cannot find live range");
1527                   fprintf(stderr, "\tmissing live range: key=%d\n", j);
1528                   exit (0);
1529                 }
1530
1531               /* if no register assigned to it */
1532               if (!sym->nRegs || sym->isspilt)
1533                 continue;
1534
1535               /* for all the registers allocated to it */
1536               for (k = 0; k < sym->nRegs; k++)
1537                 if (sym->regs[k])
1538                   ic->rMask =
1539                     bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
1540             }
1541         }
1542     }
1543 }
1544
1545 /*-----------------------------------------------------------------*/
1546 /* rematStr - returns the rematerialized string for a remat var    */
1547 /*-----------------------------------------------------------------*/
1548 static char *
1549 rematStr (symbol * sym)
1550 {
1551   char *s = buffer;
1552   iCode *ic = sym->rematiCode;
1553
1554   while (1)
1555     {
1556
1557       /* if plus or minus print the right hand side */
1558       if (ic->op == '+' || ic->op == '-')
1559         {
1560           sprintf (s, "0x%04x %c ", (int) operandLitValue (IC_RIGHT (ic)),
1561                    ic->op);
1562           s += strlen (s);
1563           ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1564           continue;
1565         }
1566
1567       /* cast then continue */
1568       if (IS_CAST_ICODE(ic)) {
1569           ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
1570           continue;
1571       }
1572       /* we reached the end */
1573       sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
1574       break;
1575     }
1576
1577   return buffer;
1578 }
1579
1580 /*-----------------------------------------------------------------*/
1581 /* regTypeNum - computes the type & number of registers required   */
1582 /*-----------------------------------------------------------------*/
1583 static void
1584 regTypeNum (eBBlock *ebbs)
1585 {
1586   symbol *sym;
1587   int k;
1588   iCode *ic;
1589
1590   /* for each live range do */
1591   for (sym = hTabFirstItem (liveRanges, &k); sym;
1592        sym = hTabNextItem (liveRanges, &k))
1593     {
1594
1595       /* if used zero times then no registers needed */
1596       if ((sym->liveTo - sym->liveFrom) == 0)
1597         continue;
1598
1599
1600       /* if the live range is a temporary */
1601       if (sym->isitmp)
1602         {
1603
1604           /* if the type is marked as a conditional */
1605           if (sym->regType == REG_CND)
1606             continue;
1607
1608           /* if used in return only then we don't 
1609              need registers */
1610           if (sym->ruonly || sym->accuse)
1611             {
1612               if (IS_AGGREGATE (sym->type) || sym->isptr)
1613                 sym->type = aggrToPtr (sym->type, FALSE);
1614               continue;
1615             }
1616
1617           /* if the symbol has only one definition &
1618              that definition is a get_pointer */
1619           if (bitVectnBitsOn (sym->defs) == 1 &&
1620               (ic = hTabItemWithKey (iCodehTab,
1621                                      bitVectFirstBit (sym->defs))) &&
1622               POINTER_GET (ic) &&
1623               !sym->noSpilLoc &&
1624               !IS_BITVAR (sym->etype))
1625             {
1626
1627
1628               /* and that pointer is remat in data space */
1629               if (IS_SYMOP (IC_LEFT (ic)) &&
1630                   OP_SYMBOL (IC_LEFT (ic))->remat &&
1631                   !IS_CAST_ICODE(OP_SYMBOL (IC_LEFT (ic))->rematiCode) &&
1632                   DCL_TYPE (aggrToPtr (operandType(IC_LEFT(ic)), FALSE)) == POINTER)
1633                 {
1634                   /* create a psuedo symbol & force a spil */
1635                   symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
1636                   psym->type = sym->type;
1637                   psym->etype = sym->etype;
1638                   
1639                   strcpy (psym->rname, psym->name);
1640                   sym->isspilt = 1;
1641                   sym->usl.spillLoc = psym;
1642 #if 0 // an alternative fix for bug #480076
1643                   /* now this is a useless assignment to itself */
1644                   remiCodeFromeBBlock (ebbs, ic);
1645 #else
1646                   /* now this really is an assignment to itself, make it so;
1647                      it will be optimized out later */
1648                   ic->op='=';
1649                   ReplaceOpWithCheaperOp(&IC_RIGHT(ic), IC_RESULT(ic));
1650                   IC_LEFT(ic)=NULL;
1651 #endif
1652                   continue;
1653                 }
1654
1655               /* if in data space or idata space then try to
1656                  allocate pointer register */
1657
1658             }
1659
1660           /* if not then we require registers */
1661           sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
1662                         getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1663                         getSize (sym->type));
1664
1665           if (sym->nRegs > 4)
1666             {
1667               fprintf (stderr, "allocated more than 4 or 0 registers for type ");
1668               printTypeChain (sym->type, stderr);
1669               fprintf (stderr, "\n");
1670             }
1671
1672           /* determine the type of register required */
1673           if (sym->nRegs == 1 &&
1674               IS_PTR (sym->type) &&
1675               sym->uptr)
1676             sym->regType = REG_PTR;
1677           else
1678             sym->regType = REG_GPR;
1679
1680         }
1681       else
1682         /* for the first run we don't provide */
1683         /* registers for true symbols we will */
1684         /* see how things go                  */
1685         sym->nRegs = 0;
1686           }
1687
1688 }
1689
1690 /*-----------------------------------------------------------------*/
1691 /* freeAllRegs - mark all registers as free                        */
1692 /*-----------------------------------------------------------------*/
1693 static void
1694 freeAllRegs ()
1695 {
1696   int i;
1697
1698   for (i = 0; i < mcs51_nRegs; i++)
1699     regs8051[i].isFree = 1;
1700 }
1701
1702 /*-----------------------------------------------------------------*/
1703 /* deallocStackSpil - this will set the stack pointer back         */
1704 /*-----------------------------------------------------------------*/
1705 static
1706 DEFSETFUNC (deallocStackSpil)
1707 {
1708   symbol *sym = item;
1709
1710   deallocLocal (sym);
1711   return 0;
1712 }
1713
1714 /*-----------------------------------------------------------------*/
1715 /* farSpacePackable - returns the packable icode for far variables */
1716 /*-----------------------------------------------------------------*/
1717 static iCode *
1718 farSpacePackable (iCode * ic)
1719 {
1720   iCode *dic;
1721
1722   /* go thru till we find a definition for the
1723      symbol on the right */
1724   for (dic = ic->prev; dic; dic = dic->prev)
1725     {
1726       /* if the definition is a call then no */
1727       if ((dic->op == CALL || dic->op == PCALL) &&
1728           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1729         {
1730           return NULL;
1731         }
1732
1733       /* if shift by unknown amount then not */
1734       if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
1735           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1736         return NULL;
1737
1738       /* if pointer get and size > 1 */
1739       if (POINTER_GET (dic) &&
1740           getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
1741         return NULL;
1742
1743       if (POINTER_SET (dic) &&
1744           getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
1745         return NULL;
1746
1747       if (dic->op == IFX)
1748         {
1749           if (IC_COND (dic) &&
1750               IS_TRUE_SYMOP (IC_COND (dic)) &&
1751               isOperandInFarSpace (IC_COND (dic)))
1752             return NULL;
1753         }
1754       else if (dic->op == JUMPTABLE)
1755         {
1756           if (IC_JTCOND (dic) &&
1757               IS_TRUE_SYMOP (IC_JTCOND (dic)) &&
1758               isOperandInFarSpace (IC_JTCOND (dic)))
1759             return NULL;
1760         }
1761       else
1762         {
1763           /* if any three is a true symbol in far space */
1764           if (IC_RESULT (dic) &&
1765               IS_TRUE_SYMOP (IC_RESULT (dic)) &&
1766               isOperandInFarSpace (IC_RESULT (dic)))
1767             return NULL;
1768
1769           if (IC_RIGHT (dic) &&
1770               IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
1771               isOperandInFarSpace (IC_RIGHT (dic)) &&
1772               !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
1773             return NULL;
1774
1775           if (IC_LEFT (dic) &&
1776               IS_TRUE_SYMOP (IC_LEFT (dic)) &&
1777               isOperandInFarSpace (IC_LEFT (dic)) &&
1778               !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
1779             return NULL;
1780         }
1781
1782       if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
1783         {
1784           if ((dic->op == LEFT_OP ||
1785                dic->op == RIGHT_OP ||
1786                dic->op == '-') &&
1787               IS_OP_LITERAL (IC_RIGHT (dic)))
1788             return NULL;
1789           else
1790             return dic;
1791         }
1792     }
1793
1794   return NULL;
1795 }
1796
1797 /*-----------------------------------------------------------------*/
1798 /* packRegsForAssign - register reduction for assignment           */
1799 /*-----------------------------------------------------------------*/
1800 static int
1801 packRegsForAssign (iCode * ic, eBBlock * ebp)
1802 {
1803   iCode *dic, *sic;
1804
1805   if (!IS_ITEMP (IC_RIGHT (ic)) ||
1806       OP_SYMBOL (IC_RIGHT (ic))->isind ||
1807       OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
1808     {
1809       return 0;
1810     }
1811
1812
1813   /* if the true symbol is defined in far space or on stack
1814      then we should not since this will increase register pressure */
1815   if (isOperandInFarSpace(IC_RESULT(ic)) && !farSpacePackable(ic)) {
1816     return 0;
1817   }
1818
1819   /* find the definition of iTempNN scanning backwards if we find a 
1820      a use of the true symbol in before we find the definition then 
1821      we cannot */
1822   for (dic = ic->prev; dic; dic = dic->prev)
1823     {
1824
1825 #if 0 /* jwk: This collides with 1.43 but I really see no need for
1826          this anymore. It fixes bug #716790 and substantially improves 
1827          redundant register usage around function calls.
1828       */
1829
1830       /* if there is a function call then don't pack it */
1831       if ((dic->op == CALL || dic->op == PCALL))
1832         {
1833           dic = NULL;
1834           break;
1835         }
1836 #endif
1837
1838       if (SKIP_IC2 (dic))
1839         continue;
1840
1841       if (dic->op == IFX)
1842         {
1843           if (IS_SYMOP (IC_COND (dic)) &&
1844               (IC_COND (dic)->key == IC_RESULT (ic)->key ||
1845                IC_COND (dic)->key == IC_RIGHT (ic)->key))
1846             {
1847               dic = NULL;
1848               break;
1849             }
1850         }
1851       else
1852         {
1853           if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
1854               IS_OP_VOLATILE (IC_RESULT (dic)))
1855             {
1856               dic = NULL;
1857               break;
1858             }
1859
1860           if (IS_SYMOP (IC_RESULT (dic)) &&
1861               IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1862             {
1863               if (POINTER_SET (dic))
1864                 dic = NULL;
1865
1866               break;
1867             }
1868
1869           if (IS_SYMOP (IC_RIGHT (dic)) &&
1870               (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
1871                IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
1872             {
1873               dic = NULL;
1874               break;
1875             }
1876
1877           if (IS_SYMOP (IC_LEFT (dic)) &&
1878               (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
1879                IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
1880             {
1881               dic = NULL;
1882               break;
1883             }
1884
1885           if (POINTER_SET (dic) &&
1886               IC_RESULT (dic)->key == IC_RESULT (ic)->key)
1887             {
1888               dic = NULL;
1889               break;
1890             }
1891         }
1892     }
1893
1894   if (!dic)
1895     return 0;                   /* did not find */
1896
1897   /* if assignment then check that right is not a bit */
1898   if (ASSIGNMENT (dic) && !POINTER_SET (dic))
1899     {
1900       sym_link *etype = operandType (IC_RIGHT (dic));
1901       if (IS_BITFIELD (etype))
1902         {
1903           /* if result is a bit too then it's ok */
1904           etype = operandType (IC_RESULT (dic));
1905           if (!IS_BITFIELD (etype))
1906             return 0;
1907         }
1908     }
1909   /* if the result is on stack or iaccess then it must be
1910      the same atleast one of the operands */
1911   if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
1912       OP_SYMBOL (IC_RESULT (ic))->iaccess)
1913     {
1914
1915       /* the operation has only one symbol
1916          operator then we can pack */
1917       if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
1918           (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
1919         goto pack;
1920
1921       if (!((IC_LEFT (dic) &&
1922              IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
1923             (IC_RIGHT (dic) &&
1924              IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
1925         return 0;
1926     }
1927 pack:
1928   /* found the definition */
1929   /* replace the result with the result of */
1930   /* this assignment and remove this assignment */
1931   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1932   ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
1933
1934   if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
1935     {
1936       OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
1937     }
1938   // TODO: and the otherway around?
1939
1940   /* delete from liverange table also 
1941      delete from all the points inbetween and the new
1942      one */
1943   for (sic = dic; sic != ic; sic = sic->next)
1944     {
1945       bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
1946       if (IS_ITEMP (IC_RESULT (dic)))
1947         bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
1948     }
1949
1950   remiCodeFromeBBlock (ebp, ic);
1951   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
1952   hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
1953   OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
1954   return 1;
1955 }
1956
1957 /*------------------------------------------------------------------*/
1958 /* findAssignToSym : scanning backwards looks for first assig found */
1959 /*------------------------------------------------------------------*/
1960 static iCode *
1961 findAssignToSym (operand * op, iCode * ic)
1962 {
1963   iCode *dic;
1964
1965   /* This routine is used to find sequences like
1966      iTempAA = FOO;
1967      ...;  (intervening ops don't use iTempAA or modify FOO)
1968      blah = blah + iTempAA;
1969
1970      and eliminate the use of iTempAA, freeing up its register for
1971      other uses.
1972   */
1973      
1974
1975   for (dic = ic->prev; dic; dic = dic->prev)
1976     {
1977
1978       /* if definition by assignment */
1979       if (dic->op == '=' &&
1980           !POINTER_SET (dic) &&
1981           IC_RESULT (dic)->key == op->key
1982 /*          &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) */
1983         )
1984         break;  /* found where this temp was defined */
1985
1986       /* if we find an usage then we cannot delete it */
1987       
1988       if (dic->op == IFX)
1989         {
1990           if (IC_COND (dic) && IC_COND (dic)->key == op->key)
1991             return NULL;
1992         }
1993       else if (dic->op == JUMPTABLE)
1994         {
1995           if (IC_JTCOND (dic) && IC_JTCOND (dic)->key == op->key)
1996             return NULL;
1997         }
1998       else
1999         {
2000           if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2001             return NULL;
2002
2003           if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2004             return NULL;
2005
2006           if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2007             return NULL;
2008         }
2009     }
2010
2011   if (!dic)
2012     return NULL;   /* didn't find any assignment to op */
2013
2014   /* we are interested only if defined in far space */
2015   /* or in stack space in case of + & - */
2016   
2017   /* if assigned to a non-symbol then don't repack regs */
2018   if (!IS_SYMOP (IC_RIGHT (dic)))
2019     return NULL;
2020   
2021   /* if the symbol is volatile then we should not */
2022   if (isOperandVolatile (IC_RIGHT (dic), TRUE))
2023     return NULL;
2024   /* XXX TODO --- should we be passing FALSE to isOperandVolatile()?
2025      What does it mean for an iTemp to be volatile, anyway? Passing
2026      TRUE is more cautious but may prevent possible optimizations */
2027
2028   /* if the symbol is in far space then we should not */
2029   if (isOperandInFarSpace (IC_RIGHT (dic)))
2030     return NULL;
2031   
2032   /* for + & - operations make sure that
2033      if it is on the stack it is the same
2034      as one of the three operands */
2035   if ((ic->op == '+' || ic->op == '-') &&
2036       OP_SYMBOL (IC_RIGHT (dic))->onStack)
2037     {
2038       
2039       if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2040           IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2041           IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2042         return NULL;
2043     }
2044   
2045   /* now make sure that the right side of dic
2046      is not defined between ic & dic */
2047   if (dic)
2048     {
2049       iCode *sic = dic->next;
2050
2051       for (; sic != ic; sic = sic->next)
2052         if (IC_RESULT (sic) &&
2053             IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2054           return NULL;
2055     }
2056
2057   return dic;
2058 }
2059
2060 /*-----------------------------------------------------------------*/
2061 /* reassignAliasedSym - used by packRegsForSupport to replace      */
2062 /*                      redundant iTemp with equivalent symbol     */
2063 /*-----------------------------------------------------------------*/
2064 static void
2065 reassignAliasedSym (eBBlock *ebp, iCode *assignment, iCode *use, operand *op)
2066 {
2067   iCode *ic;
2068   unsigned oldSymKey, newSymKey;
2069
2070   oldSymKey = op->key;
2071   newSymKey = IC_RIGHT(assignment)->key;
2072
2073   /* only track live ranges of compiler-generated temporaries */
2074   if (!IS_ITEMP(IC_RIGHT(assignment)))
2075     newSymKey = 0;
2076
2077   /* update the live-value bitmaps */
2078   for (ic = assignment; ic != use; ic = ic->next) {
2079     bitVectUnSetBit (ic->rlive, oldSymKey);
2080     if (newSymKey != 0)
2081       ic->rlive = bitVectSetBit (ic->rlive, newSymKey);
2082   }
2083
2084   /* update the sym of the used operand */
2085   OP_SYMBOL(op) = OP_SYMBOL(IC_RIGHT(assignment));
2086   op->key = OP_SYMBOL(op)->key;
2087
2088   /* update the sym's liverange */
2089   if ( OP_LIVETO(op) < ic->seq )
2090     setToRange(op, ic->seq, FALSE);
2091
2092   /* remove the assignment iCode now that its result is unused */
2093   remiCodeFromeBBlock (ebp, assignment);
2094   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(assignment))->defs, assignment->key);
2095   hTabDeleteItem (&iCodehTab, assignment->key, assignment, DELETE_ITEM, NULL);
2096 }
2097   
2098
2099 /*-----------------------------------------------------------------*/
2100 /* packRegsForSupport :- reduce some registers for support calls   */
2101 /*-----------------------------------------------------------------*/
2102 static int
2103 packRegsForSupport (iCode * ic, eBBlock * ebp)
2104 {
2105   iCode *dic;
2106   
2107   /* for the left & right operand :- look to see if the
2108      left was assigned a true symbol in far space in that
2109      case replace them */
2110
2111   if (IS_ITEMP (IC_LEFT (ic)) &&
2112       OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2113     {
2114       dic = findAssignToSym (IC_LEFT (ic), ic);
2115
2116       if (dic)
2117         {
2118           /* found it we need to remove it from the block */
2119           reassignAliasedSym (ebp, dic, ic, IC_LEFT(ic));
2120           return 1;
2121         }
2122     }
2123
2124   /* do the same for the right operand */
2125   if (IS_ITEMP (IC_RIGHT (ic)) &&
2126       OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2127     {
2128       iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2129
2130       if (dic)
2131         {
2132           /* if this is a subtraction & the result
2133              is a true symbol in far space then don't pack */
2134           if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
2135             {
2136               sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
2137               if (IN_FARSPACE (SPEC_OCLS (etype)))
2138                 return 0;
2139             }
2140           /* found it we need to remove it from the
2141              block */
2142           reassignAliasedSym (ebp, dic, ic, IC_RIGHT(ic));
2143           
2144           return 1;
2145         }
2146     }
2147
2148   return 0;
2149 }
2150
2151 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
2152
2153
2154 /*-----------------------------------------------------------------*/
2155 /* packRegsForOneuse : - will reduce some registers for single Use */
2156 /*-----------------------------------------------------------------*/
2157 static iCode *
2158 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
2159 {
2160   bitVect *uses;
2161   iCode *dic, *sic;
2162
2163   /* if returning a literal then do nothing */
2164   if (!IS_SYMOP (op))
2165     return NULL;
2166
2167   /* only upto 2 bytes since we cannot predict
2168      the usage of b, & acc */
2169   if (getSize (operandType (op)) > (fReturnSizeMCS51 - 2))
2170     return NULL;
2171
2172   if (ic->op != RETURN &&
2173       ic->op != SEND &&
2174       !POINTER_SET (ic) &&
2175       !POINTER_GET (ic))
2176     return NULL;
2177   
2178   if (ic->op == SEND && ic->argreg != 1) return NULL;
2179
2180   /* this routine will mark the a symbol as used in one 
2181      instruction use only && if the defintion is local 
2182      (ie. within the basic block) && has only one definition &&
2183      that definiion is either a return value from a 
2184      function or does not contain any variables in
2185      far space */
2186   uses = bitVectCopy (OP_USES (op));
2187   bitVectUnSetBit (uses, ic->key);      /* take away this iCode */
2188   if (!bitVectIsZero (uses))    /* has other uses */
2189     return NULL;
2190
2191   /* if it has only one defintion */
2192   if (bitVectnBitsOn (OP_DEFS (op)) > 1)
2193     return NULL;                /* has more than one definition */
2194
2195   /* get that definition */
2196   if (!(dic =
2197         hTabItemWithKey (iCodehTab,
2198                          bitVectFirstBit (OP_DEFS (op)))))
2199     return NULL;
2200
2201   /* if that only usage is a cast */
2202   if (dic->op == CAST) {
2203     /* to a bigger type */
2204     if (getSize(OP_SYM_TYPE(IC_RESULT(dic))) > 
2205         getSize(OP_SYM_TYPE(IC_RIGHT(dic)))) {
2206       /* than we can not, since we cannot predict the usage of b & acc */
2207       return NULL;
2208     }
2209   }
2210
2211   /* found the definition now check if it is local */
2212   if (dic->seq < ebp->fSeq ||
2213       dic->seq > ebp->lSeq)
2214     return NULL;                /* non-local */
2215
2216   /* now check if it is the return from
2217      a function call */
2218   if (dic->op == CALL || dic->op == PCALL)
2219     {
2220       if (ic->op != SEND && ic->op != RETURN &&
2221           !POINTER_SET(ic) && !POINTER_GET(ic))
2222         {
2223           OP_SYMBOL (op)->ruonly = 1;
2224           return dic;
2225         }
2226       dic = dic->next;
2227     }
2228
2229
2230   /* otherwise check that the definition does
2231      not contain any symbols in far space */
2232   if (isOperandInFarSpace (IC_LEFT (dic)) ||
2233       isOperandInFarSpace (IC_RIGHT (dic)) ||
2234       IS_OP_RUONLY (IC_LEFT (ic)) ||
2235       IS_OP_RUONLY (IC_RIGHT (ic)))
2236     {
2237       return NULL;
2238     }
2239
2240   /* if pointer set then make sure the pointer
2241      is one byte */
2242   if (POINTER_SET (dic) &&
2243       !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2244     return NULL;
2245
2246   if (POINTER_GET (dic) &&
2247       !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2248     return NULL;
2249
2250   sic = dic;
2251
2252   /* also make sure the intervenening instructions
2253      don't have any thing in far space */
2254   for (dic = dic->next; dic && dic != ic && sic != ic; dic = dic->next)
2255     {
2256
2257       /* if there is an intervening function call then no */
2258       if (dic->op == CALL || dic->op == PCALL)
2259         return NULL;
2260       /* if pointer set then make sure the pointer
2261          is one byte */
2262       if (POINTER_SET (dic) &&
2263           !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2264         return NULL;
2265
2266       if (POINTER_GET (dic) &&
2267           !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2268         return NULL;
2269
2270       /* if address of & the result is remat the okay */
2271       if (dic->op == ADDRESS_OF &&
2272           OP_SYMBOL (IC_RESULT (dic))->remat)
2273         continue;
2274
2275       /* if operand has size of three or more & this
2276          operation is a '*','/' or '%' then 'b' may
2277          cause a problem */
2278       if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
2279           getSize (operandType (op)) >= 3)
2280         return NULL;
2281
2282       /* if left or right or result is in far space */
2283       if (isOperandInFarSpace (IC_LEFT (dic)) ||
2284           isOperandInFarSpace (IC_RIGHT (dic)) ||
2285           isOperandInFarSpace (IC_RESULT (dic)) ||
2286           IS_OP_RUONLY (IC_LEFT (dic)) ||
2287           IS_OP_RUONLY (IC_RIGHT (dic)) ||
2288           IS_OP_RUONLY (IC_RESULT (dic)))
2289         {
2290           return NULL;
2291         }
2292       /* if left or right or result is on stack */
2293       if (isOperandOnStack(IC_LEFT(dic)) ||
2294           isOperandOnStack(IC_RIGHT(dic)) ||
2295           isOperandOnStack(IC_RESULT(dic))) {
2296         return NULL;
2297       }
2298     }
2299
2300   OP_SYMBOL (op)->ruonly = 1;
2301   return sic;
2302 }
2303
2304 /*-----------------------------------------------------------------*/
2305 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
2306 /*-----------------------------------------------------------------*/
2307 static bool
2308 isBitwiseOptimizable (iCode * ic)
2309 {
2310   sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
2311   sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
2312
2313   /* bitwise operations are considered optimizable
2314      under the following conditions (Jean-Louis VERN) 
2315
2316      x & lit
2317      bit & bit
2318      bit & x
2319      bit ^ bit
2320      bit ^ x
2321      x   ^ lit
2322      x   | lit
2323      bit | bit
2324      bit | x
2325   */
2326   if (IS_LITERAL(rtype) ||
2327       (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
2328     return TRUE;
2329   else
2330     return FALSE;
2331 }
2332
2333 /*-----------------------------------------------------------------*/
2334 /* isCommutativeOp - tests whether this op cares what order its    */
2335 /*                   operands are in                               */
2336 /*-----------------------------------------------------------------*/
2337 bool isCommutativeOp(unsigned int op)
2338 {
2339   if (op == '+' || op == '*' || op == EQ_OP ||
2340       op == '^' || op == '|' || op == BITWISEAND)
2341     return TRUE;
2342   else
2343     return FALSE;
2344 }
2345
2346 /*-----------------------------------------------------------------*/
2347 /* operandUsesAcc - determines whether the code generated for this */
2348 /*                  operand will have to use the accumulator       */
2349 /*-----------------------------------------------------------------*/
2350 bool operandUsesAcc(operand *op)
2351 {
2352   if (!op)
2353     return FALSE;
2354
2355   if (IS_SYMOP(op)) {
2356     symbol *sym = OP_SYMBOL(op);
2357     memmap *symspace;
2358
2359     if (sym->accuse)
2360       return TRUE;  /* duh! */
2361
2362     if (IN_STACK(sym->etype) || sym->onStack ||
2363         (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
2364       return TRUE;  /* acc is used to calc stack offset */
2365
2366     if (IS_ITEMP(op))
2367       {
2368         if (SPIL_LOC(op)) {
2369           sym = SPIL_LOC(op);  /* if spilled, look at spill location */
2370         } else {
2371           return FALSE;  /* more checks? */
2372         }
2373       }
2374
2375     symspace = SPEC_OCLS(sym->etype);
2376
2377     if (sym->iaccess && symspace->paged)
2378       return TRUE;  /* must fetch paged indirect sym via accumulator */
2379     
2380     if (IN_BITSPACE(symspace))
2381       return TRUE;  /* fetching bit vars uses the accumulator */
2382     
2383     if (IN_FARSPACE(symspace) || IN_CODESPACE(symspace)) 
2384       return TRUE;  /* fetched via accumulator and dptr */
2385   }
2386
2387   return FALSE;
2388 }
2389
2390 /*-----------------------------------------------------------------*/
2391 /* packRegsForAccUse - pack registers for acc use                  */
2392 /*-----------------------------------------------------------------*/
2393 static void
2394 packRegsForAccUse (iCode * ic)
2395 {
2396   iCode *uic;
2397
2398   /* if this is an aggregate, e.g. a one byte char array */
2399   if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
2400     return;
2401   }
2402
2403   /* if we are calling a reentrant function that has stack parameters */
2404   if (ic->op == CALL &&
2405        IFFUNC_ISREENT(operandType(IC_LEFT(ic))) &&
2406        FUNC_HASSTACKPARM(operandType(IC_LEFT(ic))))
2407       return;
2408
2409   if (ic->op == PCALL &&
2410        IFFUNC_ISREENT(operandType(IC_LEFT(ic))->next) &&
2411        FUNC_HASSTACKPARM(operandType(IC_LEFT(ic))->next))
2412       return;
2413
2414   /* if + or - then it has to be one byte result */
2415   if ((ic->op == '+' || ic->op == '-')
2416       && getSize (operandType (IC_RESULT (ic))) > 1)
2417     return;
2418
2419   /* if shift operation make sure right side is not a literal */
2420   if (ic->op == RIGHT_OP &&
2421       (isOperandLiteral (IC_RIGHT (ic)) ||
2422        getSize (operandType (IC_RESULT (ic))) > 1))
2423     return;
2424
2425   if (ic->op == LEFT_OP &&
2426       (isOperandLiteral (IC_RIGHT (ic)) ||
2427        getSize (operandType (IC_RESULT (ic))) > 1))
2428     return;
2429
2430   if (IS_BITWISE_OP (ic) &&
2431       getSize (operandType (IC_RESULT (ic))) > 1)
2432     return;
2433
2434
2435   /* has only one definition */
2436   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
2437     return;
2438
2439   /* has only one use */
2440   if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
2441     return;
2442
2443   /* and the usage immediately follows this iCode */
2444   if (!(uic = hTabItemWithKey (iCodehTab,
2445                                bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
2446     return;
2447
2448   if (ic->next != uic)
2449     return;
2450
2451   /* if it is a conditional branch then we definitely can */
2452   if (uic->op == IFX)
2453     goto accuse;
2454
2455   if (uic->op == JUMPTABLE)
2456     return;
2457
2458   if (POINTER_SET (uic) &&
2459       getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
2460     return;
2461
2462   /* if the usage is not is an assignment
2463      or an arithmetic / bitwise / shift operation then not */
2464   if (uic->op != '=' &&
2465       !IS_ARITHMETIC_OP (uic) &&
2466       !IS_BITWISE_OP (uic) &&
2467       uic->op != LEFT_OP &&
2468       uic->op != RIGHT_OP)
2469     return;
2470
2471   /* if used in ^ operation then make sure right is not a 
2472      literal (WIML: Why is this?) */
2473   if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
2474     return;
2475
2476   /* if shift operation make sure right side is not a literal */
2477   /* WIML: Why is this? */
2478   if (uic->op == RIGHT_OP &&
2479       (isOperandLiteral (IC_RIGHT (uic)) ||
2480        getSize (operandType (IC_RESULT (uic))) > 1))
2481     return;
2482   if (uic->op == LEFT_OP &&
2483       (isOperandLiteral (IC_RIGHT (uic)) ||
2484        getSize (operandType (IC_RESULT (uic))) > 1))
2485     return;
2486
2487   /* make sure that the result of this icode is not on the
2488      stack, since acc is used to compute stack offset */
2489 #if 0
2490   if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
2491       OP_SYMBOL (IC_RESULT (uic))->onStack)
2492     return;
2493 #else
2494   if (isOperandOnStack(IC_RESULT(uic)))
2495     return;
2496 #endif
2497
2498   /* if the usage has only one operand then we can */
2499   if (IC_LEFT (uic) == NULL ||
2500       IC_RIGHT (uic) == NULL)
2501     goto accuse;
2502
2503   /* if the other operand uses the accumulator then we cannot */
2504   if ( (IC_LEFT(uic)->key == IC_RESULT(ic)->key &&
2505         operandUsesAcc(IC_RIGHT(uic))) ||
2506        (IC_RIGHT(uic)->key == IC_RESULT(ic)->key &&
2507         operandUsesAcc(IC_LEFT(uic))) ) 
2508     return;
2509
2510   /* make sure this is on the left side if not commutative */
2511   /* except for '-', which has been written to be able to
2512      handle reversed operands */
2513   if (!(isCommutativeOp(ic->op) || ic->op == '-') &&
2514        IC_LEFT (uic)->key != IC_RESULT (ic)->key)
2515     return;
2516
2517 #if 0
2518   // this is too dangerous and need further restrictions
2519   // see bug #447547
2520
2521   /* if one of them is a literal then we can */
2522   if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
2523       (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
2524     {
2525       OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2526       return;
2527     }
2528 #endif
2529
2530 accuse:
2531   OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2532
2533 }
2534
2535 /*-----------------------------------------------------------------*/
2536 /* packForPush - hueristics to reduce iCode for pushing            */
2537 /*-----------------------------------------------------------------*/
2538 static void
2539 packForPush (iCode * ic, eBBlock ** ebpp, int blockno)
2540 {
2541   iCode *dic, *lic;
2542   bitVect *dbv;
2543   struct eBBlock * ebp=ebpp[blockno];
2544
2545   if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
2546     return;
2547
2548   /* must have only definition & one usage */
2549   if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
2550       bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
2551     return;
2552
2553   /* find the definition */
2554   if (!(dic = hTabItemWithKey (iCodehTab,
2555                                bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
2556     return;
2557
2558   if (dic->op != '=' || POINTER_SET (dic))
2559     return;
2560
2561   if (dic->seq < ebp->fSeq) { // Evelyn did this
2562     int i;
2563     for (i=0; i<blockno; i++) {
2564       if (dic->seq >= ebpp[i]->fSeq && dic->seq <= ebpp[i]->lSeq) {
2565         ebp=ebpp[i];
2566         break;
2567       }
2568     }
2569     wassert (i!=blockno); // no way to recover from here
2570   }
2571
2572   if (IS_SYMOP(IC_RIGHT(dic))) {
2573     /* make sure the right side does not have any definitions
2574        inbetween */
2575     dbv = OP_DEFS(IC_RIGHT(dic));
2576     for (lic = ic; lic && lic != dic ; lic = lic->prev) {
2577       if (bitVectBitValue(dbv,lic->key)) 
2578         return ;
2579     }
2580     /* make sure they have the same type */
2581     if (IS_SPEC(operandType(IC_LEFT(ic))))
2582     {
2583       sym_link *itype=operandType(IC_LEFT(ic));
2584       sym_link *ditype=operandType(IC_RIGHT(dic));
2585       
2586       if (SPEC_USIGN(itype)!=SPEC_USIGN(ditype) ||
2587           SPEC_LONG(itype)!=SPEC_LONG(ditype))
2588         return;
2589     }
2590     /* extend the live range of replaced operand if needed */
2591     if (OP_SYMBOL(IC_RIGHT(dic))->liveTo < ic->seq) {
2592       OP_SYMBOL(IC_RIGHT(dic))->liveTo = ic->seq;
2593     }
2594     bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2595   } 
2596
2597   /* we now we know that it has one & only one def & use
2598      and the that the definition is an assignment */
2599   ReplaceOpWithCheaperOp(&IC_LEFT (ic), IC_RIGHT (dic));
2600   remiCodeFromeBBlock (ebp, dic);
2601   hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2602 }
2603
2604 /*-----------------------------------------------------------------*/
2605 /* packRegisters - does some transformations to reduce register    */
2606 /*                   pressure                                      */
2607 /*-----------------------------------------------------------------*/
2608 static void
2609 packRegisters (eBBlock ** ebpp, int blockno)
2610 {
2611   iCode *ic;
2612   int change = 0;
2613   eBBlock *ebp=ebpp[blockno];
2614
2615   while (1)
2616     {
2617
2618       change = 0;
2619
2620       /* look for assignments of the form */
2621       /* iTempNN = TRueSym (someoperation) SomeOperand */
2622       /*       ....                       */
2623       /* TrueSym := iTempNN:1             */
2624       for (ic = ebp->sch; ic; ic = ic->next)
2625         {
2626           /* find assignment of the form TrueSym := iTempNN:1 */
2627           if (ic->op == '=' && !POINTER_SET (ic))
2628             change += packRegsForAssign (ic, ebp);
2629         }
2630
2631       if (!change)
2632         break;
2633     }
2634
2635   for (ic = ebp->sch; ic; ic = ic->next)
2636     {
2637       /* if this is an itemp & result of an address of a true sym 
2638          then mark this as rematerialisable   */
2639       if (ic->op == ADDRESS_OF &&
2640           IS_ITEMP (IC_RESULT (ic)) &&
2641           IS_TRUE_SYMOP (IC_LEFT (ic)) &&
2642           bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2643           !OP_SYMBOL (IC_LEFT (ic))->onStack)
2644         {
2645
2646           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2647           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2648           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2649
2650         }
2651
2652       /* if straight assignment then carry remat flag if
2653          this is the only definition */
2654       if (ic->op == '=' &&
2655           !POINTER_SET (ic) &&
2656           IS_SYMOP (IC_RIGHT (ic)) &&
2657           OP_SYMBOL (IC_RIGHT (ic))->remat &&
2658           !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode) &&
2659           bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
2660         {
2661
2662           OP_SYMBOL (IC_RESULT (ic))->remat =
2663             OP_SYMBOL (IC_RIGHT (ic))->remat;
2664           OP_SYMBOL (IC_RESULT (ic))->rematiCode =
2665             OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
2666         }
2667
2668       /* if cast to a generic pointer & the pointer being
2669          cast is remat, then we can remat this cast as well */
2670       if (ic->op == CAST && 
2671           IS_SYMOP(IC_RIGHT(ic)) &&
2672           OP_SYMBOL(IC_RIGHT(ic))->remat &&
2673           bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1) {
2674               sym_link *to_type = operandType(IC_LEFT(ic));
2675               sym_link *from_type = operandType(IC_RIGHT(ic));
2676               if (IS_GENPTR(to_type) && IS_PTR(from_type)) {                  
2677                       OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2678                       OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2679                       OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2680               }
2681       }
2682
2683       /* if this is a +/- operation with a rematerizable 
2684          then mark this as rematerializable as well */
2685       if ((ic->op == '+' || ic->op == '-') &&
2686           (IS_SYMOP (IC_LEFT (ic)) &&
2687            IS_ITEMP (IC_RESULT (ic)) &&
2688            IS_OP_LITERAL (IC_RIGHT (ic))) &&
2689            OP_SYMBOL (IC_LEFT (ic))->remat &&
2690           (!IS_SYMOP (IC_RIGHT (ic)) || !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode)) &&
2691            bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1)
2692         {
2693           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2694           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2695           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2696         }
2697
2698       /* mark the pointer usages */
2699       if (POINTER_SET (ic))
2700         OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
2701
2702       if (POINTER_GET (ic) &&
2703           IS_SYMOP(IC_LEFT (ic)))
2704         OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
2705
2706       if (!SKIP_IC2 (ic))
2707         {
2708           /* if we are using a symbol on the stack
2709              then we should say mcs51_ptrRegReq */
2710           if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
2711             mcs51_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
2712                                  OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
2713           else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
2714             mcs51_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
2715                               OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
2716           else
2717             {
2718               if (IS_SYMOP (IC_LEFT (ic)))
2719                 mcs51_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
2720                                 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
2721               if (IS_SYMOP (IC_RIGHT (ic)))
2722                 mcs51_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
2723                                OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
2724               if (IS_SYMOP (IC_RESULT (ic)))
2725                 mcs51_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
2726                               OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
2727             }
2728         }
2729
2730       /* if the condition of an if instruction
2731          is defined in the previous instruction and
2732          this is the only usage then
2733          mark the itemp as a conditional */
2734       if ((IS_CONDITIONAL (ic) ||
2735            (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic))) &&
2736           ic->next && ic->next->op == IFX &&
2737           bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
2738           isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
2739           OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2740         {
2741           OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
2742           continue;
2743         }
2744
2745       /* reduce for support function calls */
2746       if (ic->supportRtn || ic->op == '+' || ic->op == '-')
2747         packRegsForSupport (ic, ebp);
2748
2749       /* some cases the redundant moves can
2750          can be eliminated for return statements */
2751       if ((ic->op == RETURN || (ic->op == SEND && ic->argreg == 1)) &&
2752           !isOperandInFarSpace (IC_LEFT (ic)) &&
2753           options.model == MODEL_SMALL) {
2754         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2755       }
2756
2757       /* if pointer set & left has a size more than
2758          one and right is not in far space */
2759       if (POINTER_SET (ic) &&
2760           !isOperandInFarSpace (IC_RIGHT (ic)) &&
2761           !OP_SYMBOL (IC_RESULT (ic))->remat &&
2762           !IS_OP_RUONLY (IC_RIGHT (ic)) &&
2763           getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
2764         packRegsForOneuse (ic, IC_RESULT (ic), ebp);
2765
2766       /* if pointer get */
2767       if (POINTER_GET (ic) &&
2768           IS_SYMOP (IC_LEFT (ic)) &&
2769           !isOperandInFarSpace (IC_RESULT (ic)) &&
2770           !OP_SYMBOL (IC_LEFT (ic))->remat &&
2771           !IS_OP_RUONLY (IC_RESULT (ic)) &&
2772           getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
2773         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2774
2775
2776       /* if this is cast for intergral promotion then
2777          check if only use of  the definition of the 
2778          operand being casted/ if yes then replace
2779          the result of that arithmetic operation with 
2780          this result and get rid of the cast */
2781       if (ic->op == CAST)
2782         {
2783           sym_link *fromType = operandType (IC_RIGHT (ic));
2784           sym_link *toType = operandType (IC_LEFT (ic));
2785
2786           if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
2787               getSize (fromType) != getSize (toType) &&
2788               SPEC_USIGN (fromType) == SPEC_USIGN (toType))
2789             {
2790
2791               iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2792               if (dic)
2793                 {
2794                   if (IS_ARITHMETIC_OP (dic))
2795                     {                  
2796                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2797                       ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
2798                       remiCodeFromeBBlock (ebp, ic);
2799                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2800                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2801                       OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2802                       ic = ic->prev;
2803                     }
2804                   else
2805                     OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
2806                 }
2807             }
2808           else
2809             {
2810
2811               /* if the type from and type to are the same
2812                  then if this is the only use then packit */
2813               if (compareType (operandType (IC_RIGHT (ic)),
2814                              operandType (IC_LEFT (ic))) == 1)
2815                 {
2816                   iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2817                   if (dic)
2818                     {
2819                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2820                       ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
2821                       remiCodeFromeBBlock (ebp, ic);
2822                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2823                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2824                       OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2825                       ic = ic->prev;
2826                     }
2827                 }
2828             }
2829         }
2830
2831       /* pack for PUSH 
2832          iTempNN := (some variable in farspace) V1
2833          push iTempNN ;
2834          -------------
2835          push V1
2836        */
2837       if (ic->op == IPUSH)
2838         {
2839           packForPush (ic, ebpp, blockno);
2840         }
2841
2842
2843       /* pack registers for accumulator use, when the
2844          result of an arithmetic or bit wise operation
2845          has only one use, that use is immediately following
2846          the defintion and the using iCode has only one
2847          operand or has two operands but one is literal &
2848          the result of that operation is not on stack then
2849          we can leave the result of this operation in acc:b
2850          combination */
2851       if ((IS_ARITHMETIC_OP (ic)
2852            || IS_CONDITIONAL(ic)
2853            || IS_BITWISE_OP (ic)
2854            || ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == CALL
2855            || (ic->op == ADDRESS_OF && isOperandOnStack (IC_LEFT (ic)))
2856           ) &&
2857           IS_ITEMP (IC_RESULT (ic)) &&
2858           getSize (operandType (IC_RESULT (ic))) <= 2)
2859
2860         packRegsForAccUse (ic);
2861     }
2862 }
2863
2864 /*-----------------------------------------------------------------*/
2865 /* assignRegisters - assigns registers to each live range as need  */
2866 /*-----------------------------------------------------------------*/
2867 void
2868 mcs51_assignRegisters (eBBlock ** ebbs, int count)
2869 {
2870   iCode *ic;
2871   int i;
2872
2873   setToNull ((void *) &_G.funcrUsed);
2874   setToNull ((void *) &_G.regAssigned);
2875   setToNull ((void *) &_G.totRegAssigned);
2876   mcs51_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
2877   mcs51_nRegs = 8;
2878
2879   /* change assignments this will remove some
2880      live ranges reducing some register pressure */
2881   
2882   for (i = 0; i < count; i++)
2883     packRegisters (ebbs, i);
2884
2885   /* liveranges probably changed by register packing
2886      so we compute them again */
2887   recomputeLiveRanges (ebbs, count);
2888
2889   if (options.dump_pack)
2890     dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
2891
2892   /* first determine for each live range the number of 
2893      registers & the type of registers required for each */
2894   regTypeNum (*ebbs);
2895
2896   /* and serially allocate registers */
2897   serialRegAssign (ebbs, count);
2898
2899   freeAllRegs ();
2900   //setToNull ((void *) &_G.regAssigned);
2901   //setToNull ((void *) &_G.totRegAssigned);
2902   fillGaps();
2903
2904   /* if stack was extended then tell the user */
2905   if (_G.stackExtend)
2906     {
2907 /*      werror(W_TOOMANY_SPILS,"stack", */
2908 /*             _G.stackExtend,currFunc->name,""); */
2909       _G.stackExtend = 0;
2910     }
2911
2912   if (_G.dataExtend)
2913     {
2914 /*      werror(W_TOOMANY_SPILS,"data space", */
2915 /*             _G.dataExtend,currFunc->name,""); */
2916       _G.dataExtend = 0;
2917     }
2918
2919   /* after that create the register mask
2920      for each of the instruction */
2921   createRegMask (ebbs, count);
2922
2923   /* redo that offsets for stacked automatic variables */
2924   if (currFunc) {
2925     redoStackOffsets ();
2926   }
2927
2928   if (options.dump_rassgn)
2929     {
2930       dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
2931       dumpLiveRanges (DUMP_LRANGE, liveRanges);
2932     }
2933
2934   /* do the overlaysegment stuff SDCCmem.c */
2935   doOverlays (ebbs, count);
2936
2937   /* now get back the chain */
2938   ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
2939
2940   gen51Code (ic);
2941
2942   /* free up any _G.stackSpil locations allocated */
2943   applyToSet (_G.stackSpil, deallocStackSpil);
2944   _G.slocNum = 0;
2945   setToNull ((void *) &_G.stackSpil);
2946   setToNull ((void *) &_G.spiltSet);
2947   /* mark all registers as free */
2948   freeAllRegs ();
2949
2950   return;
2951 }