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(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 (short size, short type, symbol *sym,
203 short 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 /* if it does not need or is spilt
989 or is already assigned to registers
990 or will not live beyond this instructions */
993 bitVectBitValue (_G.regAssigned, sym->key) ||
994 sym->liveTo <= ic->seq)
997 /* if some liverange has been spilt at the block level
998 and this one live beyond this block then spil this
1000 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq) {
1004 /* if trying to allocate this will cause
1005 a spill and there is nothing to spill
1006 or this one is rematerializable then
1008 willCS = willCauseSpill (sym);
1009 spillable = computeSpillable (ic);
1010 if (sym->remat || (willCS && bitVectIsZero (spillable))) {
1015 /* If the live range preceeds the point of definition
1016 then ideally we must take into account registers that
1017 have been allocated after sym->liveFrom but freed
1018 before ic->seq. This is complicated, so spill this
1019 symbol instead and let fillGaps handle the allocation. */
1020 if (sym->liveFrom < ic->seq) {
1025 /* if it has a spillocation & is used less than
1026 all other live ranges then spill this */
1028 if (sym->usl.spillLoc) {
1029 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
1030 allLRs, ebbs[i], ic));
1031 if (leastUsed && leastUsed->used > sym->used) {
1036 /* if none of the liveRanges have a spillLocation then better
1037 to spill this one than anything else already assigned to registers */
1038 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
1039 /* if this is local to this block then we might find a block spil */
1040 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
1048 /* else we assign registers to it */
1049 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1050 _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key);
1052 if (sym->regType == REG_PTR)
1053 getRegPtr (ic, ebbs[i], sym, 0);
1055 getRegGpr (ic, ebbs[i], sym, 0);
1057 /* if it shares registers with operands make sure
1058 that they are in the same position */
1059 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
1060 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=') {
1061 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1062 OP_SYMBOL (IC_LEFT (ic)));
1064 /* do the same for the right operand */
1065 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
1066 OP_SYMBOL (IC_RIGHT (ic))->nRegs) {
1067 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1068 OP_SYMBOL (IC_RIGHT (ic)));
1075 /*-----------------------------------------------------------------*/
1076 /* rUmaskForOp :- returns register mask for an operand */
1077 /*-----------------------------------------------------------------*/
1078 bitVect *xa51_rUmaskForOp (operand * op) {
1083 /* only temporaries are assigned registers */
1087 sym = OP_SYMBOL (op);
1089 /* if spilt or no registers assigned to it
1091 if (sym->isspilt || !sym->nRegs || !sym->regs[0])
1094 rumask = newBitVect (xa51_nRegs);
1096 for (j = 0; j < sym->nRegs; j++) {
1097 rumask = bitVectSetBit (rumask,
1098 sym->regs[j]->rIdx);
1103 /*-----------------------------------------------------------------*/
1104 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
1105 /*-----------------------------------------------------------------*/
1107 regsUsedIniCode (iCode * ic)
1109 bitVect *rmask = newBitVect (xa51_nRegs);
1111 /* do the special cases first */
1114 rmask = bitVectUnion (rmask,
1115 xa51_rUmaskForOp (IC_COND (ic)));
1119 /* for the jumptable */
1120 if (ic->op == JUMPTABLE)
1122 rmask = bitVectUnion (rmask,
1123 xa51_rUmaskForOp (IC_JTCOND (ic)));
1128 /* of all other cases */
1130 rmask = bitVectUnion (rmask,
1131 xa51_rUmaskForOp (IC_LEFT (ic)));
1135 rmask = bitVectUnion (rmask,
1136 xa51_rUmaskForOp (IC_RIGHT (ic)));
1139 rmask = bitVectUnion (rmask,
1140 xa51_rUmaskForOp (IC_RESULT (ic)));
1146 /*-----------------------------------------------------------------*/
1147 /* createRegMask - for each instruction will determine the regsUsed */
1148 /*-----------------------------------------------------------------*/
1150 createRegMask (eBBlock ** ebbs, int count)
1154 /* for all blocks */
1155 for (i = 0; i < count; i++)
1159 if (ebbs[i]->noPath &&
1160 (ebbs[i]->entryLabel != entryLabel &&
1161 ebbs[i]->entryLabel != returnLabel))
1164 /* for all instructions */
1165 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1170 if (SKIP_IC2 (ic) || !ic->rlive)
1173 /* first mark the registers used in this
1175 ic->rUsed = regsUsedIniCode (ic);
1176 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
1178 /* now create the register mask for those
1179 registers that are in use : this is a
1180 super set of ic->rUsed */
1181 ic->rMask = newBitVect (xa51_nRegs + 1);
1183 /* for all live Ranges alive at this point */
1184 for (j = 1; j < ic->rlive->size; j++)
1189 /* if not alive then continue */
1190 if (!bitVectBitValue (ic->rlive, j))
1193 /* find the live range we are interested in */
1194 if (!(sym = hTabItemWithKey (liveRanges, j)))
1196 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1197 "createRegMask cannot find live range");
1201 /* if no register assigned to it */
1202 if (!sym->nRegs || sym->isspilt)
1205 /* for all the registers allocated to it */
1206 for (k = 0; k < sym->nRegs; k++)
1209 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
1215 /*-----------------------------------------------------------------*/
1216 /* rematStr - returns the rematerialized string for a remat var */
1217 /*-----------------------------------------------------------------*/
1219 rematStr (symbol * sym)
1222 iCode *ic = sym->rematiCode;
1227 /* if plus or minus print the right hand side */
1228 if (ic->op == '+' || ic->op == '-')
1230 sprintf (s, "0x%04x %c ", (int) operandLitValue (IC_RIGHT (ic)),
1233 ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1237 /* cast then continue */
1238 if (IS_CAST_ICODE(ic)) {
1239 ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
1242 /* we reached the end */
1243 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
1250 /*-----------------------------------------------------------------*/
1251 /* regTypeNum - computes the type & number of registers required */
1252 /*-----------------------------------------------------------------*/
1254 regTypeNum (eBBlock *ebbs)
1260 /* for each live range do */
1261 for (sym = hTabFirstItem (liveRanges, &k); sym;
1262 sym = hTabNextItem (liveRanges, &k))
1265 /* if used zero times then no registers needed */
1266 if ((sym->liveTo - sym->liveFrom) == 0)
1270 /* if the live range is a temporary */
1274 /* if the type is marked as a conditional */
1275 if (sym->regType == REG_CND)
1278 /* if used in return only then we don't
1281 if (sym->ruonly || sym->accuse)
1283 if (IS_AGGREGATE (sym->type) || sym->isptr)
1284 sym->type = aggrToPtr (sym->type, FALSE);
1289 /* if the symbol has only one definition &
1290 that definition is a get_pointer */
1291 if (bitVectnBitsOn (sym->defs) == 1 &&
1292 (ic = hTabItemWithKey (iCodehTab,
1293 bitVectFirstBit (sym->defs))) &&
1296 !IS_BITVAR (sym->etype))
1298 /* and that pointer is remat in data space */
1299 if (OP_SYMBOL (IC_LEFT (ic))->remat &&
1300 !IS_CAST_ICODE(OP_SYMBOL (IC_LEFT (ic))->rematiCode) &&
1301 DCL_TYPE (aggrToPtr (operandType(IC_LEFT(ic)), FALSE)) == POINTER)
1303 /* create a psuedo symbol & force a spil */
1304 symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
1305 psym->type = sym->type;
1306 psym->etype = sym->etype;
1307 strcpy (psym->rname, psym->name);
1309 sym->usl.spillLoc = psym;
1310 #if 0 // an alternative fix for bug #480076
1311 /* now this is a useless assignment to itself */
1312 remiCodeFromeBBlock (ebbs, ic);
1314 /* now this really is an assignment to itself, make it so;
1315 it will be optimized out later */
1317 IC_RIGHT(ic)=IC_RESULT(ic);
1323 /* if in data space or idata space then try to
1324 allocate pointer register */
1328 /* if not then we require registers */
1330 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
1331 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1332 getSize (sym->type));
1335 int size=((IS_AGGREGATE (sym->type) || sym->isptr) ?
1336 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1337 getSize (sym->type));
1341 case 2: // word or pointer
1344 case 3: // generic pointer
1347 case 4: // dword or float
1351 fprintf (stderr, "regTypeNum: unknown size\n");
1359 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
1360 printTypeChain (sym->type, stderr);
1361 fprintf (stderr, "\n");
1365 /* determine the type of register required */
1366 if (IS_PTR (sym->type))
1367 sym->regType = REG_PTR;
1369 sym->regType = REG_GPR;
1373 /* for the first run we don't provide */
1374 /* registers for true symbols we will */
1375 /* see how things go */
1381 /*-----------------------------------------------------------------*/
1382 /* deallocStackSpil - this will set the stack pointer back */
1383 /*-----------------------------------------------------------------*/
1385 DEFSETFUNC (deallocStackSpil)
1393 /*-----------------------------------------------------------------*/
1394 /* packRegsForAssign - register reduction for assignment */
1395 /*-----------------------------------------------------------------*/
1397 packRegsForAssign (iCode * ic, eBBlock * ebp)
1401 if (!IS_ITEMP (IC_RIGHT (ic)) ||
1402 OP_LIVETO (IC_RIGHT (ic)) > ic->seq) {
1406 /* find the definition of iTempNN scanning backwards */
1407 for (dic = ic->prev; dic; dic = dic->prev) {
1409 /* if there is a function call then don't pack it */
1410 if ((dic->op == CALL || dic->op == PCALL)) {
1418 if (IS_SYMOP (IC_RESULT (dic)) &&
1419 IC_RESULT (dic)->key == IC_RIGHT (ic)->key) {
1426 return 0; /* did not find */
1428 /* found the definition */
1429 /* replace the result with the result of */
1430 /* this assignment and remove this assignment */
1431 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1432 IC_RESULT (dic) = IC_RESULT (ic);
1434 if (IS_ITEMP (IC_RESULT (dic)) &&
1435 OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
1437 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
1439 /* delete from liverange table also
1440 delete from all the points inbetween and the new
1442 for (sic = dic; sic != ic; sic = sic->next)
1444 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
1445 if (IS_ITEMP (IC_RESULT (dic)))
1446 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
1449 remiCodeFromeBBlock (ebp, ic);
1450 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
1451 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
1452 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
1457 /*-----------------------------------------------------------------*/
1458 /* findAssignToSym : scanning backwards looks for first assig found */
1459 /*-----------------------------------------------------------------*/
1461 findAssignToSym (operand * op, iCode * ic)
1465 for (dic = ic->prev; dic; dic = dic->prev)
1468 /* if definition by assignment */
1469 if (dic->op == '=' &&
1470 !POINTER_SET (dic) &&
1471 IC_RESULT (dic)->key == op->key
1472 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
1476 /* we are interested only if defined in far space */
1477 /* or in stack space in case of + & - */
1479 /* if assigned to a non-symbol then return
1481 if (!IS_SYMOP (IC_RIGHT (dic)))
1484 /* if the symbol is in far space then
1486 if (isOperandInFarSpace (IC_RIGHT (dic)))
1489 /* for + & - operations make sure that
1490 if it is on the stack it is the same
1491 as one of the three operands */
1492 if ((ic->op == '+' || ic->op == '-') &&
1493 OP_SYMBOL (IC_RIGHT (dic))->onStack)
1496 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
1497 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
1498 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
1506 /* if we find an usage then we cannot delete it */
1507 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
1510 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
1513 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
1517 /* now make sure that the right side of dic
1518 is not defined between ic & dic */
1521 iCode *sic = dic->next;
1523 for (; sic != ic; sic = sic->next)
1524 if (IC_RESULT (sic) &&
1525 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
1534 /*-----------------------------------------------------------------*/
1535 /* packRegsForSupport :- reduce some registers for support calls */
1536 /*-----------------------------------------------------------------*/
1538 packRegsForSupport (iCode * ic, eBBlock * ebp)
1543 /* for the left & right operand :- look to see if the
1544 left was assigned a true symbol in far space in that
1545 case replace them */
1547 if (IS_ITEMP (IC_LEFT (ic)) &&
1548 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
1550 dic = findAssignToSym (IC_LEFT (ic), ic);
1555 /* found it we need to remove it from the
1557 for (sic = dic; sic != ic; sic = sic->next)
1558 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
1560 OP_SYMBOL(IC_LEFT (ic))=OP_SYMBOL(IC_RIGHT (dic));
1561 IC_LEFT (ic)->key = OP_SYMBOL(IC_RIGHT (dic))->key;
1562 remiCodeFromeBBlock (ebp, dic);
1563 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1564 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1568 /* do the same for the right operand */
1571 IS_ITEMP (IC_RIGHT (ic)) &&
1572 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
1574 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
1580 /* if this is a subtraction & the result
1581 is a true symbol in far space then don't pack */
1582 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
1584 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
1585 if (IN_FARSPACE (SPEC_OCLS (etype)))
1588 /* found it we need to remove it from the
1590 for (sic = dic; sic != ic; sic = sic->next)
1591 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
1593 IC_RIGHT (ic)->operand.symOperand =
1594 IC_RIGHT (dic)->operand.symOperand;
1595 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
1597 remiCodeFromeBBlock (ebp, dic);
1598 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1599 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1606 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
1609 /*-----------------------------------------------------------------*/
1610 /* packRegsForOneuse : - will reduce some registers for single Use */
1611 /*-----------------------------------------------------------------*/
1613 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
1618 /* if returning a literal then do nothing */
1622 if (ic->op != RETURN &&
1624 !POINTER_SET (ic) &&
1628 /* this routine will mark the a symbol as used in one
1629 instruction use only && if the defintion is local
1630 (ie. within the basic block) && has only one definition &&
1631 that definiion is either a return value from a
1632 function or does not contain any variables in
1634 uses = bitVectCopy (OP_USES (op));
1635 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
1636 if (!bitVectIsZero (uses)) /* has other uses */
1639 /* if it has only one defintion */
1640 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
1641 return NULL; /* has more than one definition */
1643 /* get that definition */
1645 hTabItemWithKey (iCodehTab,
1646 bitVectFirstBit (OP_DEFS (op)))))
1650 /* if that only usage is a cast */
1651 if (dic->op == CAST) {
1652 /* to a bigger type */
1653 if (getSize(OP_SYM_TYPE(IC_RESULT(dic))) >
1654 getSize(OP_SYM_TYPE(IC_RIGHT(dic)))) {
1655 /* than we can not, since we cannot predict the usage of b & acc */
1661 /* found the definition now check if it is local */
1662 if (dic->seq < ebp->fSeq ||
1663 dic->seq > ebp->lSeq)
1664 return NULL; /* non-local */
1666 /* now check if it is the return from
1668 if (dic->op == CALL || dic->op == PCALL)
1670 if (ic->op != SEND && ic->op != RETURN &&
1671 !POINTER_SET(ic) && !POINTER_GET(ic))
1673 OP_SYMBOL (op)->ruonly = 1;
1680 /* otherwise check that the definition does
1681 not contain any symbols in far space */
1682 if (isOperandInFarSpace (IC_LEFT (dic)) ||
1683 isOperandInFarSpace (IC_RIGHT (dic)) ||
1684 IS_OP_RUONLY (IC_LEFT (ic)) ||
1685 IS_OP_RUONLY (IC_RIGHT (ic)))
1692 /* if pointer set then make sure the pointer
1694 if (POINTER_SET (dic) &&
1695 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
1698 if (POINTER_GET (dic) &&
1699 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
1705 /* also make sure the intervenening instructions
1706 don't have any thing in far space */
1707 for (dic = dic->next; dic && dic != ic && sic != ic; dic = dic->next)
1710 /* if there is an intervening function call then no */
1711 if (dic->op == CALL || dic->op == PCALL)
1715 /* if pointer set then make sure the pointer
1717 if (POINTER_SET (dic) &&
1718 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
1721 if (POINTER_GET (dic) &&
1722 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
1726 /* if address of & the result is remat the okay */
1727 if (dic->op == ADDRESS_OF &&
1728 OP_SYMBOL (IC_RESULT (dic))->remat)
1732 /* if operand has size of three or more & this
1733 operation is a '*','/' or '%' then 'b' may
1735 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
1736 getSize (operandType (op)) >= 3)
1741 /* if left or right or result is in far space */
1742 if (isOperandInFarSpace (IC_LEFT (dic)) ||
1743 isOperandInFarSpace (IC_RIGHT (dic)) ||
1744 isOperandInFarSpace (IC_RESULT (dic)) ||
1745 IS_OP_RUONLY (IC_LEFT (dic)) ||
1746 IS_OP_RUONLY (IC_RIGHT (dic)) ||
1747 IS_OP_RUONLY (IC_RESULT (dic)))
1751 /* if left or right or result is on stack */
1752 if (isOperandOnStack(IC_LEFT(dic)) ||
1753 isOperandOnStack(IC_RIGHT(dic)) ||
1754 isOperandOnStack(IC_RESULT(dic))) {
1760 OP_SYMBOL (op)->ruonly = 1;
1761 fprintf (stderr, "%s is used only once in line %d.\n",
1762 OP_SYMBOL(op)->name, ic->lineno);
1767 /*-----------------------------------------------------------------*/
1768 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
1769 /*-----------------------------------------------------------------*/
1771 isBitwiseOptimizable (iCode * ic)
1773 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
1774 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
1776 /* bitwise operations are considered optimizable
1777 under the following conditions (Jean-Louis VERN)
1789 if (IS_LITERAL(rtype) ||
1790 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
1796 /*-----------------------------------------------------------------*/
1797 /* packForPush - hueristics to reduce iCode for pushing */
1798 /*-----------------------------------------------------------------*/
1800 packForPush (iCode * ic, eBBlock * ebp)
1805 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
1808 /* must have only definition & one usage */
1809 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
1810 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
1813 /* find the definition */
1814 if (!(dic = hTabItemWithKey (iCodehTab,
1815 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
1818 if (dic->op != '=' || POINTER_SET (dic))
1821 /* make sure the right side does not have any definitions
1823 dbv = OP_DEFS(IC_RIGHT(dic));
1824 for (lic = ic; lic && lic != dic ; lic = lic->prev) {
1825 if (bitVectBitValue(dbv,lic->key))
1828 /* make sure they have the same type */
1830 sym_link *itype=operandType(IC_LEFT(ic));
1831 sym_link *ditype=operandType(IC_RIGHT(dic));
1833 if (SPEC_USIGN(itype)!=SPEC_USIGN(ditype) ||
1834 SPEC_LONG(itype)!=SPEC_LONG(ditype))
1837 /* extend the live range of replaced operand if needed */
1838 if (OP_SYMBOL(IC_RIGHT(dic))->liveTo < ic->seq) {
1839 OP_SYMBOL(IC_RIGHT(dic))->liveTo = ic->seq;
1841 /* we now know that it has one & only one def & use
1842 and the that the definition is an assignment */
1843 IC_LEFT (ic) = IC_RIGHT (dic);
1845 remiCodeFromeBBlock (ebp, dic);
1846 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1847 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1850 /*-----------------------------------------------------------------*/
1851 /* packRegisters - does some transformations to reduce register */
1853 /*-----------------------------------------------------------------*/
1854 static void packRegisters (eBBlock * ebp) {
1861 for (ic = ebp->sch; ic; ic = ic->next) {
1863 change += packRegsForAssign (ic, ebp);
1870 for (ic = ebp->sch; ic; ic = ic->next)
1872 /* if the condition of an if instruction
1873 is defined in the previous instruction and
1874 this is the only usage then
1875 mark the itemp as a conditional */
1876 if ((IS_CONDITIONAL (ic) ||
1877 (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic)))) {
1878 if (ic->next && ic->next->op == IFX &&
1879 bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
1880 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
1881 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq) {
1882 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
1888 /* if this is an itemp & result of an address of a true sym
1889 then mark this as rematerialisable */
1890 if (ic->op == ADDRESS_OF &&
1891 IS_ITEMP (IC_RESULT (ic)) &&
1892 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
1893 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
1894 !OP_SYMBOL (IC_LEFT (ic))->onStack)
1896 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
1897 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
1898 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
1901 /* if straight assignment then carry remat flag if
1902 this is the only definition */
1903 if (ic->op == '=' &&
1904 !POINTER_SET (ic) &&
1905 IS_SYMOP (IC_RIGHT (ic)) &&
1906 OP_SYMBOL (IC_RIGHT (ic))->remat &&
1907 !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode) &&
1908 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
1911 OP_SYMBOL (IC_RESULT (ic))->remat =
1912 OP_SYMBOL (IC_RIGHT (ic))->remat;
1913 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
1914 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
1917 /* if cast to a generic pointer & the pointer being
1918 cast is remat, then we can remat this cast as well */
1919 if (ic->op == CAST &&
1920 IS_SYMOP(IC_RIGHT(ic)) &&
1921 OP_SYMBOL(IC_RIGHT(ic))->remat ) {
1922 sym_link *to_type = operandType(IC_LEFT(ic));
1923 sym_link *from_type = operandType(IC_RIGHT(ic));
1924 if (IS_GENPTR(to_type) && IS_PTR(from_type)) {
1925 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
1926 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
1927 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
1931 /* if this is a +/- operation with a rematerizable
1932 then mark this as rematerializable as well */
1933 if ((ic->op == '+' || ic->op == '-') &&
1934 (IS_SYMOP (IC_LEFT (ic)) &&
1935 IS_ITEMP (IC_RESULT (ic)) &&
1936 IS_OP_LITERAL (IC_RIGHT (ic))) &&
1937 OP_SYMBOL (IC_LEFT (ic))->remat &&
1938 (!IS_SYMOP (IC_RIGHT (ic)) || !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode)) &&
1939 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1)
1941 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
1942 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
1943 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
1947 /* mark the pointer usages */
1948 if (POINTER_SET (ic))
1949 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
1951 if (POINTER_GET (ic))
1952 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
1954 /* reduce for support function calls */
1955 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
1956 packRegsForSupport (ic, ebp);
1958 /* some cases the redundant moves can
1959 can be eliminated for return statements */
1960 if (ic->op == RETURN || ic->op == SEND) {
1961 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
1964 /* if pointer set & left has a size more than
1965 one and right is not in far space */
1966 if (POINTER_SET (ic) &&
1967 !isOperandInFarSpace (IC_RIGHT (ic)) &&
1968 !OP_SYMBOL (IC_RESULT (ic))->remat &&
1969 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
1970 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
1972 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
1974 /* if pointer get */
1975 if (POINTER_GET (ic) &&
1976 !isOperandInFarSpace (IC_RESULT (ic)) &&
1977 !OP_SYMBOL (IC_LEFT (ic))->remat &&
1978 !IS_OP_RUONLY (IC_RESULT (ic)) &&
1979 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
1981 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
1984 /* if this is cast for intergral promotion then
1985 check if only use of the definition of the
1986 operand being casted/ if yes then replace
1987 the result of that arithmetic operation with
1988 this result and get rid of the cast */
1991 sym_link *fromType = operandType (IC_RIGHT (ic));
1992 sym_link *toType = operandType (IC_LEFT (ic));
1994 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
1995 getSize (fromType) != getSize (toType) &&
1996 SPEC_USIGN (fromType) == SPEC_USIGN (toType))
1999 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2002 if (IS_ARITHMETIC_OP (dic))
2004 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2005 IC_RESULT (dic) = IC_RESULT (ic);
2006 remiCodeFromeBBlock (ebp, ic);
2007 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2008 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2009 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2013 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
2019 /* if the type from and type to are the same
2020 then if this is the only use then packit */
2021 if (compareType (operandType (IC_RIGHT (ic)),
2022 operandType (IC_LEFT (ic))) == 1)
2024 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2027 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2028 IC_RESULT (dic) = IC_RESULT (ic);
2029 remiCodeFromeBBlock (ebp, ic);
2030 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2031 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2032 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2040 iTempNN := (some variable in farspace) V1
2045 if (ic->op == IPUSH)
2047 packForPush (ic, ebp);
2052 /*-----------------------------------------------------------------*/
2053 /* assignRegisters - assigns registers to each live range as need */
2054 /*-----------------------------------------------------------------*/
2056 xa51_assignRegisters (eBBlock ** ebbs, int count)
2061 setToNull ((void *) &_G.funcrUsed);
2062 setToNull ((void *) &_G.totRegAssigned);
2065 /* change assignments this will remove some
2066 live ranges reducing some register pressure */
2067 for (i = 0; i < count; i++)
2068 packRegisters (ebbs[i]);
2070 /* liveranges probably changed by register packing
2071 so we compute them again */
2072 recomputeLiveRanges (ebbs, count);
2074 if (options.dump_pack)
2075 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
2077 /* first determine for each live range the number of
2078 registers & the type of registers required for each */
2081 /* and serially allocate registers */
2082 serialRegAssign (ebbs, count);
2086 /* if stack was extended then tell the user */
2089 werror(I_EXTENDED_STACK_SPILS,
2090 _G.stackExtend,currFunc->name,"");
2094 /* after that create the register mask
2095 for each of the instruction */
2096 createRegMask (ebbs, count);
2098 /* redo that offsets for stacked automatic variables */
2099 redoStackOffsets ();
2101 if (options.dump_rassgn)
2103 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
2104 dumpLiveRanges (DUMP_LRANGE, liveRanges);
2107 /* do the overlaysegment stuff SDCCmem.c */
2108 doOverlays (ebbs, count);
2110 /* now get back the chain */
2111 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
2115 /* free up any _G.stackSpil locations allocated */
2116 applyToSet (_G.stackSpil, deallocStackSpil);
2118 setToNull ((void *) &_G.stackSpil);
2119 setToNull ((void *) &_G.spiltSet);
2120 /* mark all registers as free */