1 /*------------------------------------------------------------------------
3 SDCCralloc.c - source file for register allocation. (xa51) specific
5 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
7 This program is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 In other words, you are welcome to use, share and improve this program.
22 You are forbidden to forbid anyone else to use, share and improve
23 what you give them. Help stamp out software-hoarding!
24 -------------------------------------------------------------------------*/
30 /*-----------------------------------------------------------------*/
31 /* At this point we start getting processor specific although */
32 /* some routines are non-processor specific & can be reused when */
33 /* targetting other processors. The decision for this will have */
34 /* to be made on a routine by routine basis */
35 /* routines used to pack registers are most definitely not reusable */
36 /* since the pack the registers depending strictly on the MCU */
37 /*-----------------------------------------------------------------*/
39 extern void genXA51Code (iCode *);
49 bitVect *totRegAssigned; /* final set of LRs that got into registers */
52 bitVect *funcrUsed; /* registers used in a function */
60 // index size type name regMask offset isFree symbol
61 {0x20, 2, REG_SCR, "r0", 0x0003, 0, 1, NULL}, // r0 used for scratch
62 {0x21, 2, REG_SCR, "r1", 0x000c, 2, 1, NULL}, // r1 used for scratch
63 {0x22, 2, REG_PTR, "r2", 0x0030, 4, 1, NULL},
64 {0x23, 2, REG_PTR, "r3", 0x00c0, 6, 1, NULL},
65 {0x24, 2, REG_PTR, "r4", 0x0300, 8, 1, NULL},
66 {0x25, 2, REG_PTR, "r5", 0x0c00, 10, 1, NULL},
67 {0x26, 2, REG_PTR, "r6", 0x3000, 12, 1, NULL},
68 {0x27, 2, REG_STK, "r7", 0xc000, 14, 1, NULL}, // r7=SP
69 #if 0 // some derivates have even more! (only bit/word access no ptr use)
70 {0x28, 2, REG_GPR, "r8", 0x10000, 16, 1, NULL},
71 {0x29, 2, REG_GPR, "r9", 0x20000, 18, 1, NULL},
72 {0x2a, 2, REG_GPR, "r10", 0x40000, 20, 1, NULL},
73 {0x2b, 2, REG_GPR, "r11", 0x80000, 22, 1, NULL},
74 {0x2c, 2, REG_GPR, "r12", 0x100000, 24, 1, NULL},
75 {0x2d, 2, REG_GPR, "r13", 0x200000, 26, 1, NULL},
76 {0x2e, 2, REG_GPR, "r14", 0x400000, 28, 1, NULL},
77 {0x2f, 2, REG_GPR, "r15", 0x800000, 20, 1, NULL},
79 {0x10, 1, REG_SCR, "r0h", 0x0001, 1, 1, NULL}, // r0h used for scratch
80 {0x11, 1, REG_SCR, "r0l", 0x0002, 1, 1, NULL}, // r0l used for scratch
81 {0x12, 1, REG_SCR, "r1h", 0x0004, 2, 1, NULL}, // r1h used for scratch
82 {0x13, 1, REG_SCR, "r1l", 0x0008, 3, 1, NULL}, // r1l used for scratch
83 {0x14, 1, REG_PTR, "r2h", 0x0010, 4, 1, NULL},
84 {0x15, 1, REG_PTR, "r2l", 0x0020, 5, 1, NULL},
85 {0x16, 1, REG_PTR, "r3h", 0x0040, 6, 1, NULL},
86 {0x17, 1, REG_PTR, "r3l", 0x0080, 7, 1, NULL},
87 {0x18, 1, REG_PTR, "r4h", 0x0100, 8, 1, NULL},
88 {0x19, 1, REG_PTR, "r4l", 0x0200, 9, 1, NULL},
89 {0x1a, 1, REG_PTR, "r5h", 0x0400, 10, 1, NULL},
90 {0x1b, 1, REG_PTR, "r5l", 0x0800, 11, 1, NULL},
91 {0x1c, 1, REG_PTR, "r6h", 0x1000, 12, 1, NULL},
92 {0x1d, 1, REG_PTR, "r6l", 0x2000, 13, 1, NULL},
93 {0x1e, 1, REG_STK, "r7h", 0x4000, 14, 1, NULL}, // r7=SP
94 {0x1f, 1, REG_STK, "r7l", 0x8000, 15, 1, NULL}, // r7=SP
97 int xa51_nRegs=sizeof(regsXA51)/sizeof(regs);
99 udword xa51RegsInUse=0;
101 // this should be set with a command line switch
102 bool xa51HasGprRegs=0;
104 /*-----------------------------------------------------------------*/
105 /* xa51_regWithMask - returns pointer to register with mask */
106 /*-----------------------------------------------------------------*/
107 regs *xa51_regWithMask (udword mask) {
109 for (i=0; i<xa51_nRegs; i++) {
110 if (regsXA51[i].regMask==mask) {
117 /*-----------------------------------------------------------------*/
118 /* checkRegsMask - check the consistancy of the regMask redundancy */
119 /*-----------------------------------------------------------------*/
121 void checkRegMask(char *f) { // for debugging purposes only
125 for (i=0; i<xa51_nRegs; i++) {
126 if (!regsXA51[i].isFree) {
127 regMask |= regsXA51[i].regMask;
131 if (regMask != xa51RegsInUse) {
132 fprintf (stderr, "error(%s): regMask inconsistent 0x%08x != 0x%08x\n",
133 f, regMask, xa51RegsInUse);
134 regMask=regMask^xa51RegsInUse;
135 fprintf (stderr, "%s used by %s\n",
136 xa51_regWithMask(regMask)->name,
137 xa51_regWithMask(regMask)->sym->name);
144 char *regTypeToStr(short type) {
147 case REG_PTR: return "ptr"; break; // pointer
148 case REG_GPR: return "gpr"; break; // general purpose
149 case REG_CND: return "cnd"; break; // condition (bit)
150 case REG_STK: return "stk"; break; // stack
151 case REG_SCR: return "scr"; break; // scratch
152 default: return "???"; break;
156 /*-----------------------------------------------------------------*/
157 /* freeReg - frees a previous allocated register */
158 /*-----------------------------------------------------------------*/
159 static void freeReg (regs * reg, bool silent) {
161 checkRegMask(__FUNCTION__);
164 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
165 "freeReg - freeing NULL register");
170 D(fprintf (stderr, "freeReg: (%08x) %s (%s) ", xa51RegsInUse,
171 reg->name, reg->sym->name));
174 if (reg->isFree || ((xa51RegsInUse®->regMask)!=reg->regMask)) {
175 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
176 "freeReg - freeing unused register(s)");
179 xa51RegsInUse &= ~reg->regMask;
182 if (!silent) D(fprintf (stderr, "(%08x)\n", xa51RegsInUse));
184 checkRegMask(__FUNCTION__);
187 /*-----------------------------------------------------------------*/
188 /* allocReg - allocates register of given size (byte, word) */
189 /* and type (ptr, gpr, cnd) */
190 /*-----------------------------------------------------------------*/
191 static bool allocReg (short size, short type, symbol *sym,
192 short offset, bool silent) {
195 checkRegMask(__FUNCTION__);
198 D(fprintf (stderr, "allocReg (%08x) for %s size:%d, type:%s ",
201 size, regTypeToStr(type)));
206 // TODO: gaps could be filled for dwords too
208 // let's see if we can fill a gap
209 for (i=0; i<xa51_nRegs; i++) {
210 if (regsXA51[i].size==2 && regsXA51[i].type==type) {
211 udword mask=regsXA51[i].regMask & ~xa51RegsInUse;
212 if (mask && mask!=regsXA51[i].regMask) {
213 regs *reg=xa51_regWithMask(mask);
215 sym->regs[offset]=reg;
216 xa51RegsInUse |= mask;
217 reg->isFree=0; // redundant
220 D(fprintf (stderr, "(using gap) %s\n", reg->name));
222 checkRegMask(__FUNCTION__);
227 // no we can't, fall through
229 for (i=0; i<xa51_nRegs; i++) {
230 if (regsXA51[i].size==size &&
231 regsXA51[i].type==type &&
232 (regsXA51[i].regMask & xa51RegsInUse)==0) {
233 xa51RegsInUse |= regsXA51[i].regMask;
234 regsXA51[i].isFree = 0; // redundant
235 regsXA51[i].sym = sym;
237 D(fprintf (stderr, "%s\n", regsXA51[i].name));
239 sym->regs[offset]=®sXA51[i];
240 checkRegMask(__FUNCTION__);
245 D(fprintf (stderr, "failed (%08x)\n", xa51RegsInUse));
247 checkRegMask(__FUNCTION__);
251 // this must be a generic pointer
253 D(fprintf (stderr, "trying 1+2\n"));
255 // get the generic part
256 if ((xa51HasGprRegs && allocReg (1, REG_GPR, sym, offset+1, silent)) ||
257 allocReg (1, REG_PTR, sym, offset+1, silent)) {
258 // get the pointer part
259 if (allocReg (2, REG_PTR, sym, offset, silent)) {
260 checkRegMask(__FUNCTION__);
263 freeReg(sym->regs[offset+1], silent);
264 sym->regs[offset+1]=NULL;
266 checkRegMask(__FUNCTION__);
269 case 4: // this is a dword
271 D(fprintf (stderr, "trying 2+2\n"));
273 if ((xa51HasGprRegs && allocReg (2, REG_GPR, sym, offset, silent)) ||
274 allocReg (2, REG_PTR, sym, offset, silent)) {
275 if ((xa51HasGprRegs && allocReg (2, REG_GPR, sym, offset+1, silent)) ||
276 allocReg (2, REG_PTR, sym, offset+1, silent)) {
277 checkRegMask(__FUNCTION__);
281 if (sym->regs[offset]) {
282 freeReg(sym->regs[offset], FALSE);
283 sym->regs[offset]=NULL;
285 checkRegMask(__FUNCTION__);
289 fprintf (stderr, "\nallocReg: cannot allocate reg of size %d\n", size);
293 // we should never come here
297 /*-------------------------------------------------------------------*/
298 /* freeAllRegs - frees all registers */
299 /*-------------------------------------------------------------------*/
300 // just to be sure, this should not be needed
301 static void freeAllRegs (void) {
306 checkRegMask(__FUNCTION__);
309 for (i=0; i<xa51_nRegs; i++) {
310 if (!regsXA51[i].isFree) {
311 strcat (regsFreed, regsXA51[i].name);
312 strcat (regsFreed, " ");
313 regsXA51[i].isFree=1;
314 regsXA51[i].sym=NULL;
320 fprintf (stderr, "freeAllRegisters: %d regs freed (%s)\n", nfr, regsFreed);
325 /*-----------------------------------------------------------------*/
326 /* allDefsOutOfRange - all definitions are out of a range */
327 /*-----------------------------------------------------------------*/
328 static bool allDefsOutOfRange (bitVect * defs, int fseq, int toseq) {
334 for (i = 0; i < defs->size; i++)
338 if (bitVectBitValue (defs, i) &&
339 (ic = hTabItemWithKey (iCodehTab, i)) &&
340 (ic->seq >= fseq && ic->seq <= toseq))
346 /*-----------------------------------------------------------------*/
347 /* computeSpillable - given a point find the spillable live ranges */
348 /*-----------------------------------------------------------------*/
349 static bitVect *computeSpillable (iCode * ic) {
352 /* spillable live ranges are those that are live at this
353 point . the following categories need to be subtracted
355 a) - those that are already spilt
356 b) - if being used by this one
357 c) - defined by this one */
359 spillable = bitVectCopy (ic->rlive);
361 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
363 bitVectCplAnd (spillable, ic->uses); /* used in this one */
364 bitVectUnSetBit (spillable, ic->defKey); /* defined by this one */
365 spillable = bitVectIntersect (spillable, _G.regAssigned);
370 /*-----------------------------------------------------------------*/
371 /* noSpilLoc - return true if a variable has no spil location */
372 /*-----------------------------------------------------------------*/
374 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
376 return (sym->usl.spillLoc ? 0 : 1);
379 /*-----------------------------------------------------------------*/
380 /* hasSpilLoc - will return 1 if the symbol has spil location */
381 /*-----------------------------------------------------------------*/
383 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
385 return (sym->usl.spillLoc ? 1 : 0);
388 /*-----------------------------------------------------------------*/
389 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
390 /* but is not used as a pointer */
391 /*-----------------------------------------------------------------*/
393 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
395 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
398 /*-----------------------------------------------------------------*/
399 /* rematable - will return 1 if the remat flag is set */
400 /*-----------------------------------------------------------------*/
402 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
407 /*-----------------------------------------------------------------*/
408 /* notUsedInBlock - not used in this block */
409 /*-----------------------------------------------------------------*/
411 notUsedInBlock (symbol * sym, eBBlock * ebp, iCode * ic)
413 return (!bitVectBitsInCommon (sym->defs, ebp->usesDefs) &&
414 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
415 /* return (!bitVectBitsInCommon(sym->defs,ebp->usesDefs)); */
418 /*-----------------------------------------------------------------*/
419 /* notUsedInRemaining - not used or defined in remain of the block */
420 /*-----------------------------------------------------------------*/
422 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
424 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
425 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
428 /*-----------------------------------------------------------------*/
429 /* allLRs - return true for all */
430 /*-----------------------------------------------------------------*/
432 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
437 /*-----------------------------------------------------------------*/
438 /* liveRangesWith - applies function to a given set of live range */
439 /*-----------------------------------------------------------------*/
441 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
442 eBBlock * ebp, iCode * ic)
447 if (!lrs || !lrs->size)
450 for (i = 1; i < lrs->size; i++)
453 if (!bitVectBitValue (lrs, i))
456 /* if we don't find it in the live range
457 hash table we are in serious trouble */
458 if (!(sym = hTabItemWithKey (liveRanges, i)))
460 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
461 "liveRangesWith could not find liveRange");
465 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
466 addSetHead (&rset, sym);
473 /*-----------------------------------------------------------------*/
474 /* leastUsedLR - given a set determines which is the least used */
475 /*-----------------------------------------------------------------*/
477 leastUsedLR (set * sset)
479 symbol *sym = NULL, *lsym = NULL;
481 sym = lsym = setFirstItem (sset);
486 for (; lsym; lsym = setNextItem (sset))
489 /* if usage is the same then prefer
490 the spill the smaller of the two */
491 if (lsym->used == sym->used)
492 if (getSize (lsym->type) < getSize (sym->type))
496 if (lsym->used < sym->used)
501 setToNull ((void **) &sset);
506 /*-----------------------------------------------------------------*/
507 /* noOverLap - will iterate through the list looking for over lap */
508 /*-----------------------------------------------------------------*/
510 noOverLap (set * itmpStack, symbol * fsym)
515 for (sym = setFirstItem (itmpStack); sym;
516 sym = setNextItem (itmpStack))
518 if (bitVectBitValue(sym->clashes,fsym->key)) return 0;
524 /*-----------------------------------------------------------------*/
525 /* isFree - will return 1 if the a free spil location is found */
526 /*-----------------------------------------------------------------*/
531 V_ARG (symbol **, sloc);
532 V_ARG (symbol *, fsym);
534 /* if already found */
538 /* if it is free && and the itmp assigned to
539 this does not have any overlapping live ranges
540 with the one currently being assigned and
541 the size can be accomodated */
543 noOverLap (sym->usl.itmpStack, fsym) &&
544 getSize (sym->type) >= getSize (fsym->type))
553 /*-----------------------------------------------------------------*/
554 /* createStackSpil - create a location on the stack to spil */
555 /*-----------------------------------------------------------------*/
557 createStackSpil (symbol * sym)
560 int useXstack, model;
564 D(fprintf (stderr, " createStackSpil: %s\n", sym->name));
566 /* first go try and find a free one that is already
567 existing on the stack */
568 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
570 /* found a free one : just update & return */
571 sym->usl.spillLoc = sloc;
574 addSetHead (&sloc->usl.itmpStack, sym);
578 /* could not then have to create one , this is the hard part
579 we need to allocate this on the stack : this is really a
580 hack!! but cannot think of anything better at this time */
582 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
584 fprintf (stderr, "***Internal error: slocBuffer overflowed: %s:%d\n",
589 sloc = newiTemp (slocBuffer);
591 /* set the type to the spilling symbol */
592 sloc->type = copyLinkChain (sym->type);
593 sloc->etype = getSpec (sloc->type);
594 SPEC_SCLS (sloc->etype) = S_STACK;
595 SPEC_EXTR (sloc->etype) = 0;
596 SPEC_STAT (sloc->etype) = 0;
597 SPEC_VOLATILE(sloc->etype) = 0;
598 SPEC_ABSA(sloc->etype) = 0;
600 /* we don't allow it to be allocated`
601 onto the external stack since : so we
602 temporarily turn it off ; we also
603 turn off memory model to prevent
604 the spil from going to the external storage
607 useXstack = options.useXstack;
608 model = options.model;
609 /* noOverlay = options.noOverlay; */
610 /* options.noOverlay = 1; */
611 options.model = options.useXstack = 0;
615 options.useXstack = useXstack;
616 options.model = model;
617 /* options.noOverlay = noOverlay; */
618 sloc->isref = 1; /* to prevent compiler warning */
620 /* if it is on the stack then update the stack */
621 if (IN_STACK (sloc->etype))
623 currFunc->stack += getSize (sloc->type);
624 _G.stackExtend += getSize (sloc->type);
627 _G.dataExtend += getSize (sloc->type);
629 /* add it to the _G.stackSpil set */
630 addSetHead (&_G.stackSpil, sloc);
631 sym->usl.spillLoc = sloc;
634 /* add it to the set of itempStack set
635 of the spill location */
636 addSetHead (&sloc->usl.itmpStack, sym);
640 /*-----------------------------------------------------------------*/
641 /* spillThis - spils a specific operand */
642 /*-----------------------------------------------------------------*/
644 spillThis (symbol * sym)
648 D(fprintf (stderr, " spillThis: %s\n", sym->name));
650 /* if this is rematerializable or has a spillLocation
651 we are okay, else we need to create a spillLocation
653 if (!(sym->remat || sym->usl.spillLoc))
654 createStackSpil (sym);
657 /* mark it has spilt & put it in the spilt set */
658 sym->isspilt = sym->spillA = 1;
659 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
661 bitVectUnSetBit (_G.regAssigned, sym->key);
662 bitVectUnSetBit (_G.totRegAssigned, sym->key);
664 for (i = 0; i < sym->nRegs; i++)
668 freeReg (sym->regs[i], FALSE);
671 if (sym->usl.spillLoc && !sym->remat)
672 sym->usl.spillLoc->allocreq++;
676 /*-----------------------------------------------------------------*/
677 /* selectSpil - select a iTemp to spil : rather a simple procedure */
678 /*-----------------------------------------------------------------*/
680 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
682 bitVect *lrcs = NULL;
686 /* get the spillable live ranges */
687 lrcs = computeSpillable (ic);
689 /* get all live ranges that are rematerizable */
690 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
692 /* return the least used of these */
693 return leastUsedLR (selectS);
696 /* if the symbol is local to the block then */
697 if (forSym->liveTo < ebp->lSeq)
700 /* check if there are any live ranges allocated
701 to registers that are not used in this block */
702 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
704 sym = leastUsedLR (selectS);
705 /* if this is not rematerializable */
714 /* check if there are any live ranges that not
715 used in the remainder of the block */
716 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
718 sym = leastUsedLR (selectS);
731 /* find live ranges with spillocation && not used as pointers */
732 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
735 sym = leastUsedLR (selectS);
736 /* mark this as allocation required */
737 sym->usl.spillLoc->allocreq++;
741 /* find live ranges with spillocation */
742 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
745 sym = leastUsedLR (selectS);
746 sym->usl.spillLoc->allocreq++;
750 /* couldn't find then we need to create a spil
751 location on the stack , for which one? the least
753 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
756 /* return a created spil location */
757 sym = createStackSpil (leastUsedLR (selectS));
758 sym->usl.spillLoc->allocreq++;
762 /* this is an extreme situation we will spill
763 this one : happens very rarely but it does happen */
768 /*-----------------------------------------------------------------*/
769 /* spillSomething - spil some variable & mark registers as free */
770 /*-----------------------------------------------------------------*/
772 spillSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
777 /* get something we can spil */
778 ssym = selectSpil (ic, ebp, forSym);
780 D(fprintf (stderr, " spillSomething: spilling %s\n", ssym->name));
782 /* mark it as spilt */
783 ssym->isspilt = ssym->spillA = 1;
784 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
786 /* mark it as not register assigned &
787 take it away from the set */
788 bitVectUnSetBit (_G.regAssigned, ssym->key);
789 bitVectUnSetBit (_G.totRegAssigned, ssym->key);
791 /* mark the registers as free */
792 for (i = 0; i < ssym->nRegs; i++) {
794 freeReg (ssym->regs[i], FALSE);
795 // dont NULL ssym->regs[i], it might be used later
799 /* if this was a block level spil then insert push & pop
800 at the start & end of block respectively */
803 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
804 /* add push to the start of the block */
805 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
806 ebp->sch->next : ebp->sch));
807 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
808 /* add pop to the end of the block */
809 addiCodeToeBBlock (ebp, nic, NULL);
812 /* if spilt because not used in the remainder of the
813 block then add a push before this instruction and
814 a pop at the end of the block */
815 if (ssym->remainSpil)
818 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
819 /* add push just before this instruction */
820 addiCodeToeBBlock (ebp, nic, ic);
822 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
823 /* add pop to the end of the block */
824 addiCodeToeBBlock (ebp, nic, NULL);
833 /*-----------------------------------------------------------------*/
834 /* getRegPtr - will try for PTR if not a GPR type if not spil */
835 /*-----------------------------------------------------------------*/
836 static bool getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym, short offset) {
838 D(fprintf (stderr, "getRegPtr: %s ", sym->name));
839 D(printTypeChain(sym->type, stderr));
840 D(fprintf (stderr, "\n"));
843 /* try for a ptr type */
844 if (allocReg (getSize(sym->type), REG_PTR, sym, offset, FALSE))
847 /* try for gpr type */
848 if (xa51HasGprRegs && allocReg (getSize(sym->type),
849 REG_GPR, sym, offset, FALSE))
852 /* we have to spil */
853 if (!spillSomething (ic, ebp, sym))
856 /* this looks like an infinite loop but
857 in really selectSpil will abort */
861 /*-----------------------------------------------------------------*/
862 /* getRegGpr - will try for GPR if not spil */
863 /*-----------------------------------------------------------------*/
864 static bool getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym, short offset) {
866 D(fprintf (stderr, "getRegGpr: %s ", sym->name));
867 D(printTypeChain(sym->type, stderr));
868 D(fprintf (stderr, "\n"));
871 /* try for gpr type */
872 if (xa51HasGprRegs && allocReg (getSize(sym->type),
873 REG_GPR, sym, offset, FALSE))
876 if (allocReg (getSize(sym->type), REG_PTR, sym, offset, FALSE))
879 /* we have to spil */
880 if (!spillSomething (ic, ebp, sym))
883 /* this looks like an infinite loop but
884 in really selectSpil will abort */
888 /*-----------------------------------------------------------------*/
889 /* deassignLRs - check the live to and if they have registers & are */
890 /* not spilt then free up the registers */
891 /*-----------------------------------------------------------------*/
893 deassignLRs (iCode * ic, eBBlock * ebp)
898 for (sym = hTabFirstItem (liveRanges, &k); sym;
899 sym = hTabNextItem (liveRanges, &k))
901 /* if it does not end here */
902 if (sym->liveTo > ic->seq)
905 /* if it was spilt on stack then we can
906 mark the stack spil location as free */
911 sym->usl.spillLoc->isFree = 1;
917 if (!bitVectBitValue (_G.regAssigned, sym->key))
923 bitVectUnSetBit (_G.regAssigned, sym->key);
926 for (i=0; i < sym->nRegs; i++) {
927 freeReg (sym->regs[i], FALSE);
933 /*-----------------------------------------------------------------*/
934 /* willCauseSpill - determines if allocating will cause a spill */
935 /*-----------------------------------------------------------------*/
936 static bool willCauseSpill (symbol *sym) {
938 // do it the rude way
939 if (allocReg (getSize(sym->type), sym->regType, sym, 0, TRUE) ||
940 allocReg (getSize(sym->type), sym->regType==REG_PTR?REG_GPR:REG_PTR,
942 // so we can, but we won't
943 for (i=0; i<sym->nRegs; i++) {
944 freeReg (sym->regs[i], TRUE);
949 D(fprintf (stderr, " %s will cause a spill\n", sym->name));
953 /*-----------------------------------------------------------------*/
954 /* positionRegs - the allocator can allocate same registers to res- */
955 /* ult and operand, if this happens make sure they are in the same */
956 /* position as the operand otherwise chaos results */
957 /*-----------------------------------------------------------------*/
959 positionRegs (symbol * result, symbol * opsym)
961 int count = min (result->nRegs, opsym->nRegs);
962 int i, j = 0, shared = 0;
965 /* if the result has been spilt then cannot share */
970 /* first make sure that they actually share */
971 for (i = 0; i < count; i++)
973 for (j = 0; j < count; j++)
975 if (result->regs[i] == opsym->regs[j] && i != j)
985 regs *tmp = result->regs[i];
986 result->regs[i] = result->regs[j];
987 result->regs[j] = tmp;
994 /*-----------------------------------------------------------------*/
995 /* serialRegAssign - serially allocate registers to the variables */
996 /*-----------------------------------------------------------------*/
998 serialRegAssign (eBBlock ** ebbs, int count)
1002 /* for all blocks */
1003 for (i = 0; i < count; i++) {
1007 if (ebbs[i]->noPath &&
1008 (ebbs[i]->entryLabel != entryLabel &&
1009 ebbs[i]->entryLabel != returnLabel))
1012 /* of all instructions do */
1013 for (ic = ebbs[i]->sch; ic; ic = ic->next) {
1015 /* if result is present && is a true symbol */
1016 if (IC_RESULT (ic) && ic->op != IFX &&
1017 IS_TRUE_SYMOP (IC_RESULT (ic)))
1018 OP_SYMBOL (IC_RESULT (ic))->allocreq++;
1020 /* take away registers from live
1021 ranges that end at this instruction */
1022 deassignLRs (ic, ebbs[i]);
1024 /* some don't need registers */
1025 if (SKIP_IC2 (ic) ||
1026 ic->op == JUMPTABLE ||
1030 (IC_RESULT (ic) && POINTER_SET (ic)))
1034 /* xa51 has advance compare instructions */
1035 if (ic->op == '<' || ic->op == '>' ||
1036 ic->op == LE_OP || ic->op == GE_OP ||
1037 ic->op == NE_OP || ic->op == EQ_OP) {
1038 /* if this result is only used for an ifx, we don't
1039 need registers nor the ifx */
1040 int used=bitVectnBitsOn(OP_SYMBOL(IC_RESULT(ic))->uses);
1043 fprintf (stderr, "unexpected \"used\" for cmp:%d\n", ic->op);
1047 for (nic=ic->next; nic; nic=nic->next) {
1048 if (nic->op == IFX) {
1053 // we are in big trouble
1054 fprintf (stderr, "No ifx found for %d\n",
1059 nic->prev->next=nic->next;
1061 nic->next->prev=nic->prev;
1066 /* now we need to allocate registers
1067 only for the result */
1068 if (IC_RESULT (ic)) {
1069 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
1073 /* if it does not need or is spilt
1074 or is already assigned to registers
1075 or will not live beyond this instructions */
1078 bitVectBitValue (_G.regAssigned, sym->key) ||
1079 sym->liveTo <= ic->seq)
1082 /* if some liverange has been spilt at the block level
1083 and this one live beyond this block then spil this
1085 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq) {
1089 /* if trying to allocate this will cause
1090 a spill and there is nothing to spill
1091 or this one is rematerializable then
1093 willCS = willCauseSpill (sym);
1094 spillable = computeSpillable (ic);
1095 if (sym->remat || (willCS && bitVectIsZero (spillable))) {
1100 /* if it has a spillocation & is used less than
1101 all other live ranges then spill this */
1103 if (sym->usl.spillLoc) {
1104 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
1105 allLRs, ebbs[i], ic));
1106 if (leastUsed && leastUsed->used > sym->used) {
1111 /* if none of the liveRanges have a spillLocation then better
1112 to spill this one than anything else already assigned to registers */
1113 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
1114 /* if this is local to this block then we might find a block spil */
1115 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
1123 /* else we assign registers to it */
1124 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1125 _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key);
1127 if (sym->regType == REG_PTR)
1128 getRegPtr (ic, ebbs[i], sym, 0);
1130 getRegGpr (ic, ebbs[i], sym, 0);
1132 /* if it shares registers with operands make sure
1133 that they are in the same position */
1134 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
1135 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=') {
1136 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1137 OP_SYMBOL (IC_LEFT (ic)));
1139 /* do the same for the right operand */
1140 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
1141 OP_SYMBOL (IC_RIGHT (ic))->nRegs) {
1142 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1143 OP_SYMBOL (IC_RIGHT (ic)));
1150 /*-----------------------------------------------------------------*/
1151 /* rUmaskForOp :- returns register mask for an operand */
1152 /*-----------------------------------------------------------------*/
1153 bitVect *xa51_rUmaskForOp (operand * op) {
1158 /* only temporaries are assigned registers */
1162 sym = OP_SYMBOL (op);
1164 /* if spilt or no registers assigned to it
1166 if (sym->isspilt || !sym->nRegs || !sym->regs[0])
1169 rumask = newBitVect (xa51_nRegs);
1171 for (j = 0; j < sym->nRegs; j++) {
1172 rumask = bitVectSetBit (rumask,
1173 sym->regs[j]->rIdx);
1178 /*-----------------------------------------------------------------*/
1179 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
1180 /*-----------------------------------------------------------------*/
1182 regsUsedIniCode (iCode * ic)
1184 bitVect *rmask = newBitVect (xa51_nRegs);
1186 /* do the special cases first */
1189 rmask = bitVectUnion (rmask,
1190 xa51_rUmaskForOp (IC_COND (ic)));
1194 /* for the jumptable */
1195 if (ic->op == JUMPTABLE)
1197 rmask = bitVectUnion (rmask,
1198 xa51_rUmaskForOp (IC_JTCOND (ic)));
1203 /* of all other cases */
1205 rmask = bitVectUnion (rmask,
1206 xa51_rUmaskForOp (IC_LEFT (ic)));
1210 rmask = bitVectUnion (rmask,
1211 xa51_rUmaskForOp (IC_RIGHT (ic)));
1214 rmask = bitVectUnion (rmask,
1215 xa51_rUmaskForOp (IC_RESULT (ic)));
1221 /*-----------------------------------------------------------------*/
1222 /* createRegMask - for each instruction will determine the regsUsed */
1223 /*-----------------------------------------------------------------*/
1225 createRegMask (eBBlock ** ebbs, int count)
1229 /* for all blocks */
1230 for (i = 0; i < count; i++)
1234 if (ebbs[i]->noPath &&
1235 (ebbs[i]->entryLabel != entryLabel &&
1236 ebbs[i]->entryLabel != returnLabel))
1239 /* for all instructions */
1240 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1245 if (SKIP_IC2 (ic) || !ic->rlive)
1248 /* first mark the registers used in this
1250 ic->rUsed = regsUsedIniCode (ic);
1251 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
1253 /* now create the register mask for those
1254 registers that are in use : this is a
1255 super set of ic->rUsed */
1256 ic->rMask = newBitVect (xa51_nRegs + 1);
1258 /* for all live Ranges alive at this point */
1259 for (j = 1; j < ic->rlive->size; j++)
1264 /* if not alive then continue */
1265 if (!bitVectBitValue (ic->rlive, j))
1268 /* find the live range we are interested in */
1269 if (!(sym = hTabItemWithKey (liveRanges, j)))
1271 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1272 "createRegMask cannot find live range");
1276 /* if no register assigned to it */
1277 if (!sym->nRegs || sym->isspilt)
1280 /* for all the registers allocated to it */
1281 for (k = 0; k < sym->nRegs; k++)
1284 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
1290 /*-----------------------------------------------------------------*/
1291 /* rematStr - returns the rematerialized string for a remat var */
1292 /*-----------------------------------------------------------------*/
1294 rematStr (symbol * sym)
1297 iCode *ic = sym->rematiCode;
1302 /* if plus or minus print the right hand side */
1303 if (ic->op == '+' || ic->op == '-')
1305 sprintf (s, "0x%04x %c ", (int) operandLitValue (IC_RIGHT (ic)),
1308 ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1312 /* cast then continue */
1313 if (IS_CAST_ICODE(ic)) {
1314 ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
1317 /* we reached the end */
1318 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
1325 /*-----------------------------------------------------------------*/
1326 /* regTypeNum - computes the type & number of registers required */
1327 /*-----------------------------------------------------------------*/
1329 regTypeNum (eBBlock *ebbs)
1335 /* for each live range do */
1336 for (sym = hTabFirstItem (liveRanges, &k); sym;
1337 sym = hTabNextItem (liveRanges, &k))
1340 /* if used zero times then no registers needed */
1341 if ((sym->liveTo - sym->liveFrom) == 0)
1345 /* if the live range is a temporary */
1349 /* if the type is marked as a conditional */
1350 if (sym->regType == REG_CND)
1353 /* if used in return only then we don't
1356 if (sym->ruonly || sym->accuse)
1358 if (IS_AGGREGATE (sym->type) || sym->isptr)
1359 sym->type = aggrToPtr (sym->type, FALSE);
1364 /* if the symbol has only one definition &
1365 that definition is a get_pointer and the
1366 pointer we are getting is rematerializable and
1369 if (bitVectnBitsOn (sym->defs) == 1 &&
1370 (ic = hTabItemWithKey (iCodehTab,
1371 bitVectFirstBit (sym->defs))) &&
1374 !IS_BITVAR (sym->etype))
1378 /* if remat in data space */
1379 if (OP_SYMBOL (IC_LEFT (ic))->remat &&
1380 !IS_CAST_ICODE(OP_SYMBOL (IC_LEFT (ic))->rematiCode) &&
1381 DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER)
1383 /* create a psuedo symbol & force a spil */
1384 symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
1385 psym->type = sym->type;
1386 psym->etype = sym->etype;
1387 strcpy (psym->rname, psym->name);
1389 sym->usl.spillLoc = psym;
1390 #if 0 // an alternative fix for bug #480076
1391 /* now this is a useless assignment to itself */
1392 remiCodeFromeBBlock (ebbs, ic);
1394 /* now this really is an assignment to itself, make it so;
1395 it will be optimized out later */
1397 IC_RIGHT(ic)=IC_RESULT(ic);
1403 /* if in data space or idata space then try to
1404 allocate pointer register */
1408 /* if not then we require registers */
1410 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
1411 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1412 getSize (sym->type));
1415 int size=((IS_AGGREGATE (sym->type) || sym->isptr) ?
1416 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1417 getSize (sym->type));
1421 case 2: // word or pointer
1424 case 3: // generic pointer
1427 case 4: // dword or float
1431 fprintf (stderr, "regTypeNum: unknown size\n");
1439 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
1440 printTypeChain (sym->type, stderr);
1441 fprintf (stderr, "\n");
1445 /* determine the type of register required */
1446 if (IS_PTR (sym->type))
1447 sym->regType = REG_PTR;
1449 sym->regType = REG_GPR;
1453 /* for the first run we don't provide */
1454 /* registers for true symbols we will */
1455 /* see how things go */
1461 /*-----------------------------------------------------------------*/
1462 /* deallocStackSpil - this will set the stack pointer back */
1463 /*-----------------------------------------------------------------*/
1465 DEFSETFUNC (deallocStackSpil)
1473 /*-----------------------------------------------------------------*/
1474 /* packRegsForAssign - register reduction for assignment */
1475 /*-----------------------------------------------------------------*/
1477 packRegsForAssign (iCode * ic, eBBlock * ebp)
1481 if (!IS_ITEMP (IC_RIGHT (ic)) ||
1482 OP_LIVETO (IC_RIGHT (ic)) > ic->seq) {
1486 /* find the definition of iTempNN scanning backwards */
1487 for (dic = ic->prev; dic; dic = dic->prev) {
1489 /* if there is a function call then don't pack it */
1490 if ((dic->op == CALL || dic->op == PCALL)) {
1498 if (IS_SYMOP (IC_RESULT (dic)) &&
1499 IC_RESULT (dic)->key == IC_RIGHT (ic)->key) {
1506 return 0; /* did not find */
1508 /* found the definition */
1509 /* replace the result with the result of */
1510 /* this assignment and remove this assignment */
1511 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1512 IC_RESULT (dic) = IC_RESULT (ic);
1514 if (IS_ITEMP (IC_RESULT (dic)) &&
1515 OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
1517 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
1519 /* delete from liverange table also
1520 delete from all the points inbetween and the new
1522 for (sic = dic; sic != ic; sic = sic->next)
1524 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
1525 if (IS_ITEMP (IC_RESULT (dic)))
1526 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
1529 remiCodeFromeBBlock (ebp, ic);
1530 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
1531 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
1532 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
1537 /*-----------------------------------------------------------------*/
1538 /* findAssignToSym : scanning backwards looks for first assig found */
1539 /*-----------------------------------------------------------------*/
1541 findAssignToSym (operand * op, iCode * ic)
1545 for (dic = ic->prev; dic; dic = dic->prev)
1548 /* if definition by assignment */
1549 if (dic->op == '=' &&
1550 !POINTER_SET (dic) &&
1551 IC_RESULT (dic)->key == op->key
1552 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
1556 /* we are interested only if defined in far space */
1557 /* or in stack space in case of + & - */
1559 /* if assigned to a non-symbol then return
1561 if (!IS_SYMOP (IC_RIGHT (dic)))
1564 /* if the symbol is in far space then
1566 if (isOperandInFarSpace (IC_RIGHT (dic)))
1569 /* for + & - operations make sure that
1570 if it is on the stack it is the same
1571 as one of the three operands */
1572 if ((ic->op == '+' || ic->op == '-') &&
1573 OP_SYMBOL (IC_RIGHT (dic))->onStack)
1576 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
1577 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
1578 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
1586 /* if we find an usage then we cannot delete it */
1587 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
1590 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
1593 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
1597 /* now make sure that the right side of dic
1598 is not defined between ic & dic */
1601 iCode *sic = dic->next;
1603 for (; sic != ic; sic = sic->next)
1604 if (IC_RESULT (sic) &&
1605 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
1614 /*-----------------------------------------------------------------*/
1615 /* packRegsForSupport :- reduce some registers for support calls */
1616 /*-----------------------------------------------------------------*/
1618 packRegsForSupport (iCode * ic, eBBlock * ebp)
1623 /* for the left & right operand :- look to see if the
1624 left was assigned a true symbol in far space in that
1625 case replace them */
1627 if (IS_ITEMP (IC_LEFT (ic)) &&
1628 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
1630 dic = findAssignToSym (IC_LEFT (ic), ic);
1635 /* found it we need to remove it from the
1637 for (sic = dic; sic != ic; sic = sic->next)
1638 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
1640 OP_SYMBOL(IC_LEFT (ic))=OP_SYMBOL(IC_RIGHT (dic));
1641 IC_LEFT (ic)->key = OP_SYMBOL(IC_RIGHT (dic))->key;
1642 remiCodeFromeBBlock (ebp, dic);
1643 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1644 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1648 /* do the same for the right operand */
1651 IS_ITEMP (IC_RIGHT (ic)) &&
1652 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
1654 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
1660 /* if this is a subtraction & the result
1661 is a true symbol in far space then don't pack */
1662 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
1664 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
1665 if (IN_FARSPACE (SPEC_OCLS (etype)))
1668 /* found it we need to remove it from the
1670 for (sic = dic; sic != ic; sic = sic->next)
1671 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
1673 IC_RIGHT (ic)->operand.symOperand =
1674 IC_RIGHT (dic)->operand.symOperand;
1675 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
1677 remiCodeFromeBBlock (ebp, dic);
1678 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1679 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1686 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
1689 /*-----------------------------------------------------------------*/
1690 /* packRegsForOneuse : - will reduce some registers for single Use */
1691 /*-----------------------------------------------------------------*/
1693 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
1698 /* if returning a literal then do nothing */
1702 if (ic->op != RETURN &&
1704 !POINTER_SET (ic) &&
1708 /* this routine will mark the a symbol as used in one
1709 instruction use only && if the defintion is local
1710 (ie. within the basic block) && has only one definition &&
1711 that definiion is either a return value from a
1712 function or does not contain any variables in
1714 uses = bitVectCopy (OP_USES (op));
1715 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
1716 if (!bitVectIsZero (uses)) /* has other uses */
1719 /* if it has only one defintion */
1720 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
1721 return NULL; /* has more than one definition */
1723 /* get that definition */
1725 hTabItemWithKey (iCodehTab,
1726 bitVectFirstBit (OP_DEFS (op)))))
1729 /* if that only usage is a cast */
1730 if (dic->op == CAST) {
1731 /* to a bigger type */
1732 if (getSize(OP_SYM_TYPE(IC_RESULT(dic))) >
1733 getSize(OP_SYM_TYPE(IC_RIGHT(dic)))) {
1734 /* than we can not, since we cannot predict the usage of b & acc */
1739 /* found the definition now check if it is local */
1740 if (dic->seq < ebp->fSeq ||
1741 dic->seq > ebp->lSeq)
1742 return NULL; /* non-local */
1744 /* now check if it is the return from
1746 if (dic->op == CALL || dic->op == PCALL)
1748 if (ic->op != SEND && ic->op != RETURN &&
1749 !POINTER_SET(ic) && !POINTER_GET(ic))
1751 OP_SYMBOL (op)->ruonly = 1;
1758 /* otherwise check that the definition does
1759 not contain any symbols in far space */
1760 if (isOperandInFarSpace (IC_LEFT (dic)) ||
1761 isOperandInFarSpace (IC_RIGHT (dic)) ||
1762 IS_OP_RUONLY (IC_LEFT (ic)) ||
1763 IS_OP_RUONLY (IC_RIGHT (ic)))
1768 /* if pointer set then make sure the pointer
1770 if (POINTER_SET (dic) &&
1771 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
1774 if (POINTER_GET (dic) &&
1775 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
1780 /* also make sure the intervenening instructions
1781 don't have any thing in far space */
1782 for (dic = dic->next; dic && dic != ic && sic != ic; dic = dic->next)
1785 /* if there is an intervening function call then no */
1786 if (dic->op == CALL || dic->op == PCALL)
1788 /* if pointer set then make sure the pointer
1790 if (POINTER_SET (dic) &&
1791 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
1794 if (POINTER_GET (dic) &&
1795 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
1798 /* if address of & the result is remat the okay */
1799 if (dic->op == ADDRESS_OF &&
1800 OP_SYMBOL (IC_RESULT (dic))->remat)
1803 /* if operand has size of three or more & this
1804 operation is a '*','/' or '%' then 'b' may
1806 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
1807 getSize (operandType (op)) >= 3)
1810 /* if left or right or result is in far space */
1811 if (isOperandInFarSpace (IC_LEFT (dic)) ||
1812 isOperandInFarSpace (IC_RIGHT (dic)) ||
1813 isOperandInFarSpace (IC_RESULT (dic)) ||
1814 IS_OP_RUONLY (IC_LEFT (dic)) ||
1815 IS_OP_RUONLY (IC_RIGHT (dic)) ||
1816 IS_OP_RUONLY (IC_RESULT (dic)))
1820 /* if left or right or result is on stack */
1821 if (isOperandOnStack(IC_LEFT(dic)) ||
1822 isOperandOnStack(IC_RIGHT(dic)) ||
1823 isOperandOnStack(IC_RESULT(dic))) {
1828 OP_SYMBOL (op)->ruonly = 1;
1833 /*-----------------------------------------------------------------*/
1834 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
1835 /*-----------------------------------------------------------------*/
1837 isBitwiseOptimizable (iCode * ic)
1839 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
1840 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
1842 /* bitwise operations are considered optimizable
1843 under the following conditions (Jean-Louis VERN)
1855 if (IS_LITERAL(rtype) ||
1856 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
1862 /*-----------------------------------------------------------------*/
1863 /* packForPush - hueristics to reduce iCode for pushing */
1864 /*-----------------------------------------------------------------*/
1866 packForPush (iCode * ic, eBBlock * ebp)
1871 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
1874 /* must have only definition & one usage */
1875 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
1876 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
1879 /* find the definition */
1880 if (!(dic = hTabItemWithKey (iCodehTab,
1881 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
1884 if (dic->op != '=' || POINTER_SET (dic))
1887 /* make sure the right side does not have any definitions
1889 dbv = OP_DEFS(IC_RIGHT(dic));
1890 for (lic = ic; lic && lic != dic ; lic = lic->prev) {
1891 if (bitVectBitValue(dbv,lic->key))
1894 /* make sure they have the same type */
1896 sym_link *itype=operandType(IC_LEFT(ic));
1897 sym_link *ditype=operandType(IC_RIGHT(dic));
1899 if (SPEC_USIGN(itype)!=SPEC_USIGN(ditype) ||
1900 SPEC_LONG(itype)!=SPEC_LONG(ditype))
1903 /* extend the live range of replaced operand if needed */
1904 if (OP_SYMBOL(IC_RIGHT(dic))->liveTo < ic->seq) {
1905 OP_SYMBOL(IC_RIGHT(dic))->liveTo = ic->seq;
1907 /* we now know that it has one & only one def & use
1908 and the that the definition is an assignment */
1909 IC_LEFT (ic) = IC_RIGHT (dic);
1911 remiCodeFromeBBlock (ebp, dic);
1912 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1913 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1916 /*-----------------------------------------------------------------*/
1917 /* packRegisters - does some transformations to reduce register */
1919 /*-----------------------------------------------------------------*/
1920 static void packRegisters (eBBlock * ebp) {
1927 for (ic = ebp->sch; ic; ic = ic->next) {
1929 change += packRegsForAssign (ic, ebp);
1935 return; // that's it for now
1937 for (ic = ebp->sch; ic; ic = ic->next)
1939 /* if this is an itemp & result of an address of a true sym
1940 then mark this as rematerialisable */
1941 if (ic->op == ADDRESS_OF &&
1942 IS_ITEMP (IC_RESULT (ic)) &&
1943 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
1944 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
1945 !OP_SYMBOL (IC_LEFT (ic))->onStack)
1948 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
1949 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
1950 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
1954 /* if straight assignment then carry remat flag if
1955 this is the only definition */
1956 if (ic->op == '=' &&
1957 !POINTER_SET (ic) &&
1958 IS_SYMOP (IC_RIGHT (ic)) &&
1959 OP_SYMBOL (IC_RIGHT (ic))->remat &&
1960 !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode) &&
1961 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
1964 OP_SYMBOL (IC_RESULT (ic))->remat =
1965 OP_SYMBOL (IC_RIGHT (ic))->remat;
1966 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
1967 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
1970 /* if cast to a generic pointer & the pointer being
1971 cast is remat, then we can remat this cast as well */
1972 if (ic->op == CAST &&
1973 IS_SYMOP(IC_RIGHT(ic)) &&
1974 OP_SYMBOL(IC_RIGHT(ic))->remat ) {
1975 sym_link *to_type = operandType(IC_LEFT(ic));
1976 sym_link *from_type = operandType(IC_RIGHT(ic));
1977 if (IS_GENPTR(to_type) && IS_PTR(from_type)) {
1978 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
1979 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
1980 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
1984 /* if this is a +/- operation with a rematerizable
1985 then mark this as rematerializable as well */
1986 if ((ic->op == '+' || ic->op == '-') &&
1987 (IS_SYMOP (IC_LEFT (ic)) &&
1988 IS_ITEMP (IC_RESULT (ic)) &&
1989 IS_OP_LITERAL (IC_RIGHT (ic))) &&
1990 OP_SYMBOL (IC_LEFT (ic))->remat &&
1991 (!IS_SYMOP (IC_RIGHT (ic)) || !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode)) &&
1992 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1)
1994 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
1995 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
1996 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
1999 /* mark the pointer usages */
2000 if (POINTER_SET (ic))
2001 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
2003 if (POINTER_GET (ic))
2004 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
2006 /* if the condition of an if instruction
2007 is defined in the previous instruction and
2008 this is the only usage then
2009 mark the itemp as a conditional */
2010 if ((IS_CONDITIONAL (ic) ||
2011 (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic))) &&
2012 ic->next && ic->next->op == IFX &&
2013 bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
2014 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
2015 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2017 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
2021 /* reduce for support function calls */
2022 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
2023 packRegsForSupport (ic, ebp);
2025 /* some cases the redundant moves can
2026 can be eliminated for return statements */
2027 if ((ic->op == RETURN || ic->op == SEND) &&
2028 !isOperandInFarSpace (IC_LEFT (ic)) &&
2029 options.model == MODEL_SMALL) {
2030 if (0 && options.stackAuto) {
2031 /* we should check here if acc will be clobbered for stack
2032 offset calculations */
2034 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2038 /* if pointer set & left has a size more than
2039 one and right is not in far space */
2040 if (POINTER_SET (ic) &&
2041 !isOperandInFarSpace (IC_RIGHT (ic)) &&
2042 !OP_SYMBOL (IC_RESULT (ic))->remat &&
2043 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
2044 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
2046 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
2048 /* if pointer get */
2049 if (POINTER_GET (ic) &&
2050 !isOperandInFarSpace (IC_RESULT (ic)) &&
2051 !OP_SYMBOL (IC_LEFT (ic))->remat &&
2052 !IS_OP_RUONLY (IC_RESULT (ic)) &&
2053 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
2055 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2058 /* if this is cast for intergral promotion then
2059 check if only use of the definition of the
2060 operand being casted/ if yes then replace
2061 the result of that arithmetic operation with
2062 this result and get rid of the cast */
2065 sym_link *fromType = operandType (IC_RIGHT (ic));
2066 sym_link *toType = operandType (IC_LEFT (ic));
2068 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
2069 getSize (fromType) != getSize (toType) &&
2070 SPEC_USIGN (fromType) == SPEC_USIGN (toType))
2073 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2076 if (IS_ARITHMETIC_OP (dic))
2078 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2079 IC_RESULT (dic) = IC_RESULT (ic);
2080 remiCodeFromeBBlock (ebp, ic);
2081 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2082 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2083 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2087 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
2093 /* if the type from and type to are the same
2094 then if this is the only use then packit */
2095 if (compareType (operandType (IC_RIGHT (ic)),
2096 operandType (IC_LEFT (ic))) == 1)
2098 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2101 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2102 IC_RESULT (dic) = IC_RESULT (ic);
2103 remiCodeFromeBBlock (ebp, ic);
2104 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2105 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2106 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2114 iTempNN := (some variable in farspace) V1
2119 if (ic->op == IPUSH)
2121 packForPush (ic, ebp);
2126 /*-----------------------------------------------------------------*/
2127 /* assignRegisters - assigns registers to each live range as need */
2128 /*-----------------------------------------------------------------*/
2130 xa51_assignRegisters (eBBlock ** ebbs, int count)
2135 setToNull ((void *) &_G.funcrUsed);
2136 setToNull ((void *) &_G.totRegAssigned);
2137 _G.stackExtend = _G.dataExtend = 0;
2139 /* change assignments this will remove some
2140 live ranges reducing some register pressure */
2141 for (i = 0; i < count; i++)
2142 packRegisters (ebbs[i]);
2144 if (options.dump_pack)
2145 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
2147 /* first determine for each live range the number of
2148 registers & the type of registers required for each */
2151 /* and serially allocate registers */
2152 serialRegAssign (ebbs, count);
2156 /* if stack was extended then tell the user */
2159 /* werror(W_TOOMANY_SPILS,"stack", */
2160 /* _G.stackExtend,currFunc->name,""); */
2166 /* werror(W_TOOMANY_SPILS,"data space", */
2167 /* _G.dataExtend,currFunc->name,""); */
2171 /* after that create the register mask
2172 for each of the instruction */
2173 createRegMask (ebbs, count);
2175 /* redo that offsets for stacked automatic variables */
2176 redoStackOffsets ();
2178 if (options.dump_rassgn)
2180 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
2181 dumpLiveRanges (DUMP_LRANGE, liveRanges);
2184 /* do the overlaysegment stuff SDCCmem.c */
2185 doOverlays (ebbs, count);
2187 /* now get back the chain */
2188 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
2192 /* free up any _G.stackSpil locations allocated */
2193 applyToSet (_G.stackSpil, deallocStackSpil);
2195 setToNull ((void **) &_G.stackSpil);
2196 setToNull ((void **) &_G.spiltSet);
2197 /* mark all registers as free */