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 */
658 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
660 sym = leastUsedLR (selectS);
673 /* find live ranges with spillocation && not used as pointers */
674 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
677 sym = leastUsedLR (selectS);
678 /* mark this as allocation required */
679 sym->usl.spillLoc->allocreq++;
683 /* find live ranges with spillocation */
684 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
687 sym = leastUsedLR (selectS);
688 sym->usl.spillLoc->allocreq++;
692 /* couldn't find then we need to create a spil
693 location on the stack , for which one? the least
695 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
698 /* return a created spil location */
699 sym = createStackSpil (leastUsedLR (selectS));
700 sym->usl.spillLoc->allocreq++;
704 /* this is an extreme situation we will spill
705 this one : happens very rarely but it does happen */
710 /*-----------------------------------------------------------------*/
711 /* spillSomething - spil some variable & mark registers as free */
712 /*-----------------------------------------------------------------*/
714 spillSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
719 /* get something we can spil */
720 ssym = selectSpil (ic, ebp, forSym);
722 D1(fprintf (stderr, " spillSomething: spilling %s\n", ssym->name));
724 /* mark it as spilt */
725 ssym->isspilt = ssym->spillA = 1;
726 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
728 /* mark it as not register assigned &
729 take it away from the set */
730 //bitVectUnSetBit (_G.regAssigned, ssym->key);
731 //bitVectUnSetBit (_G.totRegAssigned, ssym->key);
733 /* mark the registers as free */
734 for (i = 0; i < ssym->nRegs; i++) {
736 freeReg (ssym->regs[i], FALSE);
737 // dont NULL ssym->regs[i], it might be used later
741 /* if this was a block level spil then insert push & pop
742 at the start & end of block respectively */
745 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
746 /* add push to the start of the block */
747 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
748 ebp->sch->next : ebp->sch));
749 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
750 /* add pop to the end of the block */
751 addiCodeToeBBlock (ebp, nic, NULL);
754 /* if spilt because not used in the remainder of the
755 block then add a push before this instruction and
756 a pop at the end of the block */
757 if (ssym->remainSpil)
760 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
761 /* add push just before this instruction */
762 addiCodeToeBBlock (ebp, nic, ic);
764 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
765 /* add pop to the end of the block */
766 addiCodeToeBBlock (ebp, nic, NULL);
775 /*-----------------------------------------------------------------*/
776 /* getRegPtr - will try for PTR if not a GPR type if not spil */
777 /*-----------------------------------------------------------------*/
778 static bool getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym, short offset) {
780 D0(fprintf (stderr, "getRegPtr: %s ", sym->name));
781 D0(printTypeChain(sym->type, stderr));
782 D0(fprintf (stderr, "\n"));
785 /* this looks like an infinite loop but
786 in really selectSpil will abort */
788 /* try for a ptr type */
789 if (allocReg (getSize(sym->type), REG_PTR, sym, offset, FALSE))
792 /* try for gpr type */
793 if (xa51HasGprRegs && allocReg (getSize(sym->type),
794 REG_GPR, sym, offset, FALSE))
797 /* we have to spil */
798 if (!spillSomething (ic, ebp, sym))
804 /*-----------------------------------------------------------------*/
805 /* getRegGpr - will try for GPR if not spil */
806 /*-----------------------------------------------------------------*/
807 static bool getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym, short offset) {
809 D0(fprintf (stderr, "getRegGpr: %s ", sym->name));
810 D0(printTypeChain(sym->type, stderr));
811 D0(fprintf (stderr, "\n"));
814 /* this looks like an infinite loop but
815 in really selectSpil will abort */
817 /* try for gpr type */
818 if (xa51HasGprRegs && allocReg (getSize(sym->type),
819 REG_GPR, sym, offset, FALSE))
822 if (allocReg (getSize(sym->type), REG_PTR, sym, offset, FALSE))
825 /* we have to spil */
826 if (!spillSomething (ic, ebp, sym))
831 /*-----------------------------------------------------------------*/
832 /* deassignLRs - check the live to and if they have registers & are */
833 /* not spilt then free up the registers */
834 /*-----------------------------------------------------------------*/
836 deassignLRs (iCode * ic, eBBlock * ebp)
841 for (sym = hTabFirstItem (liveRanges, &k); sym;
842 sym = hTabNextItem (liveRanges, &k))
844 /* if it does not end here */
845 if (sym->liveTo > ic->seq)
848 /* if it was spilt on stack then we can
849 mark the stack spil location as free */
854 sym->usl.spillLoc->isFree = 1;
860 if (!bitVectBitValue (_G.regAssigned, sym->key))
866 bitVectUnSetBit (_G.regAssigned, sym->key);
869 for (i=0; i < sym->nRegs; i++) {
870 freeReg (sym->regs[i], FALSE);
876 /*-----------------------------------------------------------------*/
877 /* willCauseSpill - determines if allocating will cause a spill */
878 /*-----------------------------------------------------------------*/
879 static bool willCauseSpill (symbol *sym) {
881 // do it the rude way
882 if (allocReg (getSize(sym->type), sym->regType, sym, 0, TRUE) ||
883 allocReg (getSize(sym->type), sym->regType==REG_PTR?REG_GPR:REG_PTR,
885 // so we can, but we won't
886 for (i=0; i<sym->nRegs; i++) {
887 freeReg (sym->regs[i], TRUE);
892 D1(fprintf (stderr, " %s will cause a spill\n", sym->name));
896 /*-----------------------------------------------------------------*/
897 /* positionRegs - the allocator can allocate same registers to res- */
898 /* ult and operand, if this happens make sure they are in the same */
899 /* position as the operand otherwise chaos results */
900 /*-----------------------------------------------------------------*/
902 positionRegs (symbol * result, symbol * opsym)
904 int count = min (result->nRegs, opsym->nRegs);
905 int i, j = 0, shared = 0;
908 /* if the result has been spilt then cannot share */
913 /* first make sure that they actually share */
914 for (i = 0; i < count; i++)
916 for (j = 0; j < count; j++)
918 if (result->regs[i] == opsym->regs[j] && i != j)
928 regs *tmp = result->regs[i];
929 result->regs[i] = result->regs[j];
930 result->regs[j] = tmp;
932 D2(fprintf (stderr, "positionRegs: rearranged regs for %s and %s\n",
933 result->name, opsym->name));
939 /*-----------------------------------------------------------------*/
940 /* serialRegAssign - serially allocate registers to the variables */
941 /*-----------------------------------------------------------------*/
943 serialRegAssign (eBBlock ** ebbs, int count)
948 for (i = 0; i < count; i++) {
952 if (ebbs[i]->noPath &&
953 (ebbs[i]->entryLabel != entryLabel &&
954 ebbs[i]->entryLabel != returnLabel))
957 /* of all instructions do */
958 for (ic = ebbs[i]->sch; ic; ic = ic->next) {
960 /* if result is present && is a true symbol */
961 if (IC_RESULT (ic) && ic->op != IFX &&
962 IS_TRUE_SYMOP (IC_RESULT (ic))) {
963 OP_SYMBOL (IC_RESULT (ic))->allocreq++;
966 /* take away registers from live
967 ranges that end at this instruction */
968 deassignLRs (ic, ebbs[i]);
970 /* some don't need registers */
972 ic->op == JUMPTABLE ||
976 (IC_RESULT (ic) && POINTER_SET (ic)))
979 /* now we need to allocate registers
980 only for the result */
981 if (IC_RESULT (ic)) {
982 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
986 /* if it does not need or is spilt
987 or is already assigned to registers
988 or will not live beyond this instructions */
991 bitVectBitValue (_G.regAssigned, sym->key) ||
992 sym->liveTo <= ic->seq)
995 /* if some liverange has been spilt at the block level
996 and this one live beyond this block then spil this
998 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq) {
1002 /* if trying to allocate this will cause
1003 a spill and there is nothing to spill
1004 or this one is rematerializable then
1006 willCS = willCauseSpill (sym);
1007 spillable = computeSpillable (ic);
1008 if (sym->remat || (willCS && bitVectIsZero (spillable))) {
1013 /* if it has a spillocation & is used less than
1014 all other live ranges then spill this */
1016 if (sym->usl.spillLoc) {
1017 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
1018 allLRs, ebbs[i], ic));
1019 if (leastUsed && leastUsed->used > sym->used) {
1024 /* if none of the liveRanges have a spillLocation then better
1025 to spill this one than anything else already assigned to registers */
1026 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
1027 /* if this is local to this block then we might find a block spil */
1028 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
1036 /* else we assign registers to it */
1037 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1038 _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key);
1040 if (sym->regType == REG_PTR)
1041 getRegPtr (ic, ebbs[i], sym, 0);
1043 getRegGpr (ic, ebbs[i], sym, 0);
1045 /* if it shares registers with operands make sure
1046 that they are in the same position */
1047 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
1048 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=') {
1049 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1050 OP_SYMBOL (IC_LEFT (ic)));
1052 /* do the same for the right operand */
1053 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
1054 OP_SYMBOL (IC_RIGHT (ic))->nRegs) {
1055 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1056 OP_SYMBOL (IC_RIGHT (ic)));
1063 /*-----------------------------------------------------------------*/
1064 /* rUmaskForOp :- returns register mask for an operand */
1065 /*-----------------------------------------------------------------*/
1066 bitVect *xa51_rUmaskForOp (operand * op) {
1071 /* only temporaries are assigned registers */
1075 sym = OP_SYMBOL (op);
1077 /* if spilt or no registers assigned to it
1079 if (sym->isspilt || !sym->nRegs || !sym->regs[0])
1082 rumask = newBitVect (xa51_nRegs);
1084 for (j = 0; j < sym->nRegs; j++) {
1085 rumask = bitVectSetBit (rumask,
1086 sym->regs[j]->rIdx);
1091 /*-----------------------------------------------------------------*/
1092 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
1093 /*-----------------------------------------------------------------*/
1095 regsUsedIniCode (iCode * ic)
1097 bitVect *rmask = newBitVect (xa51_nRegs);
1099 /* do the special cases first */
1102 rmask = bitVectUnion (rmask,
1103 xa51_rUmaskForOp (IC_COND (ic)));
1107 /* for the jumptable */
1108 if (ic->op == JUMPTABLE)
1110 rmask = bitVectUnion (rmask,
1111 xa51_rUmaskForOp (IC_JTCOND (ic)));
1116 /* of all other cases */
1118 rmask = bitVectUnion (rmask,
1119 xa51_rUmaskForOp (IC_LEFT (ic)));
1123 rmask = bitVectUnion (rmask,
1124 xa51_rUmaskForOp (IC_RIGHT (ic)));
1127 rmask = bitVectUnion (rmask,
1128 xa51_rUmaskForOp (IC_RESULT (ic)));
1134 /*-----------------------------------------------------------------*/
1135 /* createRegMask - for each instruction will determine the regsUsed */
1136 /*-----------------------------------------------------------------*/
1138 createRegMask (eBBlock ** ebbs, int count)
1142 /* for all blocks */
1143 for (i = 0; i < count; i++)
1147 if (ebbs[i]->noPath &&
1148 (ebbs[i]->entryLabel != entryLabel &&
1149 ebbs[i]->entryLabel != returnLabel))
1152 /* for all instructions */
1153 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1158 if (SKIP_IC2 (ic) || !ic->rlive)
1161 /* first mark the registers used in this
1163 ic->rUsed = regsUsedIniCode (ic);
1164 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
1166 /* now create the register mask for those
1167 registers that are in use : this is a
1168 super set of ic->rUsed */
1169 ic->rMask = newBitVect (xa51_nRegs + 1);
1171 /* for all live Ranges alive at this point */
1172 for (j = 1; j < ic->rlive->size; j++)
1177 /* if not alive then continue */
1178 if (!bitVectBitValue (ic->rlive, j))
1181 /* find the live range we are interested in */
1182 if (!(sym = hTabItemWithKey (liveRanges, j)))
1184 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1185 "createRegMask cannot find live range");
1189 /* if no register assigned to it */
1190 if (!sym->nRegs || sym->isspilt)
1193 /* for all the registers allocated to it */
1194 for (k = 0; k < sym->nRegs; k++)
1197 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
1203 /*-----------------------------------------------------------------*/
1204 /* rematStr - returns the rematerialized string for a remat var */
1205 /*-----------------------------------------------------------------*/
1207 rematStr (symbol * sym)
1210 iCode *ic = sym->rematiCode;
1215 /* if plus or minus print the right hand side */
1216 if (ic->op == '+' || ic->op == '-')
1218 sprintf (s, "0x%04x %c ", (int) operandLitValue (IC_RIGHT (ic)),
1221 ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1225 /* cast then continue */
1226 if (IS_CAST_ICODE(ic)) {
1227 ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
1230 /* we reached the end */
1231 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
1238 /*-----------------------------------------------------------------*/
1239 /* regTypeNum - computes the type & number of registers required */
1240 /*-----------------------------------------------------------------*/
1242 regTypeNum (eBBlock *ebbs)
1248 /* for each live range do */
1249 for (sym = hTabFirstItem (liveRanges, &k); sym;
1250 sym = hTabNextItem (liveRanges, &k))
1253 /* if used zero times then no registers needed */
1254 if ((sym->liveTo - sym->liveFrom) == 0)
1258 /* if the live range is a temporary */
1262 /* if the type is marked as a conditional */
1263 if (sym->regType == REG_CND)
1266 /* if used in return only then we don't
1269 if (sym->ruonly || sym->accuse)
1271 if (IS_AGGREGATE (sym->type) || sym->isptr)
1272 sym->type = aggrToPtr (sym->type, FALSE);
1277 /* if the symbol has only one definition &
1278 that definition is a get_pointer */
1279 if (bitVectnBitsOn (sym->defs) == 1 &&
1280 (ic = hTabItemWithKey (iCodehTab,
1281 bitVectFirstBit (sym->defs))) &&
1284 !IS_BITVAR (sym->etype))
1286 /* and that pointer is remat in data space */
1287 if (OP_SYMBOL (IC_LEFT (ic))->remat &&
1288 !IS_CAST_ICODE(OP_SYMBOL (IC_LEFT (ic))->rematiCode) &&
1289 DCL_TYPE (aggrToPtr (operandType(IC_LEFT(ic)), FALSE)) == POINTER)
1291 /* create a psuedo symbol & force a spil */
1292 symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
1293 psym->type = sym->type;
1294 psym->etype = sym->etype;
1295 strcpy (psym->rname, psym->name);
1297 sym->usl.spillLoc = psym;
1298 #if 0 // an alternative fix for bug #480076
1299 /* now this is a useless assignment to itself */
1300 remiCodeFromeBBlock (ebbs, ic);
1302 /* now this really is an assignment to itself, make it so;
1303 it will be optimized out later */
1305 IC_RIGHT(ic)=IC_RESULT(ic);
1311 /* if in data space or idata space then try to
1312 allocate pointer register */
1316 /* if not then we require registers */
1318 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
1319 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1320 getSize (sym->type));
1323 int size=((IS_AGGREGATE (sym->type) || sym->isptr) ?
1324 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1325 getSize (sym->type));
1329 case 2: // word or pointer
1332 case 3: // generic pointer
1335 case 4: // dword or float
1339 fprintf (stderr, "regTypeNum: unknown size\n");
1347 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
1348 printTypeChain (sym->type, stderr);
1349 fprintf (stderr, "\n");
1353 /* determine the type of register required */
1354 if (IS_PTR (sym->type))
1355 sym->regType = REG_PTR;
1357 sym->regType = REG_GPR;
1361 /* for the first run we don't provide */
1362 /* registers for true symbols we will */
1363 /* see how things go */
1369 /*-----------------------------------------------------------------*/
1370 /* deallocStackSpil - this will set the stack pointer back */
1371 /*-----------------------------------------------------------------*/
1373 DEFSETFUNC (deallocStackSpil)
1381 /*-----------------------------------------------------------------*/
1382 /* packRegsForAssign - register reduction for assignment */
1383 /*-----------------------------------------------------------------*/
1385 packRegsForAssign (iCode * ic, eBBlock * ebp)
1389 if (!IS_ITEMP (IC_RIGHT (ic)) ||
1390 OP_LIVETO (IC_RIGHT (ic)) > ic->seq) {
1394 /* find the definition of iTempNN scanning backwards */
1395 for (dic = ic->prev; dic; dic = dic->prev) {
1397 /* if there is a function call then don't pack it */
1398 if ((dic->op == CALL || dic->op == PCALL)) {
1406 if (IS_SYMOP (IC_RESULT (dic)) &&
1407 IC_RESULT (dic)->key == IC_RIGHT (ic)->key) {
1414 return 0; /* did not find */
1416 /* found the definition */
1417 /* replace the result with the result of */
1418 /* this assignment and remove this assignment */
1419 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1420 IC_RESULT (dic) = IC_RESULT (ic);
1422 if (IS_ITEMP (IC_RESULT (dic)) &&
1423 OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
1425 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
1427 /* delete from liverange table also
1428 delete from all the points inbetween and the new
1430 for (sic = dic; sic != ic; sic = sic->next)
1432 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
1433 if (IS_ITEMP (IC_RESULT (dic)))
1434 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
1437 remiCodeFromeBBlock (ebp, ic);
1438 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
1439 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
1440 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
1445 /*-----------------------------------------------------------------*/
1446 /* findAssignToSym : scanning backwards looks for first assig found */
1447 /*-----------------------------------------------------------------*/
1449 findAssignToSym (operand * op, iCode * ic)
1453 for (dic = ic->prev; dic; dic = dic->prev)
1456 /* if definition by assignment */
1457 if (dic->op == '=' &&
1458 !POINTER_SET (dic) &&
1459 IC_RESULT (dic)->key == op->key
1460 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
1464 /* we are interested only if defined in far space */
1465 /* or in stack space in case of + & - */
1467 /* if assigned to a non-symbol then return
1469 if (!IS_SYMOP (IC_RIGHT (dic)))
1472 /* if the symbol is in far space then
1474 if (isOperandInFarSpace (IC_RIGHT (dic)))
1477 /* for + & - operations make sure that
1478 if it is on the stack it is the same
1479 as one of the three operands */
1480 if ((ic->op == '+' || ic->op == '-') &&
1481 OP_SYMBOL (IC_RIGHT (dic))->onStack)
1484 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
1485 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
1486 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
1494 /* if we find an usage then we cannot delete it */
1495 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
1498 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
1501 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
1505 /* now make sure that the right side of dic
1506 is not defined between ic & dic */
1509 iCode *sic = dic->next;
1511 for (; sic != ic; sic = sic->next)
1512 if (IC_RESULT (sic) &&
1513 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
1522 /*-----------------------------------------------------------------*/
1523 /* packRegsForSupport :- reduce some registers for support calls */
1524 /*-----------------------------------------------------------------*/
1526 packRegsForSupport (iCode * ic, eBBlock * ebp)
1531 /* for the left & right operand :- look to see if the
1532 left was assigned a true symbol in far space in that
1533 case replace them */
1535 if (IS_ITEMP (IC_LEFT (ic)) &&
1536 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
1538 dic = findAssignToSym (IC_LEFT (ic), ic);
1543 /* found it we need to remove it from the
1545 for (sic = dic; sic != ic; sic = sic->next)
1546 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
1548 OP_SYMBOL(IC_LEFT (ic))=OP_SYMBOL(IC_RIGHT (dic));
1549 IC_LEFT (ic)->key = OP_SYMBOL(IC_RIGHT (dic))->key;
1550 remiCodeFromeBBlock (ebp, dic);
1551 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1552 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1556 /* do the same for the right operand */
1559 IS_ITEMP (IC_RIGHT (ic)) &&
1560 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
1562 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
1568 /* if this is a subtraction & the result
1569 is a true symbol in far space then don't pack */
1570 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
1572 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
1573 if (IN_FARSPACE (SPEC_OCLS (etype)))
1576 /* found it we need to remove it from the
1578 for (sic = dic; sic != ic; sic = sic->next)
1579 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
1581 IC_RIGHT (ic)->operand.symOperand =
1582 IC_RIGHT (dic)->operand.symOperand;
1583 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
1585 remiCodeFromeBBlock (ebp, dic);
1586 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1587 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1594 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
1597 /*-----------------------------------------------------------------*/
1598 /* packRegsForOneuse : - will reduce some registers for single Use */
1599 /*-----------------------------------------------------------------*/
1601 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
1606 /* if returning a literal then do nothing */
1610 if (ic->op != RETURN &&
1612 !POINTER_SET (ic) &&
1616 /* this routine will mark the a symbol as used in one
1617 instruction use only && if the defintion is local
1618 (ie. within the basic block) && has only one definition &&
1619 that definiion is either a return value from a
1620 function or does not contain any variables in
1622 uses = bitVectCopy (OP_USES (op));
1623 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
1624 if (!bitVectIsZero (uses)) /* has other uses */
1627 /* if it has only one defintion */
1628 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
1629 return NULL; /* has more than one definition */
1631 /* get that definition */
1633 hTabItemWithKey (iCodehTab,
1634 bitVectFirstBit (OP_DEFS (op)))))
1638 /* if that only usage is a cast */
1639 if (dic->op == CAST) {
1640 /* to a bigger type */
1641 if (getSize(OP_SYM_TYPE(IC_RESULT(dic))) >
1642 getSize(OP_SYM_TYPE(IC_RIGHT(dic)))) {
1643 /* than we can not, since we cannot predict the usage of b & acc */
1649 /* found the definition now check if it is local */
1650 if (dic->seq < ebp->fSeq ||
1651 dic->seq > ebp->lSeq)
1652 return NULL; /* non-local */
1654 /* now check if it is the return from
1656 if (dic->op == CALL || dic->op == PCALL)
1658 if (ic->op != SEND && ic->op != RETURN &&
1659 !POINTER_SET(ic) && !POINTER_GET(ic))
1661 OP_SYMBOL (op)->ruonly = 1;
1668 /* otherwise check that the definition does
1669 not contain any symbols in far space */
1670 if (isOperandInFarSpace (IC_LEFT (dic)) ||
1671 isOperandInFarSpace (IC_RIGHT (dic)) ||
1672 IS_OP_RUONLY (IC_LEFT (ic)) ||
1673 IS_OP_RUONLY (IC_RIGHT (ic)))
1680 /* if pointer set then make sure the pointer
1682 if (POINTER_SET (dic) &&
1683 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
1686 if (POINTER_GET (dic) &&
1687 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
1693 /* also make sure the intervenening instructions
1694 don't have any thing in far space */
1695 for (dic = dic->next; dic && dic != ic && sic != ic; dic = dic->next)
1698 /* if there is an intervening function call then no */
1699 if (dic->op == CALL || dic->op == PCALL)
1703 /* if pointer set then make sure the pointer
1705 if (POINTER_SET (dic) &&
1706 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
1709 if (POINTER_GET (dic) &&
1710 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
1714 /* if address of & the result is remat the okay */
1715 if (dic->op == ADDRESS_OF &&
1716 OP_SYMBOL (IC_RESULT (dic))->remat)
1720 /* if operand has size of three or more & this
1721 operation is a '*','/' or '%' then 'b' may
1723 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
1724 getSize (operandType (op)) >= 3)
1729 /* if left or right or result is in far space */
1730 if (isOperandInFarSpace (IC_LEFT (dic)) ||
1731 isOperandInFarSpace (IC_RIGHT (dic)) ||
1732 isOperandInFarSpace (IC_RESULT (dic)) ||
1733 IS_OP_RUONLY (IC_LEFT (dic)) ||
1734 IS_OP_RUONLY (IC_RIGHT (dic)) ||
1735 IS_OP_RUONLY (IC_RESULT (dic)))
1739 /* if left or right or result is on stack */
1740 if (isOperandOnStack(IC_LEFT(dic)) ||
1741 isOperandOnStack(IC_RIGHT(dic)) ||
1742 isOperandOnStack(IC_RESULT(dic))) {
1748 OP_SYMBOL (op)->ruonly = 1;
1749 fprintf (stderr, "%s is used only once in line %d.\n",
1750 OP_SYMBOL(op)->name, ic->lineno);
1755 /*-----------------------------------------------------------------*/
1756 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
1757 /*-----------------------------------------------------------------*/
1759 isBitwiseOptimizable (iCode * ic)
1761 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
1762 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
1764 /* bitwise operations are considered optimizable
1765 under the following conditions (Jean-Louis VERN)
1777 if (IS_LITERAL(rtype) ||
1778 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
1784 /*-----------------------------------------------------------------*/
1785 /* packForPush - hueristics to reduce iCode for pushing */
1786 /*-----------------------------------------------------------------*/
1788 packForPush (iCode * ic, eBBlock * ebp)
1793 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
1796 /* must have only definition & one usage */
1797 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
1798 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
1801 /* find the definition */
1802 if (!(dic = hTabItemWithKey (iCodehTab,
1803 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
1806 if (dic->op != '=' || POINTER_SET (dic))
1809 /* make sure the right side does not have any definitions
1811 dbv = OP_DEFS(IC_RIGHT(dic));
1812 for (lic = ic; lic && lic != dic ; lic = lic->prev) {
1813 if (bitVectBitValue(dbv,lic->key))
1816 /* make sure they have the same type */
1818 sym_link *itype=operandType(IC_LEFT(ic));
1819 sym_link *ditype=operandType(IC_RIGHT(dic));
1821 if (SPEC_USIGN(itype)!=SPEC_USIGN(ditype) ||
1822 SPEC_LONG(itype)!=SPEC_LONG(ditype))
1825 /* extend the live range of replaced operand if needed */
1826 if (OP_SYMBOL(IC_RIGHT(dic))->liveTo < ic->seq) {
1827 OP_SYMBOL(IC_RIGHT(dic))->liveTo = ic->seq;
1829 /* we now know that it has one & only one def & use
1830 and the that the definition is an assignment */
1831 IC_LEFT (ic) = IC_RIGHT (dic);
1833 remiCodeFromeBBlock (ebp, dic);
1834 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1835 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1838 /*-----------------------------------------------------------------*/
1839 /* packRegisters - does some transformations to reduce register */
1841 /*-----------------------------------------------------------------*/
1842 static void packRegisters (eBBlock * ebp) {
1849 for (ic = ebp->sch; ic; ic = ic->next) {
1851 change += packRegsForAssign (ic, ebp);
1858 for (ic = ebp->sch; ic; ic = ic->next)
1860 /* if the condition of an if instruction
1861 is defined in the previous instruction and
1862 this is the only usage then
1863 mark the itemp as a conditional */
1864 if ((IS_CONDITIONAL (ic) ||
1865 (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic)))) {
1866 if (ic->next && ic->next->op == IFX &&
1867 bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
1868 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
1869 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq) {
1870 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
1876 /* if this is an itemp & result of an address of a true sym
1877 then mark this as rematerialisable */
1878 if (ic->op == ADDRESS_OF &&
1879 IS_ITEMP (IC_RESULT (ic)) &&
1880 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
1881 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
1882 !OP_SYMBOL (IC_LEFT (ic))->onStack)
1884 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
1885 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
1886 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
1889 /* if straight assignment then carry remat flag if
1890 this is the only definition */
1891 if (ic->op == '=' &&
1892 !POINTER_SET (ic) &&
1893 IS_SYMOP (IC_RIGHT (ic)) &&
1894 OP_SYMBOL (IC_RIGHT (ic))->remat &&
1895 !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode) &&
1896 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
1899 OP_SYMBOL (IC_RESULT (ic))->remat =
1900 OP_SYMBOL (IC_RIGHT (ic))->remat;
1901 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
1902 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
1905 /* if cast to a generic pointer & the pointer being
1906 cast is remat, then we can remat this cast as well */
1907 if (ic->op == CAST &&
1908 IS_SYMOP(IC_RIGHT(ic)) &&
1909 OP_SYMBOL(IC_RIGHT(ic))->remat ) {
1910 sym_link *to_type = operandType(IC_LEFT(ic));
1911 sym_link *from_type = operandType(IC_RIGHT(ic));
1912 if (IS_GENPTR(to_type) && IS_PTR(from_type)) {
1913 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
1914 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
1915 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
1919 /* if this is a +/- operation with a rematerizable
1920 then mark this as rematerializable as well */
1921 if ((ic->op == '+' || ic->op == '-') &&
1922 (IS_SYMOP (IC_LEFT (ic)) &&
1923 IS_ITEMP (IC_RESULT (ic)) &&
1924 IS_OP_LITERAL (IC_RIGHT (ic))) &&
1925 OP_SYMBOL (IC_LEFT (ic))->remat &&
1926 (!IS_SYMOP (IC_RIGHT (ic)) || !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode)) &&
1927 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1)
1929 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
1930 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
1931 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
1935 /* mark the pointer usages */
1936 if (POINTER_SET (ic))
1937 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
1939 if (POINTER_GET (ic))
1940 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
1942 /* reduce for support function calls */
1943 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
1944 packRegsForSupport (ic, ebp);
1946 /* some cases the redundant moves can
1947 can be eliminated for return statements */
1948 if (ic->op == RETURN || ic->op == SEND) {
1949 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
1952 /* if pointer set & left has a size more than
1953 one and right is not in far space */
1954 if (POINTER_SET (ic) &&
1955 !isOperandInFarSpace (IC_RIGHT (ic)) &&
1956 !OP_SYMBOL (IC_RESULT (ic))->remat &&
1957 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
1958 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
1960 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
1962 /* if pointer get */
1963 if (POINTER_GET (ic) &&
1964 !isOperandInFarSpace (IC_RESULT (ic)) &&
1965 !OP_SYMBOL (IC_LEFT (ic))->remat &&
1966 !IS_OP_RUONLY (IC_RESULT (ic)) &&
1967 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
1969 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
1972 /* if this is cast for intergral promotion then
1973 check if only use of the definition of the
1974 operand being casted/ if yes then replace
1975 the result of that arithmetic operation with
1976 this result and get rid of the cast */
1979 sym_link *fromType = operandType (IC_RIGHT (ic));
1980 sym_link *toType = operandType (IC_LEFT (ic));
1982 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
1983 getSize (fromType) != getSize (toType) &&
1984 SPEC_USIGN (fromType) == SPEC_USIGN (toType))
1987 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
1990 if (IS_ARITHMETIC_OP (dic))
1992 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1993 IC_RESULT (dic) = IC_RESULT (ic);
1994 remiCodeFromeBBlock (ebp, ic);
1995 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
1996 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
1997 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2001 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
2007 /* if the type from and type to are the same
2008 then if this is the only use then packit */
2009 if (compareType (operandType (IC_RIGHT (ic)),
2010 operandType (IC_LEFT (ic))) == 1)
2012 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2015 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2016 IC_RESULT (dic) = IC_RESULT (ic);
2017 remiCodeFromeBBlock (ebp, ic);
2018 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2019 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2020 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2028 iTempNN := (some variable in farspace) V1
2033 if (ic->op == IPUSH)
2035 packForPush (ic, ebp);
2040 /*-----------------------------------------------------------------*/
2041 /* assignRegisters - assigns registers to each live range as need */
2042 /*-----------------------------------------------------------------*/
2044 xa51_assignRegisters (eBBlock ** ebbs, int count)
2049 setToNull ((void *) &_G.funcrUsed);
2050 setToNull ((void *) &_G.totRegAssigned);
2053 /* change assignments this will remove some
2054 live ranges reducing some register pressure */
2055 for (i = 0; i < count; i++)
2056 packRegisters (ebbs[i]);
2058 if (options.dump_pack)
2059 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
2061 /* first determine for each live range the number of
2062 registers & the type of registers required for each */
2065 /* and serially allocate registers */
2066 serialRegAssign (ebbs, count);
2070 /* if stack was extended then tell the user */
2073 werror(I_EXTENDED_STACK_SPILS,
2074 _G.stackExtend,currFunc->name,"");
2078 /* after that create the register mask
2079 for each of the instruction */
2080 createRegMask (ebbs, count);
2082 /* redo that offsets for stacked automatic variables */
2083 redoStackOffsets ();
2085 if (options.dump_rassgn)
2087 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
2088 dumpLiveRanges (DUMP_LRANGE, liveRanges);
2091 /* do the overlaysegment stuff SDCCmem.c */
2092 doOverlays (ebbs, count);
2094 /* now get back the chain */
2095 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
2099 /* free up any _G.stackSpil locations allocated */
2100 applyToSet (_G.stackSpil, deallocStackSpil);
2102 setToNull ((void **) &_G.stackSpil);
2103 setToNull ((void **) &_G.spiltSet);
2104 /* mark all registers as free */