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