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