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