1 /* This port is in development, UNSTABLE, DEVELOPERS ONLY! */
4 R0-^-R2(R0L-R2H) used for scratch (byte, word, pointer)
5 R3L-^-R6H used for bytes
7 R15/R6-v-R4 used for words
12 /*------------------------------------------------------------------------
14 SDCCralloc.c - source file for register allocation. (xa51) specific
18 This program is free software; you can redistribute it and/or modify it
19 under the terms of the GNU General Public License as published by the
20 Free Software Foundation; either version 2, or (at your option) any
23 This program is distributed in the hope that it will be useful,
24 but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 GNU General Public License for more details.
28 You should have received a copy of the GNU General Public License
29 along with this program; if not, write to the Free Software
30 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32 In other words, you are welcome to use, share and improve this program.
33 You are forbidden to forbid anyone else to use, share and improve
34 what you give them. Help stamp out software-hoarding!
35 -------------------------------------------------------------------------*/
41 extern void genXA51Code (iCode *);
53 bitVect *totRegAssigned; /* final set of LRs that got into registers */
56 bitVect *funcrUsed; /* registers used in a function */
63 // index size type name regMask isFree symbol
64 {R0L_ID, 1, REG_SCR, "r0l", 0x0001, 1, NULL}, // r0l used for scratch
65 {R0H_ID, 1, REG_SCR, "r0h", 0x0002, 1, NULL}, // r0h used for scratch
66 {R1L_ID, 1, REG_SCR, "r1l", 0x0004, 1, NULL}, // r1l used for scratch
67 {R1H_ID, 1, REG_SCR, "r1h", 0x0008, 1, NULL}, // r1h used for scratch
68 {R2L_ID, 1, REG_PTR, "r2l", 0x0010, 1, NULL},
69 {R2H_ID, 1, REG_PTR, "r2h", 0x0020, 1, NULL},
70 {R3L_ID, 1, REG_PTR, "r3l", 0x0040, 1, NULL},
71 {R3H_ID, 1, REG_PTR, "r3h", 0x0080, 1, NULL},
72 {R4L_ID, 1, REG_PTR, "r4l", 0x0100, 1, NULL},
73 {R4H_ID, 1, REG_PTR, "r4h", 0x0200, 1, NULL},
74 {R5L_ID, 1, REG_PTR, "r5l", 0x0400, 1, NULL},
75 {R5H_ID, 1, REG_PTR, "r5h", 0x0800, 1, NULL},
76 {R6L_ID, 1, REG_PTR, "r6l", 0x1000, 1, NULL},
77 {R6H_ID, 1, REG_PTR, "r6h", 0x2000, 1, NULL},
78 {R7L_ID, 1, REG_STK, "r7l", 0x4000, 1, NULL}, // r7=SP
79 {R7H_ID, 1, REG_STK, "r7h", 0x8000, 1, NULL}, // r7=SP
81 {R0_ID, 2, REG_SCR, "r0", 0x0003, 1, NULL}, // r0 used for scratch
82 {R1_ID, 2, REG_SCR, "r1", 0x000c, 1, NULL}, // r1 used for scratch
83 {R2_ID, 2, REG_PTR, "r2", 0x0030, 1, NULL},
84 {R3_ID, 2, REG_PTR, "r3", 0x00c0, 1, NULL},
85 {R4_ID, 2, REG_PTR, "r4", 0x0300, 1, NULL},
86 {R5_ID, 2, REG_PTR, "r5", 0x0c00, 1, NULL},
87 {R6_ID, 2, REG_PTR, "r6", 0x3000, 1, NULL},
88 {R7_ID, 2, REG_STK, "r7", 0xc000, 1, NULL}, // r7=SP
89 #if 0 // some derivates have even more! (only bit/word access no ptr use)
90 {R8_ID, 2, REG_GPR, "r8", 0x010000, 1, NULL},
91 {R9_ID, 2, REG_GPR, "r9", 0x020000, 1, NULL},
92 {R10_ID, 2, REG_GPR, "r10", 0x040000, 1, NULL},
93 {R11_ID, 2, REG_GPR, "r11", 0x080000, 1, NULL},
94 {R12_ID, 2, REG_GPR, "r12", 0x100000, 1, NULL},
95 {R13_ID, 2, REG_GPR, "r13", 0x200000, 1, NULL},
96 {R14_ID, 2, REG_GPR, "r14", 0x400000, 1, NULL},
97 {R15_ID, 2, REG_GPR, "r15", 0x800000, 1, NULL},
99 {R0R1_ID, 4, REG_GPR, "(r0,r1)", 0x000f, 1, NULL},
100 {R2R3_ID, 4, REG_GPR, "(r2,r3)", 0x00f0, 1, NULL},
101 {R4R5_ID, 4, REG_GPR, "(r4,r5)", 0x0f00, 1, NULL},
102 {R6R7_ID, 4, REG_GPR, "(r6,r7)", 0xf000, 1, NULL},
105 int xa51_nRegs=sizeof(regsXA51)/sizeof(regs);
107 // the currently in use registers
108 unsigned long xa51RegsInUse=0;
110 // this should be set with a command line switch
111 bool xa51HasGprRegs=0;
113 /*-----------------------------------------------------------------*/
114 /* xa51_regWithMask - returns pointer to register with mask */
115 /*-----------------------------------------------------------------*/
116 regs *xa51_regWithMask (unsigned long mask) {
118 for (i=0; i<xa51_nRegs; i++) {
119 if (regsXA51[i].regMask==mask) {
126 /*-----------------------------------------------------------------*/
127 /* checkRegsMask - check the consistancy of the regMask redundancy */
128 /*-----------------------------------------------------------------*/
130 void checkRegMask(const char *f) { // for debugging purposes only
132 unsigned long regMask=0;
134 // rebuild the regmask
135 for (i=0; i<xa51_nRegs; i++) {
136 if (!regsXA51[i].isFree) {
137 regMask |= regsXA51[i].regMask;
142 if (regMask != xa51RegsInUse) {
143 fprintf (stderr, "error(%s): regMask inconsistent 0x%08lx != 0x%08lx\n",
144 f, regMask, xa51RegsInUse);
145 regMask=regMask^xa51RegsInUse;
146 fprintf (stderr, "%s used by %s\n",
147 xa51_regWithMask(regMask)->name,
148 xa51_regWithMask(regMask)->sym->name);
155 char *regTypeToStr(short type) {
158 case REG_PTR: return "ptr"; break; // pointer
159 case REG_GPR: return "gpr"; break; // general purpose
160 case REG_CND: return "cnd"; break; // condition (bit)
161 case REG_STK: return "stk"; break; // stack
162 case REG_SCR: return "scr"; break; // scratch
163 default: return "???";
167 /*-----------------------------------------------------------------*/
168 /* freeReg - frees a previous allocated register */
169 /*-----------------------------------------------------------------*/
170 static void freeReg (regs * reg, bool silent) {
172 checkRegMask(__FUNCTION__);
175 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
176 "freeReg - freeing NULL register");
181 D0(fprintf (stderr, "freeReg: (%08lx) %s (%s) ", xa51RegsInUse,
182 reg->name, reg->sym->name));
185 if (reg->isFree || ((xa51RegsInUse®->regMask)!=reg->regMask)) {
186 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
187 "freeReg - freeing unused register(s)");
190 xa51RegsInUse &= ~reg->regMask;
193 if (!silent) D0(fprintf (stderr, "(%08lx)\n", xa51RegsInUse));
195 checkRegMask(__FUNCTION__);
198 /*-----------------------------------------------------------------*/
199 /* allocReg - allocates register of given size (byte, word, dword) */
200 /* and type (ptr, gpr, cnd) */
201 /*-----------------------------------------------------------------*/
202 static bool allocReg (unsigned int size, int type, symbol *sym,
203 int offset, bool silent) {
206 checkRegMask(__FUNCTION__);
209 D0(fprintf (stderr, "allocReg (%08lx) for %s size:%d, type:%s ",
212 size, regTypeToStr(type)));
217 // TODO: gaps could be filled for dwords too
219 // let's see if we can fill a gap
220 for (i=0; i<xa51_nRegs; i++) {
221 if (regsXA51[i].size==2 && regsXA51[i].type==type) {
222 unsigned long mask=regsXA51[i].regMask & ~xa51RegsInUse;
223 if (mask && mask!=regsXA51[i].regMask) {
224 regs *reg=xa51_regWithMask(mask);
226 sym->regs[offset]=reg;
227 xa51RegsInUse |= mask;
228 reg->isFree=0; // redundant
231 D0(fprintf (stderr, "(using gap) %s\n", reg->name));
233 checkRegMask(__FUNCTION__);
238 // no we can't, fall through
240 for (i=0; i<xa51_nRegs; i++) {
241 if (regsXA51[i].size==size &&
242 regsXA51[i].type==type &&
243 (regsXA51[i].regMask & xa51RegsInUse)==0) {
244 xa51RegsInUse |= regsXA51[i].regMask;
245 regsXA51[i].isFree = 0; // redundant
246 regsXA51[i].sym = sym;
248 D0(fprintf (stderr, "%s\n", regsXA51[i].name));
250 sym->regs[offset]=®sXA51[i];
251 checkRegMask(__FUNCTION__);
256 D0(fprintf (stderr, "failed (%08lx)\n", xa51RegsInUse));
258 checkRegMask(__FUNCTION__);
262 // this must be a generic pointer
264 D0(fprintf (stderr, "trying 1+2\n"));
266 // get the generic part (gpr regs can't be byte)
267 if (allocReg (1, REG_PTR, sym, offset+1, silent)) {
268 // get the pointer part
269 if (allocReg (2, REG_PTR, sym, offset, silent)) {
270 checkRegMask(__FUNCTION__);
273 freeReg(sym->regs[offset+1], silent);
274 sym->regs[offset+1]=NULL;
276 checkRegMask(__FUNCTION__);
279 case 4: // this is a dword
281 D0(fprintf (stderr, "trying 2+2\n"));
283 if ((xa51HasGprRegs && allocReg (2, REG_GPR, sym, offset, silent)) ||
284 allocReg (2, REG_PTR, sym, offset, silent)) {
285 if ((xa51HasGprRegs && allocReg (2, REG_GPR, sym, offset+1, silent)) ||
286 allocReg (2, REG_PTR, sym, offset+1, silent)) {
287 checkRegMask(__FUNCTION__);
291 if (sym->regs[offset]) {
292 freeReg(sym->regs[offset], FALSE);
293 sym->regs[offset]=NULL;
295 checkRegMask(__FUNCTION__);
299 fprintf (stderr, "\nallocReg: cannot allocate reg of size %d\n", size);
304 /*-------------------------------------------------------------------*/
305 /* freeAllRegs - frees all registers */
306 /*-------------------------------------------------------------------*/
307 // just to be sure, this should not be needed
308 static void freeAllRegs (void) {
313 checkRegMask(__FUNCTION__);
316 for (i=0; i<xa51_nRegs; i++) {
317 if (!regsXA51[i].isFree) {
318 strcat (regsFreed, regsXA51[i].name);
319 strcat (regsFreed, " ");
320 regsXA51[i].isFree=1;
321 regsXA51[i].sym=NULL;
327 fprintf (stderr, "freeAllRegisters: %d regs freed (%s)\n", nfr, regsFreed);
332 /*-----------------------------------------------------------------*/
333 /* computeSpillable - given a point find the spillable live ranges */
334 /*-----------------------------------------------------------------*/
335 static bitVect *computeSpillable (iCode * ic) {
338 /* spillable live ranges are those that are live at this
339 point . the following categories need to be subtracted
341 a) - those that are already spilt
342 b) - if being used by this one
343 c) - defined by this one */
345 spillable = bitVectCopy (ic->rlive);
347 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
349 bitVectCplAnd (spillable, ic->uses); /* used in this one */
350 bitVectUnSetBit (spillable, ic->defKey); /* defined by this one */
351 spillable = bitVectIntersect (spillable, _G.regAssigned);
356 /*-----------------------------------------------------------------*/
357 /* noSpilLoc - return true if a variable has no spil location */
358 /*-----------------------------------------------------------------*/
360 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
362 return (sym->usl.spillLoc ? 0 : 1);
365 /*-----------------------------------------------------------------*/
366 /* hasSpilLoc - will return 1 if the symbol has spil location */
367 /*-----------------------------------------------------------------*/
369 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
371 return (sym->usl.spillLoc ? 1 : 0);
374 /*-----------------------------------------------------------------*/
375 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
376 /* but is not used as a pointer */
377 /*-----------------------------------------------------------------*/
379 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
381 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
384 /*-----------------------------------------------------------------*/
385 /* rematable - will return 1 if the remat flag is set */
386 /*-----------------------------------------------------------------*/
388 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
393 /*-----------------------------------------------------------------*/
394 /* notUsedInRemaining - not used or defined in remain of the block */
395 /*-----------------------------------------------------------------*/
397 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
399 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
400 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
403 /*-----------------------------------------------------------------*/
404 /* allLRs - return true for all */
405 /*-----------------------------------------------------------------*/
407 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
412 /*-----------------------------------------------------------------*/
413 /* liveRangesWith - applies function to a given set of live range */
414 /*-----------------------------------------------------------------*/
416 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
417 eBBlock * ebp, iCode * ic)
422 if (!lrs || !lrs->size)
425 for (i = 1; i < lrs->size; i++)
428 if (!bitVectBitValue (lrs, i))
431 /* if we don't find it in the live range
432 hash table we are in serious trouble */
433 if (!(sym = hTabItemWithKey (liveRanges, i)))
435 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
436 "liveRangesWith could not find liveRange");
440 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
441 addSetHead (&rset, sym);
448 /*-----------------------------------------------------------------*/
449 /* leastUsedLR - given a set determines which is the least used */
450 /*-----------------------------------------------------------------*/
452 leastUsedLR (set * sset)
454 symbol *sym = NULL, *lsym = NULL;
456 sym = lsym = setFirstItem (sset);
461 for (; lsym; lsym = setNextItem (sset))
464 /* if usage is the same then prefer
465 the spill the smaller of the two */
466 if (lsym->used == sym->used)
467 if (getSize (lsym->type) < getSize (sym->type))
471 if (lsym->used < sym->used)
476 setToNull ((void *) &sset);
481 /*-----------------------------------------------------------------*/
482 /* noOverLap - will iterate through the list looking for over lap */
483 /*-----------------------------------------------------------------*/
485 noOverLap (set * itmpStack, symbol * fsym)
490 for (sym = setFirstItem (itmpStack); sym;
491 sym = setNextItem (itmpStack))
493 if (bitVectBitValue(sym->clashes,fsym->key)) return 0;
499 /*-----------------------------------------------------------------*/
500 /* isFree - will return 1 if the a free spil location is found */
501 /*-----------------------------------------------------------------*/
502 static DEFSETFUNC (isFree) {
504 V_ARG (symbol **, sloc);
505 V_ARG (symbol *, fsym);
507 /* if already found */
511 /* if it is free && and the itmp assigned to
512 this does not have any overlapping live ranges
513 with the one currently being assigned and
514 the size can be accomodated */
516 noOverLap (sym->usl.itmpStack, fsym) &&
517 /* TODO: this is a waste but causes to many problems
518 getSize (sym->type) >= getSize (fsym->type)) {
520 getSize (sym->type) == getSize (fsym->type)) {
528 /*-----------------------------------------------------------------*/
529 /* createStackSpil - create a location on the stack to spil */
530 /*-----------------------------------------------------------------*/
532 createStackSpil (symbol * sym)
537 D1(fprintf (stderr, " createStackSpil for %s\n", sym->name));
539 /* first go try and find a free one that is already
540 existing on the stack */
541 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
543 /* found a free one : just update & return */
544 sym->usl.spillLoc = sloc;
547 addSetHead (&sloc->usl.itmpStack, sym);
548 D1(fprintf (stderr, " using existing %s\n", sloc->name));
552 sprintf (slocBuffer, "sloc%d", _G.slocNum++);
553 sloc = newiTemp (slocBuffer);
555 /* set the type to the spilling symbol */
556 sloc->type = copyLinkChain (sym->type);
557 sloc->etype = getSpec (sloc->type);
558 SPEC_SCLS (sloc->etype) = S_STACK;
559 SPEC_EXTR (sloc->etype) = 0;
560 SPEC_STAT (sloc->etype) = 0;
561 SPEC_VOLATILE(sloc->etype) = 0;
562 SPEC_ABSA(sloc->etype) = 0;
566 sloc->isref = 1; /* to prevent compiler warning */
568 currFunc->stack += getSize (sloc->type);
569 _G.stackExtend += getSize (sloc->type);
571 /* add it to the _G.stackSpil set */
572 addSetHead (&_G.stackSpil, sloc);
573 sym->usl.spillLoc = sloc;
576 /* add it to the set of itempStack set
577 of the spill location */
578 addSetHead (&sloc->usl.itmpStack, sym);
582 /*-----------------------------------------------------------------*/
583 /* spillThis - spils a specific operand */
584 /*-----------------------------------------------------------------*/
586 spillThis (symbol * sym)
590 D1(fprintf (stderr, " spillThis: %s\n", sym->name));
592 /* if this is rematerializable or has a spillLocation
593 we are okay, else we need to create a spillLocation
595 if (!(sym->remat || sym->usl.spillLoc))
596 createStackSpil (sym);
599 /* mark it has spilt & put it in the spilt set */
600 sym->isspilt = sym->spillA = 1;
601 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
603 bitVectUnSetBit (_G.regAssigned, sym->key);
604 bitVectUnSetBit (_G.totRegAssigned, sym->key);
606 for (i = 0; i < sym->nRegs; i++)
610 freeReg (sym->regs[i], FALSE);
613 if (sym->usl.spillLoc && !sym->remat)
614 sym->usl.spillLoc->allocreq++;
618 /*-----------------------------------------------------------------*/
619 /* selectSpil - select a iTemp to spil : rather a simple procedure */
620 /*-----------------------------------------------------------------*/
622 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
624 bitVect *lrcs = NULL;
628 /* get the spillable live ranges */
629 lrcs = computeSpillable (ic);
631 /* get all live ranges that are rematerizable */
632 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
634 /* return the least used of these */
635 return leastUsedLR (selectS);
638 /* if the symbol is local to the block then */
639 if (forSym->liveTo < ebp->lSeq)
642 /* check if there are any live ranges allocated
643 to registers that are not used in this block */
644 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
646 sym = leastUsedLR (selectS);
647 /* if this is not rematerializable */
656 /* check if there are any live ranges that not
657 used in the remainder of the block */
659 !isiCodeInFunctionCall (ic) &&
660 (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
662 sym = leastUsedLR (selectS);
675 /* find live ranges with spillocation && not used as pointers */
676 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
679 sym = leastUsedLR (selectS);
680 /* mark this as allocation required */
681 sym->usl.spillLoc->allocreq++;
685 /* find live ranges with spillocation */
686 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
689 sym = leastUsedLR (selectS);
690 sym->usl.spillLoc->allocreq++;
694 /* couldn't find then we need to create a spil
695 location on the stack , for which one? the least
697 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
700 /* return a created spil location */
701 sym = createStackSpil (leastUsedLR (selectS));
702 sym->usl.spillLoc->allocreq++;
706 /* this is an extreme situation we will spill
707 this one : happens very rarely but it does happen */
712 /*-----------------------------------------------------------------*/
713 /* spillSomething - spil some variable & mark registers as free */
714 /*-----------------------------------------------------------------*/
716 spillSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
721 /* get something we can spil */
722 ssym = selectSpil (ic, ebp, forSym);
724 D1(fprintf (stderr, " spillSomething: spilling %s\n", ssym->name));
726 /* mark it as spilt */
727 ssym->isspilt = ssym->spillA = 1;
728 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
730 /* mark it as not register assigned &
731 take it away from the set */
732 //bitVectUnSetBit (_G.regAssigned, ssym->key);
733 //bitVectUnSetBit (_G.totRegAssigned, ssym->key);
735 /* mark the registers as free */
736 for (i = 0; i < ssym->nRegs; i++) {
738 freeReg (ssym->regs[i], FALSE);
739 // dont NULL ssym->regs[i], it might be used later
743 /* if this was a block level spil then insert push & pop
744 at the start & end of block respectively */
747 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
748 /* add push to the start of the block */
749 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
750 ebp->sch->next : ebp->sch));
751 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
752 /* add pop to the end of the block */
753 addiCodeToeBBlock (ebp, nic, NULL);
756 /* if spilt because not used in the remainder of the
757 block then add a push before this instruction and
758 a pop at the end of the block */
759 if (ssym->remainSpil)
762 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
763 /* add push just before this instruction */
764 addiCodeToeBBlock (ebp, nic, ic);
766 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
767 /* add pop to the end of the block */
768 addiCodeToeBBlock (ebp, nic, NULL);
777 /*-----------------------------------------------------------------*/
778 /* getRegPtr - will try for PTR if not a GPR type if not spil */
779 /*-----------------------------------------------------------------*/
780 static bool getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym, short offset) {
782 D0(fprintf (stderr, "getRegPtr: %s ", sym->name));
783 D0(printTypeChain(sym->type, stderr));
784 D0(fprintf (stderr, "\n"));
787 /* this looks like an infinite loop but
788 in really selectSpil will abort */
790 /* try for a ptr type */
791 if (allocReg (getSize(sym->type), REG_PTR, sym, offset, FALSE))
794 /* try for gpr type */
795 if (xa51HasGprRegs && allocReg (getSize(sym->type),
796 REG_GPR, sym, offset, FALSE))
799 /* we have to spil */
800 if (!spillSomething (ic, ebp, sym))
806 /*-----------------------------------------------------------------*/
807 /* getRegGpr - will try for GPR if not spil */
808 /*-----------------------------------------------------------------*/
809 static bool getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym, short offset) {
811 D0(fprintf (stderr, "getRegGpr: %s ", sym->name));
812 D0(printTypeChain(sym->type, stderr));
813 D0(fprintf (stderr, "\n"));
816 /* this looks like an infinite loop but
817 in really selectSpil will abort */
819 /* try for gpr type */
820 if (xa51HasGprRegs && allocReg (getSize(sym->type),
821 REG_GPR, sym, offset, FALSE))
824 if (allocReg (getSize(sym->type), REG_PTR, sym, offset, FALSE))
827 /* we have to spil */
828 if (!spillSomething (ic, ebp, sym))
833 /*-----------------------------------------------------------------*/
834 /* deassignLRs - check the live to and if they have registers & are */
835 /* not spilt then free up the registers */
836 /*-----------------------------------------------------------------*/
838 deassignLRs (iCode * ic, eBBlock * ebp)
843 for (sym = hTabFirstItem (liveRanges, &k); sym;
844 sym = hTabNextItem (liveRanges, &k))
846 /* if it does not end here */
847 if (sym->liveTo > ic->seq)
850 /* if it was spilt on stack then we can
851 mark the stack spil location as free */
856 sym->usl.spillLoc->isFree = 1;
862 if (!bitVectBitValue (_G.regAssigned, sym->key))
868 bitVectUnSetBit (_G.regAssigned, sym->key);
871 for (i=0; i < sym->nRegs; i++) {
872 freeReg (sym->regs[i], FALSE);
878 /*-----------------------------------------------------------------*/
879 /* willCauseSpill - determines if allocating will cause a spill */
880 /*-----------------------------------------------------------------*/
881 static bool willCauseSpill (symbol *sym) {
883 // do it the rude way
884 if (allocReg (getSize(sym->type), sym->regType, sym, 0, TRUE) ||
885 allocReg (getSize(sym->type), sym->regType==REG_PTR?REG_GPR:REG_PTR,
887 // so we can, but we won't
888 for (i=0; i<sym->nRegs; i++) {
889 freeReg (sym->regs[i], TRUE);
894 D1(fprintf (stderr, " %s will cause a spill\n", sym->name));
898 /*-----------------------------------------------------------------*/
899 /* positionRegs - the allocator can allocate same registers to res- */
900 /* ult and operand, if this happens make sure they are in the same */
901 /* position as the operand otherwise chaos results */
902 /*-----------------------------------------------------------------*/
904 positionRegs (symbol * result, symbol * opsym)
906 int count = min (result->nRegs, opsym->nRegs);
907 int i, j = 0, shared = 0;
910 /* if the result has been spilt then cannot share */
915 /* first make sure that they actually share */
916 for (i = 0; i < count; i++)
918 for (j = 0; j < count; j++)
920 if (result->regs[i] == opsym->regs[j] && i != j)
930 regs *tmp = result->regs[i];
931 result->regs[i] = result->regs[j];
932 result->regs[j] = tmp;
934 D2(fprintf (stderr, "positionRegs: rearranged regs for %s and %s\n",
935 result->name, opsym->name));
941 /*-----------------------------------------------------------------*/
942 /* serialRegAssign - serially allocate registers to the variables */
943 /*-----------------------------------------------------------------*/
945 serialRegAssign (eBBlock ** ebbs, int count)
950 for (i = 0; i < count; i++) {
954 if (ebbs[i]->noPath &&
955 (ebbs[i]->entryLabel != entryLabel &&
956 ebbs[i]->entryLabel != returnLabel))
959 /* of all instructions do */
960 for (ic = ebbs[i]->sch; ic; ic = ic->next) {
962 /* if result is present && is a true symbol */
963 if (IC_RESULT (ic) && ic->op != IFX &&
964 IS_TRUE_SYMOP (IC_RESULT (ic))) {
965 OP_SYMBOL (IC_RESULT (ic))->allocreq++;
968 /* take away registers from live
969 ranges that end at this instruction */
970 deassignLRs (ic, ebbs[i]);
972 /* some don't need registers */
974 ic->op == JUMPTABLE ||
978 (IC_RESULT (ic) && POINTER_SET (ic)))
981 /* now we need to allocate registers
982 only for the result */
983 if (IC_RESULT (ic)) {
984 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
988 /* Make sure any spill location is definately allocated */
989 if (sym->isspilt && !sym->remat && sym->usl.spillLoc &&
990 !sym->usl.spillLoc->allocreq) {
991 sym->usl.spillLoc->allocreq++;
994 /* if it does not need or is spilt
995 or is already assigned to registers
996 or will not live beyond this instructions */
999 bitVectBitValue (_G.regAssigned, sym->key) ||
1000 sym->liveTo <= ic->seq)
1003 /* if some liverange has been spilt at the block level
1004 and this one live beyond this block then spil this
1006 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq) {
1010 /* if trying to allocate this will cause
1011 a spill and there is nothing to spill
1012 or this one is rematerializable then
1014 willCS = willCauseSpill (sym);
1015 spillable = computeSpillable (ic);
1016 if (sym->remat || (willCS && bitVectIsZero (spillable))) {
1021 /* If the live range preceeds the point of definition
1022 then ideally we must take into account registers that
1023 have been allocated after sym->liveFrom but freed
1024 before ic->seq. This is complicated, so spill this
1025 symbol instead and let fillGaps handle the allocation. */
1026 if (sym->liveFrom < ic->seq) {
1031 /* if it has a spillocation & is used less than
1032 all other live ranges then spill this */
1034 if (sym->usl.spillLoc) {
1035 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
1036 allLRs, ebbs[i], ic));
1037 if (leastUsed && leastUsed->used > sym->used) {
1042 /* if none of the liveRanges have a spillLocation then better
1043 to spill this one than anything else already assigned to registers */
1044 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
1045 /* if this is local to this block then we might find a block spil */
1046 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
1054 /* else we assign registers to it */
1055 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1056 _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key);
1058 if (sym->regType == REG_PTR)
1059 getRegPtr (ic, ebbs[i], sym, 0);
1061 getRegGpr (ic, ebbs[i], sym, 0);
1063 /* if it shares registers with operands make sure
1064 that they are in the same position */
1065 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
1066 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=') {
1067 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1068 OP_SYMBOL (IC_LEFT (ic)));
1070 /* do the same for the right operand */
1071 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
1072 OP_SYMBOL (IC_RIGHT (ic))->nRegs) {
1073 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1074 OP_SYMBOL (IC_RIGHT (ic)));
1081 /*-----------------------------------------------------------------*/
1082 /* rUmaskForOp :- returns register mask for an operand */
1083 /*-----------------------------------------------------------------*/
1084 bitVect *xa51_rUmaskForOp (operand * op) {
1089 /* only temporaries are assigned registers */
1093 sym = OP_SYMBOL (op);
1095 /* if spilt or no registers assigned to it
1097 if (sym->isspilt || !sym->nRegs || !sym->regs[0])
1100 rumask = newBitVect (xa51_nRegs);
1102 for (j = 0; j < sym->nRegs; j++) {
1103 rumask = bitVectSetBit (rumask,
1104 sym->regs[j]->rIdx);
1109 /*-----------------------------------------------------------------*/
1110 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
1111 /*-----------------------------------------------------------------*/
1113 regsUsedIniCode (iCode * ic)
1115 bitVect *rmask = newBitVect (xa51_nRegs);
1117 /* do the special cases first */
1120 rmask = bitVectUnion (rmask,
1121 xa51_rUmaskForOp (IC_COND (ic)));
1125 /* for the jumptable */
1126 if (ic->op == JUMPTABLE)
1128 rmask = bitVectUnion (rmask,
1129 xa51_rUmaskForOp (IC_JTCOND (ic)));
1134 /* of all other cases */
1136 rmask = bitVectUnion (rmask,
1137 xa51_rUmaskForOp (IC_LEFT (ic)));
1141 rmask = bitVectUnion (rmask,
1142 xa51_rUmaskForOp (IC_RIGHT (ic)));
1145 rmask = bitVectUnion (rmask,
1146 xa51_rUmaskForOp (IC_RESULT (ic)));
1152 /*-----------------------------------------------------------------*/
1153 /* createRegMask - for each instruction will determine the regsUsed */
1154 /*-----------------------------------------------------------------*/
1156 createRegMask (eBBlock ** ebbs, int count)
1160 /* for all blocks */
1161 for (i = 0; i < count; i++)
1165 if (ebbs[i]->noPath &&
1166 (ebbs[i]->entryLabel != entryLabel &&
1167 ebbs[i]->entryLabel != returnLabel))
1170 /* for all instructions */
1171 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1176 if (SKIP_IC2 (ic) || !ic->rlive)
1179 /* first mark the registers used in this
1181 ic->rUsed = regsUsedIniCode (ic);
1182 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
1184 /* now create the register mask for those
1185 registers that are in use : this is a
1186 super set of ic->rUsed */
1187 ic->rMask = newBitVect (xa51_nRegs + 1);
1189 /* for all live Ranges alive at this point */
1190 for (j = 1; j < ic->rlive->size; j++)
1195 /* if not alive then continue */
1196 if (!bitVectBitValue (ic->rlive, j))
1199 /* find the live range we are interested in */
1200 if (!(sym = hTabItemWithKey (liveRanges, j)))
1202 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1203 "createRegMask cannot find live range");
1207 /* if no register assigned to it */
1208 if (!sym->nRegs || sym->isspilt)
1211 /* for all the registers allocated to it */
1212 for (k = 0; k < sym->nRegs; k++)
1215 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
1221 /*-----------------------------------------------------------------*/
1222 /* rematStr - returns the rematerialized string for a remat var */
1223 /*-----------------------------------------------------------------*/
1225 rematStr (symbol * sym)
1228 iCode *ic = sym->rematiCode;
1233 /* if plus or minus print the right hand side */
1234 if (ic->op == '+' || ic->op == '-')
1236 sprintf (s, "0x%04x %c ", (int) operandLitValue (IC_RIGHT (ic)),
1239 ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1243 /* cast then continue */
1244 if (IS_CAST_ICODE(ic)) {
1245 ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
1248 /* we reached the end */
1249 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
1256 /*-----------------------------------------------------------------*/
1257 /* regTypeNum - computes the type & number of registers required */
1258 /*-----------------------------------------------------------------*/
1260 regTypeNum (eBBlock *ebbs)
1266 /* for each live range do */
1267 for (sym = hTabFirstItem (liveRanges, &k); sym;
1268 sym = hTabNextItem (liveRanges, &k))
1271 /* if used zero times then no registers needed */
1272 if ((sym->liveTo - sym->liveFrom) == 0)
1276 /* if the live range is a temporary */
1280 /* if the type is marked as a conditional */
1281 if (sym->regType == REG_CND)
1284 /* if used in return only then we don't
1287 if (sym->ruonly || sym->accuse)
1289 if (IS_AGGREGATE (sym->type) || sym->isptr)
1290 sym->type = aggrToPtr (sym->type, FALSE);
1295 /* if the symbol has only one definition &
1296 that definition is a get_pointer */
1297 if (bitVectnBitsOn (sym->defs) == 1 &&
1298 (ic = hTabItemWithKey (iCodehTab,
1299 bitVectFirstBit (sym->defs))) &&
1302 !IS_BITVAR (sym->etype))
1304 /* and that pointer is remat in data space */
1305 if (OP_SYMBOL (IC_LEFT (ic))->remat &&
1306 !IS_CAST_ICODE(OP_SYMBOL (IC_LEFT (ic))->rematiCode) &&
1307 DCL_TYPE (aggrToPtr (operandType(IC_LEFT(ic)), FALSE)) == POINTER)
1309 /* create a psuedo symbol & force a spil */
1310 symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
1311 psym->type = sym->type;
1312 psym->etype = sym->etype;
1313 strcpy (psym->rname, psym->name);
1315 sym->usl.spillLoc = psym;
1316 #if 0 // an alternative fix for bug #480076
1317 /* now this is a useless assignment to itself */
1318 remiCodeFromeBBlock (ebbs, ic);
1320 /* now this really is an assignment to itself, make it so;
1321 it will be optimized out later */
1323 IC_RIGHT(ic)=IC_RESULT(ic);
1329 /* if in data space or idata space then try to
1330 allocate pointer register */
1334 /* if not then we require registers */
1336 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
1337 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1338 getSize (sym->type));
1341 int size=((IS_AGGREGATE (sym->type) || sym->isptr) ?
1342 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1343 getSize (sym->type));
1347 case 2: // word or pointer
1350 case 3: // generic pointer
1353 case 4: // dword or float
1357 fprintf (stderr, "regTypeNum: unknown size\n");
1365 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
1366 printTypeChain (sym->type, stderr);
1367 fprintf (stderr, "\n");
1371 /* determine the type of register required */
1372 if (IS_PTR (sym->type))
1373 sym->regType = REG_PTR;
1375 sym->regType = REG_GPR;
1379 /* for the first run we don't provide */
1380 /* registers for true symbols we will */
1381 /* see how things go */
1387 /*-----------------------------------------------------------------*/
1388 /* deallocStackSpil - this will set the stack pointer back */
1389 /*-----------------------------------------------------------------*/
1391 DEFSETFUNC (deallocStackSpil)
1399 /*-----------------------------------------------------------------*/
1400 /* packRegsForAssign - register reduction for assignment */
1401 /*-----------------------------------------------------------------*/
1403 packRegsForAssign (iCode * ic, eBBlock * ebp)
1407 if (!IS_ITEMP (IC_RIGHT (ic)) ||
1408 OP_LIVETO (IC_RIGHT (ic)) > ic->seq) {
1412 /* find the definition of iTempNN scanning backwards */
1413 for (dic = ic->prev; dic; dic = dic->prev) {
1415 /* if there is a function call then don't pack it */
1416 if ((dic->op == CALL || dic->op == PCALL)) {
1424 if (IS_SYMOP (IC_RESULT (dic)) &&
1425 IC_RESULT (dic)->key == IC_RIGHT (ic)->key) {
1432 return 0; /* did not find */
1434 /* found the definition */
1435 /* replace the result with the result of */
1436 /* this assignment and remove this assignment */
1437 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1438 IC_RESULT (dic) = IC_RESULT (ic);
1440 if (IS_ITEMP (IC_RESULT (dic)) &&
1441 OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
1443 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
1445 /* delete from liverange table also
1446 delete from all the points inbetween and the new
1448 for (sic = dic; sic != ic; sic = sic->next)
1450 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
1451 if (IS_ITEMP (IC_RESULT (dic)))
1452 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
1455 remiCodeFromeBBlock (ebp, ic);
1456 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
1457 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
1458 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
1463 /*-----------------------------------------------------------------*/
1464 /* findAssignToSym : scanning backwards looks for first assig found */
1465 /*-----------------------------------------------------------------*/
1467 findAssignToSym (operand * op, iCode * ic)
1471 for (dic = ic->prev; dic; dic = dic->prev)
1474 /* if definition by assignment */
1475 if (dic->op == '=' &&
1476 !POINTER_SET (dic) &&
1477 IC_RESULT (dic)->key == op->key
1478 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
1482 /* we are interested only if defined in far space */
1483 /* or in stack space in case of + & - */
1485 /* if assigned to a non-symbol then return
1487 if (!IS_SYMOP (IC_RIGHT (dic)))
1490 /* if the symbol is in far space then
1492 if (isOperandInFarSpace (IC_RIGHT (dic)))
1495 /* for + & - operations make sure that
1496 if it is on the stack it is the same
1497 as one of the three operands */
1498 if ((ic->op == '+' || ic->op == '-') &&
1499 OP_SYMBOL (IC_RIGHT (dic))->onStack)
1502 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
1503 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
1504 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
1512 /* if we find an usage then we cannot delete it */
1513 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
1516 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
1519 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
1523 /* now make sure that the right side of dic
1524 is not defined between ic & dic */
1527 iCode *sic = dic->next;
1529 for (; sic != ic; sic = sic->next)
1530 if (IC_RESULT (sic) &&
1531 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
1540 /*-----------------------------------------------------------------*/
1541 /* packRegsForSupport :- reduce some registers for support calls */
1542 /*-----------------------------------------------------------------*/
1544 packRegsForSupport (iCode * ic, eBBlock * ebp)
1549 /* for the left & right operand :- look to see if the
1550 left was assigned a true symbol in far space in that
1551 case replace them */
1553 if (IS_ITEMP (IC_LEFT (ic)) &&
1554 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
1556 dic = findAssignToSym (IC_LEFT (ic), ic);
1561 /* found it we need to remove it from the
1563 for (sic = dic; sic != ic; sic = sic->next)
1564 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
1566 OP_SYMBOL(IC_LEFT (ic))=OP_SYMBOL(IC_RIGHT (dic));
1567 IC_LEFT (ic)->key = OP_SYMBOL(IC_RIGHT (dic))->key;
1568 remiCodeFromeBBlock (ebp, dic);
1569 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1570 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1574 /* do the same for the right operand */
1577 IS_ITEMP (IC_RIGHT (ic)) &&
1578 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
1580 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
1586 /* if this is a subtraction & the result
1587 is a true symbol in far space then don't pack */
1588 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
1590 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
1591 if (IN_FARSPACE (SPEC_OCLS (etype)))
1594 /* found it we need to remove it from the
1596 for (sic = dic; sic != ic; sic = sic->next)
1597 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
1599 IC_RIGHT (ic)->operand.symOperand =
1600 IC_RIGHT (dic)->operand.symOperand;
1601 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
1603 remiCodeFromeBBlock (ebp, dic);
1604 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1605 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1612 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
1615 /*-----------------------------------------------------------------*/
1616 /* packRegsForOneuse : - will reduce some registers for single Use */
1617 /*-----------------------------------------------------------------*/
1619 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
1624 /* if returning a literal then do nothing */
1628 if (ic->op != RETURN &&
1630 !POINTER_SET (ic) &&
1634 /* this routine will mark the a symbol as used in one
1635 instruction use only && if the defintion is local
1636 (ie. within the basic block) && has only one definition &&
1637 that definiion is either a return value from a
1638 function or does not contain any variables in
1640 uses = bitVectCopy (OP_USES (op));
1641 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
1642 if (!bitVectIsZero (uses)) /* has other uses */
1645 /* if it has only one defintion */
1646 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
1647 return NULL; /* has more than one definition */
1649 /* get that definition */
1651 hTabItemWithKey (iCodehTab,
1652 bitVectFirstBit (OP_DEFS (op)))))
1656 /* if that only usage is a cast */
1657 if (dic->op == CAST) {
1658 /* to a bigger type */
1659 if (getSize(OP_SYM_TYPE(IC_RESULT(dic))) >
1660 getSize(OP_SYM_TYPE(IC_RIGHT(dic)))) {
1661 /* than we can not, since we cannot predict the usage of b & acc */
1667 /* found the definition now check if it is local */
1668 if (dic->seq < ebp->fSeq ||
1669 dic->seq > ebp->lSeq)
1670 return NULL; /* non-local */
1672 /* now check if it is the return from
1674 if (dic->op == CALL || dic->op == PCALL)
1676 if (ic->op != SEND && ic->op != RETURN &&
1677 !POINTER_SET(ic) && !POINTER_GET(ic))
1679 OP_SYMBOL (op)->ruonly = 1;
1686 /* otherwise check that the definition does
1687 not contain any symbols in far space */
1688 if (isOperandInFarSpace (IC_LEFT (dic)) ||
1689 isOperandInFarSpace (IC_RIGHT (dic)) ||
1690 IS_OP_RUONLY (IC_LEFT (ic)) ||
1691 IS_OP_RUONLY (IC_RIGHT (ic)))
1698 /* if pointer set then make sure the pointer
1700 if (POINTER_SET (dic) &&
1701 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
1704 if (POINTER_GET (dic) &&
1705 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
1711 /* also make sure the intervenening instructions
1712 don't have any thing in far space */
1713 for (dic = dic->next; dic && dic != ic && sic != ic; dic = dic->next)
1716 /* if there is an intervening function call then no */
1717 if (dic->op == CALL || dic->op == PCALL)
1721 /* if pointer set then make sure the pointer
1723 if (POINTER_SET (dic) &&
1724 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
1727 if (POINTER_GET (dic) &&
1728 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
1732 /* if address of & the result is remat the okay */
1733 if (dic->op == ADDRESS_OF &&
1734 OP_SYMBOL (IC_RESULT (dic))->remat)
1738 /* if operand has size of three or more & this
1739 operation is a '*','/' or '%' then 'b' may
1741 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
1742 getSize (operandType (op)) >= 3)
1747 /* if left or right or result is in far space */
1748 if (isOperandInFarSpace (IC_LEFT (dic)) ||
1749 isOperandInFarSpace (IC_RIGHT (dic)) ||
1750 isOperandInFarSpace (IC_RESULT (dic)) ||
1751 IS_OP_RUONLY (IC_LEFT (dic)) ||
1752 IS_OP_RUONLY (IC_RIGHT (dic)) ||
1753 IS_OP_RUONLY (IC_RESULT (dic)))
1757 /* if left or right or result is on stack */
1758 if (isOperandOnStack(IC_LEFT(dic)) ||
1759 isOperandOnStack(IC_RIGHT(dic)) ||
1760 isOperandOnStack(IC_RESULT(dic))) {
1766 OP_SYMBOL (op)->ruonly = 1;
1767 fprintf (stderr, "%s is used only once in line %d.\n",
1768 OP_SYMBOL(op)->name, ic->lineno);
1773 /*-----------------------------------------------------------------*/
1774 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
1775 /*-----------------------------------------------------------------*/
1777 isBitwiseOptimizable (iCode * ic)
1779 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
1780 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
1782 /* bitwise operations are considered optimizable
1783 under the following conditions (Jean-Louis VERN)
1795 if (IS_LITERAL(rtype) ||
1796 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
1802 /*-----------------------------------------------------------------*/
1803 /* packForPush - hueristics to reduce iCode for pushing */
1804 /*-----------------------------------------------------------------*/
1806 packForPush (iCode * ic, eBBlock * ebp)
1811 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
1814 /* must have only definition & one usage */
1815 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
1816 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
1819 /* find the definition */
1820 if (!(dic = hTabItemWithKey (iCodehTab,
1821 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
1824 if (dic->op != '=' || POINTER_SET (dic))
1827 /* make sure the right side does not have any definitions
1829 dbv = OP_DEFS(IC_RIGHT(dic));
1830 for (lic = ic; lic && lic != dic ; lic = lic->prev) {
1831 if (bitVectBitValue(dbv,lic->key))
1834 /* make sure they have the same type */
1836 sym_link *itype=operandType(IC_LEFT(ic));
1837 sym_link *ditype=operandType(IC_RIGHT(dic));
1839 if (SPEC_USIGN(itype)!=SPEC_USIGN(ditype) ||
1840 SPEC_LONG(itype)!=SPEC_LONG(ditype))
1843 /* extend the live range of replaced operand if needed */
1844 if (OP_SYMBOL(IC_RIGHT(dic))->liveTo < ic->seq) {
1845 OP_SYMBOL(IC_RIGHT(dic))->liveTo = ic->seq;
1847 /* we now know that it has one & only one def & use
1848 and the that the definition is an assignment */
1849 IC_LEFT (ic) = IC_RIGHT (dic);
1851 remiCodeFromeBBlock (ebp, dic);
1852 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1853 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1856 /*-----------------------------------------------------------------*/
1857 /* packRegisters - does some transformations to reduce register */
1859 /*-----------------------------------------------------------------*/
1860 static void packRegisters (eBBlock * ebp) {
1867 for (ic = ebp->sch; ic; ic = ic->next) {
1869 change += packRegsForAssign (ic, ebp);
1876 for (ic = ebp->sch; ic; ic = ic->next)
1878 /* if the condition of an if instruction
1879 is defined in the previous instruction and
1880 this is the only usage then
1881 mark the itemp as a conditional */
1882 if ((IS_CONDITIONAL (ic) ||
1883 (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic)))) {
1884 if (ic->next && ic->next->op == IFX &&
1885 bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
1886 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
1887 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq) {
1888 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
1894 /* if this is an itemp & result of an address of a true sym
1895 then mark this as rematerialisable */
1896 if (ic->op == ADDRESS_OF &&
1897 IS_ITEMP (IC_RESULT (ic)) &&
1898 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
1899 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
1900 !OP_SYMBOL (IC_LEFT (ic))->onStack)
1902 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
1903 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
1904 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
1907 /* if straight assignment then carry remat flag if
1908 this is the only definition */
1909 if (ic->op == '=' &&
1910 !POINTER_SET (ic) &&
1911 IS_SYMOP (IC_RIGHT (ic)) &&
1912 OP_SYMBOL (IC_RIGHT (ic))->remat &&
1913 !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode) &&
1914 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
1917 OP_SYMBOL (IC_RESULT (ic))->remat =
1918 OP_SYMBOL (IC_RIGHT (ic))->remat;
1919 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
1920 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
1923 /* if cast to a generic pointer & the pointer being
1924 cast is remat, then we can remat this cast as well */
1925 if (ic->op == CAST &&
1926 IS_SYMOP(IC_RIGHT(ic)) &&
1927 OP_SYMBOL(IC_RIGHT(ic))->remat ) {
1928 sym_link *to_type = operandType(IC_LEFT(ic));
1929 sym_link *from_type = operandType(IC_RIGHT(ic));
1930 if (IS_GENPTR(to_type) && IS_PTR(from_type)) {
1931 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
1932 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
1933 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
1937 /* if this is a +/- operation with a rematerizable
1938 then mark this as rematerializable as well */
1939 if ((ic->op == '+' || ic->op == '-') &&
1940 (IS_SYMOP (IC_LEFT (ic)) &&
1941 IS_ITEMP (IC_RESULT (ic)) &&
1942 IS_OP_LITERAL (IC_RIGHT (ic))) &&
1943 OP_SYMBOL (IC_LEFT (ic))->remat &&
1944 (!IS_SYMOP (IC_RIGHT (ic)) || !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode)) &&
1945 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1)
1947 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
1948 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
1949 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
1953 /* mark the pointer usages */
1954 if (POINTER_SET (ic))
1955 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
1957 if (POINTER_GET (ic))
1958 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
1960 /* reduce for support function calls */
1961 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
1962 packRegsForSupport (ic, ebp);
1964 /* some cases the redundant moves can
1965 can be eliminated for return statements */
1966 if (ic->op == RETURN || ic->op == SEND) {
1967 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
1970 /* if pointer set & left has a size more than
1971 one and right is not in far space */
1972 if (POINTER_SET (ic) &&
1973 !isOperandInFarSpace (IC_RIGHT (ic)) &&
1974 !OP_SYMBOL (IC_RESULT (ic))->remat &&
1975 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
1976 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
1978 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
1980 /* if pointer get */
1981 if (POINTER_GET (ic) &&
1982 !isOperandInFarSpace (IC_RESULT (ic)) &&
1983 !OP_SYMBOL (IC_LEFT (ic))->remat &&
1984 !IS_OP_RUONLY (IC_RESULT (ic)) &&
1985 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
1987 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
1990 /* if this is cast for intergral promotion then
1991 check if only use of the definition of the
1992 operand being casted/ if yes then replace
1993 the result of that arithmetic operation with
1994 this result and get rid of the cast */
1997 sym_link *fromType = operandType (IC_RIGHT (ic));
1998 sym_link *toType = operandType (IC_LEFT (ic));
2000 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
2001 getSize (fromType) != getSize (toType) &&
2002 SPEC_USIGN (fromType) == SPEC_USIGN (toType))
2005 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2008 if (IS_ARITHMETIC_OP (dic))
2010 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2011 IC_RESULT (dic) = IC_RESULT (ic);
2012 remiCodeFromeBBlock (ebp, ic);
2013 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2014 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2015 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2019 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
2025 /* if the type from and type to are the same
2026 then if this is the only use then packit */
2027 if (compareType (operandType (IC_RIGHT (ic)),
2028 operandType (IC_LEFT (ic))) == 1)
2030 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2033 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2034 IC_RESULT (dic) = IC_RESULT (ic);
2035 remiCodeFromeBBlock (ebp, ic);
2036 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2037 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2038 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2046 iTempNN := (some variable in farspace) V1
2051 if (ic->op == IPUSH)
2053 packForPush (ic, ebp);
2058 /*-----------------------------------------------------------------*/
2059 /* assignRegisters - assigns registers to each live range as need */
2060 /*-----------------------------------------------------------------*/
2062 xa51_assignRegisters (ebbIndex * ebbi)
2064 eBBlock ** ebbs = ebbi->bbOrder;
2065 int count = ebbi->count;
2069 setToNull ((void *) &_G.funcrUsed);
2070 setToNull ((void *) &_G.totRegAssigned);
2073 /* change assignments this will remove some
2074 live ranges reducing some register pressure */
2075 for (i = 0; i < count; i++)
2076 packRegisters (ebbs[i]);
2078 /* liveranges probably changed by register packing
2079 so we compute them again */
2080 recomputeLiveRanges (ebbs, count);
2082 if (options.dump_pack)
2083 dumpEbbsToFileExt (DUMP_PACK, ebbi);
2085 /* first determine for each live range the number of
2086 registers & the type of registers required for each */
2089 /* and serially allocate registers */
2090 serialRegAssign (ebbs, count);
2094 /* if stack was extended then tell the user */
2097 werror(I_EXTENDED_STACK_SPILS,
2098 _G.stackExtend,currFunc->name,"");
2102 /* after that create the register mask
2103 for each of the instruction */
2104 createRegMask (ebbs, count);
2106 /* redo that offsets for stacked automatic variables */
2107 redoStackOffsets ();
2109 if (options.dump_rassgn)
2111 dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
2112 dumpLiveRanges (DUMP_LRANGE, liveRanges);
2115 /* do the overlaysegment stuff SDCCmem.c */
2116 doOverlays (ebbs, count);
2118 /* now get back the chain */
2119 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
2123 /* free up any _G.stackSpil locations allocated */
2124 applyToSet (_G.stackSpil, deallocStackSpil);
2126 setToNull ((void *) &_G.stackSpil);
2127 setToNull ((void *) &_G.spiltSet);
2128 /* mark all registers as free */