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