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