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