2001-10-21 Michael Hope <michaelh@juju.net.nz>
[fw/sdcc] / src / z80 / ralloc.c
1 /** @name Z80 Register allocation functions.
2     @author Michael Hope
3
4     Note: much of this is ripped straight from Sandeep's mcs51 code.
5
6     This code maps the virtual symbols and code onto the real
7     hardware.  It allocates based on usage and how long the varible
8     lives into registers or temporary memory on the stack.
9
10     On the Z80 hl and ix and a are reserved for the code generator,
11     leaving bc and de for allocation.  iy is unusable due to currently
12     as it's only adressable as a pair.  The extra register pressure
13     from reserving hl is made up for by how much easier the sub
14     operations become.  You could swap hl for iy if the undocumented
15     iyl/iyh instructions are available.
16
17     The stack frame is the common ix-bp style.  Basically:
18
19     ix+4+n:     param 1 
20     ix+4:       param 0 
21     ix+2:       return address 
22     ix+0:       calling functions ix 
23     ix-n:       local varibles 
24     ...  
25     sp:         end of local varibles
26
27     There is currently no support for bit spaces or banked functions.
28     
29     This program is free software; you can redistribute it and/or
30     modify it under the terms of the GNU General Public License as
31     published by the Free Software Foundation; either version 2, or (at
32     your option) any later version.  This program is distributed in the
33     hope that it will be useful, but WITHOUT ANY WARRANTY; without even
34     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
35     PURPOSE.  See the GNU General Public License for more details.
36     
37     You should have received a copy of the GNU General Public License
38     along with this program; if not, write to the Free Software
39     Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
40     USA.  In other words, you are welcome to use, share and improve
41     this program.  You are forbidden to forbid anyone else to use,
42     share and improve what you give them.  Help stamp out
43     software-hoarding!  
44 */
45
46 #include "z80.h"
47
48 /* Flags to turn off optimisations.
49  */
50 enum
51   {
52     DISABLE_PACK_ACC = 0,
53     DISABLE_PACK_ASSIGN = 0,
54     /* Pack for one use is quite broken. */
55     DISABLE_PACK_ONE_USE = 1,
56     DISABLE_PACK_HL = 0,
57   };
58
59 /* Flags to turn on debugging code.
60  */
61 enum
62   {
63     D_ALLOC = 0,
64     D_ALLOC2 = 0,
65     D_ACCUSE2 = 0,
66     D_ACCUSE2_VERBOSE = 0
67   };
68
69 #if 1
70 #define D(_a, _s)       if (_a)  { printf _s; fflush(stdout); }
71 #else
72 #define D(_a, _s)
73 #endif
74
75 #define DISABLE_PACKREGSFORSUPPORT      1
76 #define DISABLE_PACKREGSFORACCUSE       1
77
78 extern void genZ80Code (iCode *);
79
80 /** Local static variables */
81 static struct
82 {
83   bitVect *spiltSet;
84   set *stackSpil;
85   bitVect *regAssigned;
86   short blockSpil;
87   int slocNum;
88   /* registers used in a function */
89   bitVect *funcrUsed;
90   int stackExtend;
91   int dataExtend;
92   int nRegs;
93 } _G;
94
95 static regs _gbz80_regs[] =
96 {
97   {REG_GPR, C_IDX, "c", 1},
98   {REG_GPR, B_IDX, "b", 1},
99   {REG_CND, CND_IDX, "c", 1}
100 };
101
102 static regs _z80_regs[] =
103 {
104   {REG_GPR, C_IDX, "c", 1},
105   {REG_GPR, B_IDX, "b", 1},
106   {REG_GPR, E_IDX, "e", 1},
107   {REG_GPR, D_IDX, "d", 1},
108   {REG_CND, CND_IDX, "c", 1}
109 };
110
111 regs *regsZ80;
112
113 /** Number of usable registers (all but C) */
114 #define Z80_MAX_REGS ((sizeof(_z80_regs)/sizeof(_z80_regs[0]))-1)
115 #define GBZ80_MAX_REGS ((sizeof(_gbz80_regs)/sizeof(_gbz80_regs[0]))-1)
116
117 static void spillThis (symbol *);
118
119 /** Allocates register of given type.
120     'type' is not used on the z80 version.  It was used to select
121     between pointer and general purpose registers on the mcs51 version.
122
123     @return             Pointer to the newly allocated register.
124  */
125 static regs *
126 allocReg (short type)
127 {
128   int i;
129
130   for (i = 0; i < _G.nRegs; i++)
131     {
132       /* For now we allocate from any free */
133       if (regsZ80[i].isFree)
134         {
135           regsZ80[i].isFree = 0;
136           if (currFunc)
137             {
138               currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, i);
139             }
140           D (D_ALLOC, ("allocReg: alloced %p\n", &regsZ80[i]));
141           return &regsZ80[i];
142         }
143     }
144   D (D_ALLOC, ("allocReg: No free.\n"));
145   return NULL;
146 }
147
148 /** Returns pointer to register wit index number
149  */
150 regs *
151 regWithIdx (int idx)
152 {
153   int i;
154
155   for (i = 0; i < _G.nRegs; i++)
156     {
157       if (regsZ80[i].rIdx == idx)
158         {
159           return &regsZ80[i];
160         }
161     }
162
163   wassertl (0, "regWithIdx not found");
164   exit (1);
165 }
166
167 /** Frees a register.
168  */
169 static void 
170 freeReg (regs * reg)
171 {
172   wassert (!reg->isFree);
173   reg->isFree = 1;
174   D (D_ALLOC, ("freeReg: freed %p\n", reg));
175 }
176
177
178 /** Returns number of free registers.
179  */
180 static int 
181 nFreeRegs (int type)
182 {
183   int i;
184   int nfr = 0;
185
186   for (i = 0; i < _G.nRegs; i++)
187     {
188       /* For now only one reg type */
189       if (regsZ80[i].isFree)
190         {
191           nfr++;
192         }
193     }
194   return nfr;
195 }
196
197 /** Free registers with type.
198  */
199 static int 
200 nfreeRegsType (int type)
201 {
202   int nfr;
203   if (type == REG_PTR)
204     {
205       if ((nfr = nFreeRegs (type)) == 0)
206         {
207           return nFreeRegs (REG_GPR);
208         }
209     }
210
211   return nFreeRegs (type);
212 }
213
214
215 #if 0
216 /*-----------------------------------------------------------------*/
217 /* allDefsOutOfRange - all definitions are out of a range          */
218 /*-----------------------------------------------------------------*/
219 static bool 
220 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
221 {
222   int i;
223
224   if (!defs)
225     return TRUE;
226
227   for (i = 0; i < defs->size; i++)
228     {
229       iCode *ic;
230
231       if (bitVectBitValue (defs, i) &&
232           (ic = hTabItemWithKey (iCodehTab, i)) &&
233           (ic->seq >= fseq && ic->seq <= toseq))
234
235         return FALSE;
236
237     }
238
239   return TRUE;
240 }
241 #endif
242
243 /*-----------------------------------------------------------------*/
244 /* computeSpillable - given a point find the spillable live ranges */
245 /*-----------------------------------------------------------------*/
246 static bitVect *
247 computeSpillable (iCode * ic)
248 {
249   bitVect *spillable;
250
251   /* spillable live ranges are those that are live at this 
252      point . the following categories need to be subtracted
253      from this set. 
254      a) - those that are already spilt
255      b) - if being used by this one
256      c) - defined by this one */
257
258   spillable = bitVectCopy (ic->rlive);
259   spillable =
260     bitVectCplAnd (spillable, _G.spiltSet);     /* those already spilt */
261   spillable =
262     bitVectCplAnd (spillable, ic->uses);        /* used in this one */
263   bitVectUnSetBit (spillable, ic->defKey);
264   spillable = bitVectIntersect (spillable, _G.regAssigned);
265
266   return spillable;
267 }
268
269 /*-----------------------------------------------------------------*/
270 /* noSpilLoc - return true if a variable has no spil location      */
271 /*-----------------------------------------------------------------*/
272 static int 
273 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
274 {
275   return (sym->usl.spillLoc ? 0 : 1);
276 }
277
278 /*-----------------------------------------------------------------*/
279 /* hasSpilLoc - will return 1 if the symbol has spil location      */
280 /*-----------------------------------------------------------------*/
281 static int 
282 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
283 {
284   return (sym->usl.spillLoc ? 1 : 0);
285 }
286
287 /** Will return 1 if the remat flag is set.
288     A symbol is rematerialisable if it doesnt need to be allocated
289     into registers at creation as it can be re-created at any time -
290     i.e. it's constant in some way.
291 */
292 static int 
293 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
294 {
295   return sym->remat;
296 }
297
298 /*-----------------------------------------------------------------*/
299 /* allLRs - return true for all                                    */
300 /*-----------------------------------------------------------------*/
301 static int 
302 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
303 {
304   return 1;
305 }
306
307 /** liveRangesWith - applies function to a given set of live range 
308  */
309 static set *
310 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
311                 eBBlock * ebp, iCode * ic)
312 {
313   set *rset = NULL;
314   int i;
315
316   if (!lrs || !lrs->size)
317     return NULL;
318
319   for (i = 1; i < lrs->size; i++)
320     {
321       symbol *sym;
322       if (!bitVectBitValue (lrs, i))
323         continue;
324
325       /* if we don't find it in the live range 
326          hash table we are in serious trouble */
327       if (!(sym = hTabItemWithKey (liveRanges, i)))
328         {
329           wassertl (0, "liveRangesWith could not find liveRange");
330           exit (1);
331         }
332
333       if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
334         {
335           addSetHead (&rset, sym);
336         }
337     }
338
339   return rset;
340 }
341
342
343 /** leastUsedLR - given a set determines which is the least used 
344  */
345 static symbol *
346 leastUsedLR (set * sset)
347 {
348   symbol *sym = NULL, *lsym = NULL;
349
350   sym = lsym = setFirstItem (sset);
351
352   if (!lsym)
353     return NULL;
354
355   for (; lsym; lsym = setNextItem (sset))
356     {
357
358       /* if usage is the same then prefer
359          the spill the smaller of the two */
360       if (lsym->used == sym->used)
361         if (getSize (lsym->type) < getSize (sym->type))
362           sym = lsym;
363
364       /* if less usage */
365       if (lsym->used < sym->used)
366         sym = lsym;
367
368     }
369
370   setToNull ((void **) &sset);
371   sym->blockSpil = 0;
372   return sym;
373 }
374
375 /** noOverLap - will iterate through the list looking for over lap
376  */
377 static int 
378 noOverLap (set * itmpStack, symbol * fsym)
379 {
380   symbol *sym;
381
382   for (sym = setFirstItem (itmpStack); sym;
383        sym = setNextItem (itmpStack))
384     {
385             // if sym starts before (or on) our end point
386             // and ends after (or on) our start point, 
387             // it is an overlap.
388             if (sym->liveFrom <= fsym->liveTo &&
389                 sym->liveTo   >= fsym->liveFrom)
390             {
391                 return 0;
392             }
393     }
394   return 1;
395 }
396
397 /*-----------------------------------------------------------------*/
398 /* isFree - will return 1 if the a free spil location is found     */
399 /*-----------------------------------------------------------------*/
400 DEFSETFUNC (isFree)
401 {
402   symbol *sym = item;
403   V_ARG (symbol **, sloc);
404   V_ARG (symbol *, fsym);
405
406   /* if already found */
407   if (*sloc)
408     return 0;
409
410   /* if it is free && and the itmp assigned to
411      this does not have any overlapping live ranges
412      with the one currently being assigned and
413      the size can be accomodated  */
414   if (sym->isFree &&
415       noOverLap (sym->usl.itmpStack, fsym) &&
416       getSize (sym->type) >= getSize (fsym->type))
417     {
418       *sloc = sym;
419       return 1;
420     }
421
422   return 0;
423 }
424
425 /*-----------------------------------------------------------------*/
426 /* createStackSpil - create a location on the stack to spil        */
427 /*-----------------------------------------------------------------*/
428 static symbol *
429 createStackSpil (symbol * sym)
430 {
431   symbol *sloc = NULL;
432
433   D (D_ALLOC, ("createStackSpil: for sym %p\n", sym));
434
435   /* first go try and find a free one that is already 
436      existing on the stack */
437   if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
438     {
439       /* found a free one : just update & return */
440       sym->usl.spillLoc = sloc;
441       sym->stackSpil = 1;
442       sloc->isFree = 0;
443       addSetHead (&sloc->usl.itmpStack, sym);
444       D (D_ALLOC, ("createStackSpil: found existing\n"));
445       return sym;
446     }
447
448   /* could not then have to create one , this is the hard part
449      we need to allocate this on the stack : this is really a
450      hack!! but cannot think of anything better at this time */
451
452   sprintf (buffer, "sloc%d", _G.slocNum++);
453   sloc = newiTemp (buffer);
454
455   /* set the type to the spilling symbol */
456   sloc->type = copyLinkChain (sym->type);
457   sloc->etype = getSpec (sloc->type);
458   SPEC_SCLS (sloc->etype) = S_AUTO;
459
460   allocLocal (sloc);
461
462   sloc->isref = 1;              /* to prevent compiler warning */
463
464   /* if it is on the stack then update the stack */
465   if (IN_STACK (sloc->etype))
466     {
467       currFunc->stack += getSize (sloc->type);
468       _G.stackExtend += getSize (sloc->type);
469     }
470   else
471     {
472       _G.dataExtend += getSize (sloc->type);
473     }
474
475   /* add it to the stackSpil set */
476   addSetHead (&_G.stackSpil, sloc);
477   sym->usl.spillLoc = sloc;
478   sym->stackSpil = 1;
479
480   /* add it to the set of itempStack set 
481      of the spill location */
482   addSetHead (&sloc->usl.itmpStack, sym);
483
484   D (D_ALLOC, ("createStackSpil: created new\n"));
485   return sym;
486 }
487
488 /*-----------------------------------------------------------------*/
489 /* spillThis - spils a specific operand                            */
490 /*-----------------------------------------------------------------*/
491 static void 
492 spillThis (symbol * sym)
493 {
494   int i;
495
496   D (D_ALLOC, ("spillThis: spilling %p\n", sym));
497
498   /* if this is rematerializable or has a spillLocation
499      we are okay, else we need to create a spillLocation
500      for it */
501   if (!(sym->remat || sym->usl.spillLoc))
502     {
503       createStackSpil (sym);
504     }
505
506   /* mark it has spilt & put it in the spilt set */
507   sym->isspilt = 1;
508   _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
509
510   bitVectUnSetBit (_G.regAssigned, sym->key);
511
512   for (i = 0; i < sym->nRegs; i++)
513     {
514       if (sym->regs[i])
515         {
516           freeReg (sym->regs[i]);
517           sym->regs[i] = NULL;
518         }
519     }
520
521   if (sym->usl.spillLoc && !sym->remat)
522     {
523       sym->usl.spillLoc->allocreq = 1;
524     }
525   return;
526 }
527
528 #if DISABLED
529 /*-----------------------------------------------------------------*/
530 /* allDefsOutOfRange - all definitions are out of a range          */
531 /*-----------------------------------------------------------------*/
532 static bool
533 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
534 {
535   int i;
536
537   if (!defs)
538     return TRUE;
539
540   for (i = 0; i < defs->size; i++)
541     {
542       iCode *ic;
543
544       if (bitVectBitValue (defs, i) &&
545           (ic = hTabItemWithKey (iCodehTab, i)) &&
546           (ic->seq >= fseq && ic->seq <= toseq))
547
548         return FALSE;
549
550     }
551
552   return TRUE;
553 }
554
555 /*-----------------------------------------------------------------*/
556 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
557 /*                    but is not used as a pointer                 */
558 /*-----------------------------------------------------------------*/
559 static int
560 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
561 {
562   return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
563 }
564
565 /*-----------------------------------------------------------------*/
566 /* notUsedInBlock - not used in this block                         */
567 /*-----------------------------------------------------------------*/
568 static int
569 notUsedInBlock (symbol * sym, eBBlock * ebp, iCode * ic)
570 {
571   return (!bitVectBitsInCommon (sym->defs, ebp->usesDefs) &&
572           allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
573 /*     return (!bitVectBitsInCommon(sym->defs,ebp->usesDefs)); */
574 }
575
576 /*-----------------------------------------------------------------*/
577 /* notUsedInRemaining - not used or defined in remain of the block */
578 /*-----------------------------------------------------------------*/
579 static int
580 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
581 {
582   return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
583           allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
584 }
585 #endif
586
587 /** Select a iTemp to spil : rather a simple procedure.
588  */
589 symbol *
590 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
591 {
592   bitVect *lrcs = NULL;
593   set *selectS;
594   symbol *sym;
595
596   D (D_ALLOC, ("selectSpil: finding spill for ic %p\n", ic));
597   /* get the spillable live ranges */
598   lrcs = computeSpillable (ic);
599
600   /* get all live ranges that are rematerizable */
601   if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
602     {
603       D (D_ALLOC, ("selectSpil: using remat.\n"));
604       /* return the least used of these */
605       return leastUsedLR (selectS);
606     }
607
608 #if 0
609   /* get live ranges with spillLocations in direct space */
610   if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
611     {
612       sym = leastUsedLR (selectS);
613       strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
614                            sym->usl.spillLoc->rname :
615                            sym->usl.spillLoc->name));
616       sym->spildir = 1;
617       /* mark it as allocation required */
618       sym->usl.spillLoc->allocreq = 1;
619       return sym;
620     }
621
622   /* if the symbol is local to the block then */
623   if (forSym->liveTo < ebp->lSeq)
624     {
625
626       /* check if there are any live ranges allocated
627          to registers that are not used in this block */
628       if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
629         {
630           sym = leastUsedLR (selectS);
631           /* if this is not rematerializable */
632           if (!sym->remat)
633             {
634               _G.blockSpil++;
635               wassertl (0, "Attempted to do an unsupported block spill");
636               sym->blockSpil = 1;
637             }
638           return sym;
639         }
640
641       /* check if there are any live ranges that not
642          used in the remainder of the block */
643       if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
644         {
645           sym = leastUsedLR (selectS);
646           if (sym != forSym)
647             {
648               if (!sym->remat)
649                 {
650                   wassertl (0, "Attempted to do an unsupported remain spill");
651                   sym->remainSpil = 1;
652                   _G.blockSpil++;
653                 }
654               return sym;
655             }
656         }
657     }
658   /* find live ranges with spillocation && not used as pointers */
659   if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
660     {
661
662       sym = leastUsedLR (selectS);
663       /* mark this as allocation required */
664       sym->usl.spillLoc->allocreq = 1;
665       return sym;
666     }
667 #endif
668
669   /* find live ranges with spillocation */
670   if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
671     {
672       D (D_ALLOC, ("selectSpil: using with spill.\n"));
673       sym = leastUsedLR (selectS);
674       sym->usl.spillLoc->allocreq = 1;
675       return sym;
676     }
677
678   /* couldn't find then we need to create a spil
679      location on the stack , for which one? the least
680      used ofcourse */
681   if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
682     {
683       D (D_ALLOC, ("selectSpil: creating new spill.\n"));
684       /* return a created spil location */
685       sym = createStackSpil (leastUsedLR (selectS));
686       sym->usl.spillLoc->allocreq = 1;
687       return sym;
688     }
689
690   /* this is an extreme situation we will spill
691      this one : happens very rarely but it does happen */
692   D (D_ALLOC, ("selectSpil: using spillThis.\n"));
693   spillThis (forSym);
694   return forSym;
695
696 }
697
698 /** Spil some variable & mark registers as free.
699     A spill occurs when an iTemp wont fit into the available registers.
700  */
701 bool 
702 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
703 {
704   symbol *ssym;
705   int i;
706
707   D (D_ALLOC, ("spilSomething: spilling on ic %p\n", ic));
708
709   /* get something we can spil */
710   ssym = selectSpil (ic, ebp, forSym);
711
712   /* mark it as spilt */
713   ssym->isspilt = 1;
714   _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
715
716   /* mark it as not register assigned &
717      take it away from the set */
718   bitVectUnSetBit (_G.regAssigned, ssym->key);
719
720   /* mark the registers as free */
721   for (i = 0; i < ssym->nRegs; i++)
722     if (ssym->regs[i])
723       freeReg (ssym->regs[i]);
724
725   wassertl (ssym->blockSpil == 0, "Encountered a sym with a block spill");
726   wassertl (ssym->remainSpil == 0, "Encountered a sym with a remain spill");
727 #if 0
728   /* if spilt on stack then free up r0 & r1 
729      if they could have been assigned to as gprs */
730   if (!ptrRegReq && isSpiltOnStack (ssym))
731     {
732       ptrRegReq++;
733       spillLRWithPtrReg (ssym);
734     }
735
736   /* if this was a block level spil then insert push & pop 
737      at the start & end of block respectively */
738   if (ssym->blockSpil)
739     {
740       iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
741       /* add push to the start of the block */
742       addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
743                                     ebp->sch->next : ebp->sch));
744       nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
745       /* add pop to the end of the block */
746       addiCodeToeBBlock (ebp, nic, NULL);
747     }
748
749   /* if spilt because not used in the remainder of the
750      block then add a push before this instruction and
751      a pop at the end of the block */
752   if (ssym->remainSpil)
753     {
754
755       iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
756       /* add push just before this instruction */
757       addiCodeToeBBlock (ebp, nic, ic);
758
759       nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
760       /* add pop to the end of the block */
761       addiCodeToeBBlock (ebp, nic, NULL);
762     }
763 #endif
764
765   D (D_ALLOC, ("spilSomething: done.\n"));
766
767   if (ssym == forSym)
768     return FALSE;
769   else
770     return TRUE;
771 }
772
773 /** Will try for GPR if not spil.
774  */
775 regs *
776 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
777 {
778   regs *reg;
779
780   D (D_ALLOC, ("getRegGpr: on ic %p\n", ic));
781 tryAgain:
782   /* try for gpr type */
783   if ((reg = allocReg (REG_GPR)))
784     {
785       D (D_ALLOC, ("getRegGpr: got a reg.\n"));
786       return reg;
787     }
788
789   /* we have to spil */
790   if (!spilSomething (ic, ebp, sym))
791     {
792       D (D_ALLOC, ("getRegGpr: have to spill.\n"));
793       return NULL;
794     }
795
796   /* this looks like an infinite loop but 
797      in really selectSpil will abort  */
798   goto tryAgain;
799 }
800
801 /** Symbol has a given register.
802  */
803 static bool 
804 symHasReg (symbol * sym, regs * reg)
805 {
806   int i;
807
808   for (i = 0; i < sym->nRegs; i++)
809     if (sym->regs[i] == reg)
810       return TRUE;
811
812   return FALSE;
813 }
814
815 /** Check the live to and if they have registers & are not spilt then
816     free up the registers 
817 */
818 static void 
819 deassignLRs (iCode * ic, eBBlock * ebp)
820 {
821   symbol *sym;
822   int k;
823   symbol *result;
824
825   for (sym = hTabFirstItem (liveRanges, &k); sym;
826        sym = hTabNextItem (liveRanges, &k))
827     {
828
829       symbol *psym = NULL;
830       /* if it does not end here */
831       if (sym->liveTo > ic->seq)
832         continue;
833
834       /* if it was spilt on stack then we can 
835          mark the stack spil location as free */
836       if (sym->isspilt)
837         {
838           if (sym->stackSpil)
839             {
840               sym->usl.spillLoc->isFree = 1;
841               sym->stackSpil = 0;
842             }
843           continue;
844         }
845
846       if (!bitVectBitValue (_G.regAssigned, sym->key))
847         continue;
848
849       /* special case check if this is an IFX &
850          the privious one was a pop and the 
851          previous one was not spilt then keep track
852          of the symbol */
853       if (ic->op == IFX && ic->prev &&
854           ic->prev->op == IPOP &&
855           !ic->prev->parmPush &&
856           !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
857         psym = OP_SYMBOL (IC_LEFT (ic->prev));
858
859       D (D_ALLOC, ("deassignLRs: in loop on sym %p nregs %u\n", sym, sym->nRegs));
860
861       if (sym->nRegs)
862         {
863           int i = 0;
864
865           bitVectUnSetBit (_G.regAssigned, sym->key);
866
867           /* if the result of this one needs registers
868              and does not have it then assign it right
869              away */
870           if (IC_RESULT (ic) &&
871               !(SKIP_IC2 (ic) ||        /* not a special icode */
872                 ic->op == JUMPTABLE ||
873                 ic->op == IFX ||
874                 ic->op == IPUSH ||
875                 ic->op == IPOP ||
876                 ic->op == RETURN) &&
877               (result = OP_SYMBOL (IC_RESULT (ic))) &&  /* has a result */
878               result->liveTo > ic->seq &&       /* and will live beyond this */
879               result->liveTo <= ebp->lSeq &&    /* does not go beyond this block */
880               result->regType == sym->regType &&        /* same register types */
881               result->nRegs &&  /* which needs registers */
882               !result->isspilt &&       /* and does not already have them */
883               !result->remat &&
884               !bitVectBitValue (_G.regAssigned, result->key) &&
885           /* the number of free regs + number of regs in this LR
886              can accomodate the what result Needs */
887               ((nfreeRegsType (result->regType) +
888                 sym->nRegs) >= result->nRegs)
889             )
890             {
891               for (i = 0; i < result->nRegs; i++)
892                 {
893                   if (i < sym->nRegs)
894                     result->regs[i] = sym->regs[i];
895                   else
896                     result->regs[i] = getRegGpr (ic, ebp, result);
897
898                   /* if the allocation falied which means
899                      this was spilt then break */
900                   if (!result->regs[i])
901                     {
902                       wassert (0);
903                       assert (0);
904                       break;
905                     }
906                 }
907
908               _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
909             }
910
911           /* free the remaining */
912           for (; i < sym->nRegs; i++)
913             {
914               if (psym)
915                 {
916                   if (!symHasReg (psym, sym->regs[i]))
917                     freeReg (sym->regs[i]);
918                 }
919               else
920                 freeReg (sym->regs[i]);
921               //              sym->regs[i] = NULL;
922             }
923         }
924     }
925 }
926
927
928 /** Reassign this to registers.
929  */
930 static void 
931 reassignLR (operand * op)
932 {
933   symbol *sym = OP_SYMBOL (op);
934   int i;
935
936   D (D_ALLOC, ("reassingLR: on sym %p\n", sym));
937
938   /* not spilt any more */
939   sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
940   bitVectUnSetBit (_G.spiltSet, sym->key);
941
942   _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
943
944   _G.blockSpil--;
945
946   for (i = 0; i < sym->nRegs; i++)
947     sym->regs[i]->isFree = 0;
948 }
949
950 /** Determines if allocating will cause a spill.
951  */
952 static int 
953 willCauseSpill (int nr, int rt)
954 {
955   /* first check if there are any avlb registers
956      of te type required */
957   if (nFreeRegs (0) >= nr)
958     return 0;
959
960   /* it will cause a spil */
961   return 1;
962 }
963
964 /** The allocator can allocate same registers to result and operand,
965     if this happens make sure they are in the same position as the operand
966     otherwise chaos results.
967 */
968 static void 
969 positionRegs (symbol * result, symbol * opsym, int lineno)
970 {
971   int count = min (result->nRegs, opsym->nRegs);
972   int i, j = 0, shared = 0;
973
974   D (D_ALLOC, ("positionRegs: on result %p opsum %p line %u\n", result, opsym, lineno));
975
976   /* if the result has been spilt then cannot share */
977   if (opsym->isspilt)
978     return;
979 again:
980   shared = 0;
981   /* first make sure that they actually share */
982   for (i = 0; i < count; i++)
983     {
984       for (j = 0; j < count; j++)
985         {
986           if (result->regs[i] == opsym->regs[j] && i != j)
987             {
988               shared = 1;
989               goto xchgPositions;
990             }
991         }
992     }
993 xchgPositions:
994   if (shared)
995     {
996       regs *tmp = result->regs[i];
997       result->regs[i] = result->regs[j];
998       result->regs[j] = tmp;
999       goto again;
1000     }
1001 }
1002
1003 /** Try to allocate a pair of registers to the symbol.
1004  */
1005 bool 
1006 tryAllocatingRegPair (symbol * sym)
1007 {
1008   int i;
1009   wassert (sym->nRegs == 2);
1010   for (i = 0; i < _G.nRegs; i += 2)
1011     {
1012       if ((regsZ80[i].isFree) && (regsZ80[i + 1].isFree))
1013         {
1014           regsZ80[i].isFree = 0;
1015           sym->regs[0] = &regsZ80[i];
1016           regsZ80[i + 1].isFree = 0;
1017           sym->regs[1] = &regsZ80[i + 1];
1018           if (currFunc)
1019             {
1020               currFunc->regsUsed =
1021                 bitVectSetBit (currFunc->regsUsed, i);
1022               currFunc->regsUsed =
1023                 bitVectSetBit (currFunc->regsUsed, i + 1);
1024             }
1025           D (D_ALLOC, ("tryAllocRegPair: succeded for sym %p\n", sym));
1026           return TRUE;
1027         }
1028     }
1029   D (D_ALLOC, ("tryAllocRegPair: failed on sym %p\n", sym));
1030   return FALSE;
1031 }
1032
1033 /** Serially allocate registers to the variables.
1034     This is the main register allocation function.  It is called after
1035     packing.
1036  */
1037 static void 
1038 serialRegAssign (eBBlock ** ebbs, int count)
1039 {
1040   int i;
1041
1042   /* for all blocks */
1043   for (i = 0; i < count; i++)
1044     {
1045
1046       iCode *ic;
1047
1048       if (ebbs[i]->noPath &&
1049           (ebbs[i]->entryLabel != entryLabel &&
1050            ebbs[i]->entryLabel != returnLabel))
1051         continue;
1052
1053       /* of all instructions do */
1054       for (ic = ebbs[i]->sch; ic; ic = ic->next)
1055         {
1056
1057           /* if this is an ipop that means some live
1058              range will have to be assigned again */
1059           if (ic->op == IPOP)
1060             {
1061               wassert (0);
1062               reassignLR (IC_LEFT (ic));
1063             }
1064
1065           /* if result is present && is a true symbol */
1066           if (IC_RESULT (ic) && ic->op != IFX &&
1067               IS_TRUE_SYMOP (IC_RESULT (ic)))
1068             OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
1069
1070           /* take away registers from live
1071              ranges that end at this instruction */
1072           deassignLRs (ic, ebbs[i]);
1073
1074           /* some don't need registers */
1075           /* MLH: removed RESULT and POINTER_SET condition */
1076           if (SKIP_IC2 (ic) ||
1077               ic->op == JUMPTABLE ||
1078               ic->op == IFX ||
1079               ic->op == IPUSH ||
1080               ic->op == IPOP)
1081             continue;
1082
1083           /* now we need to allocate registers only for the result */
1084           if (IC_RESULT (ic))
1085             {
1086               symbol *sym = OP_SYMBOL (IC_RESULT (ic));
1087               bitVect *spillable;
1088               int willCS;
1089               int j;
1090
1091               D (D_ALLOC, ("serialRegAssign: in loop on result %p\n", sym));
1092
1093               /* if it does not need or is spilt 
1094                  or is already assigned to registers
1095                  or will not live beyond this instructions */
1096               if (!sym->nRegs ||
1097                   sym->isspilt ||
1098                   bitVectBitValue (_G.regAssigned, sym->key) ||
1099                   sym->liveTo <= ic->seq)
1100                 {
1101                   D (D_ALLOC, ("serialRegAssign: wont live long enough.\n"));
1102                   continue;
1103                 }
1104
1105               /* if some liverange has been spilt at the block level
1106                  and this one live beyond this block then spil this
1107                  to be safe */
1108               if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
1109                 {
1110                   D (D_ALLOC, ("serialRegAssign: \"spilling to be safe.\"\n"));
1111                   spillThis (sym);
1112                   continue;
1113                 }
1114               /* if trying to allocate this will cause
1115                  a spill and there is nothing to spill 
1116                  or this one is rematerializable then
1117                  spill this one */
1118               willCS = willCauseSpill (sym->nRegs, sym->regType);
1119               spillable = computeSpillable (ic);
1120               if (sym->remat ||
1121                   (willCS && bitVectIsZero (spillable)))
1122                 {
1123
1124                   D (D_ALLOC, ("serialRegAssign: \"remat spill\"\n"));
1125                   spillThis (sym);
1126                   continue;
1127
1128                 }
1129
1130               /* if it has a spillocation & is used less than
1131                  all other live ranges then spill this */
1132               if (willCS) {
1133                       if (sym->usl.spillLoc) {
1134                               symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
1135                                                                                allLRs, ebbs[i], ic));
1136                               if (leastUsed && leastUsed->used > sym->used) {
1137                                       spillThis (sym);
1138                                       continue;
1139                               }
1140                       } else {
1141                               /* if none of the liveRanges have a spillLocation then better
1142                                  to spill this one than anything else already assigned to registers */
1143                               if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
1144                                       spillThis (sym);
1145                                       continue;
1146                               }
1147                       }
1148               }
1149
1150               /* else we assign registers to it */
1151               _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1152
1153               /* Special case:  Try to fit into a reg pair if
1154                  available */
1155               D (D_ALLOC, ("serialRegAssign: actually allocing regs!\n"));
1156               if ((sym->nRegs == 2) && tryAllocatingRegPair (sym))
1157                 {
1158                 }
1159               else
1160                 {
1161                   for (j = 0; j < sym->nRegs; j++)
1162                     {
1163                       sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
1164
1165                       /* if the allocation falied which means
1166                          this was spilt then break */
1167                       if (!sym->regs[j])
1168                         {
1169                           D (D_ALLOC, ("Couldnt alloc (spill)\n"))
1170                             break;
1171                         }
1172                     }
1173                 }
1174               /* if it shares registers with operands make sure
1175                  that they are in the same position */
1176               if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
1177                   OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
1178                 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1179                               OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
1180               /* do the same for the right operand */
1181               if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
1182                   OP_SYMBOL (IC_RIGHT (ic))->nRegs)
1183                 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1184                               OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
1185
1186             }
1187         }
1188     }
1189 }
1190
1191 /*-----------------------------------------------------------------*/
1192 /* rUmaskForOp :- returns register mask for an operand             */
1193 /*-----------------------------------------------------------------*/
1194 bitVect *
1195 rUmaskForOp (operand * op)
1196 {
1197   bitVect *rumask;
1198   symbol *sym;
1199   int j;
1200
1201   /* only temporaries are assigned registers */
1202   if (!IS_ITEMP (op))
1203     return NULL;
1204
1205   sym = OP_SYMBOL (op);
1206
1207   /* if spilt or no registers assigned to it
1208      then nothing */
1209   if (sym->isspilt || !sym->nRegs)
1210     return NULL;
1211
1212   rumask = newBitVect (_G.nRegs);
1213
1214   for (j = 0; j < sym->nRegs; j++)
1215     {
1216       rumask = bitVectSetBit (rumask, sym->regs[j]->rIdx);
1217     }
1218
1219   return rumask;
1220 }
1221
1222 bitVect *
1223 z80_rUmaskForOp (operand * op)
1224 {
1225   return rUmaskForOp (op);
1226 }
1227
1228 /** Returns bit vector of registers used in iCode.
1229  */
1230 bitVect *
1231 regsUsedIniCode (iCode * ic)
1232 {
1233   bitVect *rmask = newBitVect (_G.nRegs);
1234
1235   /* do the special cases first */
1236   if (ic->op == IFX)
1237     {
1238       rmask = bitVectUnion (rmask,
1239                             rUmaskForOp (IC_COND (ic)));
1240       goto ret;
1241     }
1242
1243   /* for the jumptable */
1244   if (ic->op == JUMPTABLE)
1245     {
1246       rmask = bitVectUnion (rmask,
1247                             rUmaskForOp (IC_JTCOND (ic)));
1248
1249       goto ret;
1250     }
1251
1252   /* of all other cases */
1253   if (IC_LEFT (ic))
1254     rmask = bitVectUnion (rmask,
1255                           rUmaskForOp (IC_LEFT (ic)));
1256
1257
1258   if (IC_RIGHT (ic))
1259     rmask = bitVectUnion (rmask,
1260                           rUmaskForOp (IC_RIGHT (ic)));
1261
1262   if (IC_RESULT (ic))
1263     rmask = bitVectUnion (rmask,
1264                           rUmaskForOp (IC_RESULT (ic)));
1265
1266 ret:
1267   return rmask;
1268 }
1269
1270 /** For each instruction will determine the regsUsed.
1271  */
1272 static void 
1273 createRegMask (eBBlock ** ebbs, int count)
1274 {
1275   int i;
1276
1277   /* for all blocks */
1278   for (i = 0; i < count; i++)
1279     {
1280       iCode *ic;
1281
1282       if (ebbs[i]->noPath &&
1283           (ebbs[i]->entryLabel != entryLabel &&
1284            ebbs[i]->entryLabel != returnLabel))
1285         continue;
1286
1287       /* for all instructions */
1288       for (ic = ebbs[i]->sch; ic; ic = ic->next)
1289         {
1290
1291           int j;
1292
1293           if (SKIP_IC2 (ic) || !ic->rlive)
1294             continue;
1295
1296           /* first mark the registers used in this
1297              instruction */
1298           ic->rUsed = regsUsedIniCode (ic);
1299           _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
1300
1301           /* now create the register mask for those 
1302              registers that are in use : this is a
1303              super set of ic->rUsed */
1304           ic->rMask = newBitVect (_G.nRegs + 1);
1305
1306           /* for all live Ranges alive at this point */
1307           for (j = 1; j < ic->rlive->size; j++)
1308             {
1309               symbol *sym;
1310               int k;
1311
1312               /* if not alive then continue */
1313               if (!bitVectBitValue (ic->rlive, j))
1314                 continue;
1315
1316               /* find the live range we are interested in */
1317               if (!(sym = hTabItemWithKey (liveRanges, j)))
1318                 {
1319                   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1320                           "createRegMask cannot find live range");
1321                   exit (0);
1322                 }
1323
1324               /* if no register assigned to it */
1325               if (!sym->nRegs || sym->isspilt)
1326                 continue;
1327
1328               /* for all the registers allocated to it */
1329               for (k = 0; k < sym->nRegs; k++)
1330                 if (sym->regs[k])
1331                   ic->rMask =
1332                     bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
1333             }
1334         }
1335     }
1336 }
1337
1338 /** Returns the rematerialized string for a remat var.
1339  */
1340 char *
1341 rematStr (symbol * sym)
1342 {
1343   char *s = buffer;
1344   iCode *ic = sym->rematiCode;
1345
1346   while (1)
1347     {
1348
1349       /* if plus or minus print the right hand side */
1350       if (ic->op == '+' || ic->op == '-')
1351         {
1352           sprintf (s, "0x%04x %c ", (int) operandLitValue (IC_RIGHT (ic)),
1353                    ic->op);
1354           s += strlen (s);
1355           ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1356           continue;
1357         }
1358       /* we reached the end */
1359       sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
1360       break;
1361     }
1362
1363   return buffer;
1364 }
1365
1366 /*-----------------------------------------------------------------*/
1367 /* regTypeNum - computes the type & number of registers required   */
1368 /*-----------------------------------------------------------------*/
1369 static void 
1370 regTypeNum (void)
1371 {
1372   symbol *sym;
1373   int k;
1374
1375   /* for each live range do */
1376   for (sym = hTabFirstItem (liveRanges, &k); sym;
1377        sym = hTabNextItem (liveRanges, &k))
1378     {
1379
1380       /* if used zero times then no registers needed */
1381       if ((sym->liveTo - sym->liveFrom) == 0)
1382         continue;
1383
1384       D (D_ALLOC, ("regTypeNum: loop on sym %p\n", sym));
1385
1386       /* if the live range is a temporary */
1387       if (sym->isitmp)
1388         {
1389
1390           /* if the type is marked as a conditional */
1391           if (sym->regType == REG_CND)
1392             continue;
1393
1394           /* if used in return only then we don't 
1395              need registers */
1396           if (sym->ruonly || sym->accuse)
1397             {
1398               if (IS_AGGREGATE (sym->type) || sym->isptr)
1399                 sym->type = aggrToPtr (sym->type, FALSE);
1400               continue;
1401             }
1402
1403           /* if not then we require registers */
1404           D (D_ALLOC, ("regTypeNum: isagg %u nRegs %u type %p\n", IS_AGGREGATE (sym->type) || sym->isptr, sym->nRegs, sym->type));
1405           sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
1406                         getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1407                         getSize (sym->type));
1408           D (D_ALLOC, ("regTypeNum: setting nRegs of %s (%p) to %u\n", sym->name, sym, sym->nRegs));
1409
1410           D (D_ALLOC, ("regTypeNum: setup to assign regs sym %p\n", sym));
1411
1412           if (sym->nRegs > 4)
1413             {
1414               fprintf (stderr, "allocated more than 4 or 0 registers for type ");
1415               printTypeChain (sym->type, stderr);
1416               fprintf (stderr, "\n");
1417             }
1418
1419           /* determine the type of register required */
1420           /* Always general purpose */
1421           sym->regType = REG_GPR;
1422
1423         }
1424       else
1425         {
1426           /* for the first run we don't provide */
1427           /* registers for true symbols we will */
1428           /* see how things go                  */
1429           D (D_ALLOC, ("regTypeNum: #2 setting num of %p to 0\n", sym));
1430           sym->nRegs = 0;
1431         }
1432     }
1433
1434 }
1435
1436 /** Mark all registers as free.
1437  */
1438 static void 
1439 freeAllRegs ()
1440 {
1441   int i;
1442
1443   D (D_ALLOC, ("freeAllRegs: running.\n"));
1444
1445   for (i = 0; i < _G.nRegs; i++)
1446     regsZ80[i].isFree = 1;
1447 }
1448
1449 /*-----------------------------------------------------------------*/
1450 /* deallocStackSpil - this will set the stack pointer back         */
1451 /*-----------------------------------------------------------------*/
1452 DEFSETFUNC (deallocStackSpil)
1453 {
1454   symbol *sym = item;
1455
1456   deallocLocal (sym);
1457   return 0;
1458 }
1459
1460 /** Register reduction for assignment.
1461  */
1462 static int 
1463 packRegsForAssign (iCode * ic, eBBlock * ebp)
1464 {
1465   iCode *dic, *sic;
1466
1467   D (D_ALLOC, ("packRegsForAssign: running on ic %p\n", ic));
1468
1469   if (!IS_ITEMP (IC_RIGHT (ic)) ||
1470       OP_SYMBOL (IC_RIGHT (ic))->isind ||
1471       OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
1472     {
1473       return 0;
1474     }
1475
1476 #if 0
1477   /* if the true symbol is defined in far space or on stack
1478      then we should not since this will increase register pressure */
1479   if (isOperandInFarSpace (IC_RESULT (ic)))
1480     {
1481       if ((dic = farSpacePackable (ic)))
1482         goto pack;
1483       else
1484         return 0;
1485     }
1486 #endif
1487
1488   /* find the definition of iTempNN scanning backwards if we find a 
1489      a use of the true symbol in before we find the definition then 
1490      we cannot */
1491   for (dic = ic->prev; dic; dic = dic->prev)
1492     {
1493       /* if there is a function call and this is
1494          a parameter & not my parameter then don't pack it */
1495       if ((dic->op == CALL || dic->op == PCALL) &&
1496           (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
1497            !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
1498         {
1499           dic = NULL;
1500           break;
1501         }
1502
1503       if (SKIP_IC2 (dic))
1504         continue;
1505
1506       if (IS_SYMOP (IC_RESULT (dic)) &&
1507           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1508         {
1509           break;
1510         }
1511
1512       if (IS_SYMOP (IC_RIGHT (dic)) &&
1513           (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
1514            IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
1515         {
1516           dic = NULL;
1517           break;
1518         }
1519
1520       if (IS_SYMOP (IC_LEFT (dic)) &&
1521           (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
1522            IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
1523         {
1524           dic = NULL;
1525           break;
1526         }
1527 #if 0
1528       if (POINTER_SET (dic) &&
1529           IC_RESULT (dic)->key == IC_RESULT (ic)->key)
1530         {
1531           dic = NULL;
1532           break;
1533         }
1534 #endif
1535     }
1536
1537   if (!dic)
1538     return 0;                   /* did not find */
1539
1540   /* if the result is on stack or iaccess then it must be
1541      the same atleast one of the operands */
1542   if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
1543       OP_SYMBOL (IC_RESULT (ic))->iaccess)
1544     {
1545
1546       /* the operation has only one symbol
1547          operator then we can pack */
1548       if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
1549           (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
1550         goto pack;
1551
1552       if (!((IC_LEFT (dic) &&
1553              IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
1554             (IC_RIGHT (dic) &&
1555              IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
1556         return 0;
1557     }
1558 pack:
1559   /* found the definition */
1560   /* replace the result with the result of */
1561   /* this assignment and remove this assignment */
1562   IC_RESULT (dic) = IC_RESULT (ic);
1563
1564   if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
1565     {
1566       OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
1567     }
1568   /* delete from liverange table also 
1569      delete from all the points inbetween and the new
1570      one */
1571   for (sic = dic; sic != ic; sic = sic->next)
1572     {
1573       bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
1574       if (IS_ITEMP (IC_RESULT (dic)))
1575         bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
1576     }
1577
1578   remiCodeFromeBBlock (ebp, ic);
1579   // PENDING: Check vs mcs51
1580   return 1;
1581 }
1582
1583 /** Scanning backwards looks for first assig found.
1584  */
1585 iCode *
1586 findAssignToSym (operand * op, iCode * ic)
1587 {
1588   iCode *dic;
1589
1590   for (dic = ic->prev; dic; dic = dic->prev)
1591     {
1592
1593       /* if definition by assignment */
1594       if (dic->op == '=' &&
1595           !POINTER_SET (dic) &&
1596           IC_RESULT (dic)->key == op->key)
1597         /*      &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) */
1598         {
1599
1600           /* we are interested only if defined in far space */
1601           /* or in stack space in case of + & - */
1602
1603           /* if assigned to a non-symbol then return
1604              true */
1605           if (!IS_SYMOP (IC_RIGHT (dic)))
1606             break;
1607
1608           /* if the symbol is in far space then
1609              we should not */
1610           if (isOperandInFarSpace (IC_RIGHT (dic)))
1611             return NULL;
1612
1613           /* for + & - operations make sure that
1614              if it is on the stack it is the same
1615              as one of the three operands */
1616           if ((ic->op == '+' || ic->op == '-') &&
1617               OP_SYMBOL (IC_RIGHT (dic))->onStack)
1618             {
1619
1620               if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
1621                   IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
1622                   IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
1623                 return NULL;
1624             }
1625
1626           break;
1627
1628         }
1629
1630       /* if we find an usage then we cannot delete it */
1631       if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
1632         return NULL;
1633
1634       if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
1635         return NULL;
1636
1637       if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
1638         return NULL;
1639     }
1640
1641   /* now make sure that the right side of dic
1642      is not defined between ic & dic */
1643   if (dic)
1644     {
1645       iCode *sic = dic->next;
1646
1647       for (; sic != ic; sic = sic->next)
1648         if (IC_RESULT (sic) &&
1649             IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
1650           return NULL;
1651     }
1652
1653   return dic;
1654
1655
1656 }
1657
1658 #if !DISABLE_PACKREGSFORSUPPORT
1659 // PENDING
1660
1661 /*-----------------------------------------------------------------*/
1662 /* packRegsForSupport :- reduce some registers for support calls   */
1663 /*-----------------------------------------------------------------*/
1664 static int 
1665 packRegsForSupport (iCode * ic, eBBlock * ebp)
1666 {
1667   int change = 0;
1668   /* for the left & right operand :- look to see if the
1669      left was assigned a true symbol in far space in that
1670      case replace them */
1671   D (D_ALLOC, ("packRegsForSupport: running on ic %p\n", ic));
1672
1673   if (IS_ITEMP (IC_LEFT (ic)) &&
1674       OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
1675     {
1676       iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
1677       iCode *sic;
1678
1679       if (!dic)
1680         goto right;
1681
1682       /* found it we need to remove it from the
1683          block */
1684       for (sic = dic; sic != ic; sic = sic->next)
1685         bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
1686
1687       IC_LEFT (ic)->operand.symOperand =
1688         IC_RIGHT (dic)->operand.symOperand;
1689       IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
1690       remiCodeFromeBBlock (ebp, dic);
1691       // PENDING: Check vs mcs51
1692       change++;
1693     }
1694
1695   /* do the same for the right operand */
1696 right:
1697   if (!change &&
1698       IS_ITEMP (IC_RIGHT (ic)) &&
1699       OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
1700     {
1701       iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
1702       iCode *sic;
1703
1704       if (!dic)
1705         return change;
1706
1707       /* found it we need to remove it from the block */
1708       for (sic = dic; sic != ic; sic = sic->next)
1709         bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
1710
1711       IC_RIGHT (ic)->operand.symOperand =
1712         IC_RIGHT (dic)->operand.symOperand;
1713       IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
1714
1715       remiCodeFromeBBlock (ebp, dic);
1716       // PENDING: vs mcs51
1717       change++;
1718     }
1719
1720   return change;
1721 }
1722 #endif
1723
1724 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
1725
1726 /** Will reduce some registers for single use.
1727  */
1728 static iCode *
1729 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
1730 {
1731   bitVect *uses;
1732   iCode *dic, *sic;
1733
1734   // PENDING: Disable
1735   D (D_ALLOC, ("packRegsForOneUse: running on ic %p\n", ic));
1736
1737   /* if returning a literal then do nothing */
1738   if (!IS_SYMOP (op))
1739     return NULL;
1740
1741   /* only upto 2 bytes since we cannot predict
1742      the usage of b, & acc */
1743   if (getSize (operandType (op)) > 2 &&
1744       ic->op != RETURN &&
1745       ic->op != SEND)
1746     return NULL;
1747
1748   /* this routine will mark the a symbol as used in one 
1749      instruction use only && if the defintion is local 
1750      (ie. within the basic block) && has only one definition &&
1751      that definiion is either a return value from a 
1752      function or does not contain any variables in
1753      far space */
1754   uses = bitVectCopy (OP_USES (op));
1755   bitVectUnSetBit (uses, ic->key);      /* take away this iCode */
1756   if (!bitVectIsZero (uses))    /* has other uses */
1757     return NULL;
1758
1759   /* if it has only one defintion */
1760   if (bitVectnBitsOn (OP_DEFS (op)) > 1)
1761     return NULL;                /* has more than one definition */
1762
1763   /* get the that definition */
1764   if (!(dic =
1765         hTabItemWithKey (iCodehTab,
1766                          bitVectFirstBit (OP_DEFS (op)))))
1767     return NULL;
1768
1769   /* found the definition now check if it is local */
1770   if (dic->seq < ebp->fSeq ||
1771       dic->seq > ebp->lSeq)
1772     return NULL;                /* non-local */
1773
1774   /* now check if it is the return from a function call */
1775   if (dic->op == CALL || dic->op == PCALL)
1776     {
1777       if (ic->op != SEND && ic->op != RETURN)
1778         {
1779           OP_SYMBOL (op)->ruonly = 1;
1780           return dic;
1781         }
1782       dic = dic->next;
1783     }
1784
1785   /* otherwise check that the definition does
1786      not contain any symbols in far space */
1787   if (isOperandInFarSpace (IC_LEFT (dic)) ||
1788       isOperandInFarSpace (IC_RIGHT (dic)) ||
1789       IS_OP_RUONLY (IC_LEFT (ic)) ||
1790       IS_OP_RUONLY (IC_RIGHT (ic)))
1791     {
1792       return NULL;
1793     }
1794
1795   /* if pointer set then make sure the pointer is one byte */
1796   if (POINTER_SET (dic))
1797     return NULL;
1798
1799   if (POINTER_GET (dic))
1800     return NULL;
1801
1802   sic = dic;
1803
1804   /* also make sure the intervenening instructions
1805      don't have any thing in far space */
1806   for (dic = dic->next; dic && dic != ic; dic = dic->next)
1807     {
1808       /* if there is an intervening function call then no */
1809       if (dic->op == CALL || dic->op == PCALL)
1810         return NULL;
1811       /* if pointer set then make sure the pointer
1812          is one byte */
1813       if (POINTER_SET (dic))
1814         return NULL;
1815
1816       if (POINTER_GET (dic))
1817         return NULL;
1818
1819       /* if address of & the result is remat the okay */
1820       if (dic->op == ADDRESS_OF &&
1821           OP_SYMBOL (IC_RESULT (dic))->remat)
1822         continue;
1823
1824       /* if left or right or result is in far space */
1825       if (isOperandInFarSpace (IC_LEFT (dic)) ||
1826           isOperandInFarSpace (IC_RIGHT (dic)) ||
1827           isOperandInFarSpace (IC_RESULT (dic)) ||
1828           IS_OP_RUONLY (IC_LEFT (dic)) ||
1829           IS_OP_RUONLY (IC_RIGHT (dic)) ||
1830           IS_OP_RUONLY (IC_RESULT (dic)))
1831         {
1832           return NULL;
1833         }
1834     }
1835
1836   OP_SYMBOL (op)->ruonly = 1;
1837   return sic;
1838 }
1839
1840 /*-----------------------------------------------------------------*/
1841 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
1842 /*-----------------------------------------------------------------*/
1843 static bool 
1844 isBitwiseOptimizable (iCode * ic)
1845 {
1846   sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
1847
1848   /* bitwise operations are considered optimizable
1849      under the following conditions (Jean-Louis VERN) 
1850
1851      x & lit
1852      bit & bit
1853      bit & x
1854      bit ^ bit
1855      bit ^ x
1856      x   ^ lit
1857      x   | lit
1858      bit | bit
1859      bit | x
1860    */
1861   if (IS_LITERAL (rtype))
1862     return TRUE;
1863   return FALSE;
1864 }
1865
1866 /** Optimisations:
1867     Certian assignments involving pointers can be temporarly stored
1868     in HL.  Esp.
1869 genAssign
1870     ld  iy,#_Blah
1871     ld  bc,(iy)
1872 genAssign (ptr)
1873     ld  hl,bc
1874     ld  iy,#_Blah2
1875     ld  (iy),(hl)
1876 */
1877
1878 #if !DISABLE_PACKREGSFORACCUSE
1879 // PENDING
1880
1881 /** Pack registers for acc use.
1882     When the result of this operation is small and short lived it may
1883     be able to be stored in the accumelator.
1884  */
1885 static void 
1886 packRegsForAccUse (iCode * ic)
1887 {
1888   iCode *uic;
1889
1890   /* if + or - then it has to be one byte result */
1891   if ((ic->op == '+' || ic->op == '-')
1892       && getSize (operandType (IC_RESULT (ic))) > 1)
1893     return;
1894
1895   /* if shift operation make sure right side is not a literal */
1896   if (ic->op == RIGHT_OP &&
1897       (isOperandLiteral (IC_RIGHT (ic)) ||
1898        getSize (operandType (IC_RESULT (ic))) > 1))
1899     return;
1900
1901   if (ic->op == LEFT_OP &&
1902       (isOperandLiteral (IC_RIGHT (ic)) ||
1903        getSize (operandType (IC_RESULT (ic))) > 1))
1904     return;
1905
1906   /* has only one definition */
1907   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
1908     return;
1909
1910   /* has only one use */
1911   if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
1912     return;
1913
1914   /* and the usage immediately follows this iCode */
1915   if (!(uic = hTabItemWithKey (iCodehTab,
1916                                bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
1917     return;
1918
1919   if (ic->next != uic)
1920     return;
1921
1922   /* if it is a conditional branch then we definitely can */
1923   if (uic->op == IFX)
1924     goto accuse;
1925
1926   if (uic->op == JUMPTABLE)
1927     return;
1928
1929 #if 0
1930   /* if the usage is not is an assignment or an 
1931      arithmetic / bitwise / shift operation then not */
1932   if (POINTER_SET (uic) &&
1933       getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
1934     return;
1935 #endif
1936
1937   if (uic->op != '=' &&
1938       !IS_ARITHMETIC_OP (uic) &&
1939       !IS_BITWISE_OP (uic) &&
1940       uic->op != LEFT_OP &&
1941       uic->op != RIGHT_OP)
1942     return;
1943
1944   /* if used in ^ operation then make sure right is not a 
1945      literl */
1946   if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
1947     return;
1948
1949   /* if shift operation make sure right side is not a literal */
1950   if (uic->op == RIGHT_OP &&
1951       (isOperandLiteral (IC_RIGHT (uic)) ||
1952        getSize (operandType (IC_RESULT (uic))) > 1))
1953     return;
1954
1955   if (uic->op == LEFT_OP &&
1956       (isOperandLiteral (IC_RIGHT (uic)) ||
1957        getSize (operandType (IC_RESULT (uic))) > 1))
1958     return;
1959
1960 #if 0
1961   /* make sure that the result of this icode is not on the
1962      stack, since acc is used to compute stack offset */
1963   if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
1964       OP_SYMBOL (IC_RESULT (uic))->onStack)
1965     return;
1966 #endif
1967
1968 #if 0
1969   /* if either one of them in far space then we cannot */
1970   if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
1971        isOperandInFarSpace (IC_LEFT (uic))) ||
1972       (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
1973        isOperandInFarSpace (IC_RIGHT (uic))))
1974     return;
1975 #endif
1976
1977   /* if the usage has only one operand then we can */
1978   if (IC_LEFT (uic) == NULL ||
1979       IC_RIGHT (uic) == NULL)
1980     goto accuse;
1981
1982   /* make sure this is on the left side if not
1983      a '+' since '+' is commutative */
1984   if (ic->op != '+' &&
1985       IC_LEFT (uic)->key != IC_RESULT (ic)->key)
1986     return;
1987
1988   // See mcs51 ralloc for reasoning
1989 #if 0
1990   /* if one of them is a literal then we can */
1991   if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
1992       (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
1993     {
1994       goto accuse;
1995       return;
1996     }
1997 #endif
1998
1999 /** This is confusing :)  Guess for now */
2000   if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
2001       (IS_ITEMP (IC_RIGHT (uic)) ||
2002        (IS_TRUE_SYMOP (IC_RIGHT (uic)))))
2003     goto accuse;
2004
2005   if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
2006       (IS_ITEMP (IC_LEFT (uic)) ||
2007        (IS_TRUE_SYMOP (IC_LEFT (uic)))))
2008     goto accuse;
2009   return;
2010 accuse:
2011   OP_SYMBOL (IC_RESULT (ic))->accuse = ACCUSE_A;
2012 }
2013 #endif
2014
2015 static void 
2016 packRegsForHLUse (iCode * ic)
2017 {
2018   iCode *uic;
2019
2020   if (IS_GB)
2021     return;
2022
2023   /* has only one definition */
2024   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
2025     return;
2026
2027   /* has only one use */
2028   if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
2029     return;
2030
2031   /* and the usage immediately follows this iCode */
2032   if (!(uic = hTabItemWithKey (iCodehTab,
2033                                bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
2034     return;
2035
2036   if (ic->next != uic)
2037     return;
2038
2039   if (ic->op == CAST && uic->op == IPUSH)
2040     goto hluse;
2041   if (ic->op == ADDRESS_OF && uic->op == IPUSH)
2042     goto hluse;
2043   if (ic->op == CALL && ic->parmBytes == 0 && (uic->op == '-' || uic->op == '+'))
2044     goto hluse;
2045   return;
2046 hluse:
2047   OP_SYMBOL (IC_RESULT (ic))->accuse = ACCUSE_HL;
2048 }
2049
2050 static bool 
2051 opPreservesA (iCode * ic, iCode * uic)
2052 {
2053   if (uic->op == IFX)
2054     {
2055       /* If we've gotten this far then the thing to compare must be
2056          small enough and must be in A.
2057       */
2058       return TRUE;
2059     }
2060
2061   if (uic->op == JUMPTABLE)
2062     {
2063       D (D_ACCUSE2, ("  + Dropping as operation is a Jumptable\n"));
2064       return FALSE;
2065     }
2066
2067   /* A pointer assign preserves A if A is the left value. */
2068   if (uic->op == '=' && POINTER_SET (uic))
2069     {
2070       return TRUE;
2071     }
2072
2073   /* if the usage has only one operand then we can */
2074   /* PENDING: check */
2075   if (IC_LEFT (uic) == NULL ||
2076       IC_RIGHT (uic) == NULL)
2077     {
2078       D (D_ACCUSE2, ("  + Dropping as operation has only one operand\n"));
2079       return FALSE;
2080     }
2081
2082   /* PENDING: check this rule */
2083   if (getSize (operandType (IC_RESULT (uic))) > 1)
2084     {
2085       D (D_ACCUSE2, ("  + Dropping as operation has size is too big\n"));
2086       return FALSE;
2087     }
2088
2089
2090   /* Disabled all of the old rules as they weren't verified and have
2091      caused at least one problem.
2092    */
2093   return FALSE;
2094 }
2095
2096 static bool
2097 opIgnoresA (iCode * ic, iCode * uic)
2098 {
2099   /* A increment of an iTemp by a constant is OK. */
2100   if ( uic->op == '+' &&
2101        IS_ITEMP (IC_LEFT (uic)) &&
2102        IS_ITEMP (IC_RESULT (uic)) &&
2103        IS_OP_LITERAL (IC_RIGHT (uic)))
2104     {
2105       unsigned int icount = (unsigned int) floatFromVal (IC_RIGHT (uic)->operand.valOperand);
2106
2107       /* Being an ITEMP means that we're already a symbol. */
2108       if (icount == 1 &&
2109           IC_RESULT (uic)->operand.symOperand->key == IC_LEFT (uic)->operand.symOperand->key
2110           )
2111         {
2112           return TRUE;
2113         }
2114     }
2115
2116   return FALSE;
2117 }
2118
2119
2120 /* Some optimisation cases:
2121
2122    1. Part of memcpy
2123 ;       genPointerGet
2124         ld      l,-4(ix)
2125         ld      h,-3(ix)
2126         ld      c,(hl)
2127 ;       genPlus
2128         inc     -4(ix)
2129         jp      nz,00108$
2130         inc     -3(ix)
2131 00108$:
2132 ;       genAssign (pointer)
2133         ld      a,c
2134         ld      (de),a
2135  
2136       want to optimise down to:
2137         ld       hl,-4(ix) ...
2138         ld       a,(hl)
2139         inc      -4(ix).w  ...
2140         ld       (de),a
2141
2142       So genPointer get is OK
2143       genPlus where the right is constant, left is iTemp, and result is same as left
2144       genAssign (pointer) is OK
2145
2146     2. Part of _strcpy
2147 ;       genPointerGet
2148         ld      a,(de)
2149         ld      c,a
2150 ;       genIfx
2151         xor     a,a
2152         or      a,c
2153         jp      z,00103$
2154 ;       _strcpy.c 40
2155 ;       genAssign (pointer)
2156 ;       AOP_STK for _strcpy_to_1_1
2157         ld      l,-2(ix)
2158         ld      h,-1(ix)
2159         ld      (hl),c
2160
2161       want to optimise down to:
2162         ld      a,(de)
2163         or      a,a
2164         jp      z,00103$
2165         ld      (bc),a
2166       
2167       So genIfx where IC_COND has size of 1 and is a constant.
2168 */
2169
2170 /** Pack registers for acc use.
2171     When the result of this operation is small and short lived it may
2172     be able to be stored in the accumulator.
2173
2174     Note that the 'A preserving' list is currently emperical :)
2175  */
2176 static void 
2177 packRegsForAccUse2 (iCode * ic)
2178 {
2179   iCode *uic;
2180
2181   D (D_ALLOC, ("packRegsForAccUse2: running on ic %p\n", ic));
2182
2183   /* Filter out all but those 'good' commands */
2184   if (
2185        !POINTER_GET (ic) &&
2186        ic->op != '+' &&
2187        !IS_BITWISE_OP (ic) &&
2188        ic->op != '=' &&
2189        ic->op != EQ_OP &&
2190        ic->op != CAST &&
2191        1)
2192     {
2193       D (D_ACCUSE2, ("  + Dropping as not a 'good' source command\n"));
2194       return;
2195     }
2196
2197   /* if + or - then it has to be one byte result.
2198      MLH: Ok.
2199    */
2200   if ((ic->op == '+' || ic->op == '-')
2201       && getSize (operandType (IC_RESULT (ic))) > 1)
2202     {
2203       D (D_ACCUSE2, ("  + Dropping as it's a big + or -\n"));
2204       return;
2205     }
2206
2207   /* has only one definition */
2208   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
2209     {
2210       D (D_ACCUSE2, ("  + Dropping as it has more than one definition\n"));
2211       return;
2212     }
2213
2214   /* Right.  We may be able to propagate it through if:
2215      For each in the chain of uses the intermediate is OK.
2216    */
2217   /* Get next with 'uses result' bit on
2218      If this->next == next
2219      Validate use of next
2220      If OK, increase count
2221    */
2222   /* and the usage immediately follows this iCode */
2223   if (!(uic = hTabItemWithKey (iCodehTab,
2224                                bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
2225     {
2226       D (D_ACCUSE2, ("  + Dropping as usage does not follow first\n"));
2227       return;
2228     }
2229
2230   {
2231     /* Create a copy of the OP_USES bit vect */
2232     bitVect *uses = bitVectCopy (OP_USES (IC_RESULT (ic)));
2233     int setBit;
2234     iCode *scan = ic, *next;
2235
2236     do
2237       {
2238         setBit = bitVectFirstBit (uses);
2239         next = hTabItemWithKey (iCodehTab, setBit);
2240         if (scan->next == next)
2241           {
2242             D (D_ACCUSE2_VERBOSE, ("  ! Is next in line\n"));
2243
2244             bitVectUnSetBit (uses, setBit);
2245             /* Still contigous. */
2246             if (!opPreservesA (ic, next))
2247               {
2248                 D (D_ACCUSE2, ("  + Dropping as operation doesn't preserve A\n"));
2249                 return;
2250               }
2251             D (D_ACCUSE2_VERBOSE, ("  ! Preserves A, so continue scanning\n"));
2252             scan = next;
2253           }
2254         else if (scan->next == NULL && bitVectnBitsOn (uses) == 1 && next != NULL)
2255           {
2256             if (next->prev == NULL)
2257               {
2258                 if (!opPreservesA (ic, next))
2259                   {
2260                     D (D_ACCUSE2, ("  + Dropping as operation doesn't preserve A #2\n"));
2261                     return;
2262                   }
2263                 bitVectUnSetBit (uses, setBit);
2264                 scan = next;
2265               }
2266             else 
2267               {
2268                 D (D_ACCUSE2, ("  + Dropping as last in list and next doesn't start a block\n"));
2269                 return;
2270               }
2271           }
2272         else if (scan->next == NULL)
2273           {
2274             D (D_ACCUSE2, ("  + Dropping as hit the end of the list\n"));
2275             D (D_ACCUSE2, ("  + Next in htab: %p\n", next));
2276             return;
2277           }
2278         else
2279           {
2280             if (opIgnoresA (ic, scan->next))
2281               {
2282                 /* Safe for now. */
2283                 scan = scan->next;
2284                 D (D_ACCUSE2_VERBOSE, ("  ! Op ignores A, so continue scanning\n"));
2285               }
2286             else
2287               {
2288                 D (D_ACCUSE2, ("  + Dropping as parts are not consecuitive and intermediate might use A\n"));
2289                 return;
2290               }
2291           }
2292       }
2293     while (!bitVectIsZero (uses));
2294
2295     OP_SYMBOL (IC_RESULT (ic))->accuse = ACCUSE_A;
2296     return;
2297   }
2298
2299   /* OLD CODE FOLLOWS */
2300   /* if it is a conditional branch then we definitely can
2301      MLH: Depends.
2302    */
2303 #if 0
2304   if (uic->op == IFX)
2305     goto accuse;
2306
2307   /* MLH: Depends. */
2308   if (uic->op == JUMPTABLE)
2309     return;
2310 #endif
2311
2312   /* if the usage is not is an assignment or an 
2313      arithmetic / bitwise / shift operation then not.
2314      MLH: Pending:  Invalid.  Our pointer sets are always peechy.
2315    */
2316 #if 0
2317   if (POINTER_SET (uic) &&
2318       getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
2319     {
2320       printf ("e5 %u\n", getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)));
2321       return;
2322     }
2323 #endif
2324
2325   printf ("1\n");
2326   if (uic->op != '=' &&
2327       !IS_ARITHMETIC_OP (uic) &&
2328       !IS_BITWISE_OP (uic) &&
2329       uic->op != LEFT_OP &&
2330       uic->op != RIGHT_OP)
2331     {
2332       printf ("e6\n");
2333       return;
2334     }
2335
2336   /* if used in ^ operation then make sure right is not a 
2337      literl */
2338   if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
2339     return;
2340
2341   /* if shift operation make sure right side is not a literal */
2342   if (uic->op == RIGHT_OP &&
2343       (isOperandLiteral (IC_RIGHT (uic)) ||
2344        getSize (operandType (IC_RESULT (uic))) > 1))
2345     return;
2346
2347   if (uic->op == LEFT_OP &&
2348       (isOperandLiteral (IC_RIGHT (uic)) ||
2349        getSize (operandType (IC_RESULT (uic))) > 1))
2350     return;
2351
2352 #if 0
2353   /* make sure that the result of this icode is not on the
2354      stack, since acc is used to compute stack offset */
2355   if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
2356       OP_SYMBOL (IC_RESULT (uic))->onStack)
2357     return;
2358 #endif
2359
2360 #if 0
2361   /* if either one of them in far space then we cannot */
2362   if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
2363        isOperandInFarSpace (IC_LEFT (uic))) ||
2364       (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
2365        isOperandInFarSpace (IC_RIGHT (uic))))
2366     return;
2367 #endif
2368
2369   /* if the usage has only one operand then we can */
2370   if (IC_LEFT (uic) == NULL ||
2371       IC_RIGHT (uic) == NULL)
2372     goto accuse;
2373
2374   /* make sure this is on the left side if not
2375      a '+' since '+' is commutative */
2376   if (ic->op != '+' &&
2377       IC_LEFT (uic)->key != IC_RESULT (ic)->key)
2378     return;
2379
2380   /* if one of them is a literal then we can */
2381   if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
2382       (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
2383     {
2384       goto accuse;
2385       return;
2386     }
2387
2388 /** This is confusing :)  Guess for now */
2389   if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
2390       (IS_ITEMP (IC_RIGHT (uic)) ||
2391        (IS_TRUE_SYMOP (IC_RIGHT (uic)))))
2392     goto accuse;
2393
2394   if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
2395       (IS_ITEMP (IC_LEFT (uic)) ||
2396        (IS_TRUE_SYMOP (IC_LEFT (uic)))))
2397     goto accuse;
2398   return;
2399 accuse:
2400   printf ("acc ok!\n");
2401   OP_SYMBOL (IC_RESULT (ic))->accuse = ACCUSE_A;
2402 }
2403
2404 /** Does some transformations to reduce register pressure.
2405  */
2406 static void 
2407 packRegisters (eBBlock * ebp)
2408 {
2409   iCode *ic;
2410   int change = 0;
2411
2412   D (D_ALLOC, ("packRegisters: entered.\n"));
2413
2414   while (1 && !DISABLE_PACK_ASSIGN)
2415     {
2416       change = 0;
2417       /* look for assignments of the form */
2418       /* iTempNN = TRueSym (someoperation) SomeOperand */
2419       /*       ....                       */
2420       /* TrueSym := iTempNN:1             */
2421       for (ic = ebp->sch; ic; ic = ic->next)
2422         {
2423           /* find assignment of the form TrueSym := iTempNN:1 */
2424           if (ic->op == '=' && !POINTER_SET (ic))
2425             change += packRegsForAssign (ic, ebp);
2426         }
2427       if (!change)
2428         break;
2429     }
2430
2431   for (ic = ebp->sch; ic; ic = ic->next)
2432     {
2433       /* Safe: address of a true sym is always constant. */
2434       /* if this is an itemp & result of a address of a true sym 
2435          then mark this as rematerialisable   */
2436       D (D_ALLOC, ("packRegisters: looping on ic %p\n", ic));
2437
2438       if (ic->op == ADDRESS_OF &&
2439           IS_ITEMP (IC_RESULT (ic)) &&
2440           IS_TRUE_SYMOP (IC_LEFT (ic)) &&
2441           bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2442           !OP_SYMBOL (IC_LEFT (ic))->onStack)
2443         {
2444
2445           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2446           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2447           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2448         }
2449
2450       /* Safe: just propagates the remat flag */
2451       /* if straight assignment then carry remat flag if this is the
2452          only definition */
2453       if (ic->op == '=' &&
2454           !POINTER_SET (ic) &&
2455           IS_SYMOP (IC_RIGHT (ic)) &&
2456           OP_SYMBOL (IC_RIGHT (ic))->remat &&
2457           bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
2458         {
2459
2460           OP_SYMBOL (IC_RESULT (ic))->remat =
2461             OP_SYMBOL (IC_RIGHT (ic))->remat;
2462           OP_SYMBOL (IC_RESULT (ic))->rematiCode =
2463             OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
2464         }
2465
2466       /* if the condition of an if instruction is defined in the
2467          previous instruction then mark the itemp as a conditional */
2468       if ((IS_CONDITIONAL (ic) ||
2469            ((ic->op == BITWISEAND ||
2470              ic->op == '|' ||
2471              ic->op == '^') &&
2472             isBitwiseOptimizable (ic))) &&
2473           ic->next && ic->next->op == IFX &&
2474           bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
2475           isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
2476           OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2477         {
2478
2479           OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
2480           continue;
2481         }
2482
2483 #if 0
2484       /* reduce for support function calls */
2485       if (ic->supportRtn || ic->op == '+' || ic->op == '-')
2486         packRegsForSupport (ic, ebp);
2487 #endif
2488
2489       /* if pointer set & left has a size more than
2490          one and right is not in far space */
2491       if (!DISABLE_PACK_ONE_USE &&
2492           POINTER_SET (ic) &&
2493           /* MLH: no such thing.
2494              !isOperandInFarSpace(IC_RIGHT(ic)) && */
2495           !OP_SYMBOL (IC_RESULT (ic))->remat &&
2496           !IS_OP_RUONLY (IC_RIGHT (ic)) &&
2497           getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
2498         {
2499
2500           packRegsForOneuse (ic, IC_RESULT (ic), ebp);
2501         }
2502
2503       /* if pointer get */
2504       if (!DISABLE_PACK_ONE_USE &&
2505           POINTER_GET (ic) &&
2506       /* MLH: dont have far space
2507          !isOperandInFarSpace(IC_RESULT(ic))&& */
2508           !OP_SYMBOL (IC_LEFT (ic))->remat &&
2509           !IS_OP_RUONLY (IC_RESULT (ic)) &&
2510           getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
2511         {
2512
2513           packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2514         }
2515
2516       /* pack registers for accumulator use, when the result of an
2517          arithmetic or bit wise operation has only one use, that use is
2518          immediately following the defintion and the using iCode has
2519          only one operand or has two operands but one is literal & the
2520          result of that operation is not on stack then we can leave the
2521          result of this operation in acc:b combination */
2522
2523       if (!DISABLE_PACK_HL && IS_ITEMP (IC_RESULT (ic)))
2524         {
2525           packRegsForHLUse (ic);
2526         }
2527
2528       if (!DISABLE_PACK_ACC && IS_ITEMP (IC_RESULT (ic)) &&
2529           getSize (operandType (IC_RESULT (ic))) == 1)
2530         {
2531           packRegsForAccUse2 (ic);
2532         }
2533     }
2534 }
2535
2536 /*-----------------------------------------------------------------*/
2537 /* assignRegisters - assigns registers to each live range as need  */
2538 /*-----------------------------------------------------------------*/
2539 void 
2540 z80_assignRegisters (eBBlock ** ebbs, int count)
2541 {
2542   iCode *ic;
2543   int i;
2544
2545   D (D_ALLOC, ("\n-> z80_assignRegisters: entered.\n"));
2546
2547   setToNull ((void *) &_G.funcrUsed);
2548   _G.stackExtend = _G.dataExtend = 0;
2549
2550   if (IS_GB)
2551     {
2552       /* DE is required for the code gen. */
2553       _G.nRegs = GBZ80_MAX_REGS;
2554       regsZ80 = _gbz80_regs;
2555     }
2556   else
2557     {
2558       _G.nRegs = Z80_MAX_REGS;
2559       regsZ80 = _z80_regs;
2560     }
2561
2562   /* change assignments this will remove some
2563      live ranges reducing some register pressure */
2564   for (i = 0; i < count; i++)
2565     packRegisters (ebbs[i]);
2566
2567   if (options.dump_pack)
2568     dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
2569
2570   /* first determine for each live range the number of 
2571      registers & the type of registers required for each */
2572   regTypeNum ();
2573
2574   /* and serially allocate registers */
2575   serialRegAssign (ebbs, count);
2576
2577   /* if stack was extended then tell the user */
2578   if (_G.stackExtend)
2579     {
2580 /*      werror(W_TOOMANY_SPILS,"stack", */
2581 /*             _G.stackExtend,currFunc->name,""); */
2582       _G.stackExtend = 0;
2583     }
2584
2585   if (_G.dataExtend)
2586     {
2587 /*      werror(W_TOOMANY_SPILS,"data space", */
2588 /*             _G.dataExtend,currFunc->name,""); */
2589       _G.dataExtend = 0;
2590     }
2591
2592   if (options.dump_rassgn) {
2593     dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
2594     dumpLiveRanges (DUMP_LRANGE, liveRanges);
2595   }
2596
2597   /* after that create the register mask
2598      for each of the instruction */
2599   createRegMask (ebbs, count);
2600
2601   /* now get back the chain */
2602   ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
2603
2604   /* redo that offsets for stacked automatic variables */
2605   redoStackOffsets ();
2606
2607   genZ80Code (ic);
2608
2609   /* free up any stackSpil locations allocated */
2610   applyToSet (_G.stackSpil, deallocStackSpil);
2611   _G.slocNum = 0;
2612   setToNull ((void **) &_G.stackSpil);
2613   setToNull ((void **) &_G.spiltSet);
2614   /* mark all registers as free */
2615   freeAllRegs ();
2616
2617   return;
2618 }