* src/SDCCsymt.h,
[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   int j;
786
787 tryAgain:
788   /* try for a ptr type */
789   if ((reg = allocReg (REG_PTR)))
790     return reg;
791
792   /* try for gpr type */
793   if ((reg = allocReg (REG_GPR)))
794     return reg;
795
796   /* we have to spil */
797   if (!spilSomething (ic, ebp, sym))
798     return NULL;
799
800   /* make sure partially assigned registers aren't reused */
801   for (j=0; j<=sym->nRegs; j++)
802     if (sym->regs[j])
803       sym->regs[j]->isFree = 0;
804       
805   /* this looks like an infinite loop but 
806      in really selectSpil will abort  */
807   goto tryAgain;
808 }
809
810 /*-----------------------------------------------------------------*/
811 /* getRegGpr - will try for GPR if not spil                        */
812 /*-----------------------------------------------------------------*/
813 static regs *
814 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
815 {
816   regs *reg;
817   int j;
818   
819 tryAgain:
820   /* try for gpr type */
821   if ((reg = allocReg (REG_GPR)))
822     return reg;
823
824   if (!mcs51_ptrRegReq)
825     if ((reg = allocReg (REG_PTR)))
826       return reg;
827
828   /* we have to spil */
829   if (!spilSomething (ic, ebp, sym))
830     return NULL;
831
832   /* make sure partially assigned registers aren't reused */
833   for (j=0; j<=sym->nRegs; j++)
834     if (sym->regs[j])
835       sym->regs[j]->isFree = 0;
836       
837   /* this looks like an infinite loop but 
838      in really selectSpil will abort  */
839   goto tryAgain;
840 }
841
842 /*-----------------------------------------------------------------*/
843 /* getRegPtrNoSpil - get it cannot split                           */
844 /*-----------------------------------------------------------------*/
845 static regs *getRegPtrNoSpil()
846 {
847   regs *reg;
848
849   /* try for a ptr type */
850   if ((reg = allocReg (REG_PTR)))
851     return reg;
852
853   /* try for gpr type */
854   if ((reg = allocReg (REG_GPR)))
855     return reg;
856
857   assert(0);
858
859   /* just to make the compiler happy */
860   return 0;
861 }
862
863 /*-----------------------------------------------------------------*/
864 /* getRegGprNoSpil - get it cannot split                           */
865 /*-----------------------------------------------------------------*/
866 static regs *getRegGprNoSpil()
867 {
868
869   regs *reg;
870   if ((reg = allocReg (REG_GPR)))
871     return reg;
872
873   if (!mcs51_ptrRegReq)
874     if ((reg = allocReg (REG_PTR)))
875       return reg;
876
877   assert(0);
878
879   /* just to make the compiler happy */
880   return 0;
881 }
882
883 /*-----------------------------------------------------------------*/
884 /* symHasReg - symbol has a given register                         */
885 /*-----------------------------------------------------------------*/
886 static bool
887 symHasReg (symbol * sym, regs * reg)
888 {
889   int i;
890
891   for (i = 0; i < sym->nRegs; i++)
892     if (sym->regs[i] == reg)
893       return TRUE;
894
895   return FALSE;
896 }
897
898 /*-----------------------------------------------------------------*/
899 /* deassignLRs - check the live to and if they have registers & are */
900 /*               not spilt then free up the registers              */
901 /*-----------------------------------------------------------------*/
902 static void
903 deassignLRs (iCode * ic, eBBlock * ebp)
904 {
905   symbol *sym;
906   int k;
907   symbol *result;
908
909   for (sym = hTabFirstItem (liveRanges, &k); sym;
910        sym = hTabNextItem (liveRanges, &k))
911     {
912
913       symbol *psym = NULL;
914       /* if it does not end here */
915       if (sym->liveTo > ic->seq)
916         continue;
917
918       /* if it was spilt on stack then we can 
919          mark the stack spil location as free */
920       if (sym->isspilt)
921         {
922           if (sym->stackSpil)
923             {
924               sym->usl.spillLoc->isFree = 1;
925               sym->stackSpil = 0;
926             }
927           continue;
928         }
929
930       if (!bitVectBitValue (_G.regAssigned, sym->key))
931         continue;
932
933       /* special case check if this is an IFX &
934          the privious one was a pop and the 
935          previous one was not spilt then keep track
936          of the symbol */
937       if (ic->op == IFX && ic->prev &&
938           ic->prev->op == IPOP &&
939           !ic->prev->parmPush &&
940           !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
941         psym = OP_SYMBOL (IC_LEFT (ic->prev));
942
943       if (sym->nRegs)
944         {
945           int i = 0;
946
947           bitVectUnSetBit (_G.regAssigned, sym->key);
948
949           /* if the result of this one needs registers
950              and does not have it then assign it right
951              away */
952           if (IC_RESULT (ic) &&
953               !(SKIP_IC2 (ic) ||        /* not a special icode */
954                 ic->op == JUMPTABLE ||
955                 ic->op == IFX ||
956                 ic->op == IPUSH ||
957                 ic->op == IPOP ||
958                 ic->op == RETURN ||
959                 POINTER_SET (ic)) &&
960               (result = OP_SYMBOL (IC_RESULT (ic))) &&  /* has a result */
961               result->liveTo > ic->seq &&       /* and will live beyond this */
962               result->liveTo <= ebp->lSeq &&    /* does not go beyond this block */
963               result->regType == sym->regType &&        /* same register types */
964               result->nRegs &&  /* which needs registers */
965               !result->isspilt &&       /* and does not already have them */
966               !result->remat &&
967               !bitVectBitValue (_G.regAssigned, result->key) &&
968           /* the number of free regs + number of regs in this LR
969              can accomodate the what result Needs */
970               ((nfreeRegsType (result->regType) +
971                 sym->nRegs) >= result->nRegs)
972             )
973             {
974
975               for (i = 0; i < result->nRegs; i++)
976                 if (i < sym->nRegs)
977                   result->regs[i] = sym->regs[i];
978                 else
979                   result->regs[i] = getRegGpr (ic, ebp, result);
980
981               _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
982               _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, result->key);
983
984             }
985
986           /* free the remaining */
987           for (; i < sym->nRegs; i++)
988             {
989               if (psym)
990                 {
991                   if (!symHasReg (psym, sym->regs[i]))
992                     freeReg (sym->regs[i]);
993                 }
994               else
995                 freeReg (sym->regs[i]);
996             }
997         }
998     }
999 }
1000
1001
1002 /*-----------------------------------------------------------------*/
1003 /* reassignLR - reassign this to registers                         */
1004 /*-----------------------------------------------------------------*/
1005 static void
1006 reassignLR (operand * op)
1007 {
1008   symbol *sym = OP_SYMBOL (op);
1009   int i;
1010
1011   /* not spilt any more */
1012   sym->isspilt = sym->spillA = sym->blockSpil = sym->remainSpil = 0;
1013   bitVectUnSetBit (_G.spiltSet, sym->key);
1014
1015   _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1016   _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key);
1017
1018   _G.blockSpil--;
1019
1020   for (i = 0; i < sym->nRegs; i++)
1021     sym->regs[i]->isFree = 0;
1022 }
1023
1024 /*-----------------------------------------------------------------*/
1025 /* willCauseSpill - determines if allocating will cause a spill    */
1026 /*-----------------------------------------------------------------*/
1027 static int
1028 willCauseSpill (int nr, int rt)
1029 {
1030   /* first check if there are any avlb registers
1031      of te type required */
1032   if (rt == REG_PTR)
1033     {
1034       /* special case for pointer type 
1035          if pointer type not avlb then 
1036          check for type gpr */
1037       if (nFreeRegs (rt) >= nr)
1038         return 0;
1039       if (nFreeRegs (REG_GPR) >= nr)
1040         return 0;
1041     }
1042   else
1043     {
1044       if (mcs51_ptrRegReq)
1045         {
1046           if (nFreeRegs (rt) >= nr)
1047             return 0;
1048         }
1049       else
1050         {
1051           if (nFreeRegs (REG_PTR) +
1052               nFreeRegs (REG_GPR) >= nr)
1053             return 0;
1054         }
1055     }
1056
1057   /* it will cause a spil */
1058   return 1;
1059 }
1060
1061 /*-----------------------------------------------------------------*/
1062 /* positionRegs - the allocator can allocate same registers to res- */
1063 /* ult and operand, if this happens make sure they are in the same */
1064 /* position as the operand otherwise chaos results                 */
1065 /*-----------------------------------------------------------------*/
1066 static int
1067 positionRegs (symbol * result, symbol * opsym)
1068 {
1069   int count = min (result->nRegs, opsym->nRegs);
1070   int i, j = 0, shared = 0;
1071   int change = 0;
1072
1073   /* if the result has been spilt then cannot share */
1074   if (opsym->isspilt)
1075     return 0;
1076 again:
1077   shared = 0;
1078   /* first make sure that they actually share */
1079   for (i = 0; i < count; i++)
1080     {
1081       for (j = 0; j < count; j++)
1082         {
1083           if (result->regs[i] == opsym->regs[j] && i != j)
1084             {
1085               shared = 1;
1086               goto xchgPositions;
1087             }
1088         }
1089     }
1090 xchgPositions:
1091   if (shared)
1092     {
1093       regs *tmp = result->regs[i];
1094       result->regs[i] = result->regs[j];
1095       result->regs[j] = tmp;
1096       change ++;
1097       goto again;
1098     }
1099   return change;
1100 }
1101
1102
1103 /*------------------------------------------------------------------*/
1104 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
1105 /* it should either have registers or have beed spilled. Otherwise, */
1106 /* there was an uninitialized variable, so just spill this to get   */
1107 /* the operand in a valid state.                                    */
1108 /*------------------------------------------------------------------*/
1109 static void
1110 verifyRegsAssigned (operand *op, iCode * ic)
1111 {
1112   symbol * sym;
1113   
1114   if (!op) return;
1115   if (!IS_ITEMP (op)) return;
1116   
1117   sym = OP_SYMBOL (op);
1118   if (sym->isspilt) return;
1119   if (!sym->nRegs) return;
1120   if (sym->regs[0]) return;
1121   
1122   werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT, 
1123             sym->prereqv ? sym->prereqv->name : sym->name);
1124   spillThis (sym);
1125 }
1126
1127
1128
1129 /*-----------------------------------------------------------------*/
1130 /* serialRegAssign - serially allocate registers to the variables  */
1131 /*-----------------------------------------------------------------*/
1132 static void
1133 serialRegAssign (eBBlock ** ebbs, int count)
1134 {
1135     int i;
1136
1137     /* for all blocks */
1138     for (i = 0; i < count; i++) {
1139
1140         iCode *ic;
1141
1142         if (ebbs[i]->noPath &&
1143             (ebbs[i]->entryLabel != entryLabel &&
1144              ebbs[i]->entryLabel != returnLabel))
1145             continue;
1146
1147         /* of all instructions do */
1148         for (ic = ebbs[i]->sch; ic; ic = ic->next) {
1149 #if 1
1150             int reg;
1151
1152             // update the registers in use at the start of this icode
1153             for (reg=0; reg<mcs51_nRegs; reg++) {
1154               if (regs8051[reg].isFree) {
1155                 ic->riu &= ~(1<<regs8051[reg].offset);
1156               } else {
1157                 ic->riu |= (1<<regs8051[reg].offset);
1158               }
1159             }
1160 #endif
1161
1162             /* if this is an ipop that means some live
1163                range will have to be assigned again */
1164             if (ic->op == IPOP)
1165                 reassignLR (IC_LEFT (ic));
1166
1167             /* if result is present && is a true symbol */
1168             if (IC_RESULT (ic) && ic->op != IFX &&
1169                 IS_TRUE_SYMOP (IC_RESULT (ic)))
1170                 OP_SYMBOL (IC_RESULT (ic))->allocreq++;
1171
1172             /* take away registers from live
1173                ranges that end at this instruction */
1174             deassignLRs (ic, ebbs[i]);
1175
1176             /* some don't need registers */
1177             if (SKIP_IC2 (ic) ||
1178                 ic->op == JUMPTABLE ||
1179                 ic->op == IFX ||
1180                 ic->op == IPUSH ||
1181                 ic->op == IPOP ||
1182                 (IC_RESULT (ic) && POINTER_SET (ic)))
1183                 continue;
1184
1185             /* now we need to allocate registers
1186                only for the result */
1187             if (IC_RESULT (ic)) {
1188                 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
1189                 bitVect *spillable;
1190                 int willCS;
1191                 int j;
1192                 int ptrRegSet = 0;
1193
1194                 /* if it does not need or is spilt 
1195                    or is already assigned to registers
1196                    or will not live beyond this instructions */
1197                 if (!sym->nRegs ||
1198                     sym->isspilt ||
1199                     bitVectBitValue (_G.regAssigned, sym->key) ||
1200                     sym->liveTo <= ic->seq)
1201                     continue;
1202
1203                 /* if some liverange has been spilt at the block level
1204                    and this one live beyond this block then spil this
1205                    to be safe */
1206                 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq) {
1207                     spillThis (sym);
1208                     continue;
1209                 }
1210                 /* if trying to allocate this will cause
1211                    a spill and there is nothing to spill 
1212                    or this one is rematerializable then
1213                    spill this one */
1214                 willCS = willCauseSpill (sym->nRegs, sym->regType);
1215                 spillable = computeSpillable (ic);
1216                 if (sym->remat || (willCS && bitVectIsZero (spillable))) {                    
1217                     spillThis (sym);
1218                     continue;                 
1219                 }
1220
1221                 /* if it has a spillocation & is used less than
1222                    all other live ranges then spill this */
1223                 if (willCS) {
1224                     if (sym->usl.spillLoc) {
1225                         symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
1226                                                                          allLRs, ebbs[i], ic));
1227                         if (leastUsed && leastUsed->used > sym->used) {
1228                             spillThis (sym);
1229                             continue;
1230                         }
1231                     } else {
1232                         /* if none of the liveRanges have a spillLocation then better
1233                            to spill this one than anything else already assigned to registers */
1234                         if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
1235                             /* if this is local to this block then we might find a block spil */
1236                             if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
1237                                 spillThis (sym);
1238                                 continue;
1239                             }
1240                         }
1241                     }
1242                 }
1243                 /* if we need ptr regs for the right side
1244                    then mark it */
1245                 if (POINTER_GET (ic) && IS_SYMOP (IC_LEFT (ic))
1246                     && getSize (OP_SYMBOL (IC_LEFT (ic))->type) <= (unsigned int) PTRSIZE) {
1247                     mcs51_ptrRegReq++;
1248                     ptrRegSet = 1;
1249                 }
1250                 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic))
1251                     && SPEC_OCLS(OP_SYMBOL (IC_LEFT (ic))->etype) == idata) {
1252                     mcs51_ptrRegReq++;
1253                     ptrRegSet = 1;
1254                 }
1255                 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic))
1256                     && SPEC_OCLS(OP_SYMBOL (IC_RIGHT (ic))->etype) == idata) {
1257                     mcs51_ptrRegReq++;
1258                     ptrRegSet = 1;
1259                 }
1260                 
1261                 /* else we assign registers to it */
1262                 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1263                 _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key);
1264
1265                 for (j = 0; j < sym->nRegs; j++) {
1266                     if (sym->regType == REG_PTR)
1267                         sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
1268                     else
1269                         sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
1270
1271                     /* if the allocation failed which means
1272                        this was spilt then break */
1273                     if (!sym->regs[j]) {
1274                       break;
1275                     }
1276                 }
1277
1278                 if (!POINTER_SET(ic) && !POINTER_GET(ic)) {
1279                     /* if it shares registers with operands make sure
1280                        that they are in the same position */
1281                     if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
1282                         OP_SYMBOL (IC_LEFT (ic))->nRegs) {
1283                         positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1284                                       OP_SYMBOL (IC_LEFT (ic)));
1285                     }
1286                     /* do the same for the right operand */
1287                     if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
1288                         OP_SYMBOL (IC_RIGHT (ic))->nRegs) {
1289                         positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1290                                       OP_SYMBOL (IC_RIGHT (ic)));
1291                     }
1292                 }
1293
1294                 if (ptrRegSet) {
1295                     mcs51_ptrRegReq--;
1296                     ptrRegSet = 0;
1297                 }
1298
1299             }
1300         }
1301     }
1302
1303     /* Check for and fix any problems with uninitialized operands */
1304     for (i = 0; i < count; i++)
1305       {
1306         iCode *ic;
1307
1308         if (ebbs[i]->noPath &&
1309             (ebbs[i]->entryLabel != entryLabel &&
1310              ebbs[i]->entryLabel != returnLabel))
1311             continue;
1312
1313         for (ic = ebbs[i]->sch; ic; ic = ic->next)
1314           {
1315             if (SKIP_IC2 (ic))
1316               continue;
1317
1318             if (ic->op == IFX)
1319               {
1320                 verifyRegsAssigned (IC_COND (ic), ic);
1321                 continue;
1322               }
1323
1324             if (ic->op == JUMPTABLE)
1325               {
1326                 verifyRegsAssigned (IC_JTCOND (ic), ic);
1327                 continue;
1328               }
1329
1330             verifyRegsAssigned (IC_RESULT (ic), ic);
1331             verifyRegsAssigned (IC_LEFT (ic), ic);
1332             verifyRegsAssigned (IC_RIGHT (ic), ic);
1333           }
1334       }    
1335 }
1336
1337 /*-----------------------------------------------------------------*/
1338 /* fillGaps - Try to fill in the Gaps left by Pass1                */
1339 /*-----------------------------------------------------------------*/
1340 static void fillGaps()
1341 {
1342     symbol *sym =NULL;
1343     int key =0;
1344     int pass;
1345     
1346     if (getenv("DISABLE_FILL_GAPS")) return;
1347     
1348     /* look for livernages that was spilt by the allocator */
1349     for (sym = hTabFirstItem(liveRanges,&key) ; sym ; 
1350          sym = hTabNextItem(liveRanges,&key)) {
1351
1352         int i;
1353         int pdone = 0;
1354
1355         if (!sym->spillA || !sym->clashes || sym->remat) continue ;
1356
1357         /* find the liveRanges this one clashes with, that are
1358            still assigned to registers & mark the registers as used*/
1359         for ( i = 0 ; i < sym->clashes->size ; i ++) {
1360             int k;
1361             symbol *clr;
1362
1363             if (bitVectBitValue(sym->clashes,i) == 0 ||    /* those that clash with this */
1364                 bitVectBitValue(_G.totRegAssigned,i) == 0) /* and are still assigned to registers */
1365                 continue ;
1366
1367                 clr = hTabItemWithKey(liveRanges,i);
1368             assert(clr);
1369          
1370             /* mark these registers as used */
1371             for (k = 0 ; k < clr->nRegs ; k++ ) 
1372                 useReg(clr->regs[k]);
1373         }
1374
1375         if (willCauseSpill(sym->nRegs,sym->regType)) {
1376             /* NOPE :( clear all registers & and continue */
1377             freeAllRegs();
1378             continue ;
1379         }
1380
1381         D(printf("Atemping fillGaps on %s: [",sym->name));
1382         /* THERE IS HOPE !!!! */
1383         for (i=0; i < sym->nRegs ; i++ ) {
1384             if (sym->regType == REG_PTR)
1385                 sym->regs[i] = getRegPtrNoSpil ();
1386             else
1387                 sym->regs[i] = getRegGprNoSpil ();                
1388             D(printf("%s ", sym->regs[i]->name));
1389         }
1390         D(printf("]\n"));
1391
1392         /* For all its definitions check if the registers
1393            allocated needs positioning NOTE: we can position
1394            only ONCE if more than One positioning required 
1395            then give up.
1396            We may need to perform the checks twice; once to
1397            position the registers as needed, the second to
1398            verify any register repositioning is still
1399            compatible.
1400           */
1401         sym->isspilt = 0;
1402         for (pass=0; pass<2; pass++) {
1403             D(printf(" checking definitions\n"));
1404             for (i = 0 ; i < sym->defs->size ; i++ ) {
1405                 if (bitVectBitValue(sym->defs,i)) {
1406                     iCode *ic;
1407                     if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
1408                     D(printf("  ic->seq = %d\n", ic->seq));
1409                     if (SKIP_IC(ic)) continue;
1410                     assert(isSymbolEqual(sym,OP_SYMBOL(IC_RESULT(ic)))); /* just making sure */
1411                     /* if left is assigned to registers */
1412                     if (IS_SYMOP(IC_LEFT(ic)))
1413                       {
1414                         D(printf("   left = "));
1415                         D(printOperand(IC_LEFT(ic),NULL));
1416                       }
1417                     if (IS_SYMOP(IC_LEFT(ic)) && 
1418                       bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_LEFT(ic))->key)) {
1419                         pdone += (positionRegs(sym,OP_SYMBOL(IC_LEFT(ic)))>0);
1420                     }
1421                     if (IS_SYMOP(IC_RIGHT(ic)))
1422                       {
1423                         D(printf("   right = "));
1424                         D(printOperand(IC_RIGHT(ic),NULL));
1425                       }
1426                     if (IS_SYMOP(IC_RIGHT(ic)) && 
1427                       bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RIGHT(ic))->key)) {
1428                         pdone += (positionRegs(sym,OP_SYMBOL(IC_RIGHT(ic)))>0);
1429                     }
1430                     D(printf("   pdone = %d\n", pdone));
1431                     if (pdone > 1) break;
1432                 }
1433             }
1434             D(printf(" checking uses\n"));
1435             for (i = 0 ; i < sym->uses->size ; i++ ) {
1436                 if (bitVectBitValue(sym->uses,i)) {
1437                     iCode *ic;
1438                     if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
1439                     D(printf("  ic->seq = %d\n", ic->seq));
1440                     if (SKIP_IC(ic)) continue;
1441                     if (POINTER_SET(ic) || POINTER_GET(ic)) continue ;
1442
1443                     /* if result is assigned to registers */
1444                     if (IS_SYMOP(IC_RESULT(ic)))
1445                       {
1446                         D(printf("   result = "));
1447                         D(printOperand(IC_RESULT(ic),NULL));
1448                       }
1449                     if (IS_SYMOP(IC_RESULT(ic)) && 
1450                         bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RESULT(ic))->key)) {
1451                         pdone += (positionRegs(sym,OP_SYMBOL(IC_RESULT(ic)))>0);
1452                     }
1453                     D(printf("   pdone = %d\n", pdone));
1454                     if (pdone > 1) break;
1455                 }
1456             }
1457             if (pdone == 0) break; /* second pass only if regs repositioned */
1458             if (pdone > 1) break;
1459         }
1460         D(printf(" sym->regs = ["));
1461         for (i=0; i < sym->nRegs ; i++ )
1462           D(printf("%s ", sym->regs[i]->name));
1463         D(printf("]\n"));
1464         /* had to position more than once GIVE UP */
1465         if (pdone > 1) {
1466             /* UNDO all the changes we made to try this */
1467             sym->isspilt = 1;
1468             for (i=0; i < sym->nRegs ; i++ ) {
1469                     sym->regs[i] = NULL;
1470             }
1471             freeAllRegs();
1472             D(printf ("Fill Gap gave up due to positioning for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN"));
1473             continue ;      
1474         }
1475         D(printf ("FILLED GAP for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN"));
1476         _G.totRegAssigned = bitVectSetBit(_G.totRegAssigned,sym->key);
1477         sym->isspilt = sym->spillA = 0 ;
1478         sym->usl.spillLoc->allocreq--;
1479         freeAllRegs();
1480     }
1481 }
1482
1483 /*-----------------------------------------------------------------*/
1484 /* rUmaskForOp :- returns register mask for an operand             */
1485 /*-----------------------------------------------------------------*/
1486 bitVect *
1487 mcs51_rUmaskForOp (operand * op)
1488 {
1489   bitVect *rumask;
1490   symbol *sym;
1491   int j;
1492
1493   /* only temporaries are assigned registers */
1494   if (!IS_ITEMP (op))
1495     return NULL;
1496
1497   sym = OP_SYMBOL (op);
1498
1499   /* if spilt or no registers assigned to it
1500      then nothing */
1501   if (sym->isspilt || !sym->nRegs)
1502     return NULL;
1503
1504   rumask = newBitVect (mcs51_nRegs);
1505
1506   for (j = 0; j < sym->nRegs; j++)
1507     {
1508       if (sym->regs[j]) /* EEP - debug */
1509       rumask = bitVectSetBit (rumask,
1510                               sym->regs[j]->rIdx);
1511     }
1512
1513   return rumask;
1514 }
1515
1516 /*-----------------------------------------------------------------*/
1517 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
1518 /*-----------------------------------------------------------------*/
1519 static bitVect *
1520 regsUsedIniCode (iCode * ic)
1521 {
1522   bitVect *rmask = newBitVect (mcs51_nRegs);
1523
1524   /* do the special cases first */
1525   if (ic->op == IFX)
1526     {
1527       rmask = bitVectUnion (rmask,
1528                             mcs51_rUmaskForOp (IC_COND (ic)));
1529       goto ret;
1530     }
1531
1532   /* for the jumptable */
1533   if (ic->op == JUMPTABLE)
1534     {
1535       rmask = bitVectUnion (rmask,
1536                             mcs51_rUmaskForOp (IC_JTCOND (ic)));
1537
1538       goto ret;
1539     }
1540
1541   /* of all other cases */
1542   if (IC_LEFT (ic))
1543     rmask = bitVectUnion (rmask,
1544                           mcs51_rUmaskForOp (IC_LEFT (ic)));
1545
1546
1547   if (IC_RIGHT (ic))
1548     rmask = bitVectUnion (rmask,
1549                           mcs51_rUmaskForOp (IC_RIGHT (ic)));
1550
1551   if (IC_RESULT (ic))
1552     rmask = bitVectUnion (rmask,
1553                           mcs51_rUmaskForOp (IC_RESULT (ic)));
1554
1555 ret:
1556   return rmask;
1557 }
1558
1559 /*-----------------------------------------------------------------*/
1560 /* createRegMask - for each instruction will determine the regsUsed */
1561 /*-----------------------------------------------------------------*/
1562 static void
1563 createRegMask (eBBlock ** ebbs, int count)
1564 {
1565   int i;
1566
1567   /* for all blocks */
1568   for (i = 0; i < count; i++)
1569     {
1570       iCode *ic;
1571
1572       if (ebbs[i]->noPath &&
1573           (ebbs[i]->entryLabel != entryLabel &&
1574            ebbs[i]->entryLabel != returnLabel))
1575         continue;
1576
1577       /* for all instructions */
1578       for (ic = ebbs[i]->sch; ic; ic = ic->next)
1579         {
1580
1581           int j;
1582
1583           if (SKIP_IC2 (ic) || !ic->rlive)
1584             continue;
1585
1586           /* first mark the registers used in this
1587              instruction */
1588           ic->rUsed = regsUsedIniCode (ic);
1589           _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
1590
1591           /* now create the register mask for those 
1592              registers that are in use : this is a
1593              super set of ic->rUsed */
1594           ic->rMask = newBitVect (mcs51_nRegs + 1);
1595
1596           /* for all live Ranges alive at this point */
1597           for (j = 1; j < ic->rlive->size; j++)
1598             {
1599               symbol *sym;
1600               int k;
1601
1602               /* if not alive then continue */
1603               if (!bitVectBitValue (ic->rlive, j))
1604                 continue;
1605
1606               /* find the live range we are interested in */
1607               if (!(sym = hTabItemWithKey (liveRanges, j)))
1608                 {
1609                   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1610                           "createRegMask cannot find live range");
1611                   fprintf(stderr, "\tmissing live range: key=%d\n", j);
1612                   exit (0);
1613                 }
1614
1615               /* if no register assigned to it */
1616               if (!sym->nRegs || sym->isspilt)
1617                 continue;
1618
1619               /* for all the registers allocated to it */
1620               for (k = 0; k < sym->nRegs; k++)
1621                 if (sym->regs[k])
1622                   ic->rMask =
1623                     bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
1624             }
1625         }
1626     }
1627 }
1628
1629 /*-----------------------------------------------------------------*/
1630 /* rematStr - returns the rematerialized string for a remat var    */
1631 /*-----------------------------------------------------------------*/
1632 static char *
1633 rematStr (symbol * sym)
1634 {
1635   char *s = buffer;
1636   iCode *ic = sym->rematiCode;
1637
1638   while (1)
1639     {
1640
1641       /* if plus or minus print the right hand side */
1642       if (ic->op == '+' || ic->op == '-')
1643         {
1644           sprintf (s, "0x%04x %c ", (int) operandLitValue (IC_RIGHT (ic)),
1645                    ic->op);
1646           s += strlen (s);
1647           ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1648           continue;
1649         }
1650
1651       /* cast then continue */
1652       if (IS_CAST_ICODE(ic)) {
1653           ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
1654           continue;
1655       }
1656       /* we reached the end */
1657       sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
1658       break;
1659     }
1660
1661   return buffer;
1662 }
1663
1664 /*-----------------------------------------------------------------*/
1665 /* regTypeNum - computes the type & number of registers required   */
1666 /*-----------------------------------------------------------------*/
1667 static void
1668 regTypeNum (eBBlock *ebbs)
1669 {
1670   symbol *sym;
1671   int k;
1672   iCode *ic;
1673
1674   /* for each live range do */
1675   for (sym = hTabFirstItem (liveRanges, &k); sym;
1676        sym = hTabNextItem (liveRanges, &k))
1677     {
1678
1679       /* if used zero times then no registers needed */
1680       if ((sym->liveTo - sym->liveFrom) == 0)
1681         continue;
1682
1683
1684       /* if the live range is a temporary */
1685       if (sym->isitmp)
1686         {
1687
1688           /* if the type is marked as a conditional */
1689           if (sym->regType == REG_CND)
1690             continue;
1691
1692           /* if used in return only then we don't 
1693              need registers */
1694           if (sym->ruonly || sym->accuse)
1695             {
1696               if (IS_AGGREGATE (sym->type) || sym->isptr)
1697                 sym->type = aggrToPtr (sym->type, FALSE);
1698               continue;
1699             }
1700
1701           /* if the symbol has only one definition &
1702              that definition is a get_pointer */
1703           if (bitVectnBitsOn (sym->defs) == 1 &&
1704               (ic = hTabItemWithKey (iCodehTab,
1705                                      bitVectFirstBit (sym->defs))) &&
1706               POINTER_GET (ic) &&
1707               !sym->noSpilLoc &&
1708               !IS_BITVAR (sym->etype))
1709             {
1710
1711
1712               /* and that pointer is remat in data space */
1713               if (IS_SYMOP (IC_LEFT (ic)) &&
1714                   OP_SYMBOL (IC_LEFT (ic))->remat &&
1715                   !IS_CAST_ICODE(OP_SYMBOL (IC_LEFT (ic))->rematiCode) &&
1716                   DCL_TYPE (aggrToPtr (operandType(IC_LEFT(ic)), FALSE)) == POINTER)
1717                 {
1718                   /* create a psuedo symbol & force a spil */
1719                   symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
1720                   psym->type = sym->type;
1721                   psym->etype = sym->etype;
1722                   
1723                   strcpy (psym->rname, psym->name);
1724                   sym->isspilt = 1;
1725                   sym->usl.spillLoc = psym;
1726 #if 0 // an alternative fix for bug #480076
1727                   /* now this is a useless assignment to itself */
1728                   remiCodeFromeBBlock (ebbs, ic);
1729 #else
1730                   /* now this really is an assignment to itself, make it so;
1731                      it will be optimized out later */
1732                   ic->op='=';
1733                   ReplaceOpWithCheaperOp(&IC_RIGHT(ic), IC_RESULT(ic));
1734                   IC_LEFT(ic)=NULL;
1735 #endif
1736                   continue;
1737                 }
1738
1739               /* if in data space or idata space then try to
1740                  allocate pointer register */
1741
1742             }
1743
1744           /* if not then we require registers */
1745           sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
1746                         getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1747                         getSize (sym->type));
1748
1749           if (sym->nRegs > 4)
1750             {
1751               fprintf (stderr, "allocated more than 4 or 0 registers for type ");
1752               printTypeChain (sym->type, stderr);
1753               fprintf (stderr, "\n");
1754             }
1755
1756           /* determine the type of register required */
1757           if (sym->nRegs == 1 &&
1758               IS_PTR (sym->type) &&
1759               sym->uptr)
1760             sym->regType = REG_PTR;
1761           else
1762             sym->regType = REG_GPR;
1763
1764         }
1765       else
1766         /* for the first run we don't provide */
1767         /* registers for true symbols we will */
1768         /* see how things go                  */
1769         sym->nRegs = 0;
1770           }
1771
1772 }
1773
1774 /*-----------------------------------------------------------------*/
1775 /* freeAllRegs - mark all registers as free                        */
1776 /*-----------------------------------------------------------------*/
1777 static void
1778 freeAllRegs ()
1779 {
1780   int i;
1781
1782   for (i = 0; i < mcs51_nRegs; i++)
1783     regs8051[i].isFree = 1;
1784 }
1785
1786 /*-----------------------------------------------------------------*/
1787 /* deallocStackSpil - this will set the stack pointer back         */
1788 /*-----------------------------------------------------------------*/
1789 static
1790 DEFSETFUNC (deallocStackSpil)
1791 {
1792   symbol *sym = item;
1793
1794   deallocLocal (sym);
1795   return 0;
1796 }
1797
1798 /*-----------------------------------------------------------------*/
1799 /* farSpacePackable - returns the packable icode for far variables */
1800 /*-----------------------------------------------------------------*/
1801 static iCode *
1802 farSpacePackable (iCode * ic)
1803 {
1804   iCode *dic;
1805
1806   /* go thru till we find a definition for the
1807      symbol on the right */
1808   for (dic = ic->prev; dic; dic = dic->prev)
1809     {
1810       /* if the definition is a call then no */
1811       if ((dic->op == CALL || dic->op == PCALL) &&
1812           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1813         {
1814           return NULL;
1815         }
1816
1817       /* if shift by unknown amount then not */
1818       if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
1819           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1820         return NULL;
1821
1822       /* if pointer get and size > 1 */
1823       if (POINTER_GET (dic) &&
1824           getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
1825         return NULL;
1826
1827       if (POINTER_SET (dic) &&
1828           getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
1829         return NULL;
1830
1831       if (dic->op == IFX)
1832         {
1833           if (IC_COND (dic) &&
1834               IS_TRUE_SYMOP (IC_COND (dic)) &&
1835               isOperandInFarSpace (IC_COND (dic)))
1836             return NULL;
1837         }
1838       else if (dic->op == JUMPTABLE)
1839         {
1840           if (IC_JTCOND (dic) &&
1841               IS_TRUE_SYMOP (IC_JTCOND (dic)) &&
1842               isOperandInFarSpace (IC_JTCOND (dic)))
1843             return NULL;
1844         }
1845       else
1846         {
1847           /* if any three is a true symbol in far space */
1848           if (IC_RESULT (dic) &&
1849               IS_TRUE_SYMOP (IC_RESULT (dic)) &&
1850               isOperandInFarSpace (IC_RESULT (dic)))
1851             return NULL;
1852
1853           if (IC_RIGHT (dic) &&
1854               IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
1855               isOperandInFarSpace (IC_RIGHT (dic)) &&
1856               !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
1857             return NULL;
1858
1859           if (IC_LEFT (dic) &&
1860               IS_TRUE_SYMOP (IC_LEFT (dic)) &&
1861               isOperandInFarSpace (IC_LEFT (dic)) &&
1862               !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
1863             return NULL;
1864         }
1865
1866       if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
1867         {
1868           if ((dic->op == LEFT_OP ||
1869                dic->op == RIGHT_OP ||
1870                dic->op == '-') &&
1871               IS_OP_LITERAL (IC_RIGHT (dic)))
1872             return NULL;
1873           else
1874             return dic;
1875         }
1876     }
1877
1878   return NULL;
1879 }
1880
1881 /*-----------------------------------------------------------------*/
1882 /* packRegsForAssign - register reduction for assignment           */
1883 /*-----------------------------------------------------------------*/
1884 static int
1885 packRegsForAssign (iCode * ic, eBBlock * ebp)
1886 {
1887   iCode *dic, *sic;
1888
1889   if (!IS_ITEMP (IC_RIGHT (ic)) ||
1890       OP_SYMBOL (IC_RIGHT (ic))->isind ||
1891       OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
1892     {
1893       return 0;
1894     }
1895
1896
1897   /* if the true symbol is defined in far space or on stack
1898      then we should not since this will increase register pressure */
1899   if (isOperandInFarSpace(IC_RESULT(ic)) && !farSpacePackable(ic)) {
1900     return 0;
1901   }
1902
1903   /* find the definition of iTempNN scanning backwards if we find a 
1904      a use of the true symbol in before we find the definition then 
1905      we cannot */
1906   for (dic = ic->prev; dic; dic = dic->prev)
1907     {
1908
1909 #if 0 /* jwk: This collides with 1.43 but I really see no need for
1910          this anymore. It fixes bug #716790 and substantially improves 
1911          redundant register usage around function calls.
1912       */
1913
1914       /* if there is a function call then don't pack it */
1915       if ((dic->op == CALL || dic->op == PCALL))
1916         {
1917           dic = NULL;
1918           break;
1919         }
1920 #endif
1921
1922       if (SKIP_IC2 (dic))
1923         continue;
1924
1925       if (dic->op == IFX)
1926         {
1927           if (IS_SYMOP (IC_COND (dic)) &&
1928               (IC_COND (dic)->key == IC_RESULT (ic)->key ||
1929                IC_COND (dic)->key == IC_RIGHT (ic)->key))
1930             {
1931               dic = NULL;
1932               break;
1933             }
1934         }
1935       else
1936         {
1937           if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
1938               IS_OP_VOLATILE (IC_RESULT (dic)))
1939             {
1940               dic = NULL;
1941               break;
1942             }
1943
1944           if (IS_SYMOP (IC_RESULT (dic)) &&
1945               IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1946             {
1947               if (POINTER_SET (dic))
1948                 dic = NULL;
1949
1950               break;
1951             }
1952
1953           if (IS_SYMOP (IC_RIGHT (dic)) &&
1954               (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
1955                IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
1956             {
1957               dic = NULL;
1958               break;
1959             }
1960
1961           if (IS_SYMOP (IC_LEFT (dic)) &&
1962               (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
1963                IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
1964             {
1965               dic = NULL;
1966               break;
1967             }
1968
1969           if (POINTER_SET (dic) &&
1970               IC_RESULT (dic)->key == IC_RESULT (ic)->key)
1971             {
1972               dic = NULL;
1973               break;
1974             }
1975         }
1976     }
1977
1978   if (!dic)
1979     return 0;                   /* did not find */
1980
1981   /* if assignment then check that right is not a bit */
1982   if (ASSIGNMENT (dic) && !POINTER_SET (dic))
1983     {
1984       sym_link *etype = operandType (IC_RIGHT (dic));
1985       if (IS_BITFIELD (etype))
1986         {
1987           /* if result is a bit too then it's ok */
1988           etype = operandType (IC_RESULT (dic));
1989           if (!IS_BITFIELD (etype))
1990             return 0;
1991         }
1992     }
1993   /* if the result is on stack or iaccess then it must be
1994      the same atleast one of the operands */
1995   if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
1996       OP_SYMBOL (IC_RESULT (ic))->iaccess)
1997     {
1998
1999       /* the operation has only one symbol
2000          operator then we can pack */
2001       if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2002           (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2003         goto pack;
2004
2005       if (!((IC_LEFT (dic) &&
2006              IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2007             (IC_RIGHT (dic) &&
2008              IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2009         return 0;
2010     }
2011 pack:
2012   /* found the definition */
2013   /* replace the result with the result of */
2014   /* this assignment and remove this assignment */
2015   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2016   ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
2017
2018   if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2019     {
2020       OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2021     }
2022   // TODO: and the otherway around?
2023
2024   /* delete from liverange table also 
2025      delete from all the points inbetween and the new
2026      one */
2027   for (sic = dic; sic != ic; sic = sic->next)
2028     {
2029       bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2030       if (IS_ITEMP (IC_RESULT (dic)))
2031         bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2032     }
2033
2034   remiCodeFromeBBlock (ebp, ic);
2035   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2036   hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2037   OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2038   return 1;
2039 }
2040
2041 /*------------------------------------------------------------------*/
2042 /* findAssignToSym : scanning backwards looks for first assig found */
2043 /*------------------------------------------------------------------*/
2044 static iCode *
2045 findAssignToSym (operand * op, iCode * ic)
2046 {
2047   iCode *dic;
2048
2049   /* This routine is used to find sequences like
2050      iTempAA = FOO;
2051      ...;  (intervening ops don't use iTempAA or modify FOO)
2052      blah = blah + iTempAA;
2053
2054      and eliminate the use of iTempAA, freeing up its register for
2055      other uses.
2056   */
2057      
2058
2059   for (dic = ic->prev; dic; dic = dic->prev)
2060     {
2061
2062       /* if definition by assignment */
2063       if (dic->op == '=' &&
2064           !POINTER_SET (dic) &&
2065           IC_RESULT (dic)->key == op->key
2066 /*          &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2067         )
2068         break;  /* found where this temp was defined */
2069
2070       /* if we find an usage then we cannot delete it */
2071       
2072       if (dic->op == IFX)
2073         {
2074           if (IC_COND (dic) && IC_COND (dic)->key == op->key)
2075             return NULL;
2076         }
2077       else if (dic->op == JUMPTABLE)
2078         {
2079           if (IC_JTCOND (dic) && IC_JTCOND (dic)->key == op->key)
2080             return NULL;
2081         }
2082       else
2083         {
2084           if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2085             return NULL;
2086
2087           if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2088             return NULL;
2089
2090           if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2091             return NULL;
2092         }
2093     }
2094
2095   if (!dic)
2096     return NULL;   /* didn't find any assignment to op */
2097
2098   /* we are interested only if defined in far space */
2099   /* or in stack space in case of + & - */
2100   
2101   /* if assigned to a non-symbol then don't repack regs */
2102   if (!IS_SYMOP (IC_RIGHT (dic)))
2103     return NULL;
2104   
2105   /* if the symbol is volatile then we should not */
2106   if (isOperandVolatile (IC_RIGHT (dic), TRUE))
2107     return NULL;
2108   /* XXX TODO --- should we be passing FALSE to isOperandVolatile()?
2109      What does it mean for an iTemp to be volatile, anyway? Passing
2110      TRUE is more cautious but may prevent possible optimizations */
2111
2112   /* if the symbol is in far space then we should not */
2113   if (isOperandInFarSpace (IC_RIGHT (dic)))
2114     return NULL;
2115   
2116   /* for + & - operations make sure that
2117      if it is on the stack it is the same
2118      as one of the three operands */
2119   if ((ic->op == '+' || ic->op == '-') &&
2120       OP_SYMBOL (IC_RIGHT (dic))->onStack)
2121     {
2122       
2123       if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2124           IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2125           IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2126         return NULL;
2127     }
2128   
2129   /* now make sure that the right side of dic
2130      is not defined between ic & dic */
2131   if (dic)
2132     {
2133       iCode *sic = dic->next;
2134
2135       for (; sic != ic; sic = sic->next)
2136         if (IC_RESULT (sic) &&
2137             IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2138           return NULL;
2139     }
2140
2141   return dic;
2142 }
2143
2144 /*-----------------------------------------------------------------*/
2145 /* reassignAliasedSym - used by packRegsForSupport to replace      */
2146 /*                      redundant iTemp with equivalent symbol     */
2147 /*-----------------------------------------------------------------*/
2148 static void
2149 reassignAliasedSym (eBBlock *ebp, iCode *assignment, iCode *use, operand *op)
2150 {
2151   iCode *ic;
2152   unsigned oldSymKey, newSymKey;
2153
2154   oldSymKey = op->key;
2155   newSymKey = IC_RIGHT(assignment)->key;
2156
2157   /* only track live ranges of compiler-generated temporaries */
2158   if (!IS_ITEMP(IC_RIGHT(assignment)))
2159     newSymKey = 0;
2160
2161   /* update the live-value bitmaps */
2162   for (ic = assignment; ic != use; ic = ic->next) {
2163     bitVectUnSetBit (ic->rlive, oldSymKey);
2164     if (newSymKey != 0)
2165       ic->rlive = bitVectSetBit (ic->rlive, newSymKey);
2166   }
2167
2168   /* update the sym of the used operand */
2169   OP_SYMBOL(op) = OP_SYMBOL(IC_RIGHT(assignment));
2170   op->key = OP_SYMBOL(op)->key;
2171
2172   /* update the sym's liverange */
2173   if ( OP_LIVETO(op) < ic->seq )
2174     setToRange(op, ic->seq, FALSE);
2175
2176   /* remove the assignment iCode now that its result is unused */
2177   remiCodeFromeBBlock (ebp, assignment);
2178   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(assignment))->defs, assignment->key);
2179   hTabDeleteItem (&iCodehTab, assignment->key, assignment, DELETE_ITEM, NULL);
2180 }
2181   
2182
2183 /*-----------------------------------------------------------------*/
2184 /* packRegsForSupport :- reduce some registers for support calls   */
2185 /*-----------------------------------------------------------------*/
2186 static int
2187 packRegsForSupport (iCode * ic, eBBlock * ebp)
2188 {
2189   iCode *dic;
2190   
2191   /* for the left & right operand :- look to see if the
2192      left was assigned a true symbol in far space in that
2193      case replace them */
2194
2195   if (IS_ITEMP (IC_LEFT (ic)) &&
2196       OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2197     {
2198       dic = findAssignToSym (IC_LEFT (ic), ic);
2199
2200       if (dic)
2201         {
2202           /* found it we need to remove it from the block */
2203           reassignAliasedSym (ebp, dic, ic, IC_LEFT(ic));
2204           return 1;
2205         }
2206     }
2207
2208   /* do the same for the right operand */
2209   if (IS_ITEMP (IC_RIGHT (ic)) &&
2210       OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2211     {
2212       iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2213
2214       if (dic)
2215         {
2216           /* if this is a subtraction & the result
2217              is a true symbol in far space then don't pack */
2218           if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
2219             {
2220               sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
2221               if (IN_FARSPACE (SPEC_OCLS (etype)))
2222                 return 0;
2223             }
2224           /* found it we need to remove it from the
2225              block */
2226           reassignAliasedSym (ebp, dic, ic, IC_RIGHT(ic));
2227           
2228           return 1;
2229         }
2230     }
2231
2232   return 0;
2233 }
2234
2235 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
2236
2237
2238 /*-----------------------------------------------------------------*/
2239 /* packRegsForOneuse : - will reduce some registers for single Use */
2240 /*-----------------------------------------------------------------*/
2241 static iCode *
2242 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
2243 {
2244   bitVect *uses;
2245   iCode *dic, *sic;
2246
2247   /* if returning a literal then do nothing */
2248   if (!IS_SYMOP (op))
2249     return NULL;
2250
2251   /* only upto 2 bytes since we cannot predict
2252      the usage of b, & acc */
2253   if (getSize (operandType (op)) > (fReturnSizeMCS51 - 2))
2254     return NULL;
2255
2256   if (ic->op != RETURN &&
2257       ic->op != SEND &&
2258       !POINTER_SET (ic) &&
2259       !POINTER_GET (ic))
2260     return NULL;
2261   
2262   if (ic->op == SEND && ic->argreg != 1) return NULL;
2263
2264   /* this routine will mark the a symbol as used in one 
2265      instruction use only && if the defintion is local 
2266      (ie. within the basic block) && has only one definition &&
2267      that definiion is either a return value from a 
2268      function or does not contain any variables in
2269      far space */
2270   uses = bitVectCopy (OP_USES (op));
2271   bitVectUnSetBit (uses, ic->key);      /* take away this iCode */
2272   if (!bitVectIsZero (uses))    /* has other uses */
2273     return NULL;
2274
2275   /* if it has only one defintion */
2276   if (bitVectnBitsOn (OP_DEFS (op)) > 1)
2277     return NULL;                /* has more than one definition */
2278
2279   /* get that definition */
2280   if (!(dic =
2281         hTabItemWithKey (iCodehTab,
2282                          bitVectFirstBit (OP_DEFS (op)))))
2283     return NULL;
2284
2285   /* if that only usage is a cast */
2286   if (dic->op == CAST) {
2287     /* to a bigger type */
2288     if (getSize(OP_SYM_TYPE(IC_RESULT(dic))) > 
2289         getSize(OP_SYM_TYPE(IC_RIGHT(dic)))) {
2290       /* than we can not, since we cannot predict the usage of b & acc */
2291       return NULL;
2292     }
2293   }
2294
2295   /* found the definition now check if it is local */
2296   if (dic->seq < ebp->fSeq ||
2297       dic->seq > ebp->lSeq)
2298     return NULL;                /* non-local */
2299
2300   /* now check if it is the return from
2301      a function call */
2302   if (dic->op == CALL || dic->op == PCALL)
2303     {
2304       if (ic->op != SEND && ic->op != RETURN &&
2305           !POINTER_SET(ic) && !POINTER_GET(ic))
2306         {
2307           OP_SYMBOL (op)->ruonly = 1;
2308           return dic;
2309         }
2310       dic = dic->next;
2311     }
2312
2313
2314   /* otherwise check that the definition does
2315      not contain any symbols in far space */
2316   if (isOperandInFarSpace (IC_LEFT (dic)) ||
2317       isOperandInFarSpace (IC_RIGHT (dic)) ||
2318       IS_OP_RUONLY (IC_LEFT (ic)) ||
2319       IS_OP_RUONLY (IC_RIGHT (ic)))
2320     {
2321       return NULL;
2322     }
2323
2324   /* if pointer set then make sure the pointer
2325      is one byte */
2326   if (POINTER_SET (dic) &&
2327       !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2328     return NULL;
2329
2330   if (POINTER_GET (dic) &&
2331       !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2332     return NULL;
2333
2334   sic = dic;
2335
2336   /* also make sure the intervenening instructions
2337      don't have any thing in far space */
2338   for (dic = dic->next; dic && dic != ic && sic != ic; dic = dic->next)
2339     {
2340
2341       /* if there is an intervening function call then no */
2342       if (dic->op == CALL || dic->op == PCALL)
2343         return NULL;
2344       /* if pointer set then make sure the pointer
2345          is one byte */
2346       if (POINTER_SET (dic) &&
2347           !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2348         return NULL;
2349
2350       if (POINTER_GET (dic) &&
2351           !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2352         return NULL;
2353
2354       /* if address of & the result is remat the okay */
2355       if (dic->op == ADDRESS_OF &&
2356           OP_SYMBOL (IC_RESULT (dic))->remat)
2357         continue;
2358
2359       /* if operand has size of three or more & this
2360          operation is a '*','/' or '%' then 'b' may
2361          cause a problem */
2362       if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
2363           getSize (operandType (op)) >= 3)
2364         return NULL;
2365
2366       /* if left or right or result is in far space */
2367       if (isOperandInFarSpace (IC_LEFT (dic)) ||
2368           isOperandInFarSpace (IC_RIGHT (dic)) ||
2369           isOperandInFarSpace (IC_RESULT (dic)) ||
2370           IS_OP_RUONLY (IC_LEFT (dic)) ||
2371           IS_OP_RUONLY (IC_RIGHT (dic)) ||
2372           IS_OP_RUONLY (IC_RESULT (dic)))
2373         {
2374           return NULL;
2375         }
2376       /* if left or right or result is on stack */
2377       if (isOperandOnStack(IC_LEFT(dic)) ||
2378           isOperandOnStack(IC_RIGHT(dic)) ||
2379           isOperandOnStack(IC_RESULT(dic))) {
2380         return NULL;
2381       }
2382     }
2383
2384   OP_SYMBOL (op)->ruonly = 1;
2385   return sic;
2386 }
2387
2388 /*-----------------------------------------------------------------*/
2389 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
2390 /*-----------------------------------------------------------------*/
2391 static bool
2392 isBitwiseOptimizable (iCode * ic)
2393 {
2394   sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
2395   sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
2396
2397   /* bitwise operations are considered optimizable
2398      under the following conditions (Jean-Louis VERN) 
2399
2400      x & lit
2401      bit & bit
2402      bit & x
2403      bit ^ bit
2404      bit ^ x
2405      x   ^ lit
2406      x   | lit
2407      bit | bit
2408      bit | x
2409   */
2410   if (IS_LITERAL(rtype) ||
2411       (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
2412     return TRUE;
2413   else
2414     return FALSE;
2415 }
2416
2417 /*-----------------------------------------------------------------*/
2418 /* isCommutativeOp - tests whether this op cares what order its    */
2419 /*                   operands are in                               */
2420 /*-----------------------------------------------------------------*/
2421 bool isCommutativeOp(unsigned int op)
2422 {
2423   if (op == '+' || op == '*' || op == EQ_OP ||
2424       op == '^' || op == '|' || op == BITWISEAND)
2425     return TRUE;
2426   else
2427     return FALSE;
2428 }
2429
2430 /*-----------------------------------------------------------------*/
2431 /* operandUsesAcc - determines whether the code generated for this */
2432 /*                  operand will have to use the accumulator       */
2433 /*-----------------------------------------------------------------*/
2434 bool operandUsesAcc(operand *op)
2435 {
2436   if (!op)
2437     return FALSE;
2438
2439   if (IS_SYMOP(op)) {
2440     symbol *sym = OP_SYMBOL(op);
2441     memmap *symspace;
2442
2443     if (sym->accuse)
2444       return TRUE;  /* duh! */
2445
2446     if (IN_STACK(sym->etype) || sym->onStack ||
2447         (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
2448       return TRUE;  /* acc is used to calc stack offset */
2449
2450     if (IS_ITEMP(op))
2451       {
2452         if (SPIL_LOC(op)) {
2453           sym = SPIL_LOC(op);  /* if spilled, look at spill location */
2454         } else {
2455           return FALSE;  /* more checks? */
2456         }
2457       }
2458
2459     symspace = SPEC_OCLS(sym->etype);
2460
2461     if (sym->iaccess && symspace->paged)
2462       return TRUE;  /* must fetch paged indirect sym via accumulator */
2463     
2464     if (IN_BITSPACE(symspace))
2465       return TRUE;  /* fetching bit vars uses the accumulator */
2466     
2467     if (IN_FARSPACE(symspace) || IN_CODESPACE(symspace)) 
2468       return TRUE;  /* fetched via accumulator and dptr */
2469   }
2470
2471   return FALSE;
2472 }
2473
2474 /*-----------------------------------------------------------------*/
2475 /* packRegsForAccUse - pack registers for acc use                  */
2476 /*-----------------------------------------------------------------*/
2477 static void
2478 packRegsForAccUse (iCode * ic)
2479 {
2480   iCode *uic;
2481
2482   /* if this is an aggregate, e.g. a one byte char array */
2483   if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
2484     return;
2485   }
2486
2487   /* if we are calling a reentrant function that has stack parameters */
2488   if (ic->op == CALL &&
2489        IFFUNC_ISREENT(operandType(IC_LEFT(ic))) &&
2490        FUNC_HASSTACKPARM(operandType(IC_LEFT(ic))))
2491       return;
2492
2493   if (ic->op == PCALL &&
2494        IFFUNC_ISREENT(operandType(IC_LEFT(ic))->next) &&
2495        FUNC_HASSTACKPARM(operandType(IC_LEFT(ic))->next))
2496       return;
2497
2498   /* if + or - then it has to be one byte result */
2499   if ((ic->op == '+' || ic->op == '-')
2500       && getSize (operandType (IC_RESULT (ic))) > 1)
2501     return;
2502
2503   /* if shift operation make sure right side is not a literal */
2504   if (ic->op == RIGHT_OP &&
2505       (isOperandLiteral (IC_RIGHT (ic)) ||
2506        getSize (operandType (IC_RESULT (ic))) > 1))
2507     return;
2508
2509   if (ic->op == LEFT_OP &&
2510       (isOperandLiteral (IC_RIGHT (ic)) ||
2511        getSize (operandType (IC_RESULT (ic))) > 1))
2512     return;
2513
2514   if (IS_BITWISE_OP (ic) &&
2515       getSize (operandType (IC_RESULT (ic))) > 1)
2516     return;
2517
2518
2519   /* has only one definition */
2520   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
2521     return;
2522
2523   /* has only one use */
2524   if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
2525     return;
2526
2527   /* and the usage immediately follows this iCode */
2528   if (!(uic = hTabItemWithKey (iCodehTab,
2529                                bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
2530     return;
2531
2532   if (ic->next != uic)
2533     return;
2534
2535   /* if it is a conditional branch then we definitely can */
2536   if (uic->op == IFX)
2537     goto accuse;
2538
2539   if (uic->op == JUMPTABLE)
2540     return;
2541
2542   if (POINTER_SET (uic) &&
2543       getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
2544     return;
2545
2546   /* if the usage is not is an assignment
2547      or an arithmetic / bitwise / shift operation then not */
2548   if (uic->op != '=' &&
2549       !IS_ARITHMETIC_OP (uic) &&
2550       !IS_BITWISE_OP (uic) &&
2551       uic->op != LEFT_OP &&
2552       uic->op != RIGHT_OP)
2553     return;
2554
2555   /* if used in ^ operation then make sure right is not a 
2556      literal (WIML: Why is this?) */
2557   if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
2558     return;
2559
2560   /* if shift operation make sure right side is not a literal */
2561   /* WIML: Why is this? */
2562   if (uic->op == RIGHT_OP &&
2563       (isOperandLiteral (IC_RIGHT (uic)) ||
2564        getSize (operandType (IC_RESULT (uic))) > 1))
2565     return;
2566   if (uic->op == LEFT_OP &&
2567       (isOperandLiteral (IC_RIGHT (uic)) ||
2568        getSize (operandType (IC_RESULT (uic))) > 1))
2569     return;
2570
2571   /* make sure that the result of this icode is not on the
2572      stack, since acc is used to compute stack offset */
2573 #if 0
2574   if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
2575       OP_SYMBOL (IC_RESULT (uic))->onStack)
2576     return;
2577 #else
2578   if (isOperandOnStack(IC_RESULT(uic)))
2579     return;
2580 #endif
2581
2582   /* if the usage has only one operand then we can */
2583   if (IC_LEFT (uic) == NULL ||
2584       IC_RIGHT (uic) == NULL)
2585     goto accuse;
2586
2587   /* if the other operand uses the accumulator then we cannot */
2588   if ( (IC_LEFT(uic)->key == IC_RESULT(ic)->key &&
2589         operandUsesAcc(IC_RIGHT(uic))) ||
2590        (IC_RIGHT(uic)->key == IC_RESULT(ic)->key &&
2591         operandUsesAcc(IC_LEFT(uic))) ) 
2592     return;
2593
2594   /* make sure this is on the left side if not commutative */
2595   /* except for '-', which has been written to be able to
2596      handle reversed operands */
2597   if (!(isCommutativeOp(ic->op) || ic->op == '-') &&
2598        IC_LEFT (uic)->key != IC_RESULT (ic)->key)
2599     return;
2600
2601 #if 0
2602   // this is too dangerous and need further restrictions
2603   // see bug #447547
2604
2605   /* if one of them is a literal then we can */
2606   if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
2607       (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
2608     {
2609       OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2610       return;
2611     }
2612 #endif
2613
2614 accuse:
2615   OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2616
2617 }
2618
2619 /*-----------------------------------------------------------------*/
2620 /* packForPush - hueristics to reduce iCode for pushing            */
2621 /*-----------------------------------------------------------------*/
2622 static void
2623 packForPush (iCode * ic, eBBlock ** ebpp, int blockno)
2624 {
2625   iCode *dic, *lic;
2626   bitVect *dbv;
2627   struct eBBlock * ebp=ebpp[blockno];
2628
2629   if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
2630     return;
2631
2632   /* must have only definition & one usage */
2633   if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
2634       bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
2635     return;
2636
2637   /* find the definition */
2638   if (!(dic = hTabItemWithKey (iCodehTab,
2639                                bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
2640     return;
2641
2642   if (dic->op != '=' || POINTER_SET (dic))
2643     return;
2644
2645   if (dic->seq < ebp->fSeq) { // Evelyn did this
2646     int i;
2647     for (i=0; i<blockno; i++) {
2648       if (dic->seq >= ebpp[i]->fSeq && dic->seq <= ebpp[i]->lSeq) {
2649         ebp=ebpp[i];
2650         break;
2651       }
2652     }
2653     wassert (i!=blockno); // no way to recover from here
2654   }
2655
2656   if (IS_SYMOP(IC_RIGHT(dic))) {
2657     /* make sure the right side does not have any definitions
2658        inbetween */
2659     dbv = OP_DEFS(IC_RIGHT(dic));
2660     for (lic = ic; lic && lic != dic ; lic = lic->prev) {
2661       if (bitVectBitValue(dbv,lic->key)) 
2662         return ;
2663     }
2664     /* make sure they have the same type */
2665     if (IS_SPEC(operandType(IC_LEFT(ic))))
2666     {
2667       sym_link *itype=operandType(IC_LEFT(ic));
2668       sym_link *ditype=operandType(IC_RIGHT(dic));
2669       
2670       if (SPEC_USIGN(itype)!=SPEC_USIGN(ditype) ||
2671           SPEC_LONG(itype)!=SPEC_LONG(ditype))
2672         return;
2673     }
2674     /* extend the live range of replaced operand if needed */
2675     if (OP_SYMBOL(IC_RIGHT(dic))->liveTo < ic->seq) {
2676       OP_SYMBOL(IC_RIGHT(dic))->liveTo = ic->seq;
2677     }
2678     bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2679   } 
2680
2681   /* we now we know that it has one & only one def & use
2682      and the that the definition is an assignment */
2683   ReplaceOpWithCheaperOp(&IC_LEFT (ic), IC_RIGHT (dic));
2684   remiCodeFromeBBlock (ebp, dic);
2685   hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2686 }
2687
2688 /*-----------------------------------------------------------------*/
2689 /* packRegisters - does some transformations to reduce register    */
2690 /*                   pressure                                      */
2691 /*-----------------------------------------------------------------*/
2692 static void
2693 packRegisters (eBBlock ** ebpp, int blockno)
2694 {
2695   iCode *ic;
2696   int change = 0;
2697   eBBlock *ebp=ebpp[blockno];
2698
2699   while (1)
2700     {
2701
2702       change = 0;
2703
2704       /* look for assignments of the form */
2705       /* iTempNN = TRueSym (someoperation) SomeOperand */
2706       /*       ....                       */
2707       /* TrueSym := iTempNN:1             */
2708       for (ic = ebp->sch; ic; ic = ic->next)
2709         {
2710           /* find assignment of the form TrueSym := iTempNN:1 */
2711           if (ic->op == '=' && !POINTER_SET (ic))
2712             change += packRegsForAssign (ic, ebp);
2713         }
2714
2715       if (!change)
2716         break;
2717     }
2718
2719   for (ic = ebp->sch; ic; ic = ic->next)
2720     {
2721       /* if this is an itemp & result of an address of a true sym 
2722          then mark this as rematerialisable   */
2723       if (ic->op == ADDRESS_OF &&
2724           IS_ITEMP (IC_RESULT (ic)) &&
2725           IS_TRUE_SYMOP (IC_LEFT (ic)) &&
2726           bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2727           !OP_SYMBOL (IC_LEFT (ic))->onStack)
2728         {
2729
2730           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2731           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2732           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2733
2734         }
2735
2736       /* if straight assignment then carry remat flag if
2737          this is the only definition */
2738       if (ic->op == '=' &&
2739           !POINTER_SET (ic) &&
2740           IS_SYMOP (IC_RIGHT (ic)) &&
2741           OP_SYMBOL (IC_RIGHT (ic))->remat &&
2742           !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode) &&
2743           bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
2744         {
2745
2746           OP_SYMBOL (IC_RESULT (ic))->remat =
2747             OP_SYMBOL (IC_RIGHT (ic))->remat;
2748           OP_SYMBOL (IC_RESULT (ic))->rematiCode =
2749             OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
2750         }
2751
2752       /* if cast to a generic pointer & the pointer being
2753          cast is remat, then we can remat this cast as well */
2754       if (ic->op == CAST && 
2755           IS_SYMOP(IC_RIGHT(ic)) &&
2756           OP_SYMBOL(IC_RIGHT(ic))->remat &&
2757           bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1) {
2758               sym_link *to_type = operandType(IC_LEFT(ic));
2759               sym_link *from_type = operandType(IC_RIGHT(ic));
2760               if (IS_GENPTR(to_type) && IS_PTR(from_type)) {                  
2761                       OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2762                       OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2763                       OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2764               }
2765       }
2766
2767       /* if this is a +/- operation with a rematerizable 
2768          then mark this as rematerializable as well */
2769       if ((ic->op == '+' || ic->op == '-') &&
2770           (IS_SYMOP (IC_LEFT (ic)) &&
2771            IS_ITEMP (IC_RESULT (ic)) &&
2772            IS_OP_LITERAL (IC_RIGHT (ic))) &&
2773            OP_SYMBOL (IC_LEFT (ic))->remat &&
2774           (!IS_SYMOP (IC_RIGHT (ic)) || !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode)) &&
2775            bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1)
2776         {
2777           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2778           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2779           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2780         }
2781
2782       /* mark the pointer usages */
2783       if (POINTER_SET (ic))
2784         OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
2785
2786       if (POINTER_GET (ic) &&
2787           IS_SYMOP(IC_LEFT (ic)))
2788         OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
2789
2790       if (!SKIP_IC2 (ic))
2791         {
2792           /* if we are using a symbol on the stack
2793              then we should say mcs51_ptrRegReq */
2794           if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
2795             mcs51_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
2796                                  OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
2797           else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
2798             mcs51_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
2799                               OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
2800           else
2801             {
2802               if (IS_SYMOP (IC_LEFT (ic)))
2803                 mcs51_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
2804                                 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
2805               if (IS_SYMOP (IC_RIGHT (ic)))
2806                 mcs51_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
2807                                OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
2808               if (IS_SYMOP (IC_RESULT (ic)))
2809                 mcs51_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
2810                               OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
2811             }
2812         }
2813
2814       /* if the condition of an if instruction
2815          is defined in the previous instruction and
2816          this is the only usage then
2817          mark the itemp as a conditional */
2818       if ((IS_CONDITIONAL (ic) ||
2819            (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic))) &&
2820           ic->next && ic->next->op == IFX &&
2821           bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
2822           isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
2823           OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2824         {
2825           OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
2826           continue;
2827         }
2828
2829       /* reduce for support function calls */
2830       if (ic->supportRtn || ic->op == '+' || ic->op == '-')
2831         packRegsForSupport (ic, ebp);
2832
2833       /* some cases the redundant moves can
2834          can be eliminated for return statements */
2835       if ((ic->op == RETURN || (ic->op == SEND && ic->argreg == 1)) &&
2836           !isOperandInFarSpace (IC_LEFT (ic)) &&
2837           options.model == MODEL_SMALL) {
2838         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2839       }
2840
2841       /* if pointer set & left has a size more than
2842          one and right is not in far space */
2843       if (POINTER_SET (ic) &&
2844           !isOperandInFarSpace (IC_RIGHT (ic)) &&
2845           !OP_SYMBOL (IC_RESULT (ic))->remat &&
2846           !IS_OP_RUONLY (IC_RIGHT (ic)) &&
2847           getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
2848         packRegsForOneuse (ic, IC_RESULT (ic), ebp);
2849
2850       /* if pointer get */
2851       if (POINTER_GET (ic) &&
2852           IS_SYMOP (IC_LEFT (ic)) &&
2853           !isOperandInFarSpace (IC_RESULT (ic)) &&
2854           !OP_SYMBOL (IC_LEFT (ic))->remat &&
2855           !IS_OP_RUONLY (IC_RESULT (ic)) &&
2856           getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
2857         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2858
2859
2860       /* if this is cast for intergral promotion then
2861          check if only use of  the definition of the 
2862          operand being casted/ if yes then replace
2863          the result of that arithmetic operation with 
2864          this result and get rid of the cast */
2865       if (ic->op == CAST)
2866         {
2867           sym_link *fromType = operandType (IC_RIGHT (ic));
2868           sym_link *toType = operandType (IC_LEFT (ic));
2869
2870           if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
2871               getSize (fromType) != getSize (toType) &&
2872               SPEC_USIGN (fromType) == SPEC_USIGN (toType))
2873             {
2874
2875               iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2876               if (dic)
2877                 {
2878                   if (IS_ARITHMETIC_OP (dic))
2879                     {                  
2880                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2881                       ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
2882                       remiCodeFromeBBlock (ebp, ic);
2883                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2884                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2885                       OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2886                       ic = ic->prev;
2887                     }
2888                   else
2889                     OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
2890                 }
2891             }
2892           else
2893             {
2894
2895               /* if the type from and type to are the same
2896                  then if this is the only use then packit */
2897               if (compareType (operandType (IC_RIGHT (ic)),
2898                              operandType (IC_LEFT (ic))) == 1)
2899                 {
2900                   iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2901                   if (dic)
2902                     {
2903                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2904                       ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
2905                       remiCodeFromeBBlock (ebp, ic);
2906                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2907                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2908                       OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2909                       ic = ic->prev;
2910                     }
2911                 }
2912             }
2913         }
2914
2915       /* pack for PUSH 
2916          iTempNN := (some variable in farspace) V1
2917          push iTempNN ;
2918          -------------
2919          push V1
2920        */
2921       if (ic->op == IPUSH)
2922         {
2923           packForPush (ic, ebpp, blockno);
2924         }
2925
2926
2927       /* pack registers for accumulator use, when the
2928          result of an arithmetic or bit wise operation
2929          has only one use, that use is immediately following
2930          the defintion and the using iCode has only one
2931          operand or has two operands but one is literal &
2932          the result of that operation is not on stack then
2933          we can leave the result of this operation in acc:b
2934          combination */
2935       if ((IS_ARITHMETIC_OP (ic)
2936            || IS_CONDITIONAL(ic)
2937            || IS_BITWISE_OP (ic)
2938            || ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == CALL
2939            || (ic->op == ADDRESS_OF && isOperandOnStack (IC_LEFT (ic)))
2940           ) &&
2941           IS_ITEMP (IC_RESULT (ic)) &&
2942           getSize (operandType (IC_RESULT (ic))) <= 2)
2943
2944         packRegsForAccUse (ic);
2945     }
2946 }
2947
2948 /*-----------------------------------------------------------------*/
2949 /* assignRegisters - assigns registers to each live range as need  */
2950 /*-----------------------------------------------------------------*/
2951 void
2952 mcs51_assignRegisters (eBBlock ** ebbs, int count)
2953 {
2954   iCode *ic;
2955   int i;
2956
2957   setToNull ((void *) &_G.funcrUsed);
2958   setToNull ((void *) &_G.regAssigned);
2959   setToNull ((void *) &_G.totRegAssigned);
2960   mcs51_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
2961   mcs51_nRegs = 8;
2962
2963   /* change assignments this will remove some
2964      live ranges reducing some register pressure */
2965   
2966   for (i = 0; i < count; i++)
2967     packRegisters (ebbs, i);
2968
2969   /* liveranges probably changed by register packing
2970      so we compute them again */
2971   recomputeLiveRanges (ebbs, count);
2972
2973   if (options.dump_pack)
2974     dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
2975
2976   /* first determine for each live range the number of 
2977      registers & the type of registers required for each */
2978   regTypeNum (*ebbs);
2979
2980   /* and serially allocate registers */
2981   serialRegAssign (ebbs, count);
2982
2983   freeAllRegs ();
2984   //setToNull ((void *) &_G.regAssigned);
2985   //setToNull ((void *) &_G.totRegAssigned);
2986   fillGaps();
2987
2988   /* if stack was extended then tell the user */
2989   if (_G.stackExtend)
2990     {
2991 /*      werror(W_TOOMANY_SPILS,"stack", */
2992 /*             _G.stackExtend,currFunc->name,""); */
2993       _G.stackExtend = 0;
2994     }
2995
2996   if (_G.dataExtend)
2997     {
2998 /*      werror(W_TOOMANY_SPILS,"data space", */
2999 /*             _G.dataExtend,currFunc->name,""); */
3000       _G.dataExtend = 0;
3001     }
3002
3003   /* after that create the register mask
3004      for each of the instruction */
3005   createRegMask (ebbs, count);
3006
3007   /* redo that offsets for stacked automatic variables */
3008   if (currFunc) {
3009     redoStackOffsets ();
3010   }
3011
3012   if (options.dump_rassgn)
3013     {
3014       dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3015       dumpLiveRanges (DUMP_LRANGE, liveRanges);
3016     }
3017
3018   /* do the overlaysegment stuff SDCCmem.c */
3019   doOverlays (ebbs, count);
3020
3021   /* now get back the chain */
3022   ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3023
3024   gen51Code (ic);
3025
3026   /* free up any _G.stackSpil locations allocated */
3027   applyToSet (_G.stackSpil, deallocStackSpil);
3028   _G.slocNum = 0;
3029   setToNull ((void *) &_G.stackSpil);
3030   setToNull ((void *) &_G.spiltSet);
3031   /* mark all registers as free */
3032   freeAllRegs ();
3033
3034   return;
3035 }