1 /*------------------------------------------------------------------------
3 SDCCralloc.c - source file for register allocation. (8051) 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 genhc08Code (iCode *);
48 bitVect *totRegAssigned; /* final set of LRs that got into registers */
51 bitVect *funcrUsed; /* registers used in a function */
57 /* Shared with gen.c */
58 int hc08_ptrRegReq; /* one byte pointer register required */
64 {REG_GPR, A_IDX, REG_GPR, "a", "a", "0", 1, NULL, 0, 1},
65 {REG_GPR, X_IDX, REG_GPR, "x", "x", "0", 2, NULL, 0, 1},
66 {REG_GPR, H_IDX, REG_GPR, "h", "h", "0", 4, NULL, 0, 1},
67 {REG_PTR, HX_IDX, REG_PTR, "hx", "hx", "0", 6, NULL, 0, 1},
68 {REG_GPR, XA_IDX, REG_GPR, "xa", "xa", "0", 3, NULL, 0, 1},
70 {REG_CND, CND_IDX, REG_CND, "C", "C", "xreg", 0, NULL, 0, 1},
80 static void spillThis (symbol *);
81 static void freeAllRegs ();
83 /*-----------------------------------------------------------------*/
84 /* allocReg - allocates register of given type */
85 /*-----------------------------------------------------------------*/
91 if ((type==REG_PTR) && (regshc08[HX_IDX].isFree))
93 regshc08[HX_IDX].isFree = 0;
96 bitVectSetBit (currFunc->regsUsed, HX_IDX);
97 return ®shc08[HX_IDX];
102 /*-----------------------------------------------------------------*/
103 /* hc08_regWithIdx - returns pointer to register wit index number */
104 /*-----------------------------------------------------------------*/
106 hc08_regWithIdx (int idx)
110 for (i = 0; i < hc08_nRegs; i++)
111 if (regshc08[i].rIdx == idx)
114 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
115 "regWithIdx not found");
119 /*-----------------------------------------------------------------*/
120 /* hc08_freeReg - frees a register */
121 /*-----------------------------------------------------------------*/
123 hc08_freeReg (regs * reg)
127 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
128 "hc08_freeReg - Freeing NULL register");
137 if (hc08_reg_x->isFree)
138 hc08_reg_xa->isFree = 1;
141 if (hc08_reg_a->isFree)
142 hc08_reg_xa->isFree = 1;
143 if (hc08_reg_h->isFree)
144 hc08_reg_hx->isFree = 1;
147 if (hc08_reg_x->isFree)
148 hc08_reg_hx->isFree = 1;
151 hc08_reg_h->isFree = 1;
152 hc08_reg_x->isFree = 1;
153 if (hc08_reg_a->isFree)
154 hc08_reg_xa->isFree = 1;
157 hc08_reg_x->isFree = 1;
158 hc08_reg_a->isFree = 1;
159 if (hc08_reg_h->isFree)
160 hc08_reg_hx->isFree = 1;
168 /*-----------------------------------------------------------------*/
169 /* nFreeRegs - returns number of free registers */
170 /*-----------------------------------------------------------------*/
179 for (i = 0; i < hc08_nRegs; i++)
180 if (regshc08[i].isFree && regshc08[i].type == type)
185 /*-----------------------------------------------------------------*/
186 /* nfreeRegsType - free registers with type */
187 /*-----------------------------------------------------------------*/
189 nfreeRegsType (int type)
194 if ((nfr = nFreeRegs (type)) == 0)
195 return nFreeRegs (REG_GPR);
198 return nFreeRegs (type);
201 /*-----------------------------------------------------------------*/
202 /* hc08_useReg - marks a register as used */
203 /*-----------------------------------------------------------------*/
205 hc08_useReg (regs * reg)
212 hc08_reg_xa->aop = NULL;
213 hc08_reg_xa->isFree = 0;
216 hc08_reg_xa->aop = NULL;
217 hc08_reg_xa->isFree = 0;
218 hc08_reg_hx->aop = NULL;
219 hc08_reg_hx->isFree = 0;
222 hc08_reg_hx->aop = NULL;
223 hc08_reg_hx->isFree = 0;
226 hc08_reg_h->aop = NULL;
227 hc08_reg_h->isFree = 0;
228 hc08_reg_x->aop = NULL;
229 hc08_reg_x->isFree = 0;
232 hc08_reg_x->aop = NULL;
233 hc08_reg_x->isFree = 0;
234 hc08_reg_a->aop = NULL;
235 hc08_reg_a->isFree = 0;
243 /*-----------------------------------------------------------------*/
244 /* hc08_dirtyReg - marks a register as dirty */
245 /*-----------------------------------------------------------------*/
247 hc08_dirtyReg (regs * reg, bool freereg)
254 hc08_reg_xa->aop = NULL;
257 hc08_reg_xa->aop = NULL;
258 hc08_reg_hx->aop = NULL;
261 hc08_reg_hx->aop = NULL;
264 hc08_reg_h->aop = NULL;
265 hc08_reg_x->aop = NULL;
268 hc08_reg_x->aop = NULL;
269 hc08_reg_a->aop = NULL;
278 /*-----------------------------------------------------------------*/
279 /* computeSpillable - given a point find the spillable live ranges */
280 /*-----------------------------------------------------------------*/
282 computeSpillable (iCode * ic)
286 /* spillable live ranges are those that are live at this
287 point . the following categories need to be subtracted
289 a) - those that are already spilt
290 b) - if being used by this one
291 c) - defined by this one */
293 spillable = bitVectCopy (ic->rlive);
295 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
297 bitVectCplAnd (spillable, ic->uses); /* used in this one */
298 bitVectUnSetBit (spillable, ic->defKey);
299 spillable = bitVectIntersect (spillable, _G.regAssigned);
304 /*-----------------------------------------------------------------*/
305 /* noSpilLoc - return true if a variable has no spil location */
306 /*-----------------------------------------------------------------*/
308 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
310 return (sym->usl.spillLoc ? 0 : 1);
313 /*-----------------------------------------------------------------*/
314 /* hasSpilLoc - will return 1 if the symbol has spil location */
315 /*-----------------------------------------------------------------*/
317 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
319 return (sym->usl.spillLoc ? 1 : 0);
322 /*-----------------------------------------------------------------*/
323 /* directSpilLoc - will return 1 if the splilocation is in direct */
324 /*-----------------------------------------------------------------*/
326 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
328 if (sym->usl.spillLoc &&
329 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
335 /*-----------------------------------------------------------------*/
336 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
337 /* but is not used as a pointer */
338 /*-----------------------------------------------------------------*/
340 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
342 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
345 /*-----------------------------------------------------------------*/
346 /* rematable - will return 1 if the remat flag is set */
347 /*-----------------------------------------------------------------*/
349 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
354 /*-----------------------------------------------------------------*/
355 /* notUsedInRemaining - not used or defined in remain of the block */
356 /*-----------------------------------------------------------------*/
358 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
360 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
361 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
364 /*-----------------------------------------------------------------*/
365 /* allLRs - return true for all */
366 /*-----------------------------------------------------------------*/
368 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
373 /*-----------------------------------------------------------------*/
374 /* liveRangesWith - applies function to a given set of live range */
375 /*-----------------------------------------------------------------*/
377 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
378 eBBlock * ebp, iCode * ic)
383 if (!lrs || !lrs->size)
386 for (i = 1; i < lrs->size; i++)
389 if (!bitVectBitValue (lrs, i))
392 /* if we don't find it in the live range
393 hash table we are in serious trouble */
394 if (!(sym = hTabItemWithKey (liveRanges, i)))
396 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
397 "liveRangesWith could not find liveRange");
401 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
402 addSetHead (&rset, sym);
409 /*-----------------------------------------------------------------*/
410 /* leastUsedLR - given a set determines which is the least used */
411 /*-----------------------------------------------------------------*/
413 leastUsedLR (set * sset)
415 symbol *sym = NULL, *lsym = NULL;
417 sym = lsym = setFirstItem (sset);
422 for (; lsym; lsym = setNextItem (sset))
425 /* if usage is the same then prefer
426 the spill the smaller of the two */
427 if (lsym->used == sym->used)
428 if (getSize (lsym->type) < getSize (sym->type))
432 if (lsym->used < sym->used)
437 setToNull ((void *) &sset);
442 /*-----------------------------------------------------------------*/
443 /* noOverLap - will iterate through the list looking for over lap */
444 /*-----------------------------------------------------------------*/
446 noOverLap (set * itmpStack, symbol * fsym)
451 for (sym = setFirstItem (itmpStack); sym;
452 sym = setNextItem (itmpStack))
454 if (bitVectBitValue(sym->clashes,fsym->key)) return 0;
460 /*-----------------------------------------------------------------*/
461 /* isFree - will return 1 if the a free spil location is found */
462 /*-----------------------------------------------------------------*/
467 V_ARG (symbol **, sloc);
468 V_ARG (symbol *, fsym);
470 /* if already found */
474 /* if it is free && and the itmp assigned to
475 this does not have any overlapping live ranges
476 with the one currently being assigned and
477 the size can be accomodated */
479 noOverLap (sym->usl.itmpStack, fsym) &&
480 getSize (sym->type) >= getSize (fsym->type))
489 /*-----------------------------------------------------------------*/
490 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
491 /*-----------------------------------------------------------------*/
493 spillLRWithPtrReg (symbol * forSym)
499 if (!_G.regAssigned ||
500 bitVectIsZero (_G.regAssigned))
503 hx = hc08_regWithIdx (HX_IDX);
505 /* for all live ranges */
506 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
507 lrsym = hTabNextItem (liveRanges, &k))
511 /* if no registers assigned to it or spilt */
512 /* if it does not overlap with this then
513 not need to spill it */
515 if (lrsym->isspilt || !lrsym->nRegs ||
516 (lrsym->liveTo < forSym->liveFrom))
519 /* go thru the registers : if it is either
520 r0 or r1 then spil it */
521 for (j = 0; j < lrsym->nRegs; j++)
522 if (lrsym->regs[j] == hx)
531 /*-----------------------------------------------------------------*/
532 /* createStackSpil - create a location on the stack to spil */
533 /*-----------------------------------------------------------------*/
535 createStackSpil (symbol * sym)
538 int useXstack, model;
542 /* first go try and find a free one that is already
543 existing on the stack */
544 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
546 /* found a free one : just update & return */
547 sym->usl.spillLoc = sloc;
550 addSetHead (&sloc->usl.itmpStack, sym);
554 /* could not then have to create one , this is the hard part
555 we need to allocate this on the stack : this is really a
556 hack!! but cannot think of anything better at this time */
558 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
560 fprintf (stderr, "***Internal error: slocBuffer overflowed: %s:%d\n",
565 sloc = newiTemp (slocBuffer);
567 /* set the type to the spilling symbol */
568 sloc->type = copyLinkChain (sym->type);
569 sloc->etype = getSpec (sloc->type);
570 SPEC_SCLS (sloc->etype) = S_DATA;
571 SPEC_EXTR (sloc->etype) = 0;
572 SPEC_STAT (sloc->etype) = 0;
573 SPEC_VOLATILE(sloc->etype) = 0;
574 SPEC_ABSA(sloc->etype) = 0;
576 /* we don't allow it to be allocated`
577 onto the external stack since : so we
578 temporarily turn it off ; we also
579 turn off memory model to prevent
580 the spil from going to the external storage
583 useXstack = options.useXstack;
584 model = options.model;
585 /* noOverlay = options.noOverlay; */
586 /* options.noOverlay = 1; */
587 options.model = options.useXstack = 0;
591 options.useXstack = useXstack;
592 options.model = model;
593 /* options.noOverlay = noOverlay; */
594 sloc->isref = 1; /* to prevent compiler warning */
596 /* if it is on the stack then update the stack */
597 if (IN_STACK (sloc->etype))
599 currFunc->stack += getSize (sloc->type);
600 _G.stackExtend += getSize (sloc->type);
603 _G.dataExtend += getSize (sloc->type);
605 /* add it to the _G.stackSpil set */
606 addSetHead (&_G.stackSpil, sloc);
607 sym->usl.spillLoc = sloc;
610 /* add it to the set of itempStack set
611 of the spill location */
612 addSetHead (&sloc->usl.itmpStack, sym);
616 /*-----------------------------------------------------------------*/
617 /* isSpiltOnStack - returns true if the spil location is on stack */
618 /*-----------------------------------------------------------------*/
620 isSpiltOnStack (symbol * sym)
630 /* if (sym->_G.stackSpil) */
633 if (!sym->usl.spillLoc)
636 etype = getSpec (sym->usl.spillLoc->type);
637 if (IN_STACK (etype))
643 /*-----------------------------------------------------------------*/
644 /* spillThis - spils a specific operand */
645 /*-----------------------------------------------------------------*/
647 spillThis (symbol * sym)
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);
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 hc08_freeReg (sym->regs[i]);
671 /* if spilt on stack then free up r0 & r1
672 if they could have been assigned to some
674 // if (!hc08_ptrRegReq && isSpiltOnStack (sym))
677 // spillLRWithPtrReg (sym);
680 if (sym->usl.spillLoc && !sym->remat)
681 sym->usl.spillLoc->allocreq++;
685 /*-----------------------------------------------------------------*/
686 /* selectSpil - select a iTemp to spil : rather a simple procedure */
687 /*-----------------------------------------------------------------*/
689 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
691 bitVect *lrcs = NULL;
695 /* get the spillable live ranges */
696 lrcs = computeSpillable (ic);
698 /* get all live ranges that are rematerizable */
699 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
702 /* return the least used of these */
703 return leastUsedLR (selectS);
706 /* get live ranges with spillLocations in direct space */
707 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
709 sym = leastUsedLR (selectS);
710 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
711 sym->usl.spillLoc->rname :
712 sym->usl.spillLoc->name));
714 /* mark it as allocation required */
715 sym->usl.spillLoc->allocreq++;
719 /* if the symbol is local to the block then */
720 if (forSym->liveTo < ebp->lSeq)
723 /* check if there are any live ranges allocated
724 to registers that are not used in this block */
725 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
727 sym = leastUsedLR (selectS);
728 /* if this is not rematerializable */
737 /* check if there are any live ranges that not
738 used in the remainder of the block */
739 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
741 sym = leastUsedLR (selectS);
754 /* find live ranges with spillocation && not used as pointers */
755 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
758 sym = leastUsedLR (selectS);
759 /* mark this as allocation required */
760 sym->usl.spillLoc->allocreq++;
764 /* find live ranges with spillocation */
765 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
768 sym = leastUsedLR (selectS);
769 sym->usl.spillLoc->allocreq++;
773 /* couldn't find then we need to create a spil
774 location on the stack , for which one? the least
776 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
779 /* return a created spil location */
780 sym = createStackSpil (leastUsedLR (selectS));
781 sym->usl.spillLoc->allocreq++;
785 /* this is an extreme situation we will spill
786 this one : happens very rarely but it does happen */
792 /*-----------------------------------------------------------------*/
793 /* spilSomething - spil some variable & mark registers as free */
794 /*-----------------------------------------------------------------*/
796 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
801 /* get something we can spil */
802 ssym = selectSpil (ic, ebp, forSym);
804 /* mark it as spilt */
805 ssym->isspilt = ssym->spillA = 1;
806 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
808 /* mark it as not register assigned &
809 take it away from the set */
810 bitVectUnSetBit (_G.regAssigned, ssym->key);
811 bitVectUnSetBit (_G.totRegAssigned, ssym->key);
813 /* mark the registers as free */
814 for (i = 0; i < ssym->nRegs; i++)
816 hc08_freeReg (ssym->regs[i]);
818 /* if spilt on stack then free up hx
819 if it could have been assigned to as gprs */
820 if (!hc08_ptrRegReq && isSpiltOnStack (ssym))
823 spillLRWithPtrReg (ssym);
826 /* if this was a block level spil then insert push & pop
827 at the start & end of block respectively */
830 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
831 /* add push to the start of the block */
832 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
833 ebp->sch->next : ebp->sch));
834 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
835 /* add pop to the end of the block */
836 addiCodeToeBBlock (ebp, nic, NULL);
839 /* if spilt because not used in the remainder of the
840 block then add a push before this instruction and
841 a pop at the end of the block */
842 if (ssym->remainSpil)
845 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
846 /* add push just before this instruction */
847 addiCodeToeBBlock (ebp, nic, ic);
849 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
850 /* add pop to the end of the block */
851 addiCodeToeBBlock (ebp, nic, NULL);
860 /*-----------------------------------------------------------------*/
861 /* getRegPtr - will try for PTR if not a GPR type if not spil */
862 /*-----------------------------------------------------------------*/
864 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
869 /* try for a ptr type */
870 if ((reg = allocReg (REG_PTR)))
873 /* try for gpr type */
874 if ((reg = allocReg (REG_GPR)))
877 /* we have to spil */
878 if (!spilSomething (ic, ebp, sym))
881 /* this looks like an infinite loop but
882 in really selectSpil will abort */
886 /*-----------------------------------------------------------------*/
887 /* getRegGpr - will try for GPR if not spil */
888 /*-----------------------------------------------------------------*/
890 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
895 /* try for gpr type */
896 if ((reg = allocReg (REG_GPR)))
900 if ((reg = allocReg (REG_PTR)))
903 /* we have to spil */
904 if (!spilSomething (ic, ebp, sym))
907 /* this looks like an infinite loop but
908 in really selectSpil will abort */
912 /*-----------------------------------------------------------------*/
913 /* getRegPtrNoSpil - get it cannot split */
914 /*-----------------------------------------------------------------*/
915 static regs *getRegPtrNoSpil()
919 /* try for a ptr type */
920 if ((reg = allocReg (REG_PTR)))
923 /* try for gpr type */
924 if ((reg = allocReg (REG_GPR)))
929 /* just to make the compiler happy */
933 /*-----------------------------------------------------------------*/
934 /* getRegGprNoSpil - get it cannot split */
935 /*-----------------------------------------------------------------*/
936 static regs *getRegGprNoSpil()
940 if ((reg = allocReg (REG_GPR)))
944 if ((reg = allocReg (REG_PTR)))
949 /* just to make the compiler happy */
953 /*-----------------------------------------------------------------*/
954 /* symHasReg - symbol has a given register */
955 /*-----------------------------------------------------------------*/
957 symHasReg (symbol * sym, regs * reg)
961 for (i = 0; i < sym->nRegs; i++)
962 if (sym->regs[i] == reg)
968 /*-----------------------------------------------------------------*/
969 /* deassignLRs - check the live to and if they have registers & are */
970 /* not spilt then free up the registers */
971 /*-----------------------------------------------------------------*/
973 deassignLRs (iCode * ic, eBBlock * ebp)
979 for (sym = hTabFirstItem (liveRanges, &k); sym;
980 sym = hTabNextItem (liveRanges, &k))
984 /* if it does not end here */
985 if (sym->liveTo > ic->seq)
988 /* if it was spilt on stack then we can
989 mark the stack spil location as free */
994 sym->usl.spillLoc->isFree = 1;
1000 if (!bitVectBitValue (_G.regAssigned, sym->key))
1003 /* special case check if this is an IFX &
1004 the privious one was a pop and the
1005 previous one was not spilt then keep track
1007 if (ic->op == IFX && ic->prev &&
1008 ic->prev->op == IPOP &&
1009 !ic->prev->parmPush &&
1010 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1011 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1017 bitVectUnSetBit (_G.regAssigned, sym->key);
1019 /* if the result of this one needs registers
1020 and does not have it then assign it right
1022 if (IC_RESULT (ic) &&
1023 !(SKIP_IC2 (ic) || /* not a special icode */
1024 ic->op == JUMPTABLE ||
1029 POINTER_SET (ic)) &&
1030 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1031 result->liveTo > ic->seq && /* and will live beyond this */
1032 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1033 result->regType == sym->regType && /* same register types */
1034 result->nRegs && /* which needs registers */
1035 !result->isspilt && /* and does not already have them */
1037 !bitVectBitValue (_G.regAssigned, result->key) &&
1038 /* the number of free regs + number of regs in this LR
1039 can accomodate the what result Needs */
1040 ((nfreeRegsType (result->regType) +
1041 sym->nRegs) >= result->nRegs)
1045 for (i = 0; i < result->nRegs; i++)
1047 result->regs[i] = sym->regs[i];
1049 result->regs[i] = getRegGpr (ic, ebp, result);
1051 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1052 _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, result->key);
1056 /* free the remaining */
1057 for (; i < sym->nRegs; i++)
1061 if (!symHasReg (psym, sym->regs[i]))
1062 hc08_freeReg (sym->regs[i]);
1065 hc08_freeReg (sym->regs[i]);
1072 /*-----------------------------------------------------------------*/
1073 /* reassignLR - reassign this to registers */
1074 /*-----------------------------------------------------------------*/
1076 reassignLR (operand * op)
1078 symbol *sym = OP_SYMBOL (op);
1081 /* not spilt any more */
1082 sym->isspilt = sym->spillA = sym->blockSpil = sym->remainSpil = 0;
1083 bitVectUnSetBit (_G.spiltSet, sym->key);
1085 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1086 _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key);
1090 for (i = 0; i < sym->nRegs; i++)
1091 sym->regs[i]->isFree = 0;
1094 /*-----------------------------------------------------------------*/
1095 /* willCauseSpill - determines if allocating will cause a spill */
1096 /*-----------------------------------------------------------------*/
1098 willCauseSpill (int nr, int rt)
1100 /* first check if there are any avlb registers
1101 of te type required */
1104 /* special case for pointer type
1105 if pointer type not avlb then
1106 check for type gpr */
1107 if (nFreeRegs (rt) >= nr)
1109 if (nFreeRegs (REG_GPR) >= nr)
1116 if (nFreeRegs (rt) >= nr)
1121 if (nFreeRegs (REG_PTR) +
1122 nFreeRegs (REG_GPR) >= nr)
1127 /* it will cause a spil */
1131 /*-----------------------------------------------------------------*/
1132 /* positionRegs - the allocator can allocate same registers to res- */
1133 /* ult and operand, if this happens make sure they are in the same */
1134 /* position as the operand otherwise chaos results */
1135 /*-----------------------------------------------------------------*/
1137 positionRegs (symbol * result, symbol * opsym)
1139 int count = min (result->nRegs, opsym->nRegs);
1140 int i, j = 0, shared = 0;
1143 /* if the result has been spilt then cannot share */
1148 /* first make sure that they actually share */
1149 for (i = 0; i < count; i++)
1151 for (j = 0; j < count; j++)
1153 if (result->regs[i] == opsym->regs[j] && i != j)
1163 regs *tmp = result->regs[i];
1164 result->regs[i] = result->regs[j];
1165 result->regs[j] = tmp;
1172 /*------------------------------------------------------------------*/
1173 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
1174 /* it should either have registers or have beed spilled. Otherwise, */
1175 /* there was an uninitialized variable, so just spill this to get */
1176 /* the operand in a valid state. */
1177 /*------------------------------------------------------------------*/
1179 verifyRegsAssigned (operand *op, iCode * ic)
1184 if (!IS_ITEMP (op)) return;
1186 sym = OP_SYMBOL (op);
1187 if (sym->isspilt) return;
1188 if (!sym->nRegs) return;
1189 if (sym->regs[0]) return;
1191 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
1192 sym->prereqv ? sym->prereqv->name : sym->name);
1198 /*-----------------------------------------------------------------*/
1199 /* serialRegAssign - serially allocate registers to the variables */
1200 /*-----------------------------------------------------------------*/
1202 serialRegAssign (eBBlock ** ebbs, int count)
1206 /* for all blocks */
1207 for (i = 0; i < count; i++) {
1211 if (ebbs[i]->noPath &&
1212 (ebbs[i]->entryLabel != entryLabel &&
1213 ebbs[i]->entryLabel != returnLabel))
1216 /* of all instructions do */
1217 for (ic = ebbs[i]->sch; ic; ic = ic->next) {
1221 // update the registers in use at the start of this icode
1222 for (reg=0; reg<hc08_nRegs; reg++) {
1223 if (regshc08[reg].isFree) {
1224 ic->riu &= ~(regshc08[reg].mask);
1226 ic->riu |= (regshc08[reg].mask);
1231 /* if this is an ipop that means some live
1232 range will have to be assigned again */
1234 reassignLR (IC_LEFT (ic));
1236 /* if result is present && is a true symbol */
1237 if (IC_RESULT (ic) && ic->op != IFX &&
1238 IS_TRUE_SYMOP (IC_RESULT (ic)))
1239 OP_SYMBOL (IC_RESULT (ic))->allocreq++;
1241 /* take away registers from live
1242 ranges that end at this instruction */
1243 deassignLRs (ic, ebbs[i]);
1245 /* some don't need registers */
1246 if (SKIP_IC2 (ic) ||
1247 ic->op == JUMPTABLE ||
1251 (IC_RESULT (ic) && POINTER_SET (ic)))
1254 /* now we need to allocate registers
1255 only for the result */
1256 if (IC_RESULT (ic)) {
1257 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
1263 /* if it does not need or is spilt
1264 or is already assigned to registers
1265 or will not live beyond this instructions */
1268 bitVectBitValue (_G.regAssigned, sym->key) ||
1269 sym->liveTo <= ic->seq)
1272 /* if some liverange has been spilt at the block level
1273 and this one live beyond this block then spil this
1275 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq) {
1279 /* if trying to allocate this will cause
1280 a spill and there is nothing to spill
1281 or this one is rematerializable then
1283 willCS = willCauseSpill (sym->nRegs, sym->regType);
1284 spillable = computeSpillable (ic);
1285 if (sym->remat || (willCS && bitVectIsZero (spillable))) {
1290 /* if it has a spillocation & is used less than
1291 all other live ranges then spill this */
1293 if (sym->usl.spillLoc) {
1294 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
1295 allLRs, ebbs[i], ic));
1296 if (leastUsed && leastUsed->used > sym->used) {
1301 /* if none of the liveRanges have a spillLocation then better
1302 to spill this one than anything else already assigned to registers */
1303 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
1304 /* if this is local to this block then we might find a block spil */
1305 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
1312 /* if we need ptr regs for the right side
1314 if (POINTER_GET (ic) && IS_SYMOP (IC_LEFT (ic))
1315 && getSize (OP_SYMBOL (IC_LEFT (ic))->type) <= (unsigned int) PTRSIZE) {
1319 /* else we assign registers to it */
1320 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1321 _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key);
1323 for (j = 0; j < sym->nRegs; j++) {
1324 if (sym->regType == REG_PTR)
1325 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
1327 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
1329 /* if the allocation failed which means
1330 this was spilt then break */
1331 if (!sym->regs[j]) {
1336 /* if it shares registers with operands make sure
1337 that they are in the same position */
1338 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
1339 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=') {
1340 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1341 OP_SYMBOL (IC_LEFT (ic)));
1343 /* do the same for the right operand */
1344 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
1345 OP_SYMBOL (IC_RIGHT (ic))->nRegs) {
1346 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1347 OP_SYMBOL (IC_RIGHT (ic)));
1359 /* Check for and fix any problems with uninitialized operands */
1360 for (i = 0; i < count; i++)
1364 if (ebbs[i]->noPath &&
1365 (ebbs[i]->entryLabel != entryLabel &&
1366 ebbs[i]->entryLabel != returnLabel))
1369 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1376 verifyRegsAssigned (IC_COND (ic), ic);
1380 if (ic->op == JUMPTABLE)
1382 verifyRegsAssigned (IC_JTCOND (ic), ic);
1386 verifyRegsAssigned (IC_RESULT (ic), ic);
1387 verifyRegsAssigned (IC_LEFT (ic), ic);
1388 verifyRegsAssigned (IC_RIGHT (ic), ic);
1394 /*-----------------------------------------------------------------*/
1395 /* fillGaps - Try to fill in the Gaps left by Pass1 */
1396 /*-----------------------------------------------------------------*/
1397 static void fillGaps()
1402 if (getenv("DISABLE_FILL_GAPS")) return;
1404 /* look for livernages that was spilt by the allocator */
1405 for (sym = hTabFirstItem(liveRanges,&key) ; sym ;
1406 sym = hTabNextItem(liveRanges,&key)) {
1411 if (!sym->spillA || !sym->clashes || sym->remat) continue ;
1413 /* find the liveRanges this one clashes with, that are
1414 still assigned to registers & mark the registers as used*/
1415 for ( i = 0 ; i < sym->clashes->size ; i ++) {
1419 if (bitVectBitValue(sym->clashes,i) == 0 || /* those that clash with this */
1420 bitVectBitValue(_G.totRegAssigned,i) == 0) /* and are still assigned to registers */
1423 clr = hTabItemWithKey(liveRanges,i);
1426 /* mark these registers as used */
1427 for (k = 0 ; k < clr->nRegs ; k++ )
1428 hc08_useReg(clr->regs[k]);
1431 if (willCauseSpill(sym->nRegs,sym->regType)) {
1432 /* NOPE :( clear all registers & and continue */
1437 /* THERE IS HOPE !!!! */
1438 for (i=0; i < sym->nRegs ; i++ ) {
1439 if (sym->regType == REG_PTR)
1440 sym->regs[i] = getRegPtrNoSpil ();
1442 sym->regs[i] = getRegGprNoSpil ();
1445 /* for all its definitions check if the registers
1446 allocated needs positioning NOTE: we can position
1447 only ONCE if more than One positioning required
1450 for (i = 0 ; i < sym->defs->size ; i++ ) {
1451 if (bitVectBitValue(sym->defs,i)) {
1453 if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
1454 if (SKIP_IC(ic)) continue;
1455 assert(isSymbolEqual(sym,OP_SYMBOL(IC_RESULT(ic)))); /* just making sure */
1456 /* if left is assigned to registers */
1457 if (IS_SYMOP(IC_LEFT(ic)) &&
1458 bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_LEFT(ic))->key)) {
1459 pdone += positionRegs(sym,OP_SYMBOL(IC_LEFT(ic)));
1461 if (IS_SYMOP(IC_RIGHT(ic)) &&
1462 bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RIGHT(ic))->key)) {
1463 pdone += positionRegs(sym,OP_SYMBOL(IC_RIGHT(ic)));
1465 if (pdone > 1) break;
1468 for (i = 0 ; i < sym->uses->size ; i++ ) {
1469 if (bitVectBitValue(sym->uses,i)) {
1471 if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
1472 if (SKIP_IC(ic)) continue;
1473 if (!IS_ASSIGN_ICODE(ic)) continue ;
1475 /* if result is assigned to registers */
1476 if (IS_SYMOP(IC_RESULT(ic)) &&
1477 bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RESULT(ic))->key)) {
1478 pdone += positionRegs(sym,OP_SYMBOL(IC_RESULT(ic)));
1480 if (pdone > 1) break;
1483 /* had to position more than once GIVE UP */
1485 /* UNDO all the changes we made to try this */
1487 for (i=0; i < sym->nRegs ; i++ ) {
1488 sym->regs[i] = NULL;
1491 D(printf ("Fill Gap gave up due to positioning for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN"));
1494 D(printf ("FILLED GAP for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN"));
1495 _G.totRegAssigned = bitVectSetBit(_G.totRegAssigned,sym->key);
1496 sym->isspilt = sym->spillA = 0 ;
1497 sym->usl.spillLoc->allocreq--;
1502 /*-----------------------------------------------------------------*/
1503 /* rUmaskForOp :- returns register mask for an operand */
1504 /*-----------------------------------------------------------------*/
1506 hc08_rUmaskForOp (operand * op)
1512 /* only temporaries are assigned registers */
1516 sym = OP_SYMBOL (op);
1518 /* if spilt or no registers assigned to it
1520 if (sym->isspilt || !sym->nRegs)
1523 rumask = newBitVect (hc08_nRegs);
1525 for (j = 0; j < sym->nRegs; j++)
1527 rumask = bitVectSetBit (rumask,
1528 sym->regs[j]->rIdx);
1534 /*-----------------------------------------------------------------*/
1535 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
1536 /*-----------------------------------------------------------------*/
1538 regsUsedIniCode (iCode * ic)
1540 bitVect *rmask = newBitVect (hc08_nRegs);
1542 /* do the special cases first */
1545 rmask = bitVectUnion (rmask,
1546 hc08_rUmaskForOp (IC_COND (ic)));
1550 /* for the jumptable */
1551 if (ic->op == JUMPTABLE)
1553 rmask = bitVectUnion (rmask,
1554 hc08_rUmaskForOp (IC_JTCOND (ic)));
1559 /* of all other cases */
1561 rmask = bitVectUnion (rmask,
1562 hc08_rUmaskForOp (IC_LEFT (ic)));
1566 rmask = bitVectUnion (rmask,
1567 hc08_rUmaskForOp (IC_RIGHT (ic)));
1570 rmask = bitVectUnion (rmask,
1571 hc08_rUmaskForOp (IC_RESULT (ic)));
1577 /*-----------------------------------------------------------------*/
1578 /* createRegMask - for each instruction will determine the regsUsed */
1579 /*-----------------------------------------------------------------*/
1581 createRegMask (eBBlock ** ebbs, int count)
1585 /* for all blocks */
1586 for (i = 0; i < count; i++)
1590 if (ebbs[i]->noPath &&
1591 (ebbs[i]->entryLabel != entryLabel &&
1592 ebbs[i]->entryLabel != returnLabel))
1595 /* for all instructions */
1596 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1601 if (SKIP_IC2 (ic) || !ic->rlive)
1604 /* first mark the registers used in this
1606 ic->rUsed = regsUsedIniCode (ic);
1607 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
1609 /* now create the register mask for those
1610 registers that are in use : this is a
1611 super set of ic->rUsed */
1612 ic->rMask = newBitVect (hc08_nRegs + 1);
1614 /* for all live Ranges alive at this point */
1615 for (j = 1; j < ic->rlive->size; j++)
1620 /* if not alive then continue */
1621 if (!bitVectBitValue (ic->rlive, j))
1624 /* find the live range we are interested in */
1625 if (!(sym = hTabItemWithKey (liveRanges, j)))
1627 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1628 "createRegMask cannot find live range");
1629 fprintf(stderr, "\tmissing live range: key=%d\n", j);
1633 /* if no register assigned to it */
1634 if (!sym->nRegs || sym->isspilt)
1637 /* for all the registers allocated to it */
1638 for (k = 0; k < sym->nRegs; k++)
1641 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
1647 /*-----------------------------------------------------------------*/
1648 /* rematStr - returns the rematerialized string for a remat var */
1649 /*-----------------------------------------------------------------*/
1651 rematStr (symbol * sym)
1654 iCode *ic = sym->rematiCode;
1659 /* if plus or minus print the right hand side */
1660 if (ic->op == '+' || ic->op == '-')
1662 sprintf (s, "0x%04x %c ", (int) operandLitValue (IC_RIGHT (ic)),
1665 ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1672 offset += operandLitValue (IC_RIGHT (ic));
1673 ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1678 offset -= operandLitValue (IC_RIGHT (ic));
1679 ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1683 /* cast then continue */
1684 if (IS_CAST_ICODE(ic)) {
1685 ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
1688 /* we reached the end */
1689 if (ic->op == ADDRESS_OF)
1690 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
1691 else if (ic->op == '=')
1692 sprintf (s, "0x%04x", (int) operandLitValue (IC_RIGHT (ic)) );
1699 /*-----------------------------------------------------------------*/
1700 /* regTypeNum - computes the type & number of registers required */
1701 /*-----------------------------------------------------------------*/
1703 regTypeNum (eBBlock *ebbs)
1709 /* for each live range do */
1710 for (sym = hTabFirstItem (liveRanges, &k); sym;
1711 sym = hTabNextItem (liveRanges, &k))
1714 /* if used zero times then no registers needed */
1715 if ((sym->liveTo - sym->liveFrom) == 0)
1719 /* if the live range is a temporary */
1723 /* if the type is marked as a conditional */
1724 if (sym->regType == REG_CND)
1727 /* if used in return only then we don't
1729 if (sym->ruonly || sym->accuse)
1731 if (IS_AGGREGATE (sym->type) || sym->isptr)
1732 sym->type = aggrToPtr (sym->type, FALSE);
1736 /* if the symbol has only one definition &
1737 that definition is a get_pointer */
1738 if (bitVectnBitsOn (sym->defs) == 1 &&
1739 (ic = hTabItemWithKey (iCodehTab,
1740 bitVectFirstBit (sym->defs))) &&
1743 !IS_BITVAR (sym->etype))
1747 /* and that pointer is remat in data space */
1748 if (IS_SYMOP (IC_LEFT (ic)) &&
1749 OP_SYMBOL (IC_LEFT (ic))->remat &&
1750 !IS_CAST_ICODE(OP_SYMBOL (IC_LEFT (ic))->rematiCode) &&
1751 DCL_TYPE (aggrToPtr (operandType(IC_LEFT(ic)), FALSE)) == POINTER)
1753 /* create a psuedo symbol & force a spil */
1754 symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
1755 psym->type = sym->type;
1756 psym->etype = sym->etype;
1757 strcpy (psym->rname, psym->name);
1759 sym->usl.spillLoc = psym;
1760 #if 0 // an alternative fix for bug #480076
1761 /* now this is a useless assignment to itself */
1762 remiCodeFromeBBlock (ebbs, ic);
1764 /* now this really is an assignment to itself, make it so;
1765 it will be optimized out later */
1767 ReplaceOpWithCheaperOp(&IC_RIGHT(ic), IC_RESULT(ic));
1773 /* if in data space or idata space then try to
1774 allocate pointer register */
1778 /* if not then we require registers */
1779 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
1780 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1781 getSize (sym->type));
1785 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
1786 printTypeChain (sym->type, stderr);
1787 fprintf (stderr, "\n");
1790 /* determine the type of register required */
1791 if (sym->nRegs == 1 &&
1792 IS_PTR (sym->type) &&
1794 sym->regType = REG_PTR;
1796 sym->regType = REG_GPR;
1800 /* for the first run we don't provide */
1801 /* registers for true symbols we will */
1802 /* see how things go */
1808 /*-----------------------------------------------------------------*/
1809 /* freeAllRegs - mark all registers as free */
1810 /*-----------------------------------------------------------------*/
1816 for (i = 0; i < hc08_nRegs; i++) {
1817 regshc08[i].isFree = 1;
1818 regshc08[i].aop = NULL;
1822 /*-----------------------------------------------------------------*/
1823 /* deallocStackSpil - this will set the stack pointer back */
1824 /*-----------------------------------------------------------------*/
1826 DEFSETFUNC (deallocStackSpil)
1835 /*-----------------------------------------------------------------*/
1836 /* farSpacePackable - returns the packable icode for far variables */
1837 /*-----------------------------------------------------------------*/
1839 farSpacePackable (iCode * ic)
1843 /* go thru till we find a definition for the
1844 symbol on the right */
1845 for (dic = ic->prev; dic; dic = dic->prev)
1847 /* if the definition is a call then no */
1848 if ((dic->op == CALL || dic->op == PCALL) &&
1849 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1854 /* if shift by unknown amount then not */
1855 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
1856 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1860 /* if pointer get and size > 1 */
1861 if (POINTER_GET (dic) &&
1862 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
1865 if (POINTER_SET (dic) &&
1866 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
1870 /* if any three is a true symbol in far space */
1871 if (IC_RESULT (dic) &&
1872 IS_TRUE_SYMOP (IC_RESULT (dic)) /* &&
1873 isOperandInFarSpace (IC_RESULT (dic)) */)
1876 if (IC_RIGHT (dic) &&
1877 IS_TRUE_SYMOP (IC_RIGHT (dic)) /* &&
1878 isOperandInFarSpace (IC_RIGHT (dic)) */ &&
1879 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
1882 if (IC_LEFT (dic) &&
1883 IS_TRUE_SYMOP (IC_LEFT (dic)) /* &&
1884 isOperandInFarSpace (IC_LEFT (dic)) */ &&
1885 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
1888 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
1890 if ((dic->op == LEFT_OP ||
1891 dic->op == RIGHT_OP ||
1893 IS_OP_LITERAL (IC_RIGHT (dic)))
1906 packRegsForLiteral (iCode * ic)
1913 if (POINTER_SET (ic))
1915 if (!IS_LITERAL (getSpec (operandType (IC_RIGHT (ic)))))
1917 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
1920 for (k=0; k< OP_USES (IC_RESULT (ic))->size; k++)
1921 if (bitVectBitValue (OP_USES (IC_RESULT (ic)), k))
1923 uic = hTabItemWithKey (iCodehTab, k);
1926 if (uic->op != IFX && uic->op != JUMPTABLE)
1928 if (IC_LEFT (uic) && IC_LEFT (uic)->key == IC_RESULT (ic)->key)
1929 ReplaceOpWithCheaperOp(&IC_LEFT(uic), IC_RIGHT(ic));
1930 if (IC_RIGHT (uic) && IC_RIGHT (uic)->key == IC_RESULT (ic)->key)
1931 ReplaceOpWithCheaperOp(&IC_RIGHT(uic), IC_RIGHT(ic));
1932 if (IC_RESULT (uic) && IC_RESULT (uic)->key == IC_RESULT (ic)->key)
1933 ReplaceOpWithCheaperOp(&IC_RESULT(uic), IC_RIGHT(ic));
1941 /*-----------------------------------------------------------------*/
1942 /* packRegsForAssign - register reduction for assignment */
1943 /*-----------------------------------------------------------------*/
1945 packRegsForAssign (iCode * ic, eBBlock * ebp)
1949 if (!IS_ITEMP (IC_RIGHT (ic)) ||
1950 OP_SYMBOL (IC_RIGHT (ic))->isind ||
1951 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
1957 /* if the true symbol is defined in far space or on stack
1958 then we should not since this will increase register pressure */
1960 if (isOperandInFarSpace(IC_RESULT(ic)) && !farSpacePackable(ic)) {
1965 /* find the definition of iTempNN scanning backwards if we find a
1966 a use of the true symbol in before we find the definition then
1968 for (dic = ic->prev; dic; dic = dic->prev)
1971 #if 0 /* jwk: This collides with 1.43 but I really see no need for
1972 this anymore. It fixes bug #716790 and substantially improves
1973 redundant register usage around function calls.
1976 /* if there is a function call then don't pack it */
1977 if ((dic->op == CALL || dic->op == PCALL))
1987 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
1988 IS_OP_VOLATILE (IC_RESULT (dic)))
1994 if (IS_SYMOP (IC_RESULT (dic)) &&
1995 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1997 if (POINTER_SET (dic))
2003 if (IS_SYMOP (IC_RIGHT (dic)) &&
2004 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2005 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2011 if (IS_SYMOP (IC_LEFT (dic)) &&
2012 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2013 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2019 if (POINTER_SET (dic) &&
2020 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2028 return 0; /* did not find */
2030 /* if assignment then check that right is not a bit */
2031 if (ASSIGNMENT (dic) && !POINTER_SET (dic))
2033 sym_link *etype = operandType (IC_RIGHT (dic));
2034 if (IS_BITFIELD (etype))
2036 /* if result is a bit too then it's ok */
2037 etype = operandType (IC_RESULT (dic));
2038 if (!IS_BITFIELD (etype))
2042 /* if the result is on stack or iaccess then it must be
2043 the same atleast one of the operands */
2044 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2045 OP_SYMBOL (IC_RESULT (ic))->iaccess)
2048 /* the operation has only one symbol
2049 operator then we can pack */
2050 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2051 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2054 if (!((IC_LEFT (dic) &&
2055 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2057 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2061 /* found the definition */
2062 /* replace the result with the result of */
2063 /* this assignment and remove this assignment */
2064 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2065 ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
2067 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2069 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2071 // TODO: and the otherway around?
2073 /* delete from liverange table also
2074 delete from all the points inbetween and the new
2076 for (sic = dic; sic != ic; sic = sic->next)
2078 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2079 if (IS_ITEMP (IC_RESULT (dic)))
2080 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2083 remiCodeFromeBBlock (ebp, ic);
2084 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2085 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2086 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2091 /*------------------------------------------------------------------*/
2092 /* findAssignToSym : scanning backwards looks for first assig found */
2093 /*------------------------------------------------------------------*/
2095 findAssignToSym (operand * op, iCode * ic)
2099 /* This routine is used to find sequences like
2101 ...; (intervening ops don't use iTempAA or modify FOO)
2102 blah = blah + iTempAA;
2104 and eliminate the use of iTempAA, freeing up its register for
2109 for (dic = ic->prev; dic; dic = dic->prev)
2112 /* if definition by assignment */
2113 if (dic->op == '=' &&
2114 !POINTER_SET (dic) &&
2115 IC_RESULT (dic)->key == op->key
2116 && IS_TRUE_SYMOP(IC_RIGHT(dic))
2118 break; /* found where this temp was defined */
2120 /* if we find an usage then we cannot delete it */
2121 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2124 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2127 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2132 return NULL; /* didn't find any assignment to op */
2134 /* we are interested only if defined in far space */
2135 /* or in stack space in case of + & - */
2137 /* if assigned to a non-symbol then don't repack regs */
2138 if (!IS_SYMOP (IC_RIGHT (dic)))
2141 /* if the symbol is volatile then we should not */
2142 if (isOperandVolatile (IC_RIGHT (dic), TRUE))
2144 /* XXX TODO --- should we be passing FALSE to isOperandVolatile()?
2145 What does it mean for an iTemp to be volatile, anyway? Passing
2146 TRUE is more cautious but may prevent possible optimizations */
2148 /* if the symbol is in far space then we should not */
2149 /* if (isOperandInFarSpace (IC_RIGHT (dic)))
2152 /* for + & - operations make sure that
2153 if it is on the stack it is the same
2154 as one of the three operands */
2156 if ((ic->op == '+' || ic->op == '-') &&
2157 OP_SYMBOL (IC_RIGHT (dic))->onStack)
2160 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2161 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2162 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2167 /* now make sure that the right side of dic
2168 is not defined between ic & dic */
2171 iCode *sic = dic->next;
2173 for (; sic != ic; sic = sic->next)
2174 if (IC_RESULT (sic) &&
2175 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2182 /*-----------------------------------------------------------------*/
2183 /* reassignAliasedSym - used by packRegsForSupport to replace */
2184 /* redundant iTemp with equivalent symbol */
2185 /*-----------------------------------------------------------------*/
2187 reassignAliasedSym (eBBlock *ebp, iCode *assignment, iCode *use, operand *op)
2190 unsigned oldSymKey, newSymKey;
2192 oldSymKey = op->key;
2193 newSymKey = IC_RIGHT(assignment)->key;
2195 /* only track live ranges of compiler-generated temporaries */
2196 if (!IS_ITEMP(IC_RIGHT(assignment)))
2199 /* update the live-value bitmaps */
2200 for (ic = assignment; ic != use; ic = ic->next) {
2201 bitVectUnSetBit (ic->rlive, oldSymKey);
2203 ic->rlive = bitVectSetBit (ic->rlive, newSymKey);
2206 /* update the sym of the used operand */
2207 OP_SYMBOL(op) = OP_SYMBOL(IC_RIGHT(assignment));
2208 op->key = OP_SYMBOL(op)->key;
2210 /* update the sym's liverange */
2211 if ( OP_LIVETO(op) < ic->seq )
2212 setToRange(op, ic->seq, FALSE);
2214 /* remove the assignment iCode now that its result is unused */
2215 remiCodeFromeBBlock (ebp, assignment);
2216 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(assignment))->defs, assignment->key);
2217 hTabDeleteItem (&iCodehTab, assignment->key, assignment, DELETE_ITEM, NULL);
2221 /*-----------------------------------------------------------------*/
2222 /* packRegsForSupport :- reduce some registers for support calls */
2223 /*-----------------------------------------------------------------*/
2225 packRegsForSupport (iCode * ic, eBBlock * ebp)
2230 /* for the left & right operand :- look to see if the
2231 left was assigned a true symbol in far space in that
2232 case replace them */
2234 if (IS_ITEMP (IC_LEFT (ic)) &&
2235 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2237 dic = findAssignToSym (IC_LEFT (ic), ic);
2241 /* found it we need to remove it from the block */
2242 reassignAliasedSym (ebp, dic, ic, IC_LEFT(ic));
2247 /* do the same for the right operand */
2248 if (IS_ITEMP (IC_RIGHT (ic)) &&
2249 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2251 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2255 /* found it we need to remove it from the block */
2256 reassignAliasedSym (ebp, dic, ic, IC_RIGHT(ic));
2264 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
2268 /*-----------------------------------------------------------------*/
2269 /* packRegsForOneuse : - will reduce some registers for single Use */
2270 /*-----------------------------------------------------------------*/
2272 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
2277 /* if returning a literal then do nothing */
2281 /* only up to 2 bytes */
2282 if (getSize (operandType (op)) > (fReturnSizeHC08 - 2))
2287 if (ic->op != SEND //RETURN
2289 && !POINTER_SET (ic)
2290 && !POINTER_GET (ic) )
2293 if (ic->op == SEND && ic->argreg != 1) return NULL;
2295 /* this routine will mark the a symbol as used in one
2296 instruction use only && if the defintion is local
2297 (ie. within the basic block) && has only one definition &&
2298 that definiion is either a return value from a
2299 function or does not contain any variables in
2301 uses = bitVectCopy (OP_USES (op));
2302 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
2303 if (!bitVectIsZero (uses)) /* has other uses */
2306 /* if it has only one defintion */
2307 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
2308 return NULL; /* has more than one definition */
2310 /* get that definition */
2312 hTabItemWithKey (iCodehTab,
2313 bitVectFirstBit (OP_DEFS (op)))))
2316 /* if that only usage is a cast */
2317 if (dic->op == CAST) {
2318 /* to a bigger type */
2319 if (getSize(OP_SYM_TYPE(IC_RESULT(dic))) >
2320 getSize(OP_SYM_TYPE(IC_RIGHT(dic)))) {
2321 /* than we can not, since we cannot predict the usage of b & acc */
2326 /* found the definition now check if it is local */
2327 if (dic->seq < ebp->fSeq ||
2328 dic->seq > ebp->lSeq)
2329 return NULL; /* non-local */
2331 /* now check if it is the return from
2333 if (dic->op == CALL || dic->op == PCALL)
2335 if (ic->op != SEND && ic->op != RETURN &&
2336 !POINTER_SET(ic) && !POINTER_GET(ic))
2338 OP_SYMBOL (op)->ruonly = 1;
2345 /* otherwise check that the definition does
2346 not contain any symbols in far space */
2347 // if (isOperandInFarSpace (IC_LEFT (dic)) ||
2348 // isOperandInFarSpace (IC_RIGHT (dic)) ||
2349 // IS_OP_RUONLY (IC_LEFT (ic)) ||
2350 // IS_OP_RUONLY (IC_RIGHT (ic)))
2355 /* if pointer set then make sure the pointer
2358 if (POINTER_SET (dic) &&
2359 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2362 if (POINTER_GET (dic) &&
2363 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2369 /* also make sure the intervenening instructions
2370 don't have any thing in far space */
2371 for (dic = dic->next; dic && dic != ic && sic != ic; dic = dic->next)
2374 /* if there is an intervening function call then no */
2375 if (dic->op == CALL || dic->op == PCALL)
2377 /* if pointer set then make sure the pointer
2380 if (POINTER_SET (dic) &&
2381 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2384 if (POINTER_GET (dic) &&
2385 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2388 /* if address of & the result is remat the okay */
2389 if (dic->op == ADDRESS_OF &&
2390 OP_SYMBOL (IC_RESULT (dic))->remat)
2393 /* if operand has size of three or more & this
2394 operation is a '*','/' or '%' then 'b' may
2397 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
2398 getSize (operandType (op)) >= 3)
2402 /* if left or right or result is in far space */
2403 // if (isOperandInFarSpace (IC_LEFT (dic)) ||
2404 // isOperandInFarSpace (IC_RIGHT (dic)) ||
2405 // isOperandInFarSpace (IC_RESULT (dic)) ||
2406 // IS_OP_RUONLY (IC_LEFT (dic)) ||
2407 // IS_OP_RUONLY (IC_RIGHT (dic)) ||
2408 // IS_OP_RUONLY (IC_RESULT (dic)))
2412 // /* if left or right or result is on stack */
2413 // if (isOperandOnStack(IC_LEFT(dic)) ||
2414 // isOperandOnStack(IC_RIGHT(dic)) ||
2415 // isOperandOnStack(IC_RESULT(dic))) {
2420 OP_SYMBOL (op)->ruonly = 1;
2425 /*-----------------------------------------------------------------*/
2426 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
2427 /*-----------------------------------------------------------------*/
2429 isBitwiseOptimizable (iCode * ic)
2431 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
2432 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
2434 /* bitwise operations are considered optimizable
2435 under the following conditions (Jean-Louis VERN)
2447 if (IS_LITERAL(rtype) ||
2448 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
2454 /*-----------------------------------------------------------------*/
2455 /* isCommutativeOp - tests whether this op cares what order its */
2456 /* operands are in */
2457 /*-----------------------------------------------------------------*/
2458 bool isCommutativeOp2(unsigned int op)
2460 if (op == '+' || op == '*' || op == EQ_OP ||
2461 op == '^' || op == '|' || op == BITWISEAND)
2467 /*-----------------------------------------------------------------*/
2468 /* operandUsesAcc2 - determines whether the code generated for this */
2469 /* operand will have to use the accumulator */
2470 /*-----------------------------------------------------------------*/
2471 bool operandUsesAcc2(operand *op)
2477 symbol *sym = OP_SYMBOL(op);
2481 return TRUE; /* duh! */
2483 // if (IN_STACK(sym->etype) || sym->onStack ||
2484 // (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
2485 // return TRUE; /* acc is used to calc stack offset */
2490 sym = SPIL_LOC(op); /* if spilled, look at spill location */
2492 return FALSE; /* more checks? */
2496 symspace = SPEC_OCLS(sym->etype);
2498 // if (sym->iaccess && symspace->paged)
2499 // return TRUE; /* must fetch paged indirect sym via accumulator */
2501 if (IN_BITSPACE(symspace))
2502 return TRUE; /* fetching bit vars uses the accumulator */
2504 if (IN_FARSPACE(symspace) || IN_CODESPACE(symspace))
2505 return TRUE; /* fetched via accumulator and dptr */
2511 /*-----------------------------------------------------------------*/
2512 /* packRegsForAccUse - pack registers for acc use */
2513 /*-----------------------------------------------------------------*/
2515 packRegsForAccUse (iCode * ic)
2519 /* if this is an aggregate, e.g. a one byte char array */
2520 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
2524 /* if we are calling a reentrant function that has stack parameters */
2526 if (ic->op == CALL &&
2527 IFFUNC_ISREENT(operandType(IC_LEFT(ic))) &&
2528 FUNC_HASSTACKPARM(operandType(IC_LEFT(ic))))
2531 if (ic->op == PCALL &&
2532 IFFUNC_ISREENT(operandType(IC_LEFT(ic))->next) &&
2533 FUNC_HASSTACKPARM(operandType(IC_LEFT(ic))->next))
2537 /* if + or - then it has to be one byte result */
2538 if ((ic->op == '+' || ic->op == '-')
2539 && getSize (operandType (IC_RESULT (ic))) > 1)
2543 /* if shift operation make sure right side is a literal */
2544 if (ic->op == RIGHT_OP &&
2545 (!isOperandLiteral (IC_RIGHT (ic)) ||
2546 (getSize (operandType (IC_RESULT (ic) )) > 1)))
2549 if (ic->op == LEFT_OP &&
2550 (!isOperandLiteral (IC_RIGHT (ic)) ||
2551 (getSize (operandType (IC_RESULT (ic) )) > 1)))
2554 if (IS_BITWISE_OP (ic) &&
2555 getSize (operandType (IC_RESULT (ic))) > 1)
2559 /* has only one definition */
2560 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
2563 /* has only one use */
2564 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
2567 /* and the usage immediately follows this iCode */
2568 if (!(uic = hTabItemWithKey (iCodehTab,
2569 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
2572 if (ic->next != uic)
2575 /* if it is a conditional branch then we definitely can */
2579 if (uic->op == JUMPTABLE)
2583 if (POINTER_SET (uic) &&
2584 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
2588 /* if the usage is not is an assignment
2589 or an arithmetic / bitwise / shift operation then not */
2590 if (uic->op != '=' &&
2591 !IS_ARITHMETIC_OP (uic) &&
2592 !IS_BITWISE_OP (uic) &&
2593 (uic->op != LEFT_OP) &&
2594 (uic->op != RIGHT_OP) &&
2595 (uic->op != GETHBIT) &&
2596 (uic->op != RETURN) &&
2602 /* if used in ^ operation then make sure right is not a
2603 literal (WIML: Why is this?) */
2604 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
2607 /* if shift operation make sure right side is not a literal */
2608 /* WIML: Why is this? */
2609 if (uic->op == RIGHT_OP &&
2610 (isOperandLiteral (IC_RIGHT (uic)) ||
2611 getSize (operandType (IC_RESULT (uic))) > 1))
2613 if (uic->op == LEFT_OP &&
2614 (isOperandLiteral (IC_RIGHT (uic)) ||
2615 getSize (operandType (IC_RESULT (uic))) > 1))
2619 /* make sure that the result of this icode is not on the
2620 stack, since acc is used to compute stack offset */
2622 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
2623 OP_SYMBOL (IC_RESULT (uic))->onStack)
2626 // if (isOperandOnStack(IC_RESULT(uic)))
2630 /* if the usage has only one operand then we can */
2631 if (IC_LEFT (uic) == NULL ||
2632 IC_RIGHT (uic) == NULL)
2636 /* if the other operand uses the accumulator then we cannot */
2637 if ( (IC_LEFT(uic)->key == IC_RESULT(ic)->key &&
2638 operandUsesAcc2(IC_RIGHT(uic))) ||
2639 (IC_RIGHT(uic)->key == IC_RESULT(ic)->key &&
2640 operandUsesAcc2(IC_LEFT(uic))) )
2643 /* make sure this is on the left side if not commutative */
2644 /* except for '-', which has been written to be able to
2645 handle reversed operands */
2646 if (!(isCommutativeOp2(ic->op) || ic->op == '-') &&
2647 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
2652 // this is too dangerous and need further restrictions
2655 /* if one of them is a literal then we can */
2656 if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
2657 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
2659 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2666 if ((POINTER_GET(uic))
2667 || (ic->op == ADDRESS_OF && uic->op == '+' && IS_OP_LITERAL (IC_RIGHT (uic))))
2669 OP_SYMBOL (IC_RESULT (ic))->accuse = ACCUSE_HX;
2673 OP_SYMBOL (IC_RESULT (ic))->accuse = ACCUSE_XA;
2676 /*-----------------------------------------------------------------*/
2677 /* packForPush - hueristics to reduce iCode for pushing */
2678 /*-----------------------------------------------------------------*/
2680 packForPush (iCode * ic, eBBlock ** ebpp, int blockno)
2684 struct eBBlock * ebp=ebpp[blockno];
2686 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
2689 /* must have only definition & one usage */
2690 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
2691 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
2694 /* find the definition */
2695 if (!(dic = hTabItemWithKey (iCodehTab,
2696 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
2699 if (dic->op != '=' || POINTER_SET (dic))
2702 if (dic->seq < ebp->fSeq) { // Evelyn did this
2704 for (i=0; i<blockno; i++) {
2705 if (dic->seq >= ebpp[i]->fSeq && dic->seq <= ebpp[i]->lSeq) {
2710 wassert (i!=blockno); // no way to recover from here
2713 if (IS_SYMOP(IC_RIGHT(dic))) {
2714 /* make sure the right side does not have any definitions
2716 dbv = OP_DEFS(IC_RIGHT(dic));
2717 for (lic = ic; lic && lic != dic ; lic = lic->prev) {
2718 if (bitVectBitValue(dbv,lic->key))
2721 /* make sure they have the same type */
2722 if (IS_SPEC(operandType(IC_LEFT(ic))))
2724 sym_link *itype=operandType(IC_LEFT(ic));
2725 sym_link *ditype=operandType(IC_RIGHT(dic));
2727 if (SPEC_USIGN(itype)!=SPEC_USIGN(ditype) ||
2728 SPEC_LONG(itype)!=SPEC_LONG(ditype))
2731 /* extend the live range of replaced operand if needed */
2732 if (OP_SYMBOL(IC_RIGHT(dic))->liveTo < ic->seq) {
2733 OP_SYMBOL(IC_RIGHT(dic))->liveTo = ic->seq;
2735 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2738 /* we now we know that it has one & only one def & use
2739 and the that the definition is an assignment */
2740 ReplaceOpWithCheaperOp(&IC_LEFT (ic), IC_RIGHT (dic));
2741 remiCodeFromeBBlock (ebp, dic);
2742 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2745 /*-----------------------------------------------------------------*/
2746 /* packRegisters - does some transformations to reduce register */
2748 /*-----------------------------------------------------------------*/
2750 packRegisters (eBBlock ** ebpp, int blockno)
2754 eBBlock *ebp=ebpp[blockno];
2761 /* look for assignments of the form */
2762 /* iTempNN = TRueSym (someoperation) SomeOperand */
2764 /* TrueSym := iTempNN:1 */
2765 for (ic = ebp->sch; ic; ic = ic->next)
2767 /* find assignment of the form TrueSym := iTempNN:1 */
2768 if (ic->op == '=' && !POINTER_SET (ic) )
2769 change += packRegsForAssign (ic, ebp);
2776 for (ic = ebp->sch; ic; ic = ic->next)
2778 //packRegsForLiteral (ic);
2780 /* if this is an itemp & result of an address of a true sym
2781 then mark this as rematerialisable */
2782 if (ic->op == ADDRESS_OF &&
2783 IS_ITEMP (IC_RESULT (ic)) &&
2784 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
2785 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2786 !OP_SYMBOL (IC_LEFT (ic))->onStack )
2789 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2790 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2791 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2795 if (ic->op == '=' &&
2796 !POINTER_SET (ic) &&
2797 IS_ITEMP (IC_RESULT (ic)) &&
2798 IS_VALOP (IC_RIGHT (ic)) &&
2799 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1)
2802 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2803 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2804 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2808 /* if straight assignment then carry remat flag if
2809 this is the only definition */
2810 if (ic->op == '=' &&
2811 !POINTER_SET (ic) &&
2812 IS_SYMOP (IC_RIGHT (ic)) &&
2813 OP_SYMBOL (IC_RIGHT (ic))->remat &&
2814 !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode) &&
2815 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
2818 OP_SYMBOL (IC_RESULT (ic))->remat =
2819 OP_SYMBOL (IC_RIGHT (ic))->remat;
2820 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
2821 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
2824 /* if cast to a generic pointer & the pointer being
2825 cast is remat, then we can remat this cast as well */
2826 if (ic->op == CAST &&
2827 IS_SYMOP(IC_RIGHT(ic)) &&
2828 OP_SYMBOL(IC_RIGHT(ic))->remat &&
2829 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1) {
2830 sym_link *to_type = operandType(IC_LEFT(ic));
2831 sym_link *from_type = operandType(IC_RIGHT(ic));
2832 if (IS_GENPTR(to_type) && IS_PTR(from_type)) {
2833 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2834 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2835 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2839 /* if this is a +/- operation with a rematerizable
2840 then mark this as rematerializable as well */
2841 if ((ic->op == '+' || ic->op == '-') &&
2842 (IS_SYMOP (IC_LEFT (ic)) &&
2843 IS_ITEMP (IC_RESULT (ic)) &&
2844 IS_OP_LITERAL (IC_RIGHT (ic))) &&
2845 OP_SYMBOL (IC_LEFT (ic))->remat &&
2846 (!IS_SYMOP (IC_RIGHT (ic)) || !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode)) &&
2847 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1)
2849 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2850 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2851 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2854 /* mark the pointer usages */
2855 if (POINTER_SET (ic))
2856 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
2858 if (POINTER_GET (ic) &&
2859 IS_SYMOP(IC_LEFT (ic)))
2860 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
2865 /* if we are using a symbol on the stack
2866 then we should say hc08_ptrRegReq */
2867 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
2868 hc08_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
2869 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
2870 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
2871 hc08_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
2872 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
2875 if (IS_SYMOP (IC_LEFT (ic)))
2876 hc08_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
2877 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
2878 if (IS_SYMOP (IC_RIGHT (ic)))
2879 hc08_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
2880 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
2881 if (IS_SYMOP (IC_RESULT (ic)))
2882 hc08_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
2883 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
2888 /* if the condition of an if instruction
2889 is defined in the previous instruction and
2890 this is the only usage then
2891 mark the itemp as a conditional */
2892 if ((IS_CONDITIONAL (ic) ||
2893 (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic))) &&
2894 ic->next && ic->next->op == IFX &&
2895 bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
2896 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
2897 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2899 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
2903 /* reduce for support function calls */
2904 if (ic->supportRtn || (ic->op != IFX && ic->op != JUMPTABLE))
2905 packRegsForSupport (ic, ebp);
2908 /* some cases the redundant moves can
2909 can be eliminated for return statements */
2910 if ((ic->op == RETURN || (ic->op == SEND && ic->argreg == 1)) &&
2911 /* !isOperandInFarSpace (IC_LEFT (ic)) && */
2912 options.model == MODEL_SMALL) {
2913 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2916 /* if pointer set & left has a size more than
2917 one and right is not in far space */
2918 if (POINTER_SET (ic) &&
2919 /* !isOperandInFarSpace (IC_RIGHT (ic)) && */
2920 !OP_SYMBOL (IC_RESULT (ic))->remat &&
2921 !IS_OP_RUONLY (IC_RIGHT (ic))
2922 /* && getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1 */ )
2923 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
2925 /* if pointer get */
2926 if (POINTER_GET (ic) &&
2927 IS_SYMOP (IC_LEFT (ic)) &&
2928 /* !isOperandInFarSpace (IC_RESULT (ic)) && */
2929 !OP_SYMBOL (IC_LEFT (ic))->remat &&
2930 !IS_OP_RUONLY (IC_RESULT (ic))
2931 /* && getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1 */)
2932 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2935 /* if this is cast for intergral promotion then
2936 check if only use of the definition of the
2937 operand being casted/ if yes then replace
2938 the result of that arithmetic operation with
2939 this result and get rid of the cast */
2942 sym_link *fromType = operandType (IC_RIGHT (ic));
2943 sym_link *toType = operandType (IC_LEFT (ic));
2945 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
2946 getSize (fromType) != getSize (toType) &&
2947 SPEC_USIGN (fromType) == SPEC_USIGN (toType))
2950 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2953 if (IS_ARITHMETIC_OP (dic))
2955 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2956 ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
2957 remiCodeFromeBBlock (ebp, ic);
2958 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2959 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2960 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2964 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
2970 /* if the type from and type to are the same
2971 then if this is the only use then packit */
2972 if (compareType (operandType (IC_RIGHT (ic)),
2973 operandType (IC_LEFT (ic))) == 1)
2975 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2978 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2979 ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
2980 remiCodeFromeBBlock (ebp, ic);
2981 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2982 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2983 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2992 iTempNN := (some variable in farspace) V1
2997 if (ic->op == IPUSH)
2999 packForPush (ic, ebpp, blockno);
3004 /* pack registers for accumulator use, when the
3005 result of an arithmetic or bit wise operation
3006 has only one use, that use is immediately following
3007 the defintion and the using iCode has only one
3008 operand or has two operands but one is literal &
3009 the result of that operation is not on stack then
3010 we can leave the result of this operation in x:a
3012 if ((IS_ARITHMETIC_OP (ic)
3013 || IS_CONDITIONAL(ic)
3014 || IS_BITWISE_OP (ic)
3018 || ic->op == GETHBIT
3019 || ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == CALL
3020 || (ic->op == ADDRESS_OF && isOperandOnStack (IC_LEFT (ic)))
3021 || ic->op == RECEIVE
3023 IS_ITEMP (IC_RESULT (ic)) &&
3024 getSize (operandType (IC_RESULT (ic))) <= 1)
3026 packRegsForAccUse (ic);
3031 /*-----------------------------------------------------------------*/
3032 /* assignRegisters - assigns registers to each live range as need */
3033 /*-----------------------------------------------------------------*/
3035 hc08_assignRegisters (eBBlock ** ebbs, int count)
3040 setToNull ((void *) &_G.funcrUsed);
3041 setToNull ((void *) &_G.regAssigned);
3042 setToNull ((void *) &_G.totRegAssigned);
3043 hc08_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3045 hc08_reg_a = hc08_regWithIdx(A_IDX);
3046 hc08_reg_x = hc08_regWithIdx(X_IDX);
3047 hc08_reg_h = hc08_regWithIdx(H_IDX);
3048 hc08_reg_hx = hc08_regWithIdx(HX_IDX);
3049 hc08_reg_xa = hc08_regWithIdx(XA_IDX);
3051 /* change assignments this will remove some
3052 live ranges reducing some register pressure */
3053 for (i = 0; i < count; i++)
3054 packRegisters (ebbs, i);
3056 /* liveranges probably changed by register packing
3057 so we compute them again */
3058 recomputeLiveRanges (ebbs, count);
3060 if (options.dump_pack)
3061 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3063 /* first determine for each live range the number of
3064 registers & the type of registers required for each */
3067 /* and serially allocate registers */
3068 serialRegAssign (ebbs, count);
3071 //setToNull ((void *) &_G.regAssigned);
3072 //setToNull ((void *) &_G.totRegAssigned);
3075 /* if stack was extended then tell the user */
3078 /* werror(W_TOOMANY_SPILS,"stack", */
3079 /* _G.stackExtend,currFunc->name,""); */
3085 /* werror(W_TOOMANY_SPILS,"data space", */
3086 /* _G.dataExtend,currFunc->name,""); */
3090 /* after that create the register mask
3091 for each of the instruction */
3092 createRegMask (ebbs, count);
3094 /* redo that offsets for stacked automatic variables */
3096 redoStackOffsets ();
3099 if (options.dump_rassgn)
3101 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3102 dumpLiveRanges (DUMP_LRANGE, liveRanges);
3105 /* do the overlaysegment stuff SDCCmem.c */
3106 doOverlays (ebbs, count);
3108 /* now get back the chain */
3109 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3113 /* free up any _G.stackSpil locations allocated */
3114 applyToSet (_G.stackSpil, deallocStackSpil);
3116 setToNull ((void **) &_G.stackSpil);
3117 setToNull ((void **) &_G.spiltSet);
3118 /* mark all registers as free */