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 bit/word access no ptr 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 (%s) ", xa51RegsInUse,
170 reg->name, reg->sym->name);
173 if (reg->isFree || ((xa51RegsInUse®->regMask)!=reg->regMask)) {
174 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
175 "freeReg - freeing unused register(s)");
178 xa51RegsInUse &= ~reg->regMask;
181 if (!silent) fprintf (stderr, "(%08x)\n", xa51RegsInUse);
183 checkRegMask(__FUNCTION__);
186 /*-----------------------------------------------------------------*/
187 /* allocReg - allocates register of given size (byte, word) */
188 /* and type (ptr, gpr, cnd) */
189 /*-----------------------------------------------------------------*/
190 static bool allocReg (short size, short type, symbol *sym,
191 short offset, bool silent) {
194 checkRegMask(__FUNCTION__);
197 fprintf (stderr, "allocReg (%08x) for %s size:%d, type:%s ",
200 size, regTypeToStr(type));
205 // TODO: gaps should be filled for dwords too
207 // let's see if we can fill a gap
208 for (i=0; i<xa51_nRegs; i++) {
209 if (regsXA51[i].size==2 && regsXA51[i].type==type) {
210 udword mask=regsXA51[i].regMask & ~xa51RegsInUse;
211 if (mask && mask!=regsXA51[i].regMask) {
212 regs *reg=xa51_regWithMask(mask);
214 sym->regs[offset]=reg;
215 xa51RegsInUse |= mask;
216 reg->isFree=0; // redundant
219 fprintf (stderr, "(using gap) %s\n", reg->name);
221 checkRegMask(__FUNCTION__);
226 // no we can't, fall through
228 for (i=0; i<xa51_nRegs; i++) {
229 if (regsXA51[i].size==size &&
230 regsXA51[i].type==type &&
231 (regsXA51[i].regMask & xa51RegsInUse)==0) {
232 xa51RegsInUse |= regsXA51[i].regMask;
233 regsXA51[i].isFree = 0; // redundant
234 regsXA51[i].sym = sym;
236 fprintf (stderr, "%s\n", regsXA51[i].name);
238 sym->regs[offset]=®sXA51[i];
239 checkRegMask(__FUNCTION__);
244 fprintf (stderr, "failed (%08x)\n", xa51RegsInUse);
246 checkRegMask(__FUNCTION__);
250 // this must be a generic pointer
252 fprintf (stderr, "trying 2+1\n");
254 // get the pointer part
255 if (allocReg (2, REG_PTR, sym, offset, silent)) {
256 // get the generic part
257 if ((xa51HasGprRegs && allocReg (1, REG_GPR, sym, offset+1, silent)) ||
258 allocReg (1, REG_PTR, sym, offset+1, silent)) {
259 checkRegMask(__FUNCTION__);
262 freeReg(sym->regs[offset], silent);
263 sym->regs[offset]=NULL;
265 checkRegMask(__FUNCTION__);
268 case 4: // this is a dword
270 fprintf (stderr, "trying 2+2\n");
272 if ((xa51HasGprRegs && allocReg (2, REG_GPR, sym, offset, silent)) ||
273 allocReg (2, REG_PTR, sym, offset, silent)) {
274 if ((xa51HasGprRegs && allocReg (2, REG_GPR, sym, offset+1, silent)) ||
275 allocReg (2, REG_PTR, sym, offset+1, silent)) {
276 checkRegMask(__FUNCTION__);
280 if (sym->regs[offset]) {
281 freeReg(sym->regs[offset], FALSE);
282 sym->regs[offset]=NULL;
284 checkRegMask(__FUNCTION__);
288 fprintf (stderr, "\nallocReg: cannot allocate reg of size %d\n", size);
292 // we should never come here
296 /*-------------------------------------------------------------------*/
297 /* freeAllRegs - frees all registers */
298 /*-------------------------------------------------------------------*/
299 // just to be sure, this should not be needed
300 static void freeAllRegs (void) {
305 checkRegMask(__FUNCTION__);
308 for (i=0; i<xa51_nRegs; i++) {
309 if (!regsXA51[i].isFree) {
310 strcat (regsFreed, regsXA51[i].name);
311 strcat (regsFreed, " ");
312 regsXA51[i].isFree=1;
313 regsXA51[i].sym=NULL;
319 fprintf (stderr, "freeAllRegisters: %d regs freed (%s)\n", nfr, regsFreed);
324 /*-----------------------------------------------------------------*/
325 /* allDefsOutOfRange - all definitions are out of a range */
326 /*-----------------------------------------------------------------*/
327 static bool allDefsOutOfRange (bitVect * defs, int fseq, int toseq) {
333 for (i = 0; i < defs->size; i++)
337 if (bitVectBitValue (defs, i) &&
338 (ic = hTabItemWithKey (iCodehTab, i)) &&
339 (ic->seq >= fseq && ic->seq <= toseq))
345 /*-----------------------------------------------------------------*/
346 /* computeSpillable - given a point find the spillable live ranges */
347 /*-----------------------------------------------------------------*/
348 static bitVect *computeSpillable (iCode * ic) {
351 /* spillable live ranges are those that are live at this
352 point . the following categories need to be subtracted
354 a) - those that are already spilt
355 b) - if being used by this one
356 c) - defined by this one */
358 spillable = bitVectCopy (ic->rlive);
360 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
362 bitVectCplAnd (spillable, ic->uses); /* used in this one */
363 bitVectUnSetBit (spillable, ic->defKey); /* defined by this one */
364 spillable = bitVectIntersect (spillable, _G.regAssigned);
369 /*-----------------------------------------------------------------*/
370 /* noSpilLoc - return true if a variable has no spil location */
371 /*-----------------------------------------------------------------*/
373 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
375 return (sym->usl.spillLoc ? 0 : 1);
378 /*-----------------------------------------------------------------*/
379 /* hasSpilLoc - will return 1 if the symbol has spil location */
380 /*-----------------------------------------------------------------*/
382 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
384 return (sym->usl.spillLoc ? 1 : 0);
387 /*-----------------------------------------------------------------*/
388 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
389 /* but is not used as a pointer */
390 /*-----------------------------------------------------------------*/
392 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
394 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
397 /*-----------------------------------------------------------------*/
398 /* rematable - will return 1 if the remat flag is set */
399 /*-----------------------------------------------------------------*/
401 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
406 /*-----------------------------------------------------------------*/
407 /* notUsedInBlock - not used in this block */
408 /*-----------------------------------------------------------------*/
410 notUsedInBlock (symbol * sym, eBBlock * ebp, iCode * ic)
412 return (!bitVectBitsInCommon (sym->defs, ebp->usesDefs) &&
413 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
414 /* return (!bitVectBitsInCommon(sym->defs,ebp->usesDefs)); */
417 /*-----------------------------------------------------------------*/
418 /* notUsedInRemaining - not used or defined in remain of the block */
419 /*-----------------------------------------------------------------*/
421 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
423 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
424 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
427 /*-----------------------------------------------------------------*/
428 /* allLRs - return true for all */
429 /*-----------------------------------------------------------------*/
431 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
436 /*-----------------------------------------------------------------*/
437 /* liveRangesWith - applies function to a given set of live range */
438 /*-----------------------------------------------------------------*/
440 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
441 eBBlock * ebp, iCode * ic)
446 if (!lrs || !lrs->size)
449 for (i = 1; i < lrs->size; i++)
452 if (!bitVectBitValue (lrs, i))
455 /* if we don't find it in the live range
456 hash table we are in serious trouble */
457 if (!(sym = hTabItemWithKey (liveRanges, i)))
459 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
460 "liveRangesWith could not find liveRange");
464 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
465 addSetHead (&rset, sym);
472 /*-----------------------------------------------------------------*/
473 /* leastUsedLR - given a set determines which is the least used */
474 /*-----------------------------------------------------------------*/
476 leastUsedLR (set * sset)
478 symbol *sym = NULL, *lsym = NULL;
480 sym = lsym = setFirstItem (sset);
485 for (; lsym; lsym = setNextItem (sset))
488 /* if usage is the same then prefer
489 the spill the smaller of the two */
490 if (lsym->used == sym->used)
491 if (getSize (lsym->type) < getSize (sym->type))
495 if (lsym->used < sym->used)
500 setToNull ((void **) &sset);
505 /*-----------------------------------------------------------------*/
506 /* noOverLap - will iterate through the list looking for over lap */
507 /*-----------------------------------------------------------------*/
509 noOverLap (set * itmpStack, symbol * fsym)
514 for (sym = setFirstItem (itmpStack); sym;
515 sym = setNextItem (itmpStack))
517 if (bitVectBitValue(sym->clashes,fsym->key)) return 0;
523 /*-----------------------------------------------------------------*/
524 /* isFree - will return 1 if the a free spil location is found */
525 /*-----------------------------------------------------------------*/
530 V_ARG (symbol **, sloc);
531 V_ARG (symbol *, fsym);
533 /* if already found */
537 /* if it is free && and the itmp assigned to
538 this does not have any overlapping live ranges
539 with the one currently being assigned and
540 the size can be accomodated */
542 noOverLap (sym->usl.itmpStack, fsym) &&
543 getSize (sym->type) >= getSize (fsym->type))
552 /*-----------------------------------------------------------------*/
553 /* createStackSpil - create a location on the stack to spil */
554 /*-----------------------------------------------------------------*/
556 createStackSpil (symbol * sym)
559 int useXstack, model;
563 fprintf (stderr, " createStackSpil: %s\n", sym->name);
565 /* first go try and find a free one that is already
566 existing on the stack */
567 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
569 /* found a free one : just update & return */
570 sym->usl.spillLoc = sloc;
573 addSetHead (&sloc->usl.itmpStack, sym);
577 /* could not then have to create one , this is the hard part
578 we need to allocate this on the stack : this is really a
579 hack!! but cannot think of anything better at this time */
581 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
583 fprintf (stderr, "***Internal error: slocBuffer overflowed: %s:%d\n",
588 sloc = newiTemp (slocBuffer);
590 /* set the type to the spilling symbol */
591 sloc->type = copyLinkChain (sym->type);
592 sloc->etype = getSpec (sloc->type);
593 SPEC_SCLS (sloc->etype) = S_STACK;
594 SPEC_EXTR (sloc->etype) = 0;
595 SPEC_STAT (sloc->etype) = 0;
596 SPEC_VOLATILE(sloc->etype) = 0;
597 SPEC_ABSA(sloc->etype) = 0;
599 /* we don't allow it to be allocated`
600 onto the external stack since : so we
601 temporarily turn it off ; we also
602 turn off memory model to prevent
603 the spil from going to the external storage
606 useXstack = options.useXstack;
607 model = options.model;
608 /* noOverlay = options.noOverlay; */
609 /* options.noOverlay = 1; */
610 options.model = options.useXstack = 0;
614 options.useXstack = useXstack;
615 options.model = model;
616 /* options.noOverlay = noOverlay; */
617 sloc->isref = 1; /* to prevent compiler warning */
619 /* if it is on the stack then update the stack */
620 if (IN_STACK (sloc->etype))
622 currFunc->stack += getSize (sloc->type);
623 _G.stackExtend += getSize (sloc->type);
626 _G.dataExtend += getSize (sloc->type);
628 /* add it to the _G.stackSpil set */
629 addSetHead (&_G.stackSpil, sloc);
630 sym->usl.spillLoc = sloc;
633 /* add it to the set of itempStack set
634 of the spill location */
635 addSetHead (&sloc->usl.itmpStack, sym);
639 /*-----------------------------------------------------------------*/
640 /* spillThis - spils a specific operand */
641 /*-----------------------------------------------------------------*/
643 spillThis (symbol * sym)
647 fprintf (stderr, " spillThis: %s\n", sym->name);
649 /* if this is rematerializable or has a spillLocation
650 we are okay, else we need to create a spillLocation
652 if (!(sym->remat || sym->usl.spillLoc))
653 createStackSpil (sym);
656 /* mark it has spilt & put it in the spilt set */
657 sym->isspilt = sym->spillA = 1;
658 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
660 bitVectUnSetBit (_G.regAssigned, sym->key);
661 bitVectUnSetBit (_G.totRegAssigned, sym->key);
663 for (i = 0; i < sym->nRegs; i++)
667 freeReg (sym->regs[i], FALSE);
670 if (sym->usl.spillLoc && !sym->remat)
671 sym->usl.spillLoc->allocreq++;
675 /*-----------------------------------------------------------------*/
676 /* selectSpil - select a iTemp to spil : rather a simple procedure */
677 /*-----------------------------------------------------------------*/
679 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
681 bitVect *lrcs = NULL;
685 /* get the spillable live ranges */
686 lrcs = computeSpillable (ic);
688 /* get all live ranges that are rematerizable */
689 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
691 /* return the least used of these */
692 return leastUsedLR (selectS);
695 /* if the symbol is local to the block then */
696 if (forSym->liveTo < ebp->lSeq)
699 /* check if there are any live ranges allocated
700 to registers that are not used in this block */
701 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
703 sym = leastUsedLR (selectS);
704 /* if this is not rematerializable */
713 /* check if there are any live ranges that not
714 used in the remainder of the block */
715 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
717 sym = leastUsedLR (selectS);
730 /* find live ranges with spillocation && not used as pointers */
731 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
734 sym = leastUsedLR (selectS);
735 /* mark this as allocation required */
736 sym->usl.spillLoc->allocreq++;
740 /* find live ranges with spillocation */
741 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
744 sym = leastUsedLR (selectS);
745 sym->usl.spillLoc->allocreq++;
749 /* couldn't find then we need to create a spil
750 location on the stack , for which one? the least
752 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
755 /* return a created spil location */
756 sym = createStackSpil (leastUsedLR (selectS));
757 sym->usl.spillLoc->allocreq++;
761 /* this is an extreme situation we will spill
762 this one : happens very rarely but it does happen */
767 /*-----------------------------------------------------------------*/
768 /* spillSomething - spil some variable & mark registers as free */
769 /*-----------------------------------------------------------------*/
771 spillSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
776 /* get something we can spil */
777 ssym = selectSpil (ic, ebp, forSym);
779 fprintf (stderr, " spillSomething: spilling %s\n", ssym->name);
781 /* mark it as spilt */
782 ssym->isspilt = ssym->spillA = 1;
783 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
785 /* mark it as not register assigned &
786 take it away from the set */
787 bitVectUnSetBit (_G.regAssigned, ssym->key);
788 bitVectUnSetBit (_G.totRegAssigned, ssym->key);
790 /* mark the registers as free */
791 for (i = 0; i < ssym->nRegs; i++) {
793 freeReg (ssym->regs[i], FALSE);
794 // dont NULL ssym->regs[i], it might be used later
798 /* if this was a block level spil then insert push & pop
799 at the start & end of block respectively */
802 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
803 /* add push to the start of the block */
804 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
805 ebp->sch->next : ebp->sch));
806 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
807 /* add pop to the end of the block */
808 addiCodeToeBBlock (ebp, nic, NULL);
811 /* if spilt because not used in the remainder of the
812 block then add a push before this instruction and
813 a pop at the end of the block */
814 if (ssym->remainSpil)
817 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
818 /* add push just before this instruction */
819 addiCodeToeBBlock (ebp, nic, ic);
821 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
822 /* add pop to the end of the block */
823 addiCodeToeBBlock (ebp, nic, NULL);
832 /*-----------------------------------------------------------------*/
833 /* getRegPtr - will try for PTR if not a GPR type if not spil */
834 /*-----------------------------------------------------------------*/
835 static bool getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym, short offset) {
837 fprintf (stderr, "getRegPtr: %s ", sym->name);
838 printTypeChain(sym->type, stderr);
839 fprintf (stderr, "\n");
842 /* try for a ptr type */
843 if (allocReg (getSize(sym->type), REG_PTR, sym, offset, FALSE))
846 /* try for gpr type */
847 if (xa51HasGprRegs && allocReg (getSize(sym->type),
848 REG_GPR, sym, offset, FALSE))
851 /* we have to spil */
852 if (!spillSomething (ic, ebp, sym))
855 /* this looks like an infinite loop but
856 in really selectSpil will abort */
860 /*-----------------------------------------------------------------*/
861 /* getRegGpr - will try for GPR if not spil */
862 /*-----------------------------------------------------------------*/
863 static bool getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym, short offset) {
865 fprintf (stderr, "getRegGpr: %s ", sym->name);
866 printTypeChain(sym->type, stderr);
867 fprintf (stderr, "\n");
870 /* try for gpr type */
871 if (xa51HasGprRegs && allocReg (getSize(sym->type),
872 REG_GPR, sym, offset, FALSE))
875 if (allocReg (getSize(sym->type), REG_PTR, sym, offset, FALSE))
878 /* we have to spil */
879 if (!spillSomething (ic, ebp, sym))
882 /* this looks like an infinite loop but
883 in really selectSpil will abort */
887 /*-----------------------------------------------------------------*/
888 /* deassignLRs - check the live to and if they have registers & are */
889 /* not spilt then free up the registers */
890 /*-----------------------------------------------------------------*/
892 deassignLRs (iCode * ic, eBBlock * ebp)
897 for (sym = hTabFirstItem (liveRanges, &k); sym;
898 sym = hTabNextItem (liveRanges, &k))
900 /* if it does not end here */
901 if (sym->liveTo > ic->seq)
904 /* if it was spilt on stack then we can
905 mark the stack spil location as free */
910 sym->usl.spillLoc->isFree = 1;
916 if (!bitVectBitValue (_G.regAssigned, sym->key))
922 bitVectUnSetBit (_G.regAssigned, sym->key);
925 for (i=0; i < sym->nRegs; i++) {
926 freeReg (sym->regs[i], FALSE);
932 /*-----------------------------------------------------------------*/
933 /* willCauseSpill - determines if allocating will cause a spill */
934 /*-----------------------------------------------------------------*/
935 static bool willCauseSpill (symbol *sym) {
937 // do it the rude way
938 if (allocReg (getSize(sym->type), sym->regType, sym, 0, TRUE) ||
939 allocReg (getSize(sym->type), sym->regType==REG_PTR?REG_GPR:REG_PTR,
941 // so we can, but we won't
942 for (i=0; i<sym->nRegs; i++) {
943 freeReg (sym->regs[i], TRUE);
948 fprintf (stderr, " %s will cause a spill\n", sym->name);
952 /*-----------------------------------------------------------------*/
953 /* positionRegs - the allocator can allocate same registers to res- */
954 /* ult and operand, if this happens make sure they are in the same */
955 /* position as the operand otherwise chaos results */
956 /*-----------------------------------------------------------------*/
958 positionRegs (symbol * result, symbol * opsym)
960 int count = min (result->nRegs, opsym->nRegs);
961 int i, j = 0, shared = 0;
964 /* if the result has been spilt then cannot share */
969 /* first make sure that they actually share */
970 for (i = 0; i < count; i++)
972 for (j = 0; j < count; j++)
974 if (result->regs[i] == opsym->regs[j] && i != j)
984 regs *tmp = result->regs[i];
985 result->regs[i] = result->regs[j];
986 result->regs[j] = tmp;
993 /*-----------------------------------------------------------------*/
994 /* serialRegAssign - serially allocate registers to the variables */
995 /*-----------------------------------------------------------------*/
997 serialRegAssign (eBBlock ** ebbs, int count)
1001 /* for all blocks */
1002 for (i = 0; i < count; i++) {
1006 if (ebbs[i]->noPath &&
1007 (ebbs[i]->entryLabel != entryLabel &&
1008 ebbs[i]->entryLabel != returnLabel))
1011 /* of all instructions do */
1012 for (ic = ebbs[i]->sch; ic; ic = ic->next) {
1014 /* if result is present && is a true symbol */
1015 if (IC_RESULT (ic) && ic->op != IFX &&
1016 IS_TRUE_SYMOP (IC_RESULT (ic)))
1017 OP_SYMBOL (IC_RESULT (ic))->allocreq++;
1019 /* take away registers from live
1020 ranges that end at this instruction */
1021 deassignLRs (ic, ebbs[i]);
1023 /* some don't need registers */
1024 if (SKIP_IC2 (ic) ||
1025 ic->op == JUMPTABLE ||
1029 (IC_RESULT (ic) && POINTER_SET (ic)))
1032 /* now we need to allocate registers
1033 only for the result */
1034 if (IC_RESULT (ic)) {
1035 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
1039 /* if it does not need or is spilt
1040 or is already assigned to registers
1041 or will not live beyond this instructions */
1044 bitVectBitValue (_G.regAssigned, sym->key) ||
1045 sym->liveTo <= ic->seq)
1048 /* if some liverange has been spilt at the block level
1049 and this one live beyond this block then spil this
1051 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq) {
1055 /* if trying to allocate this will cause
1056 a spill and there is nothing to spill
1057 or this one is rematerializable then
1059 willCS = willCauseSpill (sym);
1060 spillable = computeSpillable (ic);
1061 if (sym->remat || (willCS && bitVectIsZero (spillable))) {
1066 /* if it has a spillocation & is used less than
1067 all other live ranges then spill this */
1069 if (sym->usl.spillLoc) {
1070 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
1071 allLRs, ebbs[i], ic));
1072 if (leastUsed && leastUsed->used > sym->used) {
1077 /* if none of the liveRanges have a spillLocation then better
1078 to spill this one than anything else already assigned to registers */
1079 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
1080 /* if this is local to this block then we might find a block spil */
1081 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
1089 /* else we assign registers to it */
1090 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1091 _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key);
1093 if (sym->regType == REG_PTR)
1094 getRegPtr (ic, ebbs[i], sym, 0);
1096 getRegGpr (ic, ebbs[i], sym, 0);
1098 /* if it shares registers with operands make sure
1099 that they are in the same position */
1100 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
1101 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=') {
1102 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1103 OP_SYMBOL (IC_LEFT (ic)));
1105 /* do the same for the right operand */
1106 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
1107 OP_SYMBOL (IC_RIGHT (ic))->nRegs) {
1108 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1109 OP_SYMBOL (IC_RIGHT (ic)));
1116 /*-----------------------------------------------------------------*/
1117 /* rUmaskForOp :- returns register mask for an operand */
1118 /*-----------------------------------------------------------------*/
1119 bitVect *xa51_rUmaskForOp (operand * op) {
1124 /* only temporaries are assigned registers */
1128 sym = OP_SYMBOL (op);
1130 /* if spilt or no registers assigned to it
1132 if (sym->isspilt || !sym->nRegs || !sym->regs[0])
1135 rumask = newBitVect (xa51_nRegs);
1137 for (j = 0; j < sym->nRegs; j++) {
1138 rumask = bitVectSetBit (rumask,
1139 sym->regs[j]->rIdx);
1144 /*-----------------------------------------------------------------*/
1145 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
1146 /*-----------------------------------------------------------------*/
1148 regsUsedIniCode (iCode * ic)
1150 bitVect *rmask = newBitVect (xa51_nRegs);
1152 /* do the special cases first */
1155 rmask = bitVectUnion (rmask,
1156 xa51_rUmaskForOp (IC_COND (ic)));
1160 /* for the jumptable */
1161 if (ic->op == JUMPTABLE)
1163 rmask = bitVectUnion (rmask,
1164 xa51_rUmaskForOp (IC_JTCOND (ic)));
1169 /* of all other cases */
1171 rmask = bitVectUnion (rmask,
1172 xa51_rUmaskForOp (IC_LEFT (ic)));
1176 rmask = bitVectUnion (rmask,
1177 xa51_rUmaskForOp (IC_RIGHT (ic)));
1180 rmask = bitVectUnion (rmask,
1181 xa51_rUmaskForOp (IC_RESULT (ic)));
1187 /*-----------------------------------------------------------------*/
1188 /* createRegMask - for each instruction will determine the regsUsed */
1189 /*-----------------------------------------------------------------*/
1191 createRegMask (eBBlock ** ebbs, int count)
1195 /* for all blocks */
1196 for (i = 0; i < count; i++)
1200 if (ebbs[i]->noPath &&
1201 (ebbs[i]->entryLabel != entryLabel &&
1202 ebbs[i]->entryLabel != returnLabel))
1205 /* for all instructions */
1206 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1211 if (SKIP_IC2 (ic) || !ic->rlive)
1214 /* first mark the registers used in this
1216 ic->rUsed = regsUsedIniCode (ic);
1217 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
1219 /* now create the register mask for those
1220 registers that are in use : this is a
1221 super set of ic->rUsed */
1222 ic->rMask = newBitVect (xa51_nRegs + 1);
1224 /* for all live Ranges alive at this point */
1225 for (j = 1; j < ic->rlive->size; j++)
1230 /* if not alive then continue */
1231 if (!bitVectBitValue (ic->rlive, j))
1234 /* find the live range we are interested in */
1235 if (!(sym = hTabItemWithKey (liveRanges, j)))
1237 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1238 "createRegMask cannot find live range");
1242 /* if no register assigned to it */
1243 if (!sym->nRegs || sym->isspilt)
1246 /* for all the registers allocated to it */
1247 for (k = 0; k < sym->nRegs; k++)
1250 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
1256 /*-----------------------------------------------------------------*/
1257 /* rematStr - returns the rematerialized string for a remat var */
1258 /*-----------------------------------------------------------------*/
1260 rematStr (symbol * sym)
1263 iCode *ic = sym->rematiCode;
1268 /* if plus or minus print the right hand side */
1269 if (ic->op == '+' || ic->op == '-')
1271 sprintf (s, "0x%04x %c ", (int) operandLitValue (IC_RIGHT (ic)),
1274 ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1278 /* cast then continue */
1279 if (IS_CAST_ICODE(ic)) {
1280 ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
1283 /* we reached the end */
1284 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
1291 /*-----------------------------------------------------------------*/
1292 /* regTypeNum - computes the type & number of registers required */
1293 /*-----------------------------------------------------------------*/
1295 regTypeNum (eBBlock *ebbs)
1301 /* for each live range do */
1302 for (sym = hTabFirstItem (liveRanges, &k); sym;
1303 sym = hTabNextItem (liveRanges, &k))
1306 /* if used zero times then no registers needed */
1307 if ((sym->liveTo - sym->liveFrom) == 0)
1311 /* if the live range is a temporary */
1315 /* if the type is marked as a conditional */
1316 if (sym->regType == REG_CND)
1319 /* if used in return only then we don't
1322 if (sym->ruonly || sym->accuse)
1324 if (IS_AGGREGATE (sym->type) || sym->isptr)
1325 sym->type = aggrToPtr (sym->type, FALSE);
1330 /* if the symbol has only one definition &
1331 that definition is a get_pointer and the
1332 pointer we are getting is rematerializable and
1335 if (bitVectnBitsOn (sym->defs) == 1 &&
1336 (ic = hTabItemWithKey (iCodehTab,
1337 bitVectFirstBit (sym->defs))) &&
1340 !IS_BITVAR (sym->etype))
1344 /* if remat in data space */
1345 if (OP_SYMBOL (IC_LEFT (ic))->remat &&
1346 !IS_CAST_ICODE(OP_SYMBOL (IC_LEFT (ic))->rematiCode) &&
1347 DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER)
1349 /* create a psuedo symbol & force a spil */
1350 symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
1351 psym->type = sym->type;
1352 psym->etype = sym->etype;
1353 strcpy (psym->rname, psym->name);
1355 sym->usl.spillLoc = psym;
1356 #if 0 // an alternative fix for bug #480076
1357 /* now this is a useless assignment to itself */
1358 remiCodeFromeBBlock (ebbs, ic);
1360 /* now this really is an assignment to itself, make it so;
1361 it will be optimized out later */
1363 IC_RIGHT(ic)=IC_RESULT(ic);
1369 /* if in data space or idata space then try to
1370 allocate pointer register */
1374 /* if not then we require registers */
1376 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
1377 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1378 getSize (sym->type));
1381 int size=((IS_AGGREGATE (sym->type) || sym->isptr) ?
1382 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1383 getSize (sym->type));
1387 case 2: // word or pointer
1390 case 3: // generic pointer
1393 case 4: // dword or float
1397 fprintf (stderr, "regTypeNum: unknown size\n");
1405 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
1406 printTypeChain (sym->type, stderr);
1407 fprintf (stderr, "\n");
1410 /* determine the type of register required */
1411 if (IS_PTR (sym->type))
1412 sym->regType = REG_PTR;
1414 sym->regType = REG_GPR;
1418 /* for the first run we don't provide */
1419 /* registers for true symbols we will */
1420 /* see how things go */
1426 /*-----------------------------------------------------------------*/
1427 /* deallocStackSpil - this will set the stack pointer back */
1428 /*-----------------------------------------------------------------*/
1430 DEFSETFUNC (deallocStackSpil)
1438 /*-----------------------------------------------------------------*/
1439 /* packRegsForAssign - register reduction for assignment */
1440 /*-----------------------------------------------------------------*/
1442 packRegsForAssign (iCode * ic, eBBlock * ebp)
1446 if (!IS_ITEMP (IC_RIGHT (ic)) ||
1447 OP_LIVETO (IC_RIGHT (ic)) > ic->seq) {
1451 /* find the definition of iTempNN scanning backwards */
1452 for (dic = ic->prev; dic; dic = dic->prev) {
1454 /* if there is a function call then don't pack it */
1455 if ((dic->op == CALL || dic->op == PCALL)) {
1463 if (IS_SYMOP (IC_RESULT (dic)) &&
1464 IC_RESULT (dic)->key == IC_RIGHT (ic)->key) {
1471 return 0; /* did not find */
1473 /* found the definition */
1474 /* replace the result with the result of */
1475 /* this assignment and remove this assignment */
1476 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1477 IC_RESULT (dic) = IC_RESULT (ic);
1479 if (IS_ITEMP (IC_RESULT (dic)) &&
1480 OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
1482 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
1484 /* delete from liverange table also
1485 delete from all the points inbetween and the new
1487 for (sic = dic; sic != ic; sic = sic->next)
1489 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
1490 if (IS_ITEMP (IC_RESULT (dic)))
1491 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
1494 remiCodeFromeBBlock (ebp, ic);
1495 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
1496 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
1497 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
1502 /*-----------------------------------------------------------------*/
1503 /* findAssignToSym : scanning backwards looks for first assig found */
1504 /*-----------------------------------------------------------------*/
1506 findAssignToSym (operand * op, iCode * ic)
1510 for (dic = ic->prev; dic; dic = dic->prev)
1513 /* if definition by assignment */
1514 if (dic->op == '=' &&
1515 !POINTER_SET (dic) &&
1516 IC_RESULT (dic)->key == op->key
1517 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
1521 /* we are interested only if defined in far space */
1522 /* or in stack space in case of + & - */
1524 /* if assigned to a non-symbol then return
1526 if (!IS_SYMOP (IC_RIGHT (dic)))
1529 /* if the symbol is in far space then
1531 if (isOperandInFarSpace (IC_RIGHT (dic)))
1534 /* for + & - operations make sure that
1535 if it is on the stack it is the same
1536 as one of the three operands */
1537 if ((ic->op == '+' || ic->op == '-') &&
1538 OP_SYMBOL (IC_RIGHT (dic))->onStack)
1541 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
1542 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
1543 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
1551 /* if we find an usage then we cannot delete it */
1552 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
1555 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
1558 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
1562 /* now make sure that the right side of dic
1563 is not defined between ic & dic */
1566 iCode *sic = dic->next;
1568 for (; sic != ic; sic = sic->next)
1569 if (IC_RESULT (sic) &&
1570 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
1579 /*-----------------------------------------------------------------*/
1580 /* packRegsForSupport :- reduce some registers for support calls */
1581 /*-----------------------------------------------------------------*/
1583 packRegsForSupport (iCode * ic, eBBlock * ebp)
1588 /* for the left & right operand :- look to see if the
1589 left was assigned a true symbol in far space in that
1590 case replace them */
1592 if (IS_ITEMP (IC_LEFT (ic)) &&
1593 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
1595 dic = findAssignToSym (IC_LEFT (ic), ic);
1600 /* found it we need to remove it from the
1602 for (sic = dic; sic != ic; sic = sic->next)
1603 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
1605 OP_SYMBOL(IC_LEFT (ic))=OP_SYMBOL(IC_RIGHT (dic));
1606 IC_LEFT (ic)->key = OP_SYMBOL(IC_RIGHT (dic))->key;
1607 remiCodeFromeBBlock (ebp, dic);
1608 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1609 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1613 /* do the same for the right operand */
1616 IS_ITEMP (IC_RIGHT (ic)) &&
1617 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
1619 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
1625 /* if this is a subtraction & the result
1626 is a true symbol in far space then don't pack */
1627 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
1629 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
1630 if (IN_FARSPACE (SPEC_OCLS (etype)))
1633 /* found it we need to remove it from the
1635 for (sic = dic; sic != ic; sic = sic->next)
1636 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
1638 IC_RIGHT (ic)->operand.symOperand =
1639 IC_RIGHT (dic)->operand.symOperand;
1640 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
1642 remiCodeFromeBBlock (ebp, dic);
1643 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1644 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1651 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
1654 /*-----------------------------------------------------------------*/
1655 /* packRegsForOneuse : - will reduce some registers for single Use */
1656 /*-----------------------------------------------------------------*/
1658 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
1663 /* if returning a literal then do nothing */
1667 if (ic->op != RETURN &&
1669 !POINTER_SET (ic) &&
1673 /* this routine will mark the a symbol as used in one
1674 instruction use only && if the defintion is local
1675 (ie. within the basic block) && has only one definition &&
1676 that definiion is either a return value from a
1677 function or does not contain any variables in
1679 uses = bitVectCopy (OP_USES (op));
1680 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
1681 if (!bitVectIsZero (uses)) /* has other uses */
1684 /* if it has only one defintion */
1685 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
1686 return NULL; /* has more than one definition */
1688 /* get that definition */
1690 hTabItemWithKey (iCodehTab,
1691 bitVectFirstBit (OP_DEFS (op)))))
1694 /* if that only usage is a cast */
1695 if (dic->op == CAST) {
1696 /* to a bigger type */
1697 if (getSize(OP_SYM_TYPE(IC_RESULT(dic))) >
1698 getSize(OP_SYM_TYPE(IC_RIGHT(dic)))) {
1699 /* than we can not, since we cannot predict the usage of b & acc */
1704 /* found the definition now check if it is local */
1705 if (dic->seq < ebp->fSeq ||
1706 dic->seq > ebp->lSeq)
1707 return NULL; /* non-local */
1709 /* now check if it is the return from
1711 if (dic->op == CALL || dic->op == PCALL)
1713 if (ic->op != SEND && ic->op != RETURN &&
1714 !POINTER_SET(ic) && !POINTER_GET(ic))
1716 OP_SYMBOL (op)->ruonly = 1;
1723 /* otherwise check that the definition does
1724 not contain any symbols in far space */
1725 if (isOperandInFarSpace (IC_LEFT (dic)) ||
1726 isOperandInFarSpace (IC_RIGHT (dic)) ||
1727 IS_OP_RUONLY (IC_LEFT (ic)) ||
1728 IS_OP_RUONLY (IC_RIGHT (ic)))
1733 /* if pointer set then make sure the pointer
1735 if (POINTER_SET (dic) &&
1736 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
1739 if (POINTER_GET (dic) &&
1740 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
1745 /* also make sure the intervenening instructions
1746 don't have any thing in far space */
1747 for (dic = dic->next; dic && dic != ic && sic != ic; dic = dic->next)
1750 /* if there is an intervening function call then no */
1751 if (dic->op == CALL || dic->op == PCALL)
1753 /* if pointer set then make sure the pointer
1755 if (POINTER_SET (dic) &&
1756 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
1759 if (POINTER_GET (dic) &&
1760 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
1763 /* if address of & the result is remat the okay */
1764 if (dic->op == ADDRESS_OF &&
1765 OP_SYMBOL (IC_RESULT (dic))->remat)
1768 /* if operand has size of three or more & this
1769 operation is a '*','/' or '%' then 'b' may
1771 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
1772 getSize (operandType (op)) >= 3)
1775 /* if left or right or result is in far space */
1776 if (isOperandInFarSpace (IC_LEFT (dic)) ||
1777 isOperandInFarSpace (IC_RIGHT (dic)) ||
1778 isOperandInFarSpace (IC_RESULT (dic)) ||
1779 IS_OP_RUONLY (IC_LEFT (dic)) ||
1780 IS_OP_RUONLY (IC_RIGHT (dic)) ||
1781 IS_OP_RUONLY (IC_RESULT (dic)))
1785 /* if left or right or result is on stack */
1786 if (isOperandOnStack(IC_LEFT(dic)) ||
1787 isOperandOnStack(IC_RIGHT(dic)) ||
1788 isOperandOnStack(IC_RESULT(dic))) {
1793 OP_SYMBOL (op)->ruonly = 1;
1798 /*-----------------------------------------------------------------*/
1799 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
1800 /*-----------------------------------------------------------------*/
1802 isBitwiseOptimizable (iCode * ic)
1804 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
1805 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
1807 /* bitwise operations are considered optimizable
1808 under the following conditions (Jean-Louis VERN)
1820 if (IS_LITERAL(rtype) ||
1821 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
1827 /*-----------------------------------------------------------------*/
1828 /* packForPush - hueristics to reduce iCode for pushing */
1829 /*-----------------------------------------------------------------*/
1831 packForPush (iCode * ic, eBBlock * ebp)
1836 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
1839 /* must have only definition & one usage */
1840 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
1841 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
1844 /* find the definition */
1845 if (!(dic = hTabItemWithKey (iCodehTab,
1846 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
1849 if (dic->op != '=' || POINTER_SET (dic))
1852 /* make sure the right side does not have any definitions
1854 dbv = OP_DEFS(IC_RIGHT(dic));
1855 for (lic = ic; lic && lic != dic ; lic = lic->prev) {
1856 if (bitVectBitValue(dbv,lic->key))
1859 /* make sure they have the same type */
1861 sym_link *itype=operandType(IC_LEFT(ic));
1862 sym_link *ditype=operandType(IC_RIGHT(dic));
1864 if (SPEC_USIGN(itype)!=SPEC_USIGN(ditype) ||
1865 SPEC_LONG(itype)!=SPEC_LONG(ditype))
1868 /* extend the live range of replaced operand if needed */
1869 if (OP_SYMBOL(IC_RIGHT(dic))->liveTo < ic->seq) {
1870 OP_SYMBOL(IC_RIGHT(dic))->liveTo = ic->seq;
1872 /* we now know that it has one & only one def & use
1873 and the that the definition is an assignment */
1874 IC_LEFT (ic) = IC_RIGHT (dic);
1876 remiCodeFromeBBlock (ebp, dic);
1877 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
1878 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
1881 /*-----------------------------------------------------------------*/
1882 /* packRegisters - does some transformations to reduce register */
1884 /*-----------------------------------------------------------------*/
1885 static void packRegisters (eBBlock * ebp) {
1892 for (ic = ebp->sch; ic; ic = ic->next) {
1894 change += packRegsForAssign (ic, ebp);
1900 return; // that's it for now
1902 for (ic = ebp->sch; ic; ic = ic->next)
1904 /* if this is an itemp & result of an address of a true sym
1905 then mark this as rematerialisable */
1906 if (ic->op == ADDRESS_OF &&
1907 IS_ITEMP (IC_RESULT (ic)) &&
1908 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
1909 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
1910 !OP_SYMBOL (IC_LEFT (ic))->onStack)
1913 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
1914 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
1915 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
1919 /* if straight assignment then carry remat flag if
1920 this is the only definition */
1921 if (ic->op == '=' &&
1922 !POINTER_SET (ic) &&
1923 IS_SYMOP (IC_RIGHT (ic)) &&
1924 OP_SYMBOL (IC_RIGHT (ic))->remat &&
1925 !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode) &&
1926 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
1929 OP_SYMBOL (IC_RESULT (ic))->remat =
1930 OP_SYMBOL (IC_RIGHT (ic))->remat;
1931 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
1932 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
1935 /* if cast to a generic pointer & the pointer being
1936 cast is remat, then we can remat this cast as well */
1937 if (ic->op == CAST &&
1938 IS_SYMOP(IC_RIGHT(ic)) &&
1939 OP_SYMBOL(IC_RIGHT(ic))->remat ) {
1940 sym_link *to_type = operandType(IC_LEFT(ic));
1941 sym_link *from_type = operandType(IC_RIGHT(ic));
1942 if (IS_GENPTR(to_type) && IS_PTR(from_type)) {
1943 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
1944 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
1945 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
1949 /* if this is a +/- operation with a rematerizable
1950 then mark this as rematerializable as well */
1951 if ((ic->op == '+' || ic->op == '-') &&
1952 (IS_SYMOP (IC_LEFT (ic)) &&
1953 IS_ITEMP (IC_RESULT (ic)) &&
1954 IS_OP_LITERAL (IC_RIGHT (ic))) &&
1955 OP_SYMBOL (IC_LEFT (ic))->remat &&
1956 (!IS_SYMOP (IC_RIGHT (ic)) || !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode)) &&
1957 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1)
1959 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
1960 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
1961 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
1964 /* mark the pointer usages */
1965 if (POINTER_SET (ic))
1966 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
1968 if (POINTER_GET (ic))
1969 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
1971 /* if the condition of an if instruction
1972 is defined in the previous instruction and
1973 this is the only usage then
1974 mark the itemp as a conditional */
1975 if ((IS_CONDITIONAL (ic) ||
1976 (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic))) &&
1977 ic->next && ic->next->op == IFX &&
1978 bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
1979 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
1980 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
1982 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
1986 /* reduce for support function calls */
1987 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
1988 packRegsForSupport (ic, ebp);
1990 /* some cases the redundant moves can
1991 can be eliminated for return statements */
1992 if ((ic->op == RETURN || ic->op == SEND) &&
1993 !isOperandInFarSpace (IC_LEFT (ic)) &&
1994 options.model == MODEL_SMALL) {
1995 if (0 && options.stackAuto) {
1996 /* we should check here if acc will be clobbered for stack
1997 offset calculations */
1999 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2003 /* if pointer set & left has a size more than
2004 one and right is not in far space */
2005 if (POINTER_SET (ic) &&
2006 !isOperandInFarSpace (IC_RIGHT (ic)) &&
2007 !OP_SYMBOL (IC_RESULT (ic))->remat &&
2008 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
2009 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
2011 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
2013 /* if pointer get */
2014 if (POINTER_GET (ic) &&
2015 !isOperandInFarSpace (IC_RESULT (ic)) &&
2016 !OP_SYMBOL (IC_LEFT (ic))->remat &&
2017 !IS_OP_RUONLY (IC_RESULT (ic)) &&
2018 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
2020 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2023 /* if this is cast for intergral promotion then
2024 check if only use of the definition of the
2025 operand being casted/ if yes then replace
2026 the result of that arithmetic operation with
2027 this result and get rid of the cast */
2030 sym_link *fromType = operandType (IC_RIGHT (ic));
2031 sym_link *toType = operandType (IC_LEFT (ic));
2033 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
2034 getSize (fromType) != getSize (toType) &&
2035 SPEC_USIGN (fromType) == SPEC_USIGN (toType))
2038 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2041 if (IS_ARITHMETIC_OP (dic))
2043 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2044 IC_RESULT (dic) = IC_RESULT (ic);
2045 remiCodeFromeBBlock (ebp, ic);
2046 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2047 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2048 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2052 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
2058 /* if the type from and type to are the same
2059 then if this is the only use then packit */
2060 if (compareType (operandType (IC_RIGHT (ic)),
2061 operandType (IC_LEFT (ic))) == 1)
2063 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2066 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2067 IC_RESULT (dic) = IC_RESULT (ic);
2068 remiCodeFromeBBlock (ebp, ic);
2069 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2070 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2071 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2079 iTempNN := (some variable in farspace) V1
2084 if (ic->op == IPUSH)
2086 packForPush (ic, ebp);
2091 /*-----------------------------------------------------------------*/
2092 /* assignRegisters - assigns registers to each live range as need */
2093 /*-----------------------------------------------------------------*/
2095 xa51_assignRegisters (eBBlock ** ebbs, int count)
2100 setToNull ((void *) &_G.funcrUsed);
2101 setToNull ((void *) &_G.totRegAssigned);
2102 _G.stackExtend = _G.dataExtend = 0;
2104 /* change assignments this will remove some
2105 live ranges reducing some register pressure */
2106 for (i = 0; i < count; i++)
2107 packRegisters (ebbs[i]);
2109 if (options.dump_pack)
2110 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
2112 /* first determine for each live range the number of
2113 registers & the type of registers required for each */
2116 /* and serially allocate registers */
2117 serialRegAssign (ebbs, count);
2121 /* if stack was extended then tell the user */
2124 /* werror(W_TOOMANY_SPILS,"stack", */
2125 /* _G.stackExtend,currFunc->name,""); */
2131 /* werror(W_TOOMANY_SPILS,"data space", */
2132 /* _G.dataExtend,currFunc->name,""); */
2136 /* after that create the register mask
2137 for each of the instruction */
2138 createRegMask (ebbs, count);
2140 /* redo that offsets for stacked automatic variables */
2141 redoStackOffsets ();
2143 if (options.dump_rassgn)
2145 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
2146 dumpLiveRanges (DUMP_LRANGE, liveRanges);
2149 /* do the overlaysegment stuff SDCCmem.c */
2150 doOverlays (ebbs, count);
2152 /* now get back the chain */
2153 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
2157 /* free up any _G.stackSpil locations allocated */
2158 applyToSet (_G.stackSpil, deallocStackSpil);
2160 setToNull ((void **) &_G.stackSpil);
2161 setToNull ((void **) &_G.spiltSet);
2162 /* mark all registers as free */