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