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