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 *);
48 bitVect *totRegAssigned; /* final set of LRs that got into registers */
51 bitVect *funcrUsed; /* registers used in a function */
59 // index size type name regMask offset isFree symbol
60 {0x20, 2, REG_SCR, "r0", 0x0003, 0, 1, NULL}, // r0 used for scratch
61 {0x21, 2, REG_SCR, "r1", 0x000c, 2, 1, NULL}, // r1 used for scratch
62 {0x22, 2, REG_PTR, "r2", 0x0030, 4, 1, NULL},
63 {0x23, 2, REG_PTR, "r3", 0x00c0, 6, 1, NULL},
64 {0x24, 2, REG_PTR, "r4", 0x0300, 8, 1, NULL},
65 {0x25, 2, REG_PTR, "r5", 0x0c00, 10, 1, NULL},
66 {0x26, 2, REG_PTR, "r6", 0x3000, 12, 1, NULL},
67 {0x27, 2, REG_STK, "r7", 0xc000, 14, 1, NULL}, // r7=SP
68 #if 0 // some derivates have even more! (only word access and gpr use)
69 {0x28, 2, REG_GPR, "r8", 0x10000, 16, 1, NULL},
70 {0x29, 2, REG_GPR, "r9", 0x20000, 18, 1, NULL},
71 {0x2a, 2, REG_GPR, "r10", 0x40000, 20, 1, NULL},
72 {0x2b, 2, REG_GPR, "r11", 0x80000, 22, 1, NULL},
73 {0x2c, 2, REG_GPR, "r12", 0x100000, 24, 1, NULL},
74 {0x2d, 2, REG_GPR, "r13", 0x200000, 26, 1, NULL},
75 {0x2e, 2, REG_GPR, "r14", 0x400000, 28, 1, NULL},
76 {0x2f, 2, REG_GPR, "r15", 0x800000, 20, 1, NULL},
78 {0x10, 1, REG_SCR, "r0h", 0x0001, 1, 1, NULL}, // r0h used for scratch
79 {0x11, 1, REG_SCR, "r0l", 0x0002, 1, 1, NULL}, // r0l used for scratch
80 {0x12, 1, REG_SCR, "r1h", 0x0004, 2, 1, NULL}, // r1h used for scratch
81 {0x13, 1, REG_SCR, "r1l", 0x0008, 3, 1, NULL}, // r1l used for scratch
82 {0x14, 1, REG_PTR, "r2h", 0x0010, 4, 1, NULL},
83 {0x15, 1, REG_PTR, "r2l", 0x0020, 5, 1, NULL},
84 {0x16, 1, REG_PTR, "r3h", 0x0040, 6, 1, NULL},
85 {0x17, 1, REG_PTR, "r3l", 0x0080, 7, 1, NULL},
86 {0x18, 1, REG_PTR, "r4h", 0x0100, 8, 1, NULL},
87 {0x19, 1, REG_PTR, "r4l", 0x0200, 9, 1, NULL},
88 {0x1a, 1, REG_PTR, "r5h", 0x0400, 10, 1, NULL},
89 {0x1b, 1, REG_PTR, "r5l", 0x0800, 11, 1, NULL},
90 {0x1c, 1, REG_PTR, "r6h", 0x1000, 12, 1, NULL},
91 {0x1d, 1, REG_PTR, "r6l", 0x2000, 13, 1, NULL},
92 {0x1e, 1, REG_STK, "r7h", 0x4000, 14, 1, NULL}, // r7=SP
93 {0x1f, 1, REG_STK, "r7l", 0x8000, 15, 1, NULL}, // r7=SP
96 int xa51_nRegs=sizeof(regsXA51)/sizeof(regs);
98 udword xa51RegsInUse=0;
100 // this should be set with a command line switch
101 bool xa51HasGprRegs=0;
103 /*-----------------------------------------------------------------*/
104 /* xa51_regWithMask - returns pointer to register with mask */
105 /*-----------------------------------------------------------------*/
106 regs *xa51_regWithMask (udword mask) {
108 for (i=0; i<xa51_nRegs; i++) {
109 if (regsXA51[i].regMask==mask) {
116 /*-----------------------------------------------------------------*/
117 /* checkRegsMask - check the consistancy of the regMask redundancy */
118 /*-----------------------------------------------------------------*/
120 void checkRegMask(char *f) { // for debugging purposes only
124 for (i=0; i<xa51_nRegs; i++) {
125 if (!regsXA51[i].isFree) {
126 regMask |= regsXA51[i].regMask;
130 if (regMask != xa51RegsInUse) {
131 fprintf (stderr, "error(%s): regMask inconsistent 0x%08x != 0x%08x\n",
132 f, regMask, xa51RegsInUse);
133 regMask=regMask^xa51RegsInUse;
134 fprintf (stderr, "%s used by %s\n",
135 xa51_regWithMask(regMask)->name,
136 xa51_regWithMask(regMask)->sym->name);
143 char *regTypeToStr(short type) {
146 case REG_PTR: return "ptr"; break; // pointer
147 case REG_GPR: return "gpr"; break; // general purpose
148 case REG_CND: return "cnd"; break; // condition (bit)
149 case REG_STK: return "stk"; break; // stack
150 case REG_SCR: return "scr"; break; // scratch
151 default: return "???"; break;
155 /*-----------------------------------------------------------------*/
156 /* freeReg - frees a previous allocated register */
157 /*-----------------------------------------------------------------*/
158 static void freeReg (regs * reg, bool silent) {
160 checkRegMask(__FUNCTION__);
163 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
164 "freeReg - freeing NULL register");
169 fprintf (stderr, "freeReg: (%08x) %s ", xa51RegsInUse, reg->name);
172 if (reg->isFree || ((xa51RegsInUse®->regMask)!=reg->regMask)) {
173 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
174 "freeReg - freeing unused register(s)");
177 xa51RegsInUse &= ~reg->regMask;
180 if (!silent) fprintf (stderr, "(%08x)\n", xa51RegsInUse);
182 checkRegMask(__FUNCTION__);
185 /*-----------------------------------------------------------------*/
186 /* allocReg - allocates register of given size (byte, word) */
187 /* and type (ptr, gpr, cnd) */
188 /*-----------------------------------------------------------------*/
189 static bool allocReg (short size, short type, symbol *sym,
190 short offset, bool silent) {
193 checkRegMask(__FUNCTION__);
196 fprintf (stderr, "allocReg (0x%08x) for %s size:%d, type:%s ",
199 size, regTypeToStr(type));
204 // TODO: gaps should be filled for dwords too
206 // let's see if we can fill a gap
207 for (i=0; i<xa51_nRegs; i++) {
208 if (regsXA51[i].size==2 && regsXA51[i].type==type) {
209 udword mask=regsXA51[i].regMask & ~xa51RegsInUse;
210 if (mask && mask!=regsXA51[i].regMask) {
211 regs *reg=xa51_regWithMask(mask);
213 sym->regs[offset]=reg;
214 xa51RegsInUse |= mask;
215 reg->isFree=0; // redundant
218 fprintf (stderr, "(using gap) %s\n", reg->name);
220 checkRegMask(__FUNCTION__);
225 // no we can't, fall through
227 for (i=0; i<xa51_nRegs; i++) {
228 if (regsXA51[i].size==size &&
229 regsXA51[i].type==type &&
230 (regsXA51[i].regMask & xa51RegsInUse)==0) {
231 xa51RegsInUse |= regsXA51[i].regMask;
232 regsXA51[i].isFree = 0; // redundant
233 regsXA51[i].sym = sym;
235 fprintf (stderr, "%s\n", regsXA51[i].name);
237 sym->regs[offset]=®sXA51[i];
238 checkRegMask(__FUNCTION__);
243 fprintf (stderr, "failed (%08x)\n", xa51RegsInUse);
245 checkRegMask(__FUNCTION__);
249 // this must be a generic pointer
251 fprintf (stderr, "trying 2+1\n");
253 // get the pointer part
254 if (allocReg (2, REG_PTR, sym, offset, silent)) {
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 checkRegMask(__FUNCTION__);
261 freeReg(sym->regs[offset], silent);
262 sym->regs[offset]=NULL;
264 checkRegMask(__FUNCTION__);
267 case 4: // this is a dword
269 fprintf (stderr, "trying 2+2\n");
271 if ((xa51HasGprRegs && allocReg (2, REG_GPR, sym, offset, silent)) ||
272 allocReg (2, REG_PTR, sym, offset, silent)) {
273 if ((xa51HasGprRegs && allocReg (2, REG_GPR, sym, offset+1, silent)) ||
274 allocReg (2, REG_PTR, sym, offset+1, silent)) {
275 checkRegMask(__FUNCTION__);
279 freeReg(sym->regs[offset], FALSE);
280 sym->regs[offset]=NULL;
281 checkRegMask(__FUNCTION__);
285 fprintf (stderr, "\nallocReg: cannot allocate reg of size %d\n", size);
289 // we should never come here
293 /*-------------------------------------------------------------------*/
294 /* freeAllRegs - frees all registers */
295 /*-------------------------------------------------------------------*/
296 // just to be sure, this should not be needed
297 static void freeAllRegs (void) {
302 checkRegMask(__FUNCTION__);
305 for (i=0; i<xa51_nRegs; i++) {
306 if (!regsXA51[i].isFree) {
307 strcat (regsFreed, regsXA51[i].name);
308 strcat (regsFreed, " ");
309 regsXA51[i].isFree=1;
310 regsXA51[i].sym=NULL;
316 fprintf (stderr, "freeAllRegisters: %d regs freed (%s)\n", nfr, regsFreed);
321 /*-----------------------------------------------------------------*/
322 /* allDefsOutOfRange - all definitions are out of a range */
323 /*-----------------------------------------------------------------*/
324 static bool allDefsOutOfRange (bitVect * defs, int fseq, int toseq) {
330 for (i = 0; i < defs->size; i++)
334 if (bitVectBitValue (defs, i) &&
335 (ic = hTabItemWithKey (iCodehTab, i)) &&
336 (ic->seq >= fseq && ic->seq <= toseq))
342 /*-----------------------------------------------------------------*/
343 /* computeSpillable - given a point find the spillable live ranges */
344 /*-----------------------------------------------------------------*/
345 static bitVect *computeSpillable (iCode * ic) {
348 /* spillable live ranges are those that are live at this
349 point . the following categories need to be subtracted
351 a) - those that are already spilt
352 b) - if being used by this one
353 c) - defined by this one */
355 spillable = bitVectCopy (ic->rlive);
357 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
359 bitVectCplAnd (spillable, ic->uses); /* used in this one */
360 bitVectUnSetBit (spillable, ic->defKey); /* defined by this one */
361 spillable = bitVectIntersect (spillable, _G.regAssigned);
366 /*-----------------------------------------------------------------*/
367 /* noSpilLoc - return true if a variable has no spil location */
368 /*-----------------------------------------------------------------*/
370 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
372 return (sym->usl.spillLoc ? 0 : 1);
375 /*-----------------------------------------------------------------*/
376 /* hasSpilLoc - will return 1 if the symbol has spil location */
377 /*-----------------------------------------------------------------*/
379 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
381 return (sym->usl.spillLoc ? 1 : 0);
384 /*-----------------------------------------------------------------*/
385 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
386 /* but is not used as a pointer */
387 /*-----------------------------------------------------------------*/
389 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
391 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
394 /*-----------------------------------------------------------------*/
395 /* rematable - will return 1 if the remat flag is set */
396 /*-----------------------------------------------------------------*/
398 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
403 /*-----------------------------------------------------------------*/
404 /* notUsedInBlock - not used in this block */
405 /*-----------------------------------------------------------------*/
407 notUsedInBlock (symbol * sym, eBBlock * ebp, iCode * ic)
409 return (!bitVectBitsInCommon (sym->defs, ebp->usesDefs) &&
410 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
411 /* return (!bitVectBitsInCommon(sym->defs,ebp->usesDefs)); */
414 /*-----------------------------------------------------------------*/
415 /* notUsedInRemaining - not used or defined in remain of the block */
416 /*-----------------------------------------------------------------*/
418 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
420 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
421 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
424 /*-----------------------------------------------------------------*/
425 /* allLRs - return true for all */
426 /*-----------------------------------------------------------------*/
428 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
433 /*-----------------------------------------------------------------*/
434 /* liveRangesWith - applies function to a given set of live range */
435 /*-----------------------------------------------------------------*/
437 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
438 eBBlock * ebp, iCode * ic)
443 if (!lrs || !lrs->size)
446 for (i = 1; i < lrs->size; i++)
449 if (!bitVectBitValue (lrs, i))
452 /* if we don't find it in the live range
453 hash table we are in serious trouble */
454 if (!(sym = hTabItemWithKey (liveRanges, i)))
456 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
457 "liveRangesWith could not find liveRange");
461 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
462 addSetHead (&rset, sym);
469 /*-----------------------------------------------------------------*/
470 /* leastUsedLR - given a set determines which is the least used */
471 /*-----------------------------------------------------------------*/
473 leastUsedLR (set * sset)
475 symbol *sym = NULL, *lsym = NULL;
477 sym = lsym = setFirstItem (sset);
482 for (; lsym; lsym = setNextItem (sset))
485 /* if usage is the same then prefer
486 the spill the smaller of the two */
487 if (lsym->used == sym->used)
488 if (getSize (lsym->type) < getSize (sym->type))
492 if (lsym->used < sym->used)
497 setToNull ((void **) &sset);
502 /*-----------------------------------------------------------------*/
503 /* noOverLap - will iterate through the list looking for over lap */
504 /*-----------------------------------------------------------------*/
506 noOverLap (set * itmpStack, symbol * fsym)
511 for (sym = setFirstItem (itmpStack); sym;
512 sym = setNextItem (itmpStack))
514 if (bitVectBitValue(sym->clashes,fsym->key)) return 0;
520 /*-----------------------------------------------------------------*/
521 /* isFree - will return 1 if the a free spil location is found */
522 /*-----------------------------------------------------------------*/
527 V_ARG (symbol **, sloc);
528 V_ARG (symbol *, fsym);
530 /* if already found */
534 /* if it is free && and the itmp assigned to
535 this does not have any overlapping live ranges
536 with the one currently being assigned and
537 the size can be accomodated */
539 noOverLap (sym->usl.itmpStack, fsym) &&
540 getSize (sym->type) >= getSize (fsym->type))
549 /*-----------------------------------------------------------------*/
550 /* createStackSpil - create a location on the stack to spil */
551 /*-----------------------------------------------------------------*/
553 createStackSpil (symbol * sym)
556 int useXstack, model;
560 fprintf (stderr, " createStackSpil: %s\n", sym->name);
562 /* first go try and find a free one that is already
563 existing on the stack */
564 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
566 /* found a free one : just update & return */
567 sym->usl.spillLoc = sloc;
570 addSetHead (&sloc->usl.itmpStack, sym);
574 /* could not then have to create one , this is the hard part
575 we need to allocate this on the stack : this is really a
576 hack!! but cannot think of anything better at this time */
578 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
580 fprintf (stderr, "***Internal error: slocBuffer overflowed: %s:%d\n",
585 sloc = newiTemp (slocBuffer);
587 /* set the type to the spilling symbol */
588 sloc->type = copyLinkChain (sym->type);
589 sloc->etype = getSpec (sloc->type);
590 SPEC_SCLS (sloc->etype) = S_STACK;
591 SPEC_EXTR (sloc->etype) = 0;
592 SPEC_STAT (sloc->etype) = 0;
593 SPEC_VOLATILE(sloc->etype) = 0;
594 SPEC_ABSA(sloc->etype) = 0;
596 /* we don't allow it to be allocated`
597 onto the external stack since : so we
598 temporarily turn it off ; we also
599 turn off memory model to prevent
600 the spil from going to the external storage
603 useXstack = options.useXstack;
604 model = options.model;
605 /* noOverlay = options.noOverlay; */
606 /* options.noOverlay = 1; */
607 options.model = options.useXstack = 0;
611 options.useXstack = useXstack;
612 options.model = model;
613 /* options.noOverlay = noOverlay; */
614 sloc->isref = 1; /* to prevent compiler warning */
616 /* if it is on the stack then update the stack */
617 if (IN_STACK (sloc->etype))
619 currFunc->stack += getSize (sloc->type);
620 _G.stackExtend += getSize (sloc->type);
623 _G.dataExtend += getSize (sloc->type);
625 /* add it to the _G.stackSpil set */
626 addSetHead (&_G.stackSpil, sloc);
627 sym->usl.spillLoc = sloc;
630 /* add it to the set of itempStack set
631 of the spill location */
632 addSetHead (&sloc->usl.itmpStack, sym);
636 /*-----------------------------------------------------------------*/
637 /* spillThis - spils a specific operand */
638 /*-----------------------------------------------------------------*/
640 spillThis (symbol * sym)
644 fprintf (stderr, " spillThis: %s\n", sym->name);
646 /* if this is rematerializable or has a spillLocation
647 we are okay, else we need to create a spillLocation
649 if (!(sym->remat || sym->usl.spillLoc))
650 createStackSpil (sym);
653 /* mark it has spilt & put it in the spilt set */
654 sym->isspilt = sym->spillA = 1;
655 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
657 bitVectUnSetBit (_G.regAssigned, sym->key);
658 bitVectUnSetBit (_G.totRegAssigned, sym->key);
660 for (i = 0; i < sym->nRegs; i++)
664 freeReg (sym->regs[i], FALSE);
667 if (sym->usl.spillLoc && !sym->remat)
668 sym->usl.spillLoc->allocreq++;
672 /*-----------------------------------------------------------------*/
673 /* selectSpil - select a iTemp to spil : rather a simple procedure */
674 /*-----------------------------------------------------------------*/
676 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
678 bitVect *lrcs = NULL;
682 /* get the spillable live ranges */
683 lrcs = computeSpillable (ic);
685 /* get all live ranges that are rematerizable */
686 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
688 /* return the least used of these */
689 return leastUsedLR (selectS);
692 /* if the symbol is local to the block then */
693 if (forSym->liveTo < ebp->lSeq)
696 /* check if there are any live ranges allocated
697 to registers that are not used in this block */
698 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
700 sym = leastUsedLR (selectS);
701 /* if this is not rematerializable */
710 /* check if there are any live ranges that not
711 used in the remainder of the block */
712 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
714 sym = leastUsedLR (selectS);
727 /* find live ranges with spillocation && not used as pointers */
728 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
731 sym = leastUsedLR (selectS);
732 /* mark this as allocation required */
733 sym->usl.spillLoc->allocreq++;
737 /* find live ranges with spillocation */
738 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
741 sym = leastUsedLR (selectS);
742 sym->usl.spillLoc->allocreq++;
746 /* couldn't find then we need to create a spil
747 location on the stack , for which one? the least
749 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
752 /* return a created spil location */
753 sym = createStackSpil (leastUsedLR (selectS));
754 sym->usl.spillLoc->allocreq++;
758 /* this is an extreme situation we will spill
759 this one : happens very rarely but it does happen */
764 /*-----------------------------------------------------------------*/
765 /* spillSomething - spil some variable & mark registers as free */
766 /*-----------------------------------------------------------------*/
768 spillSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
773 /* get something we can spil */
774 ssym = selectSpil (ic, ebp, forSym);
776 fprintf (stderr, " spillSomething: spilling %s\n", ssym->name);
778 /* mark it as spilt */
779 ssym->isspilt = ssym->spillA = 1;
780 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
782 /* mark it as not register assigned &
783 take it away from the set */
784 bitVectUnSetBit (_G.regAssigned, ssym->key);
785 bitVectUnSetBit (_G.totRegAssigned, ssym->key);
787 /* mark the registers as free */
788 for (i = 0; i < ssym->nRegs; i++) {
790 freeReg (ssym->regs[i], FALSE);
791 // dont NULL ssym->regs[i], it might be used later
795 /* if this was a block level spil then insert push & pop
796 at the start & end of block respectively */
799 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
800 /* add push to the start of the block */
801 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
802 ebp->sch->next : ebp->sch));
803 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
804 /* add pop to the end of the block */
805 addiCodeToeBBlock (ebp, nic, NULL);
808 /* if spilt because not used in the remainder of the
809 block then add a push before this instruction and
810 a pop at the end of the block */
811 if (ssym->remainSpil)
814 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
815 /* add push just before this instruction */
816 addiCodeToeBBlock (ebp, nic, ic);
818 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
819 /* add pop to the end of the block */
820 addiCodeToeBBlock (ebp, nic, NULL);
829 /*-----------------------------------------------------------------*/
830 /* getRegPtr - will try for PTR if not a GPR type if not spil */
831 /*-----------------------------------------------------------------*/
832 static bool getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym, short offset) {
834 fprintf (stderr, "getRegPtr: %s ", sym->name);
835 printTypeChain(sym->type, stderr);
836 fprintf (stderr, "\n");
839 /* try for a ptr type */
840 if (allocReg (getSize(sym->type), REG_PTR, sym, offset, FALSE))
843 /* try for gpr type */
844 if (xa51HasGprRegs && allocReg (getSize(sym->type),
845 REG_GPR, sym, offset, FALSE))
848 /* we have to spil */
849 if (!spillSomething (ic, ebp, sym))
852 /* this looks like an infinite loop but
853 in really selectSpil will abort */
857 /*-----------------------------------------------------------------*/
858 /* getRegGpr - will try for GPR if not spil */
859 /*-----------------------------------------------------------------*/
860 static bool getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym, short offset) {
862 fprintf (stderr, "getRegGpr: %s ", sym->name);
863 printTypeChain(sym->type, stderr);
864 fprintf (stderr, "\n");
867 /* try for gpr type */
868 if (xa51HasGprRegs && allocReg (getSize(sym->type),
869 REG_GPR, sym, offset, FALSE))
872 if (allocReg (getSize(sym->type), REG_PTR, sym, offset, FALSE))
875 /* we have to spil */
876 if (!spillSomething (ic, ebp, sym))
879 /* this looks like an infinite loop but
880 in really selectSpil will abort */
884 /*-----------------------------------------------------------------*/
885 /* deassignLRs - check the live to and if they have registers & are */
886 /* not spilt then free up the registers */
887 /*-----------------------------------------------------------------*/
889 deassignLRs (iCode * ic, eBBlock * ebp)
894 for (sym = hTabFirstItem (liveRanges, &k); sym;
895 sym = hTabNextItem (liveRanges, &k))
897 /* if it does not end here */
898 if (sym->liveTo > ic->seq)
901 /* if it was spilt on stack then we can
902 mark the stack spil location as free */
907 sym->usl.spillLoc->isFree = 1;
913 if (!bitVectBitValue (_G.regAssigned, sym->key))
919 bitVectUnSetBit (_G.regAssigned, sym->key);
922 for (i=0; i < sym->nRegs; i++) {
923 freeReg (sym->regs[i], FALSE);
929 /*-----------------------------------------------------------------*/
930 /* willCauseSpill - determines if allocating will cause a spill */
931 /*-----------------------------------------------------------------*/
932 static bool willCauseSpill (symbol *sym) {
934 // do it the rude way
935 if (allocReg (getSize(sym->type), sym->regType, sym, 0, TRUE) ||
936 allocReg (getSize(sym->type), sym->regType==REG_PTR?REG_GPR:REG_PTR,
938 // so we can, but we won't
939 for (i=0; i<sym->nRegs; i++) {
940 freeReg (sym->regs[i], TRUE);
945 fprintf (stderr, " %s will cause a spill\n", sym->name);
949 /*-----------------------------------------------------------------*/
950 /* positionRegs - the allocator can allocate same registers to res- */
951 /* ult and operand, if this happens make sure they are in the same */
952 /* position as the operand otherwise chaos results */
953 /*-----------------------------------------------------------------*/
955 positionRegs (symbol * result, symbol * opsym)
957 int count = min (result->nRegs, opsym->nRegs);
958 int i, j = 0, shared = 0;
961 /* if the result has been spilt then cannot share */
966 /* first make sure that they actually share */
967 for (i = 0; i < count; i++)
969 for (j = 0; j < count; j++)
971 if (result->regs[i] == opsym->regs[j] && i != j)
981 regs *tmp = result->regs[i];
982 result->regs[i] = result->regs[j];
983 result->regs[j] = tmp;
990 /*-----------------------------------------------------------------*/
991 /* serialRegAssign - serially allocate registers to the variables */
992 /*-----------------------------------------------------------------*/
994 serialRegAssign (eBBlock ** ebbs, int count)
999 for (i = 0; i < count; i++) {
1003 if (ebbs[i]->noPath &&
1004 (ebbs[i]->entryLabel != entryLabel &&
1005 ebbs[i]->entryLabel != returnLabel))
1008 /* of all instructions do */
1009 for (ic = ebbs[i]->sch; ic; ic = ic->next) {
1011 /* if result is present && is a true symbol */
1012 if (IC_RESULT (ic) && ic->op != IFX &&
1013 IS_TRUE_SYMOP (IC_RESULT (ic)))
1014 OP_SYMBOL (IC_RESULT (ic))->allocreq++;
1016 /* take away registers from live
1017 ranges that end at this instruction */
1018 deassignLRs (ic, ebbs[i]);
1020 /* some don't need registers */
1021 if (SKIP_IC2 (ic) ||
1022 ic->op == JUMPTABLE ||
1026 (IC_RESULT (ic) && POINTER_SET (ic)))
1029 /* now we need to allocate registers
1030 only for the result */
1031 if (IC_RESULT (ic)) {
1032 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
1036 /* if it does not need or is spilt
1037 or is already assigned to registers
1038 or will not live beyond this instructions */
1041 bitVectBitValue (_G.regAssigned, sym->key) ||
1042 sym->liveTo <= ic->seq)
1045 /* if some liverange has been spilt at the block level
1046 and this one live beyond this block then spil this
1048 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq) {
1052 /* if trying to allocate this will cause
1053 a spill and there is nothing to spill
1054 or this one is rematerializable then
1056 willCS = willCauseSpill (sym);
1057 spillable = computeSpillable (ic);
1058 if (sym->remat || (willCS && bitVectIsZero (spillable))) {
1063 /* if it has a spillocation & is used less than
1064 all other live ranges then spill this */
1066 if (sym->usl.spillLoc) {
1067 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
1068 allLRs, ebbs[i], ic));
1069 if (leastUsed && leastUsed->used > sym->used) {
1074 /* if none of the liveRanges have a spillLocation then better
1075 to spill this one than anything else already assigned to registers */
1076 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
1077 /* if this is local to this block then we might find a block spil */
1078 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
1086 /* else we assign registers to it */
1087 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1088 _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key);
1090 if (sym->regType == REG_PTR)
1091 getRegPtr (ic, ebbs[i], sym, 0);
1093 getRegGpr (ic, ebbs[i], sym, 0);
1095 /* if it shares registers with operands make sure
1096 that they are in the same position */
1097 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
1098 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=') {
1099 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1100 OP_SYMBOL (IC_LEFT (ic)));
1102 /* do the same for the right operand */
1103 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
1104 OP_SYMBOL (IC_RIGHT (ic))->nRegs) {
1105 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1106 OP_SYMBOL (IC_RIGHT (ic)));
1113 /*-----------------------------------------------------------------*/
1114 /* rUmaskForOp :- returns register mask for an operand */
1115 /*-----------------------------------------------------------------*/
1116 bitVect *xa51_rUmaskForOp (operand * op) {
1121 /* only temporaries are assigned registers */
1125 sym = OP_SYMBOL (op);
1127 /* if spilt or no registers assigned to it
1129 if (sym->isspilt || !sym->nRegs || !sym->regs[0])
1132 rumask = newBitVect (xa51_nRegs);
1134 for (j = 0; j < sym->nRegs; j++) {
1135 rumask = bitVectSetBit (rumask,
1136 sym->regs[j]->rIdx);
1141 /*-----------------------------------------------------------------*/
1142 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
1143 /*-----------------------------------------------------------------*/
1145 regsUsedIniCode (iCode * ic)
1147 bitVect *rmask = newBitVect (xa51_nRegs);
1149 /* do the special cases first */
1152 rmask = bitVectUnion (rmask,
1153 xa51_rUmaskForOp (IC_COND (ic)));
1157 /* for the jumptable */
1158 if (ic->op == JUMPTABLE)
1160 rmask = bitVectUnion (rmask,
1161 xa51_rUmaskForOp (IC_JTCOND (ic)));
1166 /* of all other cases */
1168 rmask = bitVectUnion (rmask,
1169 xa51_rUmaskForOp (IC_LEFT (ic)));
1173 rmask = bitVectUnion (rmask,
1174 xa51_rUmaskForOp (IC_RIGHT (ic)));
1177 rmask = bitVectUnion (rmask,
1178 xa51_rUmaskForOp (IC_RESULT (ic)));
1184 /*-----------------------------------------------------------------*/
1185 /* createRegMask - for each instruction will determine the regsUsed */
1186 /*-----------------------------------------------------------------*/
1188 createRegMask (eBBlock ** ebbs, int count)
1192 /* for all blocks */
1193 for (i = 0; i < count; i++)
1197 if (ebbs[i]->noPath &&
1198 (ebbs[i]->entryLabel != entryLabel &&
1199 ebbs[i]->entryLabel != returnLabel))
1202 /* for all instructions */
1203 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1208 if (SKIP_IC2 (ic) || !ic->rlive)
1211 /* first mark the registers used in this
1213 ic->rUsed = regsUsedIniCode (ic);
1214 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
1216 /* now create the register mask for those
1217 registers that are in use : this is a
1218 super set of ic->rUsed */
1219 ic->rMask = newBitVect (xa51_nRegs + 1);
1221 /* for all live Ranges alive at this point */
1222 for (j = 1; j < ic->rlive->size; j++)
1227 /* if not alive then continue */
1228 if (!bitVectBitValue (ic->rlive, j))
1231 /* find the live range we are interested in */
1232 if (!(sym = hTabItemWithKey (liveRanges, j)))
1234 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1235 "createRegMask cannot find live range");
1239 /* if no register assigned to it */
1240 if (!sym->nRegs || sym->isspilt)
1243 /* for all the registers allocated to it */
1244 for (k = 0; k < sym->nRegs; k++)
1247 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
1253 /*-----------------------------------------------------------------*/
1254 /* rematStr - returns the rematerialized string for a remat var */
1255 /*-----------------------------------------------------------------*/
1257 rematStr (symbol * sym)
1260 iCode *ic = sym->rematiCode;
1265 /* if plus or minus print the right hand side */
1266 if (ic->op == '+' || ic->op == '-')
1268 sprintf (s, "0x%04x %c ", (int) operandLitValue (IC_RIGHT (ic)),
1271 ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1275 /* cast then continue */
1276 if (IS_CAST_ICODE(ic)) {
1277 ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
1280 /* we reached the end */
1281 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
1288 /*-----------------------------------------------------------------*/
1289 /* regTypeNum - computes the type & number of registers required */
1290 /*-----------------------------------------------------------------*/
1292 regTypeNum (eBBlock *ebbs)
1298 /* for each live range do */
1299 for (sym = hTabFirstItem (liveRanges, &k); sym;
1300 sym = hTabNextItem (liveRanges, &k))
1303 /* if used zero times then no registers needed */
1304 if ((sym->liveTo - sym->liveFrom) == 0)
1308 /* if the live range is a temporary */
1312 /* if the type is marked as a conditional */
1313 if (sym->regType == REG_CND)
1316 /* if used in return only then we don't
1319 if (sym->ruonly || sym->accuse)
1321 if (IS_AGGREGATE (sym->type) || sym->isptr)
1322 sym->type = aggrToPtr (sym->type, FALSE);
1327 /* if the symbol has only one definition &
1328 that definition is a get_pointer and the
1329 pointer we are getting is rematerializable and
1332 if (bitVectnBitsOn (sym->defs) == 1 &&
1333 (ic = hTabItemWithKey (iCodehTab,
1334 bitVectFirstBit (sym->defs))) &&
1337 !IS_BITVAR (sym->etype))
1341 /* if remat in data space */
1342 if (OP_SYMBOL (IC_LEFT (ic))->remat &&
1343 !IS_CAST_ICODE(OP_SYMBOL (IC_LEFT (ic))->rematiCode) &&
1344 DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER)
1346 /* create a psuedo symbol & force a spil */
1347 symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
1348 psym->type = sym->type;
1349 psym->etype = sym->etype;
1350 strcpy (psym->rname, psym->name);
1352 sym->usl.spillLoc = psym;
1353 #if 0 // an alternative fix for bug #480076
1354 /* now this is a useless assignment to itself */
1355 remiCodeFromeBBlock (ebbs, ic);
1357 /* now this really is an assignment to itself, make it so;
1358 it will be optimized out later */
1360 IC_RIGHT(ic)=IC_RESULT(ic);
1366 /* if in data space or idata space then try to
1367 allocate pointer register */
1371 /* if not then we require registers */
1373 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
1374 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1375 getSize (sym->type));
1378 int size=((IS_AGGREGATE (sym->type) || sym->isptr) ?
1379 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1380 getSize (sym->type));
1384 case 2: // word or pointer
1387 case 3: // generic pointer
1390 case 4: // dword or float
1394 fprintf (stderr, "regTypeNum: unknown size\n");
1402 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
1403 printTypeChain (sym->type, stderr);
1404 fprintf (stderr, "\n");
1407 /* determine the type of register required */
1408 if (IS_PTR (sym->type))
1409 sym->regType = REG_PTR;
1411 sym->regType = REG_GPR;
1415 /* for the first run we don't provide */
1416 /* registers for true symbols we will */
1417 /* see how things go */
1423 /*-----------------------------------------------------------------*/
1424 /* deallocStackSpil - this will set the stack pointer back */
1425 /*-----------------------------------------------------------------*/
1427 DEFSETFUNC (deallocStackSpil)
1435 /*-----------------------------------------------------------------*/
1436 /* packRegsForAssign - register reduction for assignment */
1437 /*-----------------------------------------------------------------*/
1439 packRegsForAssign (iCode * ic, eBBlock * ebp)
1443 if (!IS_ITEMP (IC_RIGHT (ic)) ||
1444 OP_LIVETO (IC_RIGHT (ic)) > ic->seq) {
1448 /* find the definition of iTempNN scanning backwards */
1449 for (dic = ic->prev; dic; dic = dic->prev) {
1451 /* if there is a function call then don't pack it */
1452 if ((dic->op == CALL || dic->op == PCALL)) {
1460 if (IS_SYMOP (IC_RESULT (dic)) &&
1461 IC_RESULT (dic)->key == IC_RIGHT (ic)->key) {
1468 return 0; /* did not find */
1470 /* found the definition */
1471 /* replace the result with the result of */
1472 /* this assignment and remove this assignment */
1473 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1474 IC_RESULT (dic) = IC_RESULT (ic);
1476 if (IS_ITEMP (IC_RESULT (dic)) &&
1477 OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
1479 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
1481 /* delete from liverange table also
1482 delete from all the points inbetween and the new
1484 for (sic = dic; sic != ic; sic = sic->next)
1486 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
1487 if (IS_ITEMP (IC_RESULT (dic)))
1488 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
1491 remiCodeFromeBBlock (ebp, ic);
1492 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
1493 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
1494 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
1499 /*-----------------------------------------------------------------*/
1500 /* findAssignToSym : scanning backwards looks for first assig found */
1501 /*-----------------------------------------------------------------*/
1503 findAssignToSym (operand * op, iCode * ic)
1507 for (dic = ic->prev; dic; dic = dic->prev)
1510 /* if definition by assignment */
1511 if (dic->op == '=' &&
1512 !POINTER_SET (dic) &&
1513 IC_RESULT (dic)->key == op->key
1514 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
1518 /* we are interested only if defined in far space */
1519 /* or in stack space in case of + & - */
1521 /* if assigned to a non-symbol then return
1523 if (!IS_SYMOP (IC_RIGHT (dic)))
1526 /* if the symbol is in far space then
1528 if (isOperandInFarSpace (IC_RIGHT (dic)))
1531 /* for + & - operations make sure that
1532 if it is on the stack it is the same
1533 as one of the three operands */
1534 if ((ic->op == '+' || ic->op == '-') &&
1535 OP_SYMBOL (IC_RIGHT (dic))->onStack)
1538 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
1539 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
1540 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
1548 /* if we find an usage then we cannot delete it */
1549 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
1552 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
1555 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
1559 /* now make sure that the right side of dic
1560 is not defined between ic & dic */
1563 iCode *sic = dic->next;
1565 for (; sic != ic; sic = sic->next)
1566 if (IC_RESULT (sic) &&
1567 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
1576 /*-----------------------------------------------------------------*/
1577 /* packRegsForSupport :- reduce some registers for support calls */
1578 /*-----------------------------------------------------------------*/
1580 packRegsForSupport (iCode * ic, eBBlock * ebp)
1585 /* for the left & right operand :- look to see if the
1586 left was assigned a true symbol in far space in that
1587 case replace them */
1589 if (IS_ITEMP (IC_LEFT (ic)) &&
1590 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
1592 dic = findAssignToSym (IC_LEFT (ic), ic);
1597 /* found it we need to remove it from the
1599 for (sic = dic; sic != ic; sic = sic->next)
1600 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
1602 OP_SYMBOL(IC_LEFT (ic))=OP_SYMBOL(IC_RIGHT (dic));
1603 IC_LEFT (ic)->key = OP_SYMBOL(IC_RIGHT (dic))->key;
1604 remiCodeFromeBBlock (ebp, dic);
1605 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1606 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1610 /* do the same for the right operand */
1613 IS_ITEMP (IC_RIGHT (ic)) &&
1614 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
1616 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
1622 /* if this is a subtraction & the result
1623 is a true symbol in far space then don't pack */
1624 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
1626 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
1627 if (IN_FARSPACE (SPEC_OCLS (etype)))
1630 /* found it we need to remove it from the
1632 for (sic = dic; sic != ic; sic = sic->next)
1633 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
1635 IC_RIGHT (ic)->operand.symOperand =
1636 IC_RIGHT (dic)->operand.symOperand;
1637 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
1639 remiCodeFromeBBlock (ebp, dic);
1640 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1641 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1648 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
1651 /*-----------------------------------------------------------------*/
1652 /* packRegsForOneuse : - will reduce some registers for single Use */
1653 /*-----------------------------------------------------------------*/
1655 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
1660 /* if returning a literal then do nothing */
1664 if (ic->op != RETURN &&
1666 !POINTER_SET (ic) &&
1670 /* this routine will mark the a symbol as used in one
1671 instruction use only && if the defintion is local
1672 (ie. within the basic block) && has only one definition &&
1673 that definiion is either a return value from a
1674 function or does not contain any variables in
1676 uses = bitVectCopy (OP_USES (op));
1677 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
1678 if (!bitVectIsZero (uses)) /* has other uses */
1681 /* if it has only one defintion */
1682 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
1683 return NULL; /* has more than one definition */
1685 /* get that definition */
1687 hTabItemWithKey (iCodehTab,
1688 bitVectFirstBit (OP_DEFS (op)))))
1691 /* if that only usage is a cast */
1692 if (dic->op == CAST) {
1693 /* to a bigger type */
1694 if (getSize(OP_SYM_TYPE(IC_RESULT(dic))) >
1695 getSize(OP_SYM_TYPE(IC_RIGHT(dic)))) {
1696 /* than we can not, since we cannot predict the usage of b & acc */
1701 /* found the definition now check if it is local */
1702 if (dic->seq < ebp->fSeq ||
1703 dic->seq > ebp->lSeq)
1704 return NULL; /* non-local */
1706 /* now check if it is the return from
1708 if (dic->op == CALL || dic->op == PCALL)
1710 if (ic->op != SEND && ic->op != RETURN &&
1711 !POINTER_SET(ic) && !POINTER_GET(ic))
1713 OP_SYMBOL (op)->ruonly = 1;
1720 /* otherwise check that the definition does
1721 not contain any symbols in far space */
1722 if (isOperandInFarSpace (IC_LEFT (dic)) ||
1723 isOperandInFarSpace (IC_RIGHT (dic)) ||
1724 IS_OP_RUONLY (IC_LEFT (ic)) ||
1725 IS_OP_RUONLY (IC_RIGHT (ic)))
1730 /* if pointer set then make sure the pointer
1732 if (POINTER_SET (dic) &&
1733 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
1736 if (POINTER_GET (dic) &&
1737 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
1742 /* also make sure the intervenening instructions
1743 don't have any thing in far space */
1744 for (dic = dic->next; dic && dic != ic && sic != ic; dic = dic->next)
1747 /* if there is an intervening function call then no */
1748 if (dic->op == CALL || dic->op == PCALL)
1750 /* if pointer set then make sure the pointer
1752 if (POINTER_SET (dic) &&
1753 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
1756 if (POINTER_GET (dic) &&
1757 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
1760 /* if address of & the result is remat the okay */
1761 if (dic->op == ADDRESS_OF &&
1762 OP_SYMBOL (IC_RESULT (dic))->remat)
1765 /* if operand has size of three or more & this
1766 operation is a '*','/' or '%' then 'b' may
1768 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
1769 getSize (operandType (op)) >= 3)
1772 /* if left or right or result is in far space */
1773 if (isOperandInFarSpace (IC_LEFT (dic)) ||
1774 isOperandInFarSpace (IC_RIGHT (dic)) ||
1775 isOperandInFarSpace (IC_RESULT (dic)) ||
1776 IS_OP_RUONLY (IC_LEFT (dic)) ||
1777 IS_OP_RUONLY (IC_RIGHT (dic)) ||
1778 IS_OP_RUONLY (IC_RESULT (dic)))
1782 /* if left or right or result is on stack */
1783 if (isOperandOnStack(IC_LEFT(dic)) ||
1784 isOperandOnStack(IC_RIGHT(dic)) ||
1785 isOperandOnStack(IC_RESULT(dic))) {
1790 OP_SYMBOL (op)->ruonly = 1;
1795 /*-----------------------------------------------------------------*/
1796 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
1797 /*-----------------------------------------------------------------*/
1799 isBitwiseOptimizable (iCode * ic)
1801 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
1802 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
1804 /* bitwise operations are considered optimizable
1805 under the following conditions (Jean-Louis VERN)
1817 if (IS_LITERAL(rtype) ||
1818 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
1824 /*-----------------------------------------------------------------*/
1825 /* packForPush - hueristics to reduce iCode for pushing */
1826 /*-----------------------------------------------------------------*/
1828 packForPush (iCode * ic, eBBlock * ebp)
1833 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
1836 /* must have only definition & one usage */
1837 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
1838 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
1841 /* find the definition */
1842 if (!(dic = hTabItemWithKey (iCodehTab,
1843 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
1846 if (dic->op != '=' || POINTER_SET (dic))
1849 /* make sure the right side does not have any definitions
1851 dbv = OP_DEFS(IC_RIGHT(dic));
1852 for (lic = ic; lic && lic != dic ; lic = lic->prev) {
1853 if (bitVectBitValue(dbv,lic->key))
1856 /* make sure they have the same type */
1858 sym_link *itype=operandType(IC_LEFT(ic));
1859 sym_link *ditype=operandType(IC_RIGHT(dic));
1861 if (SPEC_USIGN(itype)!=SPEC_USIGN(ditype) ||
1862 SPEC_LONG(itype)!=SPEC_LONG(ditype))
1865 /* extend the live range of replaced operand if needed */
1866 if (OP_SYMBOL(IC_RIGHT(dic))->liveTo < ic->seq) {
1867 OP_SYMBOL(IC_RIGHT(dic))->liveTo = ic->seq;
1869 /* we now know that it has one & only one def & use
1870 and the that the definition is an assignment */
1871 IC_LEFT (ic) = IC_RIGHT (dic);
1873 remiCodeFromeBBlock (ebp, dic);
1874 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1875 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1878 /*-----------------------------------------------------------------*/
1879 /* packRegisters - does some transformations to reduce register */
1881 /*-----------------------------------------------------------------*/
1882 static void packRegisters (eBBlock * ebp) {
1889 for (ic = ebp->sch; ic; ic = ic->next) {
1891 change += packRegsForAssign (ic, ebp);
1897 return; // that's it for now
1899 for (ic = ebp->sch; ic; ic = ic->next)
1901 /* if this is an itemp & result of an address of a true sym
1902 then mark this as rematerialisable */
1903 if (ic->op == ADDRESS_OF &&
1904 IS_ITEMP (IC_RESULT (ic)) &&
1905 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
1906 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
1907 !OP_SYMBOL (IC_LEFT (ic))->onStack)
1910 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
1911 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
1912 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
1916 /* if straight assignment then carry remat flag if
1917 this is the only definition */
1918 if (ic->op == '=' &&
1919 !POINTER_SET (ic) &&
1920 IS_SYMOP (IC_RIGHT (ic)) &&
1921 OP_SYMBOL (IC_RIGHT (ic))->remat &&
1922 !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode) &&
1923 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
1926 OP_SYMBOL (IC_RESULT (ic))->remat =
1927 OP_SYMBOL (IC_RIGHT (ic))->remat;
1928 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
1929 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
1932 /* if cast to a generic pointer & the pointer being
1933 cast is remat, then we can remat this cast as well */
1934 if (ic->op == CAST &&
1935 IS_SYMOP(IC_RIGHT(ic)) &&
1936 OP_SYMBOL(IC_RIGHT(ic))->remat ) {
1937 sym_link *to_type = operandType(IC_LEFT(ic));
1938 sym_link *from_type = operandType(IC_RIGHT(ic));
1939 if (IS_GENPTR(to_type) && IS_PTR(from_type)) {
1940 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
1941 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
1942 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
1946 /* if this is a +/- operation with a rematerizable
1947 then mark this as rematerializable as well */
1948 if ((ic->op == '+' || ic->op == '-') &&
1949 (IS_SYMOP (IC_LEFT (ic)) &&
1950 IS_ITEMP (IC_RESULT (ic)) &&
1951 IS_OP_LITERAL (IC_RIGHT (ic))) &&
1952 OP_SYMBOL (IC_LEFT (ic))->remat &&
1953 (!IS_SYMOP (IC_RIGHT (ic)) || !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode)) &&
1954 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1)
1956 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
1957 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
1958 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
1961 /* mark the pointer usages */
1962 if (POINTER_SET (ic))
1963 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
1965 if (POINTER_GET (ic))
1966 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
1968 /* if the condition of an if instruction
1969 is defined in the previous instruction and
1970 this is the only usage then
1971 mark the itemp as a conditional */
1972 if ((IS_CONDITIONAL (ic) ||
1973 (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic))) &&
1974 ic->next && ic->next->op == IFX &&
1975 bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
1976 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
1977 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
1979 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
1983 /* reduce for support function calls */
1984 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
1985 packRegsForSupport (ic, ebp);
1987 /* some cases the redundant moves can
1988 can be eliminated for return statements */
1989 if ((ic->op == RETURN || ic->op == SEND) &&
1990 !isOperandInFarSpace (IC_LEFT (ic)) &&
1991 options.model == MODEL_SMALL) {
1992 if (0 && options.stackAuto) {
1993 /* we should check here if acc will be clobbered for stack
1994 offset calculations */
1996 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2000 /* if pointer set & left has a size more than
2001 one and right is not in far space */
2002 if (POINTER_SET (ic) &&
2003 !isOperandInFarSpace (IC_RIGHT (ic)) &&
2004 !OP_SYMBOL (IC_RESULT (ic))->remat &&
2005 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
2006 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
2008 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
2010 /* if pointer get */
2011 if (POINTER_GET (ic) &&
2012 !isOperandInFarSpace (IC_RESULT (ic)) &&
2013 !OP_SYMBOL (IC_LEFT (ic))->remat &&
2014 !IS_OP_RUONLY (IC_RESULT (ic)) &&
2015 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
2017 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2020 /* if this is cast for intergral promotion then
2021 check if only use of the definition of the
2022 operand being casted/ if yes then replace
2023 the result of that arithmetic operation with
2024 this result and get rid of the cast */
2027 sym_link *fromType = operandType (IC_RIGHT (ic));
2028 sym_link *toType = operandType (IC_LEFT (ic));
2030 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
2031 getSize (fromType) != getSize (toType) &&
2032 SPEC_USIGN (fromType) == SPEC_USIGN (toType))
2035 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2038 if (IS_ARITHMETIC_OP (dic))
2040 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2041 IC_RESULT (dic) = IC_RESULT (ic);
2042 remiCodeFromeBBlock (ebp, ic);
2043 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2044 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2045 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2049 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
2055 /* if the type from and type to are the same
2056 then if this is the only use then packit */
2057 if (compareType (operandType (IC_RIGHT (ic)),
2058 operandType (IC_LEFT (ic))) == 1)
2060 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2063 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2064 IC_RESULT (dic) = IC_RESULT (ic);
2065 remiCodeFromeBBlock (ebp, ic);
2066 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2067 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2068 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2076 iTempNN := (some variable in farspace) V1
2081 if (ic->op == IPUSH)
2083 packForPush (ic, ebp);
2088 /*-----------------------------------------------------------------*/
2089 /* assignRegisters - assigns registers to each live range as need */
2090 /*-----------------------------------------------------------------*/
2092 xa51_assignRegisters (eBBlock ** ebbs, int count)
2097 setToNull ((void *) &_G.funcrUsed);
2098 setToNull ((void *) &_G.totRegAssigned);
2099 _G.stackExtend = _G.dataExtend = 0;
2101 /* change assignments this will remove some
2102 live ranges reducing some register pressure */
2103 for (i = 0; i < count; i++)
2104 packRegisters (ebbs[i]);
2106 if (options.dump_pack)
2107 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
2109 /* first determine for each live range the number of
2110 registers & the type of registers required for each */
2113 /* and serially allocate registers */
2114 serialRegAssign (ebbs, count);
2118 /* if stack was extended then tell the user */
2121 /* werror(W_TOOMANY_SPILS,"stack", */
2122 /* _G.stackExtend,currFunc->name,""); */
2128 /* werror(W_TOOMANY_SPILS,"data space", */
2129 /* _G.dataExtend,currFunc->name,""); */
2133 /* after that create the register mask
2134 for each of the instruction */
2135 createRegMask (ebbs, count);
2137 /* redo that offsets for stacked automatic variables */
2138 redoStackOffsets ();
2140 if (options.dump_rassgn)
2142 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
2143 dumpLiveRanges (DUMP_LRANGE, liveRanges);
2146 /* do the overlaysegment stuff SDCCmem.c */
2147 doOverlays (ebbs, count);
2149 /* now get back the chain */
2150 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
2154 /* free up any _G.stackSpil locations allocated */
2155 applyToSet (_G.stackSpil, deallocStackSpil);
2157 setToNull ((void **) &_G.stackSpil);
2158 setToNull ((void **) &_G.spiltSet);
2159 /* mark all registers as free */