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