d7ac59b6c9f9a44631d5cb57ef05710faca3de39
[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 && (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 /* spillSomething - spil some variable & mark registers as free    */
712 /*-----------------------------------------------------------------*/
713 static bool
714 spillSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
715 {
716   symbol *ssym;
717   int i;
718   
719   /* get something we can spil */
720   ssym = selectSpil (ic, ebp, forSym);
721   
722   D1(fprintf (stderr, "  spillSomething: spilling %s\n", ssym->name));
723   
724   /* mark it as spilt */
725   ssym->isspilt = ssym->spillA = 1;
726   _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
727   
728   /* mark it as not register assigned &
729      take it away from the set */
730   //bitVectUnSetBit (_G.regAssigned, ssym->key);
731   //bitVectUnSetBit (_G.totRegAssigned, ssym->key);
732   
733   /* mark the registers as free */
734   for (i = 0; i < ssym->nRegs; i++) {
735     if (ssym->regs[i]) {
736       freeReg (ssym->regs[i], FALSE);
737       // dont NULL ssym->regs[i], it might be used later
738     }
739   }
740   
741   /* if this was a block level spil then insert push & pop 
742      at the start & end of block respectively */
743   if (ssym->blockSpil)
744     {
745       iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
746       /* add push to the start of the block */
747       addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
748                                     ebp->sch->next : ebp->sch));
749       nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
750       /* add pop to the end of the block */
751       addiCodeToeBBlock (ebp, nic, NULL);
752     }
753   
754   /* if spilt because not used in the remainder of the
755      block then add a push before this instruction and
756      a pop at the end of the block */
757   if (ssym->remainSpil)
758     {
759       
760       iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
761       /* add push just before this instruction */
762       addiCodeToeBBlock (ebp, nic, ic);
763       
764       nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
765       /* add pop to the end of the block */
766       addiCodeToeBBlock (ebp, nic, NULL);
767     }
768   
769   if (ssym == forSym)
770     return FALSE;
771   else
772     return TRUE;
773 }
774
775 /*-----------------------------------------------------------------*/
776 /* getRegPtr - will try for PTR if not a GPR type if not spil      */
777 /*-----------------------------------------------------------------*/
778 static bool getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym, short offset) {
779   
780   D0(fprintf (stderr, "getRegPtr: %s ", sym->name));
781   D0(printTypeChain(sym->type, stderr));
782   D0(fprintf (stderr, "\n"));
783   
784   while (1) {
785     /* this looks like an infinite loop but 
786        in really selectSpil will abort  */
787     
788     /* try for a ptr type */
789     if (allocReg (getSize(sym->type), REG_PTR, sym, offset, FALSE))
790       return TRUE;
791     
792     /* try for gpr type */
793     if (xa51HasGprRegs && allocReg (getSize(sym->type), 
794                                     REG_GPR, sym, offset, FALSE))
795       return TRUE;
796     
797     /* we have to spil */
798     if (!spillSomething (ic, ebp, sym))
799       return FALSE;
800     
801   }
802 }
803
804 /*-----------------------------------------------------------------*/
805 /* getRegGpr - will try for GPR if not spil                        */
806 /*-----------------------------------------------------------------*/
807 static bool getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym, short offset) {
808   
809   D0(fprintf (stderr, "getRegGpr: %s ", sym->name));
810   D0(printTypeChain(sym->type, stderr));
811   D0(fprintf (stderr, "\n"));
812   
813   while(1) {
814     /* this looks like an infinite loop but 
815        in really selectSpil will abort  */
816     
817     /* try for gpr type */
818     if (xa51HasGprRegs && allocReg (getSize(sym->type), 
819                                     REG_GPR, sym, offset, FALSE))
820       return TRUE;
821     
822     if (allocReg (getSize(sym->type), REG_PTR, sym, offset, FALSE))
823       return TRUE;
824     
825     /* we have to spil */
826     if (!spillSomething (ic, ebp, sym))
827       return FALSE;
828   }
829 }
830
831 /*-----------------------------------------------------------------*/
832 /* deassignLRs - check the live to and if they have registers & are */
833 /*               not spilt then free up the registers              */
834 /*-----------------------------------------------------------------*/
835 static void
836 deassignLRs (iCode * ic, eBBlock * ebp)
837 {
838   symbol *sym;
839   int k;
840   
841   for (sym = hTabFirstItem (liveRanges, &k); sym;
842        sym = hTabNextItem (liveRanges, &k))
843     {
844       /* if it does not end here */
845       if (sym->liveTo > ic->seq)
846         continue;
847       
848       /* if it was spilt on stack then we can 
849          mark the stack spil location as free */
850       if (sym->isspilt)
851         {
852           if (sym->stackSpil)
853             {
854               sym->usl.spillLoc->isFree = 1;
855               sym->stackSpil = 0;
856             }
857           continue;
858         }
859       
860       if (!bitVectBitValue (_G.regAssigned, sym->key))
861         continue;
862       
863       if (sym->nRegs) {
864         int i;
865         
866         bitVectUnSetBit (_G.regAssigned, sym->key);
867         
868         /* free the regs */
869         for (i=0; i < sym->nRegs; i++) {
870           freeReg (sym->regs[i], FALSE);
871         }
872       }
873     }
874 }
875
876 /*-----------------------------------------------------------------*/
877 /* willCauseSpill - determines if allocating will cause a spill    */
878 /*-----------------------------------------------------------------*/
879 static bool willCauseSpill (symbol *sym) {
880   int i;
881   // do it the rude way
882   if (allocReg (getSize(sym->type), sym->regType, sym, 0, TRUE) ||
883       allocReg (getSize(sym->type), sym->regType==REG_PTR?REG_GPR:REG_PTR, 
884                 sym, 0, TRUE)) {
885     // so we can, but we won't
886     for (i=0; i<sym->nRegs; i++) {
887       freeReg (sym->regs[i], TRUE);
888       sym->regs[i]=NULL;
889     }
890     return FALSE;
891   }
892   D1(fprintf (stderr, "  %s will cause a spill\n", sym->name));
893   return TRUE;
894 }
895
896 /*-----------------------------------------------------------------*/
897 /* positionRegs - the allocator can allocate same registers to res- */
898 /* ult and operand, if this happens make sure they are in the same */
899 /* position as the operand otherwise chaos results                 */
900 /*-----------------------------------------------------------------*/
901 static int
902 positionRegs (symbol * result, symbol * opsym)
903 {
904   int count = min (result->nRegs, opsym->nRegs);
905   int i, j = 0, shared = 0;
906   int changed = 0;
907   
908   /* if the result has been spilt then cannot share */
909   if (opsym->isspilt)
910     return 0;
911  again:
912   shared = 0;
913   /* first make sure that they actually share */
914   for (i = 0; i < count; i++)
915     {
916       for (j = 0; j < count; j++)
917         {
918           if (result->regs[i] == opsym->regs[j] && i != j)
919             {
920               shared = 1;
921               goto xchgPositions;
922             }
923         }
924     }
925  xchgPositions:
926   if (shared)
927     {
928       regs *tmp = result->regs[i];
929       result->regs[i] = result->regs[j];
930       result->regs[j] = tmp;
931       changed ++;
932       D2(fprintf (stderr, "positionRegs: rearranged regs for %s and %s\n",
933                   result->name, opsym->name));
934       goto again;
935     }
936   return changed;
937 }
938
939 /*-----------------------------------------------------------------*/
940 /* serialRegAssign - serially allocate registers to the variables  */
941 /*-----------------------------------------------------------------*/
942 static void
943 serialRegAssign (eBBlock ** ebbs, int count)
944 {
945   int i;
946   
947   /* for all blocks */
948   for (i = 0; i < count; i++) {
949     
950     iCode *ic;
951     
952     if (ebbs[i]->noPath &&
953         (ebbs[i]->entryLabel != entryLabel &&
954          ebbs[i]->entryLabel != returnLabel))
955       continue;
956     
957     /* of all instructions do */
958     for (ic = ebbs[i]->sch; ic; ic = ic->next) {
959       
960       /* if result is present && is a true symbol */
961       if (IC_RESULT (ic) && ic->op != IFX &&
962           IS_TRUE_SYMOP (IC_RESULT (ic))) {
963         OP_SYMBOL (IC_RESULT (ic))->allocreq++;
964       }
965       
966       /* take away registers from live
967          ranges that end at this instruction */
968       deassignLRs (ic, ebbs[i]);
969       
970       /* some don't need registers */
971       if (SKIP_IC2 (ic) ||
972           ic->op == JUMPTABLE ||
973           ic->op == IFX ||
974           ic->op == IPUSH ||
975           ic->op == IPOP ||
976           (IC_RESULT (ic) && POINTER_SET (ic)))
977         continue;
978       
979       /* now we need to allocate registers
980          only for the result */
981       if (IC_RESULT (ic)) {
982         symbol *sym = OP_SYMBOL (IC_RESULT (ic));
983         bitVect *spillable;
984         int willCS;
985         
986         /* if it does not need or is spilt 
987            or is already assigned to registers
988            or will not live beyond this instructions */
989         if (!sym->nRegs ||
990             sym->isspilt ||
991             bitVectBitValue (_G.regAssigned, sym->key) ||
992             sym->liveTo <= ic->seq)
993           continue;
994         
995         /* if some liverange has been spilt at the block level
996            and this one live beyond this block then spil this
997            to be safe */
998         if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq) {
999           spillThis (sym);
1000           continue;
1001         }
1002         /* if trying to allocate this will cause
1003            a spill and there is nothing to spill 
1004            or this one is rematerializable then
1005            spill this one */
1006         willCS = willCauseSpill (sym);
1007         spillable = computeSpillable (ic);
1008         if (sym->remat || (willCS && bitVectIsZero (spillable))) {                    
1009           spillThis (sym);
1010           continue;                   
1011         }
1012         
1013         /* if it has a spillocation & is used less than
1014            all other live ranges then spill this */
1015         if (willCS) {
1016           if (sym->usl.spillLoc) {
1017             symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
1018                                                              allLRs, ebbs[i], ic));
1019             if (leastUsed && leastUsed->used > sym->used) {
1020               spillThis (sym);
1021               continue;
1022             }
1023           } else {
1024             /* if none of the liveRanges have a spillLocation then better
1025                to spill this one than anything else already assigned to registers */
1026             if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
1027               /* if this is local to this block then we might find a block spil */
1028               if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
1029                 spillThis (sym);
1030                 continue;
1031               }
1032             }
1033           }
1034         }
1035         
1036         /* else we assign registers to it */
1037         _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1038         _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key);
1039         
1040         if (sym->regType == REG_PTR)
1041           getRegPtr (ic, ebbs[i], sym, 0);
1042         else
1043           getRegGpr (ic, ebbs[i], sym, 0);
1044         
1045         /* if it shares registers with operands make sure
1046            that they are in the same position */
1047         if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
1048             OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=') {
1049           positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1050                         OP_SYMBOL (IC_LEFT (ic)));
1051         }
1052         /* do the same for the right operand */
1053         if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
1054             OP_SYMBOL (IC_RIGHT (ic))->nRegs) {
1055           positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1056                         OP_SYMBOL (IC_RIGHT (ic)));
1057         }
1058       }
1059     }
1060   }
1061 }
1062
1063 /*-----------------------------------------------------------------*/
1064 /* rUmaskForOp :- returns register mask for an operand             */
1065 /*-----------------------------------------------------------------*/
1066 bitVect *xa51_rUmaskForOp (operand * op) {
1067   bitVect *rumask;
1068   symbol *sym;
1069   int j;
1070   
1071   /* only temporaries are assigned registers */
1072   if (!IS_ITEMP (op))
1073     return NULL;
1074   
1075   sym = OP_SYMBOL (op);
1076   
1077   /* if spilt or no registers assigned to it 
1078      then nothing */
1079   if (sym->isspilt || !sym->nRegs || !sym->regs[0])
1080     return NULL;
1081   
1082   rumask = newBitVect (xa51_nRegs);
1083   
1084   for (j = 0; j < sym->nRegs; j++) {
1085     rumask = bitVectSetBit (rumask,
1086                             sym->regs[j]->rIdx);
1087   }
1088   return rumask;
1089 }
1090
1091 /*-----------------------------------------------------------------*/
1092 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
1093 /*-----------------------------------------------------------------*/
1094 static bitVect *
1095 regsUsedIniCode (iCode * ic)
1096 {
1097   bitVect *rmask = newBitVect (xa51_nRegs);
1098   
1099   /* do the special cases first */
1100   if (ic->op == IFX)
1101     {
1102       rmask = bitVectUnion (rmask,
1103                             xa51_rUmaskForOp (IC_COND (ic)));
1104       goto ret;
1105     }
1106   
1107   /* for the jumptable */
1108   if (ic->op == JUMPTABLE)
1109     {
1110       rmask = bitVectUnion (rmask,
1111                             xa51_rUmaskForOp (IC_JTCOND (ic)));
1112       
1113       goto ret;
1114     }
1115   
1116   /* of all other cases */
1117   if (IC_LEFT (ic))
1118     rmask = bitVectUnion (rmask,
1119                           xa51_rUmaskForOp (IC_LEFT (ic)));
1120   
1121   
1122   if (IC_RIGHT (ic))
1123     rmask = bitVectUnion (rmask,
1124                           xa51_rUmaskForOp (IC_RIGHT (ic)));
1125   
1126   if (IC_RESULT (ic))
1127     rmask = bitVectUnion (rmask,
1128                           xa51_rUmaskForOp (IC_RESULT (ic)));
1129   
1130  ret:
1131   return rmask;
1132 }
1133
1134 /*-----------------------------------------------------------------*/
1135 /* createRegMask - for each instruction will determine the regsUsed */
1136 /*-----------------------------------------------------------------*/
1137 static void
1138 createRegMask (eBBlock ** ebbs, int count)
1139 {
1140   int i;
1141   
1142   /* for all blocks */
1143   for (i = 0; i < count; i++)
1144     {
1145       iCode *ic;
1146       
1147       if (ebbs[i]->noPath &&
1148           (ebbs[i]->entryLabel != entryLabel &&
1149            ebbs[i]->entryLabel != returnLabel))
1150         continue;
1151       
1152       /* for all instructions */
1153       for (ic = ebbs[i]->sch; ic; ic = ic->next)
1154         {
1155           
1156           int j;
1157           
1158           if (SKIP_IC2 (ic) || !ic->rlive)
1159             continue;
1160           
1161           /* first mark the registers used in this
1162              instruction */
1163           ic->rUsed = regsUsedIniCode (ic);
1164           _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
1165           
1166           /* now create the register mask for those 
1167              registers that are in use : this is a
1168              super set of ic->rUsed */
1169           ic->rMask = newBitVect (xa51_nRegs + 1);
1170           
1171           /* for all live Ranges alive at this point */
1172           for (j = 1; j < ic->rlive->size; j++)
1173             {
1174               symbol *sym;
1175               int k;
1176               
1177               /* if not alive then continue */
1178               if (!bitVectBitValue (ic->rlive, j))
1179                 continue;
1180               
1181               /* find the live range we are interested in */
1182               if (!(sym = hTabItemWithKey (liveRanges, j)))
1183                 {
1184                   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1185                           "createRegMask cannot find live range");
1186                   exit (0);
1187                 }
1188               
1189               /* if no register assigned to it */
1190               if (!sym->nRegs || sym->isspilt)
1191                 continue;
1192               
1193               /* for all the registers allocated to it */
1194               for (k = 0; k < sym->nRegs; k++)
1195                 if (sym->regs[k])
1196                   ic->rMask =
1197                     bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
1198             }
1199         }
1200     }
1201 }
1202
1203 /*-----------------------------------------------------------------*/
1204 /* rematStr - returns the rematerialized string for a remat var    */
1205 /*-----------------------------------------------------------------*/
1206 static char *
1207 rematStr (symbol * sym)
1208 {
1209   char *s = buffer;
1210   iCode *ic = sym->rematiCode;
1211   
1212   while (1)
1213     {
1214       
1215       /* if plus or minus print the right hand side */
1216       if (ic->op == '+' || ic->op == '-')
1217         {
1218           sprintf (s, "0x%04x %c ", (int) operandLitValue (IC_RIGHT (ic)),
1219                    ic->op);
1220           s += strlen (s);
1221           ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1222           continue;
1223         }
1224       
1225       /* cast then continue */
1226       if (IS_CAST_ICODE(ic)) {
1227         ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
1228         continue;
1229       }
1230       /* we reached the end */
1231       sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
1232       break;
1233     }
1234   
1235   return buffer;
1236 }
1237
1238 /*-----------------------------------------------------------------*/
1239 /* regTypeNum - computes the type & number of registers required   */
1240 /*-----------------------------------------------------------------*/
1241 static void
1242 regTypeNum (eBBlock *ebbs)
1243 {
1244   symbol *sym;
1245   int k;
1246   iCode *ic;
1247   
1248   /* for each live range do */
1249   for (sym = hTabFirstItem (liveRanges, &k); sym;
1250        sym = hTabNextItem (liveRanges, &k))
1251     {
1252       
1253       /* if used zero times then no registers needed */
1254       if ((sym->liveTo - sym->liveFrom) == 0)
1255         continue;
1256       
1257       
1258       /* if the live range is a temporary */
1259       if (sym->isitmp)
1260         {
1261           
1262           /* if the type is marked as a conditional */
1263           if (sym->regType == REG_CND)
1264             continue;
1265           
1266           /* if used in return only then we don't 
1267              need registers */
1268 #if 0 // not yet
1269           if (sym->ruonly || sym->accuse)
1270             {
1271               if (IS_AGGREGATE (sym->type) || sym->isptr)
1272                 sym->type = aggrToPtr (sym->type, FALSE);
1273               continue;
1274             }
1275 #endif
1276           
1277           /* if the symbol has only one definition &
1278              that definition is a get_pointer */
1279           if (bitVectnBitsOn (sym->defs) == 1 &&
1280               (ic = hTabItemWithKey (iCodehTab,
1281                                      bitVectFirstBit (sym->defs))) &&
1282               POINTER_GET (ic) &&
1283               !sym->noSpilLoc &&
1284               !IS_BITVAR (sym->etype))
1285             {
1286               /* and that pointer is remat in data space */
1287               if (OP_SYMBOL (IC_LEFT (ic))->remat &&
1288                   !IS_CAST_ICODE(OP_SYMBOL (IC_LEFT (ic))->rematiCode) &&
1289                   DCL_TYPE (aggrToPtr (operandType(IC_LEFT(ic)), FALSE)) == POINTER)
1290                 {
1291                   /* create a psuedo symbol & force a spil */
1292                   symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
1293                   psym->type = sym->type;
1294                   psym->etype = sym->etype;
1295                   strcpy (psym->rname, psym->name);
1296                   sym->isspilt = 1;
1297                   sym->usl.spillLoc = psym;
1298 #if 0 // an alternative fix for bug #480076
1299                   /* now this is a useless assignment to itself */
1300                   remiCodeFromeBBlock (ebbs, ic);
1301 #else
1302                   /* now this really is an assignment to itself, make it so;
1303                      it will be optimized out later */
1304                   ic->op='=';
1305                   IC_RIGHT(ic)=IC_RESULT(ic);
1306                   IC_LEFT(ic)=NULL;
1307 #endif
1308                   continue;
1309                 }
1310               
1311               /* if in data space or idata space then try to
1312                  allocate pointer register */
1313               
1314             }
1315           
1316           /* if not then we require registers */
1317 #if 0
1318           sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
1319                         getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1320                         getSize (sym->type));
1321 #else
1322           {
1323             int size=((IS_AGGREGATE (sym->type) || sym->isptr) ?
1324                       getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1325                       getSize (sym->type));
1326             switch (size) 
1327               {
1328               case 1: // byte
1329               case 2: // word or pointer
1330                 sym->nRegs=1;
1331                 break;
1332               case 3: // generic pointer
1333                 sym->nRegs=2;
1334                 break;
1335               case 4: // dword or float
1336                 sym->nRegs=2;
1337                 break;
1338               default: 
1339                 fprintf (stderr, "regTypeNum: unknown size\n");
1340                 exit (1);
1341               }
1342           }
1343 #endif
1344           
1345           if (sym->nRegs > 4)
1346             {
1347               fprintf (stderr, "allocated more than 4 or 0 registers for type ");
1348               printTypeChain (sym->type, stderr);
1349               fprintf (stderr, "\n");
1350               exit (1);
1351             }
1352           
1353           /* determine the type of register required */
1354           if (IS_PTR (sym->type))
1355             sym->regType = REG_PTR;
1356           else
1357             sym->regType = REG_GPR;
1358           
1359         }
1360       else
1361         /* for the first run we don't provide */
1362         /* registers for true symbols we will */
1363         /* see how things go                  */
1364         sym->nRegs = 0;
1365     }
1366   
1367 }
1368
1369 /*-----------------------------------------------------------------*/
1370 /* deallocStackSpil - this will set the stack pointer back         */
1371 /*-----------------------------------------------------------------*/
1372 static
1373 DEFSETFUNC (deallocStackSpil)
1374 {
1375   symbol *sym = item;
1376   
1377   deallocLocal (sym);
1378   return 0;
1379 }
1380
1381 /*-----------------------------------------------------------------*/
1382 /* packRegsForAssign - register reduction for assignment           */
1383 /*-----------------------------------------------------------------*/
1384 static int
1385 packRegsForAssign (iCode * ic, eBBlock * ebp)
1386 {
1387   iCode *dic, *sic;
1388   
1389   if (!IS_ITEMP (IC_RIGHT (ic)) ||
1390       OP_LIVETO (IC_RIGHT (ic)) > ic->seq) {
1391     return 0;
1392   }
1393
1394   /* find the definition of iTempNN scanning backwards */
1395   for (dic = ic->prev; dic; dic = dic->prev) {
1396     
1397     /* if there is a function call then don't pack it */
1398     if ((dic->op == CALL || dic->op == PCALL)) {
1399       dic = NULL;
1400       break;
1401     }
1402     
1403     if (SKIP_IC2 (dic))
1404       continue;
1405     
1406     if (IS_SYMOP (IC_RESULT (dic)) &&
1407         IC_RESULT (dic)->key == IC_RIGHT (ic)->key) {
1408       break;
1409     }
1410     
1411   }
1412   
1413   if (!dic)
1414     return 0;                   /* did not find */
1415
1416   /* found the definition */
1417   /* replace the result with the result of */
1418   /* this assignment and remove this assignment */
1419   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1420   IC_RESULT (dic) = IC_RESULT (ic);
1421   
1422   if (IS_ITEMP (IC_RESULT (dic)) && 
1423       OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
1424     {
1425       OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
1426     }
1427   /* delete from liverange table also 
1428      delete from all the points inbetween and the new
1429      one */
1430   for (sic = dic; sic != ic; sic = sic->next)
1431     {
1432       bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
1433       if (IS_ITEMP (IC_RESULT (dic)))
1434         bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
1435     }
1436   
1437   remiCodeFromeBBlock (ebp, ic);
1438   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
1439   hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
1440   OP_DEFS_SET ((IC_RESULT (dic)), bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key));
1441   return 1;
1442   
1443 }
1444
1445 /*-----------------------------------------------------------------*/
1446 /* findAssignToSym : scanning backwards looks for first assig found */
1447 /*-----------------------------------------------------------------*/
1448 static iCode *
1449 findAssignToSym (operand * op, iCode * ic)
1450 {
1451   iCode *dic;
1452   
1453   for (dic = ic->prev; dic; dic = dic->prev)
1454     {
1455       
1456       /* if definition by assignment */
1457       if (dic->op == '=' &&
1458           !POINTER_SET (dic) &&
1459           IC_RESULT (dic)->key == op->key
1460           /*          &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) */
1461           )
1462         {
1463           
1464           /* we are interested only if defined in far space */
1465           /* or in stack space in case of + & - */
1466           
1467           /* if assigned to a non-symbol then return
1468              FALSE */
1469           if (!IS_SYMOP (IC_RIGHT (dic)))
1470             return NULL;
1471           
1472           /* if the symbol is in far space then
1473              we should not */
1474           if (isOperandInFarSpace (IC_RIGHT (dic)))
1475             return NULL;
1476           
1477           /* for + & - operations make sure that
1478              if it is on the stack it is the same
1479              as one of the three operands */
1480           if ((ic->op == '+' || ic->op == '-') &&
1481               OP_SYMBOL (IC_RIGHT (dic))->onStack)
1482             {
1483               
1484               if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
1485                   IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
1486                   IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
1487                 return NULL;
1488             }
1489           
1490           break;
1491           
1492         }
1493       
1494       /* if we find an usage then we cannot delete it */
1495       if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
1496         return NULL;
1497       
1498       if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
1499         return NULL;
1500       
1501       if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
1502         return NULL;
1503     }
1504   
1505   /* now make sure that the right side of dic
1506      is not defined between ic & dic */
1507   if (dic)
1508     {
1509       iCode *sic = dic->next;
1510       
1511       for (; sic != ic; sic = sic->next)
1512         if (IC_RESULT (sic) &&
1513             IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
1514           return NULL;
1515     }
1516   
1517   return dic;
1518   
1519   
1520 }
1521
1522 /*-----------------------------------------------------------------*/
1523 /* packRegsForSupport :- reduce some registers for support calls   */
1524 /*-----------------------------------------------------------------*/
1525 static int
1526 packRegsForSupport (iCode * ic, eBBlock * ebp)
1527 {
1528   int change = 0;
1529   iCode *dic, *sic;
1530   
1531   /* for the left & right operand :- look to see if the
1532      left was assigned a true symbol in far space in that
1533      case replace them */
1534
1535   if (IS_ITEMP (IC_LEFT (ic)) &&
1536       OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
1537     {
1538       dic = findAssignToSym (IC_LEFT (ic), ic);
1539       
1540       if (!dic)
1541         goto right;
1542       
1543       /* found it we need to remove it from the
1544          block */
1545       for (sic = dic; sic != ic; sic = sic->next)
1546         bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
1547       
1548       OP_SYMBOL(IC_LEFT (ic))=OP_SYMBOL(IC_RIGHT (dic));
1549       IC_LEFT (ic)->key = OP_SYMBOL(IC_RIGHT (dic))->key;
1550       remiCodeFromeBBlock (ebp, dic);
1551       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1552       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1553       change++;
1554     }
1555   
1556   /* do the same for the right operand */
1557  right:
1558   if (!change &&
1559       IS_ITEMP (IC_RIGHT (ic)) &&
1560       OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
1561     {
1562       iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
1563       iCode *sic;
1564       
1565       if (!dic)
1566         return change;
1567       
1568       /* if this is a subtraction & the result
1569          is a true symbol in far space then don't pack */
1570       if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
1571         {
1572           sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
1573           if (IN_FARSPACE (SPEC_OCLS (etype)))
1574             return change;
1575         }
1576       /* found it we need to remove it from the
1577          block */
1578       for (sic = dic; sic != ic; sic = sic->next)
1579         bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
1580       
1581       IC_RIGHT (ic)->operand.symOperand =
1582         IC_RIGHT (dic)->operand.symOperand;
1583       IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
1584       
1585       remiCodeFromeBBlock (ebp, dic);
1586       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1587       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1588       change++;
1589     }
1590   
1591   return change;
1592 }
1593
1594 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
1595
1596
1597 /*-----------------------------------------------------------------*/
1598 /* packRegsForOneuse : - will reduce some registers for single Use */
1599 /*-----------------------------------------------------------------*/
1600 static iCode *
1601 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
1602 {
1603   bitVect *uses;
1604   iCode *dic, *sic;
1605
1606   /* if returning a literal then do nothing */
1607   if (!IS_SYMOP (op))
1608     return NULL;
1609   
1610   if (ic->op != RETURN &&
1611       ic->op != SEND &&
1612       !POINTER_SET (ic) &&
1613       !POINTER_GET (ic))
1614     return NULL;
1615   
1616   /* this routine will mark the a symbol as used in one 
1617      instruction use only && if the defintion is local 
1618      (ie. within the basic block) && has only one definition &&
1619      that definiion is either a return value from a 
1620      function or does not contain any variables in
1621      far space */
1622   uses = bitVectCopy (OP_USES (op));
1623   bitVectUnSetBit (uses, ic->key);      /* take away this iCode */
1624   if (!bitVectIsZero (uses))    /* has other uses */
1625     return NULL;
1626   
1627   /* if it has only one defintion */
1628   if (bitVectnBitsOn (OP_DEFS (op)) > 1)
1629     return NULL;                /* has more than one definition */
1630   
1631   /* get that definition */
1632   if (!(dic =
1633         hTabItemWithKey (iCodehTab,
1634                          bitVectFirstBit (OP_DEFS (op)))))
1635     return NULL;
1636   
1637 #if 0
1638   /* if that only usage is a cast */
1639   if (dic->op == CAST) {
1640     /* to a bigger type */
1641     if (getSize(OP_SYM_TYPE(IC_RESULT(dic))) > 
1642         getSize(OP_SYM_TYPE(IC_RIGHT(dic)))) {
1643       /* than we can not, since we cannot predict the usage of b & acc */
1644       return NULL;
1645     }
1646   }
1647 #endif
1648   
1649   /* found the definition now check if it is local */
1650   if (dic->seq < ebp->fSeq ||
1651       dic->seq > ebp->lSeq)
1652     return NULL;                /* non-local */
1653   
1654   /* now check if it is the return from
1655      a function call */
1656   if (dic->op == CALL || dic->op == PCALL)
1657     {
1658       if (ic->op != SEND && ic->op != RETURN &&
1659           !POINTER_SET(ic) && !POINTER_GET(ic))
1660         {
1661           OP_SYMBOL (op)->ruonly = 1;
1662           return dic;
1663         }
1664       dic = dic->next;
1665     }
1666   
1667 #if 0  
1668   /* otherwise check that the definition does
1669      not contain any symbols in far space */
1670   if (isOperandInFarSpace (IC_LEFT (dic)) ||
1671       isOperandInFarSpace (IC_RIGHT (dic)) ||
1672       IS_OP_RUONLY (IC_LEFT (ic)) ||
1673       IS_OP_RUONLY (IC_RIGHT (ic)))
1674     {
1675       return NULL;
1676     }
1677 #endif
1678
1679 #if 0  
1680   /* if pointer set then make sure the pointer
1681      is one byte */
1682   if (POINTER_SET (dic) &&
1683       !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
1684     return NULL;
1685   
1686   if (POINTER_GET (dic) &&
1687       !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
1688     return NULL;
1689 #endif
1690   
1691   sic = dic;
1692   
1693   /* also make sure the intervenening instructions
1694      don't have any thing in far space */
1695   for (dic = dic->next; dic && dic != ic && sic != ic; dic = dic->next)
1696     {
1697       
1698       /* if there is an intervening function call then no */
1699       if (dic->op == CALL || dic->op == PCALL)
1700         return NULL;
1701
1702 #if 0
1703       /* if pointer set then make sure the pointer
1704          is one byte */
1705       if (POINTER_SET (dic) &&
1706           !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
1707         return NULL;
1708       
1709       if (POINTER_GET (dic) &&
1710           !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
1711         return NULL;
1712 #endif
1713       
1714       /* if address of & the result is remat the okay */
1715       if (dic->op == ADDRESS_OF &&
1716           OP_SYMBOL (IC_RESULT (dic))->remat)
1717         continue;
1718
1719 #if 0      
1720       /* if operand has size of three or more & this
1721          operation is a '*','/' or '%' then 'b' may
1722          cause a problem */
1723       if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
1724           getSize (operandType (op)) >= 3)
1725         return NULL;
1726 #endif
1727       
1728 #if 0
1729       /* if left or right or result is in far space */
1730       if (isOperandInFarSpace (IC_LEFT (dic)) ||
1731           isOperandInFarSpace (IC_RIGHT (dic)) ||
1732           isOperandInFarSpace (IC_RESULT (dic)) ||
1733           IS_OP_RUONLY (IC_LEFT (dic)) ||
1734           IS_OP_RUONLY (IC_RIGHT (dic)) ||
1735           IS_OP_RUONLY (IC_RESULT (dic)))
1736         {
1737           return NULL;
1738         }
1739       /* if left or right or result is on stack */
1740       if (isOperandOnStack(IC_LEFT(dic)) ||
1741           isOperandOnStack(IC_RIGHT(dic)) ||
1742           isOperandOnStack(IC_RESULT(dic))) {
1743         return NULL;
1744       }
1745 #endif
1746     }
1747   
1748   OP_SYMBOL (op)->ruonly = 1;
1749   fprintf (stderr, "%s is used only once in line %d.\n", 
1750            OP_SYMBOL(op)->name, ic->lineno);
1751   return sic;
1752   
1753 }
1754
1755 /*-----------------------------------------------------------------*/
1756 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
1757 /*-----------------------------------------------------------------*/
1758 static bool
1759 isBitwiseOptimizable (iCode * ic)
1760 {
1761   sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
1762   sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
1763   
1764   /* bitwise operations are considered optimizable
1765      under the following conditions (Jean-Louis VERN) 
1766      
1767      x & lit
1768      bit & bit
1769      bit & x
1770      bit ^ bit
1771      bit ^ x
1772      x   ^ lit
1773      x   | lit
1774      bit | bit
1775      bit | x
1776   */
1777   if (IS_LITERAL(rtype) ||
1778       (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
1779     return TRUE;
1780   else
1781     return FALSE;
1782 }
1783
1784 /*-----------------------------------------------------------------*/
1785 /* packForPush - hueristics to reduce iCode for pushing            */
1786 /*-----------------------------------------------------------------*/
1787 static void
1788 packForPush (iCode * ic, eBBlock * ebp)
1789 {
1790   iCode *dic, *lic;
1791   bitVect *dbv;
1792
1793   if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
1794     return;
1795   
1796   /* must have only definition & one usage */
1797   if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
1798       bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
1799     return;
1800   
1801   /* find the definition */
1802   if (!(dic = hTabItemWithKey (iCodehTab,
1803                                bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
1804     return;
1805   
1806   if (dic->op != '=' || POINTER_SET (dic))
1807     return;
1808   
1809   /* make sure the right side does not have any definitions
1810      inbetween */
1811   dbv = OP_DEFS(IC_RIGHT(dic));
1812   for (lic = ic; lic && lic != dic ; lic = lic->prev) {
1813     if (bitVectBitValue(dbv,lic->key)) 
1814       return ;
1815   }
1816   /* make sure they have the same type */
1817   {
1818     sym_link *itype=operandType(IC_LEFT(ic));
1819     sym_link *ditype=operandType(IC_RIGHT(dic));
1820     
1821     if (SPEC_USIGN(itype)!=SPEC_USIGN(ditype) ||
1822         SPEC_LONG(itype)!=SPEC_LONG(ditype))
1823       return;
1824   }
1825   /* extend the live range of replaced operand if needed */
1826   if (OP_SYMBOL(IC_RIGHT(dic))->liveTo < ic->seq) {
1827     OP_SYMBOL(IC_RIGHT(dic))->liveTo = ic->seq;
1828   }
1829   /* we now know that it has one & only one def & use
1830      and the that the definition is an assignment */
1831   IC_LEFT (ic) = IC_RIGHT (dic);
1832   
1833   remiCodeFromeBBlock (ebp, dic);
1834   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1835   hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1836 }
1837
1838 /*-----------------------------------------------------------------*/
1839 /* packRegisters - does some transformations to reduce register    */
1840 /*                   pressure                                      */
1841 /*-----------------------------------------------------------------*/
1842 static void packRegisters (eBBlock * ebp) {
1843   iCode *ic;
1844   int change = 0;
1845   
1846   while (1) {
1847     change = 0;
1848     
1849     for (ic = ebp->sch; ic; ic = ic->next) {
1850       if (ic->op == '=')
1851         change += packRegsForAssign (ic, ebp);
1852     }
1853     
1854     if (!change)
1855       break;
1856   }
1857   
1858   for (ic = ebp->sch; ic; ic = ic->next)
1859     {
1860       /* if the condition of an if instruction
1861          is defined in the previous instruction and
1862          this is the only usage then
1863          mark the itemp as a conditional */
1864       if ((IS_CONDITIONAL (ic) ||
1865            (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic)))) {
1866         if (ic->next && ic->next->op == IFX &&
1867             bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
1868             isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
1869             OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq) {
1870           OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
1871           continue;
1872         }
1873       }
1874
1875 #if 0
1876       /* if this is an itemp & result of an address of a true sym 
1877          then mark this as rematerialisable   */
1878       if (ic->op == ADDRESS_OF &&
1879           IS_ITEMP (IC_RESULT (ic)) &&
1880           IS_TRUE_SYMOP (IC_LEFT (ic)) &&
1881           bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
1882           !OP_SYMBOL (IC_LEFT (ic))->onStack)
1883         {
1884           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
1885           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
1886           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
1887         }
1888
1889       /* if straight assignment then carry remat flag if
1890          this is the only definition */
1891       if (ic->op == '=' &&
1892           !POINTER_SET (ic) &&
1893           IS_SYMOP (IC_RIGHT (ic)) &&
1894           OP_SYMBOL (IC_RIGHT (ic))->remat &&
1895           !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode) &&
1896           bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
1897         {
1898           
1899           OP_SYMBOL (IC_RESULT (ic))->remat =
1900             OP_SYMBOL (IC_RIGHT (ic))->remat;
1901           OP_SYMBOL (IC_RESULT (ic))->rematiCode =
1902             OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
1903         }
1904       
1905       /* if cast to a generic pointer & the pointer being
1906          cast is remat, then we can remat this cast as well */
1907       if (ic->op == CAST && 
1908           IS_SYMOP(IC_RIGHT(ic)) &&
1909           OP_SYMBOL(IC_RIGHT(ic))->remat ) {
1910         sym_link *to_type = operandType(IC_LEFT(ic));
1911         sym_link *from_type = operandType(IC_RIGHT(ic));
1912         if (IS_GENPTR(to_type) && IS_PTR(from_type)) {                
1913           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
1914           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
1915           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
1916         }
1917       }
1918       
1919       /* if this is a +/- operation with a rematerizable 
1920          then mark this as rematerializable as well */
1921       if ((ic->op == '+' || ic->op == '-') &&
1922           (IS_SYMOP (IC_LEFT (ic)) &&
1923            IS_ITEMP (IC_RESULT (ic)) &&
1924            IS_OP_LITERAL (IC_RIGHT (ic))) &&
1925           OP_SYMBOL (IC_LEFT (ic))->remat &&
1926           (!IS_SYMOP (IC_RIGHT (ic)) || !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode)) &&
1927           bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1)
1928         {
1929           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
1930           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
1931           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
1932         }
1933 #endif
1934       
1935       /* mark the pointer usages */
1936       if (POINTER_SET (ic))
1937         OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
1938       
1939       if (POINTER_GET (ic))
1940         OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
1941       
1942       /* reduce for support function calls */
1943       if (ic->supportRtn || ic->op == '+' || ic->op == '-')
1944         packRegsForSupport (ic, ebp);
1945       
1946       /* some cases the redundant moves can
1947          can be eliminated for return statements */
1948       if (ic->op == RETURN || ic->op == SEND) {
1949           packRegsForOneuse (ic, IC_LEFT (ic), ebp);
1950         }
1951       
1952       /* if pointer set & left has a size more than
1953          one and right is not in far space */
1954       if (POINTER_SET (ic) &&
1955           !isOperandInFarSpace (IC_RIGHT (ic)) &&
1956           !OP_SYMBOL (IC_RESULT (ic))->remat &&
1957           !IS_OP_RUONLY (IC_RIGHT (ic)) &&
1958           getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
1959         
1960         packRegsForOneuse (ic, IC_RESULT (ic), ebp);
1961       
1962       /* if pointer get */
1963       if (POINTER_GET (ic) &&
1964           !isOperandInFarSpace (IC_RESULT (ic)) &&
1965           !OP_SYMBOL (IC_LEFT (ic))->remat &&
1966           !IS_OP_RUONLY (IC_RESULT (ic)) &&
1967           getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
1968         
1969         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
1970       
1971       
1972       /* if this is cast for intergral promotion then
1973          check if only use of  the definition of the 
1974          operand being casted/ if yes then replace
1975          the result of that arithmetic operation with 
1976          this result and get rid of the cast */
1977       if (ic->op == CAST)
1978         {
1979           sym_link *fromType = operandType (IC_RIGHT (ic));
1980           sym_link *toType = operandType (IC_LEFT (ic));
1981           
1982           if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
1983               getSize (fromType) != getSize (toType) &&
1984               SPEC_USIGN (fromType) == SPEC_USIGN (toType))
1985             {
1986               
1987               iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
1988               if (dic)
1989                 {
1990                   if (IS_ARITHMETIC_OP (dic))
1991                     {                  
1992                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1993                       IC_RESULT (dic) = IC_RESULT (ic);
1994                       remiCodeFromeBBlock (ebp, ic);
1995                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
1996                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
1997                       OP_DEFS_SET ((IC_RESULT (dic)), bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key));
1998                       ic = ic->prev;
1999                     }
2000                   else
2001                     OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
2002                 }
2003             }
2004           else
2005             {
2006               
2007               /* if the type from and type to are the same
2008                  then if this is the only use then packit */
2009               if (compareType (operandType (IC_RIGHT (ic)),
2010                                operandType (IC_LEFT (ic))) == 1)
2011                 {
2012                   iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2013                   if (dic)
2014                     {
2015                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2016                       IC_RESULT (dic) = IC_RESULT (ic);
2017                       remiCodeFromeBBlock (ebp, ic);
2018                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2019                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2020                       OP_DEFS_SET ((IC_RESULT (dic)), bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key));
2021                       ic = ic->prev;
2022                     }
2023                 }
2024             }
2025         }
2026       
2027       /* pack for PUSH 
2028          iTempNN := (some variable in farspace) V1
2029          push iTempNN ;
2030          -------------
2031          push V1
2032       */
2033       if (ic->op == IPUSH)
2034         {
2035           packForPush (ic, ebp);
2036         }
2037     }
2038 }
2039
2040 /*-----------------------------------------------------------------*/
2041 /* assignRegisters - assigns registers to each live range as need  */
2042 /*-----------------------------------------------------------------*/
2043 void
2044 xa51_assignRegisters (eBBlock ** ebbs, int count)
2045 {
2046   iCode *ic;
2047   int i;
2048   
2049   setToNull ((void *) &_G.funcrUsed);
2050   setToNull ((void *) &_G.totRegAssigned);
2051   _G.stackExtend = 0;
2052   
2053   /* change assignments this will remove some
2054      live ranges reducing some register pressure */
2055   for (i = 0; i < count; i++)
2056     packRegisters (ebbs[i]);
2057   
2058   if (options.dump_pack)
2059     dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
2060   
2061   /* first determine for each live range the number of 
2062      registers & the type of registers required for each */
2063   regTypeNum (*ebbs);
2064   
2065   /* and serially allocate registers */
2066   serialRegAssign (ebbs, count);
2067   
2068   freeAllRegs ();
2069   
2070   /* if stack was extended then tell the user */
2071   if (_G.stackExtend)
2072     {
2073       werror(I_EXTENDED_STACK_SPILS,
2074              _G.stackExtend,currFunc->name,"");
2075       _G.stackExtend = 0;
2076     }
2077   
2078   /* after that create the register mask
2079      for each of the instruction */
2080   createRegMask (ebbs, count);
2081   
2082   /* redo that offsets for stacked automatic variables */
2083   redoStackOffsets ();
2084   
2085   if (options.dump_rassgn)
2086     {
2087       dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
2088       dumpLiveRanges (DUMP_LRANGE, liveRanges);
2089     }
2090   
2091   /* do the overlaysegment stuff SDCCmem.c */
2092   doOverlays (ebbs, count);
2093   
2094   /* now get back the chain */
2095   ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
2096   
2097   genXA51Code (ic);
2098   
2099   /* free up any _G.stackSpil locations allocated */
2100   applyToSet (_G.stackSpil, deallocStackSpil);
2101   _G.slocNum = 0;
2102   setToNull ((void **) &_G.stackSpil);
2103   setToNull ((void **) &_G.spiltSet);
2104   /* mark all registers as free */
2105   freeAllRegs ();
2106   
2107   return;
2108 }