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