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