* as/hc08/asm.h,
[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 /* serialRegAssign - serially allocate registers to the variables  */
1174 /*-----------------------------------------------------------------*/
1175 static void
1176 serialRegAssign (eBBlock ** ebbs, int count)
1177 {
1178     int i;
1179
1180     /* for all blocks */
1181     for (i = 0; i < count; i++) {
1182
1183         iCode *ic;
1184
1185         if (ebbs[i]->noPath &&
1186             (ebbs[i]->entryLabel != entryLabel &&
1187              ebbs[i]->entryLabel != returnLabel))
1188             continue;
1189
1190         /* of all instructions do */
1191         for (ic = ebbs[i]->sch; ic; ic = ic->next) {
1192 #if 1
1193             int reg;
1194
1195             // update the registers in use at the start of this icode
1196             for (reg=0; reg<hc08_nRegs; reg++) {
1197               if (regshc08[reg].isFree) {
1198                 ic->riu &= ~(regshc08[reg].mask);
1199               } else {
1200                 ic->riu |= (regshc08[reg].mask);
1201               }
1202             }
1203 #endif
1204
1205             /* if this is an ipop that means some live
1206                range will have to be assigned again */
1207             if (ic->op == IPOP)
1208                 reassignLR (IC_LEFT (ic));
1209
1210             /* if result is present && is a true symbol */
1211             if (IC_RESULT (ic) && ic->op != IFX &&
1212                 IS_TRUE_SYMOP (IC_RESULT (ic)))
1213                 OP_SYMBOL (IC_RESULT (ic))->allocreq++;
1214
1215             /* take away registers from live
1216                ranges that end at this instruction */
1217             deassignLRs (ic, ebbs[i]);
1218
1219             /* some don't need registers */
1220             if (SKIP_IC2 (ic) ||
1221                 ic->op == JUMPTABLE ||
1222                 ic->op == IFX ||
1223                 ic->op == IPUSH ||
1224                 ic->op == IPOP ||
1225                 (IC_RESULT (ic) && POINTER_SET (ic)))
1226                 continue;
1227
1228             /* now we need to allocate registers
1229                only for the result */
1230             if (IC_RESULT (ic)) {
1231                 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
1232                 bitVect *spillable;
1233                 int willCS;
1234                 int j;
1235                 int ptrRegSet = 0;
1236
1237                 /* if it does not need or is spilt 
1238                    or is already assigned to registers
1239                    or will not live beyond this instructions */
1240                 if (!sym->nRegs ||
1241                     sym->isspilt ||
1242                     bitVectBitValue (_G.regAssigned, sym->key) ||
1243                     sym->liveTo <= ic->seq)
1244                     continue;
1245
1246                 /* if some liverange has been spilt at the block level
1247                    and this one live beyond this block then spil this
1248                    to be safe */
1249                 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq) {
1250                     spillThis (sym);
1251                     continue;
1252                 }
1253                 /* if trying to allocate this will cause
1254                    a spill and there is nothing to spill 
1255                    or this one is rematerializable then
1256                    spill this one */
1257                 willCS = willCauseSpill (sym->nRegs, sym->regType);
1258                 spillable = computeSpillable (ic);
1259                 if (sym->remat || (willCS && bitVectIsZero (spillable))) {                    
1260                     spillThis (sym);
1261                     continue;                 
1262                 }
1263
1264                 /* if it has a spillocation & is used less than
1265                    all other live ranges then spill this */
1266                 if (willCS) {
1267                     if (sym->usl.spillLoc) {
1268                         symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
1269                                                                          allLRs, ebbs[i], ic));
1270                         if (leastUsed && leastUsed->used > sym->used) {
1271                             spillThis (sym);
1272                             continue;
1273                         }
1274                     } else {
1275                         /* if none of the liveRanges have a spillLocation then better
1276                            to spill this one than anything else already assigned to registers */
1277                         if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
1278                             /* if this is local to this block then we might find a block spil */
1279                             if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
1280                                 spillThis (sym);
1281                                 continue;
1282                             }
1283                         }
1284                     }
1285                 }
1286                 /* if we need ptr regs for the right side
1287                    then mark it */
1288                 if (POINTER_GET (ic) && IS_SYMOP (IC_LEFT (ic))
1289                     && getSize (OP_SYMBOL (IC_LEFT (ic))->type) <= (unsigned int) PTRSIZE) {
1290                     hc08_ptrRegReq++;
1291                     ptrRegSet = 1;
1292                 }
1293                 /* else we assign registers to it */
1294                 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1295                 _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key);
1296
1297                 for (j = 0; j < sym->nRegs; j++) {
1298                     if (sym->regType == REG_PTR)
1299                         sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
1300                     else
1301                         sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
1302
1303                     /* if the allocation failed which means
1304                        this was spilt then break */
1305                     if (!sym->regs[j]) {
1306                       break;
1307                     }
1308                 }
1309
1310                 /* if it shares registers with operands make sure
1311                    that they are in the same position */
1312                 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
1313                     OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=') {
1314                     positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1315                                   OP_SYMBOL (IC_LEFT (ic)));
1316                 }
1317                 /* do the same for the right operand */
1318                 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
1319                     OP_SYMBOL (IC_RIGHT (ic))->nRegs) {
1320                     positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1321                                   OP_SYMBOL (IC_RIGHT (ic)));
1322                 }
1323
1324                 if (ptrRegSet) {
1325                     hc08_ptrRegReq--;
1326                     ptrRegSet = 0;
1327                 }
1328
1329             }
1330         }
1331     }
1332 }
1333
1334 /*-----------------------------------------------------------------*/
1335 /* fillGaps - Try to fill in the Gaps left by Pass1                */
1336 /*-----------------------------------------------------------------*/
1337 static void fillGaps()
1338 {
1339     symbol *sym =NULL;
1340     int key =0;    
1341     
1342     if (getenv("DISABLE_FILL_GAPS")) return;
1343     
1344     /* look for livernages that was spilt by the allocator */
1345     for (sym = hTabFirstItem(liveRanges,&key) ; sym ; 
1346          sym = hTabNextItem(liveRanges,&key)) {
1347
1348         int i;
1349         int pdone = 0;
1350
1351         if (!sym->spillA || !sym->clashes || sym->remat) continue ;
1352
1353         /* find the liveRanges this one clashes with, that are
1354            still assigned to registers & mark the registers as used*/
1355         for ( i = 0 ; i < sym->clashes->size ; i ++) {
1356             int k;
1357             symbol *clr;
1358
1359             if (bitVectBitValue(sym->clashes,i) == 0 ||    /* those that clash with this */
1360                 bitVectBitValue(_G.totRegAssigned,i) == 0) /* and are still assigned to registers */
1361                 continue ;
1362
1363                 clr = hTabItemWithKey(liveRanges,i);
1364             assert(clr);
1365          
1366             /* mark these registers as used */
1367             for (k = 0 ; k < clr->nRegs ; k++ ) 
1368                 hc08_useReg(clr->regs[k]);
1369         }
1370
1371         if (willCauseSpill(sym->nRegs,sym->regType)) {
1372             /* NOPE :( clear all registers & and continue */
1373             freeAllRegs();
1374             continue ;
1375         }
1376
1377         /* THERE IS HOPE !!!! */
1378         for (i=0; i < sym->nRegs ; i++ ) {
1379             if (sym->regType == REG_PTR)
1380                 sym->regs[i] = getRegPtrNoSpil ();
1381             else
1382                 sym->regs[i] = getRegGprNoSpil ();                
1383         }
1384
1385         /* for all its definitions check if the registers
1386            allocated needs positioning NOTE: we can position
1387            only ONCE if more than One positioning required 
1388            then give up */
1389         sym->isspilt = 0;
1390         for (i = 0 ; i < sym->defs->size ; i++ ) {
1391             if (bitVectBitValue(sym->defs,i)) {
1392                 iCode *ic;
1393                 if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
1394                 if (SKIP_IC(ic)) continue;
1395                 assert(isSymbolEqual(sym,OP_SYMBOL(IC_RESULT(ic)))); /* just making sure */
1396                 /* if left is assigned to registers */
1397                 if (IS_SYMOP(IC_LEFT(ic)) && 
1398                     bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_LEFT(ic))->key)) {
1399                     pdone += positionRegs(sym,OP_SYMBOL(IC_LEFT(ic)));
1400                 }
1401                 if (IS_SYMOP(IC_RIGHT(ic)) && 
1402                     bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RIGHT(ic))->key)) {
1403                     pdone += positionRegs(sym,OP_SYMBOL(IC_RIGHT(ic)));
1404                 }
1405                 if (pdone > 1) break;
1406             }
1407         }
1408         for (i = 0 ; i < sym->uses->size ; i++ ) {
1409             if (bitVectBitValue(sym->uses,i)) {
1410                 iCode *ic;
1411                 if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
1412                 if (SKIP_IC(ic)) continue;
1413                 if (!IS_ASSIGN_ICODE(ic)) continue ;
1414
1415                 /* if result is assigned to registers */
1416                 if (IS_SYMOP(IC_RESULT(ic)) && 
1417                     bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RESULT(ic))->key)) {
1418                     pdone += positionRegs(sym,OP_SYMBOL(IC_RESULT(ic)));
1419                 }
1420                 if (pdone > 1) break;
1421             }
1422         }
1423         /* had to position more than once GIVE UP */
1424         if (pdone > 1) {
1425             /* UNDO all the changes we made to try this */
1426             sym->isspilt = 1;
1427             for (i=0; i < sym->nRegs ; i++ ) {
1428                     sym->regs[i] = NULL;
1429             }
1430             freeAllRegs();
1431             D(printf ("Fill Gap gave up due to positioning for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN"));
1432             continue ;      
1433         }
1434         D(printf ("FILLED GAP for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN"));
1435         _G.totRegAssigned = bitVectSetBit(_G.totRegAssigned,sym->key);
1436         sym->isspilt = sym->spillA = 0 ;
1437         sym->usl.spillLoc->allocreq--;
1438         freeAllRegs();
1439     }
1440 }
1441
1442 /*-----------------------------------------------------------------*/
1443 /* rUmaskForOp :- returns register mask for an operand             */
1444 /*-----------------------------------------------------------------*/
1445 bitVect *
1446 hc08_rUmaskForOp (operand * op)
1447 {
1448   bitVect *rumask;
1449   symbol *sym;
1450   int j;
1451
1452   /* only temporaries are assigned registers */
1453   if (!IS_ITEMP (op))
1454     return NULL;
1455
1456   sym = OP_SYMBOL (op);
1457
1458   /* if spilt or no registers assigned to it
1459      then nothing */
1460   if (sym->isspilt || !sym->nRegs)
1461     return NULL;
1462
1463   rumask = newBitVect (hc08_nRegs);
1464
1465   for (j = 0; j < sym->nRegs; j++)
1466     {
1467       rumask = bitVectSetBit (rumask,
1468                               sym->regs[j]->rIdx);
1469     }
1470
1471   return rumask;
1472 }
1473
1474 /*-----------------------------------------------------------------*/
1475 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
1476 /*-----------------------------------------------------------------*/
1477 static bitVect *
1478 regsUsedIniCode (iCode * ic)
1479 {
1480   bitVect *rmask = newBitVect (hc08_nRegs);
1481
1482   /* do the special cases first */
1483   if (ic->op == IFX)
1484     {
1485       rmask = bitVectUnion (rmask,
1486                             hc08_rUmaskForOp (IC_COND (ic)));
1487       goto ret;
1488     }
1489
1490   /* for the jumptable */
1491   if (ic->op == JUMPTABLE)
1492     {
1493       rmask = bitVectUnion (rmask,
1494                             hc08_rUmaskForOp (IC_JTCOND (ic)));
1495
1496       goto ret;
1497     }
1498
1499   /* of all other cases */
1500   if (IC_LEFT (ic))
1501     rmask = bitVectUnion (rmask,
1502                           hc08_rUmaskForOp (IC_LEFT (ic)));
1503
1504
1505   if (IC_RIGHT (ic))
1506     rmask = bitVectUnion (rmask,
1507                           hc08_rUmaskForOp (IC_RIGHT (ic)));
1508
1509   if (IC_RESULT (ic))
1510     rmask = bitVectUnion (rmask,
1511                           hc08_rUmaskForOp (IC_RESULT (ic)));
1512
1513 ret:
1514   return rmask;
1515 }
1516
1517 /*-----------------------------------------------------------------*/
1518 /* createRegMask - for each instruction will determine the regsUsed */
1519 /*-----------------------------------------------------------------*/
1520 static void
1521 createRegMask (eBBlock ** ebbs, int count)
1522 {
1523   int i;
1524
1525   /* for all blocks */
1526   for (i = 0; i < count; i++)
1527     {
1528       iCode *ic;
1529
1530       if (ebbs[i]->noPath &&
1531           (ebbs[i]->entryLabel != entryLabel &&
1532            ebbs[i]->entryLabel != returnLabel))
1533         continue;
1534
1535       /* for all instructions */
1536       for (ic = ebbs[i]->sch; ic; ic = ic->next)
1537         {
1538
1539           int j;
1540
1541           if (SKIP_IC2 (ic) || !ic->rlive)
1542             continue;
1543
1544           /* first mark the registers used in this
1545              instruction */
1546           ic->rUsed = regsUsedIniCode (ic);
1547           _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
1548
1549           /* now create the register mask for those 
1550              registers that are in use : this is a
1551              super set of ic->rUsed */
1552           ic->rMask = newBitVect (hc08_nRegs + 1);
1553
1554           /* for all live Ranges alive at this point */
1555           for (j = 1; j < ic->rlive->size; j++)
1556             {
1557               symbol *sym;
1558               int k;
1559
1560               /* if not alive then continue */
1561               if (!bitVectBitValue (ic->rlive, j))
1562                 continue;
1563
1564               /* find the live range we are interested in */
1565               if (!(sym = hTabItemWithKey (liveRanges, j)))
1566                 {
1567                   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1568                           "createRegMask cannot find live range");
1569                   fprintf(stderr, "\tmissing live range: key=%d\n", j);
1570                   exit (0);
1571                 }
1572
1573               /* if no register assigned to it */
1574               if (!sym->nRegs || sym->isspilt)
1575                 continue;
1576
1577               /* for all the registers allocated to it */
1578               for (k = 0; k < sym->nRegs; k++)
1579                 if (sym->regs[k])
1580                   ic->rMask =
1581                     bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
1582             }
1583         }
1584     }
1585 }
1586
1587 /*-----------------------------------------------------------------*/
1588 /* rematStr - returns the rematerialized string for a remat var    */
1589 /*-----------------------------------------------------------------*/
1590 static char *
1591 rematStr (symbol * sym)
1592 {
1593   char *s = buffer;
1594   iCode *ic = sym->rematiCode;
1595 //  int offset = 0;
1596   
1597   while (1)
1598     {
1599
1600       /* if plus or minus print the right hand side */
1601       if (ic->op == '+' || ic->op == '-')
1602         {
1603           sprintf (s, "0x%04x %c ", (int) operandLitValue (IC_RIGHT (ic)),
1604                    ic->op);
1605           s += strlen (s);
1606           ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1607           continue;
1608         }
1609 /*      
1610       if (ic->op == '+')
1611         {
1612           offset += operandLitValue (IC_RIGHT (ic));
1613           ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1614           continue;
1615         }
1616       if (ic->op == '-')
1617         {
1618           offset -= operandLitValue (IC_RIGHT (ic));
1619           ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1620           continue;
1621         }
1622 */
1623       /* cast then continue */
1624       if (IS_CAST_ICODE(ic)) {
1625           ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
1626           continue;
1627       }
1628       /* we reached the end */
1629       sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
1630       break;
1631     }
1632
1633   return buffer;
1634 }
1635
1636 /*-----------------------------------------------------------------*/
1637 /* regTypeNum - computes the type & number of registers required   */
1638 /*-----------------------------------------------------------------*/
1639 static void
1640 regTypeNum (eBBlock *ebbs)
1641 {
1642   symbol *sym;
1643   int k;
1644   iCode *ic;
1645
1646   /* for each live range do */
1647   for (sym = hTabFirstItem (liveRanges, &k); sym;
1648        sym = hTabNextItem (liveRanges, &k))
1649     {
1650
1651       /* if used zero times then no registers needed */
1652       if ((sym->liveTo - sym->liveFrom) == 0)
1653         continue;
1654
1655
1656       /* if the live range is a temporary */
1657       if (sym->isitmp)
1658         {
1659
1660           /* if the type is marked as a conditional */
1661           if (sym->regType == REG_CND)
1662             continue;
1663
1664           /* if used in return only then we don't 
1665              need registers */
1666           if (sym->ruonly || sym->accuse)
1667             {
1668               if (IS_AGGREGATE (sym->type) || sym->isptr)
1669                 sym->type = aggrToPtr (sym->type, FALSE);
1670               continue;
1671             }
1672
1673           /* if the symbol has only one definition &
1674              that definition is a get_pointer */
1675           if (bitVectnBitsOn (sym->defs) == 1 &&
1676               (ic = hTabItemWithKey (iCodehTab,
1677                                      bitVectFirstBit (sym->defs))) &&
1678               POINTER_GET (ic) &&
1679               !sym->noSpilLoc &&
1680               !IS_BITVAR (sym->etype))
1681             {
1682
1683
1684               /* and that pointer is remat in data space */
1685               if (IS_SYMOP (IC_LEFT (ic)) &&
1686                   OP_SYMBOL (IC_LEFT (ic))->remat &&
1687                   !IS_CAST_ICODE(OP_SYMBOL (IC_LEFT (ic))->rematiCode) &&
1688                   DCL_TYPE (aggrToPtr (operandType(IC_LEFT(ic)), FALSE)) == POINTER)
1689                 {
1690                   /* create a psuedo symbol & force a spil */
1691                   symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
1692                   psym->type = sym->type;
1693                   psym->etype = sym->etype;
1694                   strcpy (psym->rname, psym->name);
1695                   sym->isspilt = 1;
1696                   sym->usl.spillLoc = psym;
1697 #if 0 // an alternative fix for bug #480076
1698                   /* now this is a useless assignment to itself */
1699                   remiCodeFromeBBlock (ebbs, ic);
1700 #else
1701                   /* now this really is an assignment to itself, make it so;
1702                      it will be optimized out later */
1703                   ic->op='=';
1704                   ReplaceOpWithCheaperOp(&IC_RIGHT(ic), IC_RESULT(ic));
1705                   IC_LEFT(ic)=NULL;
1706 #endif
1707                   continue;
1708                 }
1709
1710               /* if in data space or idata space then try to
1711                  allocate pointer register */
1712
1713             }
1714
1715           /* if not then we require registers */
1716           sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
1717                         getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1718                         getSize (sym->type));
1719
1720           if (sym->nRegs > 4)
1721             {
1722               fprintf (stderr, "allocated more than 4 or 0 registers for type ");
1723               printTypeChain (sym->type, stderr);
1724               fprintf (stderr, "\n");
1725             }
1726
1727           /* determine the type of register required */
1728           if (sym->nRegs == 1 &&
1729               IS_PTR (sym->type) &&
1730               sym->uptr)
1731             sym->regType = REG_PTR;
1732           else
1733             sym->regType = REG_GPR;
1734
1735         }
1736       else
1737         /* for the first run we don't provide */
1738         /* registers for true symbols we will */
1739         /* see how things go                  */
1740         sym->nRegs = 0;
1741           }
1742
1743 }
1744
1745 /*-----------------------------------------------------------------*/
1746 /* freeAllRegs - mark all registers as free                        */
1747 /*-----------------------------------------------------------------*/
1748 static void
1749 freeAllRegs ()
1750 {
1751   int i;
1752
1753   for (i = 0; i < hc08_nRegs; i++) {
1754     regshc08[i].isFree = 1;
1755     regshc08[i].aop = NULL;
1756   }
1757 }
1758
1759 /*-----------------------------------------------------------------*/
1760 /* deallocStackSpil - this will set the stack pointer back         */
1761 /*-----------------------------------------------------------------*/
1762 static
1763 DEFSETFUNC (deallocStackSpil)
1764 {
1765   symbol *sym = item;
1766
1767   deallocLocal (sym);
1768   return 0;
1769 }
1770
1771 #if 0
1772 /*-----------------------------------------------------------------*/
1773 /* farSpacePackable - returns the packable icode for far variables */
1774 /*-----------------------------------------------------------------*/
1775 static iCode *
1776 farSpacePackable (iCode * ic)
1777 {
1778   iCode *dic;
1779
1780   /* go thru till we find a definition for the
1781      symbol on the right */
1782   for (dic = ic->prev; dic; dic = dic->prev)
1783     {
1784       /* if the definition is a call then no */
1785       if ((dic->op == CALL || dic->op == PCALL) &&
1786           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1787         {
1788           return NULL;
1789         }
1790
1791       /* if shift by unknown amount then not */
1792       if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
1793           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1794         return NULL;
1795
1796 #if 0
1797       /* if pointer get and size > 1 */
1798       if (POINTER_GET (dic) &&
1799           getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
1800         return NULL;
1801
1802       if (POINTER_SET (dic) &&
1803           getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
1804         return NULL;
1805 #endif
1806
1807       /* if any three is a true symbol in far space */
1808       if (IC_RESULT (dic) &&
1809           IS_TRUE_SYMOP (IC_RESULT (dic)) /* &&
1810           isOperandInFarSpace (IC_RESULT (dic)) */)
1811         return NULL;
1812
1813       if (IC_RIGHT (dic) &&
1814           IS_TRUE_SYMOP (IC_RIGHT (dic)) /* &&
1815           isOperandInFarSpace (IC_RIGHT (dic)) */ &&
1816           !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
1817         return NULL;
1818
1819       if (IC_LEFT (dic) &&
1820           IS_TRUE_SYMOP (IC_LEFT (dic)) /* &&
1821           isOperandInFarSpace (IC_LEFT (dic)) */ &&
1822           !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
1823         return NULL;
1824
1825       if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
1826         {
1827           if ((dic->op == LEFT_OP ||
1828                dic->op == RIGHT_OP ||
1829                dic->op == '-') &&
1830               IS_OP_LITERAL (IC_RIGHT (dic)))
1831             return NULL;
1832           else
1833             return dic;
1834         }
1835     }
1836
1837   return NULL;
1838 }
1839 #endif
1840
1841 /*-----------------------------------------------------------------*/
1842 /* packRegsForAssign - register reduction for assignment           */
1843 /*-----------------------------------------------------------------*/
1844 static int
1845 packRegsForAssign (iCode * ic, eBBlock * ebp)
1846 {
1847   iCode *dic, *sic;
1848
1849   if (!IS_ITEMP (IC_RIGHT (ic)) ||
1850       OP_SYMBOL (IC_RIGHT (ic))->isind ||
1851       OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
1852     {
1853       return 0;
1854     }
1855
1856
1857   /* if the true symbol is defined in far space or on stack
1858      then we should not since this will increase register pressure */
1859 #if 0
1860   if (isOperandInFarSpace(IC_RESULT(ic)) && !farSpacePackable(ic)) {
1861     return 0;
1862   }
1863 #endif
1864
1865   /* find the definition of iTempNN scanning backwards if we find a 
1866      a use of the true symbol in before we find the definition then 
1867      we cannot */
1868   for (dic = ic->prev; dic; dic = dic->prev)
1869     {
1870
1871 #if 0 /* jwk: This collides with 1.43 but I really see no need for
1872          this anymore. It fixes bug #716790 and substantially improves 
1873          redundant register usage around function calls.
1874       */
1875
1876       /* if there is a function call then don't pack it */
1877       if ((dic->op == CALL || dic->op == PCALL))
1878         {
1879           dic = NULL;
1880           break;
1881         }
1882 #endif
1883
1884       if (SKIP_IC2 (dic))
1885         continue;
1886
1887       if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
1888           IS_OP_VOLATILE (IC_RESULT (dic)))
1889         {
1890           dic = NULL;
1891           break;
1892         }
1893
1894       if (IS_SYMOP (IC_RESULT (dic)) &&
1895           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1896         {
1897           if (POINTER_SET (dic))
1898             dic = NULL;
1899
1900           break;
1901         }
1902
1903       if (IS_SYMOP (IC_RIGHT (dic)) &&
1904           (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
1905            IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
1906         {
1907           dic = NULL;
1908           break;
1909         }
1910
1911       if (IS_SYMOP (IC_LEFT (dic)) &&
1912           (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
1913            IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
1914         {
1915           dic = NULL;
1916           break;
1917         }
1918
1919       if (POINTER_SET (dic) &&
1920           IC_RESULT (dic)->key == IC_RESULT (ic)->key)
1921         {
1922           dic = NULL;
1923           break;
1924         }
1925     }
1926
1927   if (!dic)
1928     return 0;                   /* did not find */
1929
1930   /* if assignment then check that right is not a bit */
1931   if (ASSIGNMENT (dic) && !POINTER_SET (dic))
1932     {
1933       sym_link *etype = operandType (IC_RIGHT (dic));
1934       if (IS_BITFIELD (etype))
1935         {
1936           /* if result is a bit too then it's ok */
1937           etype = operandType (IC_RESULT (dic));
1938           if (!IS_BITFIELD (etype))
1939             return 0;
1940         }
1941     }
1942   /* if the result is on stack or iaccess then it must be
1943      the same atleast one of the operands */
1944   if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
1945       OP_SYMBOL (IC_RESULT (ic))->iaccess)
1946     {
1947
1948       /* the operation has only one symbol
1949          operator then we can pack */
1950       if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
1951           (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
1952         goto pack;
1953
1954       if (!((IC_LEFT (dic) &&
1955              IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
1956             (IC_RIGHT (dic) &&
1957              IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
1958         return 0;
1959     }
1960 pack:
1961   /* found the definition */
1962   /* replace the result with the result of */
1963   /* this assignment and remove this assignment */
1964   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1965   ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
1966
1967   if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
1968     {
1969       OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
1970     }
1971   // TODO: and the otherway around?
1972
1973   /* delete from liverange table also 
1974      delete from all the points inbetween and the new
1975      one */
1976   for (sic = dic; sic != ic; sic = sic->next)
1977     {
1978       bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
1979       if (IS_ITEMP (IC_RESULT (dic)))
1980         bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
1981     }
1982
1983   remiCodeFromeBBlock (ebp, ic);
1984   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
1985   hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
1986   OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
1987   return 1;
1988 }
1989
1990 /*------------------------------------------------------------------*/
1991 /* findAssignToSym : scanning backwards looks for first assig found */
1992 /*------------------------------------------------------------------*/
1993 static iCode *
1994 findAssignToSym (operand * op, iCode * ic)
1995 {
1996   iCode *dic;
1997
1998   /* This routine is used to find sequences like
1999      iTempAA = FOO;
2000      ...;  (intervening ops don't use iTempAA or modify FOO)
2001      blah = blah + iTempAA;
2002
2003      and eliminate the use of iTempAA, freeing up its register for
2004      other uses.
2005   */
2006      
2007
2008   for (dic = ic->prev; dic; dic = dic->prev)
2009     {
2010
2011       /* if definition by assignment */
2012       if (dic->op == '=' &&
2013           !POINTER_SET (dic) &&
2014           IC_RESULT (dic)->key == op->key
2015           &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) 
2016         )
2017         break;  /* found where this temp was defined */
2018
2019       /* if we find an usage then we cannot delete it */
2020       if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2021         return NULL;
2022
2023       if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2024         return NULL;
2025
2026       if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2027         return NULL;
2028     }
2029
2030   if (!dic)
2031     return NULL;   /* didn't find any assignment to op */
2032
2033   /* we are interested only if defined in far space */
2034   /* or in stack space in case of + & - */
2035   
2036   /* if assigned to a non-symbol then don't repack regs */
2037   if (!IS_SYMOP (IC_RIGHT (dic)))
2038     return NULL;
2039   
2040   /* if the symbol is volatile then we should not */
2041   if (isOperandVolatile (IC_RIGHT (dic), TRUE))
2042     return NULL;
2043   /* XXX TODO --- should we be passing FALSE to isOperandVolatile()?
2044      What does it mean for an iTemp to be volatile, anyway? Passing
2045      TRUE is more cautious but may prevent possible optimizations */
2046
2047   /* if the symbol is in far space then we should not */
2048   /* if (isOperandInFarSpace (IC_RIGHT (dic)))
2049     return NULL; */
2050   
2051   /* for + & - operations make sure that
2052      if it is on the stack it is the same
2053      as one of the three operands */
2054 #if 0
2055   if ((ic->op == '+' || ic->op == '-') &&
2056       OP_SYMBOL (IC_RIGHT (dic))->onStack)
2057     {
2058       
2059       if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2060           IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2061           IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2062         return NULL;
2063     }
2064 #endif
2065   
2066   /* now make sure that the right side of dic
2067      is not defined between ic & dic */
2068   if (dic)
2069     {
2070       iCode *sic = dic->next;
2071
2072       for (; sic != ic; sic = sic->next)
2073         if (IC_RESULT (sic) &&
2074             IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2075           return NULL;
2076     }
2077
2078   return dic;
2079 }
2080
2081 /*-----------------------------------------------------------------*/
2082 /* reassignAliasedSym - used by packRegsForSupport to replace      */
2083 /*                      redundant iTemp with equivalent symbol     */
2084 /*-----------------------------------------------------------------*/
2085 static void
2086 reassignAliasedSym (eBBlock *ebp, iCode *assignment, iCode *use, operand *op)
2087 {
2088   iCode *ic;
2089   unsigned oldSymKey, newSymKey;
2090
2091   oldSymKey = op->key;
2092   newSymKey = IC_RIGHT(assignment)->key;
2093
2094   /* only track live ranges of compiler-generated temporaries */
2095   if (!IS_ITEMP(IC_RIGHT(assignment)))
2096     newSymKey = 0;
2097
2098   /* update the live-value bitmaps */
2099   for (ic = assignment; ic != use; ic = ic->next) {
2100     bitVectUnSetBit (ic->rlive, oldSymKey);
2101     if (newSymKey != 0)
2102       ic->rlive = bitVectSetBit (ic->rlive, newSymKey);
2103   }
2104
2105   /* update the sym of the used operand */
2106   OP_SYMBOL(op) = OP_SYMBOL(IC_RIGHT(assignment));
2107   op->key = OP_SYMBOL(op)->key;
2108
2109   /* update the sym's liverange */
2110   if ( OP_LIVETO(op) < ic->seq )
2111     setToRange(op, ic->seq, FALSE);
2112
2113   /* remove the assignment iCode now that its result is unused */
2114   remiCodeFromeBBlock (ebp, assignment);
2115   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(assignment))->defs, assignment->key);
2116   hTabDeleteItem (&iCodehTab, assignment->key, assignment, DELETE_ITEM, NULL);
2117 }
2118   
2119
2120 /*-----------------------------------------------------------------*/
2121 /* packRegsForSupport :- reduce some registers for support calls   */
2122 /*-----------------------------------------------------------------*/
2123 static int
2124 packRegsForSupport (iCode * ic, eBBlock * ebp)
2125 {
2126   iCode *dic;
2127   
2128   /* for the left & right operand :- look to see if the
2129      left was assigned a true symbol in far space in that
2130      case replace them */
2131
2132   if (IS_ITEMP (IC_LEFT (ic)) &&
2133       OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2134     {
2135       dic = findAssignToSym (IC_LEFT (ic), ic);
2136
2137       if (dic)
2138         {
2139           /* found it we need to remove it from the block */
2140           reassignAliasedSym (ebp, dic, ic, IC_LEFT(ic));
2141           return 1;
2142         }
2143     }
2144
2145   /* do the same for the right operand */
2146   if (IS_ITEMP (IC_RIGHT (ic)) &&
2147       OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2148     {
2149       iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2150
2151       if (dic)
2152         {
2153           /* if this is a subtraction & the result
2154              is a true symbol in far space then don't pack */
2155 #if 0
2156           if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
2157             {
2158               sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
2159               if (IN_FARSPACE (SPEC_OCLS (etype)))
2160                 return 0;
2161             }
2162 #endif
2163           /* found it we need to remove it from the
2164              block */
2165           reassignAliasedSym (ebp, dic, ic, IC_RIGHT(ic));
2166           
2167           return 1;
2168         }
2169     }
2170
2171   return 0;
2172 }
2173
2174 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
2175
2176
2177 #if 0
2178 /*-----------------------------------------------------------------*/
2179 /* packRegsForOneuse : - will reduce some registers for single Use */
2180 /*-----------------------------------------------------------------*/
2181 static iCode *
2182 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
2183 {
2184   bitVect *uses;
2185   iCode *dic, *sic;
2186
2187   /* if returning a literal then do nothing */
2188   if (!IS_SYMOP (op))
2189     return NULL;
2190
2191   /* only up to 2 bytes */
2192   if (getSize (operandType (op)) > (fReturnSizeHC08 - 2))
2193     return NULL;
2194
2195   return NULL;
2196   
2197   if (ic->op != SEND //RETURN
2198       && ic->op != SEND
2199       && !POINTER_SET (ic)
2200       && !POINTER_GET (ic) )
2201     return NULL;
2202   
2203   if (ic->op == SEND && ic->argreg != 1) return NULL;
2204
2205   /* this routine will mark the a symbol as used in one 
2206      instruction use only && if the defintion is local 
2207      (ie. within the basic block) && has only one definition &&
2208      that definiion is either a return value from a 
2209      function or does not contain any variables in
2210      far space */
2211   uses = bitVectCopy (OP_USES (op));
2212   bitVectUnSetBit (uses, ic->key);      /* take away this iCode */
2213   if (!bitVectIsZero (uses))    /* has other uses */
2214     return NULL;
2215
2216   /* if it has only one defintion */
2217   if (bitVectnBitsOn (OP_DEFS (op)) > 1)
2218     return NULL;                /* has more than one definition */
2219
2220   /* get that definition */
2221   if (!(dic =
2222         hTabItemWithKey (iCodehTab,
2223                          bitVectFirstBit (OP_DEFS (op)))))
2224     return NULL;
2225
2226   /* if that only usage is a cast */
2227   if (dic->op == CAST) {
2228     /* to a bigger type */
2229     if (getSize(OP_SYM_TYPE(IC_RESULT(dic))) > 
2230         getSize(OP_SYM_TYPE(IC_RIGHT(dic)))) {
2231       /* than we can not, since we cannot predict the usage of b & acc */
2232       return NULL;
2233     }
2234   }
2235
2236   /* found the definition now check if it is local */
2237   if (dic->seq < ebp->fSeq ||
2238       dic->seq > ebp->lSeq)
2239     return NULL;                /* non-local */
2240
2241   /* now check if it is the return from
2242      a function call */
2243   if (dic->op == CALL || dic->op == PCALL)
2244     {
2245       if (ic->op != SEND && ic->op != RETURN &&
2246           !POINTER_SET(ic) && !POINTER_GET(ic))
2247         {
2248           OP_SYMBOL (op)->ruonly = 1;
2249           return dic;
2250         }
2251       dic = dic->next;
2252     }
2253
2254
2255   /* otherwise check that the definition does
2256      not contain any symbols in far space */
2257 //  if (isOperandInFarSpace (IC_LEFT (dic)) ||
2258 //      isOperandInFarSpace (IC_RIGHT (dic)) ||
2259 //      IS_OP_RUONLY (IC_LEFT (ic)) ||
2260 //      IS_OP_RUONLY (IC_RIGHT (ic)))
2261 //    {
2262 //      return NULL;
2263 //    }
2264
2265   /* if pointer set then make sure the pointer
2266      is one byte */
2267 #if 0
2268   if (POINTER_SET (dic) &&
2269       !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2270     return NULL;
2271
2272   if (POINTER_GET (dic) &&
2273       !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2274     return NULL;
2275 #endif 
2276
2277   sic = dic;
2278
2279   /* also make sure the intervenening instructions
2280      don't have any thing in far space */
2281   for (dic = dic->next; dic && dic != ic && sic != ic; dic = dic->next)
2282     {
2283
2284       /* if there is an intervening function call then no */
2285       if (dic->op == CALL || dic->op == PCALL)
2286         return NULL;
2287       /* if pointer set then make sure the pointer
2288          is one byte */
2289 #if 0
2290       if (POINTER_SET (dic) &&
2291           !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2292         return NULL;
2293
2294       if (POINTER_GET (dic) &&
2295           !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2296         return NULL;
2297 #endif
2298       /* if address of & the result is remat the okay */
2299       if (dic->op == ADDRESS_OF &&
2300           OP_SYMBOL (IC_RESULT (dic))->remat)
2301         continue;
2302
2303       /* if operand has size of three or more & this
2304          operation is a '*','/' or '%' then 'b' may
2305          cause a problem */
2306 #if 0
2307       if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
2308           getSize (operandType (op)) >= 3)
2309         return NULL;
2310 #endif
2311
2312       /* if left or right or result is in far space */
2313 //      if (isOperandInFarSpace (IC_LEFT (dic)) ||
2314 //        isOperandInFarSpace (IC_RIGHT (dic)) ||
2315 //        isOperandInFarSpace (IC_RESULT (dic)) ||
2316 //        IS_OP_RUONLY (IC_LEFT (dic)) ||
2317 //        IS_OP_RUONLY (IC_RIGHT (dic)) ||
2318 //        IS_OP_RUONLY (IC_RESULT (dic)))
2319 //      {
2320 //        return NULL;
2321 //      }
2322 //      /* if left or right or result is on stack */
2323 //     if (isOperandOnStack(IC_LEFT(dic)) ||
2324 //        isOperandOnStack(IC_RIGHT(dic)) ||
2325 //        isOperandOnStack(IC_RESULT(dic))) {
2326 //      return NULL;
2327 //     }
2328     }
2329
2330   OP_SYMBOL (op)->ruonly = 1;
2331   return sic;
2332 }
2333 #endif
2334
2335 /*-----------------------------------------------------------------*/
2336 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
2337 /*-----------------------------------------------------------------*/
2338 static bool
2339 isBitwiseOptimizable (iCode * ic)
2340 {
2341   sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
2342   sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
2343
2344   /* bitwise operations are considered optimizable
2345      under the following conditions (Jean-Louis VERN) 
2346
2347      x & lit
2348      bit & bit
2349      bit & x
2350      bit ^ bit
2351      bit ^ x
2352      x   ^ lit
2353      x   | lit
2354      bit | bit
2355      bit | x
2356   */
2357   if (IS_LITERAL(rtype) ||
2358       (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
2359     return TRUE;
2360   else
2361     return FALSE;
2362 }
2363
2364 /*-----------------------------------------------------------------*/
2365 /* isCommutativeOp - tests whether this op cares what order its    */
2366 /*                   operands are in                               */
2367 /*-----------------------------------------------------------------*/
2368 bool isCommutativeOp2(unsigned int op)
2369 {
2370   if (op == '+' || op == '*' || op == EQ_OP ||
2371       op == '^' || op == '|' || op == BITWISEAND)
2372     return TRUE;
2373   else
2374     return FALSE;
2375 }
2376
2377 /*-----------------------------------------------------------------*/
2378 /* operandUsesAcc2 - determines whether the code generated for this */
2379 /*                  operand will have to use the accumulator       */
2380 /*-----------------------------------------------------------------*/
2381 bool operandUsesAcc2(operand *op)
2382 {
2383   if (!op)
2384     return FALSE;
2385
2386   if (IS_SYMOP(op)) {
2387     symbol *sym = OP_SYMBOL(op);
2388     memmap *symspace;
2389
2390     if (sym->accuse)
2391       return TRUE;  /* duh! */
2392
2393 //    if (IN_STACK(sym->etype) || sym->onStack ||
2394 //      (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
2395 //      return TRUE;  /* acc is used to calc stack offset */
2396
2397     if (IS_ITEMP(op))
2398       {
2399         if (SPIL_LOC(op)) {
2400           sym = SPIL_LOC(op);  /* if spilled, look at spill location */
2401         } else {
2402           return FALSE;  /* more checks? */
2403         }
2404       }
2405
2406     symspace = SPEC_OCLS(sym->etype);
2407
2408 //    if (sym->iaccess && symspace->paged)
2409 //      return TRUE;  /* must fetch paged indirect sym via accumulator */
2410     
2411     if (IN_BITSPACE(symspace))
2412       return TRUE;  /* fetching bit vars uses the accumulator */
2413     
2414     if (IN_FARSPACE(symspace) || IN_CODESPACE(symspace)) 
2415       return TRUE;  /* fetched via accumulator and dptr */
2416   }
2417
2418   return FALSE;
2419 }
2420
2421 /*-----------------------------------------------------------------*/
2422 /* packRegsForAccUse - pack registers for acc use                  */
2423 /*-----------------------------------------------------------------*/
2424 static void
2425 packRegsForAccUse (iCode * ic)
2426 {
2427   iCode *uic;
2428
2429   /* if this is an aggregate, e.g. a one byte char array */
2430   if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
2431     return;
2432   }
2433
2434   /* if we are calling a reentrant function that has stack parameters */
2435   #if 0
2436   if (ic->op == CALL &&
2437        IFFUNC_ISREENT(operandType(IC_LEFT(ic))) &&
2438        FUNC_HASSTACKPARM(operandType(IC_LEFT(ic))))
2439       return;
2440
2441   if (ic->op == PCALL &&
2442        IFFUNC_ISREENT(operandType(IC_LEFT(ic))->next) &&
2443        FUNC_HASSTACKPARM(operandType(IC_LEFT(ic))->next))
2444       return;
2445   #endif
2446
2447   /* if + or - then it has to be one byte result */
2448   if ((ic->op == '+' || ic->op == '-')
2449       && getSize (operandType (IC_RESULT (ic))) > 1)
2450     return;
2451
2452
2453   /* if shift operation make sure right side is a literal */
2454   if (ic->op == RIGHT_OP &&
2455       (!isOperandLiteral (IC_RIGHT (ic)) ||
2456        (getSize (operandType (IC_RESULT (ic) )) > 1)))
2457     return;
2458
2459   if (ic->op == LEFT_OP &&
2460       (!isOperandLiteral (IC_RIGHT (ic)) ||
2461        (getSize (operandType (IC_RESULT (ic) )) > 1)))
2462     return;
2463
2464   if (IS_BITWISE_OP (ic) &&
2465       getSize (operandType (IC_RESULT (ic))) > 1)
2466     return;
2467
2468
2469   /* has only one definition */
2470   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
2471     return;
2472
2473   /* has only one use */
2474   if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
2475     return;
2476
2477   /* and the usage immediately follows this iCode */
2478   if (!(uic = hTabItemWithKey (iCodehTab,
2479                                bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
2480     return;
2481
2482   if (ic->next != uic)
2483     return;
2484
2485   /* if it is a conditional branch then we definitely can */
2486   if (uic->op == IFX)
2487     goto accuse;
2488
2489   if (uic->op == JUMPTABLE)
2490     return;
2491
2492 #if 0
2493   if (POINTER_SET (uic) &&
2494       getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
2495     return;
2496 #endif
2497
2498   /* if the usage is not is an assignment
2499      or an arithmetic / bitwise / shift operation then not */
2500   if (uic->op != '=' &&
2501       !IS_ARITHMETIC_OP (uic) &&
2502       !IS_BITWISE_OP (uic) &&
2503       (uic->op != LEFT_OP) &&
2504       (uic->op != RIGHT_OP) &&
2505       (uic->op != GETHBIT))
2506     return;
2507
2508 #if 0
2509   /* if used in ^ operation then make sure right is not a 
2510      literal (WIML: Why is this?) */
2511   if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
2512     return;
2513
2514   /* if shift operation make sure right side is not a literal */
2515   /* WIML: Why is this? */
2516   if (uic->op == RIGHT_OP &&
2517       (isOperandLiteral (IC_RIGHT (uic)) ||
2518        getSize (operandType (IC_RESULT (uic))) > 1))
2519     return;
2520   if (uic->op == LEFT_OP &&
2521       (isOperandLiteral (IC_RIGHT (uic)) ||
2522        getSize (operandType (IC_RESULT (uic))) > 1))
2523     return;
2524 #endif
2525
2526   /* make sure that the result of this icode is not on the
2527      stack, since acc is used to compute stack offset */
2528 #if 0
2529   if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
2530       OP_SYMBOL (IC_RESULT (uic))->onStack)
2531     return;
2532 #else
2533 //  if (isOperandOnStack(IC_RESULT(uic)))
2534 //    return;
2535 #endif
2536
2537   /* if the usage has only one operand then we can */
2538   if (IC_LEFT (uic) == NULL ||
2539       IC_RIGHT (uic) == NULL)
2540     goto accuse;
2541
2542 #if 0
2543   /* if the other operand uses the accumulator then we cannot */
2544   if ( (IC_LEFT(uic)->key == IC_RESULT(ic)->key &&
2545         operandUsesAcc2(IC_RIGHT(uic))) ||
2546        (IC_RIGHT(uic)->key == IC_RESULT(ic)->key &&
2547         operandUsesAcc2(IC_LEFT(uic))) ) 
2548     return;
2549
2550   /* make sure this is on the left side if not commutative */
2551   /* except for '-', which has been written to be able to
2552      handle reversed operands */
2553   if (!(isCommutativeOp2(ic->op) || ic->op == '-') &&
2554        IC_LEFT (uic)->key != IC_RESULT (ic)->key)
2555     return;
2556 #endif
2557
2558 #if 0
2559   // this is too dangerous and need further restrictions
2560   // see bug #447547
2561
2562   /* if one of them is a literal then we can */
2563   if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
2564       (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
2565     {
2566       OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2567       return;
2568     }
2569 #endif
2570
2571 accuse:
2572
2573   if ((POINTER_GET(uic))
2574       || (ic->op == ADDRESS_OF && uic->op == '+' && IS_OP_LITERAL (IC_RIGHT (uic))))
2575     {
2576       OP_SYMBOL (IC_RESULT (ic))->accuse = ACCUSE_HX;
2577       return;
2578     }
2579   
2580   OP_SYMBOL (IC_RESULT (ic))->accuse = ACCUSE_XA;
2581 }
2582
2583 /*-----------------------------------------------------------------*/
2584 /* packForPush - hueristics to reduce iCode for pushing            */
2585 /*-----------------------------------------------------------------*/
2586 static void
2587 packForPush (iCode * ic, eBBlock ** ebpp, int blockno)
2588 {
2589   iCode *dic, *lic;
2590   bitVect *dbv;
2591   struct eBBlock * ebp=ebpp[blockno];
2592
2593   if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
2594     return;
2595
2596   /* must have only definition & one usage */
2597   if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
2598       bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
2599     return;
2600
2601   /* find the definition */
2602   if (!(dic = hTabItemWithKey (iCodehTab,
2603                                bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
2604     return;
2605
2606   if (dic->op != '=' || POINTER_SET (dic))
2607     return;
2608
2609   if (dic->seq < ebp->fSeq) { // Evelyn did this
2610     int i;
2611     for (i=0; i<blockno; i++) {
2612       if (dic->seq >= ebpp[i]->fSeq && dic->seq <= ebpp[i]->lSeq) {
2613         ebp=ebpp[i];
2614         break;
2615       }
2616     }
2617     wassert (i!=blockno); // no way to recover from here
2618   }
2619
2620   if (IS_SYMOP(IC_RIGHT(dic))) {
2621     /* make sure the right side does not have any definitions
2622        inbetween */
2623     dbv = OP_DEFS(IC_RIGHT(dic));
2624     for (lic = ic; lic && lic != dic ; lic = lic->prev) {
2625       if (bitVectBitValue(dbv,lic->key)) 
2626         return ;
2627     }
2628     /* make sure they have the same type */
2629     if (IS_SPEC(operandType(IC_LEFT(ic))))
2630     {
2631       sym_link *itype=operandType(IC_LEFT(ic));
2632       sym_link *ditype=operandType(IC_RIGHT(dic));
2633       
2634       if (SPEC_USIGN(itype)!=SPEC_USIGN(ditype) ||
2635           SPEC_LONG(itype)!=SPEC_LONG(ditype))
2636         return;
2637     }
2638     /* extend the live range of replaced operand if needed */
2639     if (OP_SYMBOL(IC_RIGHT(dic))->liveTo < ic->seq) {
2640       OP_SYMBOL(IC_RIGHT(dic))->liveTo = ic->seq;
2641     }
2642     bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2643   } 
2644
2645   /* we now we know that it has one & only one def & use
2646      and the that the definition is an assignment */
2647   ReplaceOpWithCheaperOp(&IC_LEFT (ic), IC_RIGHT (dic));
2648   remiCodeFromeBBlock (ebp, dic);
2649   hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2650 }
2651
2652 /*-----------------------------------------------------------------*/
2653 /* packRegisters - does some transformations to reduce register    */
2654 /*                   pressure                                      */
2655 /*-----------------------------------------------------------------*/
2656 static void
2657 packRegisters (eBBlock ** ebpp, int blockno)
2658 {
2659   iCode *ic;
2660   int change = 0;
2661   eBBlock *ebp=ebpp[blockno];
2662
2663   while (1)
2664     {
2665
2666       change = 0;
2667
2668       /* look for assignments of the form */
2669       /* iTempNN = TRueSym (someoperation) SomeOperand */
2670       /*       ....                       */
2671       /* TrueSym := iTempNN:1             */
2672       for (ic = ebp->sch; ic; ic = ic->next)
2673         {
2674           /* find assignment of the form TrueSym := iTempNN:1 */
2675           if (ic->op == '=' && !POINTER_SET (ic) )
2676             change += packRegsForAssign (ic, ebp);
2677         }
2678
2679       if (!change)
2680         break;
2681     }
2682
2683   for (ic = ebp->sch; ic; ic = ic->next)
2684     {
2685       /* if this is an itemp & result of an address of a true sym 
2686          then mark this as rematerialisable   */
2687       if (ic->op == ADDRESS_OF &&
2688           IS_ITEMP (IC_RESULT (ic)) &&
2689           IS_TRUE_SYMOP (IC_LEFT (ic)) &&
2690           bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2691           !OP_SYMBOL (IC_LEFT (ic))->onStack )
2692         {
2693
2694           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2695           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2696           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2697
2698         }
2699
2700       /* if straight assignment then carry remat flag if
2701          this is the only definition */
2702       if (ic->op == '=' &&
2703           !POINTER_SET (ic) &&
2704           IS_SYMOP (IC_RIGHT (ic)) &&
2705           OP_SYMBOL (IC_RIGHT (ic))->remat &&
2706           !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode) &&
2707           bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
2708         {
2709
2710           OP_SYMBOL (IC_RESULT (ic))->remat =
2711             OP_SYMBOL (IC_RIGHT (ic))->remat;
2712           OP_SYMBOL (IC_RESULT (ic))->rematiCode =
2713             OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
2714         }
2715
2716       /* if cast to a generic pointer & the pointer being
2717          cast is remat, then we can remat this cast as well */
2718       if (ic->op == CAST && 
2719           IS_SYMOP(IC_RIGHT(ic)) &&
2720           OP_SYMBOL(IC_RIGHT(ic))->remat &&
2721           bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1) {
2722               sym_link *to_type = operandType(IC_LEFT(ic));
2723               sym_link *from_type = operandType(IC_RIGHT(ic));
2724               if (IS_GENPTR(to_type) && IS_PTR(from_type)) {                  
2725                       OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2726                       OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2727                       OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2728               }
2729       }
2730
2731       /* if this is a +/- operation with a rematerizable 
2732          then mark this as rematerializable as well */
2733       if ((ic->op == '+' || ic->op == '-') &&
2734           (IS_SYMOP (IC_LEFT (ic)) &&
2735            IS_ITEMP (IC_RESULT (ic)) &&
2736            IS_OP_LITERAL (IC_RIGHT (ic))) &&
2737            OP_SYMBOL (IC_LEFT (ic))->remat &&
2738           (!IS_SYMOP (IC_RIGHT (ic)) || !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode)) &&
2739            bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1)
2740         {
2741           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2742           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2743           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2744         }
2745
2746       /* mark the pointer usages */
2747       if (POINTER_SET (ic))
2748         OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
2749
2750       if (POINTER_GET (ic) &&
2751           IS_SYMOP(IC_LEFT (ic)))
2752         OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
2753
2754       if (!SKIP_IC2 (ic))
2755         {
2756 #if 0
2757           /* if we are using a symbol on the stack
2758              then we should say hc08_ptrRegReq */
2759           if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
2760             hc08_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
2761                                  OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
2762           else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
2763             hc08_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
2764                               OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
2765           else
2766             {
2767               if (IS_SYMOP (IC_LEFT (ic)))
2768                 hc08_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
2769                                 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
2770               if (IS_SYMOP (IC_RIGHT (ic)))
2771                 hc08_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
2772                                OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
2773               if (IS_SYMOP (IC_RESULT (ic)))
2774                 hc08_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
2775                               OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
2776             }
2777 #endif
2778         }
2779
2780       /* if the condition of an if instruction
2781          is defined in the previous instruction and
2782          this is the only usage then
2783          mark the itemp as a conditional */
2784       if ((IS_CONDITIONAL (ic) ||
2785            (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic))) &&
2786           ic->next && ic->next->op == IFX &&
2787           bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
2788           isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
2789           OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2790         {
2791           OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
2792           continue;
2793         }
2794
2795       /* reduce for support function calls */
2796       if (ic->supportRtn || ic->op == '+' || ic->op == '-')
2797         packRegsForSupport (ic, ebp);
2798
2799       #if 0
2800       /* some cases the redundant moves can
2801          can be eliminated for return statements */
2802       if ((ic->op == RETURN || (ic->op == SEND && ic->argreg == 1)) &&
2803           /* !isOperandInFarSpace (IC_LEFT (ic)) && */
2804           options.model == MODEL_SMALL) {
2805         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2806       }
2807
2808       /* if pointer set & left has a size more than
2809          one and right is not in far space */
2810       if (POINTER_SET (ic) &&
2811           /* !isOperandInFarSpace (IC_RIGHT (ic)) && */
2812           !OP_SYMBOL (IC_RESULT (ic))->remat &&
2813           !IS_OP_RUONLY (IC_RIGHT (ic)) 
2814           /* && getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1 */ )
2815         packRegsForOneuse (ic, IC_RESULT (ic), ebp);
2816
2817       /* if pointer get */
2818       if (POINTER_GET (ic) &&
2819           IS_SYMOP (IC_LEFT (ic)) &&
2820           /* !isOperandInFarSpace (IC_RESULT (ic)) && */
2821           !OP_SYMBOL (IC_LEFT (ic))->remat &&
2822           !IS_OP_RUONLY (IC_RESULT (ic)) 
2823            /* && getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1 */)
2824         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2825
2826
2827       /* if this is cast for intergral promotion then
2828          check if only use of  the definition of the 
2829          operand being casted/ if yes then replace
2830          the result of that arithmetic operation with 
2831          this result and get rid of the cast */
2832       if (ic->op == CAST)
2833         {
2834           sym_link *fromType = operandType (IC_RIGHT (ic));
2835           sym_link *toType = operandType (IC_LEFT (ic));
2836
2837           if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
2838               getSize (fromType) != getSize (toType) &&
2839               SPEC_USIGN (fromType) == SPEC_USIGN (toType))
2840             {
2841
2842               iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2843               if (dic)
2844                 {
2845                   if (IS_ARITHMETIC_OP (dic))
2846                     {                  
2847                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2848                       ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
2849                       remiCodeFromeBBlock (ebp, ic);
2850                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2851                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2852                       OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2853                       ic = ic->prev;
2854                     }
2855                   else
2856                     OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
2857                 }
2858             }
2859           else
2860             {
2861
2862               /* if the type from and type to are the same
2863                  then if this is the only use then packit */
2864               if (compareType (operandType (IC_RIGHT (ic)),
2865                              operandType (IC_LEFT (ic))) == 1)
2866                 {
2867                   iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2868                   if (dic)
2869                     {
2870                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2871                       ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
2872                       remiCodeFromeBBlock (ebp, ic);
2873                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2874                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2875                       OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2876                       ic = ic->prev;
2877                     }
2878                 }
2879             }
2880         }
2881       #endif
2882       
2883       /* pack for PUSH 
2884          iTempNN := (some variable in farspace) V1
2885          push iTempNN ;
2886          -------------
2887          push V1
2888        */
2889       if (ic->op == IPUSH)
2890         {
2891           packForPush (ic, ebpp, blockno);
2892         }
2893
2894
2895       #if 1
2896       /* pack registers for accumulator use, when the
2897          result of an arithmetic or bit wise operation
2898          has only one use, that use is immediately following
2899          the defintion and the using iCode has only one
2900          operand or has two operands but one is literal &
2901          the result of that operation is not on stack then
2902          we can leave the result of this operation in x:a
2903          combination */
2904       if ((IS_ARITHMETIC_OP (ic)
2905            || IS_CONDITIONAL(ic)
2906            || IS_BITWISE_OP (ic)
2907            || ic->op == '='
2908            || ic->op == GETHBIT
2909            || ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == CALL
2910            || (ic->op == ADDRESS_OF && isOperandOnStack (IC_LEFT (ic)))
2911           ) &&
2912           IS_ITEMP (IC_RESULT (ic)) &&
2913           getSize (operandType (IC_RESULT (ic))) <= 1)
2914
2915         packRegsForAccUse (ic);
2916       #endif
2917     }
2918 }
2919
2920 /*-----------------------------------------------------------------*/
2921 /* assignRegisters - assigns registers to each live range as need  */
2922 /*-----------------------------------------------------------------*/
2923 void
2924 hc08_assignRegisters (eBBlock ** ebbs, int count)
2925 {
2926   iCode *ic;
2927   int i;
2928
2929   setToNull ((void *) &_G.funcrUsed);
2930   setToNull ((void *) &_G.regAssigned);
2931   setToNull ((void *) &_G.totRegAssigned);
2932   hc08_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
2933   hc08_nRegs = 5;
2934   hc08_reg_a = hc08_regWithIdx(A_IDX);
2935   hc08_reg_x = hc08_regWithIdx(X_IDX);
2936   hc08_reg_h = hc08_regWithIdx(H_IDX);
2937   hc08_reg_hx = hc08_regWithIdx(HX_IDX);
2938   hc08_reg_xa = hc08_regWithIdx(XA_IDX);
2939
2940   /* change assignments this will remove some
2941      live ranges reducing some register pressure */
2942   for (i = 0; i < count; i++)
2943     packRegisters (ebbs, i);
2944
2945   if (options.dump_pack)
2946     dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
2947
2948   /* first determine for each live range the number of 
2949      registers & the type of registers required for each */
2950   regTypeNum (*ebbs);
2951
2952   /* and serially allocate registers */
2953   serialRegAssign (ebbs, count);
2954
2955   freeAllRegs ();
2956   //setToNull ((void *) &_G.regAssigned);
2957   //setToNull ((void *) &_G.totRegAssigned);
2958   fillGaps();
2959
2960   /* if stack was extended then tell the user */
2961   if (_G.stackExtend)
2962     {
2963 /*      werror(W_TOOMANY_SPILS,"stack", */
2964 /*             _G.stackExtend,currFunc->name,""); */
2965       _G.stackExtend = 0;
2966     }
2967
2968   if (_G.dataExtend)
2969     {
2970 /*      werror(W_TOOMANY_SPILS,"data space", */
2971 /*             _G.dataExtend,currFunc->name,""); */
2972       _G.dataExtend = 0;
2973     }
2974
2975   /* after that create the register mask
2976      for each of the instruction */
2977   createRegMask (ebbs, count);
2978
2979   /* redo that offsets for stacked automatic variables */
2980   if (currFunc) {
2981     redoStackOffsets ();
2982   }
2983
2984   if (options.dump_rassgn)
2985     {
2986       dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
2987       dumpLiveRanges (DUMP_LRANGE, liveRanges);
2988     }
2989
2990   /* do the overlaysegment stuff SDCCmem.c */
2991   doOverlays (ebbs, count);
2992
2993   /* now get back the chain */
2994   ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
2995
2996   genhc08Code (ic);
2997
2998   /* free up any _G.stackSpil locations allocated */
2999   applyToSet (_G.stackSpil, deallocStackSpil);
3000   _G.slocNum = 0;
3001   setToNull ((void **) &_G.stackSpil);
3002   setToNull ((void **) &_G.spiltSet);
3003   /* mark all registers as free */
3004   freeAllRegs ();
3005
3006   return;
3007 }