* src/hc08/ralloc.c (rematStr): fixed bug #879282
[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       /* if plus or minus print the right hand side */
1600       if (ic->op == '+' || ic->op == '-')
1601         {
1602           sprintf (s, "0x%04x %c ", (int) operandLitValue (IC_RIGHT (ic)),
1603                    ic->op);
1604           s += strlen (s);
1605           ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1606           continue;
1607         }
1608
1609 /*      
1610       if (ic->op == '+')
1611         {
1612           offset += operandLitValue (IC_RIGHT (ic));
1613           ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1614           continue;
1615         }
1616       if (ic->op == '-')
1617         {
1618           offset -= operandLitValue (IC_RIGHT (ic));
1619           ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1620           continue;
1621         }
1622 */
1623       /* cast then continue */
1624       if (IS_CAST_ICODE(ic)) {
1625           ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
1626           continue;
1627       }
1628       /* we reached the end */
1629       if (ic->op == ADDRESS_OF)
1630         sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
1631       else if (ic->op == '=')
1632         sprintf (s, "0x%04x", (int) operandLitValue (IC_RIGHT (ic)) );
1633       break;
1634     }
1635
1636   return buffer;
1637 }
1638
1639 /*-----------------------------------------------------------------*/
1640 /* regTypeNum - computes the type & number of registers required   */
1641 /*-----------------------------------------------------------------*/
1642 static void
1643 regTypeNum (eBBlock *ebbs)
1644 {
1645   symbol *sym;
1646   int k;
1647   iCode *ic;
1648
1649   /* for each live range do */
1650   for (sym = hTabFirstItem (liveRanges, &k); sym;
1651        sym = hTabNextItem (liveRanges, &k))
1652     {
1653
1654       /* if used zero times then no registers needed */
1655       if ((sym->liveTo - sym->liveFrom) == 0)
1656         continue;
1657
1658
1659       /* if the live range is a temporary */
1660       if (sym->isitmp)
1661         {
1662
1663           /* if the type is marked as a conditional */
1664           if (sym->regType == REG_CND)
1665             continue;
1666
1667           /* if used in return only then we don't 
1668              need registers */
1669           if (sym->ruonly || sym->accuse)
1670             {
1671               if (IS_AGGREGATE (sym->type) || sym->isptr)
1672                 sym->type = aggrToPtr (sym->type, FALSE);
1673               continue;
1674             }
1675
1676           /* if the symbol has only one definition &
1677              that definition is a get_pointer */
1678           if (bitVectnBitsOn (sym->defs) == 1 &&
1679               (ic = hTabItemWithKey (iCodehTab,
1680                                      bitVectFirstBit (sym->defs))) &&
1681               POINTER_GET (ic) &&
1682               !sym->noSpilLoc &&
1683               !IS_BITVAR (sym->etype))
1684             {
1685
1686
1687               /* and that pointer is remat in data space */
1688               if (IS_SYMOP (IC_LEFT (ic)) &&
1689                   OP_SYMBOL (IC_LEFT (ic))->remat &&
1690                   !IS_CAST_ICODE(OP_SYMBOL (IC_LEFT (ic))->rematiCode) &&
1691                   DCL_TYPE (aggrToPtr (operandType(IC_LEFT(ic)), FALSE)) == POINTER)
1692                 {
1693                   /* create a psuedo symbol & force a spil */
1694                   symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
1695                   psym->type = sym->type;
1696                   psym->etype = sym->etype;
1697                   strcpy (psym->rname, psym->name);
1698                   sym->isspilt = 1;
1699                   sym->usl.spillLoc = psym;
1700 #if 0 // an alternative fix for bug #480076
1701                   /* now this is a useless assignment to itself */
1702                   remiCodeFromeBBlock (ebbs, ic);
1703 #else
1704                   /* now this really is an assignment to itself, make it so;
1705                      it will be optimized out later */
1706                   ic->op='=';
1707                   ReplaceOpWithCheaperOp(&IC_RIGHT(ic), IC_RESULT(ic));
1708                   IC_LEFT(ic)=NULL;
1709 #endif
1710                   continue;
1711                 }
1712
1713               /* if in data space or idata space then try to
1714                  allocate pointer register */
1715
1716             }
1717
1718           /* if not then we require registers */
1719           sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
1720                         getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1721                         getSize (sym->type));
1722
1723           if (sym->nRegs > 4)
1724             {
1725               fprintf (stderr, "allocated more than 4 or 0 registers for type ");
1726               printTypeChain (sym->type, stderr);
1727               fprintf (stderr, "\n");
1728             }
1729
1730           /* determine the type of register required */
1731           if (sym->nRegs == 1 &&
1732               IS_PTR (sym->type) &&
1733               sym->uptr)
1734             sym->regType = REG_PTR;
1735           else
1736             sym->regType = REG_GPR;
1737
1738         }
1739       else
1740         /* for the first run we don't provide */
1741         /* registers for true symbols we will */
1742         /* see how things go                  */
1743         sym->nRegs = 0;
1744           }
1745
1746 }
1747
1748 /*-----------------------------------------------------------------*/
1749 /* freeAllRegs - mark all registers as free                        */
1750 /*-----------------------------------------------------------------*/
1751 static void
1752 freeAllRegs ()
1753 {
1754   int i;
1755
1756   for (i = 0; i < hc08_nRegs; i++) {
1757     regshc08[i].isFree = 1;
1758     regshc08[i].aop = NULL;
1759   }
1760 }
1761
1762 /*-----------------------------------------------------------------*/
1763 /* deallocStackSpil - this will set the stack pointer back         */
1764 /*-----------------------------------------------------------------*/
1765 static
1766 DEFSETFUNC (deallocStackSpil)
1767 {
1768   symbol *sym = item;
1769
1770   deallocLocal (sym);
1771   return 0;
1772 }
1773
1774 #if 0
1775 /*-----------------------------------------------------------------*/
1776 /* farSpacePackable - returns the packable icode for far variables */
1777 /*-----------------------------------------------------------------*/
1778 static iCode *
1779 farSpacePackable (iCode * ic)
1780 {
1781   iCode *dic;
1782
1783   /* go thru till we find a definition for the
1784      symbol on the right */
1785   for (dic = ic->prev; dic; dic = dic->prev)
1786     {
1787       /* if the definition is a call then no */
1788       if ((dic->op == CALL || dic->op == PCALL) &&
1789           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1790         {
1791           return NULL;
1792         }
1793
1794       /* if shift by unknown amount then not */
1795       if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
1796           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1797         return NULL;
1798
1799 #if 0
1800       /* if pointer get and size > 1 */
1801       if (POINTER_GET (dic) &&
1802           getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
1803         return NULL;
1804
1805       if (POINTER_SET (dic) &&
1806           getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
1807         return NULL;
1808 #endif
1809
1810       /* if any three is a true symbol in far space */
1811       if (IC_RESULT (dic) &&
1812           IS_TRUE_SYMOP (IC_RESULT (dic)) /* &&
1813           isOperandInFarSpace (IC_RESULT (dic)) */)
1814         return NULL;
1815
1816       if (IC_RIGHT (dic) &&
1817           IS_TRUE_SYMOP (IC_RIGHT (dic)) /* &&
1818           isOperandInFarSpace (IC_RIGHT (dic)) */ &&
1819           !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
1820         return NULL;
1821
1822       if (IC_LEFT (dic) &&
1823           IS_TRUE_SYMOP (IC_LEFT (dic)) /* &&
1824           isOperandInFarSpace (IC_LEFT (dic)) */ &&
1825           !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
1826         return NULL;
1827
1828       if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
1829         {
1830           if ((dic->op == LEFT_OP ||
1831                dic->op == RIGHT_OP ||
1832                dic->op == '-') &&
1833               IS_OP_LITERAL (IC_RIGHT (dic)))
1834             return NULL;
1835           else
1836             return dic;
1837         }
1838     }
1839
1840   return NULL;
1841 }
1842 #endif
1843
1844 #if 0
1845 static void
1846 packRegsForLiteral (iCode * ic)
1847 {
1848   int k;
1849   iCode *uic;
1850   
1851   if (ic->op != '=')
1852     return;
1853   if (POINTER_SET (ic))
1854     return;
1855   if (!IS_LITERAL (getSpec (operandType (IC_RIGHT (ic)))))
1856     return;
1857   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
1858     return;
1859
1860   for (k=0; k< OP_USES (IC_RESULT (ic))->size; k++)
1861     if (bitVectBitValue (OP_USES (IC_RESULT (ic)), k))
1862       {
1863         uic = hTabItemWithKey (iCodehTab, k);
1864         if (!uic) continue;
1865         
1866         if (uic->op != IFX && uic->op != JUMPTABLE)
1867           {
1868             if (IC_LEFT (uic) && IC_LEFT (uic)->key == IC_RESULT (ic)->key)
1869               ReplaceOpWithCheaperOp(&IC_LEFT(uic), IC_RIGHT(ic));
1870             if (IC_RIGHT (uic) && IC_RIGHT (uic)->key == IC_RESULT (ic)->key)
1871               ReplaceOpWithCheaperOp(&IC_RIGHT(uic), IC_RIGHT(ic));
1872             if (IC_RESULT (uic) && IC_RESULT (uic)->key == IC_RESULT (ic)->key)
1873               ReplaceOpWithCheaperOp(&IC_RESULT(uic), IC_RIGHT(ic));
1874           }
1875       }
1876
1877 }
1878 #endif
1879
1880
1881 /*-----------------------------------------------------------------*/
1882 /* packRegsForAssign - register reduction for assignment           */
1883 /*-----------------------------------------------------------------*/
1884 static int
1885 packRegsForAssign (iCode * ic, eBBlock * ebp)
1886 {
1887   iCode *dic, *sic;
1888
1889   if (!IS_ITEMP (IC_RIGHT (ic)) ||
1890       OP_SYMBOL (IC_RIGHT (ic))->isind ||
1891       OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
1892     {
1893       return 0;
1894     }
1895
1896
1897   /* if the true symbol is defined in far space or on stack
1898      then we should not since this will increase register pressure */
1899 #if 0
1900   if (isOperandInFarSpace(IC_RESULT(ic)) && !farSpacePackable(ic)) {
1901     return 0;
1902   }
1903 #endif
1904
1905   /* find the definition of iTempNN scanning backwards if we find a 
1906      a use of the true symbol in before we find the definition then 
1907      we cannot */
1908   for (dic = ic->prev; dic; dic = dic->prev)
1909     {
1910
1911 #if 0 /* jwk: This collides with 1.43 but I really see no need for
1912          this anymore. It fixes bug #716790 and substantially improves 
1913          redundant register usage around function calls.
1914       */
1915
1916       /* if there is a function call then don't pack it */
1917       if ((dic->op == CALL || dic->op == PCALL))
1918         {
1919           dic = NULL;
1920           break;
1921         }
1922 #endif
1923
1924       if (SKIP_IC2 (dic))
1925         continue;
1926
1927       if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
1928           IS_OP_VOLATILE (IC_RESULT (dic)))
1929         {
1930           dic = NULL;
1931           break;
1932         }
1933
1934       if (IS_SYMOP (IC_RESULT (dic)) &&
1935           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1936         {
1937           if (POINTER_SET (dic))
1938             dic = NULL;
1939
1940           break;
1941         }
1942
1943       if (IS_SYMOP (IC_RIGHT (dic)) &&
1944           (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
1945            IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
1946         {
1947           dic = NULL;
1948           break;
1949         }
1950
1951       if (IS_SYMOP (IC_LEFT (dic)) &&
1952           (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
1953            IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
1954         {
1955           dic = NULL;
1956           break;
1957         }
1958
1959       if (POINTER_SET (dic) &&
1960           IC_RESULT (dic)->key == IC_RESULT (ic)->key)
1961         {
1962           dic = NULL;
1963           break;
1964         }
1965     }
1966
1967   if (!dic)
1968     return 0;                   /* did not find */
1969
1970   /* if assignment then check that right is not a bit */
1971   if (ASSIGNMENT (dic) && !POINTER_SET (dic))
1972     {
1973       sym_link *etype = operandType (IC_RIGHT (dic));
1974       if (IS_BITFIELD (etype))
1975         {
1976           /* if result is a bit too then it's ok */
1977           etype = operandType (IC_RESULT (dic));
1978           if (!IS_BITFIELD (etype))
1979             return 0;
1980         }
1981     }
1982   /* if the result is on stack or iaccess then it must be
1983      the same atleast one of the operands */
1984   if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
1985       OP_SYMBOL (IC_RESULT (ic))->iaccess)
1986     {
1987
1988       /* the operation has only one symbol
1989          operator then we can pack */
1990       if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
1991           (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
1992         goto pack;
1993
1994       if (!((IC_LEFT (dic) &&
1995              IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
1996             (IC_RIGHT (dic) &&
1997              IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
1998         return 0;
1999     }
2000 pack:
2001   /* found the definition */
2002   /* replace the result with the result of */
2003   /* this assignment and remove this assignment */
2004   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2005   ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
2006
2007   if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2008     {
2009       OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2010     }
2011   // TODO: and the otherway around?
2012
2013   /* delete from liverange table also 
2014      delete from all the points inbetween and the new
2015      one */
2016   for (sic = dic; sic != ic; sic = sic->next)
2017     {
2018       bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2019       if (IS_ITEMP (IC_RESULT (dic)))
2020         bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2021     }
2022
2023   remiCodeFromeBBlock (ebp, ic);
2024   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2025   hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2026   OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2027   return 1;
2028 }
2029
2030
2031 /*------------------------------------------------------------------*/
2032 /* findAssignToSym : scanning backwards looks for first assig found */
2033 /*------------------------------------------------------------------*/
2034 static iCode *
2035 findAssignToSym (operand * op, iCode * ic)
2036 {
2037   iCode *dic;
2038
2039   /* This routine is used to find sequences like
2040      iTempAA = FOO;
2041      ...;  (intervening ops don't use iTempAA or modify FOO)
2042      blah = blah + iTempAA;
2043
2044      and eliminate the use of iTempAA, freeing up its register for
2045      other uses.
2046   */
2047      
2048
2049   for (dic = ic->prev; dic; dic = dic->prev)
2050     {
2051
2052       /* if definition by assignment */
2053       if (dic->op == '=' &&
2054           !POINTER_SET (dic) &&
2055           IC_RESULT (dic)->key == op->key
2056           &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) 
2057         )
2058         break;  /* found where this temp was defined */
2059
2060       /* if we find an usage then we cannot delete it */
2061       if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2062         return NULL;
2063
2064       if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2065         return NULL;
2066
2067       if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2068         return NULL;
2069     }
2070
2071   if (!dic)
2072     return NULL;   /* didn't find any assignment to op */
2073
2074   /* we are interested only if defined in far space */
2075   /* or in stack space in case of + & - */
2076   
2077   /* if assigned to a non-symbol then don't repack regs */
2078   if (!IS_SYMOP (IC_RIGHT (dic)))
2079     return NULL;
2080   
2081   /* if the symbol is volatile then we should not */
2082   if (isOperandVolatile (IC_RIGHT (dic), TRUE))
2083     return NULL;
2084   /* XXX TODO --- should we be passing FALSE to isOperandVolatile()?
2085      What does it mean for an iTemp to be volatile, anyway? Passing
2086      TRUE is more cautious but may prevent possible optimizations */
2087
2088   /* if the symbol is in far space then we should not */
2089   /* if (isOperandInFarSpace (IC_RIGHT (dic)))
2090     return NULL; */
2091   
2092   /* for + & - operations make sure that
2093      if it is on the stack it is the same
2094      as one of the three operands */
2095 #if 0
2096   if ((ic->op == '+' || ic->op == '-') &&
2097       OP_SYMBOL (IC_RIGHT (dic))->onStack)
2098     {
2099       
2100       if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2101           IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2102           IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2103         return NULL;
2104     }
2105 #endif
2106   
2107   /* now make sure that the right side of dic
2108      is not defined between ic & dic */
2109   if (dic)
2110     {
2111       iCode *sic = dic->next;
2112
2113       for (; sic != ic; sic = sic->next)
2114         if (IC_RESULT (sic) &&
2115             IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2116           return NULL;
2117     }
2118
2119   return dic;
2120 }
2121
2122 /*-----------------------------------------------------------------*/
2123 /* reassignAliasedSym - used by packRegsForSupport to replace      */
2124 /*                      redundant iTemp with equivalent symbol     */
2125 /*-----------------------------------------------------------------*/
2126 static void
2127 reassignAliasedSym (eBBlock *ebp, iCode *assignment, iCode *use, operand *op)
2128 {
2129   iCode *ic;
2130   unsigned oldSymKey, newSymKey;
2131
2132   oldSymKey = op->key;
2133   newSymKey = IC_RIGHT(assignment)->key;
2134
2135   /* only track live ranges of compiler-generated temporaries */
2136   if (!IS_ITEMP(IC_RIGHT(assignment)))
2137     newSymKey = 0;
2138
2139   /* update the live-value bitmaps */
2140   for (ic = assignment; ic != use; ic = ic->next) {
2141     bitVectUnSetBit (ic->rlive, oldSymKey);
2142     if (newSymKey != 0)
2143       ic->rlive = bitVectSetBit (ic->rlive, newSymKey);
2144   }
2145
2146   /* update the sym of the used operand */
2147   OP_SYMBOL(op) = OP_SYMBOL(IC_RIGHT(assignment));
2148   op->key = OP_SYMBOL(op)->key;
2149
2150   /* update the sym's liverange */
2151   if ( OP_LIVETO(op) < ic->seq )
2152     setToRange(op, ic->seq, FALSE);
2153
2154   /* remove the assignment iCode now that its result is unused */
2155   remiCodeFromeBBlock (ebp, assignment);
2156   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(assignment))->defs, assignment->key);
2157   hTabDeleteItem (&iCodehTab, assignment->key, assignment, DELETE_ITEM, NULL);
2158 }
2159   
2160
2161 /*-----------------------------------------------------------------*/
2162 /* packRegsForSupport :- reduce some registers for support calls   */
2163 /*-----------------------------------------------------------------*/
2164 static int
2165 packRegsForSupport (iCode * ic, eBBlock * ebp)
2166 {
2167   iCode *dic;
2168   int changes = 0;
2169   
2170   /* for the left & right operand :- look to see if the
2171      left was assigned a true symbol in far space in that
2172      case replace them */
2173
2174   if (IS_ITEMP (IC_LEFT (ic)) &&
2175       OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2176     {
2177       dic = findAssignToSym (IC_LEFT (ic), ic);
2178
2179       if (dic)
2180         {
2181           /* found it we need to remove it from the block */
2182           reassignAliasedSym (ebp, dic, ic, IC_LEFT(ic));
2183           changes++;
2184         }
2185     }
2186
2187   /* do the same for the right operand */
2188   if (IS_ITEMP (IC_RIGHT (ic)) &&
2189       OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2190     {
2191       iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2192
2193       if (dic)
2194         {
2195           /* found it we need to remove it from the block */
2196           reassignAliasedSym (ebp, dic, ic, IC_RIGHT(ic));
2197           changes++;
2198         }
2199     }
2200
2201   return changes;
2202 }
2203
2204 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
2205
2206
2207 #if 0
2208 /*-----------------------------------------------------------------*/
2209 /* packRegsForOneuse : - will reduce some registers for single Use */
2210 /*-----------------------------------------------------------------*/
2211 static iCode *
2212 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
2213 {
2214   bitVect *uses;
2215   iCode *dic, *sic;
2216
2217   /* if returning a literal then do nothing */
2218   if (!IS_SYMOP (op))
2219     return NULL;
2220
2221   /* only up to 2 bytes */
2222   if (getSize (operandType (op)) > (fReturnSizeHC08 - 2))
2223     return NULL;
2224
2225   return NULL;
2226   
2227   if (ic->op != SEND //RETURN
2228       && ic->op != SEND
2229       && !POINTER_SET (ic)
2230       && !POINTER_GET (ic) )
2231     return NULL;
2232   
2233   if (ic->op == SEND && ic->argreg != 1) return NULL;
2234
2235   /* this routine will mark the a symbol as used in one 
2236      instruction use only && if the defintion is local 
2237      (ie. within the basic block) && has only one definition &&
2238      that definiion is either a return value from a 
2239      function or does not contain any variables in
2240      far space */
2241   uses = bitVectCopy (OP_USES (op));
2242   bitVectUnSetBit (uses, ic->key);      /* take away this iCode */
2243   if (!bitVectIsZero (uses))    /* has other uses */
2244     return NULL;
2245
2246   /* if it has only one defintion */
2247   if (bitVectnBitsOn (OP_DEFS (op)) > 1)
2248     return NULL;                /* has more than one definition */
2249
2250   /* get that definition */
2251   if (!(dic =
2252         hTabItemWithKey (iCodehTab,
2253                          bitVectFirstBit (OP_DEFS (op)))))
2254     return NULL;
2255
2256   /* if that only usage is a cast */
2257   if (dic->op == CAST) {
2258     /* to a bigger type */
2259     if (getSize(OP_SYM_TYPE(IC_RESULT(dic))) > 
2260         getSize(OP_SYM_TYPE(IC_RIGHT(dic)))) {
2261       /* than we can not, since we cannot predict the usage of b & acc */
2262       return NULL;
2263     }
2264   }
2265
2266   /* found the definition now check if it is local */
2267   if (dic->seq < ebp->fSeq ||
2268       dic->seq > ebp->lSeq)
2269     return NULL;                /* non-local */
2270
2271   /* now check if it is the return from
2272      a function call */
2273   if (dic->op == CALL || dic->op == PCALL)
2274     {
2275       if (ic->op != SEND && ic->op != RETURN &&
2276           !POINTER_SET(ic) && !POINTER_GET(ic))
2277         {
2278           OP_SYMBOL (op)->ruonly = 1;
2279           return dic;
2280         }
2281       dic = dic->next;
2282     }
2283
2284
2285   /* otherwise check that the definition does
2286      not contain any symbols in far space */
2287 //  if (isOperandInFarSpace (IC_LEFT (dic)) ||
2288 //      isOperandInFarSpace (IC_RIGHT (dic)) ||
2289 //      IS_OP_RUONLY (IC_LEFT (ic)) ||
2290 //      IS_OP_RUONLY (IC_RIGHT (ic)))
2291 //    {
2292 //      return NULL;
2293 //    }
2294
2295   /* if pointer set then make sure the pointer
2296      is one byte */
2297 #if 0
2298   if (POINTER_SET (dic) &&
2299       !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2300     return NULL;
2301
2302   if (POINTER_GET (dic) &&
2303       !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2304     return NULL;
2305 #endif 
2306
2307   sic = dic;
2308
2309   /* also make sure the intervenening instructions
2310      don't have any thing in far space */
2311   for (dic = dic->next; dic && dic != ic && sic != ic; dic = dic->next)
2312     {
2313
2314       /* if there is an intervening function call then no */
2315       if (dic->op == CALL || dic->op == PCALL)
2316         return NULL;
2317       /* if pointer set then make sure the pointer
2318          is one byte */
2319 #if 0
2320       if (POINTER_SET (dic) &&
2321           !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2322         return NULL;
2323
2324       if (POINTER_GET (dic) &&
2325           !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2326         return NULL;
2327 #endif
2328       /* if address of & the result is remat the okay */
2329       if (dic->op == ADDRESS_OF &&
2330           OP_SYMBOL (IC_RESULT (dic))->remat)
2331         continue;
2332
2333       /* if operand has size of three or more & this
2334          operation is a '*','/' or '%' then 'b' may
2335          cause a problem */
2336 #if 0
2337       if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
2338           getSize (operandType (op)) >= 3)
2339         return NULL;
2340 #endif
2341
2342       /* if left or right or result is in far space */
2343 //      if (isOperandInFarSpace (IC_LEFT (dic)) ||
2344 //        isOperandInFarSpace (IC_RIGHT (dic)) ||
2345 //        isOperandInFarSpace (IC_RESULT (dic)) ||
2346 //        IS_OP_RUONLY (IC_LEFT (dic)) ||
2347 //        IS_OP_RUONLY (IC_RIGHT (dic)) ||
2348 //        IS_OP_RUONLY (IC_RESULT (dic)))
2349 //      {
2350 //        return NULL;
2351 //      }
2352 //      /* if left or right or result is on stack */
2353 //     if (isOperandOnStack(IC_LEFT(dic)) ||
2354 //        isOperandOnStack(IC_RIGHT(dic)) ||
2355 //        isOperandOnStack(IC_RESULT(dic))) {
2356 //      return NULL;
2357 //     }
2358     }
2359
2360   OP_SYMBOL (op)->ruonly = 1;
2361   return sic;
2362 }
2363 #endif
2364
2365 /*-----------------------------------------------------------------*/
2366 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
2367 /*-----------------------------------------------------------------*/
2368 static bool
2369 isBitwiseOptimizable (iCode * ic)
2370 {
2371   sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
2372   sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
2373
2374   /* bitwise operations are considered optimizable
2375      under the following conditions (Jean-Louis VERN) 
2376
2377      x & lit
2378      bit & bit
2379      bit & x
2380      bit ^ bit
2381      bit ^ x
2382      x   ^ lit
2383      x   | lit
2384      bit | bit
2385      bit | x
2386   */
2387   if (IS_LITERAL(rtype) ||
2388       (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
2389     return TRUE;
2390   else
2391     return FALSE;
2392 }
2393
2394 /*-----------------------------------------------------------------*/
2395 /* isCommutativeOp - tests whether this op cares what order its    */
2396 /*                   operands are in                               */
2397 /*-----------------------------------------------------------------*/
2398 bool isCommutativeOp2(unsigned int op)
2399 {
2400   if (op == '+' || op == '*' || op == EQ_OP ||
2401       op == '^' || op == '|' || op == BITWISEAND)
2402     return TRUE;
2403   else
2404     return FALSE;
2405 }
2406
2407 /*-----------------------------------------------------------------*/
2408 /* operandUsesAcc2 - determines whether the code generated for this */
2409 /*                  operand will have to use the accumulator       */
2410 /*-----------------------------------------------------------------*/
2411 bool operandUsesAcc2(operand *op)
2412 {
2413   if (!op)
2414     return FALSE;
2415
2416   if (IS_SYMOP(op)) {
2417     symbol *sym = OP_SYMBOL(op);
2418     memmap *symspace;
2419
2420     if (sym->accuse)
2421       return TRUE;  /* duh! */
2422
2423 //    if (IN_STACK(sym->etype) || sym->onStack ||
2424 //      (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
2425 //      return TRUE;  /* acc is used to calc stack offset */
2426
2427     if (IS_ITEMP(op))
2428       {
2429         if (SPIL_LOC(op)) {
2430           sym = SPIL_LOC(op);  /* if spilled, look at spill location */
2431         } else {
2432           return FALSE;  /* more checks? */
2433         }
2434       }
2435
2436     symspace = SPEC_OCLS(sym->etype);
2437
2438 //    if (sym->iaccess && symspace->paged)
2439 //      return TRUE;  /* must fetch paged indirect sym via accumulator */
2440     
2441     if (IN_BITSPACE(symspace))
2442       return TRUE;  /* fetching bit vars uses the accumulator */
2443     
2444     if (IN_FARSPACE(symspace) || IN_CODESPACE(symspace)) 
2445       return TRUE;  /* fetched via accumulator and dptr */
2446   }
2447
2448   return FALSE;
2449 }
2450
2451 /*-----------------------------------------------------------------*/
2452 /* packRegsForAccUse - pack registers for acc use                  */
2453 /*-----------------------------------------------------------------*/
2454 static void
2455 packRegsForAccUse (iCode * ic)
2456 {
2457   iCode *uic;
2458
2459   /* if this is an aggregate, e.g. a one byte char array */
2460   if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
2461     return;
2462   }
2463
2464   /* if we are calling a reentrant function that has stack parameters */
2465   #if 0
2466   if (ic->op == CALL &&
2467        IFFUNC_ISREENT(operandType(IC_LEFT(ic))) &&
2468        FUNC_HASSTACKPARM(operandType(IC_LEFT(ic))))
2469       return;
2470
2471   if (ic->op == PCALL &&
2472        IFFUNC_ISREENT(operandType(IC_LEFT(ic))->next) &&
2473        FUNC_HASSTACKPARM(operandType(IC_LEFT(ic))->next))
2474       return;
2475   #endif
2476
2477   /* if + or - then it has to be one byte result */
2478   if ((ic->op == '+' || ic->op == '-')
2479       && getSize (operandType (IC_RESULT (ic))) > 1)
2480     return;
2481
2482
2483   /* if shift operation make sure right side is a literal */
2484   if (ic->op == RIGHT_OP &&
2485       (!isOperandLiteral (IC_RIGHT (ic)) ||
2486        (getSize (operandType (IC_RESULT (ic) )) > 1)))
2487     return;
2488
2489   if (ic->op == LEFT_OP &&
2490       (!isOperandLiteral (IC_RIGHT (ic)) ||
2491        (getSize (operandType (IC_RESULT (ic) )) > 1)))
2492     return;
2493
2494   if (IS_BITWISE_OP (ic) &&
2495       getSize (operandType (IC_RESULT (ic))) > 1)
2496     return;
2497
2498
2499   /* has only one definition */
2500   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
2501     return;
2502
2503   /* has only one use */
2504   if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
2505     return;
2506
2507   /* and the usage immediately follows this iCode */
2508   if (!(uic = hTabItemWithKey (iCodehTab,
2509                                bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
2510     return;
2511
2512   if (ic->next != uic)
2513     return;
2514
2515   /* if it is a conditional branch then we definitely can */
2516   if (uic->op == IFX)
2517     goto accuse;
2518
2519   if (uic->op == JUMPTABLE)
2520     return;
2521
2522 #if 0
2523   if (POINTER_SET (uic) &&
2524       getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
2525     return;
2526 #endif
2527
2528   /* if the usage is not is an assignment
2529      or an arithmetic / bitwise / shift operation then not */
2530   if (uic->op != '=' &&
2531       !IS_ARITHMETIC_OP (uic) &&
2532       !IS_BITWISE_OP (uic) &&
2533       (uic->op != LEFT_OP) &&
2534       (uic->op != RIGHT_OP) &&
2535       (uic->op != GETHBIT) &&
2536       (uic->op != RETURN) &&
2537       (uic->op != '~') &&
2538       (uic->op != '!'))
2539     return;
2540
2541 #if 0
2542   /* if used in ^ operation then make sure right is not a 
2543      literal (WIML: Why is this?) */
2544   if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
2545     return;
2546
2547   /* if shift operation make sure right side is not a literal */
2548   /* WIML: Why is this? */
2549   if (uic->op == RIGHT_OP &&
2550       (isOperandLiteral (IC_RIGHT (uic)) ||
2551        getSize (operandType (IC_RESULT (uic))) > 1))
2552     return;
2553   if (uic->op == LEFT_OP &&
2554       (isOperandLiteral (IC_RIGHT (uic)) ||
2555        getSize (operandType (IC_RESULT (uic))) > 1))
2556     return;
2557 #endif
2558
2559   /* make sure that the result of this icode is not on the
2560      stack, since acc is used to compute stack offset */
2561 #if 0
2562   if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
2563       OP_SYMBOL (IC_RESULT (uic))->onStack)
2564     return;
2565 #else
2566 //  if (isOperandOnStack(IC_RESULT(uic)))
2567 //    return;
2568 #endif
2569
2570   /* if the usage has only one operand then we can */
2571   if (IC_LEFT (uic) == NULL ||
2572       IC_RIGHT (uic) == NULL)
2573     goto accuse;
2574
2575 #if 0
2576   /* if the other operand uses the accumulator then we cannot */
2577   if ( (IC_LEFT(uic)->key == IC_RESULT(ic)->key &&
2578         operandUsesAcc2(IC_RIGHT(uic))) ||
2579        (IC_RIGHT(uic)->key == IC_RESULT(ic)->key &&
2580         operandUsesAcc2(IC_LEFT(uic))) ) 
2581     return;
2582
2583   /* make sure this is on the left side if not commutative */
2584   /* except for '-', which has been written to be able to
2585      handle reversed operands */
2586   if (!(isCommutativeOp2(ic->op) || ic->op == '-') &&
2587        IC_LEFT (uic)->key != IC_RESULT (ic)->key)
2588     return;
2589 #endif
2590
2591 #if 0
2592   // this is too dangerous and need further restrictions
2593   // see bug #447547
2594
2595   /* if one of them is a literal then we can */
2596   if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
2597       (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
2598     {
2599       OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2600       return;
2601     }
2602 #endif
2603
2604 accuse:
2605
2606   if ((POINTER_GET(uic))
2607       || (ic->op == ADDRESS_OF && uic->op == '+' && IS_OP_LITERAL (IC_RIGHT (uic))))
2608     {
2609       OP_SYMBOL (IC_RESULT (ic))->accuse = ACCUSE_HX;
2610       return;
2611     }
2612   
2613   OP_SYMBOL (IC_RESULT (ic))->accuse = ACCUSE_XA;
2614 }
2615
2616 /*-----------------------------------------------------------------*/
2617 /* packForPush - hueristics to reduce iCode for pushing            */
2618 /*-----------------------------------------------------------------*/
2619 static void
2620 packForPush (iCode * ic, eBBlock ** ebpp, int blockno)
2621 {
2622   iCode *dic, *lic;
2623   bitVect *dbv;
2624   struct eBBlock * ebp=ebpp[blockno];
2625
2626   if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
2627     return;
2628
2629   /* must have only definition & one usage */
2630   if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
2631       bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
2632     return;
2633
2634   /* find the definition */
2635   if (!(dic = hTabItemWithKey (iCodehTab,
2636                                bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
2637     return;
2638
2639   if (dic->op != '=' || POINTER_SET (dic))
2640     return;
2641
2642   if (dic->seq < ebp->fSeq) { // Evelyn did this
2643     int i;
2644     for (i=0; i<blockno; i++) {
2645       if (dic->seq >= ebpp[i]->fSeq && dic->seq <= ebpp[i]->lSeq) {
2646         ebp=ebpp[i];
2647         break;
2648       }
2649     }
2650     wassert (i!=blockno); // no way to recover from here
2651   }
2652
2653   if (IS_SYMOP(IC_RIGHT(dic))) {
2654     /* make sure the right side does not have any definitions
2655        inbetween */
2656     dbv = OP_DEFS(IC_RIGHT(dic));
2657     for (lic = ic; lic && lic != dic ; lic = lic->prev) {
2658       if (bitVectBitValue(dbv,lic->key)) 
2659         return ;
2660     }
2661     /* make sure they have the same type */
2662     if (IS_SPEC(operandType(IC_LEFT(ic))))
2663     {
2664       sym_link *itype=operandType(IC_LEFT(ic));
2665       sym_link *ditype=operandType(IC_RIGHT(dic));
2666       
2667       if (SPEC_USIGN(itype)!=SPEC_USIGN(ditype) ||
2668           SPEC_LONG(itype)!=SPEC_LONG(ditype))
2669         return;
2670     }
2671     /* extend the live range of replaced operand if needed */
2672     if (OP_SYMBOL(IC_RIGHT(dic))->liveTo < ic->seq) {
2673       OP_SYMBOL(IC_RIGHT(dic))->liveTo = ic->seq;
2674     }
2675     bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2676   } 
2677
2678   /* we now we know that it has one & only one def & use
2679      and the that the definition is an assignment */
2680   ReplaceOpWithCheaperOp(&IC_LEFT (ic), IC_RIGHT (dic));
2681   remiCodeFromeBBlock (ebp, dic);
2682   hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2683 }
2684
2685 /*-----------------------------------------------------------------*/
2686 /* packRegisters - does some transformations to reduce register    */
2687 /*                   pressure                                      */
2688 /*-----------------------------------------------------------------*/
2689 static void
2690 packRegisters (eBBlock ** ebpp, int blockno)
2691 {
2692   iCode *ic;
2693   int change = 0;
2694   eBBlock *ebp=ebpp[blockno];
2695
2696   while (1)
2697     {
2698
2699       change = 0;
2700
2701       /* look for assignments of the form */
2702       /* iTempNN = TRueSym (someoperation) SomeOperand */
2703       /*       ....                       */
2704       /* TrueSym := iTempNN:1             */
2705       for (ic = ebp->sch; ic; ic = ic->next)
2706         {
2707           /* find assignment of the form TrueSym := iTempNN:1 */
2708           if (ic->op == '=' && !POINTER_SET (ic) )
2709             change += packRegsForAssign (ic, ebp);
2710         }
2711
2712       if (!change)
2713         break;
2714     }
2715
2716   for (ic = ebp->sch; ic; ic = ic->next)
2717     {
2718       //packRegsForLiteral (ic);
2719       
2720       /* if this is an itemp & result of an address of a true sym 
2721          then mark this as rematerialisable   */
2722       if (ic->op == ADDRESS_OF &&
2723           IS_ITEMP (IC_RESULT (ic)) && 
2724           IS_TRUE_SYMOP (IC_LEFT (ic)) &&
2725           bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2726           !OP_SYMBOL (IC_LEFT (ic))->onStack )
2727         {
2728
2729           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2730           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2731           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2732
2733         }
2734 #if 1
2735       if (ic->op == '=' &&
2736           !POINTER_SET (ic) &&
2737           IS_ITEMP (IC_RESULT (ic)) &&
2738           IS_VALOP (IC_RIGHT (ic)) &&
2739           bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1)
2740         {
2741
2742           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2743           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2744           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2745
2746         }
2747 #endif
2748       /* if straight assignment then carry remat flag if
2749          this is the only definition */
2750       if (ic->op == '=' &&
2751           !POINTER_SET (ic) &&
2752           IS_SYMOP (IC_RIGHT (ic)) &&
2753           OP_SYMBOL (IC_RIGHT (ic))->remat &&
2754           !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode) &&
2755           bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
2756         {
2757
2758           OP_SYMBOL (IC_RESULT (ic))->remat =
2759             OP_SYMBOL (IC_RIGHT (ic))->remat;
2760           OP_SYMBOL (IC_RESULT (ic))->rematiCode =
2761             OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
2762         }
2763
2764       /* if cast to a generic pointer & the pointer being
2765          cast is remat, then we can remat this cast as well */
2766       if (ic->op == CAST && 
2767           IS_SYMOP(IC_RIGHT(ic)) &&
2768           OP_SYMBOL(IC_RIGHT(ic))->remat &&
2769           bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1) {
2770               sym_link *to_type = operandType(IC_LEFT(ic));
2771               sym_link *from_type = operandType(IC_RIGHT(ic));
2772               if (IS_GENPTR(to_type) && IS_PTR(from_type)) {                  
2773                       OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2774                       OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2775                       OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2776               }
2777       }
2778
2779       /* if this is a +/- operation with a rematerizable 
2780          then mark this as rematerializable as well */
2781       if ((ic->op == '+' || ic->op == '-') &&
2782           (IS_SYMOP (IC_LEFT (ic)) &&
2783            IS_ITEMP (IC_RESULT (ic)) &&
2784            IS_OP_LITERAL (IC_RIGHT (ic))) &&
2785            OP_SYMBOL (IC_LEFT (ic))->remat &&
2786           (!IS_SYMOP (IC_RIGHT (ic)) || !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode)) &&
2787            bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1)
2788         {
2789           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2790           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2791           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2792         }
2793
2794       /* mark the pointer usages */
2795       if (POINTER_SET (ic))
2796         OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
2797
2798       if (POINTER_GET (ic) &&
2799           IS_SYMOP(IC_LEFT (ic)))
2800         OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
2801
2802       if (!SKIP_IC2 (ic))
2803         {
2804 #if 0
2805           /* if we are using a symbol on the stack
2806              then we should say hc08_ptrRegReq */
2807           if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
2808             hc08_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
2809                                  OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
2810           else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
2811             hc08_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
2812                               OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
2813           else
2814             {
2815               if (IS_SYMOP (IC_LEFT (ic)))
2816                 hc08_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
2817                                 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
2818               if (IS_SYMOP (IC_RIGHT (ic)))
2819                 hc08_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
2820                                OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
2821               if (IS_SYMOP (IC_RESULT (ic)))
2822                 hc08_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
2823                               OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
2824             }
2825 #endif
2826         }
2827
2828       /* if the condition of an if instruction
2829          is defined in the previous instruction and
2830          this is the only usage then
2831          mark the itemp as a conditional */
2832       if ((IS_CONDITIONAL (ic) ||
2833            (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic))) &&
2834           ic->next && ic->next->op == IFX &&
2835           bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
2836           isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
2837           OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2838         {
2839           OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
2840           continue;
2841         }
2842
2843       /* reduce for support function calls */
2844       if (ic->supportRtn || (ic->op != IFX && ic->op != JUMPTABLE))
2845         packRegsForSupport (ic, ebp);
2846
2847       #if 0
2848       /* some cases the redundant moves can
2849          can be eliminated for return statements */
2850       if ((ic->op == RETURN || (ic->op == SEND && ic->argreg == 1)) &&
2851           /* !isOperandInFarSpace (IC_LEFT (ic)) && */
2852           options.model == MODEL_SMALL) {
2853         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2854       }
2855
2856       /* if pointer set & left has a size more than
2857          one and right is not in far space */
2858       if (POINTER_SET (ic) &&
2859           /* !isOperandInFarSpace (IC_RIGHT (ic)) && */
2860           !OP_SYMBOL (IC_RESULT (ic))->remat &&
2861           !IS_OP_RUONLY (IC_RIGHT (ic)) 
2862           /* && getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1 */ )
2863         packRegsForOneuse (ic, IC_RESULT (ic), ebp);
2864
2865       /* if pointer get */
2866       if (POINTER_GET (ic) &&
2867           IS_SYMOP (IC_LEFT (ic)) &&
2868           /* !isOperandInFarSpace (IC_RESULT (ic)) && */
2869           !OP_SYMBOL (IC_LEFT (ic))->remat &&
2870           !IS_OP_RUONLY (IC_RESULT (ic)) 
2871            /* && getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1 */)
2872         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2873
2874
2875       /* if this is cast for intergral promotion then
2876          check if only use of  the definition of the 
2877          operand being casted/ if yes then replace
2878          the result of that arithmetic operation with 
2879          this result and get rid of the cast */
2880       if (ic->op == CAST)
2881         {
2882           sym_link *fromType = operandType (IC_RIGHT (ic));
2883           sym_link *toType = operandType (IC_LEFT (ic));
2884
2885           if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
2886               getSize (fromType) != getSize (toType) &&
2887               SPEC_USIGN (fromType) == SPEC_USIGN (toType))
2888             {
2889
2890               iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2891               if (dic)
2892                 {
2893                   if (IS_ARITHMETIC_OP (dic))
2894                     {                  
2895                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2896                       ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
2897                       remiCodeFromeBBlock (ebp, ic);
2898                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2899                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2900                       OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2901                       ic = ic->prev;
2902                     }
2903                   else
2904                     OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
2905                 }
2906             }
2907           else
2908             {
2909
2910               /* if the type from and type to are the same
2911                  then if this is the only use then packit */
2912               if (compareType (operandType (IC_RIGHT (ic)),
2913                              operandType (IC_LEFT (ic))) == 1)
2914                 {
2915                   iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2916                   if (dic)
2917                     {
2918                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2919                       ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
2920                       remiCodeFromeBBlock (ebp, ic);
2921                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2922                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2923                       OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2924                       ic = ic->prev;
2925                     }
2926                 }
2927             }
2928         }
2929       #endif
2930       
2931       /* pack for PUSH 
2932          iTempNN := (some variable in farspace) V1
2933          push iTempNN ;
2934          -------------
2935          push V1
2936        */
2937       if (ic->op == IPUSH)
2938         {
2939           packForPush (ic, ebpp, blockno);
2940         }
2941
2942
2943       #if 1
2944       /* pack registers for accumulator use, when the
2945          result of an arithmetic or bit wise operation
2946          has only one use, that use is immediately following
2947          the defintion and the using iCode has only one
2948          operand or has two operands but one is literal &
2949          the result of that operation is not on stack then
2950          we can leave the result of this operation in x:a
2951          combination */
2952       if ((IS_ARITHMETIC_OP (ic)
2953            || IS_CONDITIONAL(ic)
2954            || IS_BITWISE_OP (ic)
2955            || ic->op == '='
2956            || ic->op == '!'
2957            || ic->op == '~'
2958            || ic->op == GETHBIT
2959            || ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == CALL
2960            || (ic->op == ADDRESS_OF && isOperandOnStack (IC_LEFT (ic)))
2961            || ic->op == RECEIVE
2962           ) &&
2963           IS_ITEMP (IC_RESULT (ic)) &&
2964           getSize (operandType (IC_RESULT (ic))) <= 1)
2965
2966         packRegsForAccUse (ic);
2967       #endif
2968     }
2969 }
2970
2971 /*-----------------------------------------------------------------*/
2972 /* assignRegisters - assigns registers to each live range as need  */
2973 /*-----------------------------------------------------------------*/
2974 void
2975 hc08_assignRegisters (eBBlock ** ebbs, int count)
2976 {
2977   iCode *ic;
2978   int i;
2979
2980   setToNull ((void *) &_G.funcrUsed);
2981   setToNull ((void *) &_G.regAssigned);
2982   setToNull ((void *) &_G.totRegAssigned);
2983   hc08_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
2984   hc08_nRegs = 5;
2985   hc08_reg_a = hc08_regWithIdx(A_IDX);
2986   hc08_reg_x = hc08_regWithIdx(X_IDX);
2987   hc08_reg_h = hc08_regWithIdx(H_IDX);
2988   hc08_reg_hx = hc08_regWithIdx(HX_IDX);
2989   hc08_reg_xa = hc08_regWithIdx(XA_IDX);
2990
2991   /* change assignments this will remove some
2992      live ranges reducing some register pressure */
2993   for (i = 0; i < count; i++)
2994     packRegisters (ebbs, i);
2995
2996   /* liveranges probably changed by register packing
2997      so we compute them again */
2998   recomputeLiveRanges (ebbs, count);
2999   
3000   if (options.dump_pack)
3001     dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3002
3003   /* first determine for each live range the number of 
3004      registers & the type of registers required for each */
3005   regTypeNum (*ebbs);
3006
3007   /* and serially allocate registers */
3008   serialRegAssign (ebbs, count);
3009
3010   freeAllRegs ();
3011   //setToNull ((void *) &_G.regAssigned);
3012   //setToNull ((void *) &_G.totRegAssigned);
3013   fillGaps();
3014
3015   /* if stack was extended then tell the user */
3016   if (_G.stackExtend)
3017     {
3018 /*      werror(W_TOOMANY_SPILS,"stack", */
3019 /*             _G.stackExtend,currFunc->name,""); */
3020       _G.stackExtend = 0;
3021     }
3022
3023   if (_G.dataExtend)
3024     {
3025 /*      werror(W_TOOMANY_SPILS,"data space", */
3026 /*             _G.dataExtend,currFunc->name,""); */
3027       _G.dataExtend = 0;
3028     }
3029
3030   /* after that create the register mask
3031      for each of the instruction */
3032   createRegMask (ebbs, count);
3033
3034   /* redo that offsets for stacked automatic variables */
3035   if (currFunc) {
3036     redoStackOffsets ();
3037   }
3038
3039   if (options.dump_rassgn)
3040     {
3041       dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3042       dumpLiveRanges (DUMP_LRANGE, liveRanges);
3043     }
3044
3045   /* do the overlaysegment stuff SDCCmem.c */
3046   doOverlays (ebbs, count);
3047
3048   /* now get back the chain */
3049   ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3050
3051   genhc08Code (ic);
3052
3053   /* free up any _G.stackSpil locations allocated */
3054   applyToSet (_G.stackSpil, deallocStackSpil);
3055   _G.slocNum = 0;
3056   setToNull ((void **) &_G.stackSpil);
3057   setToNull ((void **) &_G.spiltSet);
3058   /* mark all registers as free */
3059   freeAllRegs ();
3060
3061   return;
3062 }