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