* src/z80/ralloc.c (packRegsForAssign): ported some bug fixes from the
[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 = 1,
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   int j;
767
768   D (D_ALLOC, ("getRegGpr: on ic %p\n", ic));
769 tryAgain:
770   /* try for gpr type */
771   if ((reg = allocReg (REG_GPR)))
772     {
773       D (D_ALLOC, ("getRegGpr: got a reg.\n"));
774       return reg;
775     }
776
777   /* we have to spil */
778   if (!spilSomething (ic, ebp, sym))
779     {
780       D (D_ALLOC, ("getRegGpr: have to spill.\n"));
781       return NULL;
782     }
783   
784   /* make sure partially assigned registers aren't reused */
785   for (j=0; j<=sym->nRegs; j++)
786     if (sym->regs[j])
787       sym->regs[j]->isFree = 0;
788
789   /* this looks like an infinite loop but 
790      in really selectSpil will abort  */
791   goto tryAgain;
792 }
793
794 static regs *getRegGprNoSpil()
795 {
796   regs *reg;
797
798   /* try for gpr type */
799   if ((reg = allocReg (REG_GPR)))
800     {
801       D (D_ALLOC, ("getRegGprNoSpil: got a reg.\n"));
802       return reg;
803     }
804   assert(0);
805
806   /* just to make the compiler happy */
807   return 0;
808 }
809
810 /** Symbol has a given register.
811  */
812 static bool 
813 symHasReg (symbol * sym, regs * reg)
814 {
815   int i;
816
817   for (i = 0; i < sym->nRegs; i++)
818     if (sym->regs[i] == reg)
819       return TRUE;
820
821   return FALSE;
822 }
823
824 /** Check the live to and if they have registers & are not spilt then
825     free up the registers 
826 */
827 static void 
828 deassignLRs (iCode * ic, eBBlock * ebp)
829 {
830   symbol *sym;
831   int k;
832   symbol *result;
833
834   for (sym = hTabFirstItem (liveRanges, &k); sym;
835        sym = hTabNextItem (liveRanges, &k))
836     {
837
838       symbol *psym = NULL;
839       /* if it does not end here */
840       if (sym->liveTo > ic->seq)
841         continue;
842
843       /* if it was spilt on stack then we can 
844          mark the stack spil location as free */
845       if (sym->isspilt)
846         {
847           if (sym->stackSpil)
848             {
849               sym->usl.spillLoc->isFree = 1;
850               sym->stackSpil = 0;
851             }
852           continue;
853         }
854
855       if (!bitVectBitValue (_G.regAssigned, sym->key))
856         continue;
857
858       /* special case check if this is an IFX &
859          the privious one was a pop and the 
860          previous one was not spilt then keep track
861          of the symbol */
862       if (ic->op == IFX && ic->prev &&
863           ic->prev->op == IPOP &&
864           !ic->prev->parmPush &&
865           !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
866         psym = OP_SYMBOL (IC_LEFT (ic->prev));
867
868       D (D_ALLOC, ("deassignLRs: in loop on sym %p nregs %u\n", sym, sym->nRegs));
869
870       if (sym->nRegs)
871         {
872           int i = 0;
873
874           bitVectUnSetBit (_G.regAssigned, sym->key);
875
876           /* if the result of this one needs registers
877              and does not have it then assign it right
878              away */
879           if (IC_RESULT (ic) &&
880               !(SKIP_IC2 (ic) ||        /* not a special icode */
881                 ic->op == JUMPTABLE ||
882                 ic->op == IFX ||
883                 ic->op == IPUSH ||
884                 ic->op == IPOP ||
885                 ic->op == RETURN) &&
886               (result = OP_SYMBOL (IC_RESULT (ic))) &&  /* has a result */
887               result->liveTo > ic->seq &&       /* and will live beyond this */
888               result->liveTo <= ebp->lSeq &&    /* does not go beyond this block */
889               result->liveFrom == ic->seq &&    /* does not start before here */
890               result->regType == sym->regType &&        /* same register types */
891               result->nRegs &&  /* which needs registers */
892               !result->isspilt &&       /* and does not already have them */
893               !result->remat &&
894               !bitVectBitValue (_G.regAssigned, result->key) &&
895           /* the number of free regs + number of regs in this LR
896              can accomodate the what result Needs */
897               ((nfreeRegsType (result->regType) +
898                 sym->nRegs) >= result->nRegs)
899             )
900             {
901               for (i = 0; i < result->nRegs; i++)
902                 {
903                   if (i < sym->nRegs)
904                     result->regs[i] = sym->regs[i];
905                   else
906                     result->regs[i] = getRegGpr (ic, ebp, result);
907
908                   /* if the allocation falied which means
909                      this was spilt then break */
910                   if (!result->regs[i])
911                     {
912                       wassert (0);
913                       assert (0);
914                       break;
915                     }
916                 }
917
918               _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
919               _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, result->key);
920             }
921
922           /* free the remaining */
923           for (; i < sym->nRegs; i++)
924             {
925               if (psym)
926                 {
927                   if (!symHasReg (psym, sym->regs[i]))
928                     freeReg (sym->regs[i]);
929                 }
930               else
931                 freeReg (sym->regs[i]);
932               //              sym->regs[i] = NULL;
933             }
934         }
935     }
936 }
937
938
939 /** Reassign this to registers.
940  */
941 static void 
942 reassignLR (operand * op)
943 {
944   symbol *sym = OP_SYMBOL (op);
945   int i;
946
947   D (D_ALLOC, ("reassingLR: on sym %p\n", sym));
948
949   /* not spilt any more */
950   sym->isspilt = sym->spillA = sym->blockSpil = sym->remainSpil = 0;
951   bitVectUnSetBit (_G.spiltSet, sym->key);
952
953   _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
954   _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key);
955
956   _G.blockSpil--;
957
958   for (i = 0; i < sym->nRegs; i++)
959     sym->regs[i]->isFree = 0;
960 }
961
962 /** Determines if allocating will cause a spill.
963  */
964 static int 
965 willCauseSpill (int nr, int rt)
966 {
967   /* first check if there are any avlb registers
968      of te type required */
969   if (nFreeRegs (0) >= nr)
970     return 0;
971
972   /* it will cause a spil */
973   return 1;
974 }
975
976 /** The allocator can allocate same registers to result and operand,
977     if this happens make sure they are in the same position as the operand
978     otherwise chaos results.
979 */
980 static int
981 positionRegs (symbol * result, symbol * opsym)
982 {
983   int count = min (result->nRegs, opsym->nRegs);
984   int i, j = 0, shared = 0;
985   int change = 0;
986
987   D (D_ALLOC, ("positionRegs: on result %p opsum %p line %u\n", result, opsym, lineno));
988
989   /* if the result has been spilt then cannot share */
990   if (opsym->isspilt)
991     return 0;
992 again:
993   shared = 0;
994   /* first make sure that they actually share */
995   for (i = 0; i < count; i++)
996     {
997       for (j = 0; j < count; j++)
998         {
999           if (result->regs[i] == opsym->regs[j] && i != j)
1000             {
1001               shared = 1;
1002               goto xchgPositions;
1003             }
1004         }
1005     }
1006 xchgPositions:
1007   if (shared)
1008     {
1009       regs *tmp = result->regs[i];
1010       result->regs[i] = result->regs[j];
1011       result->regs[j] = tmp;
1012       change ++;
1013       goto again;
1014     }
1015   return change ;
1016 }
1017
1018 /** Try to allocate a pair of registers to the symbol.
1019  */
1020 bool 
1021 tryAllocatingRegPair (symbol * sym)
1022 {
1023   int i;
1024   wassert (sym->nRegs == 2);
1025   for (i = 0; i < _G.nRegs; i += 2)
1026     {
1027       if ((regsZ80[i].isFree) && (regsZ80[i + 1].isFree))
1028         {
1029           regsZ80[i].isFree = 0;
1030           sym->regs[0] = &regsZ80[i];
1031           regsZ80[i + 1].isFree = 0;
1032           sym->regs[1] = &regsZ80[i + 1];
1033           sym->regType = REG_PAIR;
1034
1035           if (currFunc)
1036             {
1037               currFunc->regsUsed =
1038                 bitVectSetBit (currFunc->regsUsed, i);
1039               currFunc->regsUsed =
1040                 bitVectSetBit (currFunc->regsUsed, i + 1);
1041             }
1042           D (D_ALLOC, ("tryAllocRegPair: succeded for sym %p\n", sym));
1043           return TRUE;
1044         }
1045     }
1046   D (D_ALLOC, ("tryAllocRegPair: failed on sym %p\n", sym));
1047   return FALSE;
1048 }
1049
1050 /*------------------------------------------------------------------*/
1051 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
1052 /* it should either have registers or have beed spilled. Otherwise, */
1053 /* there was an uninitialized variable, so just spill this to get   */
1054 /* the operand in a valid state.                                    */
1055 /*------------------------------------------------------------------*/
1056 static void
1057 verifyRegsAssigned (operand *op, iCode * ic)
1058 {
1059   symbol * sym;
1060   
1061   if (!op) return;
1062   if (!IS_ITEMP (op)) return;
1063   
1064   sym = OP_SYMBOL (op);
1065   if (sym->isspilt) return;
1066   if (!sym->nRegs) return;
1067   if (sym->regs[0]) return;
1068   
1069   werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT, 
1070             sym->prereqv ? sym->prereqv->name : sym->name);
1071   spillThis (sym);
1072 }
1073
1074
1075 /** Serially allocate registers to the variables.
1076     This is the main register allocation function.  It is called after
1077     packing.
1078  */
1079 static void 
1080 serialRegAssign (eBBlock ** ebbs, int count)
1081 {
1082   int i;
1083
1084   /* for all blocks */
1085   for (i = 0; i < count; i++)
1086     {
1087
1088       iCode *ic;
1089
1090       if (ebbs[i]->noPath &&
1091           (ebbs[i]->entryLabel != entryLabel &&
1092            ebbs[i]->entryLabel != returnLabel))
1093         continue;
1094
1095       /* of all instructions do */
1096       for (ic = ebbs[i]->sch; ic; ic = ic->next)
1097         {
1098
1099           /* if this is an ipop that means some live
1100              range will have to be assigned again */
1101           if (ic->op == IPOP)
1102             {
1103               wassert (0);
1104               reassignLR (IC_LEFT (ic));
1105             }
1106
1107           /* if result is present && is a true symbol */
1108           if (IC_RESULT (ic) && ic->op != IFX &&
1109               IS_TRUE_SYMOP (IC_RESULT (ic)))
1110             OP_SYMBOL (IC_RESULT (ic))->allocreq++;
1111
1112           /* take away registers from live
1113              ranges that end at this instruction */
1114           deassignLRs (ic, ebbs[i]);
1115
1116           /* some don't need registers */
1117           /* MLH: removed RESULT and POINTER_SET condition */
1118           if (SKIP_IC2 (ic) ||
1119               ic->op == JUMPTABLE ||
1120               ic->op == IFX ||
1121               ic->op == IPUSH ||
1122               ic->op == IPOP)
1123             continue;
1124
1125           /* now we need to allocate registers only for the result */
1126           if (IC_RESULT (ic))
1127             {
1128               symbol *sym = OP_SYMBOL (IC_RESULT (ic));
1129               bitVect *spillable;
1130               int willCS;
1131               int j;
1132
1133               D (D_ALLOC, ("serialRegAssign: in loop on result %p\n", sym));
1134
1135               /* if it does not need or is spilt 
1136                  or is already assigned to registers
1137                  or will not live beyond this instructions */
1138               if (!sym->nRegs ||
1139                   sym->isspilt ||
1140                   bitVectBitValue (_G.regAssigned, sym->key) ||
1141                   sym->liveTo <= ic->seq)
1142                 {
1143                   D (D_ALLOC, ("serialRegAssign: wont live long enough.\n"));
1144                   continue;
1145                 }
1146
1147               /* if some liverange has been spilt at the block level
1148                  and this one live beyond this block then spil this
1149                  to be safe */
1150               if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
1151                 {
1152                   D (D_ALLOC, ("serialRegAssign: \"spilling to be safe.\"\n"));
1153                   spillThis (sym);
1154                   continue;
1155                 }
1156               /* if trying to allocate this will cause
1157                  a spill and there is nothing to spill 
1158                  or this one is rematerializable then
1159                  spill this one */
1160               willCS = willCauseSpill (sym->nRegs, sym->regType);
1161               spillable = computeSpillable (ic);
1162               if (sym->remat ||
1163                   (willCS && bitVectIsZero (spillable)))
1164                 {
1165
1166                   D (D_ALLOC, ("serialRegAssign: \"remat spill\"\n"));
1167                   spillThis (sym);
1168                   continue;
1169
1170                 }
1171
1172               /* If the live range preceeds the point of definition 
1173                  then ideally we must take into account registers that 
1174                  have been allocated after sym->liveFrom but freed
1175                  before ic->seq. This is complicated, so spill this
1176                  symbol instead and let fillGaps handle the allocation. */
1177               if (sym->liveFrom < ic->seq)
1178                 {
1179                     spillThis (sym);
1180                     continue;                 
1181                 }
1182
1183               /* if it has a spillocation & is used less than
1184                  all other live ranges then spill this */
1185               if (willCS) {
1186                       if (sym->usl.spillLoc) {
1187                               symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
1188                                                                                allLRs, ebbs[i], ic));
1189                               if (leastUsed && leastUsed->used > sym->used) {
1190                                       spillThis (sym);
1191                                       continue;
1192                               }
1193                       } else {
1194                               /* if none of the liveRanges have a spillLocation then better
1195                                  to spill this one than anything else already assigned to registers */
1196                               if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
1197                                   /* if this is local to this block then we might find a block spil */
1198                                   if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
1199                                       spillThis (sym);
1200                                       continue;
1201                                   }
1202                               }
1203                       }
1204               }
1205
1206               /* else we assign registers to it */
1207               _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1208               _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key);
1209
1210               /* Special case:  Try to fit into a reg pair if
1211                  available */
1212               D (D_ALLOC, ("serialRegAssign: actually allocing regs!\n"));
1213               if ((sym->nRegs == 2) && tryAllocatingRegPair (sym))
1214                 {
1215                 }
1216               else
1217                 {
1218                   for (j = 0; j < sym->nRegs; j++)
1219                     {
1220                       sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
1221
1222                       /* if the allocation falied which means
1223                          this was spilt then break */
1224                       if (!sym->regs[j])
1225                         {
1226                           D (D_ALLOC, ("Couldnt alloc (spill)\n"))
1227                             break;
1228                         }
1229                     }
1230                 }
1231               /* if it shares registers with operands make sure
1232                  that they are in the same position */
1233               if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
1234                   OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
1235                 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1236                               OP_SYMBOL (IC_LEFT (ic)));
1237               /* do the same for the right operand */
1238               if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
1239                   OP_SYMBOL (IC_RIGHT (ic))->nRegs)
1240                 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1241                               OP_SYMBOL (IC_RIGHT (ic)));
1242
1243             }
1244         }
1245     }
1246
1247     /* Check for and fix any problems with uninitialized operands */
1248     for (i = 0; i < count; i++)
1249       {
1250         iCode *ic;
1251
1252         if (ebbs[i]->noPath &&
1253             (ebbs[i]->entryLabel != entryLabel &&
1254              ebbs[i]->entryLabel != returnLabel))
1255             continue;
1256
1257         for (ic = ebbs[i]->sch; ic; ic = ic->next)
1258           {
1259             if (SKIP_IC2 (ic))
1260               continue;
1261
1262             if (ic->op == IFX)
1263               {
1264                 verifyRegsAssigned (IC_COND (ic), ic);
1265                 continue;
1266               }
1267
1268             if (ic->op == JUMPTABLE)
1269               {
1270                 verifyRegsAssigned (IC_JTCOND (ic), ic);
1271                 continue;
1272               }
1273
1274             verifyRegsAssigned (IC_RESULT (ic), ic);
1275             verifyRegsAssigned (IC_LEFT (ic), ic);
1276             verifyRegsAssigned (IC_RIGHT (ic), ic);
1277           }
1278       }    
1279
1280 }
1281
1282 /*-----------------------------------------------------------------*/
1283 /* fillGaps - Try to fill in the Gaps left by Pass1                */
1284 /*-----------------------------------------------------------------*/
1285 static void fillGaps()
1286 {
1287     symbol *sym =NULL;
1288     int key =0;    
1289     
1290     if (getenv("DISABLE_FILL_GAPS")) return;
1291     
1292     /* look for livernages that was spilt by the allocator */
1293     for (sym = hTabFirstItem(liveRanges,&key) ; sym ; 
1294          sym = hTabNextItem(liveRanges,&key)) {
1295
1296         int i;
1297         int pdone = 0;
1298
1299         if (!sym->spillA || !sym->clashes || sym->remat) continue ;
1300
1301         /* find the liveRanges this one clashes with, that are
1302            still assigned to registers & mark the registers as used*/
1303         for ( i = 0 ; i < sym->clashes->size ; i ++) {
1304             int k;
1305             symbol *clr;
1306
1307             if (bitVectBitValue(sym->clashes,i) == 0 ||    /* those that clash with this */
1308                 bitVectBitValue(_G.totRegAssigned,i) == 0) /* and are still assigned to registers */
1309                 continue ;
1310
1311             clr = hTabItemWithKey(liveRanges,i);
1312             assert(clr);
1313          
1314             /* mark these registers as used */
1315             for (k = 0 ; k < clr->nRegs ; k++ ) 
1316                 useReg(clr->regs[k]);
1317         }
1318
1319         if (willCauseSpill(sym->nRegs,sym->regType)) {
1320             /* NOPE :( clear all registers & and continue */
1321             freeAllRegs();
1322             continue ;
1323         }
1324
1325         /* THERE IS HOPE !!!! */
1326         for (i=0; i < sym->nRegs ; i++ ) {
1327                 sym->regs[i] = getRegGprNoSpil ();                
1328         }
1329
1330         /* for all its definitions check if the registers
1331            allocated needs positioning NOTE: we can position
1332            only ONCE if more than One positioning required 
1333            then give up */
1334         sym->isspilt = 0;
1335         for (i = 0 ; i < sym->defs->size ; i++ ) {
1336             if (bitVectBitValue(sym->defs,i)) {
1337                 iCode *ic;
1338                 if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
1339                 if (SKIP_IC(ic)) continue;
1340                 assert(isSymbolEqual(sym,OP_SYMBOL(IC_RESULT(ic)))); /* just making sure */
1341                 /* if left is assigned to registers */
1342                 if (IS_SYMOP(IC_LEFT(ic)) && 
1343                     bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_LEFT(ic))->key)) {
1344                     pdone += positionRegs(sym,OP_SYMBOL(IC_LEFT(ic)));
1345                 }
1346                 if (IS_SYMOP(IC_RIGHT(ic)) && 
1347                     bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RIGHT(ic))->key)) {
1348                     pdone += positionRegs(sym,OP_SYMBOL(IC_RIGHT(ic)));
1349                 }
1350                 if (pdone > 1) break;
1351             }
1352         }
1353         for (i = 0 ; i < sym->uses->size ; i++ ) {
1354             if (bitVectBitValue(sym->uses,i)) {
1355                 iCode *ic;
1356                 if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
1357                 if (SKIP_IC(ic)) continue;
1358                 if (!IS_ASSIGN_ICODE(ic)) continue ;
1359
1360                 /* if result is assigned to registers */
1361                 if (IS_SYMOP(IC_RESULT(ic)) && 
1362                     bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RESULT(ic))->key)) {
1363                     pdone += positionRegs(sym,OP_SYMBOL(IC_RESULT(ic)));
1364                 }
1365                 if (pdone > 1) break;
1366             }
1367         }
1368         /* had to position more than once GIVE UP */
1369         if (pdone > 1) {
1370             /* UNDO all the changes we made to try this */
1371             sym->isspilt = 1;
1372             for (i=0; i < sym->nRegs ; i++ ) {
1373                 sym->regs[i] = NULL;
1374             }
1375             freeAllRegs();
1376             D(D_FILL_GAPS,("Fill Gap gave up due to positioning for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN"));
1377             continue ;      
1378         }
1379         D(D_FILL_GAPS,("FILLED GAP for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN"));
1380         _G.totRegAssigned = bitVectSetBit(_G.totRegAssigned,sym->key);
1381         sym->isspilt = sym->spillA = 0 ;
1382         sym->usl.spillLoc->allocreq--;
1383         freeAllRegs();
1384     }
1385 }
1386
1387 /*-----------------------------------------------------------------*/
1388 /* rUmaskForOp :- returns register mask for an operand             */
1389 /*-----------------------------------------------------------------*/
1390 bitVect *
1391 rUmaskForOp (operand * op)
1392 {
1393   bitVect *rumask;
1394   symbol *sym;
1395   int j;
1396
1397   /* only temporaries are assigned registers */
1398   if (!IS_ITEMP (op))
1399     return NULL;
1400
1401   sym = OP_SYMBOL (op);
1402
1403   /* if spilt or no registers assigned to it
1404      then nothing */
1405   if (sym->isspilt || !sym->nRegs)
1406     return NULL;
1407
1408   rumask = newBitVect (_G.nRegs);
1409
1410   for (j = 0; j < sym->nRegs; j++)
1411     {
1412       rumask = bitVectSetBit (rumask, sym->regs[j]->rIdx);
1413     }
1414
1415   return rumask;
1416 }
1417
1418 bitVect *
1419 z80_rUmaskForOp (operand * op)
1420 {
1421   return rUmaskForOp (op);
1422 }
1423
1424 /** Returns bit vector of registers used in iCode.
1425  */
1426 bitVect *
1427 regsUsedIniCode (iCode * ic)
1428 {
1429   bitVect *rmask = newBitVect (_G.nRegs);
1430
1431   /* do the special cases first */
1432   if (ic->op == IFX)
1433     {
1434       rmask = bitVectUnion (rmask,
1435                             rUmaskForOp (IC_COND (ic)));
1436       goto ret;
1437     }
1438
1439   /* for the jumptable */
1440   if (ic->op == JUMPTABLE)
1441     {
1442       rmask = bitVectUnion (rmask,
1443                             rUmaskForOp (IC_JTCOND (ic)));
1444
1445       goto ret;
1446     }
1447
1448   /* of all other cases */
1449   if (IC_LEFT (ic))
1450     rmask = bitVectUnion (rmask,
1451                           rUmaskForOp (IC_LEFT (ic)));
1452
1453
1454   if (IC_RIGHT (ic))
1455     rmask = bitVectUnion (rmask,
1456                           rUmaskForOp (IC_RIGHT (ic)));
1457
1458   if (IC_RESULT (ic))
1459     rmask = bitVectUnion (rmask,
1460                           rUmaskForOp (IC_RESULT (ic)));
1461
1462 ret:
1463   return rmask;
1464 }
1465
1466 /** For each instruction will determine the regsUsed.
1467  */
1468 static void 
1469 createRegMask (eBBlock ** ebbs, int count)
1470 {
1471   int i;
1472
1473   /* for all blocks */
1474   for (i = 0; i < count; i++)
1475     {
1476       iCode *ic;
1477
1478       if (ebbs[i]->noPath &&
1479           (ebbs[i]->entryLabel != entryLabel &&
1480            ebbs[i]->entryLabel != returnLabel))
1481         continue;
1482
1483       /* for all instructions */
1484       for (ic = ebbs[i]->sch; ic; ic = ic->next)
1485         {
1486
1487           int j;
1488
1489           if (SKIP_IC2 (ic) || !ic->rlive)
1490             continue;
1491
1492           /* first mark the registers used in this
1493              instruction */
1494           ic->rUsed = regsUsedIniCode (ic);
1495           _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
1496
1497           /* now create the register mask for those 
1498              registers that are in use : this is a
1499              super set of ic->rUsed */
1500           ic->rMask = newBitVect (_G.nRegs + 1);
1501
1502           /* for all live Ranges alive at this point */
1503           for (j = 1; j < ic->rlive->size; j++)
1504             {
1505               symbol *sym;
1506               int k;
1507
1508               /* if not alive then continue */
1509               if (!bitVectBitValue (ic->rlive, j))
1510                 continue;
1511
1512               /* find the live range we are interested in */
1513               if (!(sym = hTabItemWithKey (liveRanges, j)))
1514                 {
1515                   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1516                           "createRegMask cannot find live range");
1517                   exit (0);
1518                 }
1519
1520               /* if no register assigned to it */
1521               if (!sym->nRegs || sym->isspilt)
1522                 continue;
1523
1524               /* for all the registers allocated to it */
1525               for (k = 0; k < sym->nRegs; k++)
1526                 if (sym->regs[k])
1527                   ic->rMask =
1528                     bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
1529             }
1530         }
1531     }
1532 }
1533
1534 /** Returns the rematerialized string for a remat var.
1535  */
1536 char *
1537 rematStr (symbol * sym)
1538 {
1539   char *s = buffer;
1540   iCode *ic = sym->rematiCode;
1541
1542   while (1)
1543     {
1544
1545       /* if plus or minus print the right hand side */
1546       if (ic->op == '+' || ic->op == '-')
1547         {
1548           sprintf (s, "0x%04x %c ", (int) operandLitValue (IC_RIGHT (ic)),
1549                    ic->op);
1550           s += strlen (s);
1551           ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1552           continue;
1553         }
1554       /* we reached the end */
1555       sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
1556       break;
1557     }
1558
1559   return buffer;
1560 }
1561
1562 /*-----------------------------------------------------------------*/
1563 /* regTypeNum - computes the type & number of registers required   */
1564 /*-----------------------------------------------------------------*/
1565 static void 
1566 regTypeNum (void)
1567 {
1568   symbol *sym;
1569   int k;
1570
1571   /* for each live range do */
1572   for (sym = hTabFirstItem (liveRanges, &k); sym;
1573        sym = hTabNextItem (liveRanges, &k))
1574     {
1575
1576       /* if used zero times then no registers needed */
1577       if ((sym->liveTo - sym->liveFrom) == 0)
1578         continue;
1579
1580       D (D_ALLOC, ("regTypeNum: loop on sym %p\n", sym));
1581
1582       /* if the live range is a temporary */
1583       if (sym->isitmp)
1584         {
1585
1586           /* if the type is marked as a conditional */
1587           if (sym->regType == REG_CND)
1588             continue;
1589
1590           /* if used in return only then we don't 
1591              need registers */
1592           if (sym->ruonly || sym->accuse)
1593             {
1594               if (IS_AGGREGATE (sym->type) || sym->isptr)
1595                 sym->type = aggrToPtr (sym->type, FALSE);
1596               continue;
1597             }
1598
1599           /* if not then we require registers */
1600           D (D_ALLOC, ("regTypeNum: isagg %u nRegs %u type %p\n", IS_AGGREGATE (sym->type) || sym->isptr, sym->nRegs, sym->type));
1601           sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
1602                         getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1603                         getSize (sym->type));
1604           D (D_ALLOC, ("regTypeNum: setting nRegs of %s (%p) to %u\n", sym->name, sym, sym->nRegs));
1605
1606           D (D_ALLOC, ("regTypeNum: setup to assign regs sym %p\n", sym));
1607
1608           if (sym->nRegs > 4)
1609             {
1610               fprintf (stderr, "allocated more than 4 or 0 registers for type ");
1611               printTypeChain (sym->type, stderr);
1612               fprintf (stderr, "\n");
1613             }
1614
1615           /* determine the type of register required */
1616           /* Always general purpose */
1617           sym->regType = REG_GPR;
1618
1619         }
1620       else
1621         {
1622           /* for the first run we don't provide */
1623           /* registers for true symbols we will */
1624           /* see how things go                  */
1625           D (D_ALLOC, ("regTypeNum: #2 setting num of %p to 0\n", sym));
1626           sym->nRegs = 0;
1627         }
1628     }
1629
1630 }
1631
1632 /** Mark all registers as free.
1633  */
1634 static void 
1635 freeAllRegs ()
1636 {
1637   int i;
1638
1639   D (D_ALLOC, ("freeAllRegs: running.\n"));
1640
1641   for (i = 0; i < _G.nRegs; i++)
1642     regsZ80[i].isFree = 1;
1643 }
1644
1645 /*-----------------------------------------------------------------*/
1646 /* deallocStackSpil - this will set the stack pointer back         */
1647 /*-----------------------------------------------------------------*/
1648 DEFSETFUNC (deallocStackSpil)
1649 {
1650   symbol *sym = item;
1651
1652   deallocLocal (sym);
1653   return 0;
1654 }
1655
1656 /** Register reduction for assignment.
1657  */
1658 static int 
1659 packRegsForAssign (iCode * ic, eBBlock * ebp)
1660 {
1661   iCode *dic, *sic;
1662
1663   D (D_ALLOC, ("packRegsForAssign: running on ic %p\n", ic));
1664
1665   if (!IS_ITEMP (IC_RIGHT (ic)) ||
1666       OP_SYMBOL (IC_RIGHT (ic))->isind ||
1667       OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
1668     {
1669       return 0;
1670     }
1671
1672   /* find the definition of iTempNN scanning backwards if we find a 
1673      a use of the true symbol in before we find the definition then 
1674      we cannot */
1675   for (dic = ic->prev; dic; dic = dic->prev)
1676     {
1677       /* PENDING: Don't pack across function calls. */
1678       if (dic->op == CALL || dic->op == PCALL)
1679         {
1680           dic = NULL;
1681           break;
1682         }
1683
1684       if (SKIP_IC2 (dic))
1685         continue;
1686
1687       if (dic->op == IFX)
1688         {
1689           if (IS_SYMOP (IC_COND (dic)) &&
1690               (IC_COND (dic)->key == IC_RESULT (ic)->key ||
1691                IC_COND (dic)->key == IC_RIGHT (ic)->key))
1692             {
1693               dic = NULL;
1694               break;
1695             }
1696         }
1697       else
1698         {
1699           if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
1700               IS_OP_VOLATILE (IC_RESULT (dic)))
1701             {
1702               dic = NULL;
1703               break;
1704             }
1705
1706           if (IS_SYMOP (IC_RESULT (dic)) &&
1707               IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1708             {
1709               if (POINTER_SET (dic))
1710                 dic = NULL;
1711
1712               break;
1713             }
1714
1715           if (IS_SYMOP (IC_RIGHT (dic)) &&
1716               (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
1717                IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
1718             {
1719               dic = NULL;
1720               break;
1721             }
1722
1723           if (IS_SYMOP (IC_LEFT (dic)) &&
1724               (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
1725                IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
1726             {
1727               dic = NULL;
1728               break;
1729             }
1730
1731           if (IS_SYMOP (IC_RESULT (dic)) &&
1732               IC_RESULT (dic)->key == IC_RESULT (ic)->key)
1733             {
1734               dic = NULL;
1735               break;
1736             }
1737             
1738         }
1739     }
1740
1741   if (!dic)
1742     return 0;                   /* did not find */
1743
1744   /* if the result is on stack or iaccess then it must be
1745      the same atleast one of the operands */
1746   if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
1747       OP_SYMBOL (IC_RESULT (ic))->iaccess)
1748     {
1749       /* the operation has only one symbol
1750          operator then we can pack */
1751       if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
1752           (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
1753         goto pack;
1754
1755       if (!((IC_LEFT (dic) &&
1756              IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
1757             (IC_RIGHT (dic) &&
1758              IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
1759         return 0;
1760     }
1761 pack:
1762   /* found the definition */
1763   /* replace the result with the result of */
1764   /* this assignment and remove this assignment */
1765   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1766   IC_RESULT (dic) = IC_RESULT (ic);
1767
1768   if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
1769     {
1770       OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
1771     }
1772   /* delete from liverange table also 
1773      delete from all the points inbetween and the new
1774      one */
1775   for (sic = dic; sic != ic; sic = sic->next)
1776     {
1777       bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
1778       if (IS_ITEMP (IC_RESULT (dic)))
1779         bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
1780     }
1781
1782   remiCodeFromeBBlock (ebp, ic);
1783   // PENDING: Check vs mcs51
1784   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
1785   hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
1786   OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
1787   return 1;
1788 }
1789
1790 /** Scanning backwards looks for first assig found.
1791  */
1792 iCode *
1793 findAssignToSym (operand * op, iCode * ic)
1794 {
1795   iCode *dic;
1796
1797   for (dic = ic->prev; dic; dic = dic->prev)
1798     {
1799
1800       /* if definition by assignment */
1801       if (dic->op == '=' &&
1802           !POINTER_SET (dic) &&
1803           IC_RESULT (dic)->key == op->key)
1804         /*      &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) */
1805         {
1806
1807           /* we are interested only if defined in far space */
1808           /* or in stack space in case of + & - */
1809
1810           /* if assigned to a non-symbol then return
1811              true */
1812           if (!IS_SYMOP (IC_RIGHT (dic)))
1813             break;
1814
1815           /* if the symbol is in far space then
1816              we should not */
1817           if (isOperandInFarSpace (IC_RIGHT (dic)))
1818             return NULL;
1819
1820           /* for + & - operations make sure that
1821              if it is on the stack it is the same
1822              as one of the three operands */
1823           if ((ic->op == '+' || ic->op == '-') &&
1824               OP_SYMBOL (IC_RIGHT (dic))->onStack)
1825             {
1826
1827               if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
1828                   IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
1829                   IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
1830                 return NULL;
1831             }
1832
1833           break;
1834
1835         }
1836
1837       /* if we find an usage then we cannot delete it */
1838       if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
1839         return NULL;
1840
1841       if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
1842         return NULL;
1843
1844       if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
1845         return NULL;
1846     }
1847
1848   /* now make sure that the right side of dic
1849      is not defined between ic & dic */
1850   if (dic)
1851     {
1852       iCode *sic = dic->next;
1853
1854       for (; sic != ic; sic = sic->next)
1855         if (IC_RESULT (sic) &&
1856             IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
1857           return NULL;
1858     }
1859
1860   return dic;
1861
1862
1863 }
1864
1865 #if !DISABLE_PACKREGSFORSUPPORT
1866 // PENDING
1867
1868 /*-----------------------------------------------------------------*/
1869 /* packRegsForSupport :- reduce some registers for support calls   */
1870 /*-----------------------------------------------------------------*/
1871 static int 
1872 packRegsForSupport (iCode * ic, eBBlock * ebp)
1873 {
1874   int change = 0;
1875   /* for the left & right operand :- look to see if the
1876      left was assigned a true symbol in far space in that
1877      case replace them */
1878   D (D_ALLOC, ("packRegsForSupport: running on ic %p\n", ic));
1879
1880   if (IS_ITEMP (IC_LEFT (ic)) &&
1881       OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
1882     {
1883       iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
1884       iCode *sic;
1885
1886       if (!dic)
1887         goto right;
1888
1889       /* found it we need to remove it from the
1890          block */
1891       for (sic = dic; sic != ic; sic = sic->next)
1892         bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
1893
1894       IC_LEFT (ic)->operand.symOperand =
1895         IC_RIGHT (dic)->operand.symOperand;
1896       IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
1897       remiCodeFromeBBlock (ebp, dic);
1898       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1899       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1900       // PENDING: Check vs mcs51
1901       change++;
1902     }
1903
1904   /* do the same for the right operand */
1905 right:
1906   if (!change &&
1907       IS_ITEMP (IC_RIGHT (ic)) &&
1908       OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
1909     {
1910       iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
1911       iCode *sic;
1912
1913       if (!dic)
1914         return change;
1915
1916       /* found it we need to remove it from the block */
1917       for (sic = dic; sic != ic; sic = sic->next)
1918         bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
1919
1920       IC_RIGHT (ic)->operand.symOperand =
1921         IC_RIGHT (dic)->operand.symOperand;
1922       IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
1923
1924       remiCodeFromeBBlock (ebp, dic);
1925       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1926       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1927       // PENDING: vs mcs51
1928       change++;
1929     }
1930
1931   return change;
1932 }
1933 #endif
1934
1935 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
1936
1937 /** Will reduce some registers for single use.
1938  */
1939 static iCode *
1940 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
1941 {
1942   bitVect *uses;
1943   iCode *dic, *sic;
1944
1945   // PENDING: Disable
1946   D (D_ALLOC, ("packRegsForOneUse: running on ic %p\n", ic));
1947
1948   /* if returning a literal then do nothing */
1949   if (!IS_SYMOP (op))
1950     return NULL;
1951
1952   /* only upto 2 bytes since we cannot predict
1953      the usage of b, & acc */
1954   if (getSize (operandType (op)) > 2)
1955     return NULL;
1956
1957   if (ic->op != RETURN &&
1958       ic->op != SEND)
1959     return NULL;
1960
1961   /* this routine will mark the a symbol as used in one 
1962      instruction use only && if the defintion is local 
1963      (ie. within the basic block) && has only one definition &&
1964      that definiion is either a return value from a 
1965      function or does not contain any variables in
1966      far space */
1967   uses = bitVectCopy (OP_USES (op));
1968   bitVectUnSetBit (uses, ic->key);      /* take away this iCode */
1969   if (!bitVectIsZero (uses))    /* has other uses */
1970     return NULL;
1971
1972   /* if it has only one defintion */
1973   if (bitVectnBitsOn (OP_DEFS (op)) > 1)
1974     return NULL;                /* has more than one definition */
1975
1976   /* get the that definition */
1977   if (!(dic =
1978         hTabItemWithKey (iCodehTab,
1979                          bitVectFirstBit (OP_DEFS (op)))))
1980     return NULL;
1981
1982   /* found the definition now check if it is local */
1983   if (dic->seq < ebp->fSeq ||
1984       dic->seq > ebp->lSeq)
1985     return NULL;                /* non-local */
1986
1987   /* now check if it is the return from a function call */
1988   if (dic->op == CALL || dic->op == PCALL)
1989     {
1990       if (ic->op != SEND && ic->op != RETURN &&
1991           !POINTER_SET(ic) && !POINTER_GET(ic))
1992         {
1993           OP_SYMBOL (op)->ruonly = 1;
1994           return dic;
1995         }
1996       dic = dic->next;
1997     }
1998
1999   /* otherwise check that the definition does
2000      not contain any symbols in far space */
2001   if (isOperandInFarSpace (IC_LEFT (dic)) ||
2002       isOperandInFarSpace (IC_RIGHT (dic)) ||
2003       IS_OP_RUONLY (IC_LEFT (ic)) ||
2004       IS_OP_RUONLY (IC_RIGHT (ic)))
2005     {
2006       return NULL;
2007     }
2008
2009   /* if pointer set then make sure the pointer is one byte */
2010   if (POINTER_SET (dic))
2011     return NULL;
2012
2013   if (POINTER_GET (dic))
2014     return NULL;
2015
2016   sic = dic;
2017
2018   /* also make sure the intervenening instructions
2019      don't have any thing in far space */
2020   for (dic = dic->next; dic && dic != ic; dic = dic->next)
2021     {
2022       /* if there is an intervening function call then no */
2023       if (dic->op == CALL || dic->op == PCALL)
2024         return NULL;
2025       /* if pointer set then make sure the pointer
2026          is one byte */
2027       if (POINTER_SET (dic))
2028         return NULL;
2029
2030       if (POINTER_GET (dic))
2031         return NULL;
2032
2033       /* if address of & the result is remat the okay */
2034       if (dic->op == ADDRESS_OF &&
2035           OP_SYMBOL (IC_RESULT (dic))->remat)
2036         continue;
2037
2038       /* if left or right or result is in far space */
2039       if (isOperandInFarSpace (IC_LEFT (dic)) ||
2040           isOperandInFarSpace (IC_RIGHT (dic)) ||
2041           isOperandInFarSpace (IC_RESULT (dic)) ||
2042           IS_OP_RUONLY (IC_LEFT (dic)) ||
2043           IS_OP_RUONLY (IC_RIGHT (dic)) ||
2044           IS_OP_RUONLY (IC_RESULT (dic)))
2045         {
2046           return NULL;
2047         }
2048     }
2049
2050   OP_SYMBOL (op)->ruonly = 1;
2051   return sic;
2052 }
2053
2054 /*-----------------------------------------------------------------*/
2055 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
2056 /*-----------------------------------------------------------------*/
2057 static bool 
2058 isBitwiseOptimizable (iCode * ic)
2059 {
2060   sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
2061
2062   /* bitwise operations are considered optimizable
2063      under the following conditions (Jean-Louis VERN) 
2064
2065      x & lit
2066      bit & bit
2067      bit & x
2068      bit ^ bit
2069      bit ^ x
2070      x   ^ lit
2071      x   | lit
2072      bit | bit
2073      bit | x
2074    */
2075   if (IS_LITERAL (rtype))
2076     return TRUE;
2077   return FALSE;
2078 }
2079
2080 /** Optimisations:
2081     Certian assignments involving pointers can be temporarly stored
2082     in HL.  Esp.
2083 genAssign
2084     ld  iy,#_Blah
2085     ld  bc,(iy)
2086 genAssign (ptr)
2087     ld  hl,bc
2088     ld  iy,#_Blah2
2089     ld  (iy),(hl)
2090 */
2091
2092 #if !DISABLE_PACKREGSFORACCUSE
2093 // PENDING
2094
2095 /** Pack registers for acc use.
2096     When the result of this operation is small and short lived it may
2097     be able to be stored in the accumelator.
2098  */
2099 static void 
2100 packRegsForAccUse (iCode * ic)
2101 {
2102   iCode *uic;
2103
2104   /* if this is an aggregate, e.g. a one byte char array */
2105   if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
2106     return;
2107   }
2108
2109   /* if + or - then it has to be one byte result */
2110   if ((ic->op == '+' || ic->op == '-')
2111       && getSize (operandType (IC_RESULT (ic))) > 1)
2112     return;
2113
2114   /* if shift operation make sure right side is not a literal */
2115   if (ic->op == RIGHT_OP &&
2116       (isOperandLiteral (IC_RIGHT (ic)) ||
2117        getSize (operandType (IC_RESULT (ic))) > 1))
2118     return;
2119
2120   if (ic->op == LEFT_OP &&
2121       (isOperandLiteral (IC_RIGHT (ic)) ||
2122        getSize (operandType (IC_RESULT (ic))) > 1))
2123     return;
2124
2125   /* has only one definition */
2126   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
2127     return;
2128
2129   /* has only one use */
2130   if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
2131     return;
2132
2133   /* and the usage immediately follows this iCode */
2134   if (!(uic = hTabItemWithKey (iCodehTab,
2135                                bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
2136     return;
2137
2138   if (ic->next != uic)
2139     return;
2140
2141   /* if it is a conditional branch then we definitely can */
2142   if (uic->op == IFX)
2143     goto accuse;
2144
2145   if (uic->op == JUMPTABLE)
2146     return;
2147
2148 #if 0
2149   /* if the usage is not is an assignment or an 
2150      arithmetic / bitwise / shift operation then not */
2151   if (POINTER_SET (uic) &&
2152       getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
2153     return;
2154 #endif
2155
2156   if (uic->op != '=' &&
2157       !IS_ARITHMETIC_OP (uic) &&
2158       !IS_BITWISE_OP (uic) &&
2159       uic->op != LEFT_OP &&
2160       uic->op != RIGHT_OP)
2161     return;
2162
2163   /* if used in ^ operation then make sure right is not a 
2164      literl */
2165   if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
2166     return;
2167
2168   /* if shift operation make sure right side is not a literal */
2169   if (uic->op == RIGHT_OP &&
2170       (isOperandLiteral (IC_RIGHT (uic)) ||
2171        getSize (operandType (IC_RESULT (uic))) > 1))
2172     return;
2173
2174   if (uic->op == LEFT_OP &&
2175       (isOperandLiteral (IC_RIGHT (uic)) ||
2176        getSize (operandType (IC_RESULT (uic))) > 1))
2177     return;
2178
2179 #if 0
2180   /* make sure that the result of this icode is not on the
2181      stack, since acc is used to compute stack offset */
2182   if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
2183       OP_SYMBOL (IC_RESULT (uic))->onStack)
2184     return;
2185 #endif
2186
2187 #if 0
2188   /* if either one of them in far space then we cannot */
2189   if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
2190        isOperandInFarSpace (IC_LEFT (uic))) ||
2191       (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
2192        isOperandInFarSpace (IC_RIGHT (uic))))
2193     return;
2194 #endif
2195
2196   /* if the usage has only one operand then we can */
2197   if (IC_LEFT (uic) == NULL ||
2198       IC_RIGHT (uic) == NULL)
2199     goto accuse;
2200
2201   /* make sure this is on the left side if not
2202      a '+' since '+' is commutative */
2203   if (ic->op != '+' &&
2204       IC_LEFT (uic)->key != IC_RESULT (ic)->key)
2205     return;
2206
2207   // See mcs51 ralloc for reasoning
2208 #if 0
2209   /* if one of them is a literal then we can */
2210   if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
2211       (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
2212     {
2213       goto accuse;
2214       return;
2215     }
2216 #endif
2217
2218 /** This is confusing :)  Guess for now */
2219   if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
2220       (IS_ITEMP (IC_RIGHT (uic)) ||
2221        (IS_TRUE_SYMOP (IC_RIGHT (uic)))))
2222     goto accuse;
2223
2224   if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
2225       (IS_ITEMP (IC_LEFT (uic)) ||
2226        (IS_TRUE_SYMOP (IC_LEFT (uic)))))
2227     goto accuse;
2228   return;
2229 accuse:
2230   OP_SYMBOL (IC_RESULT (ic))->accuse = ACCUSE_A;
2231 }
2232 #endif
2233
2234 static void 
2235 packRegsForHLUse (iCode * ic)
2236 {
2237   iCode *uic;
2238
2239   /* PENDING: Could do IFX */
2240   if (ic->op == IFX)
2241     {
2242       return;
2243     }
2244
2245   /* has only one definition */
2246   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
2247     {
2248       D (D_HLUSE, ("  + Dropping as has more than one def\n"));
2249       return;
2250     }
2251
2252   /* has only one use */
2253   if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
2254     {
2255       D (D_HLUSE, ("  + Dropping as has more than one use\n"));
2256       return;
2257     }
2258
2259   /* and the usage immediately follows this iCode */
2260   if (!(uic = hTabItemWithKey (iCodehTab,
2261                                bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
2262     {
2263       D (D_HLUSE, ("  + Dropping as usage isn't in this block\n"));
2264       return;
2265     }
2266
2267   if (ic->next != uic)
2268     {
2269       D (D_HLUSE, ("  + Dropping as usage doesn't follow this\n"));
2270       return;
2271     }
2272
2273   if (uic->op ==IFX)
2274     {
2275       return;
2276     }
2277
2278   if (getSize (operandType (IC_RESULT (ic))) != 2 ||
2279       (IC_LEFT(uic) && getSize (operandType (IC_LEFT (uic))) != 2) ||
2280       (IC_RIGHT(uic) && getSize (operandType (IC_RIGHT (uic))) != 2))
2281     {
2282       D (D_HLUSE, ("  + Dropping as the result size is not 2\n"));
2283       return;
2284     }
2285
2286   if (IS_Z80)
2287     {
2288       if (ic->op == CAST && uic->op == IPUSH)
2289         goto hluse;
2290       if (ic->op == ADDRESS_OF && uic->op == IPUSH)
2291         goto hluse;
2292       if (ic->op == ADDRESS_OF && POINTER_GET (uic) && IS_ITEMP( IC_RESULT (uic)))
2293         goto hluse;
2294       if (ic->op == CALL && ic->parmBytes == 0 && (uic->op == '-' || uic->op == '+'))
2295         goto hluse;
2296     }
2297   else if (IS_GB)
2298     {
2299       /* Case of assign a constant to offset in a static array. */
2300       if (ic->op == '+' && IS_VALOP (IC_RIGHT (ic)))
2301         {
2302           if (uic->op == '=' && POINTER_SET (uic))
2303             {
2304               goto hluse;
2305             }
2306           else if (uic->op == IPUSH && getSize (operandType (IC_LEFT (uic))) == 2)
2307             {
2308               goto hluse;
2309             }
2310         }
2311     }
2312
2313   D (D_HLUSE, ("  + Dropping as it's a bad op\n"));
2314   return;
2315 hluse:
2316   OP_SYMBOL (IC_RESULT (ic))->accuse = ACCUSE_SCRATCH;
2317 }
2318
2319 static iCode *
2320 packRegsForHLUse3 (iCode * lic, operand * op, eBBlock * ebp)
2321 {
2322   int i, key;
2323   symbol *sym;
2324   iCode *ic, *dic;
2325   bool isFirst = TRUE;
2326
2327   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));
2328   if (D_PACK_HLUSE3)
2329     piCode(lic, NULL);
2330
2331   if ( OP_SYMBOL(op)->accuse)
2332     {
2333       return NULL;
2334     }
2335
2336   if (OP_SYMBOL(op)->remat)
2337     {
2338       return NULL; 
2339     }
2340
2341   /* Only defined once */
2342   if (bitVectnBitsOn (OP_DEFS (op)) > 1)
2343     return NULL;
2344
2345   if (getSize (operandType (op)) > 2)
2346     return NULL;
2347
2348   /* And this is the definition */
2349   if (bitVectFirstBit (OP_DEFS (op)) != lic->key)
2350     return NULL;
2351
2352   /* first check if any overlapping liverange has already been
2353      assigned to DPTR */
2354   if (OP_SYMBOL(op)->clashes) 
2355     {
2356       for (i = 0 ; i < OP_SYMBOL(op)->clashes->size ; i++ ) 
2357         {
2358           if (bitVectBitValue(OP_SYMBOL(op)->clashes,i)) 
2359             {
2360               sym = hTabItemWithKey(liveRanges,i);
2361               if (sym->accuse == ACCUSE_SCRATCH)
2362                 {
2363                   return NULL;
2364                 }
2365             }
2366         }
2367     }
2368
2369   /* Nothing else that clashes with this is using the scratch
2370      register.  Scan through all of the intermediate instructions and
2371      see if any of them could nuke HL.
2372   */
2373   dic = ic = hTabFirstItemWK(iCodeSeqhTab,OP_SYMBOL(op)->liveFrom);
2374
2375   for (; ic && ic->seq <= OP_SYMBOL(op)->liveTo;
2376        ic = hTabNextItem(iCodeSeqhTab, &key)) 
2377     {
2378       if (D_PACK_HLUSE3)
2379         piCode(ic, NULL);
2380       D (D_PACK_HLUSE3, ("(On %p: op: %u next: %p)\n", ic, ic->op, ic->next));
2381
2382       if (isFirst)
2383         {
2384           isFirst = FALSE;
2385           if (ic->op == ADDRESS_OF)
2386             continue;
2387           if (POINTER_GET (ic))
2388             continue;
2389           if (ic->op == '=' && !POINTER_SET(ic))
2390             continue;
2391         }
2392
2393       if (IC_RESULT(ic) && IS_SYMOP(IC_RESULT(ic))
2394           && isOperandInDirSpace (IC_RESULT (ic)))
2395         return NULL;
2396
2397       if (IC_LEFT(ic) && IS_SYMOP(IC_LEFT(ic))
2398           && isOperandInDirSpace (IC_LEFT (ic)))
2399         return NULL;
2400
2401       if (IC_RIGHT(ic) && IS_SYMOP(IC_RIGHT(ic))
2402           && isOperandInDirSpace (IC_RIGHT (ic)))
2403         return NULL;
2404
2405       /* Handle the non left/right/result ones first */
2406       if (ic->op == IFX)
2407         continue;
2408       if (ic->op == JUMPTABLE)
2409         return NULL;
2410
2411       if (SKIP_IC2(ic))
2412         continue;
2413
2414       if (ic->op == CAST)
2415         continue;
2416
2417       if (ic->op == IPUSH && isOperandEqual (op, IC_LEFT (ic)))
2418         continue;
2419
2420       if (ic->op == SEND && isOperandEqual (op, IC_LEFT (ic)))
2421         continue;
2422
2423       if (ic->op == CALL && isOperandEqual (op, IC_RESULT (ic)))
2424         continue;
2425
2426       if (ic->op == LEFT_OP && isOperandLiteral (IC_RIGHT (ic)))
2427         continue;
2428
2429       if ((ic->op == '=' && !POINTER_SET(ic)) ||
2430           ic->op == UNARYMINUS ||
2431           ic->op == '+' ||
2432           ic->op == '-' ||
2433           ic->op == '>' ||
2434           ic->op == '<' ||
2435           ic->op == EQ_OP ||
2436           0)
2437         continue;
2438
2439       if (ic->op == '*' && isOperandEqual (op, IC_LEFT (ic)))
2440         continue;
2441
2442       if (POINTER_SET (ic) && isOperandEqual (op, IC_RESULT (ic)))
2443         continue;
2444
2445       if (POINTER_GET (ic) && isOperandEqual (op, IC_LEFT (ic)))
2446         continue;
2447
2448       if (IS_VALOP (IC_RIGHT (ic)) &&
2449           (ic->op == EQ_OP ||
2450            0))
2451         {
2452           continue;
2453         }
2454
2455       /* By default give up */
2456       return NULL;
2457     }
2458
2459   D (D_PACK_HLUSE3, ("Succeeded!\n"))
2460
2461   OP_SYMBOL (op)->accuse = ACCUSE_SCRATCH;
2462   return dic;
2463 }
2464
2465 static iCode *
2466 packRegsForIYUse (iCode * lic, operand * op, eBBlock * ebp)
2467 {
2468   int i, key;
2469   symbol *sym;
2470   iCode *ic, *dic;
2471   bitVect *uses;
2472
2473   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));
2474   if (D_PACK_IY)
2475     piCode(lic, NULL);
2476
2477   if ( OP_SYMBOL(op)->accuse)
2478     {
2479       return NULL;
2480     }
2481
2482   if (OP_SYMBOL(op)->remat)
2483     {
2484       return NULL; 
2485     }
2486
2487   /* Only defined once */
2488   if (bitVectnBitsOn (OP_DEFS (op)) > 1)
2489     return NULL;
2490
2491   /* And this is the definition */
2492   if (bitVectFirstBit (OP_DEFS (op)) != lic->key)
2493     return NULL;
2494
2495   /* first check if any overlapping liverange has already been
2496      assigned to DPTR */
2497   if (OP_SYMBOL(op)->clashes) 
2498     {
2499       for (i = 0 ; i < OP_SYMBOL(op)->clashes->size ; i++ ) 
2500         {
2501           if (bitVectBitValue(OP_SYMBOL(op)->clashes,i)) 
2502             {
2503               sym = hTabItemWithKey(liveRanges,i);
2504               if (sym->accuse == ACCUSE_IY)
2505                 {
2506                   return NULL;
2507                 }
2508             }
2509         }
2510     }
2511
2512   /* Only a few instructions can load into IY */
2513   if (lic->op != '=')
2514     {
2515       return NULL;
2516     }
2517
2518   if (getSize (operandType (op)) != 2)
2519     {
2520       D (D_ACCUSE2, ("  + Dropping as operation has size is too big\n"));
2521       return FALSE;
2522     }
2523
2524   /* Nothing else that clashes with this is using the scratch
2525      register.  Scan through all of the intermediate instructions and
2526      see if any of them could nuke HL.
2527   */
2528   dic = ic = hTabFirstItemWK(iCodeSeqhTab,OP_SYMBOL(op)->liveFrom);
2529   uses = OP_USES(op);
2530
2531   for (; ic && ic->seq <= OP_SYMBOL(op)->liveTo;
2532        ic = hTabNextItem(iCodeSeqhTab,&key)) 
2533     {
2534       if (D_PACK_IY)
2535         piCode(ic, NULL);
2536
2537       if (ic->op == PCALL || 
2538           ic->op == CALL ||
2539           ic->op == JUMPTABLE
2540           )
2541         return NULL;
2542
2543       if (SKIP_IC2(ic))
2544         continue;
2545
2546       /* Be pessamistic. */
2547       if (ic->op == IFX)
2548         return NULL;
2549
2550       D (D_PACK_IY, ("  op: %u uses %u result: %d left: %d right: %d\n", ic->op, bitVectBitValue(uses, ic->key),
2551                      IC_RESULT(ic) && IS_SYMOP(IC_RESULT(ic)) ? isOperandInDirSpace(IC_RESULT(ic)) : -1,
2552                      IC_LEFT(ic) && IS_SYMOP(IC_LEFT(ic)) ? isOperandInDirSpace(IC_LEFT(ic)) : -1,
2553                      IC_RIGHT(ic) && IS_SYMOP(IC_RIGHT(ic)) ? isOperandInDirSpace(IC_RIGHT(ic)) : -1
2554                      ));
2555
2556       if (IC_RESULT(ic) && IS_SYMOP(IC_RESULT(ic)) && 
2557           isOperandInDirSpace(IC_RESULT(ic)))
2558         return NULL;
2559       
2560       if (IC_RIGHT(ic) && IS_SYMOP(IC_RIGHT(ic)) && 
2561           isOperandInDirSpace(IC_RIGHT(ic)))
2562         return NULL;
2563       
2564       if (IC_LEFT(ic) && IS_SYMOP(IC_LEFT(ic)) && 
2565           isOperandInDirSpace(IC_LEFT(ic)))
2566         return NULL;
2567
2568       /* Only certain rules will work against IY.  Check if this iCode uses
2569          this symbol. */
2570       if (bitVectBitValue(uses, ic->key) != 0)
2571         {
2572           if (ic->op == '=' &&
2573               isOperandEqual(IC_RESULT(ic), op))
2574             continue;
2575
2576           if (ic->op == GET_VALUE_AT_ADDRESS &&
2577               isOperandEqual(IC_LEFT(ic), op))
2578             continue;
2579
2580           if (isOperandEqual(IC_RESULT(ic), IC_LEFT(ic)) == FALSE)
2581             return NULL;
2582
2583           if (IC_RIGHT (ic) && IS_VALOP (IC_RIGHT (ic)))
2584             {
2585               if (ic->op == '+' ||
2586                   ic->op == '-')
2587                 {
2588                   /* Only works if the constant is small */
2589                   if (operandLitValue (IC_RIGHT (ic)) < 4)
2590                     continue;
2591                 }
2592             }
2593
2594           return NULL;
2595         }
2596       else
2597         {
2598           /* This iCode doesn't use the sym.  See if this iCode preserves IY.
2599            */
2600           continue;
2601         }
2602
2603       /* By default give up */
2604       return NULL;
2605     }
2606
2607   D (D_PACK_IY, ("Succeeded IY!\n"));
2608
2609   OP_SYMBOL (op)->accuse = ACCUSE_IY;
2610   return dic;
2611 }
2612
2613 /** Returns TRUE if this operation can use acc and if it preserves the value.
2614  */
2615 static bool 
2616 opPreservesA (iCode * uic)
2617 {
2618   if (uic->op == IFX)
2619     {
2620       /* If we've gotten this far then the thing to compare must be
2621          small enough and must be in A.
2622       */
2623       return TRUE;
2624     }
2625
2626   if (uic->op == JUMPTABLE)
2627     {
2628       D (D_ACCUSE2, ("  + Dropping as operation is a Jumptable\n"));
2629       return FALSE;
2630     }
2631
2632   /* A pointer assign preserves A if A is the left value. */
2633   if (uic->op == '=' && POINTER_SET (uic))
2634     {
2635       return TRUE;
2636     }
2637
2638   /* if the usage has only one operand then we can */
2639   /* PENDING: check */
2640   if (IC_LEFT (uic) == NULL ||
2641       IC_RIGHT (uic) == NULL)
2642     {
2643       D (D_ACCUSE2, ("  + Dropping as operation has only one operand\n"));
2644       return FALSE;
2645     }
2646
2647   /* PENDING: check this rule */
2648   if (getSize (operandType (IC_RESULT (uic))) > 1)
2649     {
2650       D (D_ACCUSE2, ("  + Dropping as operation has size is too big\n"));
2651       return FALSE;
2652     }
2653
2654
2655   /* Disabled all of the old rules as they weren't verified and have
2656      caused at least one problem.
2657    */
2658   return FALSE;
2659 }
2660
2661 /** Returns true if this operand preserves the value of A.
2662  */
2663 static bool
2664 opIgnoresA (iCode * ic, iCode * uic)
2665 {
2666   /* A increment of an iTemp by a constant is OK. */
2667   if ( uic->op == '+' &&
2668        IS_ITEMP (IC_LEFT (uic)) &&
2669        IS_ITEMP (IC_RESULT (uic)) &&
2670        IS_OP_LITERAL (IC_RIGHT (uic)))
2671     {
2672       unsigned int icount = (unsigned int) floatFromVal (IC_RIGHT (uic)->operand.valOperand);
2673
2674       /* Being an ITEMP means that we're already a symbol. */
2675       if (icount == 1 &&
2676           IC_RESULT (uic)->operand.symOperand->key == IC_LEFT (uic)->operand.symOperand->key
2677           )
2678         {
2679           return TRUE;
2680         }
2681     }
2682   else if (uic->op == '=' && !POINTER_SET (uic))
2683     {
2684       /* If they are equal and get optimised out then things are OK. */
2685       if (isOperandEqual (IC_RESULT (uic), IC_RIGHT (uic)))
2686         {
2687           /* Straight assign is OK. */
2688           return TRUE;
2689         }
2690     }
2691
2692   return FALSE;
2693 }
2694
2695
2696 /* Some optimisation cases:
2697
2698    1. Part of memcpy
2699 ;       genPointerGet
2700         ld      l,-4(ix)
2701         ld      h,-3(ix)
2702         ld      c,(hl)
2703 ;       genPlus
2704         inc     -4(ix)
2705         jp      nz,00108$
2706         inc     -3(ix)
2707 00108$:
2708 ;       genAssign (pointer)
2709         ld      a,c
2710         ld      (de),a
2711  
2712       want to optimise down to:
2713         ld       hl,-4(ix) ...
2714         ld       a,(hl)
2715         inc      -4(ix).w  ...
2716         ld       (de),a
2717
2718       So genPointer get is OK
2719       genPlus where the right is constant, left is iTemp, and result is same as left
2720       genAssign (pointer) is OK
2721
2722     2. Part of _strcpy
2723 ;       genPointerGet
2724         ld      a,(de)
2725         ld      c,a
2726 ;       genIfx
2727         xor     a,a
2728         or      a,c
2729         jp      z,00103$
2730 ;       _strcpy.c 40
2731 ;       genAssign (pointer)
2732 ;       AOP_STK for _strcpy_to_1_1
2733         ld      l,-2(ix)
2734         ld      h,-1(ix)
2735         ld      (hl),c
2736
2737       want to optimise down to:
2738         ld      a,(de)
2739         or      a,a
2740         jp      z,00103$
2741         ld      (bc),a
2742       
2743       So genIfx where IC_COND has size of 1 and is a constant.
2744 */
2745
2746 /** Pack registers for acc use.
2747     When the result of this operation is small and short lived it may
2748     be able to be stored in the accumulator.
2749
2750     Note that the 'A preserving' list is currently emperical :)
2751  */
2752 static void 
2753 packRegsForAccUse2 (iCode * ic)
2754 {
2755   iCode *uic;
2756
2757   D (D_ACCUSE2, ("packRegsForAccUse2: running on ic %p line %u\n", ic, ic->lineno));
2758   if (D_ACCUSE2)
2759     piCode (ic, NULL);
2760
2761   /* Filter out all but those 'good' commands */
2762   if (
2763        !POINTER_GET (ic) &&
2764        ic->op != '+' &&
2765        ic->op != '-' &&
2766        !IS_BITWISE_OP (ic) &&
2767        ic->op != '=' &&
2768        ic->op != EQ_OP &&
2769        ic->op != '<' &&
2770        ic->op != '>' &&
2771        ic->op != CAST &&
2772        ic->op != GETHBIT &&
2773        1)
2774     {
2775       D (D_ACCUSE2, ("  + Dropping as not a 'good' source command\n"));
2776       return;
2777     }
2778
2779   /* if + or - then it has to be one byte result.
2780      MLH: Ok.
2781    */
2782   if ((ic->op == '+' || ic->op == '-')
2783       && getSize (operandType (IC_RESULT (ic))) > 1)
2784     {
2785       D (D_ACCUSE2, ("  + Dropping as it's a big + or -\n"));
2786       return;
2787     }
2788
2789   /* has only one definition */
2790   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
2791     {
2792       D (D_ACCUSE2, ("  + Dropping as it has more than one definition\n"));
2793       return;
2794     }
2795
2796   /* Right.  We may be able to propagate it through if:
2797      For each in the chain of uses the intermediate is OK.
2798    */
2799   /* Get next with 'uses result' bit on
2800      If this->next == next
2801      Validate use of next
2802      If OK, increase count
2803    */
2804   /* and the usage immediately follows this iCode */
2805   if (!(uic = hTabItemWithKey (iCodehTab,
2806                                bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
2807     {
2808       D (D_ACCUSE2, ("  + Dropping as usage does not follow first\n"));
2809       return;
2810     }
2811
2812   {
2813     /* Create a copy of the OP_USES bit vect */
2814     bitVect *uses = bitVectCopy (OP_USES (IC_RESULT (ic)));
2815     int setBit;
2816     iCode *scan = ic, *next;
2817
2818     do
2819       {
2820         setBit = bitVectFirstBit (uses);
2821         next = hTabItemWithKey (iCodehTab, setBit);
2822         if (scan->next == next)
2823           {
2824             D (D_ACCUSE2_VERBOSE, ("  ! Is next in line\n"));
2825
2826             bitVectUnSetBit (uses, setBit);
2827             /* Still contigous. */
2828             if (!opPreservesA (next))
2829               {
2830                 D (D_ACCUSE2, ("  + Dropping as operation doesn't preserve A\n"));
2831                 return;
2832               }
2833             D (D_ACCUSE2_VERBOSE, ("  ! Preserves A, so continue scanning\n"));
2834             scan = next;
2835           }
2836         else if (scan->next == NULL && bitVectnBitsOn (uses) == 1 && next != NULL)
2837           {
2838             if (next->prev == NULL)
2839               {
2840                 if (!opPreservesA (next))
2841                   {
2842                     D (D_ACCUSE2, ("  + Dropping as operation doesn't preserve A #2\n"));
2843                     return;
2844                   }
2845                 bitVectUnSetBit (uses, setBit);
2846                 scan = next;
2847               }
2848             else 
2849               {
2850                 D (D_ACCUSE2, ("  + Dropping as last in list and next doesn't start a block\n"));
2851                 return;
2852               }
2853           }
2854         else if (scan->next == NULL)
2855           {
2856             D (D_ACCUSE2, ("  + Dropping as hit the end of the list\n"));
2857             D (D_ACCUSE2, ("  + Next in htab: %p\n", next));
2858             return;
2859           }
2860         else
2861           {
2862             if (opIgnoresA (ic, scan->next))
2863               {
2864                 /* Safe for now. */
2865                 scan = scan->next;
2866                 D (D_ACCUSE2_VERBOSE, ("  ! Op ignores A, so continue scanning\n"));
2867               }
2868             else
2869               {
2870                 D (D_ACCUSE2, ("  + Dropping as parts are not consecuitive and intermediate might use A\n"));
2871                 return;
2872               }
2873           }
2874       }
2875     while (!bitVectIsZero (uses));
2876
2877     OP_SYMBOL (IC_RESULT (ic))->accuse = ACCUSE_A;
2878     return;
2879   }
2880 }
2881
2882 /** Does some transformations to reduce register pressure.
2883  */
2884 static void 
2885 packRegisters (eBBlock * ebp)
2886 {
2887   iCode *ic;
2888   int change = 0;
2889
2890   D (D_ALLOC, ("packRegisters: entered.\n"));
2891
2892   while (1 && !DISABLE_PACK_ASSIGN)
2893     {
2894       change = 0;
2895       /* look for assignments of the form */
2896       /* iTempNN = TRueSym (someoperation) SomeOperand */
2897       /*       ....                       */
2898       /* TrueSym := iTempNN:1             */
2899       for (ic = ebp->sch; ic; ic = ic->next)
2900         {
2901           /* find assignment of the form TrueSym := iTempNN:1 */
2902           if (ic->op == '=' && !POINTER_SET (ic))
2903             change += packRegsForAssign (ic, ebp);
2904         }
2905       if (!change)
2906         break;
2907     }
2908
2909   for (ic = ebp->sch; ic; ic = ic->next)
2910     {
2911       /* Safe: address of a true sym is always constant. */
2912       /* if this is an itemp & result of a address of a true sym 
2913          then mark this as rematerialisable   */
2914       D (D_ALLOC, ("packRegisters: looping on ic %p\n", ic));
2915
2916       if (ic->op == ADDRESS_OF &&
2917           IS_ITEMP (IC_RESULT (ic)) &&
2918           IS_TRUE_SYMOP (IC_LEFT (ic)) &&
2919           bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2920           !OP_SYMBOL (IC_LEFT (ic))->onStack)
2921         {
2922
2923           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2924           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2925           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2926         }
2927
2928       /* Safe: just propagates the remat flag */
2929       /* if straight assignment then carry remat flag if this is the
2930          only definition */
2931       if (ic->op == '=' &&
2932           !POINTER_SET (ic) &&
2933           IS_SYMOP (IC_RIGHT (ic)) &&
2934           OP_SYMBOL (IC_RIGHT (ic))->remat &&
2935           bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
2936         {
2937
2938           OP_SYMBOL (IC_RESULT (ic))->remat =
2939             OP_SYMBOL (IC_RIGHT (ic))->remat;
2940           OP_SYMBOL (IC_RESULT (ic))->rematiCode =
2941             OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
2942         }
2943
2944       /* if the condition of an if instruction is defined in the
2945          previous instruction then mark the itemp as a conditional */
2946       if ((IS_CONDITIONAL (ic) ||
2947            ((ic->op == BITWISEAND ||
2948              ic->op == '|' ||
2949              ic->op == '^') &&
2950             isBitwiseOptimizable (ic))) &&
2951           ic->next && ic->next->op == IFX &&
2952           bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
2953           isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
2954           OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2955         {
2956
2957           OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
2958           continue;
2959         }
2960
2961 #if 0
2962       /* reduce for support function calls */
2963       if (ic->supportRtn || ic->op == '+' || ic->op == '-')
2964         packRegsForSupport (ic, ebp);
2965 #endif
2966
2967       /* some cases the redundant moves can
2968          can be eliminated for return statements */
2969       if (ic->op == RETURN || ic->op == SEND)
2970         {
2971           packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2972         }
2973
2974       /* if pointer set & left has a size more than
2975          one and right is not in far space */
2976       if (!DISABLE_PACK_ONE_USE &&
2977           POINTER_SET (ic) &&
2978           /* MLH: no such thing.
2979              !isOperandInFarSpace(IC_RIGHT(ic)) && */
2980           !OP_SYMBOL (IC_RESULT (ic))->remat &&
2981           !IS_OP_RUONLY (IC_RIGHT (ic)) &&
2982           getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
2983         {
2984
2985           packRegsForOneuse (ic, IC_RESULT (ic), ebp);
2986         }
2987
2988       /* if pointer get */
2989       if (!DISABLE_PACK_ONE_USE &&
2990           POINTER_GET (ic) &&
2991           IS_SYMOP (IC_LEFT (ic)) &&
2992       /* MLH: dont have far space
2993          !isOperandInFarSpace(IC_RESULT(ic))&& */
2994           !OP_SYMBOL (IC_LEFT (ic))->remat &&
2995           !IS_OP_RUONLY (IC_RESULT (ic)) &&
2996           getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
2997         {
2998
2999           packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3000         }
3001
3002       /* pack registers for accumulator use, when the result of an
3003          arithmetic or bit wise operation has only one use, that use is
3004          immediately following the defintion and the using iCode has
3005          only one operand or has two operands but one is literal & the
3006          result of that operation is not on stack then we can leave the
3007          result of this operation in acc:b combination */
3008
3009       if (!DISABLE_PACK_HL && IS_ITEMP (IC_RESULT (ic)))
3010         {
3011           /* PENDING */
3012           if (IS_GB)
3013             {
3014               if (0)
3015                 packRegsForHLUse (ic);
3016             }
3017           else
3018             {
3019               packRegsForHLUse3 (ic, IC_RESULT (ic), ebp);
3020             }
3021         }
3022
3023       if (!DISABLE_PACK_IY && IS_ITEMP (IC_RESULT (ic)) && IS_Z80)
3024         {
3025           packRegsForIYUse (ic, IC_RESULT (ic), ebp);
3026         }
3027
3028       if (!DISABLE_PACK_ACC && IS_ITEMP (IC_RESULT (ic)) &&
3029           getSize (operandType (IC_RESULT (ic))) == 1)
3030         {
3031           packRegsForAccUse2 (ic);
3032         }
3033     }
3034 }
3035
3036 /** Joins together two byte constant pushes into one word push.
3037  */
3038 static iCode *
3039 joinPushes (iCode *lic)
3040 {
3041   iCode *ic, *uic;
3042
3043   for (ic = lic; ic; ic = ic->next)
3044     {
3045       int first, second;
3046       value *val;
3047
3048       uic = ic->next;
3049
3050       /* Anything past this? */
3051       if (uic == NULL)
3052         {
3053           continue;
3054         }
3055       /* This and the next pushes? */
3056       if (ic->op != IPUSH || uic->op != IPUSH)
3057         {
3058           continue;
3059         }
3060       /* Both literals? */
3061       if ( !IS_OP_LITERAL (IC_LEFT (ic)) || !IS_OP_LITERAL (IC_LEFT (uic)))
3062         {
3063           continue;
3064         }
3065       /* Both characters? */
3066       if ( getSize (operandType (IC_LEFT (ic))) != 1 || getSize (operandType (IC_LEFT (uic))) != 1)
3067         {
3068           continue;
3069         }
3070       /* Pull out the values, make a new type, and create the new iCode for it.
3071        */
3072       first = (int)operandLitValue ( IC_LEFT (ic));
3073       second = (int)operandLitValue ( IC_LEFT (uic));
3074
3075       sprintf (buffer, "%uu", ((first << 8) | (second & 0xFF)) & 0xFFFFU);
3076       val = constVal (buffer);
3077       SPEC_NOUN (val->type) = V_INT;
3078       IC_LEFT (ic) = operandFromOperand (IC_LEFT (ic));
3079       IC_LEFT (ic)->operand.valOperand = val;
3080       
3081       /* Now remove the second one from the list. */
3082       ic->next = uic->next;
3083       if (uic->next)
3084         {
3085           /* Patch up the reverse link */
3086           uic->next->prev = ic;
3087         }
3088     }
3089
3090   return lic;
3091 }
3092
3093 /*-----------------------------------------------------------------*/
3094 /* assignRegisters - assigns registers to each live range as need  */
3095 /*-----------------------------------------------------------------*/
3096 void 
3097 z80_assignRegisters (eBBlock ** ebbs, int count)
3098 {
3099   iCode *ic;
3100   int i;
3101
3102   D (D_ALLOC, ("\n-> z80_assignRegisters: entered.\n"));
3103
3104   setToNull ((void *) &_G.funcrUsed);
3105   setToNull ((void *) &_G.totRegAssigned);  
3106   _G.stackExtend = _G.dataExtend = 0;
3107
3108   if (IS_GB)
3109     {
3110       /* DE is required for the code gen. */
3111       _G.nRegs = GBZ80_MAX_REGS;
3112       regsZ80 = _gbz80_regs;
3113     }
3114   else
3115     {
3116       _G.nRegs = Z80_MAX_REGS;
3117       regsZ80 = _z80_regs;
3118     }
3119
3120   /* change assignments this will remove some
3121      live ranges reducing some register pressure */
3122   for (i = 0; i < count; i++)
3123     packRegisters (ebbs[i]);
3124
3125   /* liveranges probably changed by register packing
3126      so we compute them again */
3127   recomputeLiveRanges (ebbs, count);
3128
3129   if (options.dump_pack)
3130     dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3131
3132   /* first determine for each live range the number of 
3133      registers & the type of registers required for each */
3134   regTypeNum ();
3135
3136   /* and serially allocate registers */
3137   serialRegAssign (ebbs, count);
3138
3139   freeAllRegs ();
3140   fillGaps();
3141
3142   /* if stack was extended then tell the user */
3143   if (_G.stackExtend)
3144     {
3145 /*      werror(W_TOOMANY_SPILS,"stack", */
3146 /*             _G.stackExtend,currFunc->name,""); */
3147       _G.stackExtend = 0;
3148     }
3149
3150   if (_G.dataExtend)
3151     {
3152 /*      werror(W_TOOMANY_SPILS,"data space", */
3153 /*             _G.dataExtend,currFunc->name,""); */
3154       _G.dataExtend = 0;
3155     }
3156
3157   if (options.dump_rassgn) {
3158     dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3159     dumpLiveRanges (DUMP_LRANGE, liveRanges);
3160   }
3161
3162   /* after that create the register mask
3163      for each of the instruction */
3164   createRegMask (ebbs, count);
3165
3166   /* now get back the chain */
3167   ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3168
3169   ic = joinPushes (ic);
3170
3171   /* redo that offsets for stacked automatic variables */
3172   redoStackOffsets ();
3173
3174   genZ80Code (ic);
3175
3176   /* free up any stackSpil locations allocated */
3177   applyToSet (_G.stackSpil, deallocStackSpil);
3178   _G.slocNum = 0;
3179   setToNull ((void *) &_G.stackSpil);
3180   setToNull ((void *) &_G.spiltSet);
3181   /* mark all registers as free */
3182   freeAllRegs ();
3183
3184   return;
3185 }