* src/avr/ralloc.c (serialRegAssign),
[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->regType == sym->regType &&        /* same register types */
1036               result->nRegs &&  /* which needs registers */
1037               !result->isspilt &&       /* and does not already have them */
1038               !result->remat &&
1039               !bitVectBitValue (_G.regAssigned, result->key) &&
1040           /* the number of free regs + number of regs in this LR
1041              can accomodate the what result Needs */
1042               ((nfreeRegsType (result->regType) +
1043                 sym->nRegs) >= result->nRegs)
1044             )
1045             {
1046
1047               for (i = 0; i < result->nRegs; i++)
1048                 if (i < sym->nRegs)
1049                   result->regs[i] = sym->regs[i];
1050                 else
1051                   result->regs[i] = getRegGpr (ic, ebp, result);
1052
1053               _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1054               _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, result->key);
1055
1056             }
1057
1058           /* free the remaining */
1059           for (; i < sym->nRegs; i++)
1060             {
1061               if (psym)
1062                 {
1063                   if (!symHasReg (psym, sym->regs[i]))
1064                     hc08_freeReg (sym->regs[i]);
1065                 }
1066               else
1067                 hc08_freeReg (sym->regs[i]);
1068             }
1069         }
1070     }
1071 }
1072
1073
1074 /*-----------------------------------------------------------------*/
1075 /* reassignLR - reassign this to registers                         */
1076 /*-----------------------------------------------------------------*/
1077 static void
1078 reassignLR (operand * op)
1079 {
1080   symbol *sym = OP_SYMBOL (op);
1081   int i;
1082
1083   /* not spilt any more */
1084   sym->isspilt = sym->spillA = sym->blockSpil = sym->remainSpil = 0;
1085   bitVectUnSetBit (_G.spiltSet, sym->key);
1086
1087   _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1088   _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key);
1089
1090   _G.blockSpil--;
1091
1092   for (i = 0; i < sym->nRegs; i++)
1093     sym->regs[i]->isFree = 0;
1094 }
1095
1096 /*-----------------------------------------------------------------*/
1097 /* willCauseSpill - determines if allocating will cause a spill    */
1098 /*-----------------------------------------------------------------*/
1099 static int
1100 willCauseSpill (int nr, int rt)
1101 {
1102   /* first check if there are any avlb registers
1103      of te type required */
1104   if (rt == REG_PTR)
1105     {
1106       /* special case for pointer type 
1107          if pointer type not avlb then 
1108          check for type gpr */
1109       if (nFreeRegs (rt) >= nr)
1110         return 0;
1111       if (nFreeRegs (REG_GPR) >= nr)
1112         return 0;
1113     }
1114   else
1115     {
1116       if (hc08_ptrRegReq)
1117         {
1118           if (nFreeRegs (rt) >= nr)
1119             return 0;
1120         }
1121       else
1122         {
1123           if (nFreeRegs (REG_PTR) +
1124               nFreeRegs (REG_GPR) >= nr)
1125             return 0;
1126         }
1127     }
1128
1129   /* it will cause a spil */
1130   return 1;
1131 }
1132
1133 /*-----------------------------------------------------------------*/
1134 /* positionRegs - the allocator can allocate same registers to res- */
1135 /* ult and operand, if this happens make sure they are in the same */
1136 /* position as the operand otherwise chaos results                 */
1137 /*-----------------------------------------------------------------*/
1138 static int
1139 positionRegs (symbol * result, symbol * opsym)
1140 {
1141   int count = min (result->nRegs, opsym->nRegs);
1142   int i, j = 0, shared = 0;
1143   int change = 0;
1144
1145   /* if the result has been spilt then cannot share */
1146   if (opsym->isspilt)
1147     return 0;
1148 again:
1149   shared = 0;
1150   /* first make sure that they actually share */
1151   for (i = 0; i < count; i++)
1152     {
1153       for (j = 0; j < count; j++)
1154         {
1155           if (result->regs[i] == opsym->regs[j] && i != j)
1156             {
1157               shared = 1;
1158               goto xchgPositions;
1159             }
1160         }
1161     }
1162 xchgPositions:
1163   if (shared)
1164     {
1165       regs *tmp = result->regs[i];
1166       result->regs[i] = result->regs[j];
1167       result->regs[j] = tmp;
1168       change ++;
1169       goto again;
1170     }
1171   return change;
1172 }
1173
1174 /*------------------------------------------------------------------*/
1175 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
1176 /* it should either have registers or have beed spilled. Otherwise, */
1177 /* there was an uninitialized variable, so just spill this to get   */
1178 /* the operand in a valid state.                                    */
1179 /*------------------------------------------------------------------*/
1180 static void
1181 verifyRegsAssigned (operand *op, iCode * ic)
1182 {
1183   symbol * sym;
1184   
1185   if (!op) return;
1186   if (!IS_ITEMP (op)) return;
1187   
1188   sym = OP_SYMBOL (op);
1189   if (sym->isspilt) return;
1190   if (!sym->nRegs) return;
1191   if (sym->regs[0]) return;
1192   
1193   werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT, 
1194             sym->prereqv ? sym->prereqv->name : sym->name);
1195   spillThis (sym);
1196 }
1197
1198
1199
1200 /*-----------------------------------------------------------------*/
1201 /* serialRegAssign - serially allocate registers to the variables  */
1202 /*-----------------------------------------------------------------*/
1203 static void
1204 serialRegAssign (eBBlock ** ebbs, int count)
1205 {
1206     int i;
1207
1208     /* for all blocks */
1209     for (i = 0; i < count; i++) {
1210
1211         iCode *ic;
1212
1213         if (ebbs[i]->noPath &&
1214             (ebbs[i]->entryLabel != entryLabel &&
1215              ebbs[i]->entryLabel != returnLabel))
1216             continue;
1217
1218         /* of all instructions do */
1219         for (ic = ebbs[i]->sch; ic; ic = ic->next) {
1220 #if 1
1221             int reg;
1222
1223             // update the registers in use at the start of this icode
1224             for (reg=0; reg<hc08_nRegs; reg++) {
1225               if (regshc08[reg].isFree) {
1226                 ic->riu &= ~(regshc08[reg].mask);
1227               } else {
1228                 ic->riu |= (regshc08[reg].mask);
1229               }
1230             }
1231 #endif
1232
1233             /* if this is an ipop that means some live
1234                range will have to be assigned again */
1235             if (ic->op == IPOP)
1236                 reassignLR (IC_LEFT (ic));
1237
1238             /* if result is present && is a true symbol */
1239             if (IC_RESULT (ic) && ic->op != IFX &&
1240                 IS_TRUE_SYMOP (IC_RESULT (ic)))
1241                 OP_SYMBOL (IC_RESULT (ic))->allocreq++;
1242
1243             /* take away registers from live
1244                ranges that end at this instruction */
1245             deassignLRs (ic, ebbs[i]);
1246
1247             /* some don't need registers */
1248             if (SKIP_IC2 (ic) ||
1249                 ic->op == JUMPTABLE ||
1250                 ic->op == IFX ||
1251                 ic->op == IPUSH ||
1252                 ic->op == IPOP ||
1253                 (IC_RESULT (ic) && POINTER_SET (ic)))
1254                 continue;
1255
1256             /* now we need to allocate registers
1257                only for the result */
1258             if (IC_RESULT (ic)) {
1259                 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
1260                 bitVect *spillable;
1261                 int willCS;
1262                 int j;
1263                 int ptrRegSet = 0;
1264
1265                 /* if it does not need or is spilt 
1266                    or is already assigned to registers
1267                    or will not live beyond this instructions */
1268                 if (!sym->nRegs ||
1269                     sym->isspilt ||
1270                     bitVectBitValue (_G.regAssigned, sym->key) ||
1271                     sym->liveTo <= ic->seq)
1272                     continue;
1273
1274                 /* if some liverange has been spilt at the block level
1275                    and this one live beyond this block then spil this
1276                    to be safe */
1277                 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq) {
1278                     spillThis (sym);
1279                     continue;
1280                 }
1281                 /* if trying to allocate this will cause
1282                    a spill and there is nothing to spill 
1283                    or this one is rematerializable then
1284                    spill this one */
1285                 willCS = willCauseSpill (sym->nRegs, sym->regType);
1286                 spillable = computeSpillable (ic);
1287                 if (sym->remat || (willCS && bitVectIsZero (spillable))) {                    
1288                     spillThis (sym);
1289                     continue;                 
1290                 }
1291
1292                 /* If the live range preceeds the point of definition 
1293                    then ideally we must take into account registers that 
1294                    have been allocated after sym->liveFrom but freed
1295                    before ic->seq. This is complicated, so spill this
1296                    symbol instead and let fillGaps handle the allocation. */
1297                 if (sym->liveFrom < ic->seq) {
1298                     spillThis (sym);
1299                     continue;                 
1300                 }
1301
1302                 /* if it has a spillocation & is used less than
1303                    all other live ranges then spill this */
1304                 if (willCS) {
1305                     if (sym->usl.spillLoc) {
1306                         symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
1307                                                                          allLRs, ebbs[i], ic));
1308                         if (leastUsed && leastUsed->used > sym->used) {
1309                             spillThis (sym);
1310                             continue;
1311                         }
1312                     } else {
1313                         /* if none of the liveRanges have a spillLocation then better
1314                            to spill this one than anything else already assigned to registers */
1315                         if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
1316                             /* if this is local to this block then we might find a block spil */
1317                             if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
1318                                 spillThis (sym);
1319                                 continue;
1320                             }
1321                         }
1322                     }
1323                 }
1324                 /* if we need ptr regs for the right side
1325                    then mark it */
1326                 if (POINTER_GET (ic) && IS_SYMOP (IC_LEFT (ic))
1327                     && getSize (OP_SYMBOL (IC_LEFT (ic))->type) <= (unsigned int) PTRSIZE) {
1328                     hc08_ptrRegReq++;
1329                     ptrRegSet = 1;
1330                 }
1331                 /* else we assign registers to it */
1332                 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1333                 _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key);
1334
1335                 for (j = 0; j < sym->nRegs; j++) {
1336                     if (sym->regType == REG_PTR)
1337                         sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
1338                     else
1339                         sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
1340
1341                     /* if the allocation failed which means
1342                        this was spilt then break */
1343                     if (!sym->regs[j]) {
1344                       break;
1345                     }
1346                 }
1347
1348                 /* if it shares registers with operands make sure
1349                    that they are in the same position */
1350                 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
1351                     OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=') {
1352                     positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1353                                   OP_SYMBOL (IC_LEFT (ic)));
1354                 }
1355                 /* do the same for the right operand */
1356                 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
1357                     OP_SYMBOL (IC_RIGHT (ic))->nRegs) {
1358                     positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1359                                   OP_SYMBOL (IC_RIGHT (ic)));
1360                 }
1361
1362                 if (ptrRegSet) {
1363                     hc08_ptrRegReq--;
1364                     ptrRegSet = 0;
1365                 }
1366
1367             }
1368         }
1369     }
1370
1371     /* Check for and fix any problems with uninitialized operands */
1372     for (i = 0; i < count; i++)
1373       {
1374         iCode *ic;
1375
1376         if (ebbs[i]->noPath &&
1377             (ebbs[i]->entryLabel != entryLabel &&
1378              ebbs[i]->entryLabel != returnLabel))
1379             continue;
1380
1381         for (ic = ebbs[i]->sch; ic; ic = ic->next)
1382           {
1383             if (SKIP_IC2 (ic))
1384               continue;
1385
1386             if (ic->op == IFX)
1387               {
1388                 verifyRegsAssigned (IC_COND (ic), ic);
1389                 continue;
1390               }
1391
1392             if (ic->op == JUMPTABLE)
1393               {
1394                 verifyRegsAssigned (IC_JTCOND (ic), ic);
1395                 continue;
1396               }
1397
1398             verifyRegsAssigned (IC_RESULT (ic), ic);
1399             verifyRegsAssigned (IC_LEFT (ic), ic);
1400             verifyRegsAssigned (IC_RIGHT (ic), ic);
1401           }
1402       }    
1403
1404 }
1405
1406 /*-----------------------------------------------------------------*/
1407 /* fillGaps - Try to fill in the Gaps left by Pass1                */
1408 /*-----------------------------------------------------------------*/
1409 static void fillGaps()
1410 {
1411     symbol *sym =NULL;
1412     int key =0;    
1413     
1414     if (getenv("DISABLE_FILL_GAPS")) return;
1415     
1416     /* look for livernages that was spilt by the allocator */
1417     for (sym = hTabFirstItem(liveRanges,&key) ; sym ; 
1418          sym = hTabNextItem(liveRanges,&key)) {
1419
1420         int i;
1421         int pdone = 0;
1422
1423         if (!sym->spillA || !sym->clashes || sym->remat) continue ;
1424
1425         /* find the liveRanges this one clashes with, that are
1426            still assigned to registers & mark the registers as used*/
1427         for ( i = 0 ; i < sym->clashes->size ; i ++) {
1428             int k;
1429             symbol *clr;
1430
1431             if (bitVectBitValue(sym->clashes,i) == 0 ||    /* those that clash with this */
1432                 bitVectBitValue(_G.totRegAssigned,i) == 0) /* and are still assigned to registers */
1433                 continue ;
1434
1435                 clr = hTabItemWithKey(liveRanges,i);
1436             assert(clr);
1437          
1438             /* mark these registers as used */
1439             for (k = 0 ; k < clr->nRegs ; k++ ) 
1440                 hc08_useReg(clr->regs[k]);
1441         }
1442
1443         if (willCauseSpill(sym->nRegs,sym->regType)) {
1444             /* NOPE :( clear all registers & and continue */
1445             freeAllRegs();
1446             continue ;
1447         }
1448
1449         /* THERE IS HOPE !!!! */
1450         for (i=0; i < sym->nRegs ; i++ ) {
1451             if (sym->regType == REG_PTR)
1452                 sym->regs[i] = getRegPtrNoSpil ();
1453             else
1454                 sym->regs[i] = getRegGprNoSpil ();                
1455         }
1456
1457         /* for all its definitions check if the registers
1458            allocated needs positioning NOTE: we can position
1459            only ONCE if more than One positioning required 
1460            then give up */
1461         sym->isspilt = 0;
1462         for (i = 0 ; i < sym->defs->size ; i++ ) {
1463             if (bitVectBitValue(sym->defs,i)) {
1464                 iCode *ic;
1465                 if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
1466                 if (SKIP_IC(ic)) continue;
1467                 assert(isSymbolEqual(sym,OP_SYMBOL(IC_RESULT(ic)))); /* just making sure */
1468                 /* if left is assigned to registers */
1469                 if (IS_SYMOP(IC_LEFT(ic)) && 
1470                     bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_LEFT(ic))->key)) {
1471                     pdone += positionRegs(sym,OP_SYMBOL(IC_LEFT(ic)));
1472                 }
1473                 if (IS_SYMOP(IC_RIGHT(ic)) && 
1474                     bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RIGHT(ic))->key)) {
1475                     pdone += positionRegs(sym,OP_SYMBOL(IC_RIGHT(ic)));
1476                 }
1477                 if (pdone > 1) break;
1478             }
1479         }
1480         for (i = 0 ; i < sym->uses->size ; i++ ) {
1481             if (bitVectBitValue(sym->uses,i)) {
1482                 iCode *ic;
1483                 if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
1484                 if (SKIP_IC(ic)) continue;
1485                 if (!IS_ASSIGN_ICODE(ic)) continue ;
1486
1487                 /* if result is assigned to registers */
1488                 if (IS_SYMOP(IC_RESULT(ic)) && 
1489                     bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RESULT(ic))->key)) {
1490                     pdone += positionRegs(sym,OP_SYMBOL(IC_RESULT(ic)));
1491                 }
1492                 if (pdone > 1) break;
1493             }
1494         }
1495         /* had to position more than once GIVE UP */
1496         if (pdone > 1) {
1497             /* UNDO all the changes we made to try this */
1498             sym->isspilt = 1;
1499             for (i=0; i < sym->nRegs ; i++ ) {
1500                     sym->regs[i] = NULL;
1501             }
1502             freeAllRegs();
1503             D(printf ("Fill Gap gave up due to positioning for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN"));
1504             continue ;      
1505         }
1506         D(printf ("FILLED GAP for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN"));
1507         _G.totRegAssigned = bitVectSetBit(_G.totRegAssigned,sym->key);
1508         sym->isspilt = sym->spillA = 0 ;
1509         sym->usl.spillLoc->allocreq--;
1510         freeAllRegs();
1511     }
1512 }
1513
1514 /*-----------------------------------------------------------------*/
1515 /* rUmaskForOp :- returns register mask for an operand             */
1516 /*-----------------------------------------------------------------*/
1517 bitVect *
1518 hc08_rUmaskForOp (operand * op)
1519 {
1520   bitVect *rumask;
1521   symbol *sym;
1522   int j;
1523
1524   /* only temporaries are assigned registers */
1525   if (!IS_ITEMP (op))
1526     return NULL;
1527
1528   sym = OP_SYMBOL (op);
1529
1530   /* if spilt or no registers assigned to it
1531      then nothing */
1532   if (sym->isspilt || !sym->nRegs)
1533     return NULL;
1534
1535   rumask = newBitVect (hc08_nRegs);
1536
1537   for (j = 0; j < sym->nRegs; j++)
1538     {
1539       rumask = bitVectSetBit (rumask,
1540                               sym->regs[j]->rIdx);
1541     }
1542
1543   return rumask;
1544 }
1545
1546 /*-----------------------------------------------------------------*/
1547 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
1548 /*-----------------------------------------------------------------*/
1549 static bitVect *
1550 regsUsedIniCode (iCode * ic)
1551 {
1552   bitVect *rmask = newBitVect (hc08_nRegs);
1553
1554   /* do the special cases first */
1555   if (ic->op == IFX)
1556     {
1557       rmask = bitVectUnion (rmask,
1558                             hc08_rUmaskForOp (IC_COND (ic)));
1559       goto ret;
1560     }
1561
1562   /* for the jumptable */
1563   if (ic->op == JUMPTABLE)
1564     {
1565       rmask = bitVectUnion (rmask,
1566                             hc08_rUmaskForOp (IC_JTCOND (ic)));
1567
1568       goto ret;
1569     }
1570
1571   /* of all other cases */
1572   if (IC_LEFT (ic))
1573     rmask = bitVectUnion (rmask,
1574                           hc08_rUmaskForOp (IC_LEFT (ic)));
1575
1576
1577   if (IC_RIGHT (ic))
1578     rmask = bitVectUnion (rmask,
1579                           hc08_rUmaskForOp (IC_RIGHT (ic)));
1580
1581   if (IC_RESULT (ic))
1582     rmask = bitVectUnion (rmask,
1583                           hc08_rUmaskForOp (IC_RESULT (ic)));
1584
1585 ret:
1586   return rmask;
1587 }
1588
1589 /*-----------------------------------------------------------------*/
1590 /* createRegMask - for each instruction will determine the regsUsed */
1591 /*-----------------------------------------------------------------*/
1592 static void
1593 createRegMask (eBBlock ** ebbs, int count)
1594 {
1595   int i;
1596
1597   /* for all blocks */
1598   for (i = 0; i < count; i++)
1599     {
1600       iCode *ic;
1601
1602       if (ebbs[i]->noPath &&
1603           (ebbs[i]->entryLabel != entryLabel &&
1604            ebbs[i]->entryLabel != returnLabel))
1605         continue;
1606
1607       /* for all instructions */
1608       for (ic = ebbs[i]->sch; ic; ic = ic->next)
1609         {
1610
1611           int j;
1612
1613           if (SKIP_IC2 (ic) || !ic->rlive)
1614             continue;
1615
1616           /* first mark the registers used in this
1617              instruction */
1618           ic->rUsed = regsUsedIniCode (ic);
1619           _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
1620
1621           /* now create the register mask for those 
1622              registers that are in use : this is a
1623              super set of ic->rUsed */
1624           ic->rMask = newBitVect (hc08_nRegs + 1);
1625
1626           /* for all live Ranges alive at this point */
1627           for (j = 1; j < ic->rlive->size; j++)
1628             {
1629               symbol *sym;
1630               int k;
1631
1632               /* if not alive then continue */
1633               if (!bitVectBitValue (ic->rlive, j))
1634                 continue;
1635
1636               /* find the live range we are interested in */
1637               if (!(sym = hTabItemWithKey (liveRanges, j)))
1638                 {
1639                   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1640                           "createRegMask cannot find live range");
1641                   fprintf(stderr, "\tmissing live range: key=%d\n", j);
1642                   exit (0);
1643                 }
1644
1645               /* if no register assigned to it */
1646               if (!sym->nRegs || sym->isspilt)
1647                 continue;
1648
1649               /* for all the registers allocated to it */
1650               for (k = 0; k < sym->nRegs; k++)
1651                 if (sym->regs[k])
1652                   ic->rMask =
1653                     bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
1654             }
1655         }
1656     }
1657 }
1658
1659 /*-----------------------------------------------------------------*/
1660 /* rematStr - returns the rematerialized string for a remat var    */
1661 /*-----------------------------------------------------------------*/
1662 static char *
1663 rematStr (symbol * sym)
1664 {
1665   char *s = buffer;
1666   iCode *ic = sym->rematiCode;
1667 //  int offset = 0;
1668   
1669   while (1)
1670     {
1671       /* if plus or minus print the right hand side */
1672       if (ic->op == '+' || ic->op == '-')
1673         {
1674           sprintf (s, "0x%04x %c ", (int) operandLitValue (IC_RIGHT (ic)),
1675                    ic->op);
1676           s += strlen (s);
1677           ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1678           continue;
1679         }
1680
1681 /*      
1682       if (ic->op == '+')
1683         {
1684           offset += operandLitValue (IC_RIGHT (ic));
1685           ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1686           continue;
1687         }
1688       if (ic->op == '-')
1689         {
1690           offset -= operandLitValue (IC_RIGHT (ic));
1691           ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1692           continue;
1693         }
1694 */
1695       /* cast then continue */
1696       if (IS_CAST_ICODE(ic)) {
1697           ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
1698           continue;
1699       }
1700       /* we reached the end */
1701       if (ic->op == ADDRESS_OF)
1702         sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
1703       else if (ic->op == '=')
1704         sprintf (s, "0x%04x", (int) operandLitValue (IC_RIGHT (ic)) );
1705       break;
1706     }
1707
1708   return buffer;
1709 }
1710
1711 /*-----------------------------------------------------------------*/
1712 /* regTypeNum - computes the type & number of registers required   */
1713 /*-----------------------------------------------------------------*/
1714 static void
1715 regTypeNum (eBBlock *ebbs)
1716 {
1717   symbol *sym;
1718   int k;
1719   iCode *ic;
1720
1721   /* for each live range do */
1722   for (sym = hTabFirstItem (liveRanges, &k); sym;
1723        sym = hTabNextItem (liveRanges, &k))
1724     {
1725
1726       /* if used zero times then no registers needed */
1727       if ((sym->liveTo - sym->liveFrom) == 0)
1728         continue;
1729
1730
1731       /* if the live range is a temporary */
1732       if (sym->isitmp)
1733         {
1734
1735           /* if the type is marked as a conditional */
1736           if (sym->regType == REG_CND)
1737             continue;
1738
1739           /* if used in return only then we don't 
1740              need registers */
1741           if (sym->ruonly || sym->accuse)
1742             {
1743               if (IS_AGGREGATE (sym->type) || sym->isptr)
1744                 sym->type = aggrToPtr (sym->type, FALSE);
1745               continue;
1746             }
1747
1748           /* if the symbol has only one definition &
1749              that definition is a get_pointer */
1750           if (bitVectnBitsOn (sym->defs) == 1 &&
1751               (ic = hTabItemWithKey (iCodehTab,
1752                                      bitVectFirstBit (sym->defs))) &&
1753               POINTER_GET (ic) &&
1754               !IS_BITVAR (sym->etype) &&
1755               (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER))
1756             {
1757
1758               if (ptrPseudoSymSafe (sym, ic))
1759                 {
1760                   ptrPseudoSymConvert (sym, ic, rematStr (OP_SYMBOL (IC_LEFT (ic))));
1761                   continue;
1762                 }
1763
1764               /* if in data space or idata space then try to
1765                  allocate pointer register */
1766
1767             }
1768
1769           /* if not then we require registers */
1770           sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
1771                         getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1772                         getSize (sym->type));
1773
1774           if (sym->nRegs > 4)
1775             {
1776               fprintf (stderr, "allocated more than 4 or 0 registers for type ");
1777               printTypeChain (sym->type, stderr);
1778               fprintf (stderr, "\n");
1779             }
1780
1781           /* determine the type of register required */
1782           if (sym->nRegs == 1 &&
1783               IS_PTR (sym->type) &&
1784               sym->uptr)
1785             sym->regType = REG_PTR;
1786           else
1787             sym->regType = REG_GPR;
1788
1789         }
1790       else
1791         /* for the first run we don't provide */
1792         /* registers for true symbols we will */
1793         /* see how things go                  */
1794         sym->nRegs = 0;
1795           }
1796
1797 }
1798
1799 /*-----------------------------------------------------------------*/
1800 /* freeAllRegs - mark all registers as free                        */
1801 /*-----------------------------------------------------------------*/
1802 static void
1803 freeAllRegs ()
1804 {
1805   int i;
1806
1807   for (i = 0; i < hc08_nRegs; i++) {
1808     regshc08[i].isFree = 1;
1809     regshc08[i].aop = NULL;
1810   }
1811 }
1812
1813 /*-----------------------------------------------------------------*/
1814 /* deallocStackSpil - this will set the stack pointer back         */
1815 /*-----------------------------------------------------------------*/
1816 static
1817 DEFSETFUNC (deallocStackSpil)
1818 {
1819   symbol *sym = item;
1820
1821   deallocLocal (sym);
1822   return 0;
1823 }
1824
1825 #if 0
1826 /*-----------------------------------------------------------------*/
1827 /* farSpacePackable - returns the packable icode for far variables */
1828 /*-----------------------------------------------------------------*/
1829 static iCode *
1830 farSpacePackable (iCode * ic)
1831 {
1832   iCode *dic;
1833
1834   /* go thru till we find a definition for the
1835      symbol on the right */
1836   for (dic = ic->prev; dic; dic = dic->prev)
1837     {
1838       /* if the definition is a call then no */
1839       if ((dic->op == CALL || dic->op == PCALL) &&
1840           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1841         {
1842           return NULL;
1843         }
1844
1845       /* if shift by unknown amount then not */
1846       if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
1847           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1848         return NULL;
1849
1850 #if 0
1851       /* if pointer get and size > 1 */
1852       if (POINTER_GET (dic) &&
1853           getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
1854         return NULL;
1855
1856       if (POINTER_SET (dic) &&
1857           getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
1858         return NULL;
1859 #endif
1860
1861       /* if any three is a true symbol in far space */
1862       if (IC_RESULT (dic) &&
1863           IS_TRUE_SYMOP (IC_RESULT (dic)) /* &&
1864           isOperandInFarSpace (IC_RESULT (dic)) */)
1865         return NULL;
1866
1867       if (IC_RIGHT (dic) &&
1868           IS_TRUE_SYMOP (IC_RIGHT (dic)) /* &&
1869           isOperandInFarSpace (IC_RIGHT (dic)) */ &&
1870           !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
1871         return NULL;
1872
1873       if (IC_LEFT (dic) &&
1874           IS_TRUE_SYMOP (IC_LEFT (dic)) /* &&
1875           isOperandInFarSpace (IC_LEFT (dic)) */ &&
1876           !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
1877         return NULL;
1878
1879       if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
1880         {
1881           if ((dic->op == LEFT_OP ||
1882                dic->op == RIGHT_OP ||
1883                dic->op == '-') &&
1884               IS_OP_LITERAL (IC_RIGHT (dic)))
1885             return NULL;
1886           else
1887             return dic;
1888         }
1889     }
1890
1891   return NULL;
1892 }
1893 #endif
1894
1895 #if 0
1896 static void
1897 packRegsForLiteral (iCode * ic)
1898 {
1899   int k;
1900   iCode *uic;
1901   
1902   if (ic->op != '=')
1903     return;
1904   if (POINTER_SET (ic))
1905     return;
1906   if (!IS_LITERAL (getSpec (operandType (IC_RIGHT (ic)))))
1907     return;
1908   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
1909     return;
1910
1911   for (k=0; k< OP_USES (IC_RESULT (ic))->size; k++)
1912     if (bitVectBitValue (OP_USES (IC_RESULT (ic)), k))
1913       {
1914         uic = hTabItemWithKey (iCodehTab, k);
1915         if (!uic) continue;
1916         
1917         if (uic->op != IFX && uic->op != JUMPTABLE)
1918           {
1919             if (IC_LEFT (uic) && IC_LEFT (uic)->key == IC_RESULT (ic)->key)
1920               ReplaceOpWithCheaperOp(&IC_LEFT(uic), IC_RIGHT(ic));
1921             if (IC_RIGHT (uic) && IC_RIGHT (uic)->key == IC_RESULT (ic)->key)
1922               ReplaceOpWithCheaperOp(&IC_RIGHT(uic), IC_RIGHT(ic));
1923             if (IC_RESULT (uic) && IC_RESULT (uic)->key == IC_RESULT (ic)->key)
1924               ReplaceOpWithCheaperOp(&IC_RESULT(uic), IC_RIGHT(ic));
1925           }
1926       }
1927
1928 }
1929 #endif
1930
1931
1932 /*-----------------------------------------------------------------*/
1933 /* packRegsForAssign - register reduction for assignment           */
1934 /*-----------------------------------------------------------------*/
1935 static int
1936 packRegsForAssign (iCode * ic, eBBlock * ebp)
1937 {
1938   iCode *dic, *sic;
1939
1940   if (!IS_ITEMP (IC_RIGHT (ic)) ||
1941       OP_SYMBOL (IC_RIGHT (ic))->isind ||
1942       OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
1943     {
1944       return 0;
1945     }
1946
1947
1948   /* if the true symbol is defined in far space or on stack
1949      then we should not since this will increase register pressure */
1950 #if 0
1951   if (isOperandInFarSpace(IC_RESULT(ic)) && !farSpacePackable(ic)) {
1952     return 0;
1953   }
1954 #endif
1955
1956   /* find the definition of iTempNN scanning backwards if we find a 
1957      a use of the true symbol in before we find the definition then 
1958      we cannot */
1959   for (dic = ic->prev; dic; dic = dic->prev)
1960     {
1961
1962 #if 0 /* jwk: This collides with 1.43 but I really see no need for
1963          this anymore. It fixes bug #716790 and substantially improves 
1964          redundant register usage around function calls.
1965       */
1966
1967       /* if there is a function call then don't pack it */
1968       if ((dic->op == CALL || dic->op == PCALL))
1969         {
1970           dic = NULL;
1971           break;
1972         }
1973 #endif
1974
1975       if (SKIP_IC2 (dic))
1976         continue;
1977
1978       if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
1979           IS_OP_VOLATILE (IC_RESULT (dic)))
1980         {
1981           dic = NULL;
1982           break;
1983         }
1984
1985       if (IS_SYMOP (IC_RESULT (dic)) &&
1986           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1987         {
1988           if (POINTER_SET (dic))
1989             dic = NULL;
1990
1991           break;
1992         }
1993
1994       if (IS_SYMOP (IC_RIGHT (dic)) &&
1995           (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
1996            IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
1997         {
1998           dic = NULL;
1999           break;
2000         }
2001
2002       if (IS_SYMOP (IC_LEFT (dic)) &&
2003           (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2004            IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2005         {
2006           dic = NULL;
2007           break;
2008         }
2009
2010       if (POINTER_SET (dic) &&
2011           IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2012         {
2013           dic = NULL;
2014           break;
2015         }
2016     }
2017
2018   if (!dic)
2019     return 0;                   /* did not find */
2020
2021   /* if assignment then check that right is not a bit */
2022   if (ASSIGNMENT (dic) && !POINTER_SET (dic))
2023     {
2024       sym_link *etype = operandType (IC_RIGHT (dic));
2025       if (IS_BITFIELD (etype))
2026         {
2027           /* if result is a bit too then it's ok */
2028           etype = operandType (IC_RESULT (dic));
2029           if (!IS_BITFIELD (etype))
2030             return 0;
2031         }
2032     }
2033   /* if the result is on stack or iaccess then it must be
2034      the same atleast one of the operands */
2035   if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2036       OP_SYMBOL (IC_RESULT (ic))->iaccess)
2037     {
2038
2039       /* the operation has only one symbol
2040          operator then we can pack */
2041       if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2042           (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2043         goto pack;
2044
2045       if (!((IC_LEFT (dic) &&
2046              IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2047             (IC_RIGHT (dic) &&
2048              IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2049         return 0;
2050     }
2051 pack:
2052   /* found the definition */
2053   /* replace the result with the result of */
2054   /* this assignment and remove this assignment */
2055   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2056   ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
2057
2058   if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2059     {
2060       OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2061     }
2062   // TODO: and the otherway around?
2063
2064   /* delete from liverange table also 
2065      delete from all the points inbetween and the new
2066      one */
2067   for (sic = dic; sic != ic; sic = sic->next)
2068     {
2069       bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2070       if (IS_ITEMP (IC_RESULT (dic)))
2071         bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2072     }
2073
2074   remiCodeFromeBBlock (ebp, ic);
2075   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2076   hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2077   OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2078   return 1;
2079 }
2080
2081
2082 /*------------------------------------------------------------------*/
2083 /* findAssignToSym : scanning backwards looks for first assig found */
2084 /*------------------------------------------------------------------*/
2085 static iCode *
2086 findAssignToSym (operand * op, iCode * ic)
2087 {
2088   iCode *dic;
2089
2090   /* This routine is used to find sequences like
2091      iTempAA = FOO;
2092      ...;  (intervening ops don't use iTempAA or modify FOO)
2093      blah = blah + iTempAA;
2094
2095      and eliminate the use of iTempAA, freeing up its register for
2096      other uses.
2097   */
2098      
2099
2100   for (dic = ic->prev; dic; dic = dic->prev)
2101     {
2102
2103       /* if definition by assignment */
2104       if (dic->op == '=' &&
2105           !POINTER_SET (dic) &&
2106           IC_RESULT (dic)->key == op->key
2107           &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) 
2108         )
2109         break;  /* found where this temp was defined */
2110
2111       /* if we find an usage then we cannot delete it */
2112       if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2113         return NULL;
2114
2115       if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2116         return NULL;
2117
2118       if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2119         return NULL;
2120     }
2121
2122   if (!dic)
2123     return NULL;   /* didn't find any assignment to op */
2124
2125   /* we are interested only if defined in far space */
2126   /* or in stack space in case of + & - */
2127   
2128   /* if assigned to a non-symbol then don't repack regs */
2129   if (!IS_SYMOP (IC_RIGHT (dic)))
2130     return NULL;
2131   
2132   /* if the symbol is volatile then we should not */
2133   if (isOperandVolatile (IC_RIGHT (dic), TRUE))
2134     return NULL;
2135   /* XXX TODO --- should we be passing FALSE to isOperandVolatile()?
2136      What does it mean for an iTemp to be volatile, anyway? Passing
2137      TRUE is more cautious but may prevent possible optimizations */
2138
2139   /* if the symbol is in far space then we should not */
2140   /* if (isOperandInFarSpace (IC_RIGHT (dic)))
2141     return NULL; */
2142   
2143   /* for + & - operations make sure that
2144      if it is on the stack it is the same
2145      as one of the three operands */
2146 #if 0
2147   if ((ic->op == '+' || ic->op == '-') &&
2148       OP_SYMBOL (IC_RIGHT (dic))->onStack)
2149     {
2150       
2151       if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2152           IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2153           IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2154         return NULL;
2155     }
2156 #endif
2157   
2158   /* now make sure that the right side of dic
2159      is not defined between ic & dic */
2160   if (dic)
2161     {
2162       iCode *sic = dic->next;
2163
2164       for (; sic != ic; sic = sic->next)
2165         if (IC_RESULT (sic) &&
2166             IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2167           return NULL;
2168     }
2169
2170   return dic;
2171 }
2172
2173 /*-----------------------------------------------------------------*/
2174 /* reassignAliasedSym - used by packRegsForSupport to replace      */
2175 /*                      redundant iTemp with equivalent symbol     */
2176 /*-----------------------------------------------------------------*/
2177 static void
2178 reassignAliasedSym (eBBlock *ebp, iCode *assignment, iCode *use, operand *op)
2179 {
2180   iCode *ic;
2181   unsigned oldSymKey, newSymKey;
2182
2183   oldSymKey = op->key;
2184   newSymKey = IC_RIGHT(assignment)->key;
2185
2186   /* only track live ranges of compiler-generated temporaries */
2187   if (!IS_ITEMP(IC_RIGHT(assignment)))
2188     newSymKey = 0;
2189
2190   /* update the live-value bitmaps */
2191   for (ic = assignment; ic != use; ic = ic->next) {
2192     bitVectUnSetBit (ic->rlive, oldSymKey);
2193     if (newSymKey != 0)
2194       ic->rlive = bitVectSetBit (ic->rlive, newSymKey);
2195   }
2196
2197   /* update the sym of the used operand */
2198   OP_SYMBOL(op) = OP_SYMBOL(IC_RIGHT(assignment));
2199   op->key = OP_SYMBOL(op)->key;
2200
2201   /* update the sym's liverange */
2202   if ( OP_LIVETO(op) < ic->seq )
2203     setToRange(op, ic->seq, FALSE);
2204
2205   /* remove the assignment iCode now that its result is unused */
2206   remiCodeFromeBBlock (ebp, assignment);
2207   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(assignment))->defs, assignment->key);
2208   hTabDeleteItem (&iCodehTab, assignment->key, assignment, DELETE_ITEM, NULL);
2209 }
2210   
2211
2212 /*-----------------------------------------------------------------*/
2213 /* packRegsForSupport :- reduce some registers for support calls   */
2214 /*-----------------------------------------------------------------*/
2215 static int
2216 packRegsForSupport (iCode * ic, eBBlock * ebp)
2217 {
2218   iCode *dic;
2219   int changes = 0;
2220   
2221   /* for the left & right operand :- look to see if the
2222      left was assigned a true symbol in far space in that
2223      case replace them */
2224
2225   if (IS_ITEMP (IC_LEFT (ic)) &&
2226       OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2227     {
2228       dic = findAssignToSym (IC_LEFT (ic), ic);
2229
2230       if (dic)
2231         {
2232           /* found it we need to remove it from the block */
2233           reassignAliasedSym (ebp, dic, ic, IC_LEFT(ic));
2234           changes++;
2235         }
2236     }
2237
2238   /* do the same for the right operand */
2239   if (IS_ITEMP (IC_RIGHT (ic)) &&
2240       OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2241     {
2242       iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2243
2244       if (dic)
2245         {
2246           /* found it we need to remove it from the block */
2247           reassignAliasedSym (ebp, dic, ic, IC_RIGHT(ic));
2248           changes++;
2249         }
2250     }
2251
2252   return changes;
2253 }
2254
2255 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
2256
2257
2258 #if 0
2259 /*-----------------------------------------------------------------*/
2260 /* packRegsForOneuse : - will reduce some registers for single Use */
2261 /*-----------------------------------------------------------------*/
2262 static iCode *
2263 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
2264 {
2265   bitVect *uses;
2266   iCode *dic, *sic;
2267
2268   /* if returning a literal then do nothing */
2269   if (!IS_SYMOP (op))
2270     return NULL;
2271
2272   /* only up to 2 bytes */
2273   if (getSize (operandType (op)) > (fReturnSizeHC08 - 2))
2274     return NULL;
2275
2276   return NULL;
2277   
2278   if (ic->op != SEND //RETURN
2279       && ic->op != SEND
2280       && !POINTER_SET (ic)
2281       && !POINTER_GET (ic) )
2282     return NULL;
2283   
2284   if (ic->op == SEND && ic->argreg != 1) return NULL;
2285
2286   /* this routine will mark the a symbol as used in one 
2287      instruction use only && if the defintion is local 
2288      (ie. within the basic block) && has only one definition &&
2289      that definiion is either a return value from a 
2290      function or does not contain any variables in
2291      far space */
2292   uses = bitVectCopy (OP_USES (op));
2293   bitVectUnSetBit (uses, ic->key);      /* take away this iCode */
2294   if (!bitVectIsZero (uses))    /* has other uses */
2295     return NULL;
2296
2297   /* if it has only one defintion */
2298   if (bitVectnBitsOn (OP_DEFS (op)) > 1)
2299     return NULL;                /* has more than one definition */
2300
2301   /* get that definition */
2302   if (!(dic =
2303         hTabItemWithKey (iCodehTab,
2304                          bitVectFirstBit (OP_DEFS (op)))))
2305     return NULL;
2306
2307   /* if that only usage is a cast */
2308   if (dic->op == CAST) {
2309     /* to a bigger type */
2310     if (getSize(OP_SYM_TYPE(IC_RESULT(dic))) > 
2311         getSize(OP_SYM_TYPE(IC_RIGHT(dic)))) {
2312       /* than we can not, since we cannot predict the usage of b & acc */
2313       return NULL;
2314     }
2315   }
2316
2317   /* found the definition now check if it is local */
2318   if (dic->seq < ebp->fSeq ||
2319       dic->seq > ebp->lSeq)
2320     return NULL;                /* non-local */
2321
2322   /* now check if it is the return from
2323      a function call */
2324   if (dic->op == CALL || dic->op == PCALL)
2325     {
2326       if (ic->op != SEND && ic->op != RETURN &&
2327           !POINTER_SET(ic) && !POINTER_GET(ic))
2328         {
2329           OP_SYMBOL (op)->ruonly = 1;
2330           return dic;
2331         }
2332       dic = dic->next;
2333     }
2334
2335
2336   /* otherwise check that the definition does
2337      not contain any symbols in far space */
2338 //  if (isOperandInFarSpace (IC_LEFT (dic)) ||
2339 //      isOperandInFarSpace (IC_RIGHT (dic)) ||
2340 //      IS_OP_RUONLY (IC_LEFT (ic)) ||
2341 //      IS_OP_RUONLY (IC_RIGHT (ic)))
2342 //    {
2343 //      return NULL;
2344 //    }
2345
2346   /* if pointer set then make sure the pointer
2347      is one byte */
2348 #if 0
2349   if (POINTER_SET (dic) &&
2350       !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2351     return NULL;
2352
2353   if (POINTER_GET (dic) &&
2354       !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2355     return NULL;
2356 #endif 
2357
2358   sic = dic;
2359
2360   /* also make sure the intervenening instructions
2361      don't have any thing in far space */
2362   for (dic = dic->next; dic && dic != ic && sic != ic; dic = dic->next)
2363     {
2364
2365       /* if there is an intervening function call then no */
2366       if (dic->op == CALL || dic->op == PCALL)
2367         return NULL;
2368       /* if pointer set then make sure the pointer
2369          is one byte */
2370 #if 0
2371       if (POINTER_SET (dic) &&
2372           !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2373         return NULL;
2374
2375       if (POINTER_GET (dic) &&
2376           !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2377         return NULL;
2378 #endif
2379       /* if address of & the result is remat the okay */
2380       if (dic->op == ADDRESS_OF &&
2381           OP_SYMBOL (IC_RESULT (dic))->remat)
2382         continue;
2383
2384       /* if operand has size of three or more & this
2385          operation is a '*','/' or '%' then 'b' may
2386          cause a problem */
2387 #if 0
2388       if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
2389           getSize (operandType (op)) >= 3)
2390         return NULL;
2391 #endif
2392
2393       /* if left or right or result is in far space */
2394 //      if (isOperandInFarSpace (IC_LEFT (dic)) ||
2395 //        isOperandInFarSpace (IC_RIGHT (dic)) ||
2396 //        isOperandInFarSpace (IC_RESULT (dic)) ||
2397 //        IS_OP_RUONLY (IC_LEFT (dic)) ||
2398 //        IS_OP_RUONLY (IC_RIGHT (dic)) ||
2399 //        IS_OP_RUONLY (IC_RESULT (dic)))
2400 //      {
2401 //        return NULL;
2402 //      }
2403 //      /* if left or right or result is on stack */
2404 //     if (isOperandOnStack(IC_LEFT(dic)) ||
2405 //        isOperandOnStack(IC_RIGHT(dic)) ||
2406 //        isOperandOnStack(IC_RESULT(dic))) {
2407 //      return NULL;
2408 //     }
2409     }
2410
2411   OP_SYMBOL (op)->ruonly = 1;
2412   return sic;
2413 }
2414 #endif
2415
2416 /*-----------------------------------------------------------------*/
2417 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
2418 /*-----------------------------------------------------------------*/
2419 static bool
2420 isBitwiseOptimizable (iCode * ic)
2421 {
2422   sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
2423   sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
2424
2425   /* bitwise operations are considered optimizable
2426      under the following conditions (Jean-Louis VERN) 
2427
2428      x & lit
2429      bit & bit
2430      bit & x
2431      bit ^ bit
2432      bit ^ x
2433      x   ^ lit
2434      x   | lit
2435      bit | bit
2436      bit | x
2437   */
2438   if (IS_LITERAL(rtype) ||
2439       (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
2440     return TRUE;
2441   else
2442     return FALSE;
2443 }
2444
2445 /*-----------------------------------------------------------------*/
2446 /* isCommutativeOp - tests whether this op cares what order its    */
2447 /*                   operands are in                               */
2448 /*-----------------------------------------------------------------*/
2449 bool isCommutativeOp2(unsigned int op)
2450 {
2451   if (op == '+' || op == '*' || op == EQ_OP ||
2452       op == '^' || op == '|' || op == BITWISEAND)
2453     return TRUE;
2454   else
2455     return FALSE;
2456 }
2457
2458 /*-----------------------------------------------------------------*/
2459 /* operandUsesAcc2 - determines whether the code generated for this */
2460 /*                  operand will have to use the accumulator       */
2461 /*-----------------------------------------------------------------*/
2462 bool operandUsesAcc2(operand *op)
2463 {
2464   if (!op)
2465     return FALSE;
2466
2467   if (IS_SYMOP(op)) {
2468     symbol *sym = OP_SYMBOL(op);
2469     memmap *symspace;
2470
2471     if (sym->accuse)
2472       return TRUE;  /* duh! */
2473
2474 //    if (IN_STACK(sym->etype) || sym->onStack ||
2475 //      (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
2476 //      return TRUE;  /* acc is used to calc stack offset */
2477
2478     if (IS_ITEMP(op))
2479       {
2480         if (SPIL_LOC(op)) {
2481           sym = SPIL_LOC(op);  /* if spilled, look at spill location */
2482         } else {
2483           return FALSE;  /* more checks? */
2484         }
2485       }
2486
2487     symspace = SPEC_OCLS(sym->etype);
2488
2489 //    if (sym->iaccess && symspace->paged)
2490 //      return TRUE;  /* must fetch paged indirect sym via accumulator */
2491     
2492     if (IN_BITSPACE(symspace))
2493       return TRUE;  /* fetching bit vars uses the accumulator */
2494     
2495     if (IN_FARSPACE(symspace) || IN_CODESPACE(symspace)) 
2496       return TRUE;  /* fetched via accumulator and dptr */
2497   }
2498
2499   return FALSE;
2500 }
2501
2502 /*-----------------------------------------------------------------*/
2503 /* packRegsForAccUse - pack registers for acc use                  */
2504 /*-----------------------------------------------------------------*/
2505 static void
2506 packRegsForAccUse (iCode * ic)
2507 {
2508   iCode *uic;
2509
2510   /* if this is an aggregate, e.g. a one byte char array */
2511   if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
2512     return;
2513   }
2514
2515   /* if we are calling a reentrant function that has stack parameters */
2516   #if 0
2517   if (ic->op == CALL &&
2518        IFFUNC_ISREENT(operandType(IC_LEFT(ic))) &&
2519        FUNC_HASSTACKPARM(operandType(IC_LEFT(ic))))
2520       return;
2521
2522   if (ic->op == PCALL &&
2523        IFFUNC_ISREENT(operandType(IC_LEFT(ic))->next) &&
2524        FUNC_HASSTACKPARM(operandType(IC_LEFT(ic))->next))
2525       return;
2526   #endif
2527
2528   /* if + or - then it has to be one byte result */
2529   if ((ic->op == '+' || ic->op == '-')
2530       && getSize (operandType (IC_RESULT (ic))) > 1)
2531     return;
2532
2533
2534   /* if shift operation make sure right side is a literal */
2535   if (ic->op == RIGHT_OP &&
2536       (!isOperandLiteral (IC_RIGHT (ic)) ||
2537        (getSize (operandType (IC_RESULT (ic) )) > 1)))
2538     return;
2539
2540   if (ic->op == LEFT_OP &&
2541       (!isOperandLiteral (IC_RIGHT (ic)) ||
2542        (getSize (operandType (IC_RESULT (ic) )) > 1)))
2543     return;
2544
2545   if (IS_BITWISE_OP (ic) &&
2546       getSize (operandType (IC_RESULT (ic))) > 1)
2547     return;
2548
2549
2550   /* has only one definition */
2551   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
2552     return;
2553
2554   /* has only one use */
2555   if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
2556     return;
2557
2558   /* and the usage immediately follows this iCode */
2559   if (!(uic = hTabItemWithKey (iCodehTab,
2560                                bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
2561     return;
2562
2563   if (ic->next != uic)
2564     return;
2565
2566   /* if it is a conditional branch then we definitely can */
2567   if (uic->op == IFX)
2568     goto accuse;
2569
2570   if (uic->op == JUMPTABLE)
2571     return;
2572
2573 #if 0
2574   if (POINTER_SET (uic) &&
2575       getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
2576     return;
2577 #endif
2578
2579   /* if the usage is not is an assignment
2580      or an arithmetic / bitwise / shift operation then not */
2581   if (uic->op != '=' &&
2582       !IS_ARITHMETIC_OP (uic) &&
2583       !IS_BITWISE_OP (uic) &&
2584       (uic->op != LEFT_OP) &&
2585       (uic->op != RIGHT_OP) &&
2586       (uic->op != GETHBIT) &&
2587       (uic->op != RETURN) &&
2588       (uic->op != '~') &&
2589       (uic->op != '!'))
2590     return;
2591
2592 #if 0
2593   /* if used in ^ operation then make sure right is not a 
2594      literal (WIML: Why is this?) */
2595   if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
2596     return;
2597
2598   /* if shift operation make sure right side is not a literal */
2599   /* WIML: Why is this? */
2600   if (uic->op == RIGHT_OP &&
2601       (isOperandLiteral (IC_RIGHT (uic)) ||
2602        getSize (operandType (IC_RESULT (uic))) > 1))
2603     return;
2604   if (uic->op == LEFT_OP &&
2605       (isOperandLiteral (IC_RIGHT (uic)) ||
2606        getSize (operandType (IC_RESULT (uic))) > 1))
2607     return;
2608 #endif
2609
2610   /* make sure that the result of this icode is not on the
2611      stack, since acc is used to compute stack offset */
2612 #if 0
2613   if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
2614       OP_SYMBOL (IC_RESULT (uic))->onStack)
2615     return;
2616 #else
2617 //  if (isOperandOnStack(IC_RESULT(uic)))
2618 //    return;
2619 #endif
2620
2621   /* if the usage has only one operand then we can */
2622   if (IC_LEFT (uic) == NULL ||
2623       IC_RIGHT (uic) == NULL)
2624     goto accuse;
2625
2626 #if 0
2627   /* if the other operand uses the accumulator then we cannot */
2628   if ( (IC_LEFT(uic)->key == IC_RESULT(ic)->key &&
2629         operandUsesAcc2(IC_RIGHT(uic))) ||
2630        (IC_RIGHT(uic)->key == IC_RESULT(ic)->key &&
2631         operandUsesAcc2(IC_LEFT(uic))) ) 
2632     return;
2633
2634   /* make sure this is on the left side if not commutative */
2635   /* except for '-', which has been written to be able to
2636      handle reversed operands */
2637   if (!(isCommutativeOp2(ic->op) || ic->op == '-') &&
2638        IC_LEFT (uic)->key != IC_RESULT (ic)->key)
2639     return;
2640 #endif
2641
2642 #if 0
2643   // this is too dangerous and need further restrictions
2644   // see bug #447547
2645
2646   /* if one of them is a literal then we can */
2647   if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
2648       (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
2649     {
2650       OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2651       return;
2652     }
2653 #endif
2654
2655 accuse:
2656
2657   if ((POINTER_GET(uic))
2658       || (ic->op == ADDRESS_OF && uic->op == '+' && IS_OP_LITERAL (IC_RIGHT (uic))))
2659     {
2660       OP_SYMBOL (IC_RESULT (ic))->accuse = ACCUSE_HX;
2661       return;
2662     }
2663   
2664   OP_SYMBOL (IC_RESULT (ic))->accuse = ACCUSE_XA;
2665 }
2666
2667 /*-----------------------------------------------------------------*/
2668 /* packForPush - hueristics to reduce iCode for pushing            */
2669 /*-----------------------------------------------------------------*/
2670 static void
2671 packForPush (iCode * ic, eBBlock ** ebpp, int blockno)
2672 {
2673   iCode *dic, *lic;
2674   bitVect *dbv;
2675   struct eBBlock * ebp=ebpp[blockno];
2676
2677   if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
2678     return;
2679
2680   /* must have only definition & one usage */
2681   if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
2682       bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
2683     return;
2684
2685   /* find the definition */
2686   if (!(dic = hTabItemWithKey (iCodehTab,
2687                                bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
2688     return;
2689
2690   if (dic->op != '=' || POINTER_SET (dic))
2691     return;
2692
2693   if (dic->seq < ebp->fSeq) { // Evelyn did this
2694     int i;
2695     for (i=0; i<blockno; i++) {
2696       if (dic->seq >= ebpp[i]->fSeq && dic->seq <= ebpp[i]->lSeq) {
2697         ebp=ebpp[i];
2698         break;
2699       }
2700     }
2701     wassert (i!=blockno); // no way to recover from here
2702   }
2703
2704   if (IS_SYMOP(IC_RIGHT(dic))) {
2705     /* make sure the right side does not have any definitions
2706        inbetween */
2707     dbv = OP_DEFS(IC_RIGHT(dic));
2708     for (lic = ic; lic && lic != dic ; lic = lic->prev) {
2709       if (bitVectBitValue(dbv,lic->key)) 
2710         return ;
2711     }
2712     /* make sure they have the same type */
2713     if (IS_SPEC(operandType(IC_LEFT(ic))))
2714     {
2715       sym_link *itype=operandType(IC_LEFT(ic));
2716       sym_link *ditype=operandType(IC_RIGHT(dic));
2717       
2718       if (SPEC_USIGN(itype)!=SPEC_USIGN(ditype) ||
2719           SPEC_LONG(itype)!=SPEC_LONG(ditype))
2720         return;
2721     }
2722     /* extend the live range of replaced operand if needed */
2723     if (OP_SYMBOL(IC_RIGHT(dic))->liveTo < ic->seq) {
2724       OP_SYMBOL(IC_RIGHT(dic))->liveTo = ic->seq;
2725     }
2726     bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2727   } 
2728
2729   /* we now we know that it has one & only one def & use
2730      and the that the definition is an assignment */
2731   ReplaceOpWithCheaperOp(&IC_LEFT (ic), IC_RIGHT (dic));
2732   remiCodeFromeBBlock (ebp, dic);
2733   hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2734 }
2735
2736 /*-----------------------------------------------------------------*/
2737 /* packRegisters - does some transformations to reduce register    */
2738 /*                   pressure                                      */
2739 /*-----------------------------------------------------------------*/
2740 static void
2741 packRegisters (eBBlock ** ebpp, int blockno)
2742 {
2743   iCode *ic;
2744   int change = 0;
2745   eBBlock *ebp=ebpp[blockno];
2746
2747   while (1)
2748     {
2749
2750       change = 0;
2751
2752       /* look for assignments of the form */
2753       /* iTempNN = TRueSym (someoperation) SomeOperand */
2754       /*       ....                       */
2755       /* TrueSym := iTempNN:1             */
2756       for (ic = ebp->sch; ic; ic = ic->next)
2757         {
2758           /* find assignment of the form TrueSym := iTempNN:1 */
2759           if (ic->op == '=' && !POINTER_SET (ic) )
2760             change += packRegsForAssign (ic, ebp);
2761         }
2762
2763       if (!change)
2764         break;
2765     }
2766
2767   for (ic = ebp->sch; ic; ic = ic->next)
2768     {
2769       //packRegsForLiteral (ic);
2770       
2771       /* if this is an itemp & result of an address of a true sym 
2772          then mark this as rematerialisable   */
2773       if (ic->op == ADDRESS_OF &&
2774           IS_ITEMP (IC_RESULT (ic)) && 
2775           IS_TRUE_SYMOP (IC_LEFT (ic)) &&
2776           bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2777           !OP_SYMBOL (IC_LEFT (ic))->onStack )
2778         {
2779
2780           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2781           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2782           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2783
2784         }
2785 #if 1
2786       if (ic->op == '=' &&
2787           !POINTER_SET (ic) &&
2788           IS_ITEMP (IC_RESULT (ic)) &&
2789           IS_VALOP (IC_RIGHT (ic)) &&
2790           bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1)
2791         {
2792
2793           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2794           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2795           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2796
2797         }
2798 #endif
2799       /* if straight assignment then carry remat flag if
2800          this is the only definition */
2801       if (ic->op == '=' &&
2802           !POINTER_SET (ic) &&
2803           IS_SYMOP (IC_RIGHT (ic)) &&
2804           OP_SYMBOL (IC_RIGHT (ic))->remat &&
2805           !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode) &&
2806           bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
2807         {
2808
2809           OP_SYMBOL (IC_RESULT (ic))->remat =
2810             OP_SYMBOL (IC_RIGHT (ic))->remat;
2811           OP_SYMBOL (IC_RESULT (ic))->rematiCode =
2812             OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
2813         }
2814
2815       /* if cast to a generic pointer & the pointer being
2816          cast is remat, then we can remat this cast as well */
2817       if (ic->op == CAST && 
2818           IS_SYMOP(IC_RIGHT(ic)) &&
2819           OP_SYMBOL(IC_RIGHT(ic))->remat &&
2820           bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1) {
2821               sym_link *to_type = operandType(IC_LEFT(ic));
2822               sym_link *from_type = operandType(IC_RIGHT(ic));
2823               if (IS_GENPTR(to_type) && IS_PTR(from_type)) {                  
2824                       OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2825                       OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2826                       OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2827               }
2828       }
2829
2830       /* if this is a +/- operation with a rematerizable 
2831          then mark this as rematerializable as well */
2832       if ((ic->op == '+' || ic->op == '-') &&
2833           (IS_SYMOP (IC_LEFT (ic)) &&
2834            IS_ITEMP (IC_RESULT (ic)) &&
2835            IS_OP_LITERAL (IC_RIGHT (ic))) &&
2836            OP_SYMBOL (IC_LEFT (ic))->remat &&
2837           (!IS_SYMOP (IC_RIGHT (ic)) || !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode)) &&
2838            bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1)
2839         {
2840           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2841           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2842           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2843         }
2844
2845       /* mark the pointer usages */
2846       if (POINTER_SET (ic))
2847         OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
2848
2849       if (POINTER_GET (ic) &&
2850           IS_SYMOP(IC_LEFT (ic)))
2851         OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
2852
2853       if (!SKIP_IC2 (ic))
2854         {
2855 #if 0
2856           /* if we are using a symbol on the stack
2857              then we should say hc08_ptrRegReq */
2858           if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
2859             hc08_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
2860                                  OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
2861           else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
2862             hc08_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
2863                               OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
2864           else
2865             {
2866               if (IS_SYMOP (IC_LEFT (ic)))
2867                 hc08_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
2868                                 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
2869               if (IS_SYMOP (IC_RIGHT (ic)))
2870                 hc08_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
2871                                OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
2872               if (IS_SYMOP (IC_RESULT (ic)))
2873                 hc08_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
2874                               OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
2875             }
2876 #endif
2877         }
2878
2879       /* if the condition of an if instruction
2880          is defined in the previous instruction and
2881          this is the only usage then
2882          mark the itemp as a conditional */
2883       if ((IS_CONDITIONAL (ic) ||
2884            (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic))) &&
2885           ic->next && ic->next->op == IFX &&
2886           bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
2887           isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
2888           OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2889         {
2890           OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
2891           continue;
2892         }
2893
2894       /* reduce for support function calls */
2895       if (ic->supportRtn || (ic->op != IFX && ic->op != JUMPTABLE))
2896         packRegsForSupport (ic, ebp);
2897
2898       #if 0
2899       /* some cases the redundant moves can
2900          can be eliminated for return statements */
2901       if ((ic->op == RETURN || (ic->op == SEND && ic->argreg == 1)) &&
2902           /* !isOperandInFarSpace (IC_LEFT (ic)) && */
2903           options.model == MODEL_SMALL) {
2904         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2905       }
2906
2907       /* if pointer set & left has a size more than
2908          one and right is not in far space */
2909       if (POINTER_SET (ic) &&
2910           /* !isOperandInFarSpace (IC_RIGHT (ic)) && */
2911           !OP_SYMBOL (IC_RESULT (ic))->remat &&
2912           !IS_OP_RUONLY (IC_RIGHT (ic)) 
2913           /* && getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1 */ )
2914         packRegsForOneuse (ic, IC_RESULT (ic), ebp);
2915
2916       /* if pointer get */
2917       if (POINTER_GET (ic) &&
2918           IS_SYMOP (IC_LEFT (ic)) &&
2919           /* !isOperandInFarSpace (IC_RESULT (ic)) && */
2920           !OP_SYMBOL (IC_LEFT (ic))->remat &&
2921           !IS_OP_RUONLY (IC_RESULT (ic)) 
2922            /* && getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1 */)
2923         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2924
2925
2926       /* if this is cast for intergral promotion then
2927          check if only use of  the definition of the 
2928          operand being casted/ if yes then replace
2929          the result of that arithmetic operation with 
2930          this result and get rid of the cast */
2931       if (ic->op == CAST)
2932         {
2933           sym_link *fromType = operandType (IC_RIGHT (ic));
2934           sym_link *toType = operandType (IC_LEFT (ic));
2935
2936           if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
2937               getSize (fromType) != getSize (toType) &&
2938               SPEC_USIGN (fromType) == SPEC_USIGN (toType))
2939             {
2940
2941               iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2942               if (dic)
2943                 {
2944                   if (IS_ARITHMETIC_OP (dic))
2945                     {                  
2946                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2947                       ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
2948                       remiCodeFromeBBlock (ebp, ic);
2949                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2950                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2951                       OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2952                       ic = ic->prev;
2953                     }
2954                   else
2955                     OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
2956                 }
2957             }
2958           else
2959             {
2960
2961               /* if the type from and type to are the same
2962                  then if this is the only use then packit */
2963               if (compareType (operandType (IC_RIGHT (ic)),
2964                              operandType (IC_LEFT (ic))) == 1)
2965                 {
2966                   iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2967                   if (dic)
2968                     {
2969                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2970                       ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
2971                       remiCodeFromeBBlock (ebp, ic);
2972                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2973                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2974                       OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2975                       ic = ic->prev;
2976                     }
2977                 }
2978             }
2979         }
2980       #endif
2981       
2982       /* pack for PUSH 
2983          iTempNN := (some variable in farspace) V1
2984          push iTempNN ;
2985          -------------
2986          push V1
2987        */
2988       if (ic->op == IPUSH)
2989         {
2990           packForPush (ic, ebpp, blockno);
2991         }
2992
2993
2994       #if 1
2995       /* pack registers for accumulator use, when the
2996          result of an arithmetic or bit wise operation
2997          has only one use, that use is immediately following
2998          the defintion and the using iCode has only one
2999          operand or has two operands but one is literal &
3000          the result of that operation is not on stack then
3001          we can leave the result of this operation in x:a
3002          combination */
3003       if ((IS_ARITHMETIC_OP (ic)
3004            || IS_CONDITIONAL(ic)
3005            || IS_BITWISE_OP (ic)
3006            || ic->op == '='
3007            || ic->op == '!'
3008            || ic->op == '~'
3009            || ic->op == GETHBIT
3010            || ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == CALL
3011            || (ic->op == ADDRESS_OF && isOperandOnStack (IC_LEFT (ic)))
3012            || ic->op == RECEIVE
3013           ) &&
3014           IS_ITEMP (IC_RESULT (ic)) &&
3015           getSize (operandType (IC_RESULT (ic))) <= 1)
3016
3017         packRegsForAccUse (ic);
3018       #endif
3019     }
3020 }
3021
3022 /*-----------------------------------------------------------------*/
3023 /* assignRegisters - assigns registers to each live range as need  */
3024 /*-----------------------------------------------------------------*/
3025 void
3026 hc08_assignRegisters (eBBlock ** ebbs, int count)
3027 {
3028   iCode *ic;
3029   int i;
3030
3031   setToNull ((void *) &_G.funcrUsed);
3032   setToNull ((void *) &_G.regAssigned);
3033   setToNull ((void *) &_G.totRegAssigned);
3034   hc08_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3035   hc08_nRegs = 7;
3036   hc08_reg_a = hc08_regWithIdx(A_IDX);
3037   hc08_reg_x = hc08_regWithIdx(X_IDX);
3038   hc08_reg_h = hc08_regWithIdx(H_IDX);
3039   hc08_reg_hx = hc08_regWithIdx(HX_IDX);
3040   hc08_reg_xa = hc08_regWithIdx(XA_IDX);
3041   hc08_reg_sp = hc08_regWithIdx(SP_IDX);
3042   hc08_nRegs = 5;
3043
3044   /* change assignments this will remove some
3045      live ranges reducing some register pressure */
3046   for (i = 0; i < count; i++)
3047     packRegisters (ebbs, i);
3048
3049   /* liveranges probably changed by register packing
3050      so we compute them again */
3051   recomputeLiveRanges (ebbs, count);
3052   
3053   if (options.dump_pack)
3054     dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3055
3056   /* first determine for each live range the number of 
3057      registers & the type of registers required for each */
3058   regTypeNum (*ebbs);
3059
3060   /* and serially allocate registers */
3061   serialRegAssign (ebbs, count);
3062
3063   freeAllRegs ();
3064   //setToNull ((void *) &_G.regAssigned);
3065   //setToNull ((void *) &_G.totRegAssigned);
3066   fillGaps();
3067
3068   /* if stack was extended then tell the user */
3069   if (_G.stackExtend)
3070     {
3071 /*      werror(W_TOOMANY_SPILS,"stack", */
3072 /*             _G.stackExtend,currFunc->name,""); */
3073       _G.stackExtend = 0;
3074     }
3075
3076   if (_G.dataExtend)
3077     {
3078 /*      werror(W_TOOMANY_SPILS,"data space", */
3079 /*             _G.dataExtend,currFunc->name,""); */
3080       _G.dataExtend = 0;
3081     }
3082
3083   /* after that create the register mask
3084      for each of the instruction */
3085   createRegMask (ebbs, count);
3086
3087   /* redo that offsets for stacked automatic variables */
3088   if (currFunc) {
3089     redoStackOffsets ();
3090   }
3091
3092   if (options.dump_rassgn)
3093     {
3094       dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3095       dumpLiveRanges (DUMP_LRANGE, liveRanges);
3096     }
3097
3098   /* do the overlaysegment stuff SDCCmem.c */
3099   doOverlays (ebbs, count);
3100
3101   /* now get back the chain */
3102   ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3103
3104   genhc08Code (ic);
3105
3106   /* free up any _G.stackSpil locations allocated */
3107   applyToSet (_G.stackSpil, deallocStackSpil);
3108   _G.slocNum = 0;
3109   setToNull ((void **) &_G.stackSpil);
3110   setToNull ((void **) &_G.spiltSet);
3111   /* mark all registers as free */
3112   freeAllRegs ();
3113
3114   return;
3115 }