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