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