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 should 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)))
1033 /* now we need to allocate registers
1034 only for the result */
1035 if (IC_RESULT (ic)) {
1036 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
1040 /* if it does not need or is spilt
1041 or is already assigned to registers
1042 or will not live beyond this instructions */
1045 bitVectBitValue (_G.regAssigned, sym->key) ||
1046 sym->liveTo <= ic->seq)
1049 /* if some liverange has been spilt at the block level
1050 and this one live beyond this block then spil this
1052 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq) {
1056 /* if trying to allocate this will cause
1057 a spill and there is nothing to spill
1058 or this one is rematerializable then
1060 willCS = willCauseSpill (sym);
1061 spillable = computeSpillable (ic);
1062 if (sym->remat || (willCS && bitVectIsZero (spillable))) {
1067 /* if it has a spillocation & is used less than
1068 all other live ranges then spill this */
1070 if (sym->usl.spillLoc) {
1071 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
1072 allLRs, ebbs[i], ic));
1073 if (leastUsed && leastUsed->used > sym->used) {
1078 /* if none of the liveRanges have a spillLocation then better
1079 to spill this one than anything else already assigned to registers */
1080 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
1081 /* if this is local to this block then we might find a block spil */
1082 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
1090 /* else we assign registers to it */
1091 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1092 _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key);
1094 if (sym->regType == REG_PTR)
1095 getRegPtr (ic, ebbs[i], sym, 0);
1097 getRegGpr (ic, ebbs[i], sym, 0);
1099 /* if it shares registers with operands make sure
1100 that they are in the same position */
1101 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
1102 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=') {
1103 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1104 OP_SYMBOL (IC_LEFT (ic)));
1106 /* do the same for the right operand */
1107 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
1108 OP_SYMBOL (IC_RIGHT (ic))->nRegs) {
1109 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1110 OP_SYMBOL (IC_RIGHT (ic)));
1117 /*-----------------------------------------------------------------*/
1118 /* rUmaskForOp :- returns register mask for an operand */
1119 /*-----------------------------------------------------------------*/
1120 bitVect *xa51_rUmaskForOp (operand * op) {
1125 /* only temporaries are assigned registers */
1129 sym = OP_SYMBOL (op);
1131 /* if spilt or no registers assigned to it
1133 if (sym->isspilt || !sym->nRegs || !sym->regs[0])
1136 rumask = newBitVect (xa51_nRegs);
1138 for (j = 0; j < sym->nRegs; j++) {
1139 rumask = bitVectSetBit (rumask,
1140 sym->regs[j]->rIdx);
1145 /*-----------------------------------------------------------------*/
1146 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
1147 /*-----------------------------------------------------------------*/
1149 regsUsedIniCode (iCode * ic)
1151 bitVect *rmask = newBitVect (xa51_nRegs);
1153 /* do the special cases first */
1156 rmask = bitVectUnion (rmask,
1157 xa51_rUmaskForOp (IC_COND (ic)));
1161 /* for the jumptable */
1162 if (ic->op == JUMPTABLE)
1164 rmask = bitVectUnion (rmask,
1165 xa51_rUmaskForOp (IC_JTCOND (ic)));
1170 /* of all other cases */
1172 rmask = bitVectUnion (rmask,
1173 xa51_rUmaskForOp (IC_LEFT (ic)));
1177 rmask = bitVectUnion (rmask,
1178 xa51_rUmaskForOp (IC_RIGHT (ic)));
1181 rmask = bitVectUnion (rmask,
1182 xa51_rUmaskForOp (IC_RESULT (ic)));
1188 /*-----------------------------------------------------------------*/
1189 /* createRegMask - for each instruction will determine the regsUsed */
1190 /*-----------------------------------------------------------------*/
1192 createRegMask (eBBlock ** ebbs, int count)
1196 /* for all blocks */
1197 for (i = 0; i < count; i++)
1201 if (ebbs[i]->noPath &&
1202 (ebbs[i]->entryLabel != entryLabel &&
1203 ebbs[i]->entryLabel != returnLabel))
1206 /* for all instructions */
1207 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1212 if (SKIP_IC2 (ic) || !ic->rlive)
1215 /* first mark the registers used in this
1217 ic->rUsed = regsUsedIniCode (ic);
1218 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
1220 /* now create the register mask for those
1221 registers that are in use : this is a
1222 super set of ic->rUsed */
1223 ic->rMask = newBitVect (xa51_nRegs + 1);
1225 /* for all live Ranges alive at this point */
1226 for (j = 1; j < ic->rlive->size; j++)
1231 /* if not alive then continue */
1232 if (!bitVectBitValue (ic->rlive, j))
1235 /* find the live range we are interested in */
1236 if (!(sym = hTabItemWithKey (liveRanges, j)))
1238 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1239 "createRegMask cannot find live range");
1243 /* if no register assigned to it */
1244 if (!sym->nRegs || sym->isspilt)
1247 /* for all the registers allocated to it */
1248 for (k = 0; k < sym->nRegs; k++)
1251 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
1257 /*-----------------------------------------------------------------*/
1258 /* rematStr - returns the rematerialized string for a remat var */
1259 /*-----------------------------------------------------------------*/
1261 rematStr (symbol * sym)
1264 iCode *ic = sym->rematiCode;
1269 /* if plus or minus print the right hand side */
1270 if (ic->op == '+' || ic->op == '-')
1272 sprintf (s, "0x%04x %c ", (int) operandLitValue (IC_RIGHT (ic)),
1275 ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1279 /* cast then continue */
1280 if (IS_CAST_ICODE(ic)) {
1281 ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
1284 /* we reached the end */
1285 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
1292 /*-----------------------------------------------------------------*/
1293 /* regTypeNum - computes the type & number of registers required */
1294 /*-----------------------------------------------------------------*/
1296 regTypeNum (eBBlock *ebbs)
1302 /* for each live range do */
1303 for (sym = hTabFirstItem (liveRanges, &k); sym;
1304 sym = hTabNextItem (liveRanges, &k))
1307 /* if used zero times then no registers needed */
1308 if ((sym->liveTo - sym->liveFrom) == 0)
1312 /* if the live range is a temporary */
1316 /* if the type is marked as a conditional */
1317 if (sym->regType == REG_CND)
1320 /* if used in return only then we don't
1323 if (sym->ruonly || sym->accuse)
1325 if (IS_AGGREGATE (sym->type) || sym->isptr)
1326 sym->type = aggrToPtr (sym->type, FALSE);
1331 /* if the symbol has only one definition &
1332 that definition is a get_pointer and the
1333 pointer we are getting is rematerializable and
1336 if (bitVectnBitsOn (sym->defs) == 1 &&
1337 (ic = hTabItemWithKey (iCodehTab,
1338 bitVectFirstBit (sym->defs))) &&
1341 !IS_BITVAR (sym->etype))
1345 /* if remat in data space */
1346 if (OP_SYMBOL (IC_LEFT (ic))->remat &&
1347 !IS_CAST_ICODE(OP_SYMBOL (IC_LEFT (ic))->rematiCode) &&
1348 DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER)
1350 /* create a psuedo symbol & force a spil */
1351 symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
1352 psym->type = sym->type;
1353 psym->etype = sym->etype;
1354 strcpy (psym->rname, psym->name);
1356 sym->usl.spillLoc = psym;
1357 #if 0 // an alternative fix for bug #480076
1358 /* now this is a useless assignment to itself */
1359 remiCodeFromeBBlock (ebbs, ic);
1361 /* now this really is an assignment to itself, make it so;
1362 it will be optimized out later */
1364 IC_RIGHT(ic)=IC_RESULT(ic);
1370 /* if in data space or idata space then try to
1371 allocate pointer register */
1375 /* if not then we require registers */
1377 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
1378 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1379 getSize (sym->type));
1382 int size=((IS_AGGREGATE (sym->type) || sym->isptr) ?
1383 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1384 getSize (sym->type));
1388 case 2: // word or pointer
1391 case 3: // generic pointer
1394 case 4: // dword or float
1398 fprintf (stderr, "regTypeNum: unknown size\n");
1406 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
1407 printTypeChain (sym->type, stderr);
1408 fprintf (stderr, "\n");
1412 /* determine the type of register required */
1413 if (IS_PTR (sym->type))
1414 sym->regType = REG_PTR;
1416 sym->regType = REG_GPR;
1420 /* for the first run we don't provide */
1421 /* registers for true symbols we will */
1422 /* see how things go */
1428 /*-----------------------------------------------------------------*/
1429 /* deallocStackSpil - this will set the stack pointer back */
1430 /*-----------------------------------------------------------------*/
1432 DEFSETFUNC (deallocStackSpil)
1440 /*-----------------------------------------------------------------*/
1441 /* packRegsForAssign - register reduction for assignment */
1442 /*-----------------------------------------------------------------*/
1444 packRegsForAssign (iCode * ic, eBBlock * ebp)
1448 if (!IS_ITEMP (IC_RIGHT (ic)) ||
1449 OP_LIVETO (IC_RIGHT (ic)) > ic->seq) {
1453 /* find the definition of iTempNN scanning backwards */
1454 for (dic = ic->prev; dic; dic = dic->prev) {
1456 /* if there is a function call then don't pack it */
1457 if ((dic->op == CALL || dic->op == PCALL)) {
1465 if (IS_SYMOP (IC_RESULT (dic)) &&
1466 IC_RESULT (dic)->key == IC_RIGHT (ic)->key) {
1473 return 0; /* did not find */
1475 /* found the definition */
1476 /* replace the result with the result of */
1477 /* this assignment and remove this assignment */
1478 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1479 IC_RESULT (dic) = IC_RESULT (ic);
1481 if (IS_ITEMP (IC_RESULT (dic)) &&
1482 OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
1484 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
1486 /* delete from liverange table also
1487 delete from all the points inbetween and the new
1489 for (sic = dic; sic != ic; sic = sic->next)
1491 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
1492 if (IS_ITEMP (IC_RESULT (dic)))
1493 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
1496 remiCodeFromeBBlock (ebp, ic);
1497 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
1498 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
1499 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
1504 /*-----------------------------------------------------------------*/
1505 /* findAssignToSym : scanning backwards looks for first assig found */
1506 /*-----------------------------------------------------------------*/
1508 findAssignToSym (operand * op, iCode * ic)
1512 for (dic = ic->prev; dic; dic = dic->prev)
1515 /* if definition by assignment */
1516 if (dic->op == '=' &&
1517 !POINTER_SET (dic) &&
1518 IC_RESULT (dic)->key == op->key
1519 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
1523 /* we are interested only if defined in far space */
1524 /* or in stack space in case of + & - */
1526 /* if assigned to a non-symbol then return
1528 if (!IS_SYMOP (IC_RIGHT (dic)))
1531 /* if the symbol is in far space then
1533 if (isOperandInFarSpace (IC_RIGHT (dic)))
1536 /* for + & - operations make sure that
1537 if it is on the stack it is the same
1538 as one of the three operands */
1539 if ((ic->op == '+' || ic->op == '-') &&
1540 OP_SYMBOL (IC_RIGHT (dic))->onStack)
1543 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
1544 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
1545 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
1553 /* if we find an usage then we cannot delete it */
1554 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
1557 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
1560 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
1564 /* now make sure that the right side of dic
1565 is not defined between ic & dic */
1568 iCode *sic = dic->next;
1570 for (; sic != ic; sic = sic->next)
1571 if (IC_RESULT (sic) &&
1572 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
1581 /*-----------------------------------------------------------------*/
1582 /* packRegsForSupport :- reduce some registers for support calls */
1583 /*-----------------------------------------------------------------*/
1585 packRegsForSupport (iCode * ic, eBBlock * ebp)
1590 /* for the left & right operand :- look to see if the
1591 left was assigned a true symbol in far space in that
1592 case replace them */
1594 if (IS_ITEMP (IC_LEFT (ic)) &&
1595 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
1597 dic = findAssignToSym (IC_LEFT (ic), ic);
1602 /* found it we need to remove it from the
1604 for (sic = dic; sic != ic; sic = sic->next)
1605 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
1607 OP_SYMBOL(IC_LEFT (ic))=OP_SYMBOL(IC_RIGHT (dic));
1608 IC_LEFT (ic)->key = OP_SYMBOL(IC_RIGHT (dic))->key;
1609 remiCodeFromeBBlock (ebp, dic);
1610 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1611 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1615 /* do the same for the right operand */
1618 IS_ITEMP (IC_RIGHT (ic)) &&
1619 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
1621 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
1627 /* if this is a subtraction & the result
1628 is a true symbol in far space then don't pack */
1629 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
1631 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
1632 if (IN_FARSPACE (SPEC_OCLS (etype)))
1635 /* found it we need to remove it from the
1637 for (sic = dic; sic != ic; sic = sic->next)
1638 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
1640 IC_RIGHT (ic)->operand.symOperand =
1641 IC_RIGHT (dic)->operand.symOperand;
1642 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
1644 remiCodeFromeBBlock (ebp, dic);
1645 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1646 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1653 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
1656 /*-----------------------------------------------------------------*/
1657 /* packRegsForOneuse : - will reduce some registers for single Use */
1658 /*-----------------------------------------------------------------*/
1660 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
1665 /* if returning a literal then do nothing */
1669 if (ic->op != RETURN &&
1671 !POINTER_SET (ic) &&
1675 /* this routine will mark the a symbol as used in one
1676 instruction use only && if the defintion is local
1677 (ie. within the basic block) && has only one definition &&
1678 that definiion is either a return value from a
1679 function or does not contain any variables in
1681 uses = bitVectCopy (OP_USES (op));
1682 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
1683 if (!bitVectIsZero (uses)) /* has other uses */
1686 /* if it has only one defintion */
1687 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
1688 return NULL; /* has more than one definition */
1690 /* get that definition */
1692 hTabItemWithKey (iCodehTab,
1693 bitVectFirstBit (OP_DEFS (op)))))
1696 /* if that only usage is a cast */
1697 if (dic->op == CAST) {
1698 /* to a bigger type */
1699 if (getSize(OP_SYM_TYPE(IC_RESULT(dic))) >
1700 getSize(OP_SYM_TYPE(IC_RIGHT(dic)))) {
1701 /* than we can not, since we cannot predict the usage of b & acc */
1706 /* found the definition now check if it is local */
1707 if (dic->seq < ebp->fSeq ||
1708 dic->seq > ebp->lSeq)
1709 return NULL; /* non-local */
1711 /* now check if it is the return from
1713 if (dic->op == CALL || dic->op == PCALL)
1715 if (ic->op != SEND && ic->op != RETURN &&
1716 !POINTER_SET(ic) && !POINTER_GET(ic))
1718 OP_SYMBOL (op)->ruonly = 1;
1725 /* otherwise check that the definition does
1726 not contain any symbols in far space */
1727 if (isOperandInFarSpace (IC_LEFT (dic)) ||
1728 isOperandInFarSpace (IC_RIGHT (dic)) ||
1729 IS_OP_RUONLY (IC_LEFT (ic)) ||
1730 IS_OP_RUONLY (IC_RIGHT (ic)))
1735 /* if pointer set then make sure the pointer
1737 if (POINTER_SET (dic) &&
1738 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
1741 if (POINTER_GET (dic) &&
1742 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
1747 /* also make sure the intervenening instructions
1748 don't have any thing in far space */
1749 for (dic = dic->next; dic && dic != ic && sic != ic; dic = dic->next)
1752 /* if there is an intervening function call then no */
1753 if (dic->op == CALL || dic->op == PCALL)
1755 /* if pointer set then make sure the pointer
1757 if (POINTER_SET (dic) &&
1758 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
1761 if (POINTER_GET (dic) &&
1762 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
1765 /* if address of & the result is remat the okay */
1766 if (dic->op == ADDRESS_OF &&
1767 OP_SYMBOL (IC_RESULT (dic))->remat)
1770 /* if operand has size of three or more & this
1771 operation is a '*','/' or '%' then 'b' may
1773 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
1774 getSize (operandType (op)) >= 3)
1777 /* if left or right or result is in far space */
1778 if (isOperandInFarSpace (IC_LEFT (dic)) ||
1779 isOperandInFarSpace (IC_RIGHT (dic)) ||
1780 isOperandInFarSpace (IC_RESULT (dic)) ||
1781 IS_OP_RUONLY (IC_LEFT (dic)) ||
1782 IS_OP_RUONLY (IC_RIGHT (dic)) ||
1783 IS_OP_RUONLY (IC_RESULT (dic)))
1787 /* if left or right or result is on stack */
1788 if (isOperandOnStack(IC_LEFT(dic)) ||
1789 isOperandOnStack(IC_RIGHT(dic)) ||
1790 isOperandOnStack(IC_RESULT(dic))) {
1795 OP_SYMBOL (op)->ruonly = 1;
1800 /*-----------------------------------------------------------------*/
1801 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
1802 /*-----------------------------------------------------------------*/
1804 isBitwiseOptimizable (iCode * ic)
1806 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
1807 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
1809 /* bitwise operations are considered optimizable
1810 under the following conditions (Jean-Louis VERN)
1822 if (IS_LITERAL(rtype) ||
1823 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
1829 /*-----------------------------------------------------------------*/
1830 /* packForPush - hueristics to reduce iCode for pushing */
1831 /*-----------------------------------------------------------------*/
1833 packForPush (iCode * ic, eBBlock * ebp)
1838 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
1841 /* must have only definition & one usage */
1842 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
1843 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
1846 /* find the definition */
1847 if (!(dic = hTabItemWithKey (iCodehTab,
1848 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
1851 if (dic->op != '=' || POINTER_SET (dic))
1854 /* make sure the right side does not have any definitions
1856 dbv = OP_DEFS(IC_RIGHT(dic));
1857 for (lic = ic; lic && lic != dic ; lic = lic->prev) {
1858 if (bitVectBitValue(dbv,lic->key))
1861 /* make sure they have the same type */
1863 sym_link *itype=operandType(IC_LEFT(ic));
1864 sym_link *ditype=operandType(IC_RIGHT(dic));
1866 if (SPEC_USIGN(itype)!=SPEC_USIGN(ditype) ||
1867 SPEC_LONG(itype)!=SPEC_LONG(ditype))
1870 /* extend the live range of replaced operand if needed */
1871 if (OP_SYMBOL(IC_RIGHT(dic))->liveTo < ic->seq) {
1872 OP_SYMBOL(IC_RIGHT(dic))->liveTo = ic->seq;
1874 /* we now know that it has one & only one def & use
1875 and the that the definition is an assignment */
1876 IC_LEFT (ic) = IC_RIGHT (dic);
1878 remiCodeFromeBBlock (ebp, dic);
1879 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1880 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1883 /*-----------------------------------------------------------------*/
1884 /* packRegisters - does some transformations to reduce register */
1886 /*-----------------------------------------------------------------*/
1887 static void packRegisters (eBBlock * ebp) {
1894 for (ic = ebp->sch; ic; ic = ic->next) {
1896 change += packRegsForAssign (ic, ebp);
1902 return; // that's it for now
1904 for (ic = ebp->sch; ic; ic = ic->next)
1906 /* if this is an itemp & result of an address of a true sym
1907 then mark this as rematerialisable */
1908 if (ic->op == ADDRESS_OF &&
1909 IS_ITEMP (IC_RESULT (ic)) &&
1910 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
1911 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
1912 !OP_SYMBOL (IC_LEFT (ic))->onStack)
1915 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
1916 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
1917 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
1921 /* if straight assignment then carry remat flag if
1922 this is the only definition */
1923 if (ic->op == '=' &&
1924 !POINTER_SET (ic) &&
1925 IS_SYMOP (IC_RIGHT (ic)) &&
1926 OP_SYMBOL (IC_RIGHT (ic))->remat &&
1927 !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode) &&
1928 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
1931 OP_SYMBOL (IC_RESULT (ic))->remat =
1932 OP_SYMBOL (IC_RIGHT (ic))->remat;
1933 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
1934 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
1937 /* if cast to a generic pointer & the pointer being
1938 cast is remat, then we can remat this cast as well */
1939 if (ic->op == CAST &&
1940 IS_SYMOP(IC_RIGHT(ic)) &&
1941 OP_SYMBOL(IC_RIGHT(ic))->remat ) {
1942 sym_link *to_type = operandType(IC_LEFT(ic));
1943 sym_link *from_type = operandType(IC_RIGHT(ic));
1944 if (IS_GENPTR(to_type) && IS_PTR(from_type)) {
1945 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
1946 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
1947 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
1951 /* if this is a +/- operation with a rematerizable
1952 then mark this as rematerializable as well */
1953 if ((ic->op == '+' || ic->op == '-') &&
1954 (IS_SYMOP (IC_LEFT (ic)) &&
1955 IS_ITEMP (IC_RESULT (ic)) &&
1956 IS_OP_LITERAL (IC_RIGHT (ic))) &&
1957 OP_SYMBOL (IC_LEFT (ic))->remat &&
1958 (!IS_SYMOP (IC_RIGHT (ic)) || !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode)) &&
1959 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1)
1961 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
1962 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
1963 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
1966 /* mark the pointer usages */
1967 if (POINTER_SET (ic))
1968 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
1970 if (POINTER_GET (ic))
1971 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
1973 /* if the condition of an if instruction
1974 is defined in the previous instruction and
1975 this is the only usage then
1976 mark the itemp as a conditional */
1977 if ((IS_CONDITIONAL (ic) ||
1978 (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic))) &&
1979 ic->next && ic->next->op == IFX &&
1980 bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
1981 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
1982 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
1984 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
1988 /* reduce for support function calls */
1989 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
1990 packRegsForSupport (ic, ebp);
1992 /* some cases the redundant moves can
1993 can be eliminated for return statements */
1994 if ((ic->op == RETURN || ic->op == SEND) &&
1995 !isOperandInFarSpace (IC_LEFT (ic)) &&
1996 options.model == MODEL_SMALL) {
1997 if (0 && options.stackAuto) {
1998 /* we should check here if acc will be clobbered for stack
1999 offset calculations */
2001 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2005 /* if pointer set & left has a size more than
2006 one and right is not in far space */
2007 if (POINTER_SET (ic) &&
2008 !isOperandInFarSpace (IC_RIGHT (ic)) &&
2009 !OP_SYMBOL (IC_RESULT (ic))->remat &&
2010 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
2011 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
2013 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
2015 /* if pointer get */
2016 if (POINTER_GET (ic) &&
2017 !isOperandInFarSpace (IC_RESULT (ic)) &&
2018 !OP_SYMBOL (IC_LEFT (ic))->remat &&
2019 !IS_OP_RUONLY (IC_RESULT (ic)) &&
2020 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
2022 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2025 /* if this is cast for intergral promotion then
2026 check if only use of the definition of the
2027 operand being casted/ if yes then replace
2028 the result of that arithmetic operation with
2029 this result and get rid of the cast */
2032 sym_link *fromType = operandType (IC_RIGHT (ic));
2033 sym_link *toType = operandType (IC_LEFT (ic));
2035 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
2036 getSize (fromType) != getSize (toType) &&
2037 SPEC_USIGN (fromType) == SPEC_USIGN (toType))
2040 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2043 if (IS_ARITHMETIC_OP (dic))
2045 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2046 IC_RESULT (dic) = IC_RESULT (ic);
2047 remiCodeFromeBBlock (ebp, ic);
2048 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2049 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2050 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2054 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
2060 /* if the type from and type to are the same
2061 then if this is the only use then packit */
2062 if (compareType (operandType (IC_RIGHT (ic)),
2063 operandType (IC_LEFT (ic))) == 1)
2065 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2068 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2069 IC_RESULT (dic) = IC_RESULT (ic);
2070 remiCodeFromeBBlock (ebp, ic);
2071 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2072 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2073 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2081 iTempNN := (some variable in farspace) V1
2086 if (ic->op == IPUSH)
2088 packForPush (ic, ebp);
2093 /*-----------------------------------------------------------------*/
2094 /* assignRegisters - assigns registers to each live range as need */
2095 /*-----------------------------------------------------------------*/
2097 xa51_assignRegisters (eBBlock ** ebbs, int count)
2102 setToNull ((void *) &_G.funcrUsed);
2103 setToNull ((void *) &_G.totRegAssigned);
2104 _G.stackExtend = _G.dataExtend = 0;
2106 /* change assignments this will remove some
2107 live ranges reducing some register pressure */
2108 for (i = 0; i < count; i++)
2109 packRegisters (ebbs[i]);
2111 if (options.dump_pack)
2112 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
2114 /* first determine for each live range the number of
2115 registers & the type of registers required for each */
2118 /* and serially allocate registers */
2119 serialRegAssign (ebbs, count);
2123 /* if stack was extended then tell the user */
2126 /* werror(W_TOOMANY_SPILS,"stack", */
2127 /* _G.stackExtend,currFunc->name,""); */
2133 /* werror(W_TOOMANY_SPILS,"data space", */
2134 /* _G.dataExtend,currFunc->name,""); */
2138 /* after that create the register mask
2139 for each of the instruction */
2140 createRegMask (ebbs, count);
2142 /* redo that offsets for stacked automatic variables */
2143 redoStackOffsets ();
2145 if (options.dump_rassgn)
2147 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
2148 dumpLiveRanges (DUMP_LRANGE, liveRanges);
2151 /* do the overlaysegment stuff SDCCmem.c */
2152 doOverlays (ebbs, count);
2154 /* now get back the chain */
2155 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
2159 /* free up any _G.stackSpil locations allocated */
2160 applyToSet (_G.stackSpil, deallocStackSpil);
2162 setToNull ((void **) &_G.stackSpil);
2163 setToNull ((void **) &_G.spiltSet);
2164 /* mark all registers as free */