* support/regression/fwk/lib/testfwk.c: printn is recursive and thus needs
[fw/sdcc] / src / hc08 / ralloc.c
1 /*------------------------------------------------------------------------
2
3   SDCCralloc.c - source file for register allocation. (8051) 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 genhc08Code (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 /* Shared with gen.c */
58 int hc08_ptrRegReq;             /* one byte pointer register required */
59
60 /* 8051 registers */
61 regs regshc08[] =
62 {
63
64   {REG_GPR, A_IDX, REG_GPR, "a", "a", "0", 1, NULL, 0, 1},
65   {REG_GPR, X_IDX, REG_GPR, "x", "x", "0", 2, NULL, 0, 1},
66   {REG_GPR, H_IDX, REG_GPR, "h", "h", "0", 4, NULL, 0, 1},
67   {REG_PTR, HX_IDX, REG_PTR, "hx", "hx", "0", 6, NULL, 0, 1},
68   {REG_GPR, XA_IDX, REG_GPR, "xa", "xa", "0", 3, NULL, 0, 1},
69
70   {REG_CND, CND_IDX, REG_CND, "C", "C", "xreg", 0, NULL, 0, 1},
71 };
72 int hc08_nRegs = 6;
73
74 regs *hc08_reg_a;
75 regs *hc08_reg_x;
76 regs *hc08_reg_h;
77 regs *hc08_reg_hx;
78 regs *hc08_reg_xa;
79
80 static void spillThis (symbol *);
81 static void freeAllRegs ();
82
83 /*-----------------------------------------------------------------*/
84 /* allocReg - allocates register of given type                     */
85 /*-----------------------------------------------------------------*/
86 static regs *
87 allocReg (short type)
88 {
89   return NULL;
90   
91   if ((type==REG_PTR) && (regshc08[HX_IDX].isFree))
92     {
93       regshc08[HX_IDX].isFree = 0;
94       if (currFunc)
95         currFunc->regsUsed =
96           bitVectSetBit (currFunc->regsUsed, HX_IDX);
97       return &regshc08[HX_IDX];
98     }
99   return NULL;
100 }
101
102 /*-----------------------------------------------------------------*/
103 /* hc08_regWithIdx - returns pointer to register wit index number       */
104 /*-----------------------------------------------------------------*/
105 regs *
106 hc08_regWithIdx (int idx)
107 {
108   int i;
109
110   for (i = 0; i < hc08_nRegs; i++)
111     if (regshc08[i].rIdx == idx)
112       return &regshc08[i];
113
114   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
115           "regWithIdx not found");
116   exit (1);
117 }
118
119 /*-----------------------------------------------------------------*/
120 /* hc08_freeReg - frees a register                                      */
121 /*-----------------------------------------------------------------*/
122 void
123 hc08_freeReg (regs * reg)
124 {
125   if (!reg)
126     {
127       werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
128               "hc08_freeReg - Freeing NULL register");
129       exit (1);
130     }
131
132   reg->isFree = 1;
133   
134   switch (reg->rIdx)
135     {
136       case A_IDX:
137         if (hc08_reg_x->isFree)
138           hc08_reg_xa->isFree = 1;
139         break;
140       case X_IDX:
141         if (hc08_reg_a->isFree)
142           hc08_reg_xa->isFree = 1;
143         if (hc08_reg_h->isFree)
144           hc08_reg_hx->isFree = 1;
145         break;
146       case H_IDX:
147         if (hc08_reg_x->isFree)
148           hc08_reg_hx->isFree = 1;
149         break;
150       case HX_IDX:
151         hc08_reg_h->isFree = 1;
152         hc08_reg_x->isFree = 1;
153         if (hc08_reg_a->isFree)
154           hc08_reg_xa->isFree = 1;
155         break;
156       case XA_IDX:
157         hc08_reg_x->isFree = 1;
158         hc08_reg_a->isFree = 1;
159         if (hc08_reg_h->isFree)
160           hc08_reg_hx->isFree = 1;
161         break;
162       default:
163         break;
164     }
165 }
166
167
168 /*-----------------------------------------------------------------*/
169 /* nFreeRegs - returns number of free registers                    */
170 /*-----------------------------------------------------------------*/
171 static int
172 nFreeRegs (int type)
173 {
174   int i;
175   int nfr = 0;
176
177   return 0;
178
179   for (i = 0; i < hc08_nRegs; i++)
180     if (regshc08[i].isFree && regshc08[i].type == type)
181       nfr++;
182   return nfr;
183 }
184
185 /*-----------------------------------------------------------------*/
186 /* nfreeRegsType - free registers with type                         */
187 /*-----------------------------------------------------------------*/
188 static int
189 nfreeRegsType (int type)
190 {
191   int nfr;
192   if (type == REG_PTR)
193     {
194       if ((nfr = nFreeRegs (type)) == 0)
195         return nFreeRegs (REG_GPR);
196     }
197
198   return nFreeRegs (type);
199 }
200
201 /*-----------------------------------------------------------------*/
202 /* hc08_useReg - marks a register  as used                         */
203 /*-----------------------------------------------------------------*/
204 void
205 hc08_useReg (regs * reg)
206 {
207   reg->isFree = 0;
208
209   switch (reg->rIdx)
210     {
211       case A_IDX:
212         hc08_reg_xa->aop = NULL;
213         hc08_reg_xa->isFree = 0;
214         break;
215       case X_IDX:
216         hc08_reg_xa->aop = NULL;
217         hc08_reg_xa->isFree = 0;
218         hc08_reg_hx->aop = NULL;
219         hc08_reg_hx->isFree = 0;
220         break;
221       case H_IDX:
222         hc08_reg_hx->aop = NULL;
223         hc08_reg_hx->isFree = 0;
224         break;
225       case HX_IDX:
226         hc08_reg_h->aop = NULL;
227         hc08_reg_h->isFree = 0;
228         hc08_reg_x->aop = NULL;
229         hc08_reg_x->isFree = 0;
230         break;
231       case XA_IDX:
232         hc08_reg_x->aop = NULL;
233         hc08_reg_x->isFree = 0;
234         hc08_reg_a->aop = NULL;
235         hc08_reg_a->isFree = 0;
236         break;
237       default:
238         break;
239     }
240
241 }
242
243 /*-----------------------------------------------------------------*/
244 /* hc08_dirtyReg - marks a register as dirty                       */
245 /*-----------------------------------------------------------------*/
246 void
247 hc08_dirtyReg (regs * reg, bool freereg)
248 {
249   reg->aop = NULL;
250
251   switch (reg->rIdx)
252     {
253       case A_IDX:
254         hc08_reg_xa->aop = NULL;
255         break;
256       case X_IDX:
257         hc08_reg_xa->aop = NULL;
258         hc08_reg_hx->aop = NULL;
259         break;
260       case H_IDX:
261         hc08_reg_hx->aop = NULL;
262         break;
263       case HX_IDX:
264         hc08_reg_h->aop = NULL;
265         hc08_reg_x->aop = NULL;
266         break;
267       case XA_IDX:
268         hc08_reg_x->aop = NULL;
269         hc08_reg_a->aop = NULL;
270         break;
271       default:
272         break;
273     }
274   if (freereg)
275     hc08_freeReg(reg);
276 }
277
278 /*-----------------------------------------------------------------*/
279 /* computeSpillable - given a point find the spillable live ranges */
280 /*-----------------------------------------------------------------*/
281 static bitVect *
282 computeSpillable (iCode * ic)
283 {
284   bitVect *spillable;
285
286   /* spillable live ranges are those that are live at this 
287      point . the following categories need to be subtracted
288      from this set. 
289      a) - those that are already spilt
290      b) - if being used by this one
291      c) - defined by this one */
292
293   spillable = bitVectCopy (ic->rlive);
294   spillable =
295     bitVectCplAnd (spillable, _G.spiltSet);     /* those already spilt */
296   spillable =
297     bitVectCplAnd (spillable, ic->uses);        /* used in this one */
298   bitVectUnSetBit (spillable, ic->defKey);
299   spillable = bitVectIntersect (spillable, _G.regAssigned);
300   return spillable;
301
302 }
303
304 /*-----------------------------------------------------------------*/
305 /* noSpilLoc - return true if a variable has no spil location      */
306 /*-----------------------------------------------------------------*/
307 static int
308 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
309 {
310   return (sym->usl.spillLoc ? 0 : 1);
311 }
312
313 /*-----------------------------------------------------------------*/
314 /* hasSpilLoc - will return 1 if the symbol has spil location      */
315 /*-----------------------------------------------------------------*/
316 static int
317 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
318 {
319   return (sym->usl.spillLoc ? 1 : 0);
320 }
321
322 /*-----------------------------------------------------------------*/
323 /* directSpilLoc - will return 1 if the splilocation is in direct  */
324 /*-----------------------------------------------------------------*/
325 static int
326 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
327 {
328   if (sym->usl.spillLoc &&
329       (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
330     return 1;
331   else
332     return 0;
333 }
334
335 /*-----------------------------------------------------------------*/
336 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
337 /*                    but is not used as a pointer                 */
338 /*-----------------------------------------------------------------*/
339 static int
340 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
341 {
342   return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
343 }
344
345 /*-----------------------------------------------------------------*/
346 /* rematable - will return 1 if the remat flag is set              */
347 /*-----------------------------------------------------------------*/
348 static int
349 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
350 {
351   return sym->remat;
352 }
353
354 /*-----------------------------------------------------------------*/
355 /* notUsedInRemaining - not used or defined in remain of the block */
356 /*-----------------------------------------------------------------*/
357 static int
358 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
359 {
360   return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
361           allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
362 }
363
364 /*-----------------------------------------------------------------*/
365 /* allLRs - return true for all                                    */
366 /*-----------------------------------------------------------------*/
367 static int
368 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
369 {
370   return 1;
371 }
372
373 /*-----------------------------------------------------------------*/
374 /* liveRangesWith - applies function to a given set of live range  */
375 /*-----------------------------------------------------------------*/
376 static set *
377 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
378                 eBBlock * ebp, iCode * ic)
379 {
380   set *rset = NULL;
381   int i;
382
383   if (!lrs || !lrs->size)
384     return NULL;
385
386   for (i = 1; i < lrs->size; i++)
387     {
388       symbol *sym;
389       if (!bitVectBitValue (lrs, i))
390         continue;
391
392       /* if we don't find it in the live range 
393          hash table we are in serious trouble */
394       if (!(sym = hTabItemWithKey (liveRanges, i)))
395         {
396           werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
397                   "liveRangesWith could not find liveRange");
398           exit (1);
399         }
400
401       if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
402         addSetHead (&rset, sym);
403     }
404
405   return rset;
406 }
407
408
409 /*-----------------------------------------------------------------*/
410 /* leastUsedLR - given a set determines which is the least used    */
411 /*-----------------------------------------------------------------*/
412 static symbol *
413 leastUsedLR (set * sset)
414 {
415   symbol *sym = NULL, *lsym = NULL;
416
417   sym = lsym = setFirstItem (sset);
418
419   if (!lsym)
420     return NULL;
421
422   for (; lsym; lsym = setNextItem (sset))
423     {
424
425       /* if usage is the same then prefer
426          the spill the smaller of the two */
427       if (lsym->used == sym->used)
428         if (getSize (lsym->type) < getSize (sym->type))
429           sym = lsym;
430
431       /* if less usage */
432       if (lsym->used < sym->used)
433         sym = lsym;
434
435     }
436
437   setToNull ((void **) &sset);
438   sym->blockSpil = 0;
439   return sym;
440 }
441
442 /*-----------------------------------------------------------------*/
443 /* noOverLap - will iterate through the list looking for over lap  */
444 /*-----------------------------------------------------------------*/
445 static int
446 noOverLap (set * itmpStack, symbol * fsym)
447 {
448   symbol *sym;
449
450
451   for (sym = setFirstItem (itmpStack); sym;
452        sym = setNextItem (itmpStack))
453     {
454         if (bitVectBitValue(sym->clashes,fsym->key)) return 0;
455     }
456
457   return 1;
458 }
459
460 /*-----------------------------------------------------------------*/
461 /* isFree - will return 1 if the a free spil location is found     */
462 /*-----------------------------------------------------------------*/
463 static
464 DEFSETFUNC (isFree)
465 {
466   symbol *sym = item;
467   V_ARG (symbol **, sloc);
468   V_ARG (symbol *, fsym);
469
470   /* if already found */
471   if (*sloc)
472     return 0;
473
474   /* if it is free && and the itmp assigned to
475      this does not have any overlapping live ranges
476      with the one currently being assigned and
477      the size can be accomodated  */
478   if (sym->isFree &&
479       noOverLap (sym->usl.itmpStack, fsym) &&
480       getSize (sym->type) >= getSize (fsym->type))
481     {
482       *sloc = sym;
483       return 1;
484     }
485
486   return 0;
487 }
488
489 /*-----------------------------------------------------------------*/
490 /* spillLRWithPtrReg :- will spil those live ranges which use PTR  */
491 /*-----------------------------------------------------------------*/
492 static void
493 spillLRWithPtrReg (symbol * forSym)
494 {
495   symbol *lrsym;
496   regs *hx;
497   int k;
498
499   if (!_G.regAssigned ||
500       bitVectIsZero (_G.regAssigned))
501     return;
502
503   hx = hc08_regWithIdx (HX_IDX);
504
505   /* for all live ranges */
506   for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
507        lrsym = hTabNextItem (liveRanges, &k))
508     {
509       int j;
510
511       /* if no registers assigned to it or spilt */
512       /* if it does not overlap with this then 
513          not need to spill it */
514
515       if (lrsym->isspilt || !lrsym->nRegs ||
516           (lrsym->liveTo < forSym->liveFrom))
517         continue;
518
519       /* go thru the registers : if it is either
520          r0 or r1 then spil it */
521       for (j = 0; j < lrsym->nRegs; j++)
522         if (lrsym->regs[j] == hx)
523           {
524             spillThis (lrsym);
525             break;
526           }
527     }
528
529 }
530
531 /*-----------------------------------------------------------------*/
532 /* createStackSpil - create a location on the stack to spil        */
533 /*-----------------------------------------------------------------*/
534 static symbol *
535 createStackSpil (symbol * sym)
536 {
537   symbol *sloc = NULL;
538   int useXstack, model;
539
540   char slocBuffer[30];
541
542   /* first go try and find a free one that is already 
543      existing on the stack */
544   if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
545     {
546       /* found a free one : just update & return */
547       sym->usl.spillLoc = sloc;
548       sym->stackSpil = 1;
549       sloc->isFree = 0;
550       addSetHead (&sloc->usl.itmpStack, sym);
551       return sym;
552     }
553
554   /* could not then have to create one , this is the hard part
555      we need to allocate this on the stack : this is really a
556      hack!! but cannot think of anything better at this time */
557
558   if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
559     {
560       fprintf (stderr, "***Internal error: slocBuffer overflowed: %s:%d\n",
561                __FILE__, __LINE__);
562       exit (1);
563     }
564
565   sloc = newiTemp (slocBuffer);
566
567   /* set the type to the spilling symbol */
568   sloc->type = copyLinkChain (sym->type);
569   sloc->etype = getSpec (sloc->type);
570   SPEC_SCLS (sloc->etype) = S_DATA;
571   SPEC_EXTR (sloc->etype) = 0;
572   SPEC_STAT (sloc->etype) = 0;
573   SPEC_VOLATILE(sloc->etype) = 0;
574   SPEC_ABSA(sloc->etype) = 0;
575
576   /* we don't allow it to be allocated`
577      onto the external stack since : so we
578      temporarily turn it off ; we also
579      turn off memory model to prevent
580      the spil from going to the external storage
581    */
582
583   useXstack = options.useXstack;
584   model = options.model;
585 /*     noOverlay = options.noOverlay; */
586 /*     options.noOverlay = 1; */
587   options.model = options.useXstack = 0;
588
589   allocLocal (sloc);
590
591   options.useXstack = useXstack;
592   options.model = model;
593 /*     options.noOverlay = noOverlay; */
594   sloc->isref = 1;              /* to prevent compiler warning */
595
596   /* if it is on the stack then update the stack */
597   if (IN_STACK (sloc->etype))
598     {
599       currFunc->stack += getSize (sloc->type);
600       _G.stackExtend += getSize (sloc->type);
601     }
602   else
603     _G.dataExtend += getSize (sloc->type);
604
605   /* add it to the _G.stackSpil set */
606   addSetHead (&_G.stackSpil, sloc);
607   sym->usl.spillLoc = sloc;
608   sym->stackSpil = 1;
609
610   /* add it to the set of itempStack set 
611      of the spill location */
612   addSetHead (&sloc->usl.itmpStack, sym);
613   return sym;
614 }
615
616 /*-----------------------------------------------------------------*/
617 /* isSpiltOnStack - returns true if the spil location is on stack  */
618 /*-----------------------------------------------------------------*/
619 static bool
620 isSpiltOnStack (symbol * sym)
621 {
622   sym_link *etype;
623
624   if (!sym)
625     return FALSE;
626
627   if (!sym->isspilt)
628     return FALSE;
629
630 /*     if (sym->_G.stackSpil) */
631 /*      return TRUE; */
632
633   if (!sym->usl.spillLoc)
634     return FALSE;
635
636   etype = getSpec (sym->usl.spillLoc->type);
637   if (IN_STACK (etype))
638     return TRUE;
639
640   return FALSE;
641 }
642
643 /*-----------------------------------------------------------------*/
644 /* spillThis - spils a specific operand                            */
645 /*-----------------------------------------------------------------*/
646 static void
647 spillThis (symbol * sym)
648 {
649   int i;
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   /* mark it has spilt & put it in the spilt set */
657   sym->isspilt = sym->spillA = 1;
658   _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
659
660   bitVectUnSetBit (_G.regAssigned, sym->key);
661   bitVectUnSetBit (_G.totRegAssigned, sym->key);
662
663   for (i = 0; i < sym->nRegs; i++)
664
665     if (sym->regs[i])
666       {
667         hc08_freeReg (sym->regs[i]);
668         sym->regs[i] = NULL;
669       }
670
671   /* if spilt on stack then free up r0 & r1 
672      if they could have been assigned to some
673      LIVE ranges */
674 //  if (!hc08_ptrRegReq && isSpiltOnStack (sym))
675 //    {
676 //      hc08_ptrRegReq++;
677 //      spillLRWithPtrReg (sym);
678 //    }
679
680   if (sym->usl.spillLoc && !sym->remat)
681     sym->usl.spillLoc->allocreq++;
682   return;
683 }
684
685 /*-----------------------------------------------------------------*/
686 /* selectSpil - select a iTemp to spil : rather a simple procedure */
687 /*-----------------------------------------------------------------*/
688 static symbol *
689 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
690 {
691   bitVect *lrcs = NULL;
692   set *selectS;
693   symbol *sym;
694
695   /* get the spillable live ranges */
696   lrcs = computeSpillable (ic);
697
698   /* get all live ranges that are rematerizable */
699   if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
700     {
701
702       /* return the least used of these */
703       return leastUsedLR (selectS);
704     }
705
706   /* get live ranges with spillLocations in direct space */
707   if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
708     {
709       sym = leastUsedLR (selectS);
710       strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
711                            sym->usl.spillLoc->rname :
712                            sym->usl.spillLoc->name));
713       sym->spildir = 1;
714       /* mark it as allocation required */
715       sym->usl.spillLoc->allocreq++;
716       return sym;
717     }
718
719   /* if the symbol is local to the block then */
720   if (forSym->liveTo < ebp->lSeq)
721     {
722
723       /* check if there are any live ranges allocated
724          to registers that are not used in this block */
725       if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
726         {
727           sym = leastUsedLR (selectS);
728           /* if this is not rematerializable */
729           if (!sym->remat)
730             {
731               _G.blockSpil++;
732               sym->blockSpil = 1;
733             }
734           return sym;
735         }
736
737       /* check if there are any live ranges that not
738          used in the remainder of the block */
739       if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
740         {
741           sym = leastUsedLR (selectS);
742           if (sym != forSym)
743             {
744               if (!sym->remat)
745                 {
746                   sym->remainSpil = 1;
747                   _G.blockSpil++;
748                 }
749               return sym;
750             }
751         }
752     }
753
754   /* find live ranges with spillocation && not used as pointers */
755   if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
756     {
757
758       sym = leastUsedLR (selectS);
759       /* mark this as allocation required */
760       sym->usl.spillLoc->allocreq++;
761       return sym;
762     }
763
764   /* find live ranges with spillocation */
765   if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
766     {
767
768       sym = leastUsedLR (selectS);
769       sym->usl.spillLoc->allocreq++;
770       return sym;
771     }
772
773   /* couldn't find then we need to create a spil
774      location on the stack , for which one? the least
775      used ofcourse */
776   if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
777     {
778
779       /* return a created spil location */
780       sym = createStackSpil (leastUsedLR (selectS));
781       sym->usl.spillLoc->allocreq++;
782       return sym;
783     }
784
785   /* this is an extreme situation we will spill
786      this one : happens very rarely but it does happen */
787   spillThis (forSym);
788   return forSym;
789
790 }
791
792 /*-----------------------------------------------------------------*/
793 /* spilSomething - spil some variable & mark registers as free     */
794 /*-----------------------------------------------------------------*/
795 static bool
796 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
797 {
798   symbol *ssym;
799   int i;
800
801   /* get something we can spil */
802   ssym = selectSpil (ic, ebp, forSym);
803
804   /* mark it as spilt */
805   ssym->isspilt = ssym->spillA = 1;
806   _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
807
808   /* mark it as not register assigned &
809      take it away from the set */
810   bitVectUnSetBit (_G.regAssigned, ssym->key);
811   bitVectUnSetBit (_G.totRegAssigned, ssym->key);
812
813   /* mark the registers as free */
814   for (i = 0; i < ssym->nRegs; i++)
815     if (ssym->regs[i])
816       hc08_freeReg (ssym->regs[i]);
817
818   /* if spilt on stack then free up hx
819      if it could have been assigned to as gprs */
820   if (!hc08_ptrRegReq && isSpiltOnStack (ssym))
821     {
822       hc08_ptrRegReq++;
823       spillLRWithPtrReg (ssym);
824     }
825
826   /* if this was a block level spil then insert push & pop 
827      at the start & end of block respectively */
828   if (ssym->blockSpil)
829     {
830       iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
831       /* add push to the start of the block */
832       addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
833                                     ebp->sch->next : ebp->sch));
834       nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
835       /* add pop to the end of the block */
836       addiCodeToeBBlock (ebp, nic, NULL);
837     }
838
839   /* if spilt because not used in the remainder of the
840      block then add a push before this instruction and
841      a pop at the end of the block */
842   if (ssym->remainSpil)
843     {
844
845       iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
846       /* add push just before this instruction */
847       addiCodeToeBBlock (ebp, nic, ic);
848
849       nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
850       /* add pop to the end of the block */
851       addiCodeToeBBlock (ebp, nic, NULL);
852     }
853
854   if (ssym == forSym)
855     return FALSE;
856   else
857     return TRUE;
858 }
859
860 /*-----------------------------------------------------------------*/
861 /* getRegPtr - will try for PTR if not a GPR type if not spil      */
862 /*-----------------------------------------------------------------*/
863 static regs *
864 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
865 {
866   regs *reg;
867
868 tryAgain:
869   /* try for a ptr type */
870   if ((reg = allocReg (REG_PTR)))
871     return reg;
872
873   /* try for gpr type */
874   if ((reg = allocReg (REG_GPR)))
875     return reg;
876
877   /* we have to spil */
878   if (!spilSomething (ic, ebp, sym))
879     return NULL;
880
881   /* this looks like an infinite loop but 
882      in really selectSpil will abort  */
883   goto tryAgain;
884 }
885
886 /*-----------------------------------------------------------------*/
887 /* getRegGpr - will try for GPR if not spil                        */
888 /*-----------------------------------------------------------------*/
889 static regs *
890 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
891 {
892   regs *reg;
893
894 tryAgain:
895   /* try for gpr type */
896   if ((reg = allocReg (REG_GPR)))
897     return reg;
898
899   if (!hc08_ptrRegReq)
900     if ((reg = allocReg (REG_PTR)))
901       return reg;
902
903   /* we have to spil */
904   if (!spilSomething (ic, ebp, sym))
905     return NULL;
906
907   /* this looks like an infinite loop but 
908      in really selectSpil will abort  */
909   goto tryAgain;
910 }
911
912 /*-----------------------------------------------------------------*/
913 /* getRegPtrNoSpil - get it cannot split                           */
914 /*-----------------------------------------------------------------*/
915 static regs *getRegPtrNoSpil()
916 {
917   regs *reg;
918
919   /* try for a ptr type */
920   if ((reg = allocReg (REG_PTR)))
921     return reg;
922
923   /* try for gpr type */
924   if ((reg = allocReg (REG_GPR)))
925     return reg;
926
927   assert(0);
928
929   /* just to make the compiler happy */
930   return 0;
931 }
932
933 /*-----------------------------------------------------------------*/
934 /* getRegGprNoSpil - get it cannot split                           */
935 /*-----------------------------------------------------------------*/
936 static regs *getRegGprNoSpil()
937 {
938
939   regs *reg;
940   if ((reg = allocReg (REG_GPR)))
941     return reg;
942
943   if (!hc08_ptrRegReq)
944     if ((reg = allocReg (REG_PTR)))
945       return reg;
946
947   assert(0);
948
949   /* just to make the compiler happy */
950   return 0;
951 }
952
953 /*-----------------------------------------------------------------*/
954 /* symHasReg - symbol has a given register                         */
955 /*-----------------------------------------------------------------*/
956 static bool
957 symHasReg (symbol * sym, regs * reg)
958 {
959   int i;
960
961   for (i = 0; i < sym->nRegs; i++)
962     if (sym->regs[i] == reg)
963       return TRUE;
964
965   return FALSE;
966 }
967
968 /*-----------------------------------------------------------------*/
969 /* deassignLRs - check the live to and if they have registers & are */
970 /*               not spilt then free up the registers              */
971 /*-----------------------------------------------------------------*/
972 static void
973 deassignLRs (iCode * ic, eBBlock * ebp)
974 {
975   symbol *sym;
976   int k;
977   symbol *result;
978
979   for (sym = hTabFirstItem (liveRanges, &k); sym;
980        sym = hTabNextItem (liveRanges, &k))
981     {
982
983       symbol *psym = NULL;
984       /* if it does not end here */
985       if (sym->liveTo > ic->seq)
986         continue;
987
988       /* if it was spilt on stack then we can 
989          mark the stack spil location as free */
990       if (sym->isspilt)
991         {
992           if (sym->stackSpil)
993             {
994               sym->usl.spillLoc->isFree = 1;
995               sym->stackSpil = 0;
996             }
997           continue;
998         }
999
1000       if (!bitVectBitValue (_G.regAssigned, sym->key))
1001         continue;
1002
1003       /* special case check if this is an IFX &
1004          the privious one was a pop and the 
1005          previous one was not spilt then keep track
1006          of the symbol */
1007       if (ic->op == IFX && ic->prev &&
1008           ic->prev->op == IPOP &&
1009           !ic->prev->parmPush &&
1010           !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1011         psym = OP_SYMBOL (IC_LEFT (ic->prev));
1012
1013       if (sym->nRegs)
1014         {
1015           int i = 0;
1016
1017           bitVectUnSetBit (_G.regAssigned, sym->key);
1018
1019           /* if the result of this one needs registers
1020              and does not have it then assign it right
1021              away */
1022           if (IC_RESULT (ic) &&
1023               !(SKIP_IC2 (ic) ||        /* not a special icode */
1024                 ic->op == JUMPTABLE ||
1025                 ic->op == IFX ||
1026                 ic->op == IPUSH ||
1027                 ic->op == IPOP ||
1028                 ic->op == RETURN ||
1029                 POINTER_SET (ic)) &&
1030               (result = OP_SYMBOL (IC_RESULT (ic))) &&  /* has a result */
1031               result->liveTo > ic->seq &&       /* and will live beyond this */
1032               result->liveTo <= ebp->lSeq &&    /* does not go beyond this block */
1033               result->regType == sym->regType &&        /* same register types */
1034               result->nRegs &&  /* which needs registers */
1035               !result->isspilt &&       /* and does not already have them */
1036               !result->remat &&
1037               !bitVectBitValue (_G.regAssigned, result->key) &&
1038           /* the number of free regs + number of regs in this LR
1039              can accomodate the what result Needs */
1040               ((nfreeRegsType (result->regType) +
1041                 sym->nRegs) >= result->nRegs)
1042             )
1043             {
1044
1045               for (i = 0; i < result->nRegs; i++)
1046                 if (i < sym->nRegs)
1047                   result->regs[i] = sym->regs[i];
1048                 else
1049                   result->regs[i] = getRegGpr (ic, ebp, result);
1050
1051               _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1052               _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, result->key);
1053
1054             }
1055
1056           /* free the remaining */
1057           for (; i < sym->nRegs; i++)
1058             {
1059               if (psym)
1060                 {
1061                   if (!symHasReg (psym, sym->regs[i]))
1062                     hc08_freeReg (sym->regs[i]);
1063                 }
1064               else
1065                 hc08_freeReg (sym->regs[i]);
1066             }
1067         }
1068     }
1069 }
1070
1071
1072 /*-----------------------------------------------------------------*/
1073 /* reassignLR - reassign this to registers                         */
1074 /*-----------------------------------------------------------------*/
1075 static void
1076 reassignLR (operand * op)
1077 {
1078   symbol *sym = OP_SYMBOL (op);
1079   int i;
1080
1081   /* not spilt any more */
1082   sym->isspilt = sym->spillA = sym->blockSpil = sym->remainSpil = 0;
1083   bitVectUnSetBit (_G.spiltSet, sym->key);
1084
1085   _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1086   _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key);
1087
1088   _G.blockSpil--;
1089
1090   for (i = 0; i < sym->nRegs; i++)
1091     sym->regs[i]->isFree = 0;
1092 }
1093
1094 /*-----------------------------------------------------------------*/
1095 /* willCauseSpill - determines if allocating will cause a spill    */
1096 /*-----------------------------------------------------------------*/
1097 static int
1098 willCauseSpill (int nr, int rt)
1099 {
1100   /* first check if there are any avlb registers
1101      of te type required */
1102   if (rt == REG_PTR)
1103     {
1104       /* special case for pointer type 
1105          if pointer type not avlb then 
1106          check for type gpr */
1107       if (nFreeRegs (rt) >= nr)
1108         return 0;
1109       if (nFreeRegs (REG_GPR) >= nr)
1110         return 0;
1111     }
1112   else
1113     {
1114       if (hc08_ptrRegReq)
1115         {
1116           if (nFreeRegs (rt) >= nr)
1117             return 0;
1118         }
1119       else
1120         {
1121           if (nFreeRegs (REG_PTR) +
1122               nFreeRegs (REG_GPR) >= nr)
1123             return 0;
1124         }
1125     }
1126
1127   /* it will cause a spil */
1128   return 1;
1129 }
1130
1131 /*-----------------------------------------------------------------*/
1132 /* positionRegs - the allocator can allocate same registers to res- */
1133 /* ult and operand, if this happens make sure they are in the same */
1134 /* position as the operand otherwise chaos results                 */
1135 /*-----------------------------------------------------------------*/
1136 static int
1137 positionRegs (symbol * result, symbol * opsym)
1138 {
1139   int count = min (result->nRegs, opsym->nRegs);
1140   int i, j = 0, shared = 0;
1141   int change = 0;
1142
1143   /* if the result has been spilt then cannot share */
1144   if (opsym->isspilt)
1145     return 0;
1146 again:
1147   shared = 0;
1148   /* first make sure that they actually share */
1149   for (i = 0; i < count; i++)
1150     {
1151       for (j = 0; j < count; j++)
1152         {
1153           if (result->regs[i] == opsym->regs[j] && i != j)
1154             {
1155               shared = 1;
1156               goto xchgPositions;
1157             }
1158         }
1159     }
1160 xchgPositions:
1161   if (shared)
1162     {
1163       regs *tmp = result->regs[i];
1164       result->regs[i] = result->regs[j];
1165       result->regs[j] = tmp;
1166       change ++;
1167       goto again;
1168     }
1169   return change;
1170 }
1171
1172 /*-----------------------------------------------------------------*/
1173 /* serialRegAssign - serially allocate registers to the variables  */
1174 /*-----------------------------------------------------------------*/
1175 static void
1176 serialRegAssign (eBBlock ** ebbs, int count)
1177 {
1178     int i;
1179
1180     /* for all blocks */
1181     for (i = 0; i < count; i++) {
1182
1183         iCode *ic;
1184
1185         if (ebbs[i]->noPath &&
1186             (ebbs[i]->entryLabel != entryLabel &&
1187              ebbs[i]->entryLabel != returnLabel))
1188             continue;
1189
1190         /* of all instructions do */
1191         for (ic = ebbs[i]->sch; ic; ic = ic->next) {
1192 #if 1
1193             int reg;
1194
1195             // update the registers in use at the start of this icode
1196             for (reg=0; reg<hc08_nRegs; reg++) {
1197               if (regshc08[reg].isFree) {
1198                 ic->riu &= ~(regshc08[reg].mask);
1199               } else {
1200                 ic->riu |= (regshc08[reg].mask);
1201               }
1202             }
1203 #endif
1204
1205             /* if this is an ipop that means some live
1206                range will have to be assigned again */
1207             if (ic->op == IPOP)
1208                 reassignLR (IC_LEFT (ic));
1209
1210             /* if result is present && is a true symbol */
1211             if (IC_RESULT (ic) && ic->op != IFX &&
1212                 IS_TRUE_SYMOP (IC_RESULT (ic)))
1213                 OP_SYMBOL (IC_RESULT (ic))->allocreq++;
1214
1215             /* take away registers from live
1216                ranges that end at this instruction */
1217             deassignLRs (ic, ebbs[i]);
1218
1219             /* some don't need registers */
1220             if (SKIP_IC2 (ic) ||
1221                 ic->op == JUMPTABLE ||
1222                 ic->op == IFX ||
1223                 ic->op == IPUSH ||
1224                 ic->op == IPOP ||
1225                 (IC_RESULT (ic) && POINTER_SET (ic)))
1226                 continue;
1227
1228             /* now we need to allocate registers
1229                only for the result */
1230             if (IC_RESULT (ic)) {
1231                 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
1232                 bitVect *spillable;
1233                 int willCS;
1234                 int j;
1235                 int ptrRegSet = 0;
1236
1237                 /* if it does not need or is spilt 
1238                    or is already assigned to registers
1239                    or will not live beyond this instructions */
1240                 if (!sym->nRegs ||
1241                     sym->isspilt ||
1242                     bitVectBitValue (_G.regAssigned, sym->key) ||
1243                     sym->liveTo <= ic->seq)
1244                     continue;
1245
1246                 /* if some liverange has been spilt at the block level
1247                    and this one live beyond this block then spil this
1248                    to be safe */
1249                 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq) {
1250                     spillThis (sym);
1251                     continue;
1252                 }
1253                 /* if trying to allocate this will cause
1254                    a spill and there is nothing to spill 
1255                    or this one is rematerializable then
1256                    spill this one */
1257                 willCS = willCauseSpill (sym->nRegs, sym->regType);
1258                 spillable = computeSpillable (ic);
1259                 if (sym->remat || (willCS && bitVectIsZero (spillable))) {                    
1260                     spillThis (sym);
1261                     continue;                 
1262                 }
1263
1264                 /* if it has a spillocation & is used less than
1265                    all other live ranges then spill this */
1266                 if (willCS) {
1267                     if (sym->usl.spillLoc) {
1268                         symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
1269                                                                          allLRs, ebbs[i], ic));
1270                         if (leastUsed && leastUsed->used > sym->used) {
1271                             spillThis (sym);
1272                             continue;
1273                         }
1274                     } else {
1275                         /* if none of the liveRanges have a spillLocation then better
1276                            to spill this one than anything else already assigned to registers */
1277                         if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
1278                             /* if this is local to this block then we might find a block spil */
1279                             if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
1280                                 spillThis (sym);
1281                                 continue;
1282                             }
1283                         }
1284                     }
1285                 }
1286                 /* if we need ptr regs for the right side
1287                    then mark it */
1288                 if (POINTER_GET (ic) && IS_SYMOP (IC_LEFT (ic))
1289                     && getSize (OP_SYMBOL (IC_LEFT (ic))->type) <= (unsigned int) PTRSIZE) {
1290                     hc08_ptrRegReq++;
1291                     ptrRegSet = 1;
1292                 }
1293                 /* else we assign registers to it */
1294                 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1295                 _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key);
1296
1297                 for (j = 0; j < sym->nRegs; j++) {
1298                     if (sym->regType == REG_PTR)
1299                         sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
1300                     else
1301                         sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
1302
1303                     /* if the allocation failed which means
1304                        this was spilt then break */
1305                     if (!sym->regs[j]) {
1306                       break;
1307                     }
1308                 }
1309
1310                 /* if it shares registers with operands make sure
1311                    that they are in the same position */
1312                 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
1313                     OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=') {
1314                     positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1315                                   OP_SYMBOL (IC_LEFT (ic)));
1316                 }
1317                 /* do the same for the right operand */
1318                 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
1319                     OP_SYMBOL (IC_RIGHT (ic))->nRegs) {
1320                     positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1321                                   OP_SYMBOL (IC_RIGHT (ic)));
1322                 }
1323
1324                 if (ptrRegSet) {
1325                     hc08_ptrRegReq--;
1326                     ptrRegSet = 0;
1327                 }
1328
1329             }
1330         }
1331     }
1332 }
1333
1334 /*-----------------------------------------------------------------*/
1335 /* fillGaps - Try to fill in the Gaps left by Pass1                */
1336 /*-----------------------------------------------------------------*/
1337 static void fillGaps()
1338 {
1339     symbol *sym =NULL;
1340     int key =0;    
1341     
1342     if (getenv("DISABLE_FILL_GAPS")) return;
1343     
1344     /* look for livernages that was spilt by the allocator */
1345     for (sym = hTabFirstItem(liveRanges,&key) ; sym ; 
1346          sym = hTabNextItem(liveRanges,&key)) {
1347
1348         int i;
1349         int pdone = 0;
1350
1351         if (!sym->spillA || !sym->clashes || sym->remat) continue ;
1352
1353         /* find the liveRanges this one clashes with, that are
1354            still assigned to registers & mark the registers as used*/
1355         for ( i = 0 ; i < sym->clashes->size ; i ++) {
1356             int k;
1357             symbol *clr;
1358
1359             if (bitVectBitValue(sym->clashes,i) == 0 ||    /* those that clash with this */
1360                 bitVectBitValue(_G.totRegAssigned,i) == 0) /* and are still assigned to registers */
1361                 continue ;
1362
1363                 clr = hTabItemWithKey(liveRanges,i);
1364             assert(clr);
1365          
1366             /* mark these registers as used */
1367             for (k = 0 ; k < clr->nRegs ; k++ ) 
1368                 hc08_useReg(clr->regs[k]);
1369         }
1370
1371         if (willCauseSpill(sym->nRegs,sym->regType)) {
1372             /* NOPE :( clear all registers & and continue */
1373             freeAllRegs();
1374             continue ;
1375         }
1376
1377         /* THERE IS HOPE !!!! */
1378         for (i=0; i < sym->nRegs ; i++ ) {
1379             if (sym->regType == REG_PTR)
1380                 sym->regs[i] = getRegPtrNoSpil ();
1381             else
1382                 sym->regs[i] = getRegGprNoSpil ();                
1383         }
1384
1385         /* for all its definitions check if the registers
1386            allocated needs positioning NOTE: we can position
1387            only ONCE if more than One positioning required 
1388            then give up */
1389         sym->isspilt = 0;
1390         for (i = 0 ; i < sym->defs->size ; i++ ) {
1391             if (bitVectBitValue(sym->defs,i)) {
1392                 iCode *ic;
1393                 if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
1394                 if (SKIP_IC(ic)) continue;
1395                 assert(isSymbolEqual(sym,OP_SYMBOL(IC_RESULT(ic)))); /* just making sure */
1396                 /* if left is assigned to registers */
1397                 if (IS_SYMOP(IC_LEFT(ic)) && 
1398                     bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_LEFT(ic))->key)) {
1399                     pdone += positionRegs(sym,OP_SYMBOL(IC_LEFT(ic)));
1400                 }
1401                 if (IS_SYMOP(IC_RIGHT(ic)) && 
1402                     bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RIGHT(ic))->key)) {
1403                     pdone += positionRegs(sym,OP_SYMBOL(IC_RIGHT(ic)));
1404                 }
1405                 if (pdone > 1) break;
1406             }
1407         }
1408         for (i = 0 ; i < sym->uses->size ; i++ ) {
1409             if (bitVectBitValue(sym->uses,i)) {
1410                 iCode *ic;
1411                 if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
1412                 if (SKIP_IC(ic)) continue;
1413                 if (!IS_ASSIGN_ICODE(ic)) continue ;
1414
1415                 /* if result is assigned to registers */
1416                 if (IS_SYMOP(IC_RESULT(ic)) && 
1417                     bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RESULT(ic))->key)) {
1418                     pdone += positionRegs(sym,OP_SYMBOL(IC_RESULT(ic)));
1419                 }
1420                 if (pdone > 1) break;
1421             }
1422         }
1423         /* had to position more than once GIVE UP */
1424         if (pdone > 1) {
1425             /* UNDO all the changes we made to try this */
1426             sym->isspilt = 1;
1427             for (i=0; i < sym->nRegs ; i++ ) {
1428                     sym->regs[i] = NULL;
1429             }
1430             freeAllRegs();
1431             D(printf ("Fill Gap gave up due to positioning for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN"));
1432             continue ;      
1433         }
1434         D(printf ("FILLED GAP for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN"));
1435         _G.totRegAssigned = bitVectSetBit(_G.totRegAssigned,sym->key);
1436         sym->isspilt = sym->spillA = 0 ;
1437         sym->usl.spillLoc->allocreq--;
1438         freeAllRegs();
1439     }
1440 }
1441
1442 /*-----------------------------------------------------------------*/
1443 /* rUmaskForOp :- returns register mask for an operand             */
1444 /*-----------------------------------------------------------------*/
1445 bitVect *
1446 hc08_rUmaskForOp (operand * op)
1447 {
1448   bitVect *rumask;
1449   symbol *sym;
1450   int j;
1451
1452   /* only temporaries are assigned registers */
1453   if (!IS_ITEMP (op))
1454     return NULL;
1455
1456   sym = OP_SYMBOL (op);
1457
1458   /* if spilt or no registers assigned to it
1459      then nothing */
1460   if (sym->isspilt || !sym->nRegs)
1461     return NULL;
1462
1463   rumask = newBitVect (hc08_nRegs);
1464
1465   for (j = 0; j < sym->nRegs; j++)
1466     {
1467       rumask = bitVectSetBit (rumask,
1468                               sym->regs[j]->rIdx);
1469     }
1470
1471   return rumask;
1472 }
1473
1474 /*-----------------------------------------------------------------*/
1475 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
1476 /*-----------------------------------------------------------------*/
1477 static bitVect *
1478 regsUsedIniCode (iCode * ic)
1479 {
1480   bitVect *rmask = newBitVect (hc08_nRegs);
1481
1482   /* do the special cases first */
1483   if (ic->op == IFX)
1484     {
1485       rmask = bitVectUnion (rmask,
1486                             hc08_rUmaskForOp (IC_COND (ic)));
1487       goto ret;
1488     }
1489
1490   /* for the jumptable */
1491   if (ic->op == JUMPTABLE)
1492     {
1493       rmask = bitVectUnion (rmask,
1494                             hc08_rUmaskForOp (IC_JTCOND (ic)));
1495
1496       goto ret;
1497     }
1498
1499   /* of all other cases */
1500   if (IC_LEFT (ic))
1501     rmask = bitVectUnion (rmask,
1502                           hc08_rUmaskForOp (IC_LEFT (ic)));
1503
1504
1505   if (IC_RIGHT (ic))
1506     rmask = bitVectUnion (rmask,
1507                           hc08_rUmaskForOp (IC_RIGHT (ic)));
1508
1509   if (IC_RESULT (ic))
1510     rmask = bitVectUnion (rmask,
1511                           hc08_rUmaskForOp (IC_RESULT (ic)));
1512
1513 ret:
1514   return rmask;
1515 }
1516
1517 /*-----------------------------------------------------------------*/
1518 /* createRegMask - for each instruction will determine the regsUsed */
1519 /*-----------------------------------------------------------------*/
1520 static void
1521 createRegMask (eBBlock ** ebbs, int count)
1522 {
1523   int i;
1524
1525   /* for all blocks */
1526   for (i = 0; i < count; i++)
1527     {
1528       iCode *ic;
1529
1530       if (ebbs[i]->noPath &&
1531           (ebbs[i]->entryLabel != entryLabel &&
1532            ebbs[i]->entryLabel != returnLabel))
1533         continue;
1534
1535       /* for all instructions */
1536       for (ic = ebbs[i]->sch; ic; ic = ic->next)
1537         {
1538
1539           int j;
1540
1541           if (SKIP_IC2 (ic) || !ic->rlive)
1542             continue;
1543
1544           /* first mark the registers used in this
1545              instruction */
1546           ic->rUsed = regsUsedIniCode (ic);
1547           _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
1548
1549           /* now create the register mask for those 
1550              registers that are in use : this is a
1551              super set of ic->rUsed */
1552           ic->rMask = newBitVect (hc08_nRegs + 1);
1553
1554           /* for all live Ranges alive at this point */
1555           for (j = 1; j < ic->rlive->size; j++)
1556             {
1557               symbol *sym;
1558               int k;
1559
1560               /* if not alive then continue */
1561               if (!bitVectBitValue (ic->rlive, j))
1562                 continue;
1563
1564               /* find the live range we are interested in */
1565               if (!(sym = hTabItemWithKey (liveRanges, j)))
1566                 {
1567                   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1568                           "createRegMask cannot find live range");
1569                   fprintf(stderr, "\tmissing live range: key=%d\n", j);
1570                   exit (0);
1571                 }
1572
1573               /* if no register assigned to it */
1574               if (!sym->nRegs || sym->isspilt)
1575                 continue;
1576
1577               /* for all the registers allocated to it */
1578               for (k = 0; k < sym->nRegs; k++)
1579                 if (sym->regs[k])
1580                   ic->rMask =
1581                     bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
1582             }
1583         }
1584     }
1585 }
1586
1587 /*-----------------------------------------------------------------*/
1588 /* rematStr - returns the rematerialized string for a remat var    */
1589 /*-----------------------------------------------------------------*/
1590 static char *
1591 rematStr (symbol * sym)
1592 {
1593   char *s = buffer;
1594   iCode *ic = sym->rematiCode;
1595 //  int offset = 0;
1596   
1597   while (1)
1598     {
1599
1600       /* if plus or minus print the right hand side */
1601       if (ic->op == '+' || ic->op == '-')
1602         {
1603           sprintf (s, "0x%04x %c ", (int) operandLitValue (IC_RIGHT (ic)),
1604                    ic->op);
1605           s += strlen (s);
1606           ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1607           continue;
1608         }
1609
1610 /*      
1611       if (ic->op == '+')
1612         {
1613           offset += operandLitValue (IC_RIGHT (ic));
1614           ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1615           continue;
1616         }
1617       if (ic->op == '-')
1618         {
1619           offset -= operandLitValue (IC_RIGHT (ic));
1620           ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1621           continue;
1622         }
1623 */
1624       /* cast then continue */
1625       if (IS_CAST_ICODE(ic)) {
1626           ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
1627           continue;
1628       }
1629       /* we reached the end */
1630       if (ic->op == ADDRESS_OF)
1631         sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
1632       else if (ic->op == '=');
1633         sprintf (s, "0x%04x", (int) operandLitValue (IC_RIGHT (ic)) );
1634       break;
1635     }
1636
1637   return buffer;
1638 }
1639
1640 /*-----------------------------------------------------------------*/
1641 /* regTypeNum - computes the type & number of registers required   */
1642 /*-----------------------------------------------------------------*/
1643 static void
1644 regTypeNum (eBBlock *ebbs)
1645 {
1646   symbol *sym;
1647   int k;
1648   iCode *ic;
1649
1650   /* for each live range do */
1651   for (sym = hTabFirstItem (liveRanges, &k); sym;
1652        sym = hTabNextItem (liveRanges, &k))
1653     {
1654
1655       /* if used zero times then no registers needed */
1656       if ((sym->liveTo - sym->liveFrom) == 0)
1657         continue;
1658
1659
1660       /* if the live range is a temporary */
1661       if (sym->isitmp)
1662         {
1663
1664           /* if the type is marked as a conditional */
1665           if (sym->regType == REG_CND)
1666             continue;
1667
1668           /* if used in return only then we don't 
1669              need registers */
1670           if (sym->ruonly || sym->accuse)
1671             {
1672               if (IS_AGGREGATE (sym->type) || sym->isptr)
1673                 sym->type = aggrToPtr (sym->type, FALSE);
1674               continue;
1675             }
1676
1677           /* if the symbol has only one definition &
1678              that definition is a get_pointer */
1679           if (bitVectnBitsOn (sym->defs) == 1 &&
1680               (ic = hTabItemWithKey (iCodehTab,
1681                                      bitVectFirstBit (sym->defs))) &&
1682               POINTER_GET (ic) &&
1683               !sym->noSpilLoc &&
1684               !IS_BITVAR (sym->etype))
1685             {
1686
1687
1688               /* and that pointer is remat in data space */
1689               if (IS_SYMOP (IC_LEFT (ic)) &&
1690                   OP_SYMBOL (IC_LEFT (ic))->remat &&
1691                   !IS_CAST_ICODE(OP_SYMBOL (IC_LEFT (ic))->rematiCode) &&
1692                   DCL_TYPE (aggrToPtr (operandType(IC_LEFT(ic)), FALSE)) == POINTER)
1693                 {
1694                   /* create a psuedo symbol & force a spil */
1695                   symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
1696                   psym->type = sym->type;
1697                   psym->etype = sym->etype;
1698                   strcpy (psym->rname, psym->name);
1699                   sym->isspilt = 1;
1700                   sym->usl.spillLoc = psym;
1701 #if 0 // an alternative fix for bug #480076
1702                   /* now this is a useless assignment to itself */
1703                   remiCodeFromeBBlock (ebbs, ic);
1704 #else
1705                   /* now this really is an assignment to itself, make it so;
1706                      it will be optimized out later */
1707                   ic->op='=';
1708                   ReplaceOpWithCheaperOp(&IC_RIGHT(ic), IC_RESULT(ic));
1709                   IC_LEFT(ic)=NULL;
1710 #endif
1711                   continue;
1712                 }
1713
1714               /* if in data space or idata space then try to
1715                  allocate pointer register */
1716
1717             }
1718
1719           /* if not then we require registers */
1720           sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
1721                         getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1722                         getSize (sym->type));
1723
1724           if (sym->nRegs > 4)
1725             {
1726               fprintf (stderr, "allocated more than 4 or 0 registers for type ");
1727               printTypeChain (sym->type, stderr);
1728               fprintf (stderr, "\n");
1729             }
1730
1731           /* determine the type of register required */
1732           if (sym->nRegs == 1 &&
1733               IS_PTR (sym->type) &&
1734               sym->uptr)
1735             sym->regType = REG_PTR;
1736           else
1737             sym->regType = REG_GPR;
1738
1739         }
1740       else
1741         /* for the first run we don't provide */
1742         /* registers for true symbols we will */
1743         /* see how things go                  */
1744         sym->nRegs = 0;
1745           }
1746
1747 }
1748
1749 /*-----------------------------------------------------------------*/
1750 /* freeAllRegs - mark all registers as free                        */
1751 /*-----------------------------------------------------------------*/
1752 static void
1753 freeAllRegs ()
1754 {
1755   int i;
1756
1757   for (i = 0; i < hc08_nRegs; i++) {
1758     regshc08[i].isFree = 1;
1759     regshc08[i].aop = NULL;
1760   }
1761 }
1762
1763 /*-----------------------------------------------------------------*/
1764 /* deallocStackSpil - this will set the stack pointer back         */
1765 /*-----------------------------------------------------------------*/
1766 static
1767 DEFSETFUNC (deallocStackSpil)
1768 {
1769   symbol *sym = item;
1770
1771   deallocLocal (sym);
1772   return 0;
1773 }
1774
1775 #if 0
1776 /*-----------------------------------------------------------------*/
1777 /* farSpacePackable - returns the packable icode for far variables */
1778 /*-----------------------------------------------------------------*/
1779 static iCode *
1780 farSpacePackable (iCode * ic)
1781 {
1782   iCode *dic;
1783
1784   /* go thru till we find a definition for the
1785      symbol on the right */
1786   for (dic = ic->prev; dic; dic = dic->prev)
1787     {
1788       /* if the definition is a call then no */
1789       if ((dic->op == CALL || dic->op == PCALL) &&
1790           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1791         {
1792           return NULL;
1793         }
1794
1795       /* if shift by unknown amount then not */
1796       if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
1797           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1798         return NULL;
1799
1800 #if 0
1801       /* if pointer get and size > 1 */
1802       if (POINTER_GET (dic) &&
1803           getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
1804         return NULL;
1805
1806       if (POINTER_SET (dic) &&
1807           getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
1808         return NULL;
1809 #endif
1810
1811       /* if any three is a true symbol in far space */
1812       if (IC_RESULT (dic) &&
1813           IS_TRUE_SYMOP (IC_RESULT (dic)) /* &&
1814           isOperandInFarSpace (IC_RESULT (dic)) */)
1815         return NULL;
1816
1817       if (IC_RIGHT (dic) &&
1818           IS_TRUE_SYMOP (IC_RIGHT (dic)) /* &&
1819           isOperandInFarSpace (IC_RIGHT (dic)) */ &&
1820           !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
1821         return NULL;
1822
1823       if (IC_LEFT (dic) &&
1824           IS_TRUE_SYMOP (IC_LEFT (dic)) /* &&
1825           isOperandInFarSpace (IC_LEFT (dic)) */ &&
1826           !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
1827         return NULL;
1828
1829       if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
1830         {
1831           if ((dic->op == LEFT_OP ||
1832                dic->op == RIGHT_OP ||
1833                dic->op == '-') &&
1834               IS_OP_LITERAL (IC_RIGHT (dic)))
1835             return NULL;
1836           else
1837             return dic;
1838         }
1839     }
1840
1841   return NULL;
1842 }
1843 #endif
1844
1845 #if 0
1846 static void
1847 packRegsForLiteral (iCode * ic)
1848 {
1849   int k;
1850   iCode *uic;
1851   
1852   if (ic->op != '=')
1853     return;
1854   if (POINTER_SET (ic))
1855     return;
1856   if (!IS_LITERAL (getSpec (operandType (IC_RIGHT (ic)))))
1857     return;
1858   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
1859     return;
1860
1861   for (k=0; k< OP_USES (IC_RESULT (ic))->size; k++)
1862     if (bitVectBitValue (OP_USES (IC_RESULT (ic)), k))
1863       {
1864         uic = hTabItemWithKey (iCodehTab, k);
1865         if (!uic) continue;
1866         
1867         if (uic->op != IFX && uic->op != JUMPTABLE)
1868           {
1869             if (IC_LEFT (uic) && IC_LEFT (uic)->key == IC_RESULT (ic)->key)
1870               ReplaceOpWithCheaperOp(&IC_LEFT(uic), IC_RIGHT(ic));
1871             if (IC_RIGHT (uic) && IC_RIGHT (uic)->key == IC_RESULT (ic)->key)
1872               ReplaceOpWithCheaperOp(&IC_RIGHT(uic), IC_RIGHT(ic));
1873             if (IC_RESULT (uic) && IC_RESULT (uic)->key == IC_RESULT (ic)->key)
1874               ReplaceOpWithCheaperOp(&IC_RESULT(uic), IC_RIGHT(ic));
1875           }
1876       }
1877
1878 }
1879 #endif
1880
1881
1882 /*-----------------------------------------------------------------*/
1883 /* packRegsForAssign - register reduction for assignment           */
1884 /*-----------------------------------------------------------------*/
1885 static int
1886 packRegsForAssign (iCode * ic, eBBlock * ebp)
1887 {
1888   iCode *dic, *sic;
1889
1890   if (!IS_ITEMP (IC_RIGHT (ic)) ||
1891       OP_SYMBOL (IC_RIGHT (ic))->isind ||
1892       OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
1893     {
1894       return 0;
1895     }
1896
1897
1898   /* if the true symbol is defined in far space or on stack
1899      then we should not since this will increase register pressure */
1900 #if 0
1901   if (isOperandInFarSpace(IC_RESULT(ic)) && !farSpacePackable(ic)) {
1902     return 0;
1903   }
1904 #endif
1905
1906   /* find the definition of iTempNN scanning backwards if we find a 
1907      a use of the true symbol in before we find the definition then 
1908      we cannot */
1909   for (dic = ic->prev; dic; dic = dic->prev)
1910     {
1911
1912 #if 0 /* jwk: This collides with 1.43 but I really see no need for
1913          this anymore. It fixes bug #716790 and substantially improves 
1914          redundant register usage around function calls.
1915       */
1916
1917       /* if there is a function call then don't pack it */
1918       if ((dic->op == CALL || dic->op == PCALL))
1919         {
1920           dic = NULL;
1921           break;
1922         }
1923 #endif
1924
1925       if (SKIP_IC2 (dic))
1926         continue;
1927
1928       if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
1929           IS_OP_VOLATILE (IC_RESULT (dic)))
1930         {
1931           dic = NULL;
1932           break;
1933         }
1934
1935       if (IS_SYMOP (IC_RESULT (dic)) &&
1936           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1937         {
1938           if (POINTER_SET (dic))
1939             dic = NULL;
1940
1941           break;
1942         }
1943
1944       if (IS_SYMOP (IC_RIGHT (dic)) &&
1945           (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
1946            IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
1947         {
1948           dic = NULL;
1949           break;
1950         }
1951
1952       if (IS_SYMOP (IC_LEFT (dic)) &&
1953           (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
1954            IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
1955         {
1956           dic = NULL;
1957           break;
1958         }
1959
1960       if (POINTER_SET (dic) &&
1961           IC_RESULT (dic)->key == IC_RESULT (ic)->key)
1962         {
1963           dic = NULL;
1964           break;
1965         }
1966     }
1967
1968   if (!dic)
1969     return 0;                   /* did not find */
1970
1971   /* if assignment then check that right is not a bit */
1972   if (ASSIGNMENT (dic) && !POINTER_SET (dic))
1973     {
1974       sym_link *etype = operandType (IC_RIGHT (dic));
1975       if (IS_BITFIELD (etype))
1976         {
1977           /* if result is a bit too then it's ok */
1978           etype = operandType (IC_RESULT (dic));
1979           if (!IS_BITFIELD (etype))
1980             return 0;
1981         }
1982     }
1983   /* if the result is on stack or iaccess then it must be
1984      the same atleast one of the operands */
1985   if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
1986       OP_SYMBOL (IC_RESULT (ic))->iaccess)
1987     {
1988
1989       /* the operation has only one symbol
1990          operator then we can pack */
1991       if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
1992           (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
1993         goto pack;
1994
1995       if (!((IC_LEFT (dic) &&
1996              IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
1997             (IC_RIGHT (dic) &&
1998              IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
1999         return 0;
2000     }
2001 pack:
2002   /* found the definition */
2003   /* replace the result with the result of */
2004   /* this assignment and remove this assignment */
2005   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2006   ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
2007
2008   if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2009     {
2010       OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2011     }
2012   // TODO: and the otherway around?
2013
2014   /* delete from liverange table also 
2015      delete from all the points inbetween and the new
2016      one */
2017   for (sic = dic; sic != ic; sic = sic->next)
2018     {
2019       bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2020       if (IS_ITEMP (IC_RESULT (dic)))
2021         bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2022     }
2023
2024   remiCodeFromeBBlock (ebp, ic);
2025   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2026   hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2027   OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2028   return 1;
2029 }
2030
2031
2032 /*------------------------------------------------------------------*/
2033 /* findAssignToSym : scanning backwards looks for first assig found */
2034 /*------------------------------------------------------------------*/
2035 static iCode *
2036 findAssignToSym (operand * op, iCode * ic)
2037 {
2038   iCode *dic;
2039
2040   /* This routine is used to find sequences like
2041      iTempAA = FOO;
2042      ...;  (intervening ops don't use iTempAA or modify FOO)
2043      blah = blah + iTempAA;
2044
2045      and eliminate the use of iTempAA, freeing up its register for
2046      other uses.
2047   */
2048      
2049
2050   for (dic = ic->prev; dic; dic = dic->prev)
2051     {
2052
2053       /* if definition by assignment */
2054       if (dic->op == '=' &&
2055           !POINTER_SET (dic) &&
2056           IC_RESULT (dic)->key == op->key
2057           &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) 
2058         )
2059         break;  /* found where this temp was defined */
2060
2061       /* if we find an usage then we cannot delete it */
2062       if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2063         return NULL;
2064
2065       if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2066         return NULL;
2067
2068       if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2069         return NULL;
2070     }
2071
2072   if (!dic)
2073     return NULL;   /* didn't find any assignment to op */
2074
2075   /* we are interested only if defined in far space */
2076   /* or in stack space in case of + & - */
2077   
2078   /* if assigned to a non-symbol then don't repack regs */
2079   if (!IS_SYMOP (IC_RIGHT (dic)))
2080     return NULL;
2081   
2082   /* if the symbol is volatile then we should not */
2083   if (isOperandVolatile (IC_RIGHT (dic), TRUE))
2084     return NULL;
2085   /* XXX TODO --- should we be passing FALSE to isOperandVolatile()?
2086      What does it mean for an iTemp to be volatile, anyway? Passing
2087      TRUE is more cautious but may prevent possible optimizations */
2088
2089   /* if the symbol is in far space then we should not */
2090   /* if (isOperandInFarSpace (IC_RIGHT (dic)))
2091     return NULL; */
2092   
2093   /* for + & - operations make sure that
2094      if it is on the stack it is the same
2095      as one of the three operands */
2096 #if 0
2097   if ((ic->op == '+' || ic->op == '-') &&
2098       OP_SYMBOL (IC_RIGHT (dic))->onStack)
2099     {
2100       
2101       if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2102           IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2103           IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2104         return NULL;
2105     }
2106 #endif
2107   
2108   /* now make sure that the right side of dic
2109      is not defined between ic & dic */
2110   if (dic)
2111     {
2112       iCode *sic = dic->next;
2113
2114       for (; sic != ic; sic = sic->next)
2115         if (IC_RESULT (sic) &&
2116             IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2117           return NULL;
2118     }
2119
2120   return dic;
2121 }
2122
2123 /*-----------------------------------------------------------------*/
2124 /* reassignAliasedSym - used by packRegsForSupport to replace      */
2125 /*                      redundant iTemp with equivalent symbol     */
2126 /*-----------------------------------------------------------------*/
2127 static void
2128 reassignAliasedSym (eBBlock *ebp, iCode *assignment, iCode *use, operand *op)
2129 {
2130   iCode *ic;
2131   unsigned oldSymKey, newSymKey;
2132
2133   oldSymKey = op->key;
2134   newSymKey = IC_RIGHT(assignment)->key;
2135
2136   /* only track live ranges of compiler-generated temporaries */
2137   if (!IS_ITEMP(IC_RIGHT(assignment)))
2138     newSymKey = 0;
2139
2140   /* update the live-value bitmaps */
2141   for (ic = assignment; ic != use; ic = ic->next) {
2142     bitVectUnSetBit (ic->rlive, oldSymKey);
2143     if (newSymKey != 0)
2144       ic->rlive = bitVectSetBit (ic->rlive, newSymKey);
2145   }
2146
2147   /* update the sym of the used operand */
2148   OP_SYMBOL(op) = OP_SYMBOL(IC_RIGHT(assignment));
2149   op->key = OP_SYMBOL(op)->key;
2150
2151   /* update the sym's liverange */
2152   if ( OP_LIVETO(op) < ic->seq )
2153     setToRange(op, ic->seq, FALSE);
2154
2155   /* remove the assignment iCode now that its result is unused */
2156   remiCodeFromeBBlock (ebp, assignment);
2157   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(assignment))->defs, assignment->key);
2158   hTabDeleteItem (&iCodehTab, assignment->key, assignment, DELETE_ITEM, NULL);
2159 }
2160   
2161
2162 /*-----------------------------------------------------------------*/
2163 /* packRegsForSupport :- reduce some registers for support calls   */
2164 /*-----------------------------------------------------------------*/
2165 static int
2166 packRegsForSupport (iCode * ic, eBBlock * ebp)
2167 {
2168   iCode *dic;
2169   int changes = 0;
2170   
2171   /* for the left & right operand :- look to see if the
2172      left was assigned a true symbol in far space in that
2173      case replace them */
2174
2175   if (IS_ITEMP (IC_LEFT (ic)) &&
2176       OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2177     {
2178       dic = findAssignToSym (IC_LEFT (ic), ic);
2179
2180       if (dic)
2181         {
2182           /* found it we need to remove it from the block */
2183           reassignAliasedSym (ebp, dic, ic, IC_LEFT(ic));
2184           changes++;
2185         }
2186     }
2187
2188   /* do the same for the right operand */
2189   if (IS_ITEMP (IC_RIGHT (ic)) &&
2190       OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2191     {
2192       iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2193
2194       if (dic)
2195         {
2196           /* found it we need to remove it from the block */
2197           reassignAliasedSym (ebp, dic, ic, IC_RIGHT(ic));
2198           changes++;
2199         }
2200     }
2201
2202   return changes;
2203 }
2204
2205 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
2206
2207
2208 #if 0
2209 /*-----------------------------------------------------------------*/
2210 /* packRegsForOneuse : - will reduce some registers for single Use */
2211 /*-----------------------------------------------------------------*/
2212 static iCode *
2213 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
2214 {
2215   bitVect *uses;
2216   iCode *dic, *sic;
2217
2218   /* if returning a literal then do nothing */
2219   if (!IS_SYMOP (op))
2220     return NULL;
2221
2222   /* only up to 2 bytes */
2223   if (getSize (operandType (op)) > (fReturnSizeHC08 - 2))
2224     return NULL;
2225
2226   return NULL;
2227   
2228   if (ic->op != SEND //RETURN
2229       && ic->op != SEND
2230       && !POINTER_SET (ic)
2231       && !POINTER_GET (ic) )
2232     return NULL;
2233   
2234   if (ic->op == SEND && ic->argreg != 1) return NULL;
2235
2236   /* this routine will mark the a symbol as used in one 
2237      instruction use only && if the defintion is local 
2238      (ie. within the basic block) && has only one definition &&
2239      that definiion is either a return value from a 
2240      function or does not contain any variables in
2241      far space */
2242   uses = bitVectCopy (OP_USES (op));
2243   bitVectUnSetBit (uses, ic->key);      /* take away this iCode */
2244   if (!bitVectIsZero (uses))    /* has other uses */
2245     return NULL;
2246
2247   /* if it has only one defintion */
2248   if (bitVectnBitsOn (OP_DEFS (op)) > 1)
2249     return NULL;                /* has more than one definition */
2250
2251   /* get that definition */
2252   if (!(dic =
2253         hTabItemWithKey (iCodehTab,
2254                          bitVectFirstBit (OP_DEFS (op)))))
2255     return NULL;
2256
2257   /* if that only usage is a cast */
2258   if (dic->op == CAST) {
2259     /* to a bigger type */
2260     if (getSize(OP_SYM_TYPE(IC_RESULT(dic))) > 
2261         getSize(OP_SYM_TYPE(IC_RIGHT(dic)))) {
2262       /* than we can not, since we cannot predict the usage of b & acc */
2263       return NULL;
2264     }
2265   }
2266
2267   /* found the definition now check if it is local */
2268   if (dic->seq < ebp->fSeq ||
2269       dic->seq > ebp->lSeq)
2270     return NULL;                /* non-local */
2271
2272   /* now check if it is the return from
2273      a function call */
2274   if (dic->op == CALL || dic->op == PCALL)
2275     {
2276       if (ic->op != SEND && ic->op != RETURN &&
2277           !POINTER_SET(ic) && !POINTER_GET(ic))
2278         {
2279           OP_SYMBOL (op)->ruonly = 1;
2280           return dic;
2281         }
2282       dic = dic->next;
2283     }
2284
2285
2286   /* otherwise check that the definition does
2287      not contain any symbols in far space */
2288 //  if (isOperandInFarSpace (IC_LEFT (dic)) ||
2289 //      isOperandInFarSpace (IC_RIGHT (dic)) ||
2290 //      IS_OP_RUONLY (IC_LEFT (ic)) ||
2291 //      IS_OP_RUONLY (IC_RIGHT (ic)))
2292 //    {
2293 //      return NULL;
2294 //    }
2295
2296   /* if pointer set then make sure the pointer
2297      is one byte */
2298 #if 0
2299   if (POINTER_SET (dic) &&
2300       !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2301     return NULL;
2302
2303   if (POINTER_GET (dic) &&
2304       !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2305     return NULL;
2306 #endif 
2307
2308   sic = dic;
2309
2310   /* also make sure the intervenening instructions
2311      don't have any thing in far space */
2312   for (dic = dic->next; dic && dic != ic && sic != ic; dic = dic->next)
2313     {
2314
2315       /* if there is an intervening function call then no */
2316       if (dic->op == CALL || dic->op == PCALL)
2317         return NULL;
2318       /* if pointer set then make sure the pointer
2319          is one byte */
2320 #if 0
2321       if (POINTER_SET (dic) &&
2322           !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2323         return NULL;
2324
2325       if (POINTER_GET (dic) &&
2326           !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2327         return NULL;
2328 #endif
2329       /* if address of & the result is remat the okay */
2330       if (dic->op == ADDRESS_OF &&
2331           OP_SYMBOL (IC_RESULT (dic))->remat)
2332         continue;
2333
2334       /* if operand has size of three or more & this
2335          operation is a '*','/' or '%' then 'b' may
2336          cause a problem */
2337 #if 0
2338       if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
2339           getSize (operandType (op)) >= 3)
2340         return NULL;
2341 #endif
2342
2343       /* if left or right or result is in far space */
2344 //      if (isOperandInFarSpace (IC_LEFT (dic)) ||
2345 //        isOperandInFarSpace (IC_RIGHT (dic)) ||
2346 //        isOperandInFarSpace (IC_RESULT (dic)) ||
2347 //        IS_OP_RUONLY (IC_LEFT (dic)) ||
2348 //        IS_OP_RUONLY (IC_RIGHT (dic)) ||
2349 //        IS_OP_RUONLY (IC_RESULT (dic)))
2350 //      {
2351 //        return NULL;
2352 //      }
2353 //      /* if left or right or result is on stack */
2354 //     if (isOperandOnStack(IC_LEFT(dic)) ||
2355 //        isOperandOnStack(IC_RIGHT(dic)) ||
2356 //        isOperandOnStack(IC_RESULT(dic))) {
2357 //      return NULL;
2358 //     }
2359     }
2360
2361   OP_SYMBOL (op)->ruonly = 1;
2362   return sic;
2363 }
2364 #endif
2365
2366 /*-----------------------------------------------------------------*/
2367 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
2368 /*-----------------------------------------------------------------*/
2369 static bool
2370 isBitwiseOptimizable (iCode * ic)
2371 {
2372   sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
2373   sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
2374
2375   /* bitwise operations are considered optimizable
2376      under the following conditions (Jean-Louis VERN) 
2377
2378      x & lit
2379      bit & bit
2380      bit & x
2381      bit ^ bit
2382      bit ^ x
2383      x   ^ lit
2384      x   | lit
2385      bit | bit
2386      bit | x
2387   */
2388   if (IS_LITERAL(rtype) ||
2389       (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
2390     return TRUE;
2391   else
2392     return FALSE;
2393 }
2394
2395 /*-----------------------------------------------------------------*/
2396 /* isCommutativeOp - tests whether this op cares what order its    */
2397 /*                   operands are in                               */
2398 /*-----------------------------------------------------------------*/
2399 bool isCommutativeOp2(unsigned int op)
2400 {
2401   if (op == '+' || op == '*' || op == EQ_OP ||
2402       op == '^' || op == '|' || op == BITWISEAND)
2403     return TRUE;
2404   else
2405     return FALSE;
2406 }
2407
2408 /*-----------------------------------------------------------------*/
2409 /* operandUsesAcc2 - determines whether the code generated for this */
2410 /*                  operand will have to use the accumulator       */
2411 /*-----------------------------------------------------------------*/
2412 bool operandUsesAcc2(operand *op)
2413 {
2414   if (!op)
2415     return FALSE;
2416
2417   if (IS_SYMOP(op)) {
2418     symbol *sym = OP_SYMBOL(op);
2419     memmap *symspace;
2420
2421     if (sym->accuse)
2422       return TRUE;  /* duh! */
2423
2424 //    if (IN_STACK(sym->etype) || sym->onStack ||
2425 //      (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
2426 //      return TRUE;  /* acc is used to calc stack offset */
2427
2428     if (IS_ITEMP(op))
2429       {
2430         if (SPIL_LOC(op)) {
2431           sym = SPIL_LOC(op);  /* if spilled, look at spill location */
2432         } else {
2433           return FALSE;  /* more checks? */
2434         }
2435       }
2436
2437     symspace = SPEC_OCLS(sym->etype);
2438
2439 //    if (sym->iaccess && symspace->paged)
2440 //      return TRUE;  /* must fetch paged indirect sym via accumulator */
2441     
2442     if (IN_BITSPACE(symspace))
2443       return TRUE;  /* fetching bit vars uses the accumulator */
2444     
2445     if (IN_FARSPACE(symspace) || IN_CODESPACE(symspace)) 
2446       return TRUE;  /* fetched via accumulator and dptr */
2447   }
2448
2449   return FALSE;
2450 }
2451
2452 /*-----------------------------------------------------------------*/
2453 /* packRegsForAccUse - pack registers for acc use                  */
2454 /*-----------------------------------------------------------------*/
2455 static void
2456 packRegsForAccUse (iCode * ic)
2457 {
2458   iCode *uic;
2459
2460   /* if this is an aggregate, e.g. a one byte char array */
2461   if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
2462     return;
2463   }
2464
2465   /* if we are calling a reentrant function that has stack parameters */
2466   #if 0
2467   if (ic->op == CALL &&
2468        IFFUNC_ISREENT(operandType(IC_LEFT(ic))) &&
2469        FUNC_HASSTACKPARM(operandType(IC_LEFT(ic))))
2470       return;
2471
2472   if (ic->op == PCALL &&
2473        IFFUNC_ISREENT(operandType(IC_LEFT(ic))->next) &&
2474        FUNC_HASSTACKPARM(operandType(IC_LEFT(ic))->next))
2475       return;
2476   #endif
2477
2478   /* if + or - then it has to be one byte result */
2479   if ((ic->op == '+' || ic->op == '-')
2480       && getSize (operandType (IC_RESULT (ic))) > 1)
2481     return;
2482
2483
2484   /* if shift operation make sure right side is a literal */
2485   if (ic->op == RIGHT_OP &&
2486       (!isOperandLiteral (IC_RIGHT (ic)) ||
2487        (getSize (operandType (IC_RESULT (ic) )) > 1)))
2488     return;
2489
2490   if (ic->op == LEFT_OP &&
2491       (!isOperandLiteral (IC_RIGHT (ic)) ||
2492        (getSize (operandType (IC_RESULT (ic) )) > 1)))
2493     return;
2494
2495   if (IS_BITWISE_OP (ic) &&
2496       getSize (operandType (IC_RESULT (ic))) > 1)
2497     return;
2498
2499
2500   /* has only one definition */
2501   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
2502     return;
2503
2504   /* has only one use */
2505   if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
2506     return;
2507
2508   /* and the usage immediately follows this iCode */
2509   if (!(uic = hTabItemWithKey (iCodehTab,
2510                                bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
2511     return;
2512
2513   if (ic->next != uic)
2514     return;
2515
2516   /* if it is a conditional branch then we definitely can */
2517   if (uic->op == IFX)
2518     goto accuse;
2519
2520   if (uic->op == JUMPTABLE)
2521     return;
2522
2523 #if 0
2524   if (POINTER_SET (uic) &&
2525       getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
2526     return;
2527 #endif
2528
2529   /* if the usage is not is an assignment
2530      or an arithmetic / bitwise / shift operation then not */
2531   if (uic->op != '=' &&
2532       !IS_ARITHMETIC_OP (uic) &&
2533       !IS_BITWISE_OP (uic) &&
2534       (uic->op != LEFT_OP) &&
2535       (uic->op != RIGHT_OP) &&
2536       (uic->op != GETHBIT) &&
2537       (uic->op != RETURN) &&
2538       (uic->op != '~') &&
2539       (uic->op != '!'))
2540     return;
2541
2542 #if 0
2543   /* if used in ^ operation then make sure right is not a 
2544      literal (WIML: Why is this?) */
2545   if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
2546     return;
2547
2548   /* if shift operation make sure right side is not a literal */
2549   /* WIML: Why is this? */
2550   if (uic->op == RIGHT_OP &&
2551       (isOperandLiteral (IC_RIGHT (uic)) ||
2552        getSize (operandType (IC_RESULT (uic))) > 1))
2553     return;
2554   if (uic->op == LEFT_OP &&
2555       (isOperandLiteral (IC_RIGHT (uic)) ||
2556        getSize (operandType (IC_RESULT (uic))) > 1))
2557     return;
2558 #endif
2559
2560   /* make sure that the result of this icode is not on the
2561      stack, since acc is used to compute stack offset */
2562 #if 0
2563   if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
2564       OP_SYMBOL (IC_RESULT (uic))->onStack)
2565     return;
2566 #else
2567 //  if (isOperandOnStack(IC_RESULT(uic)))
2568 //    return;
2569 #endif
2570
2571   /* if the usage has only one operand then we can */
2572   if (IC_LEFT (uic) == NULL ||
2573       IC_RIGHT (uic) == NULL)
2574     goto accuse;
2575
2576 #if 0
2577   /* if the other operand uses the accumulator then we cannot */
2578   if ( (IC_LEFT(uic)->key == IC_RESULT(ic)->key &&
2579         operandUsesAcc2(IC_RIGHT(uic))) ||
2580        (IC_RIGHT(uic)->key == IC_RESULT(ic)->key &&
2581         operandUsesAcc2(IC_LEFT(uic))) ) 
2582     return;
2583
2584   /* make sure this is on the left side if not commutative */
2585   /* except for '-', which has been written to be able to
2586      handle reversed operands */
2587   if (!(isCommutativeOp2(ic->op) || ic->op == '-') &&
2588        IC_LEFT (uic)->key != IC_RESULT (ic)->key)
2589     return;
2590 #endif
2591
2592 #if 0
2593   // this is too dangerous and need further restrictions
2594   // see bug #447547
2595
2596   /* if one of them is a literal then we can */
2597   if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
2598       (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
2599     {
2600       OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2601       return;
2602     }
2603 #endif
2604
2605 accuse:
2606
2607   if ((POINTER_GET(uic))
2608       || (ic->op == ADDRESS_OF && uic->op == '+' && IS_OP_LITERAL (IC_RIGHT (uic))))
2609     {
2610       OP_SYMBOL (IC_RESULT (ic))->accuse = ACCUSE_HX;
2611       return;
2612     }
2613   
2614   OP_SYMBOL (IC_RESULT (ic))->accuse = ACCUSE_XA;
2615 }
2616
2617 /*-----------------------------------------------------------------*/
2618 /* packForPush - hueristics to reduce iCode for pushing            */
2619 /*-----------------------------------------------------------------*/
2620 static void
2621 packForPush (iCode * ic, eBBlock ** ebpp, int blockno)
2622 {
2623   iCode *dic, *lic;
2624   bitVect *dbv;
2625   struct eBBlock * ebp=ebpp[blockno];
2626
2627   if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
2628     return;
2629
2630   /* must have only definition & one usage */
2631   if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
2632       bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
2633     return;
2634
2635   /* find the definition */
2636   if (!(dic = hTabItemWithKey (iCodehTab,
2637                                bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
2638     return;
2639
2640   if (dic->op != '=' || POINTER_SET (dic))
2641     return;
2642
2643   if (dic->seq < ebp->fSeq) { // Evelyn did this
2644     int i;
2645     for (i=0; i<blockno; i++) {
2646       if (dic->seq >= ebpp[i]->fSeq && dic->seq <= ebpp[i]->lSeq) {
2647         ebp=ebpp[i];
2648         break;
2649       }
2650     }
2651     wassert (i!=blockno); // no way to recover from here
2652   }
2653
2654   if (IS_SYMOP(IC_RIGHT(dic))) {
2655     /* make sure the right side does not have any definitions
2656        inbetween */
2657     dbv = OP_DEFS(IC_RIGHT(dic));
2658     for (lic = ic; lic && lic != dic ; lic = lic->prev) {
2659       if (bitVectBitValue(dbv,lic->key)) 
2660         return ;
2661     }
2662     /* make sure they have the same type */
2663     if (IS_SPEC(operandType(IC_LEFT(ic))))
2664     {
2665       sym_link *itype=operandType(IC_LEFT(ic));
2666       sym_link *ditype=operandType(IC_RIGHT(dic));
2667       
2668       if (SPEC_USIGN(itype)!=SPEC_USIGN(ditype) ||
2669           SPEC_LONG(itype)!=SPEC_LONG(ditype))
2670         return;
2671     }
2672     /* extend the live range of replaced operand if needed */
2673     if (OP_SYMBOL(IC_RIGHT(dic))->liveTo < ic->seq) {
2674       OP_SYMBOL(IC_RIGHT(dic))->liveTo = ic->seq;
2675     }
2676     bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2677   } 
2678
2679   /* we now we know that it has one & only one def & use
2680      and the that the definition is an assignment */
2681   ReplaceOpWithCheaperOp(&IC_LEFT (ic), IC_RIGHT (dic));
2682   remiCodeFromeBBlock (ebp, dic);
2683   hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2684 }
2685
2686 /*-----------------------------------------------------------------*/
2687 /* packRegisters - does some transformations to reduce register    */
2688 /*                   pressure                                      */
2689 /*-----------------------------------------------------------------*/
2690 static void
2691 packRegisters (eBBlock ** ebpp, int blockno)
2692 {
2693   iCode *ic;
2694   int change = 0;
2695   eBBlock *ebp=ebpp[blockno];
2696
2697   while (1)
2698     {
2699
2700       change = 0;
2701
2702       /* look for assignments of the form */
2703       /* iTempNN = TRueSym (someoperation) SomeOperand */
2704       /*       ....                       */
2705       /* TrueSym := iTempNN:1             */
2706       for (ic = ebp->sch; ic; ic = ic->next)
2707         {
2708           /* find assignment of the form TrueSym := iTempNN:1 */
2709           if (ic->op == '=' && !POINTER_SET (ic) )
2710             change += packRegsForAssign (ic, ebp);
2711         }
2712
2713       if (!change)
2714         break;
2715     }
2716
2717   for (ic = ebp->sch; ic; ic = ic->next)
2718     {
2719       //packRegsForLiteral (ic);
2720       
2721       /* if this is an itemp & result of an address of a true sym 
2722          then mark this as rematerialisable   */
2723       if (ic->op == ADDRESS_OF &&
2724           IS_ITEMP (IC_RESULT (ic)) && 
2725           IS_TRUE_SYMOP (IC_LEFT (ic)) &&
2726           bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2727           !OP_SYMBOL (IC_LEFT (ic))->onStack )
2728         {
2729
2730           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2731           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2732           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2733
2734         }
2735 #if 1
2736       if (ic->op == '=' &&
2737           !POINTER_SET (ic) &&
2738           IS_ITEMP (IC_RESULT (ic)) &&
2739           IS_VALOP (IC_RIGHT (ic)) &&
2740           bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1)
2741         {
2742
2743           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2744           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2745           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2746
2747         }
2748 #endif
2749       /* if straight assignment then carry remat flag if
2750          this is the only definition */
2751       if (ic->op == '=' &&
2752           !POINTER_SET (ic) &&
2753           IS_SYMOP (IC_RIGHT (ic)) &&
2754           OP_SYMBOL (IC_RIGHT (ic))->remat &&
2755           !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode) &&
2756           bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
2757         {
2758
2759           OP_SYMBOL (IC_RESULT (ic))->remat =
2760             OP_SYMBOL (IC_RIGHT (ic))->remat;
2761           OP_SYMBOL (IC_RESULT (ic))->rematiCode =
2762             OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
2763         }
2764
2765       /* if cast to a generic pointer & the pointer being
2766          cast is remat, then we can remat this cast as well */
2767       if (ic->op == CAST && 
2768           IS_SYMOP(IC_RIGHT(ic)) &&
2769           OP_SYMBOL(IC_RIGHT(ic))->remat &&
2770           bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1) {
2771               sym_link *to_type = operandType(IC_LEFT(ic));
2772               sym_link *from_type = operandType(IC_RIGHT(ic));
2773               if (IS_GENPTR(to_type) && IS_PTR(from_type)) {                  
2774                       OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2775                       OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2776                       OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2777               }
2778       }
2779
2780       /* if this is a +/- operation with a rematerizable 
2781          then mark this as rematerializable as well */
2782       if ((ic->op == '+' || ic->op == '-') &&
2783           (IS_SYMOP (IC_LEFT (ic)) &&
2784            IS_ITEMP (IC_RESULT (ic)) &&
2785            IS_OP_LITERAL (IC_RIGHT (ic))) &&
2786            OP_SYMBOL (IC_LEFT (ic))->remat &&
2787           (!IS_SYMOP (IC_RIGHT (ic)) || !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode)) &&
2788            bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1)
2789         {
2790           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2791           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2792           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2793         }
2794
2795       /* mark the pointer usages */
2796       if (POINTER_SET (ic))
2797         OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
2798
2799       if (POINTER_GET (ic) &&
2800           IS_SYMOP(IC_LEFT (ic)))
2801         OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
2802
2803       if (!SKIP_IC2 (ic))
2804         {
2805 #if 0
2806           /* if we are using a symbol on the stack
2807              then we should say hc08_ptrRegReq */
2808           if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
2809             hc08_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
2810                                  OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
2811           else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
2812             hc08_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
2813                               OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
2814           else
2815             {
2816               if (IS_SYMOP (IC_LEFT (ic)))
2817                 hc08_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
2818                                 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
2819               if (IS_SYMOP (IC_RIGHT (ic)))
2820                 hc08_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
2821                                OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
2822               if (IS_SYMOP (IC_RESULT (ic)))
2823                 hc08_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
2824                               OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
2825             }
2826 #endif
2827         }
2828
2829       /* if the condition of an if instruction
2830          is defined in the previous instruction and
2831          this is the only usage then
2832          mark the itemp as a conditional */
2833       if ((IS_CONDITIONAL (ic) ||
2834            (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic))) &&
2835           ic->next && ic->next->op == IFX &&
2836           bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
2837           isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
2838           OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2839         {
2840           OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
2841           continue;
2842         }
2843
2844       /* reduce for support function calls */
2845       if (ic->supportRtn || (ic->op != IFX && ic->op != JUMPTABLE))
2846         packRegsForSupport (ic, ebp);
2847
2848       #if 0
2849       /* some cases the redundant moves can
2850          can be eliminated for return statements */
2851       if ((ic->op == RETURN || (ic->op == SEND && ic->argreg == 1)) &&
2852           /* !isOperandInFarSpace (IC_LEFT (ic)) && */
2853           options.model == MODEL_SMALL) {
2854         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2855       }
2856
2857       /* if pointer set & left has a size more than
2858          one and right is not in far space */
2859       if (POINTER_SET (ic) &&
2860           /* !isOperandInFarSpace (IC_RIGHT (ic)) && */
2861           !OP_SYMBOL (IC_RESULT (ic))->remat &&
2862           !IS_OP_RUONLY (IC_RIGHT (ic)) 
2863           /* && getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1 */ )
2864         packRegsForOneuse (ic, IC_RESULT (ic), ebp);
2865
2866       /* if pointer get */
2867       if (POINTER_GET (ic) &&
2868           IS_SYMOP (IC_LEFT (ic)) &&
2869           /* !isOperandInFarSpace (IC_RESULT (ic)) && */
2870           !OP_SYMBOL (IC_LEFT (ic))->remat &&
2871           !IS_OP_RUONLY (IC_RESULT (ic)) 
2872            /* && getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1 */)
2873         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2874
2875
2876       /* if this is cast for intergral promotion then
2877          check if only use of  the definition of the 
2878          operand being casted/ if yes then replace
2879          the result of that arithmetic operation with 
2880          this result and get rid of the cast */
2881       if (ic->op == CAST)
2882         {
2883           sym_link *fromType = operandType (IC_RIGHT (ic));
2884           sym_link *toType = operandType (IC_LEFT (ic));
2885
2886           if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
2887               getSize (fromType) != getSize (toType) &&
2888               SPEC_USIGN (fromType) == SPEC_USIGN (toType))
2889             {
2890
2891               iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2892               if (dic)
2893                 {
2894                   if (IS_ARITHMETIC_OP (dic))
2895                     {                  
2896                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2897                       ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
2898                       remiCodeFromeBBlock (ebp, ic);
2899                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2900                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2901                       OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2902                       ic = ic->prev;
2903                     }
2904                   else
2905                     OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
2906                 }
2907             }
2908           else
2909             {
2910
2911               /* if the type from and type to are the same
2912                  then if this is the only use then packit */
2913               if (compareType (operandType (IC_RIGHT (ic)),
2914                              operandType (IC_LEFT (ic))) == 1)
2915                 {
2916                   iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2917                   if (dic)
2918                     {
2919                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2920                       ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
2921                       remiCodeFromeBBlock (ebp, ic);
2922                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2923                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2924                       OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2925                       ic = ic->prev;
2926                     }
2927                 }
2928             }
2929         }
2930       #endif
2931       
2932       /* pack for PUSH 
2933          iTempNN := (some variable in farspace) V1
2934          push iTempNN ;
2935          -------------
2936          push V1
2937        */
2938       if (ic->op == IPUSH)
2939         {
2940           packForPush (ic, ebpp, blockno);
2941         }
2942
2943
2944       #if 1
2945       /* pack registers for accumulator use, when the
2946          result of an arithmetic or bit wise operation
2947          has only one use, that use is immediately following
2948          the defintion and the using iCode has only one
2949          operand or has two operands but one is literal &
2950          the result of that operation is not on stack then
2951          we can leave the result of this operation in x:a
2952          combination */
2953       if ((IS_ARITHMETIC_OP (ic)
2954            || IS_CONDITIONAL(ic)
2955            || IS_BITWISE_OP (ic)
2956            || ic->op == '='
2957            || ic->op == '!'
2958            || ic->op == '~'
2959            || ic->op == GETHBIT
2960            || ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == CALL
2961            || (ic->op == ADDRESS_OF && isOperandOnStack (IC_LEFT (ic)))
2962            || ic->op == RECEIVE
2963           ) &&
2964           IS_ITEMP (IC_RESULT (ic)) &&
2965           getSize (operandType (IC_RESULT (ic))) <= 1)
2966
2967         packRegsForAccUse (ic);
2968       #endif
2969     }
2970 }
2971
2972 /*-----------------------------------------------------------------*/
2973 /* assignRegisters - assigns registers to each live range as need  */
2974 /*-----------------------------------------------------------------*/
2975 void
2976 hc08_assignRegisters (eBBlock ** ebbs, int count)
2977 {
2978   iCode *ic;
2979   int i;
2980
2981   setToNull ((void *) &_G.funcrUsed);
2982   setToNull ((void *) &_G.regAssigned);
2983   setToNull ((void *) &_G.totRegAssigned);
2984   hc08_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
2985   hc08_nRegs = 5;
2986   hc08_reg_a = hc08_regWithIdx(A_IDX);
2987   hc08_reg_x = hc08_regWithIdx(X_IDX);
2988   hc08_reg_h = hc08_regWithIdx(H_IDX);
2989   hc08_reg_hx = hc08_regWithIdx(HX_IDX);
2990   hc08_reg_xa = hc08_regWithIdx(XA_IDX);
2991
2992   /* change assignments this will remove some
2993      live ranges reducing some register pressure */
2994   for (i = 0; i < count; i++)
2995     packRegisters (ebbs, i);
2996
2997   if (options.dump_pack)
2998     dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
2999
3000   /* first determine for each live range the number of 
3001      registers & the type of registers required for each */
3002   regTypeNum (*ebbs);
3003
3004   /* and serially allocate registers */
3005   serialRegAssign (ebbs, count);
3006
3007   freeAllRegs ();
3008   //setToNull ((void *) &_G.regAssigned);
3009   //setToNull ((void *) &_G.totRegAssigned);
3010   fillGaps();
3011
3012   /* if stack was extended then tell the user */
3013   if (_G.stackExtend)
3014     {
3015 /*      werror(W_TOOMANY_SPILS,"stack", */
3016 /*             _G.stackExtend,currFunc->name,""); */
3017       _G.stackExtend = 0;
3018     }
3019
3020   if (_G.dataExtend)
3021     {
3022 /*      werror(W_TOOMANY_SPILS,"data space", */
3023 /*             _G.dataExtend,currFunc->name,""); */
3024       _G.dataExtend = 0;
3025     }
3026
3027   /* after that create the register mask
3028      for each of the instruction */
3029   createRegMask (ebbs, count);
3030
3031   /* redo that offsets for stacked automatic variables */
3032   if (currFunc) {
3033     redoStackOffsets ();
3034   }
3035
3036   if (options.dump_rassgn)
3037     {
3038       dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3039       dumpLiveRanges (DUMP_LRANGE, liveRanges);
3040     }
3041
3042   /* do the overlaysegment stuff SDCCmem.c */
3043   doOverlays (ebbs, count);
3044
3045   /* now get back the chain */
3046   ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3047
3048   genhc08Code (ic);
3049
3050   /* free up any _G.stackSpil locations allocated */
3051   applyToSet (_G.stackSpil, deallocStackSpil);
3052   _G.slocNum = 0;
3053   setToNull ((void **) &_G.stackSpil);
3054   setToNull ((void **) &_G.spiltSet);
3055   /* mark all registers as free */
3056   freeAllRegs ();
3057
3058   return;
3059 }