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