* src/SDCCicode.h,
[fw/sdcc] / src / xa51 / ralloc.c
1 /* This port is in development, UNSTABLE, DEVELOPERS ONLY! */
2
3 /* idea:
4    R0-^-R2(R0L-R2H) used for scratch (byte, word, pointer)
5    R3L-^-R6H used for bytes
6    R6-v-R4 used for ptr
7    R15/R6-v-R4 used for words
8    
9    R7 used for stack
10 */
11
12 /*------------------------------------------------------------------------
13   
14   SDCCralloc.c - source file for register allocation. (xa51) specific
15   
16   Written By -  
17   
18   This program is free software; you can redistribute it and/or modify it
19   under the terms of the GNU General Public License as published by the
20   Free Software Foundation; either version 2, or (at your option) any
21   later version.
22   
23   This program is distributed in the hope that it will be useful,
24   but WITHOUT ANY WARRANTY; without even the implied warranty of
25   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26   GNU General Public License for more details.
27   
28   You should have received a copy of the GNU General Public License
29   along with this program; if not, write to the Free Software
30   Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31   
32   In other words, you are welcome to use, share and improve this program.
33   You are forbidden to forbid anyone else to use, share and improve
34   what you give them.   Help stamp out software-hoarding!  
35   -------------------------------------------------------------------------*/
36
37 #include "common.h"
38 #include "ralloc.h"
39 #include "gen.h"
40
41 extern void genXA51Code (iCode *);
42
43 #define D0(x) 
44 #define D1(x) x
45 #define D2(x) x
46
47 /* Global data */
48 static struct
49 {
50   bitVect *spiltSet;
51   set *stackSpil;
52   bitVect *regAssigned;
53   bitVect *totRegAssigned;    /* final set of LRs that got into registers */
54   short blockSpil;
55   int slocNum;
56   bitVect *funcrUsed;           /* registers used in a function */
57   int stackExtend;
58 }
59 _G;
60
61 /* xa51 registers */
62 regs regsXA51[]={
63   // index size type name regMask isFree symbol
64   {R0L_ID, 1, REG_SCR, "r0l", 0x0001, 1, NULL}, // r0l used for scratch
65   {R0H_ID, 1, REG_SCR, "r0h", 0x0002, 1, NULL}, // r0h used for scratch
66   {R1L_ID, 1, REG_SCR, "r1l", 0x0004, 1, NULL}, // r1l used for scratch
67   {R1H_ID, 1, REG_SCR, "r1h", 0x0008, 1, NULL}, // r1h used for scratch
68   {R2L_ID, 1, REG_PTR, "r2l", 0x0010, 1, NULL},
69   {R2H_ID, 1, REG_PTR, "r2h", 0x0020, 1, NULL},
70   {R3L_ID, 1, REG_PTR, "r3l", 0x0040, 1, NULL},
71   {R3H_ID, 1, REG_PTR, "r3h", 0x0080, 1, NULL},
72   {R4L_ID, 1, REG_PTR, "r4l", 0x0100, 1, NULL},
73   {R4H_ID, 1, REG_PTR, "r4h", 0x0200, 1, NULL},
74   {R5L_ID, 1, REG_PTR, "r5l", 0x0400, 1, NULL},
75   {R5H_ID, 1, REG_PTR, "r5h", 0x0800, 1, NULL},
76   {R6L_ID, 1, REG_PTR, "r6l", 0x1000, 1, NULL},
77   {R6H_ID, 1, REG_PTR, "r6h", 0x2000, 1, NULL},
78   {R7L_ID, 1, REG_STK, "r7l", 0x4000, 1, NULL}, // r7=SP
79   {R7H_ID, 1, REG_STK, "r7h", 0x8000, 1, NULL}, // r7=SP
80
81   {R0_ID, 2, REG_SCR, "r0",  0x0003, 1, NULL}, // r0 used for scratch
82   {R1_ID, 2, REG_SCR, "r1",  0x000c, 1, NULL}, // r1 used for scratch
83   {R2_ID, 2, REG_PTR, "r2",  0x0030, 1, NULL}, 
84   {R3_ID, 2, REG_PTR, "r3",  0x00c0, 1, NULL},
85   {R4_ID, 2, REG_PTR, "r4",  0x0300, 1, NULL}, 
86   {R5_ID, 2, REG_PTR, "r5",  0x0c00, 1, NULL}, 
87   {R6_ID, 2, REG_PTR, "r6",  0x3000, 1, NULL}, 
88   {R7_ID, 2, REG_STK, "r7",  0xc000, 1, NULL}, // r7=SP
89 #if 0 // some derivates have even more! (only bit/word access no ptr use)
90   {R8_ID, 2, REG_GPR, "r8",  0x010000, 1, NULL},
91   {R9_ID, 2, REG_GPR, "r9",  0x020000, 1, NULL},
92   {R10_ID, 2, REG_GPR, "r10", 0x040000, 1, NULL},
93   {R11_ID, 2, REG_GPR, "r11", 0x080000, 1, NULL},
94   {R12_ID, 2, REG_GPR, "r12", 0x100000, 1, NULL},
95   {R13_ID, 2, REG_GPR, "r13", 0x200000, 1, NULL},
96   {R14_ID, 2, REG_GPR, "r14", 0x400000, 1, NULL},
97   {R15_ID, 2, REG_GPR, "r15", 0x800000, 1, NULL},
98 #endif
99   {R0R1_ID, 4, REG_GPR, "(r0,r1)", 0x000f, 1, NULL},
100   {R2R3_ID, 4, REG_GPR, "(r2,r3)", 0x00f0, 1, NULL},
101   {R4R5_ID, 4, REG_GPR, "(r4,r5)", 0x0f00, 1, NULL},
102   {R6R7_ID, 4, REG_GPR, "(r6,r7)", 0xf000, 1, NULL},
103 };
104
105 int xa51_nRegs=sizeof(regsXA51)/sizeof(regs);
106
107 // the currently in use registers
108 unsigned long xa51RegsInUse=0;
109
110 // this should be set with a command line switch
111 bool xa51HasGprRegs=0;
112
113 /*-----------------------------------------------------------------*/
114 /* xa51_regWithMask - returns pointer to register with mask        */
115 /*-----------------------------------------------------------------*/
116 regs *xa51_regWithMask (unsigned long mask) {
117   int i;
118   for (i=0; i<xa51_nRegs; i++) {
119     if (regsXA51[i].regMask==mask) {
120       return &regsXA51[i];
121     }
122   }
123   return NULL;
124 }
125
126 /*-----------------------------------------------------------------*/
127 /* checkRegsMask - check the consistancy of the regMask redundancy */
128 /*-----------------------------------------------------------------*/
129
130 void checkRegMask(char *f) { // for debugging purposes only
131   int i;
132   unsigned long regMask=0;
133   
134   // rebuild the regmask
135   for (i=0; i<xa51_nRegs; i++) {
136     if (!regsXA51[i].isFree) {
137       regMask |= regsXA51[i].regMask;
138     }
139   }
140   
141   // check it
142   if (regMask != xa51RegsInUse) {
143     fprintf (stderr, "error(%s): regMask inconsistent 0x%08lx != 0x%08lx\n",
144              f, regMask, xa51RegsInUse);
145     regMask=regMask^xa51RegsInUse;
146     fprintf (stderr, "%s used by %s\n", 
147              xa51_regWithMask(regMask)->name, 
148              xa51_regWithMask(regMask)->sym->name);
149     
150     exit(1);
151     return;
152   }
153 }
154
155 char *regTypeToStr(short type) {
156   switch (type) 
157     {
158     case REG_PTR: return "ptr"; break; // pointer
159     case REG_GPR: return "gpr"; break; // general purpose
160     case REG_CND: return "cnd"; break; // condition (bit)
161     case REG_STK: return "stk"; break; // stack
162     case REG_SCR: return "scr"; break; // scratch
163     default: return "???";
164     }
165 }
166
167 /*-----------------------------------------------------------------*/
168 /* freeReg - frees a previous allocated register                   */
169 /*-----------------------------------------------------------------*/
170 static void freeReg (regs * reg, bool silent) {
171   
172   checkRegMask(__FUNCTION__);
173   
174   if (!reg) {
175     werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
176             "freeReg - freeing NULL register");
177     return;
178   }
179   
180   if (!silent) {
181     D0(fprintf (stderr, "freeReg: (%08lx) %s (%s) ", xa51RegsInUse, 
182                 reg->name, reg->sym->name));
183   }
184   
185   if (reg->isFree || ((xa51RegsInUse&reg->regMask)!=reg->regMask)) {
186     werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
187             "freeReg - freeing unused register(s)");
188     exit (1);
189   }
190   xa51RegsInUse &= ~reg->regMask;
191   reg->isFree = 1;
192   reg->sym = NULL;
193   if (!silent) D0(fprintf (stderr, "(%08lx)\n", xa51RegsInUse));
194   
195   checkRegMask(__FUNCTION__);
196 }
197
198 /*-----------------------------------------------------------------*/
199 /* allocReg - allocates register of given size (byte, word, dword) */
200 /*            and type (ptr, gpr, cnd)                             */
201 /*-----------------------------------------------------------------*/
202 static bool allocReg (short size, short type, symbol *sym, 
203                       short offset, bool silent) {
204   int i;
205   
206   checkRegMask(__FUNCTION__);
207   
208   if (!silent) {
209     D0(fprintf (stderr, "allocReg (%08lx) for %s size:%d, type:%s ", 
210                 xa51RegsInUse,
211                 sym->name,
212                 size, regTypeToStr(type)));
213   }
214   
215   switch (size) 
216     {
217       // TODO: gaps could be filled for dwords too
218     case 1:
219       // let's see if we can fill a gap
220       for (i=0; i<xa51_nRegs; i++) {
221         if (regsXA51[i].size==2 && regsXA51[i].type==type) {
222           unsigned long mask=regsXA51[i].regMask & ~xa51RegsInUse;
223           if (mask && mask!=regsXA51[i].regMask) {
224             regs *reg=xa51_regWithMask(mask);
225             // found a gap
226             sym->regs[offset]=reg;
227             xa51RegsInUse |= mask;
228             reg->isFree=0; // redundant
229             reg->sym = sym;
230             if (!silent) {
231               D0(fprintf (stderr, "(using gap) %s\n", reg->name));
232             }
233             checkRegMask(__FUNCTION__);
234             return TRUE;
235           }
236         }
237       }
238       // no we can't, fall through
239     case 2:
240       for (i=0; i<xa51_nRegs; i++) {
241         if (regsXA51[i].size==size &&
242             regsXA51[i].type==type &&
243             (regsXA51[i].regMask & xa51RegsInUse)==0) {
244           xa51RegsInUse |= regsXA51[i].regMask;
245           regsXA51[i].isFree = 0; // redundant
246           regsXA51[i].sym = sym;
247           if (!silent) {
248             D0(fprintf (stderr, "%s\n", regsXA51[i].name));
249           }
250           sym->regs[offset]=&regsXA51[i];
251           checkRegMask(__FUNCTION__);
252           return TRUE;
253         }
254       }
255       if (!silent) {
256         D0(fprintf (stderr, "failed (%08lx)\n", xa51RegsInUse));
257       }
258       checkRegMask(__FUNCTION__);
259       return FALSE;
260       break;
261     case 3:
262       // this must be a generic pointer
263       if (!silent) {
264         D0(fprintf (stderr, "trying 1+2\n"));
265       }
266       // get the generic part (gpr regs can't be byte)
267       if (allocReg (1, REG_PTR, sym, offset+1, silent)) {
268         // get the pointer part
269         if (allocReg (2, REG_PTR, sym, offset, silent)) {
270           checkRegMask(__FUNCTION__);
271           return TRUE;
272         }
273         freeReg(sym->regs[offset+1], silent);
274         sym->regs[offset+1]=NULL;
275       }
276       checkRegMask(__FUNCTION__);
277       return FALSE;
278       break;
279     case 4: // this is a dword
280       if (!silent) {
281         D0(fprintf (stderr, "trying 2+2\n"));
282       }
283       if ((xa51HasGprRegs && allocReg (2, REG_GPR, sym, offset, silent)) ||
284           allocReg (2, REG_PTR, sym, offset, silent)) {
285         if ((xa51HasGprRegs && allocReg (2, REG_GPR, sym, offset+1, silent)) ||
286             allocReg (2, REG_PTR, sym, offset+1, silent)) {
287           checkRegMask(__FUNCTION__);
288           return TRUE;
289         }
290       }
291       if (sym->regs[offset]) {
292         freeReg(sym->regs[offset], FALSE);
293         sym->regs[offset]=NULL;
294       }
295       checkRegMask(__FUNCTION__);
296       return FALSE;
297       break;
298     }
299   fprintf (stderr, "\nallocReg: cannot allocate reg of size %d\n", size);
300   exit (1);
301   return FALSE;
302 }
303
304 /*-------------------------------------------------------------------*/
305 /* freeAllRegs - frees all registers                                 */
306 /*-------------------------------------------------------------------*/
307 // just to be sure, this should not be needed
308 static void freeAllRegs (void) {
309   char regsFreed[132];
310   int i;
311   int nfr = 0;
312   
313   checkRegMask(__FUNCTION__);
314   
315   regsFreed[0]=0;
316   for (i=0; i<xa51_nRegs; i++) {
317     if (!regsXA51[i].isFree) {
318       strcat (regsFreed, regsXA51[i].name);
319       strcat (regsFreed, " ");
320       regsXA51[i].isFree=1;
321       regsXA51[i].sym=NULL;
322       nfr++;
323     }
324   }
325   xa51RegsInUse=0;
326   if (nfr) {
327     fprintf (stderr, "freeAllRegisters: %d regs freed (%s)\n", nfr, regsFreed);
328     exit (1);
329   }
330 }
331
332 /*-----------------------------------------------------------------*/
333 /* computeSpillable - given a point find the spillable live ranges */
334 /*-----------------------------------------------------------------*/
335 static bitVect *computeSpillable (iCode * ic) {
336   bitVect *spillable;
337   
338   /* spillable live ranges are those that are live at this 
339      point . the following categories need to be subtracted
340      from this set. 
341      a) - those that are already spilt
342      b) - if being used by this one
343      c) - defined by this one */
344   
345   spillable = bitVectCopy (ic->rlive);
346   spillable =
347     bitVectCplAnd (spillable, _G.spiltSet);     /* those already spilt */
348   spillable =
349     bitVectCplAnd (spillable, ic->uses);        /* used in this one */
350   bitVectUnSetBit (spillable, ic->defKey);      /* defined by this one */
351   spillable = bitVectIntersect (spillable, _G.regAssigned);
352   return spillable;
353   
354 }
355
356 /*-----------------------------------------------------------------*/
357 /* noSpilLoc - return true if a variable has no spil location      */
358 /*-----------------------------------------------------------------*/
359 static int
360 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
361 {
362   return (sym->usl.spillLoc ? 0 : 1);
363 }
364
365 /*-----------------------------------------------------------------*/
366 /* hasSpilLoc - will return 1 if the symbol has spil location      */
367 /*-----------------------------------------------------------------*/
368 static int
369 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
370 {
371   return (sym->usl.spillLoc ? 1 : 0);
372 }
373
374 /*-----------------------------------------------------------------*/
375 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
376 /*                    but is not used as a pointer                 */
377 /*-----------------------------------------------------------------*/
378 static int
379 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
380 {
381   return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
382 }
383
384 /*-----------------------------------------------------------------*/
385 /* rematable - will return 1 if the remat flag is set              */
386 /*-----------------------------------------------------------------*/
387 static int
388 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
389 {
390   return sym->remat;
391 }
392
393 /*-----------------------------------------------------------------*/
394 /* notUsedInRemaining - not used or defined in remain of the block */
395 /*-----------------------------------------------------------------*/
396 static int
397 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
398 {
399   return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
400           allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
401 }
402
403 /*-----------------------------------------------------------------*/
404 /* allLRs - return true for all                                    */
405 /*-----------------------------------------------------------------*/
406 static int
407 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
408 {
409   return 1;
410 }
411
412 /*-----------------------------------------------------------------*/
413 /* liveRangesWith - applies function to a given set of live range  */
414 /*-----------------------------------------------------------------*/
415 static set *
416 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
417                 eBBlock * ebp, iCode * ic)
418 {
419   set *rset = NULL;
420   int i;
421   
422   if (!lrs || !lrs->size)
423     return NULL;
424   
425   for (i = 1; i < lrs->size; i++)
426     {
427       symbol *sym;
428       if (!bitVectBitValue (lrs, i))
429         continue;
430       
431       /* if we don't find it in the live range 
432          hash table we are in serious trouble */
433       if (!(sym = hTabItemWithKey (liveRanges, i)))
434         {
435           werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
436                   "liveRangesWith could not find liveRange");
437           exit (1);
438         }
439       
440       if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
441         addSetHead (&rset, sym);
442     }
443   
444   return rset;
445 }
446
447
448 /*-----------------------------------------------------------------*/
449 /* leastUsedLR - given a set determines which is the least used    */
450 /*-----------------------------------------------------------------*/
451 static symbol *
452 leastUsedLR (set * sset)
453 {
454   symbol *sym = NULL, *lsym = NULL;
455   
456   sym = lsym = setFirstItem (sset);
457   
458   if (!lsym)
459     return NULL;
460   
461   for (; lsym; lsym = setNextItem (sset))
462     {
463       
464       /* if usage is the same then prefer
465          the spill the smaller of the two */
466       if (lsym->used == sym->used)
467         if (getSize (lsym->type) < getSize (sym->type))
468           sym = lsym;
469       
470       /* if less usage */
471       if (lsym->used < sym->used)
472         sym = lsym;
473       
474     }
475   
476   setToNull ((void *) &sset);
477   sym->blockSpil = 0;
478   return sym;
479 }
480
481 /*-----------------------------------------------------------------*/
482 /* noOverLap - will iterate through the list looking for over lap  */
483 /*-----------------------------------------------------------------*/
484 static int
485 noOverLap (set * itmpStack, symbol * fsym)
486 {
487   symbol *sym;
488   
489   
490   for (sym = setFirstItem (itmpStack); sym;
491        sym = setNextItem (itmpStack))
492     {
493       if (bitVectBitValue(sym->clashes,fsym->key)) return 0;
494     }
495   
496   return 1;
497 }
498
499 /*-----------------------------------------------------------------*/
500 /* isFree - will return 1 if the a free spil location is found     */
501 /*-----------------------------------------------------------------*/
502 static DEFSETFUNC (isFree) {
503   symbol *sym = item;
504   V_ARG (symbol **, sloc);
505   V_ARG (symbol *, fsym);
506   
507   /* if already found */
508   if (*sloc)
509     return 0;
510   
511   /* if it is free && and the itmp assigned to
512      this does not have any overlapping live ranges
513      with the one currently being assigned and
514      the size can be accomodated  */
515   if (sym->isFree &&
516       noOverLap (sym->usl.itmpStack, fsym) &&
517       /* TODO: this is a waste but causes to many problems 
518          getSize (sym->type) >= getSize (fsym->type)) {
519       */
520       getSize (sym->type) == getSize (fsym->type)) {
521     *sloc = sym;
522     return 1;
523   }
524   
525   return 0;
526 }
527
528 /*-----------------------------------------------------------------*/
529 /* createStackSpil - create a location on the stack to spil        */
530 /*-----------------------------------------------------------------*/
531 static symbol *
532 createStackSpil (symbol * sym)
533 {
534   symbol *sloc = NULL;
535   char slocBuffer[30];
536   
537   D1(fprintf (stderr, "  createStackSpil for %s\n", sym->name));
538   
539   /* first go try and find a free one that is already 
540      existing on the stack */
541   if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
542     {
543       /* found a free one : just update & return */
544       sym->usl.spillLoc = sloc;
545       sym->stackSpil = 1;
546       sloc->isFree = 0;
547       addSetHead (&sloc->usl.itmpStack, sym);
548       D1(fprintf (stderr, "    using existing %s\n", sloc->name));
549       return sym;
550     }
551   
552   sprintf (slocBuffer, "sloc%d", _G.slocNum++);
553   sloc = newiTemp (slocBuffer);
554   
555   /* set the type to the spilling symbol */
556   sloc->type = copyLinkChain (sym->type);
557   sloc->etype = getSpec (sloc->type);
558   SPEC_SCLS (sloc->etype) = S_STACK;
559   SPEC_EXTR (sloc->etype) = 0;
560   SPEC_STAT (sloc->etype) = 0;
561   SPEC_VOLATILE(sloc->etype) = 0;
562   SPEC_ABSA(sloc->etype) = 0;
563   
564   allocLocal (sloc);
565   
566   sloc->isref = 1;              /* to prevent compiler warning */
567   
568   currFunc->stack += getSize (sloc->type);
569   _G.stackExtend += getSize (sloc->type);
570   
571   /* add it to the _G.stackSpil set */
572   addSetHead (&_G.stackSpil, sloc);
573   sym->usl.spillLoc = sloc;
574   sym->stackSpil = 1;
575   
576   /* add it to the set of itempStack set 
577      of the spill location */
578   addSetHead (&sloc->usl.itmpStack, sym);
579   return sym;
580 }
581
582 /*-----------------------------------------------------------------*/
583 /* spillThis - spils a specific operand                            */
584 /*-----------------------------------------------------------------*/
585 static void
586 spillThis (symbol * sym)
587 {
588   int i;
589   
590   D1(fprintf (stderr, "  spillThis: %s\n", sym->name));
591   
592   /* if this is rematerializable or has a spillLocation
593      we are okay, else we need to create a spillLocation
594      for it */
595   if (!(sym->remat || sym->usl.spillLoc))
596     createStackSpil (sym);
597   
598   
599   /* mark it has spilt & put it in the spilt set */
600   sym->isspilt = sym->spillA = 1;
601   _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
602   
603   bitVectUnSetBit (_G.regAssigned, sym->key);
604   bitVectUnSetBit (_G.totRegAssigned, sym->key);
605   
606   for (i = 0; i < sym->nRegs; i++)
607     
608     if (sym->regs[i])
609       {
610         freeReg (sym->regs[i], FALSE);
611       }
612   
613   if (sym->usl.spillLoc && !sym->remat)
614     sym->usl.spillLoc->allocreq++;
615   return;
616 }
617
618 /*-----------------------------------------------------------------*/
619 /* selectSpil - select a iTemp to spil : rather a simple procedure */
620 /*-----------------------------------------------------------------*/
621 static symbol *
622 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
623 {
624   bitVect *lrcs = NULL;
625   set *selectS;
626   symbol *sym;
627   
628   /* get the spillable live ranges */
629   lrcs = computeSpillable (ic);
630   
631   /* get all live ranges that are rematerizable */
632   if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
633     {
634       /* return the least used of these */
635       return leastUsedLR (selectS);
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 &&
659           !isiCodeInFunctionCall (ic) &&       
660           (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
661         {
662           sym = leastUsedLR (selectS);
663           if (sym != forSym)
664             {
665               if (!sym->remat)
666                 {
667                   sym->remainSpil = 1;
668                   _G.blockSpil++;
669                 }
670               return sym;
671             }
672         }
673     }
674   
675   /* find live ranges with spillocation && not used as pointers */
676   if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
677     {
678       
679       sym = leastUsedLR (selectS);
680       /* mark this as allocation required */
681       sym->usl.spillLoc->allocreq++;
682       return sym;
683     }
684   
685   /* find live ranges with spillocation */
686   if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
687     {
688       
689       sym = leastUsedLR (selectS);
690       sym->usl.spillLoc->allocreq++;
691       return sym;
692     }
693   
694   /* couldn't find then we need to create a spil
695      location on the stack , for which one? the least
696      used ofcourse */
697   if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
698     {
699       
700       /* return a created spil location */
701       sym = createStackSpil (leastUsedLR (selectS));
702       sym->usl.spillLoc->allocreq++;
703       return sym;
704     }
705   
706   /* this is an extreme situation we will spill
707      this one : happens very rarely but it does happen */
708   spillThis (forSym);
709   return forSym;
710 }
711
712 /*-----------------------------------------------------------------*/
713 /* spillSomething - spil some variable & mark registers as free    */
714 /*-----------------------------------------------------------------*/
715 static bool
716 spillSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
717 {
718   symbol *ssym;
719   int i;
720   
721   /* get something we can spil */
722   ssym = selectSpil (ic, ebp, forSym);
723   
724   D1(fprintf (stderr, "  spillSomething: spilling %s\n", ssym->name));
725   
726   /* mark it as spilt */
727   ssym->isspilt = ssym->spillA = 1;
728   _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
729   
730   /* mark it as not register assigned &
731      take it away from the set */
732   //bitVectUnSetBit (_G.regAssigned, ssym->key);
733   //bitVectUnSetBit (_G.totRegAssigned, ssym->key);
734   
735   /* mark the registers as free */
736   for (i = 0; i < ssym->nRegs; i++) {
737     if (ssym->regs[i]) {
738       freeReg (ssym->regs[i], FALSE);
739       // dont NULL ssym->regs[i], it might be used later
740     }
741   }
742   
743   /* if this was a block level spil then insert push & pop 
744      at the start & end of block respectively */
745   if (ssym->blockSpil)
746     {
747       iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
748       /* add push to the start of the block */
749       addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
750                                     ebp->sch->next : ebp->sch));
751       nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
752       /* add pop to the end of the block */
753       addiCodeToeBBlock (ebp, nic, NULL);
754     }
755   
756   /* if spilt because not used in the remainder of the
757      block then add a push before this instruction and
758      a pop at the end of the block */
759   if (ssym->remainSpil)
760     {
761       
762       iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
763       /* add push just before this instruction */
764       addiCodeToeBBlock (ebp, nic, ic);
765       
766       nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
767       /* add pop to the end of the block */
768       addiCodeToeBBlock (ebp, nic, NULL);
769     }
770   
771   if (ssym == forSym)
772     return FALSE;
773   else
774     return TRUE;
775 }
776
777 /*-----------------------------------------------------------------*/
778 /* getRegPtr - will try for PTR if not a GPR type if not spil      */
779 /*-----------------------------------------------------------------*/
780 static bool getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym, short offset) {
781   
782   D0(fprintf (stderr, "getRegPtr: %s ", sym->name));
783   D0(printTypeChain(sym->type, stderr));
784   D0(fprintf (stderr, "\n"));
785   
786   while (1) {
787     /* this looks like an infinite loop but 
788        in really selectSpil will abort  */
789     
790     /* try for a ptr type */
791     if (allocReg (getSize(sym->type), REG_PTR, sym, offset, FALSE))
792       return TRUE;
793     
794     /* try for gpr type */
795     if (xa51HasGprRegs && allocReg (getSize(sym->type), 
796                                     REG_GPR, sym, offset, FALSE))
797       return TRUE;
798     
799     /* we have to spil */
800     if (!spillSomething (ic, ebp, sym))
801       return FALSE;
802     
803   }
804 }
805
806 /*-----------------------------------------------------------------*/
807 /* getRegGpr - will try for GPR if not spil                        */
808 /*-----------------------------------------------------------------*/
809 static bool getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym, short offset) {
810   
811   D0(fprintf (stderr, "getRegGpr: %s ", sym->name));
812   D0(printTypeChain(sym->type, stderr));
813   D0(fprintf (stderr, "\n"));
814   
815   while(1) {
816     /* this looks like an infinite loop but 
817        in really selectSpil will abort  */
818     
819     /* try for gpr type */
820     if (xa51HasGprRegs && allocReg (getSize(sym->type), 
821                                     REG_GPR, sym, offset, FALSE))
822       return TRUE;
823     
824     if (allocReg (getSize(sym->type), REG_PTR, sym, offset, FALSE))
825       return TRUE;
826     
827     /* we have to spil */
828     if (!spillSomething (ic, ebp, sym))
829       return FALSE;
830   }
831 }
832
833 /*-----------------------------------------------------------------*/
834 /* deassignLRs - check the live to and if they have registers & are */
835 /*               not spilt then free up the registers              */
836 /*-----------------------------------------------------------------*/
837 static void
838 deassignLRs (iCode * ic, eBBlock * ebp)
839 {
840   symbol *sym;
841   int k;
842   
843   for (sym = hTabFirstItem (liveRanges, &k); sym;
844        sym = hTabNextItem (liveRanges, &k))
845     {
846       /* if it does not end here */
847       if (sym->liveTo > ic->seq)
848         continue;
849       
850       /* if it was spilt on stack then we can 
851          mark the stack spil location as free */
852       if (sym->isspilt)
853         {
854           if (sym->stackSpil)
855             {
856               sym->usl.spillLoc->isFree = 1;
857               sym->stackSpil = 0;
858             }
859           continue;
860         }
861       
862       if (!bitVectBitValue (_G.regAssigned, sym->key))
863         continue;
864       
865       if (sym->nRegs) {
866         int i;
867         
868         bitVectUnSetBit (_G.regAssigned, sym->key);
869         
870         /* free the regs */
871         for (i=0; i < sym->nRegs; i++) {
872           freeReg (sym->regs[i], FALSE);
873         }
874       }
875     }
876 }
877
878 /*-----------------------------------------------------------------*/
879 /* willCauseSpill - determines if allocating will cause a spill    */
880 /*-----------------------------------------------------------------*/
881 static bool willCauseSpill (symbol *sym) {
882   int i;
883   // do it the rude way
884   if (allocReg (getSize(sym->type), sym->regType, sym, 0, TRUE) ||
885       allocReg (getSize(sym->type), sym->regType==REG_PTR?REG_GPR:REG_PTR, 
886                 sym, 0, TRUE)) {
887     // so we can, but we won't
888     for (i=0; i<sym->nRegs; i++) {
889       freeReg (sym->regs[i], TRUE);
890       sym->regs[i]=NULL;
891     }
892     return FALSE;
893   }
894   D1(fprintf (stderr, "  %s will cause a spill\n", sym->name));
895   return TRUE;
896 }
897
898 /*-----------------------------------------------------------------*/
899 /* positionRegs - the allocator can allocate same registers to res- */
900 /* ult and operand, if this happens make sure they are in the same */
901 /* position as the operand otherwise chaos results                 */
902 /*-----------------------------------------------------------------*/
903 static int
904 positionRegs (symbol * result, symbol * opsym)
905 {
906   int count = min (result->nRegs, opsym->nRegs);
907   int i, j = 0, shared = 0;
908   int changed = 0;
909   
910   /* if the result has been spilt then cannot share */
911   if (opsym->isspilt)
912     return 0;
913  again:
914   shared = 0;
915   /* first make sure that they actually share */
916   for (i = 0; i < count; i++)
917     {
918       for (j = 0; j < count; j++)
919         {
920           if (result->regs[i] == opsym->regs[j] && i != j)
921             {
922               shared = 1;
923               goto xchgPositions;
924             }
925         }
926     }
927  xchgPositions:
928   if (shared)
929     {
930       regs *tmp = result->regs[i];
931       result->regs[i] = result->regs[j];
932       result->regs[j] = tmp;
933       changed ++;
934       D2(fprintf (stderr, "positionRegs: rearranged regs for %s and %s\n",
935                   result->name, opsym->name));
936       goto again;
937     }
938   return changed;
939 }
940
941 /*-----------------------------------------------------------------*/
942 /* serialRegAssign - serially allocate registers to the variables  */
943 /*-----------------------------------------------------------------*/
944 static void
945 serialRegAssign (eBBlock ** ebbs, int count)
946 {
947   int i;
948   
949   /* for all blocks */
950   for (i = 0; i < count; i++) {
951     
952     iCode *ic;
953     
954     if (ebbs[i]->noPath &&
955         (ebbs[i]->entryLabel != entryLabel &&
956          ebbs[i]->entryLabel != returnLabel))
957       continue;
958     
959     /* of all instructions do */
960     for (ic = ebbs[i]->sch; ic; ic = ic->next) {
961       
962       /* if result is present && is a true symbol */
963       if (IC_RESULT (ic) && ic->op != IFX &&
964           IS_TRUE_SYMOP (IC_RESULT (ic))) {
965         OP_SYMBOL (IC_RESULT (ic))->allocreq++;
966       }
967       
968       /* take away registers from live
969          ranges that end at this instruction */
970       deassignLRs (ic, ebbs[i]);
971       
972       /* some don't need registers */
973       if (SKIP_IC2 (ic) ||
974           ic->op == JUMPTABLE ||
975           ic->op == IFX ||
976           ic->op == IPUSH ||
977           ic->op == IPOP ||
978           (IC_RESULT (ic) && POINTER_SET (ic)))
979         continue;
980       
981       /* now we need to allocate registers
982          only for the result */
983       if (IC_RESULT (ic)) {
984         symbol *sym = OP_SYMBOL (IC_RESULT (ic));
985         bitVect *spillable;
986         int willCS;
987         
988         /* if it does not need or is spilt 
989            or is already assigned to registers
990            or will not live beyond this instructions */
991         if (!sym->nRegs ||
992             sym->isspilt ||
993             bitVectBitValue (_G.regAssigned, sym->key) ||
994             sym->liveTo <= ic->seq)
995           continue;
996         
997         /* if some liverange has been spilt at the block level
998            and this one live beyond this block then spil this
999            to be safe */
1000         if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq) {
1001           spillThis (sym);
1002           continue;
1003         }
1004         /* if trying to allocate this will cause
1005            a spill and there is nothing to spill 
1006            or this one is rematerializable then
1007            spill this one */
1008         willCS = willCauseSpill (sym);
1009         spillable = computeSpillable (ic);
1010         if (sym->remat || (willCS && bitVectIsZero (spillable))) {                    
1011           spillThis (sym);
1012           continue;                   
1013         }
1014         
1015         /* If the live range preceeds the point of definition 
1016            then ideally we must take into account registers that 
1017            have been allocated after sym->liveFrom but freed
1018            before ic->seq. This is complicated, so spill this
1019            symbol instead and let fillGaps handle the allocation. */
1020         if (sym->liveFrom < ic->seq) {
1021             spillThis (sym);
1022             continue;                 
1023         }
1024         
1025         /* if it has a spillocation & is used less than
1026            all other live ranges then spill this */
1027         if (willCS) {
1028           if (sym->usl.spillLoc) {
1029             symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
1030                                                              allLRs, ebbs[i], ic));
1031             if (leastUsed && leastUsed->used > sym->used) {
1032               spillThis (sym);
1033               continue;
1034             }
1035           } else {
1036             /* if none of the liveRanges have a spillLocation then better
1037                to spill this one than anything else already assigned to registers */
1038             if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
1039               /* if this is local to this block then we might find a block spil */
1040               if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
1041                 spillThis (sym);
1042                 continue;
1043               }
1044             }
1045           }
1046         }
1047         
1048         /* else we assign registers to it */
1049         _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1050         _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key);
1051         
1052         if (sym->regType == REG_PTR)
1053           getRegPtr (ic, ebbs[i], sym, 0);
1054         else
1055           getRegGpr (ic, ebbs[i], sym, 0);
1056         
1057         /* if it shares registers with operands make sure
1058            that they are in the same position */
1059         if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
1060             OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=') {
1061           positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1062                         OP_SYMBOL (IC_LEFT (ic)));
1063         }
1064         /* do the same for the right operand */
1065         if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
1066             OP_SYMBOL (IC_RIGHT (ic))->nRegs) {
1067           positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1068                         OP_SYMBOL (IC_RIGHT (ic)));
1069         }
1070       }
1071     }
1072   }
1073 }
1074
1075 /*-----------------------------------------------------------------*/
1076 /* rUmaskForOp :- returns register mask for an operand             */
1077 /*-----------------------------------------------------------------*/
1078 bitVect *xa51_rUmaskForOp (operand * op) {
1079   bitVect *rumask;
1080   symbol *sym;
1081   int j;
1082   
1083   /* only temporaries are assigned registers */
1084   if (!IS_ITEMP (op))
1085     return NULL;
1086   
1087   sym = OP_SYMBOL (op);
1088   
1089   /* if spilt or no registers assigned to it 
1090      then nothing */
1091   if (sym->isspilt || !sym->nRegs || !sym->regs[0])
1092     return NULL;
1093   
1094   rumask = newBitVect (xa51_nRegs);
1095   
1096   for (j = 0; j < sym->nRegs; j++) {
1097     rumask = bitVectSetBit (rumask,
1098                             sym->regs[j]->rIdx);
1099   }
1100   return rumask;
1101 }
1102
1103 /*-----------------------------------------------------------------*/
1104 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
1105 /*-----------------------------------------------------------------*/
1106 static bitVect *
1107 regsUsedIniCode (iCode * ic)
1108 {
1109   bitVect *rmask = newBitVect (xa51_nRegs);
1110   
1111   /* do the special cases first */
1112   if (ic->op == IFX)
1113     {
1114       rmask = bitVectUnion (rmask,
1115                             xa51_rUmaskForOp (IC_COND (ic)));
1116       goto ret;
1117     }
1118   
1119   /* for the jumptable */
1120   if (ic->op == JUMPTABLE)
1121     {
1122       rmask = bitVectUnion (rmask,
1123                             xa51_rUmaskForOp (IC_JTCOND (ic)));
1124       
1125       goto ret;
1126     }
1127   
1128   /* of all other cases */
1129   if (IC_LEFT (ic))
1130     rmask = bitVectUnion (rmask,
1131                           xa51_rUmaskForOp (IC_LEFT (ic)));
1132   
1133   
1134   if (IC_RIGHT (ic))
1135     rmask = bitVectUnion (rmask,
1136                           xa51_rUmaskForOp (IC_RIGHT (ic)));
1137   
1138   if (IC_RESULT (ic))
1139     rmask = bitVectUnion (rmask,
1140                           xa51_rUmaskForOp (IC_RESULT (ic)));
1141   
1142  ret:
1143   return rmask;
1144 }
1145
1146 /*-----------------------------------------------------------------*/
1147 /* createRegMask - for each instruction will determine the regsUsed */
1148 /*-----------------------------------------------------------------*/
1149 static void
1150 createRegMask (eBBlock ** ebbs, int count)
1151 {
1152   int i;
1153   
1154   /* for all blocks */
1155   for (i = 0; i < count; i++)
1156     {
1157       iCode *ic;
1158       
1159       if (ebbs[i]->noPath &&
1160           (ebbs[i]->entryLabel != entryLabel &&
1161            ebbs[i]->entryLabel != returnLabel))
1162         continue;
1163       
1164       /* for all instructions */
1165       for (ic = ebbs[i]->sch; ic; ic = ic->next)
1166         {
1167           
1168           int j;
1169           
1170           if (SKIP_IC2 (ic) || !ic->rlive)
1171             continue;
1172           
1173           /* first mark the registers used in this
1174              instruction */
1175           ic->rUsed = regsUsedIniCode (ic);
1176           _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
1177           
1178           /* now create the register mask for those 
1179              registers that are in use : this is a
1180              super set of ic->rUsed */
1181           ic->rMask = newBitVect (xa51_nRegs + 1);
1182           
1183           /* for all live Ranges alive at this point */
1184           for (j = 1; j < ic->rlive->size; j++)
1185             {
1186               symbol *sym;
1187               int k;
1188               
1189               /* if not alive then continue */
1190               if (!bitVectBitValue (ic->rlive, j))
1191                 continue;
1192               
1193               /* find the live range we are interested in */
1194               if (!(sym = hTabItemWithKey (liveRanges, j)))
1195                 {
1196                   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1197                           "createRegMask cannot find live range");
1198                   exit (0);
1199                 }
1200               
1201               /* if no register assigned to it */
1202               if (!sym->nRegs || sym->isspilt)
1203                 continue;
1204               
1205               /* for all the registers allocated to it */
1206               for (k = 0; k < sym->nRegs; k++)
1207                 if (sym->regs[k])
1208                   ic->rMask =
1209                     bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
1210             }
1211         }
1212     }
1213 }
1214
1215 /*-----------------------------------------------------------------*/
1216 /* rematStr - returns the rematerialized string for a remat var    */
1217 /*-----------------------------------------------------------------*/
1218 static char *
1219 rematStr (symbol * sym)
1220 {
1221   char *s = buffer;
1222   iCode *ic = sym->rematiCode;
1223   
1224   while (1)
1225     {
1226       
1227       /* if plus or minus print the right hand side */
1228       if (ic->op == '+' || ic->op == '-')
1229         {
1230           sprintf (s, "0x%04x %c ", (int) operandLitValue (IC_RIGHT (ic)),
1231                    ic->op);
1232           s += strlen (s);
1233           ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1234           continue;
1235         }
1236       
1237       /* cast then continue */
1238       if (IS_CAST_ICODE(ic)) {
1239         ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
1240         continue;
1241       }
1242       /* we reached the end */
1243       sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
1244       break;
1245     }
1246   
1247   return buffer;
1248 }
1249
1250 /*-----------------------------------------------------------------*/
1251 /* regTypeNum - computes the type & number of registers required   */
1252 /*-----------------------------------------------------------------*/
1253 static void
1254 regTypeNum (eBBlock *ebbs)
1255 {
1256   symbol *sym;
1257   int k;
1258   iCode *ic;
1259   
1260   /* for each live range do */
1261   for (sym = hTabFirstItem (liveRanges, &k); sym;
1262        sym = hTabNextItem (liveRanges, &k))
1263     {
1264       
1265       /* if used zero times then no registers needed */
1266       if ((sym->liveTo - sym->liveFrom) == 0)
1267         continue;
1268       
1269       
1270       /* if the live range is a temporary */
1271       if (sym->isitmp)
1272         {
1273           
1274           /* if the type is marked as a conditional */
1275           if (sym->regType == REG_CND)
1276             continue;
1277           
1278           /* if used in return only then we don't 
1279              need registers */
1280 #if 0 // not yet
1281           if (sym->ruonly || sym->accuse)
1282             {
1283               if (IS_AGGREGATE (sym->type) || sym->isptr)
1284                 sym->type = aggrToPtr (sym->type, FALSE);
1285               continue;
1286             }
1287 #endif
1288           
1289           /* if the symbol has only one definition &
1290              that definition is a get_pointer */
1291           if (bitVectnBitsOn (sym->defs) == 1 &&
1292               (ic = hTabItemWithKey (iCodehTab,
1293                                      bitVectFirstBit (sym->defs))) &&
1294               POINTER_GET (ic) &&
1295               !sym->noSpilLoc &&
1296               !IS_BITVAR (sym->etype))
1297             {
1298               /* and that pointer is remat in data space */
1299               if (OP_SYMBOL (IC_LEFT (ic))->remat &&
1300                   !IS_CAST_ICODE(OP_SYMBOL (IC_LEFT (ic))->rematiCode) &&
1301                   DCL_TYPE (aggrToPtr (operandType(IC_LEFT(ic)), FALSE)) == POINTER)
1302                 {
1303                   /* create a psuedo symbol & force a spil */
1304                   symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
1305                   psym->type = sym->type;
1306                   psym->etype = sym->etype;
1307                   strcpy (psym->rname, psym->name);
1308                   sym->isspilt = 1;
1309                   sym->usl.spillLoc = psym;
1310 #if 0 // an alternative fix for bug #480076
1311                   /* now this is a useless assignment to itself */
1312                   remiCodeFromeBBlock (ebbs, ic);
1313 #else
1314                   /* now this really is an assignment to itself, make it so;
1315                      it will be optimized out later */
1316                   ic->op='=';
1317                   IC_RIGHT(ic)=IC_RESULT(ic);
1318                   IC_LEFT(ic)=NULL;
1319 #endif
1320                   continue;
1321                 }
1322               
1323               /* if in data space or idata space then try to
1324                  allocate pointer register */
1325               
1326             }
1327           
1328           /* if not then we require registers */
1329 #if 0
1330           sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
1331                         getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1332                         getSize (sym->type));
1333 #else
1334           {
1335             int size=((IS_AGGREGATE (sym->type) || sym->isptr) ?
1336                       getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1337                       getSize (sym->type));
1338             switch (size) 
1339               {
1340               case 1: // byte
1341               case 2: // word or pointer
1342                 sym->nRegs=1;
1343                 break;
1344               case 3: // generic pointer
1345                 sym->nRegs=2;
1346                 break;
1347               case 4: // dword or float
1348                 sym->nRegs=2;
1349                 break;
1350               default: 
1351                 fprintf (stderr, "regTypeNum: unknown size\n");
1352                 exit (1);
1353               }
1354           }
1355 #endif
1356           
1357           if (sym->nRegs > 4)
1358             {
1359               fprintf (stderr, "allocated more than 4 or 0 registers for type ");
1360               printTypeChain (sym->type, stderr);
1361               fprintf (stderr, "\n");
1362               exit (1);
1363             }
1364           
1365           /* determine the type of register required */
1366           if (IS_PTR (sym->type))
1367             sym->regType = REG_PTR;
1368           else
1369             sym->regType = REG_GPR;
1370           
1371         }
1372       else
1373         /* for the first run we don't provide */
1374         /* registers for true symbols we will */
1375         /* see how things go                  */
1376         sym->nRegs = 0;
1377     }
1378   
1379 }
1380
1381 /*-----------------------------------------------------------------*/
1382 /* deallocStackSpil - this will set the stack pointer back         */
1383 /*-----------------------------------------------------------------*/
1384 static
1385 DEFSETFUNC (deallocStackSpil)
1386 {
1387   symbol *sym = item;
1388   
1389   deallocLocal (sym);
1390   return 0;
1391 }
1392
1393 /*-----------------------------------------------------------------*/
1394 /* packRegsForAssign - register reduction for assignment           */
1395 /*-----------------------------------------------------------------*/
1396 static int
1397 packRegsForAssign (iCode * ic, eBBlock * ebp)
1398 {
1399   iCode *dic, *sic;
1400   
1401   if (!IS_ITEMP (IC_RIGHT (ic)) ||
1402       OP_LIVETO (IC_RIGHT (ic)) > ic->seq) {
1403     return 0;
1404   }
1405
1406   /* find the definition of iTempNN scanning backwards */
1407   for (dic = ic->prev; dic; dic = dic->prev) {
1408     
1409     /* if there is a function call then don't pack it */
1410     if ((dic->op == CALL || dic->op == PCALL)) {
1411       dic = NULL;
1412       break;
1413     }
1414     
1415     if (SKIP_IC2 (dic))
1416       continue;
1417     
1418     if (IS_SYMOP (IC_RESULT (dic)) &&
1419         IC_RESULT (dic)->key == IC_RIGHT (ic)->key) {
1420       break;
1421     }
1422     
1423   }
1424   
1425   if (!dic)
1426     return 0;                   /* did not find */
1427
1428   /* found the definition */
1429   /* replace the result with the result of */
1430   /* this assignment and remove this assignment */
1431   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1432   IC_RESULT (dic) = IC_RESULT (ic);
1433   
1434   if (IS_ITEMP (IC_RESULT (dic)) && 
1435       OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
1436     {
1437       OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
1438     }
1439   /* delete from liverange table also 
1440      delete from all the points inbetween and the new
1441      one */
1442   for (sic = dic; sic != ic; sic = sic->next)
1443     {
1444       bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
1445       if (IS_ITEMP (IC_RESULT (dic)))
1446         bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
1447     }
1448   
1449   remiCodeFromeBBlock (ebp, ic);
1450   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
1451   hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
1452   OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
1453   return 1;
1454   
1455 }
1456
1457 /*-----------------------------------------------------------------*/
1458 /* findAssignToSym : scanning backwards looks for first assig found */
1459 /*-----------------------------------------------------------------*/
1460 static iCode *
1461 findAssignToSym (operand * op, iCode * ic)
1462 {
1463   iCode *dic;
1464   
1465   for (dic = ic->prev; dic; dic = dic->prev)
1466     {
1467       
1468       /* if definition by assignment */
1469       if (dic->op == '=' &&
1470           !POINTER_SET (dic) &&
1471           IC_RESULT (dic)->key == op->key
1472           /*          &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) */
1473           )
1474         {
1475           
1476           /* we are interested only if defined in far space */
1477           /* or in stack space in case of + & - */
1478           
1479           /* if assigned to a non-symbol then return
1480              FALSE */
1481           if (!IS_SYMOP (IC_RIGHT (dic)))
1482             return NULL;
1483           
1484           /* if the symbol is in far space then
1485              we should not */
1486           if (isOperandInFarSpace (IC_RIGHT (dic)))
1487             return NULL;
1488           
1489           /* for + & - operations make sure that
1490              if it is on the stack it is the same
1491              as one of the three operands */
1492           if ((ic->op == '+' || ic->op == '-') &&
1493               OP_SYMBOL (IC_RIGHT (dic))->onStack)
1494             {
1495               
1496               if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
1497                   IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
1498                   IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
1499                 return NULL;
1500             }
1501           
1502           break;
1503           
1504         }
1505       
1506       /* if we find an usage then we cannot delete it */
1507       if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
1508         return NULL;
1509       
1510       if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
1511         return NULL;
1512       
1513       if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
1514         return NULL;
1515     }
1516   
1517   /* now make sure that the right side of dic
1518      is not defined between ic & dic */
1519   if (dic)
1520     {
1521       iCode *sic = dic->next;
1522       
1523       for (; sic != ic; sic = sic->next)
1524         if (IC_RESULT (sic) &&
1525             IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
1526           return NULL;
1527     }
1528   
1529   return dic;
1530   
1531   
1532 }
1533
1534 /*-----------------------------------------------------------------*/
1535 /* packRegsForSupport :- reduce some registers for support calls   */
1536 /*-----------------------------------------------------------------*/
1537 static int
1538 packRegsForSupport (iCode * ic, eBBlock * ebp)
1539 {
1540   int change = 0;
1541   iCode *dic, *sic;
1542   
1543   /* for the left & right operand :- look to see if the
1544      left was assigned a true symbol in far space in that
1545      case replace them */
1546
1547   if (IS_ITEMP (IC_LEFT (ic)) &&
1548       OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
1549     {
1550       dic = findAssignToSym (IC_LEFT (ic), ic);
1551       
1552       if (!dic)
1553         goto right;
1554       
1555       /* found it we need to remove it from the
1556          block */
1557       for (sic = dic; sic != ic; sic = sic->next)
1558         bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
1559       
1560       OP_SYMBOL(IC_LEFT (ic))=OP_SYMBOL(IC_RIGHT (dic));
1561       IC_LEFT (ic)->key = OP_SYMBOL(IC_RIGHT (dic))->key;
1562       remiCodeFromeBBlock (ebp, dic);
1563       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1564       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1565       change++;
1566     }
1567   
1568   /* do the same for the right operand */
1569  right:
1570   if (!change &&
1571       IS_ITEMP (IC_RIGHT (ic)) &&
1572       OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
1573     {
1574       iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
1575       iCode *sic;
1576       
1577       if (!dic)
1578         return change;
1579       
1580       /* if this is a subtraction & the result
1581          is a true symbol in far space then don't pack */
1582       if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
1583         {
1584           sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
1585           if (IN_FARSPACE (SPEC_OCLS (etype)))
1586             return change;
1587         }
1588       /* found it we need to remove it from the
1589          block */
1590       for (sic = dic; sic != ic; sic = sic->next)
1591         bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
1592       
1593       IC_RIGHT (ic)->operand.symOperand =
1594         IC_RIGHT (dic)->operand.symOperand;
1595       IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
1596       
1597       remiCodeFromeBBlock (ebp, dic);
1598       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1599       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1600       change++;
1601     }
1602   
1603   return change;
1604 }
1605
1606 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
1607
1608
1609 /*-----------------------------------------------------------------*/
1610 /* packRegsForOneuse : - will reduce some registers for single Use */
1611 /*-----------------------------------------------------------------*/
1612 static iCode *
1613 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
1614 {
1615   bitVect *uses;
1616   iCode *dic, *sic;
1617
1618   /* if returning a literal then do nothing */
1619   if (!IS_SYMOP (op))
1620     return NULL;
1621   
1622   if (ic->op != RETURN &&
1623       ic->op != SEND &&
1624       !POINTER_SET (ic) &&
1625       !POINTER_GET (ic))
1626     return NULL;
1627   
1628   /* this routine will mark the a symbol as used in one 
1629      instruction use only && if the defintion is local 
1630      (ie. within the basic block) && has only one definition &&
1631      that definiion is either a return value from a 
1632      function or does not contain any variables in
1633      far space */
1634   uses = bitVectCopy (OP_USES (op));
1635   bitVectUnSetBit (uses, ic->key);      /* take away this iCode */
1636   if (!bitVectIsZero (uses))    /* has other uses */
1637     return NULL;
1638   
1639   /* if it has only one defintion */
1640   if (bitVectnBitsOn (OP_DEFS (op)) > 1)
1641     return NULL;                /* has more than one definition */
1642   
1643   /* get that definition */
1644   if (!(dic =
1645         hTabItemWithKey (iCodehTab,
1646                          bitVectFirstBit (OP_DEFS (op)))))
1647     return NULL;
1648   
1649 #if 0
1650   /* if that only usage is a cast */
1651   if (dic->op == CAST) {
1652     /* to a bigger type */
1653     if (getSize(OP_SYM_TYPE(IC_RESULT(dic))) > 
1654         getSize(OP_SYM_TYPE(IC_RIGHT(dic)))) {
1655       /* than we can not, since we cannot predict the usage of b & acc */
1656       return NULL;
1657     }
1658   }
1659 #endif
1660   
1661   /* found the definition now check if it is local */
1662   if (dic->seq < ebp->fSeq ||
1663       dic->seq > ebp->lSeq)
1664     return NULL;                /* non-local */
1665   
1666   /* now check if it is the return from
1667      a function call */
1668   if (dic->op == CALL || dic->op == PCALL)
1669     {
1670       if (ic->op != SEND && ic->op != RETURN &&
1671           !POINTER_SET(ic) && !POINTER_GET(ic))
1672         {
1673           OP_SYMBOL (op)->ruonly = 1;
1674           return dic;
1675         }
1676       dic = dic->next;
1677     }
1678   
1679 #if 0  
1680   /* otherwise check that the definition does
1681      not contain any symbols in far space */
1682   if (isOperandInFarSpace (IC_LEFT (dic)) ||
1683       isOperandInFarSpace (IC_RIGHT (dic)) ||
1684       IS_OP_RUONLY (IC_LEFT (ic)) ||
1685       IS_OP_RUONLY (IC_RIGHT (ic)))
1686     {
1687       return NULL;
1688     }
1689 #endif
1690
1691 #if 0  
1692   /* if pointer set then make sure the pointer
1693      is one byte */
1694   if (POINTER_SET (dic) &&
1695       !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
1696     return NULL;
1697   
1698   if (POINTER_GET (dic) &&
1699       !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
1700     return NULL;
1701 #endif
1702   
1703   sic = dic;
1704   
1705   /* also make sure the intervenening instructions
1706      don't have any thing in far space */
1707   for (dic = dic->next; dic && dic != ic && sic != ic; dic = dic->next)
1708     {
1709       
1710       /* if there is an intervening function call then no */
1711       if (dic->op == CALL || dic->op == PCALL)
1712         return NULL;
1713
1714 #if 0
1715       /* if pointer set then make sure the pointer
1716          is one byte */
1717       if (POINTER_SET (dic) &&
1718           !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
1719         return NULL;
1720       
1721       if (POINTER_GET (dic) &&
1722           !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
1723         return NULL;
1724 #endif
1725       
1726       /* if address of & the result is remat the okay */
1727       if (dic->op == ADDRESS_OF &&
1728           OP_SYMBOL (IC_RESULT (dic))->remat)
1729         continue;
1730
1731 #if 0      
1732       /* if operand has size of three or more & this
1733          operation is a '*','/' or '%' then 'b' may
1734          cause a problem */
1735       if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
1736           getSize (operandType (op)) >= 3)
1737         return NULL;
1738 #endif
1739       
1740 #if 0
1741       /* if left or right or result is in far space */
1742       if (isOperandInFarSpace (IC_LEFT (dic)) ||
1743           isOperandInFarSpace (IC_RIGHT (dic)) ||
1744           isOperandInFarSpace (IC_RESULT (dic)) ||
1745           IS_OP_RUONLY (IC_LEFT (dic)) ||
1746           IS_OP_RUONLY (IC_RIGHT (dic)) ||
1747           IS_OP_RUONLY (IC_RESULT (dic)))
1748         {
1749           return NULL;
1750         }
1751       /* if left or right or result is on stack */
1752       if (isOperandOnStack(IC_LEFT(dic)) ||
1753           isOperandOnStack(IC_RIGHT(dic)) ||
1754           isOperandOnStack(IC_RESULT(dic))) {
1755         return NULL;
1756       }
1757 #endif
1758     }
1759   
1760   OP_SYMBOL (op)->ruonly = 1;
1761   fprintf (stderr, "%s is used only once in line %d.\n", 
1762            OP_SYMBOL(op)->name, ic->lineno);
1763   return sic;
1764   
1765 }
1766
1767 /*-----------------------------------------------------------------*/
1768 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
1769 /*-----------------------------------------------------------------*/
1770 static bool
1771 isBitwiseOptimizable (iCode * ic)
1772 {
1773   sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
1774   sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
1775   
1776   /* bitwise operations are considered optimizable
1777      under the following conditions (Jean-Louis VERN) 
1778      
1779      x & lit
1780      bit & bit
1781      bit & x
1782      bit ^ bit
1783      bit ^ x
1784      x   ^ lit
1785      x   | lit
1786      bit | bit
1787      bit | x
1788   */
1789   if (IS_LITERAL(rtype) ||
1790       (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
1791     return TRUE;
1792   else
1793     return FALSE;
1794 }
1795
1796 /*-----------------------------------------------------------------*/
1797 /* packForPush - hueristics to reduce iCode for pushing            */
1798 /*-----------------------------------------------------------------*/
1799 static void
1800 packForPush (iCode * ic, eBBlock * ebp)
1801 {
1802   iCode *dic, *lic;
1803   bitVect *dbv;
1804
1805   if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
1806     return;
1807   
1808   /* must have only definition & one usage */
1809   if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
1810       bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
1811     return;
1812   
1813   /* find the definition */
1814   if (!(dic = hTabItemWithKey (iCodehTab,
1815                                bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
1816     return;
1817   
1818   if (dic->op != '=' || POINTER_SET (dic))
1819     return;
1820   
1821   /* make sure the right side does not have any definitions
1822      inbetween */
1823   dbv = OP_DEFS(IC_RIGHT(dic));
1824   for (lic = ic; lic && lic != dic ; lic = lic->prev) {
1825     if (bitVectBitValue(dbv,lic->key)) 
1826       return ;
1827   }
1828   /* make sure they have the same type */
1829   {
1830     sym_link *itype=operandType(IC_LEFT(ic));
1831     sym_link *ditype=operandType(IC_RIGHT(dic));
1832     
1833     if (SPEC_USIGN(itype)!=SPEC_USIGN(ditype) ||
1834         SPEC_LONG(itype)!=SPEC_LONG(ditype))
1835       return;
1836   }
1837   /* extend the live range of replaced operand if needed */
1838   if (OP_SYMBOL(IC_RIGHT(dic))->liveTo < ic->seq) {
1839     OP_SYMBOL(IC_RIGHT(dic))->liveTo = ic->seq;
1840   }
1841   /* we now know that it has one & only one def & use
1842      and the that the definition is an assignment */
1843   IC_LEFT (ic) = IC_RIGHT (dic);
1844   
1845   remiCodeFromeBBlock (ebp, dic);
1846   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1847   hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1848 }
1849
1850 /*-----------------------------------------------------------------*/
1851 /* packRegisters - does some transformations to reduce register    */
1852 /*                   pressure                                      */
1853 /*-----------------------------------------------------------------*/
1854 static void packRegisters (eBBlock * ebp) {
1855   iCode *ic;
1856   int change = 0;
1857   
1858   while (1) {
1859     change = 0;
1860     
1861     for (ic = ebp->sch; ic; ic = ic->next) {
1862       if (ic->op == '=')
1863         change += packRegsForAssign (ic, ebp);
1864     }
1865     
1866     if (!change)
1867       break;
1868   }
1869   
1870   for (ic = ebp->sch; ic; ic = ic->next)
1871     {
1872       /* if the condition of an if instruction
1873          is defined in the previous instruction and
1874          this is the only usage then
1875          mark the itemp as a conditional */
1876       if ((IS_CONDITIONAL (ic) ||
1877            (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic)))) {
1878         if (ic->next && ic->next->op == IFX &&
1879             bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
1880             isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
1881             OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq) {
1882           OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
1883           continue;
1884         }
1885       }
1886
1887 #if 0
1888       /* if this is an itemp & result of an address of a true sym 
1889          then mark this as rematerialisable   */
1890       if (ic->op == ADDRESS_OF &&
1891           IS_ITEMP (IC_RESULT (ic)) &&
1892           IS_TRUE_SYMOP (IC_LEFT (ic)) &&
1893           bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
1894           !OP_SYMBOL (IC_LEFT (ic))->onStack)
1895         {
1896           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
1897           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
1898           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
1899         }
1900
1901       /* if straight assignment then carry remat flag if
1902          this is the only definition */
1903       if (ic->op == '=' &&
1904           !POINTER_SET (ic) &&
1905           IS_SYMOP (IC_RIGHT (ic)) &&
1906           OP_SYMBOL (IC_RIGHT (ic))->remat &&
1907           !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode) &&
1908           bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
1909         {
1910           
1911           OP_SYMBOL (IC_RESULT (ic))->remat =
1912             OP_SYMBOL (IC_RIGHT (ic))->remat;
1913           OP_SYMBOL (IC_RESULT (ic))->rematiCode =
1914             OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
1915         }
1916       
1917       /* if cast to a generic pointer & the pointer being
1918          cast is remat, then we can remat this cast as well */
1919       if (ic->op == CAST && 
1920           IS_SYMOP(IC_RIGHT(ic)) &&
1921           OP_SYMBOL(IC_RIGHT(ic))->remat ) {
1922         sym_link *to_type = operandType(IC_LEFT(ic));
1923         sym_link *from_type = operandType(IC_RIGHT(ic));
1924         if (IS_GENPTR(to_type) && IS_PTR(from_type)) {                
1925           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
1926           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
1927           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
1928         }
1929       }
1930       
1931       /* if this is a +/- operation with a rematerizable 
1932          then mark this as rematerializable as well */
1933       if ((ic->op == '+' || ic->op == '-') &&
1934           (IS_SYMOP (IC_LEFT (ic)) &&
1935            IS_ITEMP (IC_RESULT (ic)) &&
1936            IS_OP_LITERAL (IC_RIGHT (ic))) &&
1937           OP_SYMBOL (IC_LEFT (ic))->remat &&
1938           (!IS_SYMOP (IC_RIGHT (ic)) || !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode)) &&
1939           bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1)
1940         {
1941           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
1942           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
1943           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
1944         }
1945 #endif
1946       
1947       /* mark the pointer usages */
1948       if (POINTER_SET (ic))
1949         OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
1950       
1951       if (POINTER_GET (ic))
1952         OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
1953       
1954       /* reduce for support function calls */
1955       if (ic->supportRtn || ic->op == '+' || ic->op == '-')
1956         packRegsForSupport (ic, ebp);
1957       
1958       /* some cases the redundant moves can
1959          can be eliminated for return statements */
1960       if (ic->op == RETURN || ic->op == SEND) {
1961           packRegsForOneuse (ic, IC_LEFT (ic), ebp);
1962         }
1963       
1964       /* if pointer set & left has a size more than
1965          one and right is not in far space */
1966       if (POINTER_SET (ic) &&
1967           !isOperandInFarSpace (IC_RIGHT (ic)) &&
1968           !OP_SYMBOL (IC_RESULT (ic))->remat &&
1969           !IS_OP_RUONLY (IC_RIGHT (ic)) &&
1970           getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
1971         
1972         packRegsForOneuse (ic, IC_RESULT (ic), ebp);
1973       
1974       /* if pointer get */
1975       if (POINTER_GET (ic) &&
1976           !isOperandInFarSpace (IC_RESULT (ic)) &&
1977           !OP_SYMBOL (IC_LEFT (ic))->remat &&
1978           !IS_OP_RUONLY (IC_RESULT (ic)) &&
1979           getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
1980         
1981         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
1982       
1983       
1984       /* if this is cast for intergral promotion then
1985          check if only use of  the definition of the 
1986          operand being casted/ if yes then replace
1987          the result of that arithmetic operation with 
1988          this result and get rid of the cast */
1989       if (ic->op == CAST)
1990         {
1991           sym_link *fromType = operandType (IC_RIGHT (ic));
1992           sym_link *toType = operandType (IC_LEFT (ic));
1993           
1994           if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
1995               getSize (fromType) != getSize (toType) &&
1996               SPEC_USIGN (fromType) == SPEC_USIGN (toType))
1997             {
1998               
1999               iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2000               if (dic)
2001                 {
2002                   if (IS_ARITHMETIC_OP (dic))
2003                     {                  
2004                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2005                       IC_RESULT (dic) = IC_RESULT (ic);
2006                       remiCodeFromeBBlock (ebp, ic);
2007                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2008                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2009                       OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2010                       ic = ic->prev;
2011                     }
2012                   else
2013                     OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
2014                 }
2015             }
2016           else
2017             {
2018               
2019               /* if the type from and type to are the same
2020                  then if this is the only use then packit */
2021               if (compareType (operandType (IC_RIGHT (ic)),
2022                                operandType (IC_LEFT (ic))) == 1)
2023                 {
2024                   iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2025                   if (dic)
2026                     {
2027                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2028                       IC_RESULT (dic) = IC_RESULT (ic);
2029                       remiCodeFromeBBlock (ebp, ic);
2030                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2031                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2032                       OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2033                       ic = ic->prev;
2034                     }
2035                 }
2036             }
2037         }
2038       
2039       /* pack for PUSH 
2040          iTempNN := (some variable in farspace) V1
2041          push iTempNN ;
2042          -------------
2043          push V1
2044       */
2045       if (ic->op == IPUSH)
2046         {
2047           packForPush (ic, ebp);
2048         }
2049     }
2050 }
2051
2052 /*-----------------------------------------------------------------*/
2053 /* assignRegisters - assigns registers to each live range as need  */
2054 /*-----------------------------------------------------------------*/
2055 void
2056 xa51_assignRegisters (eBBlock ** ebbs, int count)
2057 {
2058   iCode *ic;
2059   int i;
2060   
2061   setToNull ((void *) &_G.funcrUsed);
2062   setToNull ((void *) &_G.totRegAssigned);
2063   _G.stackExtend = 0;
2064   
2065   /* change assignments this will remove some
2066      live ranges reducing some register pressure */
2067   for (i = 0; i < count; i++)
2068     packRegisters (ebbs[i]);
2069
2070   /* liveranges probably changed by register packing
2071      so we compute them again */
2072   recomputeLiveRanges (ebbs, count);
2073
2074   if (options.dump_pack)
2075     dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
2076   
2077   /* first determine for each live range the number of 
2078      registers & the type of registers required for each */
2079   regTypeNum (*ebbs);
2080   
2081   /* and serially allocate registers */
2082   serialRegAssign (ebbs, count);
2083   
2084   freeAllRegs ();
2085   
2086   /* if stack was extended then tell the user */
2087   if (_G.stackExtend)
2088     {
2089       werror(I_EXTENDED_STACK_SPILS,
2090              _G.stackExtend,currFunc->name,"");
2091       _G.stackExtend = 0;
2092     }
2093   
2094   /* after that create the register mask
2095      for each of the instruction */
2096   createRegMask (ebbs, count);
2097   
2098   /* redo that offsets for stacked automatic variables */
2099   redoStackOffsets ();
2100   
2101   if (options.dump_rassgn)
2102     {
2103       dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
2104       dumpLiveRanges (DUMP_LRANGE, liveRanges);
2105     }
2106   
2107   /* do the overlaysegment stuff SDCCmem.c */
2108   doOverlays (ebbs, count);
2109   
2110   /* now get back the chain */
2111   ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
2112   
2113   genXA51Code (ic);
2114   
2115   /* free up any _G.stackSpil locations allocated */
2116   applyToSet (_G.stackSpil, deallocStackSpil);
2117   _G.slocNum = 0;
2118   setToNull ((void *) &_G.stackSpil);
2119   setToNull ((void *) &_G.spiltSet);
2120   /* mark all registers as free */
2121   freeAllRegs ();
2122   
2123   return;
2124 }