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