* src/SDCCpeeph.c (replaceRule): support empty replacement peephole
[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               !IS_BITVAR (sym->etype) &&
1743               (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER))
1744             {
1745
1746               if (ptrPseudoSymSafe (sym, ic))
1747                 {
1748                   ptrPseudoSymConvert (sym, ic, rematStr (OP_SYMBOL (IC_LEFT (ic))));
1749                   continue;
1750                 }
1751
1752               /* if in data space or idata space then try to
1753                  allocate pointer register */
1754
1755             }
1756
1757           /* if not then we require registers */
1758           sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
1759                         getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1760                         getSize (sym->type));
1761
1762           if (sym->nRegs > 4)
1763             {
1764               fprintf (stderr, "allocated more than 4 or 0 registers for type ");
1765               printTypeChain (sym->type, stderr);
1766               fprintf (stderr, "\n");
1767             }
1768
1769           /* determine the type of register required */
1770           if (sym->nRegs == 1 &&
1771               IS_PTR (sym->type) &&
1772               sym->uptr)
1773             sym->regType = REG_PTR;
1774           else
1775             sym->regType = REG_GPR;
1776
1777         }
1778       else
1779         /* for the first run we don't provide */
1780         /* registers for true symbols we will */
1781         /* see how things go                  */
1782         sym->nRegs = 0;
1783           }
1784
1785 }
1786
1787 /*-----------------------------------------------------------------*/
1788 /* freeAllRegs - mark all registers as free                        */
1789 /*-----------------------------------------------------------------*/
1790 static void
1791 freeAllRegs ()
1792 {
1793   int i;
1794
1795   for (i = 0; i < hc08_nRegs; i++) {
1796     regshc08[i].isFree = 1;
1797     regshc08[i].aop = NULL;
1798   }
1799 }
1800
1801 /*-----------------------------------------------------------------*/
1802 /* deallocStackSpil - this will set the stack pointer back         */
1803 /*-----------------------------------------------------------------*/
1804 static
1805 DEFSETFUNC (deallocStackSpil)
1806 {
1807   symbol *sym = item;
1808
1809   deallocLocal (sym);
1810   return 0;
1811 }
1812
1813 #if 0
1814 /*-----------------------------------------------------------------*/
1815 /* farSpacePackable - returns the packable icode for far variables */
1816 /*-----------------------------------------------------------------*/
1817 static iCode *
1818 farSpacePackable (iCode * ic)
1819 {
1820   iCode *dic;
1821
1822   /* go thru till we find a definition for the
1823      symbol on the right */
1824   for (dic = ic->prev; dic; dic = dic->prev)
1825     {
1826       /* if the definition is a call then no */
1827       if ((dic->op == CALL || dic->op == PCALL) &&
1828           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1829         {
1830           return NULL;
1831         }
1832
1833       /* if shift by unknown amount then not */
1834       if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
1835           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1836         return NULL;
1837
1838 #if 0
1839       /* if pointer get and size > 1 */
1840       if (POINTER_GET (dic) &&
1841           getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
1842         return NULL;
1843
1844       if (POINTER_SET (dic) &&
1845           getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
1846         return NULL;
1847 #endif
1848
1849       /* if any three is a true symbol in far space */
1850       if (IC_RESULT (dic) &&
1851           IS_TRUE_SYMOP (IC_RESULT (dic)) /* &&
1852           isOperandInFarSpace (IC_RESULT (dic)) */)
1853         return NULL;
1854
1855       if (IC_RIGHT (dic) &&
1856           IS_TRUE_SYMOP (IC_RIGHT (dic)) /* &&
1857           isOperandInFarSpace (IC_RIGHT (dic)) */ &&
1858           !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
1859         return NULL;
1860
1861       if (IC_LEFT (dic) &&
1862           IS_TRUE_SYMOP (IC_LEFT (dic)) /* &&
1863           isOperandInFarSpace (IC_LEFT (dic)) */ &&
1864           !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
1865         return NULL;
1866
1867       if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
1868         {
1869           if ((dic->op == LEFT_OP ||
1870                dic->op == RIGHT_OP ||
1871                dic->op == '-') &&
1872               IS_OP_LITERAL (IC_RIGHT (dic)))
1873             return NULL;
1874           else
1875             return dic;
1876         }
1877     }
1878
1879   return NULL;
1880 }
1881 #endif
1882
1883 #if 0
1884 static void
1885 packRegsForLiteral (iCode * ic)
1886 {
1887   int k;
1888   iCode *uic;
1889   
1890   if (ic->op != '=')
1891     return;
1892   if (POINTER_SET (ic))
1893     return;
1894   if (!IS_LITERAL (getSpec (operandType (IC_RIGHT (ic)))))
1895     return;
1896   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
1897     return;
1898
1899   for (k=0; k< OP_USES (IC_RESULT (ic))->size; k++)
1900     if (bitVectBitValue (OP_USES (IC_RESULT (ic)), k))
1901       {
1902         uic = hTabItemWithKey (iCodehTab, k);
1903         if (!uic) continue;
1904         
1905         if (uic->op != IFX && uic->op != JUMPTABLE)
1906           {
1907             if (IC_LEFT (uic) && IC_LEFT (uic)->key == IC_RESULT (ic)->key)
1908               ReplaceOpWithCheaperOp(&IC_LEFT(uic), IC_RIGHT(ic));
1909             if (IC_RIGHT (uic) && IC_RIGHT (uic)->key == IC_RESULT (ic)->key)
1910               ReplaceOpWithCheaperOp(&IC_RIGHT(uic), IC_RIGHT(ic));
1911             if (IC_RESULT (uic) && IC_RESULT (uic)->key == IC_RESULT (ic)->key)
1912               ReplaceOpWithCheaperOp(&IC_RESULT(uic), IC_RIGHT(ic));
1913           }
1914       }
1915
1916 }
1917 #endif
1918
1919
1920 /*-----------------------------------------------------------------*/
1921 /* packRegsForAssign - register reduction for assignment           */
1922 /*-----------------------------------------------------------------*/
1923 static int
1924 packRegsForAssign (iCode * ic, eBBlock * ebp)
1925 {
1926   iCode *dic, *sic;
1927
1928   if (!IS_ITEMP (IC_RIGHT (ic)) ||
1929       OP_SYMBOL (IC_RIGHT (ic))->isind ||
1930       OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
1931     {
1932       return 0;
1933     }
1934
1935
1936   /* if the true symbol is defined in far space or on stack
1937      then we should not since this will increase register pressure */
1938 #if 0
1939   if (isOperandInFarSpace(IC_RESULT(ic)) && !farSpacePackable(ic)) {
1940     return 0;
1941   }
1942 #endif
1943
1944   /* find the definition of iTempNN scanning backwards if we find a 
1945      a use of the true symbol in before we find the definition then 
1946      we cannot */
1947   for (dic = ic->prev; dic; dic = dic->prev)
1948     {
1949
1950 #if 0 /* jwk: This collides with 1.43 but I really see no need for
1951          this anymore. It fixes bug #716790 and substantially improves 
1952          redundant register usage around function calls.
1953       */
1954
1955       /* if there is a function call then don't pack it */
1956       if ((dic->op == CALL || dic->op == PCALL))
1957         {
1958           dic = NULL;
1959           break;
1960         }
1961 #endif
1962
1963       if (SKIP_IC2 (dic))
1964         continue;
1965
1966       if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
1967           IS_OP_VOLATILE (IC_RESULT (dic)))
1968         {
1969           dic = NULL;
1970           break;
1971         }
1972
1973       if (IS_SYMOP (IC_RESULT (dic)) &&
1974           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1975         {
1976           if (POINTER_SET (dic))
1977             dic = NULL;
1978
1979           break;
1980         }
1981
1982       if (IS_SYMOP (IC_RIGHT (dic)) &&
1983           (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
1984            IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
1985         {
1986           dic = NULL;
1987           break;
1988         }
1989
1990       if (IS_SYMOP (IC_LEFT (dic)) &&
1991           (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
1992            IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
1993         {
1994           dic = NULL;
1995           break;
1996         }
1997
1998       if (POINTER_SET (dic) &&
1999           IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2000         {
2001           dic = NULL;
2002           break;
2003         }
2004     }
2005
2006   if (!dic)
2007     return 0;                   /* did not find */
2008
2009   /* if assignment then check that right is not a bit */
2010   if (ASSIGNMENT (dic) && !POINTER_SET (dic))
2011     {
2012       sym_link *etype = operandType (IC_RIGHT (dic));
2013       if (IS_BITFIELD (etype))
2014         {
2015           /* if result is a bit too then it's ok */
2016           etype = operandType (IC_RESULT (dic));
2017           if (!IS_BITFIELD (etype))
2018             return 0;
2019         }
2020     }
2021   /* if the result is on stack or iaccess then it must be
2022      the same atleast one of the operands */
2023   if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2024       OP_SYMBOL (IC_RESULT (ic))->iaccess)
2025     {
2026
2027       /* the operation has only one symbol
2028          operator then we can pack */
2029       if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2030           (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2031         goto pack;
2032
2033       if (!((IC_LEFT (dic) &&
2034              IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2035             (IC_RIGHT (dic) &&
2036              IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2037         return 0;
2038     }
2039 pack:
2040   /* found the definition */
2041   /* replace the result with the result of */
2042   /* this assignment and remove this assignment */
2043   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2044   ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
2045
2046   if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2047     {
2048       OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2049     }
2050   // TODO: and the otherway around?
2051
2052   /* delete from liverange table also 
2053      delete from all the points inbetween and the new
2054      one */
2055   for (sic = dic; sic != ic; sic = sic->next)
2056     {
2057       bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2058       if (IS_ITEMP (IC_RESULT (dic)))
2059         bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2060     }
2061
2062   remiCodeFromeBBlock (ebp, ic);
2063   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2064   hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2065   OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2066   return 1;
2067 }
2068
2069
2070 /*------------------------------------------------------------------*/
2071 /* findAssignToSym : scanning backwards looks for first assig found */
2072 /*------------------------------------------------------------------*/
2073 static iCode *
2074 findAssignToSym (operand * op, iCode * ic)
2075 {
2076   iCode *dic;
2077
2078   /* This routine is used to find sequences like
2079      iTempAA = FOO;
2080      ...;  (intervening ops don't use iTempAA or modify FOO)
2081      blah = blah + iTempAA;
2082
2083      and eliminate the use of iTempAA, freeing up its register for
2084      other uses.
2085   */
2086      
2087
2088   for (dic = ic->prev; dic; dic = dic->prev)
2089     {
2090
2091       /* if definition by assignment */
2092       if (dic->op == '=' &&
2093           !POINTER_SET (dic) &&
2094           IC_RESULT (dic)->key == op->key
2095           &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) 
2096         )
2097         break;  /* found where this temp was defined */
2098
2099       /* if we find an usage then we cannot delete it */
2100       if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2101         return NULL;
2102
2103       if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2104         return NULL;
2105
2106       if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2107         return NULL;
2108     }
2109
2110   if (!dic)
2111     return NULL;   /* didn't find any assignment to op */
2112
2113   /* we are interested only if defined in far space */
2114   /* or in stack space in case of + & - */
2115   
2116   /* if assigned to a non-symbol then don't repack regs */
2117   if (!IS_SYMOP (IC_RIGHT (dic)))
2118     return NULL;
2119   
2120   /* if the symbol is volatile then we should not */
2121   if (isOperandVolatile (IC_RIGHT (dic), TRUE))
2122     return NULL;
2123   /* XXX TODO --- should we be passing FALSE to isOperandVolatile()?
2124      What does it mean for an iTemp to be volatile, anyway? Passing
2125      TRUE is more cautious but may prevent possible optimizations */
2126
2127   /* if the symbol is in far space then we should not */
2128   /* if (isOperandInFarSpace (IC_RIGHT (dic)))
2129     return NULL; */
2130   
2131   /* for + & - operations make sure that
2132      if it is on the stack it is the same
2133      as one of the three operands */
2134 #if 0
2135   if ((ic->op == '+' || ic->op == '-') &&
2136       OP_SYMBOL (IC_RIGHT (dic))->onStack)
2137     {
2138       
2139       if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2140           IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2141           IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2142         return NULL;
2143     }
2144 #endif
2145   
2146   /* now make sure that the right side of dic
2147      is not defined between ic & dic */
2148   if (dic)
2149     {
2150       iCode *sic = dic->next;
2151
2152       for (; sic != ic; sic = sic->next)
2153         if (IC_RESULT (sic) &&
2154             IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2155           return NULL;
2156     }
2157
2158   return dic;
2159 }
2160
2161 /*-----------------------------------------------------------------*/
2162 /* reassignAliasedSym - used by packRegsForSupport to replace      */
2163 /*                      redundant iTemp with equivalent symbol     */
2164 /*-----------------------------------------------------------------*/
2165 static void
2166 reassignAliasedSym (eBBlock *ebp, iCode *assignment, iCode *use, operand *op)
2167 {
2168   iCode *ic;
2169   unsigned oldSymKey, newSymKey;
2170
2171   oldSymKey = op->key;
2172   newSymKey = IC_RIGHT(assignment)->key;
2173
2174   /* only track live ranges of compiler-generated temporaries */
2175   if (!IS_ITEMP(IC_RIGHT(assignment)))
2176     newSymKey = 0;
2177
2178   /* update the live-value bitmaps */
2179   for (ic = assignment; ic != use; ic = ic->next) {
2180     bitVectUnSetBit (ic->rlive, oldSymKey);
2181     if (newSymKey != 0)
2182       ic->rlive = bitVectSetBit (ic->rlive, newSymKey);
2183   }
2184
2185   /* update the sym of the used operand */
2186   OP_SYMBOL(op) = OP_SYMBOL(IC_RIGHT(assignment));
2187   op->key = OP_SYMBOL(op)->key;
2188
2189   /* update the sym's liverange */
2190   if ( OP_LIVETO(op) < ic->seq )
2191     setToRange(op, ic->seq, FALSE);
2192
2193   /* remove the assignment iCode now that its result is unused */
2194   remiCodeFromeBBlock (ebp, assignment);
2195   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(assignment))->defs, assignment->key);
2196   hTabDeleteItem (&iCodehTab, assignment->key, assignment, DELETE_ITEM, NULL);
2197 }
2198   
2199
2200 /*-----------------------------------------------------------------*/
2201 /* packRegsForSupport :- reduce some registers for support calls   */
2202 /*-----------------------------------------------------------------*/
2203 static int
2204 packRegsForSupport (iCode * ic, eBBlock * ebp)
2205 {
2206   iCode *dic;
2207   int changes = 0;
2208   
2209   /* for the left & right operand :- look to see if the
2210      left was assigned a true symbol in far space in that
2211      case replace them */
2212
2213   if (IS_ITEMP (IC_LEFT (ic)) &&
2214       OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2215     {
2216       dic = findAssignToSym (IC_LEFT (ic), ic);
2217
2218       if (dic)
2219         {
2220           /* found it we need to remove it from the block */
2221           reassignAliasedSym (ebp, dic, ic, IC_LEFT(ic));
2222           changes++;
2223         }
2224     }
2225
2226   /* do the same for the right operand */
2227   if (IS_ITEMP (IC_RIGHT (ic)) &&
2228       OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2229     {
2230       iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2231
2232       if (dic)
2233         {
2234           /* found it we need to remove it from the block */
2235           reassignAliasedSym (ebp, dic, ic, IC_RIGHT(ic));
2236           changes++;
2237         }
2238     }
2239
2240   return changes;
2241 }
2242
2243 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
2244
2245
2246 #if 0
2247 /*-----------------------------------------------------------------*/
2248 /* packRegsForOneuse : - will reduce some registers for single Use */
2249 /*-----------------------------------------------------------------*/
2250 static iCode *
2251 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
2252 {
2253   bitVect *uses;
2254   iCode *dic, *sic;
2255
2256   /* if returning a literal then do nothing */
2257   if (!IS_SYMOP (op))
2258     return NULL;
2259
2260   /* only up to 2 bytes */
2261   if (getSize (operandType (op)) > (fReturnSizeHC08 - 2))
2262     return NULL;
2263
2264   return NULL;
2265   
2266   if (ic->op != SEND //RETURN
2267       && ic->op != SEND
2268       && !POINTER_SET (ic)
2269       && !POINTER_GET (ic) )
2270     return NULL;
2271   
2272   if (ic->op == SEND && ic->argreg != 1) return NULL;
2273
2274   /* this routine will mark the a symbol as used in one 
2275      instruction use only && if the defintion is local 
2276      (ie. within the basic block) && has only one definition &&
2277      that definiion is either a return value from a 
2278      function or does not contain any variables in
2279      far space */
2280   uses = bitVectCopy (OP_USES (op));
2281   bitVectUnSetBit (uses, ic->key);      /* take away this iCode */
2282   if (!bitVectIsZero (uses))    /* has other uses */
2283     return NULL;
2284
2285   /* if it has only one defintion */
2286   if (bitVectnBitsOn (OP_DEFS (op)) > 1)
2287     return NULL;                /* has more than one definition */
2288
2289   /* get that definition */
2290   if (!(dic =
2291         hTabItemWithKey (iCodehTab,
2292                          bitVectFirstBit (OP_DEFS (op)))))
2293     return NULL;
2294
2295   /* if that only usage is a cast */
2296   if (dic->op == CAST) {
2297     /* to a bigger type */
2298     if (getSize(OP_SYM_TYPE(IC_RESULT(dic))) > 
2299         getSize(OP_SYM_TYPE(IC_RIGHT(dic)))) {
2300       /* than we can not, since we cannot predict the usage of b & acc */
2301       return NULL;
2302     }
2303   }
2304
2305   /* found the definition now check if it is local */
2306   if (dic->seq < ebp->fSeq ||
2307       dic->seq > ebp->lSeq)
2308     return NULL;                /* non-local */
2309
2310   /* now check if it is the return from
2311      a function call */
2312   if (dic->op == CALL || dic->op == PCALL)
2313     {
2314       if (ic->op != SEND && ic->op != RETURN &&
2315           !POINTER_SET(ic) && !POINTER_GET(ic))
2316         {
2317           OP_SYMBOL (op)->ruonly = 1;
2318           return dic;
2319         }
2320       dic = dic->next;
2321     }
2322
2323
2324   /* otherwise check that the definition does
2325      not contain any symbols in far space */
2326 //  if (isOperandInFarSpace (IC_LEFT (dic)) ||
2327 //      isOperandInFarSpace (IC_RIGHT (dic)) ||
2328 //      IS_OP_RUONLY (IC_LEFT (ic)) ||
2329 //      IS_OP_RUONLY (IC_RIGHT (ic)))
2330 //    {
2331 //      return NULL;
2332 //    }
2333
2334   /* if pointer set then make sure the pointer
2335      is one byte */
2336 #if 0
2337   if (POINTER_SET (dic) &&
2338       !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2339     return NULL;
2340
2341   if (POINTER_GET (dic) &&
2342       !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2343     return NULL;
2344 #endif 
2345
2346   sic = dic;
2347
2348   /* also make sure the intervenening instructions
2349      don't have any thing in far space */
2350   for (dic = dic->next; dic && dic != ic && sic != ic; dic = dic->next)
2351     {
2352
2353       /* if there is an intervening function call then no */
2354       if (dic->op == CALL || dic->op == PCALL)
2355         return NULL;
2356       /* if pointer set then make sure the pointer
2357          is one byte */
2358 #if 0
2359       if (POINTER_SET (dic) &&
2360           !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2361         return NULL;
2362
2363       if (POINTER_GET (dic) &&
2364           !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2365         return NULL;
2366 #endif
2367       /* if address of & the result is remat the okay */
2368       if (dic->op == ADDRESS_OF &&
2369           OP_SYMBOL (IC_RESULT (dic))->remat)
2370         continue;
2371
2372       /* if operand has size of three or more & this
2373          operation is a '*','/' or '%' then 'b' may
2374          cause a problem */
2375 #if 0
2376       if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
2377           getSize (operandType (op)) >= 3)
2378         return NULL;
2379 #endif
2380
2381       /* if left or right or result is in far space */
2382 //      if (isOperandInFarSpace (IC_LEFT (dic)) ||
2383 //        isOperandInFarSpace (IC_RIGHT (dic)) ||
2384 //        isOperandInFarSpace (IC_RESULT (dic)) ||
2385 //        IS_OP_RUONLY (IC_LEFT (dic)) ||
2386 //        IS_OP_RUONLY (IC_RIGHT (dic)) ||
2387 //        IS_OP_RUONLY (IC_RESULT (dic)))
2388 //      {
2389 //        return NULL;
2390 //      }
2391 //      /* if left or right or result is on stack */
2392 //     if (isOperandOnStack(IC_LEFT(dic)) ||
2393 //        isOperandOnStack(IC_RIGHT(dic)) ||
2394 //        isOperandOnStack(IC_RESULT(dic))) {
2395 //      return NULL;
2396 //     }
2397     }
2398
2399   OP_SYMBOL (op)->ruonly = 1;
2400   return sic;
2401 }
2402 #endif
2403
2404 /*-----------------------------------------------------------------*/
2405 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
2406 /*-----------------------------------------------------------------*/
2407 static bool
2408 isBitwiseOptimizable (iCode * ic)
2409 {
2410   sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
2411   sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
2412
2413   /* bitwise operations are considered optimizable
2414      under the following conditions (Jean-Louis VERN) 
2415
2416      x & lit
2417      bit & bit
2418      bit & x
2419      bit ^ bit
2420      bit ^ x
2421      x   ^ lit
2422      x   | lit
2423      bit | bit
2424      bit | x
2425   */
2426   if (IS_LITERAL(rtype) ||
2427       (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
2428     return TRUE;
2429   else
2430     return FALSE;
2431 }
2432
2433 /*-----------------------------------------------------------------*/
2434 /* isCommutativeOp - tests whether this op cares what order its    */
2435 /*                   operands are in                               */
2436 /*-----------------------------------------------------------------*/
2437 bool isCommutativeOp2(unsigned int op)
2438 {
2439   if (op == '+' || op == '*' || op == EQ_OP ||
2440       op == '^' || op == '|' || op == BITWISEAND)
2441     return TRUE;
2442   else
2443     return FALSE;
2444 }
2445
2446 /*-----------------------------------------------------------------*/
2447 /* operandUsesAcc2 - determines whether the code generated for this */
2448 /*                  operand will have to use the accumulator       */
2449 /*-----------------------------------------------------------------*/
2450 bool operandUsesAcc2(operand *op)
2451 {
2452   if (!op)
2453     return FALSE;
2454
2455   if (IS_SYMOP(op)) {
2456     symbol *sym = OP_SYMBOL(op);
2457     memmap *symspace;
2458
2459     if (sym->accuse)
2460       return TRUE;  /* duh! */
2461
2462 //    if (IN_STACK(sym->etype) || sym->onStack ||
2463 //      (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
2464 //      return TRUE;  /* acc is used to calc stack offset */
2465
2466     if (IS_ITEMP(op))
2467       {
2468         if (SPIL_LOC(op)) {
2469           sym = SPIL_LOC(op);  /* if spilled, look at spill location */
2470         } else {
2471           return FALSE;  /* more checks? */
2472         }
2473       }
2474
2475     symspace = SPEC_OCLS(sym->etype);
2476
2477 //    if (sym->iaccess && symspace->paged)
2478 //      return TRUE;  /* must fetch paged indirect sym via accumulator */
2479     
2480     if (IN_BITSPACE(symspace))
2481       return TRUE;  /* fetching bit vars uses the accumulator */
2482     
2483     if (IN_FARSPACE(symspace) || IN_CODESPACE(symspace)) 
2484       return TRUE;  /* fetched via accumulator and dptr */
2485   }
2486
2487   return FALSE;
2488 }
2489
2490 /*-----------------------------------------------------------------*/
2491 /* packRegsForAccUse - pack registers for acc use                  */
2492 /*-----------------------------------------------------------------*/
2493 static void
2494 packRegsForAccUse (iCode * ic)
2495 {
2496   iCode *uic;
2497
2498   /* if this is an aggregate, e.g. a one byte char array */
2499   if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
2500     return;
2501   }
2502
2503   /* if we are calling a reentrant function that has stack parameters */
2504   #if 0
2505   if (ic->op == CALL &&
2506        IFFUNC_ISREENT(operandType(IC_LEFT(ic))) &&
2507        FUNC_HASSTACKPARM(operandType(IC_LEFT(ic))))
2508       return;
2509
2510   if (ic->op == PCALL &&
2511        IFFUNC_ISREENT(operandType(IC_LEFT(ic))->next) &&
2512        FUNC_HASSTACKPARM(operandType(IC_LEFT(ic))->next))
2513       return;
2514   #endif
2515
2516   /* if + or - then it has to be one byte result */
2517   if ((ic->op == '+' || ic->op == '-')
2518       && getSize (operandType (IC_RESULT (ic))) > 1)
2519     return;
2520
2521
2522   /* if shift operation make sure right side is a literal */
2523   if (ic->op == RIGHT_OP &&
2524       (!isOperandLiteral (IC_RIGHT (ic)) ||
2525        (getSize (operandType (IC_RESULT (ic) )) > 1)))
2526     return;
2527
2528   if (ic->op == LEFT_OP &&
2529       (!isOperandLiteral (IC_RIGHT (ic)) ||
2530        (getSize (operandType (IC_RESULT (ic) )) > 1)))
2531     return;
2532
2533   if (IS_BITWISE_OP (ic) &&
2534       getSize (operandType (IC_RESULT (ic))) > 1)
2535     return;
2536
2537
2538   /* has only one definition */
2539   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
2540     return;
2541
2542   /* has only one use */
2543   if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
2544     return;
2545
2546   /* and the usage immediately follows this iCode */
2547   if (!(uic = hTabItemWithKey (iCodehTab,
2548                                bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
2549     return;
2550
2551   if (ic->next != uic)
2552     return;
2553
2554   /* if it is a conditional branch then we definitely can */
2555   if (uic->op == IFX)
2556     goto accuse;
2557
2558   if (uic->op == JUMPTABLE)
2559     return;
2560
2561 #if 0
2562   if (POINTER_SET (uic) &&
2563       getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
2564     return;
2565 #endif
2566
2567   /* if the usage is not is an assignment
2568      or an arithmetic / bitwise / shift operation then not */
2569   if (uic->op != '=' &&
2570       !IS_ARITHMETIC_OP (uic) &&
2571       !IS_BITWISE_OP (uic) &&
2572       (uic->op != LEFT_OP) &&
2573       (uic->op != RIGHT_OP) &&
2574       (uic->op != GETHBIT) &&
2575       (uic->op != RETURN) &&
2576       (uic->op != '~') &&
2577       (uic->op != '!'))
2578     return;
2579
2580 #if 0
2581   /* if used in ^ operation then make sure right is not a 
2582      literal (WIML: Why is this?) */
2583   if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
2584     return;
2585
2586   /* if shift operation make sure right side is not a literal */
2587   /* WIML: Why is this? */
2588   if (uic->op == RIGHT_OP &&
2589       (isOperandLiteral (IC_RIGHT (uic)) ||
2590        getSize (operandType (IC_RESULT (uic))) > 1))
2591     return;
2592   if (uic->op == LEFT_OP &&
2593       (isOperandLiteral (IC_RIGHT (uic)) ||
2594        getSize (operandType (IC_RESULT (uic))) > 1))
2595     return;
2596 #endif
2597
2598   /* make sure that the result of this icode is not on the
2599      stack, since acc is used to compute stack offset */
2600 #if 0
2601   if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
2602       OP_SYMBOL (IC_RESULT (uic))->onStack)
2603     return;
2604 #else
2605 //  if (isOperandOnStack(IC_RESULT(uic)))
2606 //    return;
2607 #endif
2608
2609   /* if the usage has only one operand then we can */
2610   if (IC_LEFT (uic) == NULL ||
2611       IC_RIGHT (uic) == NULL)
2612     goto accuse;
2613
2614 #if 0
2615   /* if the other operand uses the accumulator then we cannot */
2616   if ( (IC_LEFT(uic)->key == IC_RESULT(ic)->key &&
2617         operandUsesAcc2(IC_RIGHT(uic))) ||
2618        (IC_RIGHT(uic)->key == IC_RESULT(ic)->key &&
2619         operandUsesAcc2(IC_LEFT(uic))) ) 
2620     return;
2621
2622   /* make sure this is on the left side if not commutative */
2623   /* except for '-', which has been written to be able to
2624      handle reversed operands */
2625   if (!(isCommutativeOp2(ic->op) || ic->op == '-') &&
2626        IC_LEFT (uic)->key != IC_RESULT (ic)->key)
2627     return;
2628 #endif
2629
2630 #if 0
2631   // this is too dangerous and need further restrictions
2632   // see bug #447547
2633
2634   /* if one of them is a literal then we can */
2635   if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
2636       (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
2637     {
2638       OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2639       return;
2640     }
2641 #endif
2642
2643 accuse:
2644
2645   if ((POINTER_GET(uic))
2646       || (ic->op == ADDRESS_OF && uic->op == '+' && IS_OP_LITERAL (IC_RIGHT (uic))))
2647     {
2648       OP_SYMBOL (IC_RESULT (ic))->accuse = ACCUSE_HX;
2649       return;
2650     }
2651   
2652   OP_SYMBOL (IC_RESULT (ic))->accuse = ACCUSE_XA;
2653 }
2654
2655 /*-----------------------------------------------------------------*/
2656 /* packForPush - hueristics to reduce iCode for pushing            */
2657 /*-----------------------------------------------------------------*/
2658 static void
2659 packForPush (iCode * ic, eBBlock ** ebpp, int blockno)
2660 {
2661   iCode *dic, *lic;
2662   bitVect *dbv;
2663   struct eBBlock * ebp=ebpp[blockno];
2664
2665   if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
2666     return;
2667
2668   /* must have only definition & one usage */
2669   if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
2670       bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
2671     return;
2672
2673   /* find the definition */
2674   if (!(dic = hTabItemWithKey (iCodehTab,
2675                                bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
2676     return;
2677
2678   if (dic->op != '=' || POINTER_SET (dic))
2679     return;
2680
2681   if (dic->seq < ebp->fSeq) { // Evelyn did this
2682     int i;
2683     for (i=0; i<blockno; i++) {
2684       if (dic->seq >= ebpp[i]->fSeq && dic->seq <= ebpp[i]->lSeq) {
2685         ebp=ebpp[i];
2686         break;
2687       }
2688     }
2689     wassert (i!=blockno); // no way to recover from here
2690   }
2691
2692   if (IS_SYMOP(IC_RIGHT(dic))) {
2693     /* make sure the right side does not have any definitions
2694        inbetween */
2695     dbv = OP_DEFS(IC_RIGHT(dic));
2696     for (lic = ic; lic && lic != dic ; lic = lic->prev) {
2697       if (bitVectBitValue(dbv,lic->key)) 
2698         return ;
2699     }
2700     /* make sure they have the same type */
2701     if (IS_SPEC(operandType(IC_LEFT(ic))))
2702     {
2703       sym_link *itype=operandType(IC_LEFT(ic));
2704       sym_link *ditype=operandType(IC_RIGHT(dic));
2705       
2706       if (SPEC_USIGN(itype)!=SPEC_USIGN(ditype) ||
2707           SPEC_LONG(itype)!=SPEC_LONG(ditype))
2708         return;
2709     }
2710     /* extend the live range of replaced operand if needed */
2711     if (OP_SYMBOL(IC_RIGHT(dic))->liveTo < ic->seq) {
2712       OP_SYMBOL(IC_RIGHT(dic))->liveTo = ic->seq;
2713     }
2714     bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2715   } 
2716
2717   /* we now we know that it has one & only one def & use
2718      and the that the definition is an assignment */
2719   ReplaceOpWithCheaperOp(&IC_LEFT (ic), IC_RIGHT (dic));
2720   remiCodeFromeBBlock (ebp, dic);
2721   hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2722 }
2723
2724 /*-----------------------------------------------------------------*/
2725 /* packRegisters - does some transformations to reduce register    */
2726 /*                   pressure                                      */
2727 /*-----------------------------------------------------------------*/
2728 static void
2729 packRegisters (eBBlock ** ebpp, int blockno)
2730 {
2731   iCode *ic;
2732   int change = 0;
2733   eBBlock *ebp=ebpp[blockno];
2734
2735   while (1)
2736     {
2737
2738       change = 0;
2739
2740       /* look for assignments of the form */
2741       /* iTempNN = TRueSym (someoperation) SomeOperand */
2742       /*       ....                       */
2743       /* TrueSym := iTempNN:1             */
2744       for (ic = ebp->sch; ic; ic = ic->next)
2745         {
2746           /* find assignment of the form TrueSym := iTempNN:1 */
2747           if (ic->op == '=' && !POINTER_SET (ic) )
2748             change += packRegsForAssign (ic, ebp);
2749         }
2750
2751       if (!change)
2752         break;
2753     }
2754
2755   for (ic = ebp->sch; ic; ic = ic->next)
2756     {
2757       //packRegsForLiteral (ic);
2758       
2759       /* if this is an itemp & result of an address of a true sym 
2760          then mark this as rematerialisable   */
2761       if (ic->op == ADDRESS_OF &&
2762           IS_ITEMP (IC_RESULT (ic)) && 
2763           IS_TRUE_SYMOP (IC_LEFT (ic)) &&
2764           bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2765           !OP_SYMBOL (IC_LEFT (ic))->onStack )
2766         {
2767
2768           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2769           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2770           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2771
2772         }
2773 #if 1
2774       if (ic->op == '=' &&
2775           !POINTER_SET (ic) &&
2776           IS_ITEMP (IC_RESULT (ic)) &&
2777           IS_VALOP (IC_RIGHT (ic)) &&
2778           bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1)
2779         {
2780
2781           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2782           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2783           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2784
2785         }
2786 #endif
2787       /* if straight assignment then carry remat flag if
2788          this is the only definition */
2789       if (ic->op == '=' &&
2790           !POINTER_SET (ic) &&
2791           IS_SYMOP (IC_RIGHT (ic)) &&
2792           OP_SYMBOL (IC_RIGHT (ic))->remat &&
2793           !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode) &&
2794           bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
2795         {
2796
2797           OP_SYMBOL (IC_RESULT (ic))->remat =
2798             OP_SYMBOL (IC_RIGHT (ic))->remat;
2799           OP_SYMBOL (IC_RESULT (ic))->rematiCode =
2800             OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
2801         }
2802
2803       /* if cast to a generic pointer & the pointer being
2804          cast is remat, then we can remat this cast as well */
2805       if (ic->op == CAST && 
2806           IS_SYMOP(IC_RIGHT(ic)) &&
2807           OP_SYMBOL(IC_RIGHT(ic))->remat &&
2808           bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1) {
2809               sym_link *to_type = operandType(IC_LEFT(ic));
2810               sym_link *from_type = operandType(IC_RIGHT(ic));
2811               if (IS_GENPTR(to_type) && IS_PTR(from_type)) {                  
2812                       OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2813                       OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2814                       OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2815               }
2816       }
2817
2818       /* if this is a +/- operation with a rematerizable 
2819          then mark this as rematerializable as well */
2820       if ((ic->op == '+' || ic->op == '-') &&
2821           (IS_SYMOP (IC_LEFT (ic)) &&
2822            IS_ITEMP (IC_RESULT (ic)) &&
2823            IS_OP_LITERAL (IC_RIGHT (ic))) &&
2824            OP_SYMBOL (IC_LEFT (ic))->remat &&
2825           (!IS_SYMOP (IC_RIGHT (ic)) || !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode)) &&
2826            bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1)
2827         {
2828           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2829           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2830           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2831         }
2832
2833       /* mark the pointer usages */
2834       if (POINTER_SET (ic))
2835         OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
2836
2837       if (POINTER_GET (ic) &&
2838           IS_SYMOP(IC_LEFT (ic)))
2839         OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
2840
2841       if (!SKIP_IC2 (ic))
2842         {
2843 #if 0
2844           /* if we are using a symbol on the stack
2845              then we should say hc08_ptrRegReq */
2846           if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
2847             hc08_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
2848                                  OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
2849           else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
2850             hc08_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
2851                               OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
2852           else
2853             {
2854               if (IS_SYMOP (IC_LEFT (ic)))
2855                 hc08_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
2856                                 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
2857               if (IS_SYMOP (IC_RIGHT (ic)))
2858                 hc08_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
2859                                OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
2860               if (IS_SYMOP (IC_RESULT (ic)))
2861                 hc08_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
2862                               OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
2863             }
2864 #endif
2865         }
2866
2867       /* if the condition of an if instruction
2868          is defined in the previous instruction and
2869          this is the only usage then
2870          mark the itemp as a conditional */
2871       if ((IS_CONDITIONAL (ic) ||
2872            (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic))) &&
2873           ic->next && ic->next->op == IFX &&
2874           bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
2875           isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
2876           OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2877         {
2878           OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
2879           continue;
2880         }
2881
2882       /* reduce for support function calls */
2883       if (ic->supportRtn || (ic->op != IFX && ic->op != JUMPTABLE))
2884         packRegsForSupport (ic, ebp);
2885
2886       #if 0
2887       /* some cases the redundant moves can
2888          can be eliminated for return statements */
2889       if ((ic->op == RETURN || (ic->op == SEND && ic->argreg == 1)) &&
2890           /* !isOperandInFarSpace (IC_LEFT (ic)) && */
2891           options.model == MODEL_SMALL) {
2892         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2893       }
2894
2895       /* if pointer set & left has a size more than
2896          one and right is not in far space */
2897       if (POINTER_SET (ic) &&
2898           /* !isOperandInFarSpace (IC_RIGHT (ic)) && */
2899           !OP_SYMBOL (IC_RESULT (ic))->remat &&
2900           !IS_OP_RUONLY (IC_RIGHT (ic)) 
2901           /* && getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1 */ )
2902         packRegsForOneuse (ic, IC_RESULT (ic), ebp);
2903
2904       /* if pointer get */
2905       if (POINTER_GET (ic) &&
2906           IS_SYMOP (IC_LEFT (ic)) &&
2907           /* !isOperandInFarSpace (IC_RESULT (ic)) && */
2908           !OP_SYMBOL (IC_LEFT (ic))->remat &&
2909           !IS_OP_RUONLY (IC_RESULT (ic)) 
2910            /* && getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1 */)
2911         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2912
2913
2914       /* if this is cast for intergral promotion then
2915          check if only use of  the definition of the 
2916          operand being casted/ if yes then replace
2917          the result of that arithmetic operation with 
2918          this result and get rid of the cast */
2919       if (ic->op == CAST)
2920         {
2921           sym_link *fromType = operandType (IC_RIGHT (ic));
2922           sym_link *toType = operandType (IC_LEFT (ic));
2923
2924           if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
2925               getSize (fromType) != getSize (toType) &&
2926               SPEC_USIGN (fromType) == SPEC_USIGN (toType))
2927             {
2928
2929               iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2930               if (dic)
2931                 {
2932                   if (IS_ARITHMETIC_OP (dic))
2933                     {                  
2934                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2935                       ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
2936                       remiCodeFromeBBlock (ebp, ic);
2937                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2938                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2939                       OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2940                       ic = ic->prev;
2941                     }
2942                   else
2943                     OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
2944                 }
2945             }
2946           else
2947             {
2948
2949               /* if the type from and type to are the same
2950                  then if this is the only use then packit */
2951               if (compareType (operandType (IC_RIGHT (ic)),
2952                              operandType (IC_LEFT (ic))) == 1)
2953                 {
2954                   iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2955                   if (dic)
2956                     {
2957                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2958                       ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
2959                       remiCodeFromeBBlock (ebp, ic);
2960                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2961                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2962                       OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2963                       ic = ic->prev;
2964                     }
2965                 }
2966             }
2967         }
2968       #endif
2969       
2970       /* pack for PUSH 
2971          iTempNN := (some variable in farspace) V1
2972          push iTempNN ;
2973          -------------
2974          push V1
2975        */
2976       if (ic->op == IPUSH)
2977         {
2978           packForPush (ic, ebpp, blockno);
2979         }
2980
2981
2982       #if 1
2983       /* pack registers for accumulator use, when the
2984          result of an arithmetic or bit wise operation
2985          has only one use, that use is immediately following
2986          the defintion and the using iCode has only one
2987          operand or has two operands but one is literal &
2988          the result of that operation is not on stack then
2989          we can leave the result of this operation in x:a
2990          combination */
2991       if ((IS_ARITHMETIC_OP (ic)
2992            || IS_CONDITIONAL(ic)
2993            || IS_BITWISE_OP (ic)
2994            || ic->op == '='
2995            || ic->op == '!'
2996            || ic->op == '~'
2997            || ic->op == GETHBIT
2998            || ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == CALL
2999            || (ic->op == ADDRESS_OF && isOperandOnStack (IC_LEFT (ic)))
3000            || ic->op == RECEIVE
3001           ) &&
3002           IS_ITEMP (IC_RESULT (ic)) &&
3003           getSize (operandType (IC_RESULT (ic))) <= 1)
3004
3005         packRegsForAccUse (ic);
3006       #endif
3007     }
3008 }
3009
3010 /*-----------------------------------------------------------------*/
3011 /* assignRegisters - assigns registers to each live range as need  */
3012 /*-----------------------------------------------------------------*/
3013 void
3014 hc08_assignRegisters (eBBlock ** ebbs, int count)
3015 {
3016   iCode *ic;
3017   int i;
3018
3019   setToNull ((void *) &_G.funcrUsed);
3020   setToNull ((void *) &_G.regAssigned);
3021   setToNull ((void *) &_G.totRegAssigned);
3022   hc08_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3023   hc08_nRegs = 5;
3024   hc08_reg_a = hc08_regWithIdx(A_IDX);
3025   hc08_reg_x = hc08_regWithIdx(X_IDX);
3026   hc08_reg_h = hc08_regWithIdx(H_IDX);
3027   hc08_reg_hx = hc08_regWithIdx(HX_IDX);
3028   hc08_reg_xa = hc08_regWithIdx(XA_IDX);
3029
3030   /* change assignments this will remove some
3031      live ranges reducing some register pressure */
3032   for (i = 0; i < count; i++)
3033     packRegisters (ebbs, i);
3034
3035   /* liveranges probably changed by register packing
3036      so we compute them again */
3037   recomputeLiveRanges (ebbs, count);
3038   
3039   if (options.dump_pack)
3040     dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3041
3042   /* first determine for each live range the number of 
3043      registers & the type of registers required for each */
3044   regTypeNum (*ebbs);
3045
3046   /* and serially allocate registers */
3047   serialRegAssign (ebbs, count);
3048
3049   freeAllRegs ();
3050   //setToNull ((void *) &_G.regAssigned);
3051   //setToNull ((void *) &_G.totRegAssigned);
3052   fillGaps();
3053
3054   /* if stack was extended then tell the user */
3055   if (_G.stackExtend)
3056     {
3057 /*      werror(W_TOOMANY_SPILS,"stack", */
3058 /*             _G.stackExtend,currFunc->name,""); */
3059       _G.stackExtend = 0;
3060     }
3061
3062   if (_G.dataExtend)
3063     {
3064 /*      werror(W_TOOMANY_SPILS,"data space", */
3065 /*             _G.dataExtend,currFunc->name,""); */
3066       _G.dataExtend = 0;
3067     }
3068
3069   /* after that create the register mask
3070      for each of the instruction */
3071   createRegMask (ebbs, count);
3072
3073   /* redo that offsets for stacked automatic variables */
3074   if (currFunc) {
3075     redoStackOffsets ();
3076   }
3077
3078   if (options.dump_rassgn)
3079     {
3080       dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3081       dumpLiveRanges (DUMP_LRANGE, liveRanges);
3082     }
3083
3084   /* do the overlaysegment stuff SDCCmem.c */
3085   doOverlays (ebbs, count);
3086
3087   /* now get back the chain */
3088   ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3089
3090   genhc08Code (ic);
3091
3092   /* free up any _G.stackSpil locations allocated */
3093   applyToSet (_G.stackSpil, deallocStackSpil);
3094   _G.slocNum = 0;
3095   setToNull ((void **) &_G.stackSpil);
3096   setToNull ((void **) &_G.spiltSet);
3097   /* mark all registers as free */
3098   freeAllRegs ();
3099
3100   return;
3101 }