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