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