175f83dd3c698b25054632a10973bbf9b300bc37
[fw/sdcc] / src / hc08 / ralloc.c
1 /*------------------------------------------------------------------------
2
3   SDCCralloc.c - source file for register allocation. 68HC08 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 as 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 &&
742           !isiCodeInFunctionCall (ic) &&       
743           (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
744         {
745           sym = leastUsedLR (selectS);
746           if (sym != forSym)
747             {
748               if (!sym->remat)
749                 {
750                   sym->remainSpil = 1;
751                   _G.blockSpil++;
752                 }
753               return sym;
754             }
755         }
756     }
757
758   /* find live ranges with spillocation && not used as pointers */
759   if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
760     {
761
762       sym = leastUsedLR (selectS);
763       /* mark this as allocation required */
764       sym->usl.spillLoc->allocreq++;
765       return sym;
766     }
767
768   /* find live ranges with spillocation */
769   if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
770     {
771
772       sym = leastUsedLR (selectS);
773       sym->usl.spillLoc->allocreq++;
774       return sym;
775     }
776
777   /* couldn't find then we need to create a spil
778      location on the stack , for which one? the least
779      used ofcourse */
780   if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
781     {
782
783       /* return a created spil location */
784       sym = createStackSpil (leastUsedLR (selectS));
785       sym->usl.spillLoc->allocreq++;
786       return sym;
787     }
788
789   /* this is an extreme situation we will spill
790      this one : happens very rarely but it does happen */
791   spillThis (forSym);
792   return forSym;
793
794 }
795
796 /*-----------------------------------------------------------------*/
797 /* spilSomething - spil some variable & mark registers as free     */
798 /*-----------------------------------------------------------------*/
799 static bool
800 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
801 {
802   symbol *ssym;
803   int i;
804
805   /* get something we can spil */
806   ssym = selectSpil (ic, ebp, forSym);
807
808   /* mark it as spilt */
809   ssym->isspilt = ssym->spillA = 1;
810   _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
811
812   /* mark it as not register assigned &
813      take it away from the set */
814   bitVectUnSetBit (_G.regAssigned, ssym->key);
815   bitVectUnSetBit (_G.totRegAssigned, ssym->key);
816
817   /* mark the registers as free */
818   for (i = 0; i < ssym->nRegs; i++)
819     if (ssym->regs[i])
820       hc08_freeReg (ssym->regs[i]);
821
822   /* if spilt on stack then free up hx
823      if it could have been assigned to as gprs */
824   if (!hc08_ptrRegReq && isSpiltOnStack (ssym))
825     {
826       hc08_ptrRegReq++;
827       spillLRWithPtrReg (ssym);
828     }
829
830   /* if this was a block level spil then insert push & pop
831      at the start & end of block respectively */
832   if (ssym->blockSpil)
833     {
834       iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
835       /* add push to the start of the block */
836       addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
837                                     ebp->sch->next : ebp->sch));
838       nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
839       /* add pop to the end of the block */
840       addiCodeToeBBlock (ebp, nic, NULL);
841     }
842
843   /* if spilt because not used in the remainder of the
844      block then add a push before this instruction and
845      a pop at the end of the block */
846   if (ssym->remainSpil)
847     {
848
849       iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
850       /* add push just before this instruction */
851       addiCodeToeBBlock (ebp, nic, ic);
852
853       nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
854       /* add pop to the end of the block */
855       addiCodeToeBBlock (ebp, nic, NULL);
856     }
857
858   if (ssym == forSym)
859     return FALSE;
860   else
861     return TRUE;
862 }
863
864 /*-----------------------------------------------------------------*/
865 /* getRegPtr - will try for PTR if not a GPR type if not spil      */
866 /*-----------------------------------------------------------------*/
867 static regs *
868 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
869 {
870   regs *reg;
871
872 tryAgain:
873   /* try for a ptr type */
874   if ((reg = allocReg (REG_PTR)))
875     return reg;
876
877   /* try for gpr type */
878   if ((reg = allocReg (REG_GPR)))
879     return reg;
880
881   /* we have to spil */
882   if (!spilSomething (ic, ebp, sym))
883     return NULL;
884
885   /* this looks like an infinite loop but
886      in really selectSpil will abort  */
887   goto tryAgain;
888 }
889
890 /*-----------------------------------------------------------------*/
891 /* getRegGpr - will try for GPR if not spil                        */
892 /*-----------------------------------------------------------------*/
893 static regs *
894 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
895 {
896   regs *reg;
897
898 tryAgain:
899   /* try for gpr type */
900   if ((reg = allocReg (REG_GPR)))
901     return reg;
902
903   if (!hc08_ptrRegReq)
904     if ((reg = allocReg (REG_PTR)))
905       return reg;
906
907   /* we have to spil */
908   if (!spilSomething (ic, ebp, sym))
909     return NULL;
910
911   /* this looks like an infinite loop but
912      in really selectSpil will abort  */
913   goto tryAgain;
914 }
915
916 /*-----------------------------------------------------------------*/
917 /* getRegPtrNoSpil - get it cannot split                           */
918 /*-----------------------------------------------------------------*/
919 static regs *getRegPtrNoSpil()
920 {
921   regs *reg;
922
923   /* try for a ptr type */
924   if ((reg = allocReg (REG_PTR)))
925     return reg;
926
927   /* try for gpr type */
928   if ((reg = allocReg (REG_GPR)))
929     return reg;
930
931   assert(0);
932
933   /* just to make the compiler happy */
934   return 0;
935 }
936
937 /*-----------------------------------------------------------------*/
938 /* getRegGprNoSpil - get it cannot split                           */
939 /*-----------------------------------------------------------------*/
940 static regs *getRegGprNoSpil()
941 {
942
943   regs *reg;
944   if ((reg = allocReg (REG_GPR)))
945     return reg;
946
947   if (!hc08_ptrRegReq)
948     if ((reg = allocReg (REG_PTR)))
949       return reg;
950
951   assert(0);
952
953   /* just to make the compiler happy */
954   return 0;
955 }
956
957 /*-----------------------------------------------------------------*/
958 /* symHasReg - symbol has a given register                         */
959 /*-----------------------------------------------------------------*/
960 static bool
961 symHasReg (symbol * sym, regs * reg)
962 {
963   int i;
964
965   for (i = 0; i < sym->nRegs; i++)
966     if (sym->regs[i] == reg)
967       return TRUE;
968
969   return FALSE;
970 }
971
972 /*-----------------------------------------------------------------*/
973 /* deassignLRs - check the live to and if they have registers & are */
974 /*               not spilt then free up the registers              */
975 /*-----------------------------------------------------------------*/
976 static void
977 deassignLRs (iCode * ic, eBBlock * ebp)
978 {
979   symbol *sym;
980   int k;
981   symbol *result;
982
983   for (sym = hTabFirstItem (liveRanges, &k); sym;
984        sym = hTabNextItem (liveRanges, &k))
985     {
986
987       symbol *psym = NULL;
988       /* if it does not end here */
989       if (sym->liveTo > ic->seq)
990         continue;
991
992       /* if it was spilt on stack then we can
993          mark the stack spil location as free */
994       if (sym->isspilt)
995         {
996           if (sym->stackSpil)
997             {
998               sym->usl.spillLoc->isFree = 1;
999               sym->stackSpil = 0;
1000             }
1001           continue;
1002         }
1003
1004       if (!bitVectBitValue (_G.regAssigned, sym->key))
1005         continue;
1006
1007       /* special case check if this is an IFX &
1008          the privious one was a pop and the
1009          previous one was not spilt then keep track
1010          of the symbol */
1011       if (ic->op == IFX && ic->prev &&
1012           ic->prev->op == IPOP &&
1013           !ic->prev->parmPush &&
1014           !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1015         psym = OP_SYMBOL (IC_LEFT (ic->prev));
1016
1017       if (sym->nRegs)
1018         {
1019           int i = 0;
1020
1021           bitVectUnSetBit (_G.regAssigned, sym->key);
1022
1023           /* if the result of this one needs registers
1024              and does not have it then assign it right
1025              away */
1026           if (IC_RESULT (ic) &&
1027               !(SKIP_IC2 (ic) ||        /* not a special icode */
1028                 ic->op == JUMPTABLE ||
1029                 ic->op == IFX ||
1030                 ic->op == IPUSH ||
1031                 ic->op == IPOP ||
1032                 ic->op == RETURN ||
1033                 POINTER_SET (ic)) &&
1034               (result = OP_SYMBOL (IC_RESULT (ic))) &&  /* has a result */
1035               result->liveTo > ic->seq &&       /* and will live beyond this */
1036               result->liveTo <= ebp->lSeq &&    /* does not go beyond this block */
1037               result->liveFrom == ic->seq &&    /* does not start before here */
1038               result->regType == sym->regType &&        /* same register types */
1039               result->nRegs &&  /* which needs registers */
1040               !result->isspilt &&       /* and does not already have them */
1041               !result->remat &&
1042               !bitVectBitValue (_G.regAssigned, result->key) &&
1043           /* the number of free regs + number of regs in this LR
1044              can accomodate the what result Needs */
1045               ((nfreeRegsType (result->regType) +
1046                 sym->nRegs) >= result->nRegs)
1047             )
1048             {
1049
1050               for (i = 0; i < result->nRegs; i++)
1051                 if (i < sym->nRegs)
1052                   result->regs[i] = sym->regs[i];
1053                 else
1054                   result->regs[i] = getRegGpr (ic, ebp, result);
1055
1056               _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1057               _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, result->key);
1058
1059             }
1060
1061           /* free the remaining */
1062           for (; i < sym->nRegs; i++)
1063             {
1064               if (psym)
1065                 {
1066                   if (!symHasReg (psym, sym->regs[i]))
1067                     hc08_freeReg (sym->regs[i]);
1068                 }
1069               else
1070                 hc08_freeReg (sym->regs[i]);
1071             }
1072         }
1073     }
1074 }
1075
1076
1077 /*-----------------------------------------------------------------*/
1078 /* reassignLR - reassign this to registers                         */
1079 /*-----------------------------------------------------------------*/
1080 static void
1081 reassignLR (operand * op)
1082 {
1083   symbol *sym = OP_SYMBOL (op);
1084   int i;
1085
1086   /* not spilt any more */
1087   sym->isspilt = sym->spillA = sym->blockSpil = sym->remainSpil = 0;
1088   bitVectUnSetBit (_G.spiltSet, sym->key);
1089
1090   _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1091   _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key);
1092
1093   _G.blockSpil--;
1094
1095   for (i = 0; i < sym->nRegs; i++)
1096     sym->regs[i]->isFree = 0;
1097 }
1098
1099 /*-----------------------------------------------------------------*/
1100 /* willCauseSpill - determines if allocating will cause a spill    */
1101 /*-----------------------------------------------------------------*/
1102 static int
1103 willCauseSpill (int nr, int rt)
1104 {
1105   /* first check if there are any avlb registers
1106      of te type required */
1107   if (rt == REG_PTR)
1108     {
1109       /* special case for pointer type
1110          if pointer type not avlb then
1111          check for type gpr */
1112       if (nFreeRegs (rt) >= nr)
1113         return 0;
1114       if (nFreeRegs (REG_GPR) >= nr)
1115         return 0;
1116     }
1117   else
1118     {
1119       if (hc08_ptrRegReq)
1120         {
1121           if (nFreeRegs (rt) >= nr)
1122             return 0;
1123         }
1124       else
1125         {
1126           if (nFreeRegs (REG_PTR) +
1127               nFreeRegs (REG_GPR) >= nr)
1128             return 0;
1129         }
1130     }
1131
1132   /* it will cause a spil */
1133   return 1;
1134 }
1135
1136 /*-----------------------------------------------------------------*/
1137 /* positionRegs - the allocator can allocate same registers to res- */
1138 /* ult and operand, if this happens make sure they are in the same */
1139 /* position as the operand otherwise chaos results                 */
1140 /*-----------------------------------------------------------------*/
1141 static int
1142 positionRegs (symbol * result, symbol * opsym)
1143 {
1144   int count = min (result->nRegs, opsym->nRegs);
1145   int i, j = 0, shared = 0;
1146   int change = 0;
1147
1148   /* if the result has been spilt then cannot share */
1149   if (opsym->isspilt)
1150     return 0;
1151 again:
1152   shared = 0;
1153   /* first make sure that they actually share */
1154   for (i = 0; i < count; i++)
1155     {
1156       for (j = 0; j < count; j++)
1157         {
1158           if (result->regs[i] == opsym->regs[j] && i != j)
1159             {
1160               shared = 1;
1161               goto xchgPositions;
1162             }
1163         }
1164     }
1165 xchgPositions:
1166   if (shared)
1167     {
1168       regs *tmp = result->regs[i];
1169       result->regs[i] = result->regs[j];
1170       result->regs[j] = tmp;
1171       change ++;
1172       goto again;
1173     }
1174   return change;
1175 }
1176
1177 /*------------------------------------------------------------------*/
1178 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
1179 /* it should either have registers or have beed spilled. Otherwise, */
1180 /* there was an uninitialized variable, so just spill this to get   */
1181 /* the operand in a valid state.                                    */
1182 /*------------------------------------------------------------------*/
1183 static void
1184 verifyRegsAssigned (operand *op, iCode * ic)
1185 {
1186   symbol * sym;
1187
1188   if (!op) return;
1189   if (!IS_ITEMP (op)) return;
1190
1191   sym = OP_SYMBOL (op);
1192   if (sym->isspilt) return;
1193   if (!sym->nRegs) return;
1194   if (sym->regs[0]) return;
1195
1196   werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
1197             sym->prereqv ? sym->prereqv->name : sym->name);
1198   spillThis (sym);
1199 }
1200
1201
1202
1203 /*-----------------------------------------------------------------*/
1204 /* serialRegAssign - serially allocate registers to the variables  */
1205 /*-----------------------------------------------------------------*/
1206 static void
1207 serialRegAssign (eBBlock ** ebbs, int count)
1208 {
1209     int i;
1210
1211     /* for all blocks */
1212     for (i = 0; i < count; i++) {
1213
1214         iCode *ic;
1215
1216         if (ebbs[i]->noPath &&
1217             (ebbs[i]->entryLabel != entryLabel &&
1218              ebbs[i]->entryLabel != returnLabel))
1219             continue;
1220
1221         /* of all instructions do */
1222         for (ic = ebbs[i]->sch; ic; ic = ic->next) {
1223 #if 1
1224             int reg;
1225
1226             // update the registers in use at the start of this icode
1227             for (reg=0; reg<hc08_nRegs; reg++) {
1228               if (regshc08[reg].isFree) {
1229                 ic->riu &= ~(regshc08[reg].mask);
1230               } else {
1231                 ic->riu |= (regshc08[reg].mask);
1232               }
1233             }
1234 #endif
1235
1236             /* if this is an ipop that means some live
1237                range will have to be assigned again */
1238             if (ic->op == IPOP)
1239                 reassignLR (IC_LEFT (ic));
1240
1241             /* if result is present && is a true symbol */
1242             if (IC_RESULT (ic) && ic->op != IFX &&
1243                 IS_TRUE_SYMOP (IC_RESULT (ic)))
1244                 OP_SYMBOL (IC_RESULT (ic))->allocreq++;
1245
1246             /* take away registers from live
1247                ranges that end at this instruction */
1248             deassignLRs (ic, ebbs[i]);
1249
1250             /* some don't need registers */
1251             if (SKIP_IC2 (ic) ||
1252                 ic->op == JUMPTABLE ||
1253                 ic->op == IFX ||
1254                 ic->op == IPUSH ||
1255                 ic->op == IPOP ||
1256                 (IC_RESULT (ic) && POINTER_SET (ic)))
1257                 continue;
1258
1259             /* now we need to allocate registers
1260                only for the result */
1261             if (IC_RESULT (ic)) {
1262                 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
1263                 bitVect *spillable;
1264                 int willCS;
1265                 int j;
1266                 int ptrRegSet = 0;
1267
1268                 /* if it does not need or is spilt
1269                    or is already assigned to registers
1270                    or will not live beyond this instructions */
1271                 if (!sym->nRegs ||
1272                     sym->isspilt ||
1273                     bitVectBitValue (_G.regAssigned, sym->key) ||
1274                     sym->liveTo <= ic->seq)
1275                     continue;
1276
1277                 /* if some liverange has been spilt at the block level
1278                    and this one live beyond this block then spil this
1279                    to be safe */
1280                 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq) {
1281                     spillThis (sym);
1282                     continue;
1283                 }
1284                 /* if trying to allocate this will cause
1285                    a spill and there is nothing to spill
1286                    or this one is rematerializable then
1287                    spill this one */
1288                 willCS = willCauseSpill (sym->nRegs, sym->regType);
1289                 spillable = computeSpillable (ic);
1290                 if (sym->remat || (willCS && bitVectIsZero (spillable))) {
1291                     spillThis (sym);
1292                     continue;
1293                 }
1294
1295                 /* If the live range preceeds the point of definition
1296                    then ideally we must take into account registers that
1297                    have been allocated after sym->liveFrom but freed
1298                    before ic->seq. This is complicated, so spill this
1299                    symbol instead and let fillGaps handle the allocation. */
1300                 if (sym->liveFrom < ic->seq) {
1301                     spillThis (sym);
1302                     continue;
1303                 }
1304
1305                 /* if it has a spillocation & is used less than
1306                    all other live ranges then spill this */
1307                 if (willCS) {
1308                     if (sym->usl.spillLoc) {
1309                         symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
1310                                                                          allLRs, ebbs[i], ic));
1311                         if (leastUsed && leastUsed->used > sym->used) {
1312                             spillThis (sym);
1313                             continue;
1314                         }
1315                     } else {
1316                         /* if none of the liveRanges have a spillLocation then better
1317                            to spill this one than anything else already assigned to registers */
1318                         if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
1319                             /* if this is local to this block then we might find a block spil */
1320                             if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
1321                                 spillThis (sym);
1322                                 continue;
1323                             }
1324                         }
1325                     }
1326                 }
1327                 /* if we need ptr regs for the right side
1328                    then mark it */
1329                 if (POINTER_GET (ic) && IS_SYMOP (IC_LEFT (ic))
1330                     && getSize (OP_SYMBOL (IC_LEFT (ic))->type) <= (unsigned int) PTRSIZE) {
1331                     hc08_ptrRegReq++;
1332                     ptrRegSet = 1;
1333                 }
1334                 /* else we assign registers to it */
1335                 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1336                 _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key);
1337
1338                 for (j = 0; j < sym->nRegs; j++) {
1339                     if (sym->regType == REG_PTR)
1340                         sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
1341                     else
1342                         sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
1343
1344                     /* if the allocation failed which means
1345                        this was spilt then break */
1346                     if (!sym->regs[j]) {
1347                       break;
1348                     }
1349                 }
1350
1351                 /* if it shares registers with operands make sure
1352                    that they are in the same position */
1353                 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
1354                     OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=') {
1355                     positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1356                                   OP_SYMBOL (IC_LEFT (ic)));
1357                 }
1358                 /* do the same for the right operand */
1359                 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
1360                     OP_SYMBOL (IC_RIGHT (ic))->nRegs) {
1361                     positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1362                                   OP_SYMBOL (IC_RIGHT (ic)));
1363                 }
1364
1365                 if (ptrRegSet) {
1366                     hc08_ptrRegReq--;
1367                     ptrRegSet = 0;
1368                 }
1369
1370             }
1371         }
1372     }
1373
1374     /* Check for and fix any problems with uninitialized operands */
1375     for (i = 0; i < count; i++)
1376       {
1377         iCode *ic;
1378
1379         if (ebbs[i]->noPath &&
1380             (ebbs[i]->entryLabel != entryLabel &&
1381              ebbs[i]->entryLabel != returnLabel))
1382             continue;
1383
1384         for (ic = ebbs[i]->sch; ic; ic = ic->next)
1385           {
1386             if (SKIP_IC2 (ic))
1387               continue;
1388
1389             if (ic->op == IFX)
1390               {
1391                 verifyRegsAssigned (IC_COND (ic), ic);
1392                 continue;
1393               }
1394
1395             if (ic->op == JUMPTABLE)
1396               {
1397                 verifyRegsAssigned (IC_JTCOND (ic), ic);
1398                 continue;
1399               }
1400
1401             verifyRegsAssigned (IC_RESULT (ic), ic);
1402             verifyRegsAssigned (IC_LEFT (ic), ic);
1403             verifyRegsAssigned (IC_RIGHT (ic), ic);
1404           }
1405       }
1406
1407 }
1408
1409 /*-----------------------------------------------------------------*/
1410 /* fillGaps - Try to fill in the Gaps left by Pass1                */
1411 /*-----------------------------------------------------------------*/
1412 static void fillGaps()
1413 {
1414     symbol *sym =NULL;
1415     int key =0;
1416
1417     if (getenv("DISABLE_FILL_GAPS")) return;
1418
1419     /* look for liveranges that were spilt by the allocator */
1420     for (sym = hTabFirstItem(liveRanges,&key) ; sym ;
1421          sym = hTabNextItem(liveRanges,&key)) {
1422
1423         int i;
1424         int pdone = 0;
1425
1426         if (!sym->spillA || !sym->clashes || sym->remat) continue ;
1427
1428         /* find the liveRanges this one clashes with, that are
1429            still assigned to registers & mark the registers as used*/
1430         for ( i = 0 ; i < sym->clashes->size ; i ++) {
1431             int k;
1432             symbol *clr;
1433
1434             if (bitVectBitValue(sym->clashes,i) == 0 ||    /* those that clash with this */
1435                 bitVectBitValue(_G.totRegAssigned,i) == 0) /* and are still assigned to registers */
1436                 continue ;
1437
1438                 clr = hTabItemWithKey(liveRanges,i);
1439             assert(clr);
1440
1441             /* mark these registers as used */
1442             for (k = 0 ; k < clr->nRegs ; k++ )
1443                 hc08_useReg(clr->regs[k]);
1444         }
1445
1446         if (willCauseSpill(sym->nRegs,sym->regType)) {
1447             /* NOPE :( clear all registers & and continue */
1448             freeAllRegs();
1449             continue ;
1450         }
1451
1452         /* THERE IS HOPE !!!! */
1453         for (i=0; i < sym->nRegs ; i++ ) {
1454             if (sym->regType == REG_PTR)
1455                 sym->regs[i] = getRegPtrNoSpil ();
1456             else
1457                 sym->regs[i] = getRegGprNoSpil ();
1458         }
1459
1460         /* for all its definitions check if the registers
1461            allocated needs positioning NOTE: we can position
1462            only ONCE if more than One positioning required
1463            then give up */
1464         sym->isspilt = 0;
1465         for (i = 0 ; i < sym->defs->size ; i++ ) {
1466             if (bitVectBitValue(sym->defs,i)) {
1467                 iCode *ic;
1468                 if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
1469                 if (SKIP_IC(ic)) continue;
1470                 assert(isSymbolEqual(sym,OP_SYMBOL(IC_RESULT(ic)))); /* just making sure */
1471                 /* if left is assigned to registers */
1472                 if (IS_SYMOP(IC_LEFT(ic)) &&
1473                     bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_LEFT(ic))->key)) {
1474                     pdone += positionRegs(sym,OP_SYMBOL(IC_LEFT(ic)));
1475                 }
1476                 if (IS_SYMOP(IC_RIGHT(ic)) &&
1477                     bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RIGHT(ic))->key)) {
1478                     pdone += positionRegs(sym,OP_SYMBOL(IC_RIGHT(ic)));
1479                 }
1480                 if (pdone > 1) break;
1481             }
1482         }
1483         for (i = 0 ; i < sym->uses->size ; i++ ) {
1484             if (bitVectBitValue(sym->uses,i)) {
1485                 iCode *ic;
1486                 if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
1487                 if (SKIP_IC(ic)) continue;
1488                 if (!IS_ASSIGN_ICODE(ic)) continue ;
1489
1490                 /* if result is assigned to registers */
1491                 if (IS_SYMOP(IC_RESULT(ic)) &&
1492                     bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RESULT(ic))->key)) {
1493                     pdone += positionRegs(sym,OP_SYMBOL(IC_RESULT(ic)));
1494                 }
1495                 if (pdone > 1) break;
1496             }
1497         }
1498         /* had to position more than once GIVE UP */
1499         if (pdone > 1) {
1500             /* UNDO all the changes we made to try this */
1501             sym->isspilt = 1;
1502             for (i=0; i < sym->nRegs ; i++ ) {
1503                     sym->regs[i] = NULL;
1504             }
1505             freeAllRegs();
1506             D(printf ("Fill Gap gave up due to positioning for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN"));
1507             continue ;
1508         }
1509         D(printf ("FILLED GAP for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN"));
1510         _G.totRegAssigned = bitVectSetBit(_G.totRegAssigned,sym->key);
1511         sym->isspilt = sym->spillA = 0 ;
1512         sym->usl.spillLoc->allocreq--;
1513         freeAllRegs();
1514     }
1515 }
1516
1517 /*-----------------------------------------------------------------*/
1518 /* rUmaskForOp :- returns register mask for an operand             */
1519 /*-----------------------------------------------------------------*/
1520 bitVect *
1521 hc08_rUmaskForOp (operand * op)
1522 {
1523   bitVect *rumask;
1524   symbol *sym;
1525   int j;
1526
1527   /* only temporaries are assigned registers */
1528   if (!IS_ITEMP (op))
1529     return NULL;
1530
1531   sym = OP_SYMBOL (op);
1532
1533   /* if spilt or no registers assigned to it
1534      then nothing */
1535   if (sym->isspilt || !sym->nRegs)
1536     return NULL;
1537
1538   rumask = newBitVect (hc08_nRegs);
1539
1540   for (j = 0; j < sym->nRegs; j++)
1541     {
1542       rumask = bitVectSetBit (rumask,
1543                               sym->regs[j]->rIdx);
1544     }
1545
1546   return rumask;
1547 }
1548
1549 /*-----------------------------------------------------------------*/
1550 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
1551 /*-----------------------------------------------------------------*/
1552 static bitVect *
1553 regsUsedIniCode (iCode * ic)
1554 {
1555   bitVect *rmask = newBitVect (hc08_nRegs);
1556
1557   /* do the special cases first */
1558   if (ic->op == IFX)
1559     {
1560       rmask = bitVectUnion (rmask,
1561                             hc08_rUmaskForOp (IC_COND (ic)));
1562       goto ret;
1563     }
1564
1565   /* for the jumptable */
1566   if (ic->op == JUMPTABLE)
1567     {
1568       rmask = bitVectUnion (rmask,
1569                             hc08_rUmaskForOp (IC_JTCOND (ic)));
1570
1571       goto ret;
1572     }
1573
1574   /* of all other cases */
1575   if (IC_LEFT (ic))
1576     rmask = bitVectUnion (rmask,
1577                           hc08_rUmaskForOp (IC_LEFT (ic)));
1578
1579
1580   if (IC_RIGHT (ic))
1581     rmask = bitVectUnion (rmask,
1582                           hc08_rUmaskForOp (IC_RIGHT (ic)));
1583
1584   if (IC_RESULT (ic))
1585     rmask = bitVectUnion (rmask,
1586                           hc08_rUmaskForOp (IC_RESULT (ic)));
1587
1588 ret:
1589   return rmask;
1590 }
1591
1592 /*-----------------------------------------------------------------*/
1593 /* createRegMask - for each instruction will determine the regsUsed */
1594 /*-----------------------------------------------------------------*/
1595 static void
1596 createRegMask (eBBlock ** ebbs, int count)
1597 {
1598   int i;
1599
1600   /* for all blocks */
1601   for (i = 0; i < count; i++)
1602     {
1603       iCode *ic;
1604
1605       if (ebbs[i]->noPath &&
1606           (ebbs[i]->entryLabel != entryLabel &&
1607            ebbs[i]->entryLabel != returnLabel))
1608         continue;
1609
1610       /* for all instructions */
1611       for (ic = ebbs[i]->sch; ic; ic = ic->next)
1612         {
1613
1614           int j;
1615
1616           if (SKIP_IC2 (ic) || !ic->rlive)
1617             continue;
1618
1619           /* first mark the registers used in this
1620              instruction */
1621           ic->rUsed = regsUsedIniCode (ic);
1622           _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
1623
1624           /* now create the register mask for those
1625              registers that are in use : this is a
1626              super set of ic->rUsed */
1627           ic->rMask = newBitVect (hc08_nRegs + 1);
1628
1629           /* for all live Ranges alive at this point */
1630           for (j = 1; j < ic->rlive->size; j++)
1631             {
1632               symbol *sym;
1633               int k;
1634
1635               /* if not alive then continue */
1636               if (!bitVectBitValue (ic->rlive, j))
1637                 continue;
1638
1639               /* find the live range we are interested in */
1640               if (!(sym = hTabItemWithKey (liveRanges, j)))
1641                 {
1642                   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1643                           "createRegMask cannot find live range");
1644                   fprintf(stderr, "\tmissing live range: key=%d\n", j);
1645                   exit (0);
1646                 }
1647
1648               /* if no register assigned to it */
1649               if (!sym->nRegs || sym->isspilt)
1650                 continue;
1651
1652               /* for all the registers allocated to it */
1653               for (k = 0; k < sym->nRegs; k++)
1654                 if (sym->regs[k])
1655                   ic->rMask =
1656                     bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
1657             }
1658         }
1659     }
1660 }
1661
1662 /*-----------------------------------------------------------------*/
1663 /* rematStr - returns the rematerialized string for a remat var    */
1664 /*-----------------------------------------------------------------*/
1665 static char *
1666 rematStr (symbol * sym)
1667 {
1668   char *s = buffer;
1669   iCode *ic = sym->rematiCode;
1670 //  int offset = 0;
1671
1672   while (1)
1673     {
1674       /* if plus or minus print the right hand side */
1675       if (ic->op == '+' || ic->op == '-')
1676         {
1677           sprintf (s, "0x%04x %c ", (int) operandLitValue (IC_RIGHT (ic)),
1678                    ic->op);
1679           s += strlen (s);
1680           ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1681           continue;
1682         }
1683
1684 /*
1685       if (ic->op == '+')
1686         {
1687           offset += operandLitValue (IC_RIGHT (ic));
1688           ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1689           continue;
1690         }
1691       if (ic->op == '-')
1692         {
1693           offset -= operandLitValue (IC_RIGHT (ic));
1694           ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1695           continue;
1696         }
1697 */
1698       /* cast then continue */
1699       if (IS_CAST_ICODE(ic)) {
1700           ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
1701           continue;
1702       }
1703       /* we reached the end */
1704       if (ic->op == ADDRESS_OF)
1705         sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
1706       else if (ic->op == '=')
1707         sprintf (s, "0x%04x", (int) operandLitValue (IC_RIGHT (ic)) );
1708       break;
1709     }
1710
1711   return buffer;
1712 }
1713
1714 /*-----------------------------------------------------------------*/
1715 /* regTypeNum - computes the type & number of registers required   */
1716 /*-----------------------------------------------------------------*/
1717 static void
1718 regTypeNum (eBBlock *ebbs)
1719 {
1720   symbol *sym;
1721   int k;
1722   iCode *ic;
1723
1724   /* for each live range do */
1725   for (sym = hTabFirstItem (liveRanges, &k); sym;
1726        sym = hTabNextItem (liveRanges, &k))
1727     {
1728
1729       /* if used zero times then no registers needed */
1730       if ((sym->liveTo - sym->liveFrom) == 0)
1731         continue;
1732
1733
1734       /* if the live range is a temporary */
1735       if (sym->isitmp)
1736         {
1737
1738           /* if the type is marked as a conditional */
1739           if (sym->regType == REG_CND)
1740             continue;
1741
1742           /* if used in return only then we don't
1743              need registers */
1744           if (sym->ruonly || sym->accuse)
1745             {
1746               if (IS_AGGREGATE (sym->type) || sym->isptr)
1747                 sym->type = aggrToPtr (sym->type, FALSE);
1748               continue;
1749             }
1750
1751           /* if the symbol has only one definition &
1752              that definition is a get_pointer */
1753           if (bitVectnBitsOn (sym->defs) == 1 &&
1754               (ic = hTabItemWithKey (iCodehTab,
1755                                      bitVectFirstBit (sym->defs))) &&
1756               POINTER_GET (ic) &&
1757               !IS_BITVAR (sym->etype) &&
1758               (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER))
1759             {
1760
1761               if (ptrPseudoSymSafe (sym, ic))
1762                 {
1763                   ptrPseudoSymConvert (sym, ic, rematStr (OP_SYMBOL (IC_LEFT (ic))));
1764                   continue;
1765                 }
1766
1767               /* if in data space or idata space then try to
1768                  allocate pointer register */
1769
1770             }
1771
1772           /* if not then we require registers */
1773           sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
1774                         getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1775                         getSize (sym->type));
1776
1777           if (sym->nRegs > 4)
1778             {
1779               fprintf (stderr, "allocated more than 4 or 0 registers for type ");
1780               printTypeChain (sym->type, stderr);
1781               fprintf (stderr, "\n");
1782             }
1783
1784           /* determine the type of register required */
1785           if (sym->nRegs == 1 &&
1786               IS_PTR (sym->type) &&
1787               sym->uptr)
1788             sym->regType = REG_PTR;
1789           else
1790             sym->regType = REG_GPR;
1791
1792         }
1793       else
1794         /* for the first run we don't provide */
1795         /* registers for true symbols we will */
1796         /* see how things go                  */
1797         sym->nRegs = 0;
1798           }
1799
1800 }
1801
1802 /*-----------------------------------------------------------------*/
1803 /* freeAllRegs - mark all registers as free                        */
1804 /*-----------------------------------------------------------------*/
1805 static void
1806 freeAllRegs ()
1807 {
1808   int i;
1809
1810   for (i = 0; i < hc08_nRegs; i++) {
1811     regshc08[i].isFree = 1;
1812     regshc08[i].aop = NULL;
1813   }
1814 }
1815
1816 /*-----------------------------------------------------------------*/
1817 /* deallocStackSpil - this will set the stack pointer back         */
1818 /*-----------------------------------------------------------------*/
1819 static
1820 DEFSETFUNC (deallocStackSpil)
1821 {
1822   symbol *sym = item;
1823
1824   deallocLocal (sym);
1825   return 0;
1826 }
1827
1828 #if 0
1829 /*-----------------------------------------------------------------*/
1830 /* farSpacePackable - returns the packable icode for far variables */
1831 /*-----------------------------------------------------------------*/
1832 static iCode *
1833 farSpacePackable (iCode * ic)
1834 {
1835   iCode *dic;
1836
1837   /* go thru till we find a definition for the
1838      symbol on the right */
1839   for (dic = ic->prev; dic; dic = dic->prev)
1840     {
1841       /* if the definition is a call then no */
1842       if ((dic->op == CALL || dic->op == PCALL) &&
1843           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1844         {
1845           return NULL;
1846         }
1847
1848       /* if shift by unknown amount then not */
1849       if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
1850           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1851         return NULL;
1852
1853 #if 0
1854       /* if pointer get and size > 1 */
1855       if (POINTER_GET (dic) &&
1856           getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
1857         return NULL;
1858
1859       if (POINTER_SET (dic) &&
1860           getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
1861         return NULL;
1862 #endif
1863
1864       /* if any three is a true symbol in far space */
1865       if (IC_RESULT (dic) &&
1866           IS_TRUE_SYMOP (IC_RESULT (dic)) /* &&
1867           isOperandInFarSpace (IC_RESULT (dic)) */)
1868         return NULL;
1869
1870       if (IC_RIGHT (dic) &&
1871           IS_TRUE_SYMOP (IC_RIGHT (dic)) /* &&
1872           isOperandInFarSpace (IC_RIGHT (dic)) */ &&
1873           !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
1874         return NULL;
1875
1876       if (IC_LEFT (dic) &&
1877           IS_TRUE_SYMOP (IC_LEFT (dic)) /* &&
1878           isOperandInFarSpace (IC_LEFT (dic)) */ &&
1879           !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
1880         return NULL;
1881
1882       if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
1883         {
1884           if ((dic->op == LEFT_OP ||
1885                dic->op == RIGHT_OP ||
1886                dic->op == '-') &&
1887               IS_OP_LITERAL (IC_RIGHT (dic)))
1888             return NULL;
1889           else
1890             return dic;
1891         }
1892     }
1893
1894   return NULL;
1895 }
1896 #endif
1897
1898 #if 0
1899 static void
1900 packRegsForLiteral (iCode * ic)
1901 {
1902   int k;
1903   iCode *uic;
1904
1905   if (ic->op != '=')
1906     return;
1907   if (POINTER_SET (ic))
1908     return;
1909   if (!IS_LITERAL (getSpec (operandType (IC_RIGHT (ic)))))
1910     return;
1911   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
1912     return;
1913
1914   for (k=0; k< OP_USES (IC_RESULT (ic))->size; k++)
1915     if (bitVectBitValue (OP_USES (IC_RESULT (ic)), k))
1916       {
1917         uic = hTabItemWithKey (iCodehTab, k);
1918         if (!uic) continue;
1919
1920         if (uic->op != IFX && uic->op != JUMPTABLE)
1921           {
1922             if (IC_LEFT (uic) && IC_LEFT (uic)->key == IC_RESULT (ic)->key)
1923               ReplaceOpWithCheaperOp(&IC_LEFT(uic), IC_RIGHT(ic));
1924             if (IC_RIGHT (uic) && IC_RIGHT (uic)->key == IC_RESULT (ic)->key)
1925               ReplaceOpWithCheaperOp(&IC_RIGHT(uic), IC_RIGHT(ic));
1926             if (IC_RESULT (uic) && IC_RESULT (uic)->key == IC_RESULT (ic)->key)
1927               ReplaceOpWithCheaperOp(&IC_RESULT(uic), IC_RIGHT(ic));
1928           }
1929       }
1930
1931 }
1932 #endif
1933
1934
1935 /*-----------------------------------------------------------------*/
1936 /* packRegsForAssign - register reduction for assignment           */
1937 /*-----------------------------------------------------------------*/
1938 static int
1939 packRegsForAssign (iCode * ic, eBBlock * ebp)
1940 {
1941   iCode *dic, *sic;
1942
1943   if (!IS_ITEMP (IC_RIGHT (ic)) ||
1944       OP_SYMBOL (IC_RIGHT (ic))->isind ||
1945       OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
1946     {
1947       return 0;
1948     }
1949
1950
1951   /* if the true symbol is defined in far space or on stack
1952      then we should not since this will increase register pressure */
1953 #if 0
1954   if (isOperandInFarSpace(IC_RESULT(ic)) && !farSpacePackable(ic)) {
1955     return 0;
1956   }
1957 #endif
1958
1959   /* find the definition of iTempNN scanning backwards if we find a
1960      a use of the true symbol in before we find the definition then
1961      we cannot */
1962   for (dic = ic->prev; dic; dic = dic->prev)
1963     {
1964
1965 #if 0 /* jwk: This collides with 1.43 but I really see no need for
1966          this anymore. It fixes bug #716790 and substantially improves
1967          redundant register usage around function calls.
1968       */
1969
1970       /* if there is a function call then don't pack it */
1971       if ((dic->op == CALL || dic->op == PCALL))
1972         {
1973           dic = NULL;
1974           break;
1975         }
1976 #endif
1977
1978       if (SKIP_IC2 (dic))
1979         continue;
1980
1981       if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
1982           IS_OP_VOLATILE (IC_RESULT (dic)))
1983         {
1984           dic = NULL;
1985           break;
1986         }
1987
1988       if (IS_SYMOP (IC_RESULT (dic)) &&
1989           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1990         {
1991           if (POINTER_SET (dic))
1992             dic = NULL;
1993
1994           break;
1995         }
1996
1997       if (IS_SYMOP (IC_RIGHT (dic)) &&
1998           (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
1999            IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2000         {
2001           dic = NULL;
2002           break;
2003         }
2004
2005       if (IS_SYMOP (IC_LEFT (dic)) &&
2006           (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2007            IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2008         {
2009           dic = NULL;
2010           break;
2011         }
2012
2013       if (POINTER_SET (dic) &&
2014           IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2015         {
2016           dic = NULL;
2017           break;
2018         }
2019     }
2020
2021   if (!dic)
2022     return 0;                   /* did not find */
2023
2024   /* if assignment then check that right is not a bit */
2025   if (ASSIGNMENT (dic) && !POINTER_SET (dic))
2026     {
2027       sym_link *etype = operandType (IC_RIGHT (dic));
2028       if (IS_BITFIELD (etype))
2029         {
2030           /* if result is a bit too then it's ok */
2031           etype = operandType (IC_RESULT (dic));
2032           if (!IS_BITFIELD (etype))
2033             return 0;
2034         }
2035     }
2036   /* if the result is on stack or iaccess then it must be
2037      the same atleast one of the operands */
2038   if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2039       OP_SYMBOL (IC_RESULT (ic))->iaccess)
2040     {
2041
2042       /* the operation has only one symbol
2043          operator then we can pack */
2044       if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2045           (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2046         goto pack;
2047
2048       if (!((IC_LEFT (dic) &&
2049              IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2050             (IC_RIGHT (dic) &&
2051              IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2052         return 0;
2053     }
2054 pack:
2055   /* found the definition */
2056   /* replace the result with the result of */
2057   /* this assignment and remove this assignment */
2058   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2059   ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
2060
2061   if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2062     {
2063       OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2064     }
2065   // TODO: and the otherway around?
2066
2067   /* delete from liverange table also
2068      delete from all the points inbetween and the new
2069      one */
2070   for (sic = dic; sic != ic; sic = sic->next)
2071     {
2072       bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2073       if (IS_ITEMP (IC_RESULT (dic)))
2074         bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2075     }
2076
2077   remiCodeFromeBBlock (ebp, ic);
2078   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2079   hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2080   OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2081   return 1;
2082 }
2083
2084
2085 /*------------------------------------------------------------------*/
2086 /* findAssignToSym : scanning backwards looks for first assig found */
2087 /*------------------------------------------------------------------*/
2088 static iCode *
2089 findAssignToSym (operand * op, iCode * ic)
2090 {
2091   iCode *dic;
2092
2093   /* This routine is used to find sequences like
2094      iTempAA = FOO;
2095      ...;  (intervening ops don't use iTempAA or modify FOO)
2096      blah = blah + iTempAA;
2097
2098      and eliminate the use of iTempAA, freeing up its register for
2099      other uses.
2100   */
2101
2102
2103   for (dic = ic->prev; dic; dic = dic->prev)
2104     {
2105
2106       /* if definition by assignment */
2107       if (dic->op == '=' &&
2108           !POINTER_SET (dic) &&
2109           IC_RESULT (dic)->key == op->key
2110           &&  IS_TRUE_SYMOP(IC_RIGHT(dic))
2111         )
2112         break;  /* found where this temp was defined */
2113
2114       /* if we find an usage then we cannot delete it */
2115       if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2116         return NULL;
2117
2118       if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2119         return NULL;
2120
2121       if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2122         return NULL;
2123     }
2124
2125   if (!dic)
2126     return NULL;   /* didn't find any assignment to op */
2127
2128   /* we are interested only if defined in far space */
2129   /* or in stack space in case of + & - */
2130
2131   /* if assigned to a non-symbol then don't repack regs */
2132   if (!IS_SYMOP (IC_RIGHT (dic)))
2133     return NULL;
2134
2135   /* if the symbol is volatile then we should not */
2136   if (isOperandVolatile (IC_RIGHT (dic), TRUE))
2137     return NULL;
2138   /* XXX TODO --- should we be passing FALSE to isOperandVolatile()?
2139      What does it mean for an iTemp to be volatile, anyway? Passing
2140      TRUE is more cautious but may prevent possible optimizations */
2141
2142   /* if the symbol is in far space then we should not */
2143   /* if (isOperandInFarSpace (IC_RIGHT (dic)))
2144     return NULL; */
2145
2146   /* for + & - operations make sure that
2147      if it is on the stack it is the same
2148      as one of the three operands */
2149 #if 0
2150   if ((ic->op == '+' || ic->op == '-') &&
2151       OP_SYMBOL (IC_RIGHT (dic))->onStack)
2152     {
2153
2154       if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2155           IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2156           IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2157         return NULL;
2158     }
2159 #endif
2160
2161   /* now make sure that the right side of dic
2162      is not defined between ic & dic */
2163   if (dic)
2164     {
2165       iCode *sic = dic->next;
2166
2167       for (; sic != ic; sic = sic->next)
2168         if (IC_RESULT (sic) &&
2169             IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2170           return NULL;
2171     }
2172
2173   return dic;
2174 }
2175
2176 /*-----------------------------------------------------------------*/
2177 /* reassignAliasedSym - used by packRegsForSupport to replace      */
2178 /*                      redundant iTemp with equivalent symbol     */
2179 /*-----------------------------------------------------------------*/
2180 static void
2181 reassignAliasedSym (eBBlock *ebp, iCode *assignment, iCode *use, operand *op)
2182 {
2183   iCode *ic;
2184   unsigned oldSymKey, newSymKey;
2185
2186   oldSymKey = op->key;
2187   newSymKey = IC_RIGHT(assignment)->key;
2188
2189   /* only track live ranges of compiler-generated temporaries */
2190   if (!IS_ITEMP(IC_RIGHT(assignment)))
2191     newSymKey = 0;
2192
2193   /* update the live-value bitmaps */
2194   for (ic = assignment; ic != use; ic = ic->next) {
2195     bitVectUnSetBit (ic->rlive, oldSymKey);
2196     if (newSymKey != 0)
2197       ic->rlive = bitVectSetBit (ic->rlive, newSymKey);
2198   }
2199
2200   /* update the sym of the used operand */
2201   OP_SYMBOL(op) = OP_SYMBOL(IC_RIGHT(assignment));
2202   op->key = OP_SYMBOL(op)->key;
2203
2204   /* update the sym's liverange */
2205   if ( OP_LIVETO(op) < ic->seq )
2206     setToRange(op, ic->seq, FALSE);
2207
2208   /* remove the assignment iCode now that its result is unused */
2209   remiCodeFromeBBlock (ebp, assignment);
2210   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(assignment))->defs, assignment->key);
2211   hTabDeleteItem (&iCodehTab, assignment->key, assignment, DELETE_ITEM, NULL);
2212 }
2213
2214
2215 /*-----------------------------------------------------------------*/
2216 /* packRegsForSupport :- reduce some registers for support calls   */
2217 /*-----------------------------------------------------------------*/
2218 static int
2219 packRegsForSupport (iCode * ic, eBBlock * ebp)
2220 {
2221   iCode *dic;
2222   int changes = 0;
2223
2224   /* for the left & right operand :- look to see if the
2225      left was assigned a true symbol in far space in that
2226      case replace them */
2227
2228   if (IS_ITEMP (IC_LEFT (ic)) &&
2229       OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2230     {
2231       dic = findAssignToSym (IC_LEFT (ic), ic);
2232
2233       if (dic)
2234         {
2235           /* found it we need to remove it from the block */
2236           reassignAliasedSym (ebp, dic, ic, IC_LEFT(ic));
2237           changes++;
2238         }
2239     }
2240
2241   /* do the same for the right operand */
2242   if (IS_ITEMP (IC_RIGHT (ic)) &&
2243       OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2244     {
2245       iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2246
2247       if (dic)
2248         {
2249           /* found it we need to remove it from the block */
2250           reassignAliasedSym (ebp, dic, ic, IC_RIGHT(ic));
2251           changes++;
2252         }
2253     }
2254
2255   return changes;
2256 }
2257
2258 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
2259
2260
2261 #if 0
2262 /*-----------------------------------------------------------------*/
2263 /* packRegsForOneuse : - will reduce some registers for single Use */
2264 /*-----------------------------------------------------------------*/
2265 static iCode *
2266 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
2267 {
2268   bitVect *uses;
2269   iCode *dic, *sic;
2270
2271   /* if returning a literal then do nothing */
2272   if (!IS_SYMOP (op))
2273     return NULL;
2274
2275   /* only up to 2 bytes */
2276   if (getSize (operandType (op)) > (fReturnSizeHC08 - 2))
2277     return NULL;
2278
2279   return NULL;
2280
2281   if (ic->op != SEND //RETURN
2282       && ic->op != SEND
2283       && !POINTER_SET (ic)
2284       && !POINTER_GET (ic) )
2285     return NULL;
2286
2287   if (ic->op == SEND && ic->argreg != 1) return NULL;
2288
2289   /* this routine will mark the a symbol as used in one
2290      instruction use only && if the defintion is local
2291      (ie. within the basic block) && has only one definition &&
2292      that definiion is either a return value from a
2293      function or does not contain any variables in
2294      far space */
2295   uses = bitVectCopy (OP_USES (op));
2296   bitVectUnSetBit (uses, ic->key);      /* take away this iCode */
2297   if (!bitVectIsZero (uses))    /* has other uses */
2298     return NULL;
2299
2300   /* if it has only one defintion */
2301   if (bitVectnBitsOn (OP_DEFS (op)) > 1)
2302     return NULL;                /* has more than one definition */
2303
2304   /* get that definition */
2305   if (!(dic =
2306         hTabItemWithKey (iCodehTab,
2307                          bitVectFirstBit (OP_DEFS (op)))))
2308     return NULL;
2309
2310   /* if that only usage is a cast */
2311   if (dic->op == CAST) {
2312     /* to a bigger type */
2313     if (getSize(OP_SYM_TYPE(IC_RESULT(dic))) >
2314         getSize(OP_SYM_TYPE(IC_RIGHT(dic)))) {
2315       /* than we can not, since we cannot predict the usage of b & acc */
2316       return NULL;
2317     }
2318   }
2319
2320   /* found the definition now check if it is local */
2321   if (dic->seq < ebp->fSeq ||
2322       dic->seq > ebp->lSeq)
2323     return NULL;                /* non-local */
2324
2325   /* now check if it is the return from
2326      a function call */
2327   if (dic->op == CALL || dic->op == PCALL)
2328     {
2329       if (ic->op != SEND && ic->op != RETURN &&
2330           !POINTER_SET(ic) && !POINTER_GET(ic))
2331         {
2332           OP_SYMBOL (op)->ruonly = 1;
2333           return dic;
2334         }
2335       dic = dic->next;
2336     }
2337
2338
2339   /* otherwise check that the definition does
2340      not contain any symbols in far space */
2341 //  if (isOperandInFarSpace (IC_LEFT (dic)) ||
2342 //      isOperandInFarSpace (IC_RIGHT (dic)) ||
2343 //      IS_OP_RUONLY (IC_LEFT (ic)) ||
2344 //      IS_OP_RUONLY (IC_RIGHT (ic)))
2345 //    {
2346 //      return NULL;
2347 //    }
2348
2349   /* if pointer set then make sure the pointer
2350      is one byte */
2351 #if 0
2352   if (POINTER_SET (dic) &&
2353       !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2354     return NULL;
2355
2356   if (POINTER_GET (dic) &&
2357       !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2358     return NULL;
2359 #endif
2360
2361   sic = dic;
2362
2363   /* also make sure the intervenening instructions
2364      don't have any thing in far space */
2365   for (dic = dic->next; dic && dic != ic && sic != ic; dic = dic->next)
2366     {
2367
2368       /* if there is an intervening function call then no */
2369       if (dic->op == CALL || dic->op == PCALL)
2370         return NULL;
2371       /* if pointer set then make sure the pointer
2372          is one byte */
2373 #if 0
2374       if (POINTER_SET (dic) &&
2375           !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2376         return NULL;
2377
2378       if (POINTER_GET (dic) &&
2379           !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2380         return NULL;
2381 #endif
2382       /* if address of & the result is remat the okay */
2383       if (dic->op == ADDRESS_OF &&
2384           OP_SYMBOL (IC_RESULT (dic))->remat)
2385         continue;
2386
2387       /* if operand has size of three or more & this
2388          operation is a '*','/' or '%' then 'b' may
2389          cause a problem */
2390 #if 0
2391       if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
2392           getSize (operandType (op)) >= 3)
2393         return NULL;
2394 #endif
2395
2396       /* if left or right or result is in far space */
2397 //      if (isOperandInFarSpace (IC_LEFT (dic)) ||
2398 //        isOperandInFarSpace (IC_RIGHT (dic)) ||
2399 //        isOperandInFarSpace (IC_RESULT (dic)) ||
2400 //        IS_OP_RUONLY (IC_LEFT (dic)) ||
2401 //        IS_OP_RUONLY (IC_RIGHT (dic)) ||
2402 //        IS_OP_RUONLY (IC_RESULT (dic)))
2403 //      {
2404 //        return NULL;
2405 //      }
2406 //      /* if left or right or result is on stack */
2407 //     if (isOperandOnStack(IC_LEFT(dic)) ||
2408 //        isOperandOnStack(IC_RIGHT(dic)) ||
2409 //        isOperandOnStack(IC_RESULT(dic))) {
2410 //      return NULL;
2411 //     }
2412     }
2413
2414   OP_SYMBOL (op)->ruonly = 1;
2415   return sic;
2416 }
2417 #endif
2418
2419 /*-----------------------------------------------------------------*/
2420 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
2421 /*-----------------------------------------------------------------*/
2422 static bool
2423 isBitwiseOptimizable (iCode * ic)
2424 {
2425   sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
2426   sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
2427
2428   /* bitwise operations are considered optimizable
2429      under the following conditions (Jean-Louis VERN)
2430
2431      x & lit
2432      bit & bit
2433      bit & x
2434      bit ^ bit
2435      bit ^ x
2436      x   ^ lit
2437      x   | lit
2438      bit | bit
2439      bit | x
2440   */
2441   if (IS_LITERAL(rtype) ||
2442       (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
2443     return TRUE;
2444   else
2445     return FALSE;
2446 }
2447
2448 /*-----------------------------------------------------------------*/
2449 /* isCommutativeOp - tests whether this op cares what order its    */
2450 /*                   operands are in                               */
2451 /*-----------------------------------------------------------------*/
2452 bool isCommutativeOp2(unsigned int op)
2453 {
2454   if (op == '+' || op == '*' || op == EQ_OP ||
2455       op == '^' || op == '|' || op == BITWISEAND)
2456     return TRUE;
2457   else
2458     return FALSE;
2459 }
2460
2461 /*-----------------------------------------------------------------*/
2462 /* operandUsesAcc2 - determines whether the code generated for this */
2463 /*                  operand will have to use the accumulator       */
2464 /*-----------------------------------------------------------------*/
2465 bool operandUsesAcc2(operand *op)
2466 {
2467   if (!op)
2468     return FALSE;
2469
2470   if (IS_SYMOP(op)) {
2471     symbol *sym = OP_SYMBOL(op);
2472     memmap *symspace;
2473
2474     if (sym->accuse)
2475       return TRUE;  /* duh! */
2476
2477 //    if (IN_STACK(sym->etype) || sym->onStack ||
2478 //      (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
2479 //      return TRUE;  /* acc is used to calc stack offset */
2480
2481     if (IS_ITEMP(op))
2482       {
2483         if (SPIL_LOC(op)) {
2484           sym = SPIL_LOC(op);  /* if spilled, look at spill location */
2485         } else {
2486           return FALSE;  /* more checks? */
2487         }
2488       }
2489
2490     symspace = SPEC_OCLS(sym->etype);
2491
2492 //    if (sym->iaccess && symspace->paged)
2493 //      return TRUE;  /* must fetch paged indirect sym via accumulator */
2494
2495     if (IN_BITSPACE(symspace))
2496       return TRUE;  /* fetching bit vars uses the accumulator */
2497
2498     if (IN_FARSPACE(symspace) || IN_CODESPACE(symspace))
2499       return TRUE;  /* fetched via accumulator and dptr */
2500   }
2501
2502   return FALSE;
2503 }
2504
2505 /*-----------------------------------------------------------------*/
2506 /* canDefAccResult - return 1 if the iCode can generate a result   */
2507 /*                   in A or XA                                    */
2508 /*-----------------------------------------------------------------*/
2509 static int
2510 canDefAccResult (iCode * ic)
2511 {
2512   int size;
2513
2514   if (ic->op == IFX || ic->op == JUMPTABLE)     /* these iCodes have no result */
2515     return 0;
2516
2517   if (POINTER_SET (ic))
2518     return 0;
2519
2520   if (!IC_RESULT (ic))
2521     return 0;
2522
2523   if (!IS_ITEMP (IC_RESULT (ic)))
2524     return 0;
2525
2526   /* I don't think an iTemp can be an aggregate, but just in case */
2527   if (IS_AGGREGATE(operandType(IC_RESULT(ic))))
2528     return 0;
2529
2530   size = getSize (operandType (IC_RESULT (ic)));
2531
2532   if (size == 1)
2533     {
2534       /* All 1 byte operations should safely generate an accumulator result */
2535       return 1;
2536     }
2537   else if (size == 2)
2538     {
2539       switch (ic->op)
2540         {
2541         case LEFT_OP:
2542         case RIGHT_OP:
2543           return isOperandLiteral (IC_RIGHT (ic))
2544                   && SPEC_USIGN (operandType (IC_RESULT (ic)));
2545         case CALL:
2546         case PCALL:
2547         case '*':
2548         case RECEIVE:
2549         case '=': /* assignment, since POINTER_SET is already ruled out */
2550           return 1;
2551
2552         default:
2553           return 0;
2554         }
2555     }
2556
2557   return 0;
2558 }
2559
2560 /*-----------------------------------------------------------------*/
2561 /* canUseAccOperand - return 1 if the iCode can use the operand    */
2562 /*                    when passed in A or XA                       */
2563 /*-----------------------------------------------------------------*/
2564 static int
2565 canUseAccOperand (iCode * ic, operand * op)
2566 {
2567   int size;
2568   operand * otherOp;
2569
2570   if (ic->op == IFX)
2571     {
2572       if (isOperandEqual (op, IC_COND (ic)))
2573         return 1;
2574       else
2575         return 0;
2576     }
2577
2578   if (ic->op == JUMPTABLE)
2579     {
2580       if (isOperandEqual (op, IC_JTCOND (ic)))
2581         return 1;
2582       else
2583         return 0;
2584     }
2585
2586   if (POINTER_SET (ic) && isOperandEqual (op, IC_RESULT (ic)))
2587     return 1;
2588
2589   if (isOperandEqual (op, IC_LEFT (ic)))
2590     otherOp = IC_RIGHT (ic);
2591   else if (isOperandEqual (op, IC_RIGHT (ic)))
2592     otherOp = IC_LEFT (ic);
2593   else
2594     return 0;
2595
2596   /* Generation of SEND is deferred until CALL; not safe */
2597   /* if there are intermediate iCodes */
2598   if (ic->op == SEND && ic->next && ic->next->op != CALL)
2599     return 0;
2600
2601   size = getSize (operandType (op));
2602   if (size == 1)
2603     {
2604       /* All 1 byte operations should safely use an accumulator operand */
2605       return 1;
2606     }
2607   else if (size == 2)
2608     {
2609       switch (ic->op)
2610         {
2611         case LEFT_OP:
2612         case RIGHT_OP:
2613           return isOperandLiteral (IC_RIGHT (ic));
2614         case SEND:
2615           return 1;
2616         default:
2617           return 0;
2618         }
2619     }
2620
2621   return 0;
2622 }
2623
2624
2625 /*-----------------------------------------------------------------*/
2626 /* packRegsForAccUse - pack registers for acc use                  */
2627 /*-----------------------------------------------------------------*/
2628 static int
2629 packRegsForAccUse (iCode * ic)
2630 {
2631   iCode * uic;
2632   operand * op;
2633
2634   if (!canDefAccResult (ic))
2635     return 0;
2636
2637   op = IC_RESULT (ic);
2638
2639   /* has only one definition */
2640   if (bitVectnBitsOn (OP_DEFS (op)) > 1)
2641     return 0;
2642
2643   /* has only one use */
2644   if (bitVectnBitsOn (OP_USES (op)) > 1)
2645     return 0;
2646
2647   uic = ic->next;
2648   if (!uic)
2649     return 0;
2650
2651   if (!canUseAccOperand (uic, op))
2652     return 0;
2653
2654   #if 0
2655   if ((POINTER_GET(uic))
2656       || (ic->op == ADDRESS_OF && uic->op == '+' && IS_OP_LITERAL (IC_RIGHT (uic))))
2657     {
2658       OP_SYMBOL (IC_RESULT (ic))->accuse = ACCUSE_HX;
2659       return;
2660     }
2661   #endif
2662
2663   OP_SYMBOL (IC_RESULT (ic))->accuse = ACCUSE_XA;
2664   return 1;
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       #if 0
2895       /* if the condition of an if instruction
2896          is defined in the previous GET_POINTER instruction and
2897          this is the only usage then
2898          mark the itemp as accumulator use */
2899       if ((POINTER_GET (ic) && getSize (operandType (IC_RESULT (ic))) <=1) &&
2900           ic->next && ic->next->op == IFX &&
2901           bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
2902           isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
2903           OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2904         {
2905           OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2906           continue;
2907         }
2908
2909       if (ic->op != IFX && ic->op !=JUMPTABLE && !POINTER_SET (ic)
2910           && IC_RESULT (ic) && IS_ITEMP (IC_RESULT (ic))
2911           && getSize (operandType (IC_RESULT (ic))) == 1
2912           && bitVectnBitsOn (OP_USES (IC_RESULT (ic))) == 1
2913           && ic->next
2914           && OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2915         {
2916           int accuse = 0;
2917
2918           if (ic->next->op == IFX)
2919             {
2920               if (isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)))
2921                 accuse = 1;
2922             }
2923           else if (ic->next->op == JUMPTABLE)
2924             {
2925                if (isOperandEqual (IC_RESULT (ic), IC_JTCOND (ic->next)))
2926                  accuse = 1;
2927             }
2928           else
2929             {
2930                if (isOperandEqual (IC_RESULT (ic), IC_LEFT (ic->next)))
2931                  accuse = 1;
2932                if (isOperandEqual (IC_RESULT (ic), IC_RIGHT (ic->next)))
2933                  accuse = 1;
2934             }
2935
2936           if (accuse)
2937             {
2938               OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2939               continue;
2940             }
2941
2942         }
2943       #endif
2944
2945       /* reduce for support function calls */
2946       if (ic->supportRtn || (ic->op != IFX && ic->op != JUMPTABLE))
2947         packRegsForSupport (ic, ebp);
2948
2949       #if 0
2950       /* some cases the redundant moves can
2951          can be eliminated for return statements */
2952       if ((ic->op == RETURN || (ic->op == SEND && ic->argreg == 1)) &&
2953           /* !isOperandInFarSpace (IC_LEFT (ic)) && */
2954           options.model == MODEL_SMALL) {
2955         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2956       }
2957
2958       /* if pointer set & left has a size more than
2959          one and right is not in far space */
2960       if (POINTER_SET (ic) &&
2961           /* !isOperandInFarSpace (IC_RIGHT (ic)) && */
2962           !OP_SYMBOL (IC_RESULT (ic))->remat &&
2963           !IS_OP_RUONLY (IC_RIGHT (ic))
2964           /* && getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1 */ )
2965         packRegsForOneuse (ic, IC_RESULT (ic), ebp);
2966
2967       /* if pointer get */
2968       if (POINTER_GET (ic) &&
2969           IS_SYMOP (IC_LEFT (ic)) &&
2970           /* !isOperandInFarSpace (IC_RESULT (ic)) && */
2971           !OP_SYMBOL (IC_LEFT (ic))->remat &&
2972           !IS_OP_RUONLY (IC_RESULT (ic))
2973            /* && getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1 */)
2974         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2975
2976
2977       /* if this is cast for intergral promotion then
2978          check if only use of  the definition of the
2979          operand being casted/ if yes then replace
2980          the result of that arithmetic operation with
2981          this result and get rid of the cast */
2982       if (ic->op == CAST)
2983         {
2984           sym_link *fromType = operandType (IC_RIGHT (ic));
2985           sym_link *toType = operandType (IC_LEFT (ic));
2986
2987           if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
2988               getSize (fromType) != getSize (toType) &&
2989               SPEC_USIGN (fromType) == SPEC_USIGN (toType))
2990             {
2991
2992               iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2993               if (dic)
2994                 {
2995                   if (IS_ARITHMETIC_OP (dic))
2996                     {
2997                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2998                       ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
2999                       remiCodeFromeBBlock (ebp, ic);
3000                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3001                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3002                       OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3003                       ic = ic->prev;
3004                     }
3005                   else
3006                     OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3007                 }
3008             }
3009           else
3010             {
3011
3012               /* if the type from and type to are the same
3013                  then if this is the only use then packit */
3014               if (compareType (operandType (IC_RIGHT (ic)),
3015                              operandType (IC_LEFT (ic))) == 1)
3016                 {
3017                   iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3018                   if (dic)
3019                     {
3020                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3021                       ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
3022                       remiCodeFromeBBlock (ebp, ic);
3023                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3024                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3025                       OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3026                       ic = ic->prev;
3027                     }
3028                 }
3029             }
3030         }
3031       #endif
3032
3033       /* pack for PUSH
3034          iTempNN := (some variable in farspace) V1
3035          push iTempNN ;
3036          -------------
3037          push V1
3038        */
3039       if (ic->op == IPUSH)
3040         {
3041           packForPush (ic, ebpp, blockno);
3042         }
3043
3044       packRegsForAccUse (ic);
3045     }
3046 }
3047
3048 /*-----------------------------------------------------------------*/
3049 /* assignRegisters - assigns registers to each live range as need  */
3050 /*-----------------------------------------------------------------*/
3051 void
3052 hc08_assignRegisters (eBBlock ** ebbs, int count)
3053 {
3054   iCode *ic;
3055   int i;
3056
3057   setToNull ((void *) &_G.funcrUsed);
3058   setToNull ((void *) &_G.regAssigned);
3059   setToNull ((void *) &_G.totRegAssigned);
3060   hc08_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3061   hc08_nRegs = 7;
3062   hc08_reg_a = hc08_regWithIdx(A_IDX);
3063   hc08_reg_x = hc08_regWithIdx(X_IDX);
3064   hc08_reg_h = hc08_regWithIdx(H_IDX);
3065   hc08_reg_hx = hc08_regWithIdx(HX_IDX);
3066   hc08_reg_xa = hc08_regWithIdx(XA_IDX);
3067   hc08_reg_sp = hc08_regWithIdx(SP_IDX);
3068   hc08_nRegs = 5;
3069
3070   /* change assignments this will remove some
3071      live ranges reducing some register pressure */
3072   for (i = 0; i < count; i++)
3073     packRegisters (ebbs, i);
3074
3075   /* liveranges probably changed by register packing
3076      so we compute them again */
3077   recomputeLiveRanges (ebbs, count);
3078
3079   if (options.dump_pack)
3080     dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3081
3082   /* first determine for each live range the number of
3083      registers & the type of registers required for each */
3084   regTypeNum (*ebbs);
3085
3086   /* and serially allocate registers */
3087   serialRegAssign (ebbs, count);
3088
3089   freeAllRegs ();
3090   //setToNull ((void *) &_G.regAssigned);
3091   //setToNull ((void *) &_G.totRegAssigned);
3092   fillGaps();
3093
3094   /* if stack was extended then tell the user */
3095   if (_G.stackExtend)
3096     {
3097 /*      werror(W_TOOMANY_SPILS,"stack", */
3098 /*             _G.stackExtend,currFunc->name,""); */
3099       _G.stackExtend = 0;
3100     }
3101
3102   if (_G.dataExtend)
3103     {
3104 /*      werror(W_TOOMANY_SPILS,"data space", */
3105 /*             _G.dataExtend,currFunc->name,""); */
3106       _G.dataExtend = 0;
3107     }
3108
3109   /* after that create the register mask
3110      for each of the instruction */
3111   createRegMask (ebbs, count);
3112
3113   /* redo that offsets for stacked automatic variables */
3114   if (currFunc) {
3115     redoStackOffsets ();
3116   }
3117
3118   if (options.dump_rassgn)
3119     {
3120       dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3121       dumpLiveRanges (DUMP_LRANGE, liveRanges);
3122     }
3123
3124   /* do the overlaysegment stuff SDCCmem.c */
3125   doOverlays (ebbs, count);
3126
3127   /* now get back the chain */
3128   ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3129
3130   genhc08Code (ic);
3131
3132   /* free up any _G.stackSpil locations allocated */
3133   applyToSet (_G.stackSpil, deallocStackSpil);
3134   _G.slocNum = 0;
3135   setToNull ((void **) &_G.stackSpil);
3136   setToNull ((void **) &_G.spiltSet);
3137   /* mark all registers as free */
3138   freeAllRegs ();
3139
3140   return;
3141 }