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