1 /*------------------------------------------------------------------------
3 SDCCralloc.c - source file for register allocation. 68HC08 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, "a", 1, NULL, 0, 1},
65 {REG_GPR, X_IDX, "x", 2, NULL, 0, 1},
66 {REG_GPR, H_IDX, "h", 4, NULL, 0, 1},
67 {REG_PTR, HX_IDX, "hx", 6, NULL, 0, 1},
68 {REG_GPR, XA_IDX, "xa", 3, NULL, 0, 1},
70 {REG_CND, CND_IDX, "C", 0, NULL, 0, 1},
71 {0, SP_IDX, "sp", 0, NULL, 0, 1},
82 static void spillThis (symbol *);
83 static void freeAllRegs ();
85 /*-----------------------------------------------------------------*/
86 /* allocReg - allocates register of given type */
87 /*-----------------------------------------------------------------*/
93 if ((type==REG_PTR) && (regshc08[HX_IDX].isFree))
95 regshc08[HX_IDX].isFree = 0;
98 bitVectSetBit (currFunc->regsUsed, HX_IDX);
99 return ®shc08[HX_IDX];
104 /*-----------------------------------------------------------------*/
105 /* hc08_regWithIdx - returns pointer to register wit index number */
106 /*-----------------------------------------------------------------*/
108 hc08_regWithIdx (int idx)
112 for (i = 0; i < hc08_nRegs; i++)
113 if (regshc08[i].rIdx == idx)
116 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
117 "regWithIdx not found");
121 /*-----------------------------------------------------------------*/
122 /* hc08_freeReg - frees a register */
123 /*-----------------------------------------------------------------*/
125 hc08_freeReg (regs * reg)
129 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
130 "hc08_freeReg - Freeing NULL register");
139 if (hc08_reg_x->isFree)
140 hc08_reg_xa->isFree = 1;
143 if (hc08_reg_a->isFree)
144 hc08_reg_xa->isFree = 1;
145 if (hc08_reg_h->isFree)
146 hc08_reg_hx->isFree = 1;
149 if (hc08_reg_x->isFree)
150 hc08_reg_hx->isFree = 1;
153 hc08_reg_h->isFree = 1;
154 hc08_reg_x->isFree = 1;
155 if (hc08_reg_a->isFree)
156 hc08_reg_xa->isFree = 1;
159 hc08_reg_x->isFree = 1;
160 hc08_reg_a->isFree = 1;
161 if (hc08_reg_h->isFree)
162 hc08_reg_hx->isFree = 1;
170 /*-----------------------------------------------------------------*/
171 /* nFreeRegs - returns number of free registers */
172 /*-----------------------------------------------------------------*/
181 for (i = 0; i < hc08_nRegs; i++)
182 if (regshc08[i].isFree && regshc08[i].type == type)
187 /*-----------------------------------------------------------------*/
188 /* nfreeRegsType - free registers with type */
189 /*-----------------------------------------------------------------*/
191 nfreeRegsType (int type)
196 if ((nfr = nFreeRegs (type)) == 0)
197 return nFreeRegs (REG_GPR);
200 return nFreeRegs (type);
203 /*-----------------------------------------------------------------*/
204 /* hc08_useReg - marks a register as used */
205 /*-----------------------------------------------------------------*/
207 hc08_useReg (regs * reg)
214 hc08_reg_xa->aop = NULL;
215 hc08_reg_xa->isFree = 0;
218 hc08_reg_xa->aop = NULL;
219 hc08_reg_xa->isFree = 0;
220 hc08_reg_hx->aop = NULL;
221 hc08_reg_hx->isFree = 0;
224 hc08_reg_hx->aop = NULL;
225 hc08_reg_hx->isFree = 0;
228 hc08_reg_h->aop = NULL;
229 hc08_reg_h->isFree = 0;
230 hc08_reg_x->aop = NULL;
231 hc08_reg_x->isFree = 0;
234 hc08_reg_x->aop = NULL;
235 hc08_reg_x->isFree = 0;
236 hc08_reg_a->aop = NULL;
237 hc08_reg_a->isFree = 0;
245 /*-----------------------------------------------------------------*/
246 /* hc08_dirtyReg - marks a register as dirty */
247 /*-----------------------------------------------------------------*/
249 hc08_dirtyReg (regs * reg, bool freereg)
256 hc08_reg_xa->aop = NULL;
259 hc08_reg_xa->aop = NULL;
260 hc08_reg_hx->aop = NULL;
263 hc08_reg_hx->aop = NULL;
266 hc08_reg_h->aop = NULL;
267 hc08_reg_x->aop = NULL;
270 hc08_reg_x->aop = NULL;
271 hc08_reg_a->aop = NULL;
280 /*-----------------------------------------------------------------*/
281 /* computeSpillable - given a point find the spillable live ranges */
282 /*-----------------------------------------------------------------*/
284 computeSpillable (iCode * ic)
288 /* spillable live ranges are those that are live at this
289 point . the following categories need to be subtracted
291 a) - those that are already spilt
292 b) - if being used by this one
293 c) - defined by this one */
295 spillable = bitVectCopy (ic->rlive);
297 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
299 bitVectCplAnd (spillable, ic->uses); /* used in this one */
300 bitVectUnSetBit (spillable, ic->defKey);
301 spillable = bitVectIntersect (spillable, _G.regAssigned);
306 /*-----------------------------------------------------------------*/
307 /* noSpilLoc - return true if a variable has no spil location */
308 /*-----------------------------------------------------------------*/
310 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
312 return (sym->usl.spillLoc ? 0 : 1);
315 /*-----------------------------------------------------------------*/
316 /* hasSpilLoc - will return 1 if the symbol has spil location */
317 /*-----------------------------------------------------------------*/
319 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
321 return (sym->usl.spillLoc ? 1 : 0);
324 /*-----------------------------------------------------------------*/
325 /* directSpilLoc - will return 1 if the splilocation is in direct */
326 /*-----------------------------------------------------------------*/
328 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
330 if (sym->usl.spillLoc &&
331 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
337 /*-----------------------------------------------------------------*/
338 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
339 /* but is not used as a pointer */
340 /*-----------------------------------------------------------------*/
342 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
344 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
347 /*-----------------------------------------------------------------*/
348 /* rematable - will return 1 if the remat flag is set */
349 /*-----------------------------------------------------------------*/
351 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
356 /*-----------------------------------------------------------------*/
357 /* notUsedInRemaining - not used or defined in remain of the block */
358 /*-----------------------------------------------------------------*/
360 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
362 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
363 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
366 /*-----------------------------------------------------------------*/
367 /* allLRs - return true for all */
368 /*-----------------------------------------------------------------*/
370 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
375 /*-----------------------------------------------------------------*/
376 /* liveRangesWith - applies function to a given set of live range */
377 /*-----------------------------------------------------------------*/
379 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
380 eBBlock * ebp, iCode * ic)
385 if (!lrs || !lrs->size)
388 for (i = 1; i < lrs->size; i++)
391 if (!bitVectBitValue (lrs, i))
394 /* if we don't find it in the live range
395 hash table we are in serious trouble */
396 if (!(sym = hTabItemWithKey (liveRanges, i)))
398 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
399 "liveRangesWith could not find liveRange");
403 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
404 addSetHead (&rset, sym);
411 /*-----------------------------------------------------------------*/
412 /* leastUsedLR - given a set determines which is the least used */
413 /*-----------------------------------------------------------------*/
415 leastUsedLR (set * sset)
417 symbol *sym = NULL, *lsym = NULL;
419 sym = lsym = setFirstItem (sset);
424 for (; lsym; lsym = setNextItem (sset))
427 /* if usage is the same then prefer
428 the spill the smaller of the two */
429 if (lsym->used == sym->used)
430 if (getSize (lsym->type) < getSize (sym->type))
434 if (lsym->used < sym->used)
439 setToNull ((void *) &sset);
444 /*-----------------------------------------------------------------*/
445 /* noOverLap - will iterate through the list looking for over lap */
446 /*-----------------------------------------------------------------*/
448 noOverLap (set * itmpStack, symbol * fsym)
453 for (sym = setFirstItem (itmpStack); sym;
454 sym = setNextItem (itmpStack))
456 if (bitVectBitValue(sym->clashes,fsym->key)) return 0;
462 /*-----------------------------------------------------------------*/
463 /* isFree - will return 1 if the a free spil location is found */
464 /*-----------------------------------------------------------------*/
469 V_ARG (symbol **, sloc);
470 V_ARG (symbol *, fsym);
472 /* if already found */
476 /* if it is free && and the itmp assigned to
477 this does not have any overlapping live ranges
478 with the one currently being assigned and
479 the size can be accomodated */
481 noOverLap (sym->usl.itmpStack, fsym) &&
482 getSize (sym->type) >= getSize (fsym->type))
491 /*-----------------------------------------------------------------*/
492 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
493 /*-----------------------------------------------------------------*/
495 spillLRWithPtrReg (symbol * forSym)
501 if (!_G.regAssigned ||
502 bitVectIsZero (_G.regAssigned))
505 hx = hc08_regWithIdx (HX_IDX);
507 /* for all live ranges */
508 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
509 lrsym = hTabNextItem (liveRanges, &k))
513 /* if no registers assigned to it or spilt */
514 /* if it does not overlap with this then
515 not need to spill it */
517 if (lrsym->isspilt || !lrsym->nRegs ||
518 (lrsym->liveTo < forSym->liveFrom))
521 /* go thru the registers : if it is either
522 r0 or r1 then spil it */
523 for (j = 0; j < lrsym->nRegs; j++)
524 if (lrsym->regs[j] == hx)
533 /*-----------------------------------------------------------------*/
534 /* createStackSpil - create a location on the stack to spil */
535 /*-----------------------------------------------------------------*/
537 createStackSpil (symbol * sym)
540 int useXstack, model;
544 /* first go try and find a free one that is already
545 existing on the stack */
546 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
548 /* found a free one : just update & return */
549 sym->usl.spillLoc = sloc;
552 addSetHead (&sloc->usl.itmpStack, sym);
556 /* could not then have to create one , this is the hard part
557 we need to allocate this on the stack : this is really a
558 hack!! but cannot think of anything better at this time */
560 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
562 fprintf (stderr, "***Internal error: slocBuffer overflowed: %s:%d\n",
567 sloc = newiTemp (slocBuffer);
569 /* set the type to the spilling symbol */
570 sloc->type = copyLinkChain (sym->type);
571 sloc->etype = getSpec (sloc->type);
572 SPEC_SCLS (sloc->etype) = S_DATA;
573 SPEC_EXTR (sloc->etype) = 0;
574 SPEC_STAT (sloc->etype) = 0;
575 SPEC_VOLATILE(sloc->etype) = 0;
576 SPEC_ABSA(sloc->etype) = 0;
578 /* we don't allow it to be allocated`
579 onto the external stack since : so we
580 temporarily turn it off ; we also
581 turn off memory model to prevent
582 the spil from going to the external storage
585 useXstack = options.useXstack;
586 model = options.model;
587 /* noOverlay = options.noOverlay; */
588 /* options.noOverlay = 1; */
589 options.model = options.useXstack = 0;
593 options.useXstack = useXstack;
594 options.model = model;
595 /* options.noOverlay = noOverlay; */
596 sloc->isref = 1; /* to prevent compiler warning */
598 /* if it is on the stack then update the stack */
599 if (IN_STACK (sloc->etype))
601 currFunc->stack += getSize (sloc->type);
602 _G.stackExtend += getSize (sloc->type);
605 _G.dataExtend += getSize (sloc->type);
607 /* add it to the _G.stackSpil set */
608 addSetHead (&_G.stackSpil, sloc);
609 sym->usl.spillLoc = sloc;
612 /* add it to the set of itempStack set
613 of the spill location */
614 addSetHead (&sloc->usl.itmpStack, sym);
618 /*-----------------------------------------------------------------*/
619 /* isSpiltOnStack - returns true if the spil location is on stack */
620 /*-----------------------------------------------------------------*/
622 isSpiltOnStack (symbol * sym)
632 /* if (sym->_G.stackSpil) */
635 if (!sym->usl.spillLoc)
638 etype = getSpec (sym->usl.spillLoc->type);
639 if (IN_STACK (etype))
645 /*-----------------------------------------------------------------*/
646 /* spillThis - spils a specific operand */
647 /*-----------------------------------------------------------------*/
649 spillThis (symbol * sym)
652 /* if this is rematerializable or has a spillLocation
653 we are okay, else we need to create a spillLocation
655 if (!(sym->remat || sym->usl.spillLoc))
656 createStackSpil (sym);
658 /* mark it as spilt & put it in the spilt set */
659 sym->isspilt = sym->spillA = 1;
660 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
662 bitVectUnSetBit (_G.regAssigned, sym->key);
663 bitVectUnSetBit (_G.totRegAssigned, sym->key);
665 for (i = 0; i < sym->nRegs; i++)
669 hc08_freeReg (sym->regs[i]);
673 /* if spilt on stack then free up r0 & r1
674 if they could have been assigned to some
676 // if (!hc08_ptrRegReq && isSpiltOnStack (sym))
679 // spillLRWithPtrReg (sym);
682 if (sym->usl.spillLoc && !sym->remat)
683 sym->usl.spillLoc->allocreq++;
687 /*-----------------------------------------------------------------*/
688 /* selectSpil - select a iTemp to spil : rather a simple procedure */
689 /*-----------------------------------------------------------------*/
691 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
693 bitVect *lrcs = NULL;
697 /* get the spillable live ranges */
698 lrcs = computeSpillable (ic);
700 /* get all live ranges that are rematerizable */
701 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
704 /* return the least used of these */
705 return leastUsedLR (selectS);
708 /* get live ranges with spillLocations in direct space */
709 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
711 sym = leastUsedLR (selectS);
712 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
713 sym->usl.spillLoc->rname :
714 sym->usl.spillLoc->name));
716 /* mark it as allocation required */
717 sym->usl.spillLoc->allocreq++;
721 /* if the symbol is local to the block then */
722 if (forSym->liveTo < ebp->lSeq)
725 /* check if there are any live ranges allocated
726 to registers that are not used in this block */
727 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
729 sym = leastUsedLR (selectS);
730 /* if this is not rematerializable */
739 /* check if there are any live ranges that not
740 used in the remainder of the block */
741 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
743 sym = leastUsedLR (selectS);
756 /* find live ranges with spillocation && not used as pointers */
757 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
760 sym = leastUsedLR (selectS);
761 /* mark this as allocation required */
762 sym->usl.spillLoc->allocreq++;
766 /* find live ranges with spillocation */
767 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
770 sym = leastUsedLR (selectS);
771 sym->usl.spillLoc->allocreq++;
775 /* couldn't find then we need to create a spil
776 location on the stack , for which one? the least
778 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
781 /* return a created spil location */
782 sym = createStackSpil (leastUsedLR (selectS));
783 sym->usl.spillLoc->allocreq++;
787 /* this is an extreme situation we will spill
788 this one : happens very rarely but it does happen */
794 /*-----------------------------------------------------------------*/
795 /* spilSomething - spil some variable & mark registers as free */
796 /*-----------------------------------------------------------------*/
798 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
803 /* get something we can spil */
804 ssym = selectSpil (ic, ebp, forSym);
806 /* mark it as spilt */
807 ssym->isspilt = ssym->spillA = 1;
808 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
810 /* mark it as not register assigned &
811 take it away from the set */
812 bitVectUnSetBit (_G.regAssigned, ssym->key);
813 bitVectUnSetBit (_G.totRegAssigned, ssym->key);
815 /* mark the registers as free */
816 for (i = 0; i < ssym->nRegs; i++)
818 hc08_freeReg (ssym->regs[i]);
820 /* if spilt on stack then free up hx
821 if it could have been assigned to as gprs */
822 if (!hc08_ptrRegReq && isSpiltOnStack (ssym))
825 spillLRWithPtrReg (ssym);
828 /* if this was a block level spil then insert push & pop
829 at the start & end of block respectively */
832 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
833 /* add push to the start of the block */
834 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
835 ebp->sch->next : ebp->sch));
836 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
837 /* add pop to the end of the block */
838 addiCodeToeBBlock (ebp, nic, NULL);
841 /* if spilt because not used in the remainder of the
842 block then add a push before this instruction and
843 a pop at the end of the block */
844 if (ssym->remainSpil)
847 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
848 /* add push just before this instruction */
849 addiCodeToeBBlock (ebp, nic, ic);
851 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
852 /* add pop to the end of the block */
853 addiCodeToeBBlock (ebp, nic, NULL);
862 /*-----------------------------------------------------------------*/
863 /* getRegPtr - will try for PTR if not a GPR type if not spil */
864 /*-----------------------------------------------------------------*/
866 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
871 /* try for a ptr type */
872 if ((reg = allocReg (REG_PTR)))
875 /* try for gpr type */
876 if ((reg = allocReg (REG_GPR)))
879 /* we have to spil */
880 if (!spilSomething (ic, ebp, sym))
883 /* this looks like an infinite loop but
884 in really selectSpil will abort */
888 /*-----------------------------------------------------------------*/
889 /* getRegGpr - will try for GPR if not spil */
890 /*-----------------------------------------------------------------*/
892 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
897 /* try for gpr type */
898 if ((reg = allocReg (REG_GPR)))
902 if ((reg = allocReg (REG_PTR)))
905 /* we have to spil */
906 if (!spilSomething (ic, ebp, sym))
909 /* this looks like an infinite loop but
910 in really selectSpil will abort */
914 /*-----------------------------------------------------------------*/
915 /* getRegPtrNoSpil - get it cannot split */
916 /*-----------------------------------------------------------------*/
917 static regs *getRegPtrNoSpil()
921 /* try for a ptr type */
922 if ((reg = allocReg (REG_PTR)))
925 /* try for gpr type */
926 if ((reg = allocReg (REG_GPR)))
931 /* just to make the compiler happy */
935 /*-----------------------------------------------------------------*/
936 /* getRegGprNoSpil - get it cannot split */
937 /*-----------------------------------------------------------------*/
938 static regs *getRegGprNoSpil()
942 if ((reg = allocReg (REG_GPR)))
946 if ((reg = allocReg (REG_PTR)))
951 /* just to make the compiler happy */
955 /*-----------------------------------------------------------------*/
956 /* symHasReg - symbol has a given register */
957 /*-----------------------------------------------------------------*/
959 symHasReg (symbol * sym, regs * reg)
963 for (i = 0; i < sym->nRegs; i++)
964 if (sym->regs[i] == reg)
970 /*-----------------------------------------------------------------*/
971 /* deassignLRs - check the live to and if they have registers & are */
972 /* not spilt then free up the registers */
973 /*-----------------------------------------------------------------*/
975 deassignLRs (iCode * ic, eBBlock * ebp)
981 for (sym = hTabFirstItem (liveRanges, &k); sym;
982 sym = hTabNextItem (liveRanges, &k))
986 /* if it does not end here */
987 if (sym->liveTo > ic->seq)
990 /* if it was spilt on stack then we can
991 mark the stack spil location as free */
996 sym->usl.spillLoc->isFree = 1;
1002 if (!bitVectBitValue (_G.regAssigned, sym->key))
1005 /* special case check if this is an IFX &
1006 the privious one was a pop and the
1007 previous one was not spilt then keep track
1009 if (ic->op == IFX && ic->prev &&
1010 ic->prev->op == IPOP &&
1011 !ic->prev->parmPush &&
1012 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1013 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1019 bitVectUnSetBit (_G.regAssigned, sym->key);
1021 /* if the result of this one needs registers
1022 and does not have it then assign it right
1024 if (IC_RESULT (ic) &&
1025 !(SKIP_IC2 (ic) || /* not a special icode */
1026 ic->op == JUMPTABLE ||
1031 POINTER_SET (ic)) &&
1032 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1033 result->liveTo > ic->seq && /* and will live beyond this */
1034 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1035 result->liveFrom == ic->seq && /* does not start before here */
1036 result->regType == sym->regType && /* same register types */
1037 result->nRegs && /* which needs registers */
1038 !result->isspilt && /* and does not already have them */
1040 !bitVectBitValue (_G.regAssigned, result->key) &&
1041 /* the number of free regs + number of regs in this LR
1042 can accomodate the what result Needs */
1043 ((nfreeRegsType (result->regType) +
1044 sym->nRegs) >= result->nRegs)
1048 for (i = 0; i < result->nRegs; i++)
1050 result->regs[i] = sym->regs[i];
1052 result->regs[i] = getRegGpr (ic, ebp, result);
1054 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1055 _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, result->key);
1059 /* free the remaining */
1060 for (; i < sym->nRegs; i++)
1064 if (!symHasReg (psym, sym->regs[i]))
1065 hc08_freeReg (sym->regs[i]);
1068 hc08_freeReg (sym->regs[i]);
1075 /*-----------------------------------------------------------------*/
1076 /* reassignLR - reassign this to registers */
1077 /*-----------------------------------------------------------------*/
1079 reassignLR (operand * op)
1081 symbol *sym = OP_SYMBOL (op);
1084 /* not spilt any more */
1085 sym->isspilt = sym->spillA = sym->blockSpil = sym->remainSpil = 0;
1086 bitVectUnSetBit (_G.spiltSet, sym->key);
1088 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1089 _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key);
1093 for (i = 0; i < sym->nRegs; i++)
1094 sym->regs[i]->isFree = 0;
1097 /*-----------------------------------------------------------------*/
1098 /* willCauseSpill - determines if allocating will cause a spill */
1099 /*-----------------------------------------------------------------*/
1101 willCauseSpill (int nr, int rt)
1103 /* first check if there are any avlb registers
1104 of te type required */
1107 /* special case for pointer type
1108 if pointer type not avlb then
1109 check for type gpr */
1110 if (nFreeRegs (rt) >= nr)
1112 if (nFreeRegs (REG_GPR) >= nr)
1119 if (nFreeRegs (rt) >= nr)
1124 if (nFreeRegs (REG_PTR) +
1125 nFreeRegs (REG_GPR) >= nr)
1130 /* it will cause a spil */
1134 /*-----------------------------------------------------------------*/
1135 /* positionRegs - the allocator can allocate same registers to res- */
1136 /* ult and operand, if this happens make sure they are in the same */
1137 /* position as the operand otherwise chaos results */
1138 /*-----------------------------------------------------------------*/
1140 positionRegs (symbol * result, symbol * opsym)
1142 int count = min (result->nRegs, opsym->nRegs);
1143 int i, j = 0, shared = 0;
1146 /* if the result has been spilt then cannot share */
1151 /* first make sure that they actually share */
1152 for (i = 0; i < count; i++)
1154 for (j = 0; j < count; j++)
1156 if (result->regs[i] == opsym->regs[j] && i != j)
1166 regs *tmp = result->regs[i];
1167 result->regs[i] = result->regs[j];
1168 result->regs[j] = tmp;
1175 /*------------------------------------------------------------------*/
1176 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
1177 /* it should either have registers or have beed spilled. Otherwise, */
1178 /* there was an uninitialized variable, so just spill this to get */
1179 /* the operand in a valid state. */
1180 /*------------------------------------------------------------------*/
1182 verifyRegsAssigned (operand *op, iCode * ic)
1187 if (!IS_ITEMP (op)) return;
1189 sym = OP_SYMBOL (op);
1190 if (sym->isspilt) return;
1191 if (!sym->nRegs) return;
1192 if (sym->regs[0]) return;
1194 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
1195 sym->prereqv ? sym->prereqv->name : sym->name);
1201 /*-----------------------------------------------------------------*/
1202 /* serialRegAssign - serially allocate registers to the variables */
1203 /*-----------------------------------------------------------------*/
1205 serialRegAssign (eBBlock ** ebbs, int count)
1209 /* for all blocks */
1210 for (i = 0; i < count; i++) {
1214 if (ebbs[i]->noPath &&
1215 (ebbs[i]->entryLabel != entryLabel &&
1216 ebbs[i]->entryLabel != returnLabel))
1219 /* of all instructions do */
1220 for (ic = ebbs[i]->sch; ic; ic = ic->next) {
1224 // update the registers in use at the start of this icode
1225 for (reg=0; reg<hc08_nRegs; reg++) {
1226 if (regshc08[reg].isFree) {
1227 ic->riu &= ~(regshc08[reg].mask);
1229 ic->riu |= (regshc08[reg].mask);
1234 /* if this is an ipop that means some live
1235 range will have to be assigned again */
1237 reassignLR (IC_LEFT (ic));
1239 /* if result is present && is a true symbol */
1240 if (IC_RESULT (ic) && ic->op != IFX &&
1241 IS_TRUE_SYMOP (IC_RESULT (ic)))
1242 OP_SYMBOL (IC_RESULT (ic))->allocreq++;
1244 /* take away registers from live
1245 ranges that end at this instruction */
1246 deassignLRs (ic, ebbs[i]);
1248 /* some don't need registers */
1249 if (SKIP_IC2 (ic) ||
1250 ic->op == JUMPTABLE ||
1254 (IC_RESULT (ic) && POINTER_SET (ic)))
1257 /* now we need to allocate registers
1258 only for the result */
1259 if (IC_RESULT (ic)) {
1260 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
1266 /* if it does not need or is spilt
1267 or is already assigned to registers
1268 or will not live beyond this instructions */
1271 bitVectBitValue (_G.regAssigned, sym->key) ||
1272 sym->liveTo <= ic->seq)
1275 /* if some liverange has been spilt at the block level
1276 and this one live beyond this block then spil this
1278 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq) {
1282 /* if trying to allocate this will cause
1283 a spill and there is nothing to spill
1284 or this one is rematerializable then
1286 willCS = willCauseSpill (sym->nRegs, sym->regType);
1287 spillable = computeSpillable (ic);
1288 if (sym->remat || (willCS && bitVectIsZero (spillable))) {
1293 /* If the live range preceeds the point of definition
1294 then ideally we must take into account registers that
1295 have been allocated after sym->liveFrom but freed
1296 before ic->seq. This is complicated, so spill this
1297 symbol instead and let fillGaps handle the allocation. */
1298 if (sym->liveFrom < ic->seq) {
1303 /* if it has a spillocation & is used less than
1304 all other live ranges then spill this */
1306 if (sym->usl.spillLoc) {
1307 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
1308 allLRs, ebbs[i], ic));
1309 if (leastUsed && leastUsed->used > sym->used) {
1314 /* if none of the liveRanges have a spillLocation then better
1315 to spill this one than anything else already assigned to registers */
1316 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
1317 /* if this is local to this block then we might find a block spil */
1318 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
1325 /* if we need ptr regs for the right side
1327 if (POINTER_GET (ic) && IS_SYMOP (IC_LEFT (ic))
1328 && getSize (OP_SYMBOL (IC_LEFT (ic))->type) <= (unsigned int) PTRSIZE) {
1332 /* else we assign registers to it */
1333 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1334 _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key);
1336 for (j = 0; j < sym->nRegs; j++) {
1337 if (sym->regType == REG_PTR)
1338 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
1340 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
1342 /* if the allocation failed which means
1343 this was spilt then break */
1344 if (!sym->regs[j]) {
1349 /* if it shares registers with operands make sure
1350 that they are in the same position */
1351 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
1352 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=') {
1353 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1354 OP_SYMBOL (IC_LEFT (ic)));
1356 /* do the same for the right operand */
1357 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
1358 OP_SYMBOL (IC_RIGHT (ic))->nRegs) {
1359 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1360 OP_SYMBOL (IC_RIGHT (ic)));
1372 /* Check for and fix any problems with uninitialized operands */
1373 for (i = 0; i < count; i++)
1377 if (ebbs[i]->noPath &&
1378 (ebbs[i]->entryLabel != entryLabel &&
1379 ebbs[i]->entryLabel != returnLabel))
1382 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1389 verifyRegsAssigned (IC_COND (ic), ic);
1393 if (ic->op == JUMPTABLE)
1395 verifyRegsAssigned (IC_JTCOND (ic), ic);
1399 verifyRegsAssigned (IC_RESULT (ic), ic);
1400 verifyRegsAssigned (IC_LEFT (ic), ic);
1401 verifyRegsAssigned (IC_RIGHT (ic), ic);
1407 /*-----------------------------------------------------------------*/
1408 /* fillGaps - Try to fill in the Gaps left by Pass1 */
1409 /*-----------------------------------------------------------------*/
1410 static void fillGaps()
1415 if (getenv("DISABLE_FILL_GAPS")) return;
1417 /* look for liveranges that were spilt by the allocator */
1418 for (sym = hTabFirstItem(liveRanges,&key) ; sym ;
1419 sym = hTabNextItem(liveRanges,&key)) {
1424 if (!sym->spillA || !sym->clashes || sym->remat) continue ;
1426 /* find the liveRanges this one clashes with, that are
1427 still assigned to registers & mark the registers as used*/
1428 for ( i = 0 ; i < sym->clashes->size ; i ++) {
1432 if (bitVectBitValue(sym->clashes,i) == 0 || /* those that clash with this */
1433 bitVectBitValue(_G.totRegAssigned,i) == 0) /* and are still assigned to registers */
1436 clr = hTabItemWithKey(liveRanges,i);
1439 /* mark these registers as used */
1440 for (k = 0 ; k < clr->nRegs ; k++ )
1441 hc08_useReg(clr->regs[k]);
1444 if (willCauseSpill(sym->nRegs,sym->regType)) {
1445 /* NOPE :( clear all registers & and continue */
1450 /* THERE IS HOPE !!!! */
1451 for (i=0; i < sym->nRegs ; i++ ) {
1452 if (sym->regType == REG_PTR)
1453 sym->regs[i] = getRegPtrNoSpil ();
1455 sym->regs[i] = getRegGprNoSpil ();
1458 /* for all its definitions check if the registers
1459 allocated needs positioning NOTE: we can position
1460 only ONCE if more than One positioning required
1463 for (i = 0 ; i < sym->defs->size ; i++ ) {
1464 if (bitVectBitValue(sym->defs,i)) {
1466 if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
1467 if (SKIP_IC(ic)) continue;
1468 assert(isSymbolEqual(sym,OP_SYMBOL(IC_RESULT(ic)))); /* just making sure */
1469 /* if left is assigned to registers */
1470 if (IS_SYMOP(IC_LEFT(ic)) &&
1471 bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_LEFT(ic))->key)) {
1472 pdone += positionRegs(sym,OP_SYMBOL(IC_LEFT(ic)));
1474 if (IS_SYMOP(IC_RIGHT(ic)) &&
1475 bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RIGHT(ic))->key)) {
1476 pdone += positionRegs(sym,OP_SYMBOL(IC_RIGHT(ic)));
1478 if (pdone > 1) break;
1481 for (i = 0 ; i < sym->uses->size ; i++ ) {
1482 if (bitVectBitValue(sym->uses,i)) {
1484 if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
1485 if (SKIP_IC(ic)) continue;
1486 if (!IS_ASSIGN_ICODE(ic)) continue ;
1488 /* if result is assigned to registers */
1489 if (IS_SYMOP(IC_RESULT(ic)) &&
1490 bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RESULT(ic))->key)) {
1491 pdone += positionRegs(sym,OP_SYMBOL(IC_RESULT(ic)));
1493 if (pdone > 1) break;
1496 /* had to position more than once GIVE UP */
1498 /* UNDO all the changes we made to try this */
1500 for (i=0; i < sym->nRegs ; i++ ) {
1501 sym->regs[i] = NULL;
1504 D(printf ("Fill Gap gave up due to positioning for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN"));
1507 D(printf ("FILLED GAP for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN"));
1508 _G.totRegAssigned = bitVectSetBit(_G.totRegAssigned,sym->key);
1509 sym->isspilt = sym->spillA = 0 ;
1510 sym->usl.spillLoc->allocreq--;
1515 /*-----------------------------------------------------------------*/
1516 /* rUmaskForOp :- returns register mask for an operand */
1517 /*-----------------------------------------------------------------*/
1519 hc08_rUmaskForOp (operand * op)
1525 /* only temporaries are assigned registers */
1529 sym = OP_SYMBOL (op);
1531 /* if spilt or no registers assigned to it
1533 if (sym->isspilt || !sym->nRegs)
1536 rumask = newBitVect (hc08_nRegs);
1538 for (j = 0; j < sym->nRegs; j++)
1540 rumask = bitVectSetBit (rumask,
1541 sym->regs[j]->rIdx);
1547 /*-----------------------------------------------------------------*/
1548 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
1549 /*-----------------------------------------------------------------*/
1551 regsUsedIniCode (iCode * ic)
1553 bitVect *rmask = newBitVect (hc08_nRegs);
1555 /* do the special cases first */
1558 rmask = bitVectUnion (rmask,
1559 hc08_rUmaskForOp (IC_COND (ic)));
1563 /* for the jumptable */
1564 if (ic->op == JUMPTABLE)
1566 rmask = bitVectUnion (rmask,
1567 hc08_rUmaskForOp (IC_JTCOND (ic)));
1572 /* of all other cases */
1574 rmask = bitVectUnion (rmask,
1575 hc08_rUmaskForOp (IC_LEFT (ic)));
1579 rmask = bitVectUnion (rmask,
1580 hc08_rUmaskForOp (IC_RIGHT (ic)));
1583 rmask = bitVectUnion (rmask,
1584 hc08_rUmaskForOp (IC_RESULT (ic)));
1590 /*-----------------------------------------------------------------*/
1591 /* createRegMask - for each instruction will determine the regsUsed */
1592 /*-----------------------------------------------------------------*/
1594 createRegMask (eBBlock ** ebbs, int count)
1598 /* for all blocks */
1599 for (i = 0; i < count; i++)
1603 if (ebbs[i]->noPath &&
1604 (ebbs[i]->entryLabel != entryLabel &&
1605 ebbs[i]->entryLabel != returnLabel))
1608 /* for all instructions */
1609 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1614 if (SKIP_IC2 (ic) || !ic->rlive)
1617 /* first mark the registers used in this
1619 ic->rUsed = regsUsedIniCode (ic);
1620 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
1622 /* now create the register mask for those
1623 registers that are in use : this is a
1624 super set of ic->rUsed */
1625 ic->rMask = newBitVect (hc08_nRegs + 1);
1627 /* for all live Ranges alive at this point */
1628 for (j = 1; j < ic->rlive->size; j++)
1633 /* if not alive then continue */
1634 if (!bitVectBitValue (ic->rlive, j))
1637 /* find the live range we are interested in */
1638 if (!(sym = hTabItemWithKey (liveRanges, j)))
1640 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1641 "createRegMask cannot find live range");
1642 fprintf(stderr, "\tmissing live range: key=%d\n", j);
1646 /* if no register assigned to it */
1647 if (!sym->nRegs || sym->isspilt)
1650 /* for all the registers allocated to it */
1651 for (k = 0; k < sym->nRegs; k++)
1654 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
1660 /*-----------------------------------------------------------------*/
1661 /* rematStr - returns the rematerialized string for a remat var */
1662 /*-----------------------------------------------------------------*/
1664 rematStr (symbol * sym)
1667 iCode *ic = sym->rematiCode;
1672 /* if plus or minus print the right hand side */
1673 if (ic->op == '+' || ic->op == '-')
1675 sprintf (s, "0x%04x %c ", (int) operandLitValue (IC_RIGHT (ic)),
1678 ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1685 offset += operandLitValue (IC_RIGHT (ic));
1686 ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1691 offset -= operandLitValue (IC_RIGHT (ic));
1692 ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1696 /* cast then continue */
1697 if (IS_CAST_ICODE(ic)) {
1698 ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
1701 /* we reached the end */
1702 if (ic->op == ADDRESS_OF)
1703 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
1704 else if (ic->op == '=')
1705 sprintf (s, "0x%04x", (int) operandLitValue (IC_RIGHT (ic)) );
1712 /*-----------------------------------------------------------------*/
1713 /* regTypeNum - computes the type & number of registers required */
1714 /*-----------------------------------------------------------------*/
1716 regTypeNum (eBBlock *ebbs)
1722 /* for each live range do */
1723 for (sym = hTabFirstItem (liveRanges, &k); sym;
1724 sym = hTabNextItem (liveRanges, &k))
1727 /* if used zero times then no registers needed */
1728 if ((sym->liveTo - sym->liveFrom) == 0)
1732 /* if the live range is a temporary */
1736 /* if the type is marked as a conditional */
1737 if (sym->regType == REG_CND)
1740 /* if used in return only then we don't
1742 if (sym->ruonly || sym->accuse)
1744 if (IS_AGGREGATE (sym->type) || sym->isptr)
1745 sym->type = aggrToPtr (sym->type, FALSE);
1749 /* if the symbol has only one definition &
1750 that definition is a get_pointer */
1751 if (bitVectnBitsOn (sym->defs) == 1 &&
1752 (ic = hTabItemWithKey (iCodehTab,
1753 bitVectFirstBit (sym->defs))) &&
1755 !IS_BITVAR (sym->etype) &&
1756 (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER))
1759 if (ptrPseudoSymSafe (sym, ic))
1761 ptrPseudoSymConvert (sym, ic, rematStr (OP_SYMBOL (IC_LEFT (ic))));
1765 /* if in data space or idata space then try to
1766 allocate pointer register */
1770 /* if not then we require registers */
1771 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
1772 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1773 getSize (sym->type));
1777 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
1778 printTypeChain (sym->type, stderr);
1779 fprintf (stderr, "\n");
1782 /* determine the type of register required */
1783 if (sym->nRegs == 1 &&
1784 IS_PTR (sym->type) &&
1786 sym->regType = REG_PTR;
1788 sym->regType = REG_GPR;
1792 /* for the first run we don't provide */
1793 /* registers for true symbols we will */
1794 /* see how things go */
1800 /*-----------------------------------------------------------------*/
1801 /* freeAllRegs - mark all registers as free */
1802 /*-----------------------------------------------------------------*/
1808 for (i = 0; i < hc08_nRegs; i++) {
1809 regshc08[i].isFree = 1;
1810 regshc08[i].aop = NULL;
1814 /*-----------------------------------------------------------------*/
1815 /* deallocStackSpil - this will set the stack pointer back */
1816 /*-----------------------------------------------------------------*/
1818 DEFSETFUNC (deallocStackSpil)
1827 /*-----------------------------------------------------------------*/
1828 /* farSpacePackable - returns the packable icode for far variables */
1829 /*-----------------------------------------------------------------*/
1831 farSpacePackable (iCode * ic)
1835 /* go thru till we find a definition for the
1836 symbol on the right */
1837 for (dic = ic->prev; dic; dic = dic->prev)
1839 /* if the definition is a call then no */
1840 if ((dic->op == CALL || dic->op == PCALL) &&
1841 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1846 /* if shift by unknown amount then not */
1847 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
1848 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1852 /* if pointer get and size > 1 */
1853 if (POINTER_GET (dic) &&
1854 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
1857 if (POINTER_SET (dic) &&
1858 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
1862 /* if any three is a true symbol in far space */
1863 if (IC_RESULT (dic) &&
1864 IS_TRUE_SYMOP (IC_RESULT (dic)) /* &&
1865 isOperandInFarSpace (IC_RESULT (dic)) */)
1868 if (IC_RIGHT (dic) &&
1869 IS_TRUE_SYMOP (IC_RIGHT (dic)) /* &&
1870 isOperandInFarSpace (IC_RIGHT (dic)) */ &&
1871 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
1874 if (IC_LEFT (dic) &&
1875 IS_TRUE_SYMOP (IC_LEFT (dic)) /* &&
1876 isOperandInFarSpace (IC_LEFT (dic)) */ &&
1877 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
1880 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
1882 if ((dic->op == LEFT_OP ||
1883 dic->op == RIGHT_OP ||
1885 IS_OP_LITERAL (IC_RIGHT (dic)))
1898 packRegsForLiteral (iCode * ic)
1905 if (POINTER_SET (ic))
1907 if (!IS_LITERAL (getSpec (operandType (IC_RIGHT (ic)))))
1909 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
1912 for (k=0; k< OP_USES (IC_RESULT (ic))->size; k++)
1913 if (bitVectBitValue (OP_USES (IC_RESULT (ic)), k))
1915 uic = hTabItemWithKey (iCodehTab, k);
1918 if (uic->op != IFX && uic->op != JUMPTABLE)
1920 if (IC_LEFT (uic) && IC_LEFT (uic)->key == IC_RESULT (ic)->key)
1921 ReplaceOpWithCheaperOp(&IC_LEFT(uic), IC_RIGHT(ic));
1922 if (IC_RIGHT (uic) && IC_RIGHT (uic)->key == IC_RESULT (ic)->key)
1923 ReplaceOpWithCheaperOp(&IC_RIGHT(uic), IC_RIGHT(ic));
1924 if (IC_RESULT (uic) && IC_RESULT (uic)->key == IC_RESULT (ic)->key)
1925 ReplaceOpWithCheaperOp(&IC_RESULT(uic), IC_RIGHT(ic));
1933 /*-----------------------------------------------------------------*/
1934 /* packRegsForAssign - register reduction for assignment */
1935 /*-----------------------------------------------------------------*/
1937 packRegsForAssign (iCode * ic, eBBlock * ebp)
1941 if (!IS_ITEMP (IC_RIGHT (ic)) ||
1942 OP_SYMBOL (IC_RIGHT (ic))->isind ||
1943 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
1949 /* if the true symbol is defined in far space or on stack
1950 then we should not since this will increase register pressure */
1952 if (isOperandInFarSpace(IC_RESULT(ic)) && !farSpacePackable(ic)) {
1957 /* find the definition of iTempNN scanning backwards if we find a
1958 a use of the true symbol in before we find the definition then
1960 for (dic = ic->prev; dic; dic = dic->prev)
1963 #if 0 /* jwk: This collides with 1.43 but I really see no need for
1964 this anymore. It fixes bug #716790 and substantially improves
1965 redundant register usage around function calls.
1968 /* if there is a function call then don't pack it */
1969 if ((dic->op == CALL || dic->op == PCALL))
1979 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
1980 IS_OP_VOLATILE (IC_RESULT (dic)))
1986 if (IS_SYMOP (IC_RESULT (dic)) &&
1987 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1989 if (POINTER_SET (dic))
1995 if (IS_SYMOP (IC_RIGHT (dic)) &&
1996 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
1997 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2003 if (IS_SYMOP (IC_LEFT (dic)) &&
2004 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2005 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2011 if (POINTER_SET (dic) &&
2012 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2020 return 0; /* did not find */
2022 /* if assignment then check that right is not a bit */
2023 if (ASSIGNMENT (dic) && !POINTER_SET (dic))
2025 sym_link *etype = operandType (IC_RIGHT (dic));
2026 if (IS_BITFIELD (etype))
2028 /* if result is a bit too then it's ok */
2029 etype = operandType (IC_RESULT (dic));
2030 if (!IS_BITFIELD (etype))
2034 /* if the result is on stack or iaccess then it must be
2035 the same atleast one of the operands */
2036 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2037 OP_SYMBOL (IC_RESULT (ic))->iaccess)
2040 /* the operation has only one symbol
2041 operator then we can pack */
2042 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2043 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2046 if (!((IC_LEFT (dic) &&
2047 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2049 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2053 /* found the definition */
2054 /* replace the result with the result of */
2055 /* this assignment and remove this assignment */
2056 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2057 ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
2059 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2061 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2063 // TODO: and the otherway around?
2065 /* delete from liverange table also
2066 delete from all the points inbetween and the new
2068 for (sic = dic; sic != ic; sic = sic->next)
2070 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2071 if (IS_ITEMP (IC_RESULT (dic)))
2072 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2075 remiCodeFromeBBlock (ebp, ic);
2076 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2077 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2078 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2083 /*------------------------------------------------------------------*/
2084 /* findAssignToSym : scanning backwards looks for first assig found */
2085 /*------------------------------------------------------------------*/
2087 findAssignToSym (operand * op, iCode * ic)
2091 /* This routine is used to find sequences like
2093 ...; (intervening ops don't use iTempAA or modify FOO)
2094 blah = blah + iTempAA;
2096 and eliminate the use of iTempAA, freeing up its register for
2101 for (dic = ic->prev; dic; dic = dic->prev)
2104 /* if definition by assignment */
2105 if (dic->op == '=' &&
2106 !POINTER_SET (dic) &&
2107 IC_RESULT (dic)->key == op->key
2108 && IS_TRUE_SYMOP(IC_RIGHT(dic))
2110 break; /* found where this temp was defined */
2112 /* if we find an usage then we cannot delete it */
2113 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2116 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2119 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2124 return NULL; /* didn't find any assignment to op */
2126 /* we are interested only if defined in far space */
2127 /* or in stack space in case of + & - */
2129 /* if assigned to a non-symbol then don't repack regs */
2130 if (!IS_SYMOP (IC_RIGHT (dic)))
2133 /* if the symbol is volatile then we should not */
2134 if (isOperandVolatile (IC_RIGHT (dic), TRUE))
2136 /* XXX TODO --- should we be passing FALSE to isOperandVolatile()?
2137 What does it mean for an iTemp to be volatile, anyway? Passing
2138 TRUE is more cautious but may prevent possible optimizations */
2140 /* if the symbol is in far space then we should not */
2141 /* if (isOperandInFarSpace (IC_RIGHT (dic)))
2144 /* for + & - operations make sure that
2145 if it is on the stack it is the same
2146 as one of the three operands */
2148 if ((ic->op == '+' || ic->op == '-') &&
2149 OP_SYMBOL (IC_RIGHT (dic))->onStack)
2152 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2153 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2154 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2159 /* now make sure that the right side of dic
2160 is not defined between ic & dic */
2163 iCode *sic = dic->next;
2165 for (; sic != ic; sic = sic->next)
2166 if (IC_RESULT (sic) &&
2167 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2174 /*-----------------------------------------------------------------*/
2175 /* reassignAliasedSym - used by packRegsForSupport to replace */
2176 /* redundant iTemp with equivalent symbol */
2177 /*-----------------------------------------------------------------*/
2179 reassignAliasedSym (eBBlock *ebp, iCode *assignment, iCode *use, operand *op)
2182 unsigned oldSymKey, newSymKey;
2184 oldSymKey = op->key;
2185 newSymKey = IC_RIGHT(assignment)->key;
2187 /* only track live ranges of compiler-generated temporaries */
2188 if (!IS_ITEMP(IC_RIGHT(assignment)))
2191 /* update the live-value bitmaps */
2192 for (ic = assignment; ic != use; ic = ic->next) {
2193 bitVectUnSetBit (ic->rlive, oldSymKey);
2195 ic->rlive = bitVectSetBit (ic->rlive, newSymKey);
2198 /* update the sym of the used operand */
2199 OP_SYMBOL(op) = OP_SYMBOL(IC_RIGHT(assignment));
2200 op->key = OP_SYMBOL(op)->key;
2202 /* update the sym's liverange */
2203 if ( OP_LIVETO(op) < ic->seq )
2204 setToRange(op, ic->seq, FALSE);
2206 /* remove the assignment iCode now that its result is unused */
2207 remiCodeFromeBBlock (ebp, assignment);
2208 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(assignment))->defs, assignment->key);
2209 hTabDeleteItem (&iCodehTab, assignment->key, assignment, DELETE_ITEM, NULL);
2213 /*-----------------------------------------------------------------*/
2214 /* packRegsForSupport :- reduce some registers for support calls */
2215 /*-----------------------------------------------------------------*/
2217 packRegsForSupport (iCode * ic, eBBlock * ebp)
2222 /* for the left & right operand :- look to see if the
2223 left was assigned a true symbol in far space in that
2224 case replace them */
2226 if (IS_ITEMP (IC_LEFT (ic)) &&
2227 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2229 dic = findAssignToSym (IC_LEFT (ic), ic);
2233 /* found it we need to remove it from the block */
2234 reassignAliasedSym (ebp, dic, ic, IC_LEFT(ic));
2239 /* do the same for the right operand */
2240 if (IS_ITEMP (IC_RIGHT (ic)) &&
2241 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2243 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2247 /* found it we need to remove it from the block */
2248 reassignAliasedSym (ebp, dic, ic, IC_RIGHT(ic));
2256 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
2260 /*-----------------------------------------------------------------*/
2261 /* packRegsForOneuse : - will reduce some registers for single Use */
2262 /*-----------------------------------------------------------------*/
2264 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
2269 /* if returning a literal then do nothing */
2273 /* only up to 2 bytes */
2274 if (getSize (operandType (op)) > (fReturnSizeHC08 - 2))
2279 if (ic->op != SEND //RETURN
2281 && !POINTER_SET (ic)
2282 && !POINTER_GET (ic) )
2285 if (ic->op == SEND && ic->argreg != 1) return NULL;
2287 /* this routine will mark the a symbol as used in one
2288 instruction use only && if the defintion is local
2289 (ie. within the basic block) && has only one definition &&
2290 that definiion is either a return value from a
2291 function or does not contain any variables in
2293 uses = bitVectCopy (OP_USES (op));
2294 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
2295 if (!bitVectIsZero (uses)) /* has other uses */
2298 /* if it has only one defintion */
2299 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
2300 return NULL; /* has more than one definition */
2302 /* get that definition */
2304 hTabItemWithKey (iCodehTab,
2305 bitVectFirstBit (OP_DEFS (op)))))
2308 /* if that only usage is a cast */
2309 if (dic->op == CAST) {
2310 /* to a bigger type */
2311 if (getSize(OP_SYM_TYPE(IC_RESULT(dic))) >
2312 getSize(OP_SYM_TYPE(IC_RIGHT(dic)))) {
2313 /* than we can not, since we cannot predict the usage of b & acc */
2318 /* found the definition now check if it is local */
2319 if (dic->seq < ebp->fSeq ||
2320 dic->seq > ebp->lSeq)
2321 return NULL; /* non-local */
2323 /* now check if it is the return from
2325 if (dic->op == CALL || dic->op == PCALL)
2327 if (ic->op != SEND && ic->op != RETURN &&
2328 !POINTER_SET(ic) && !POINTER_GET(ic))
2330 OP_SYMBOL (op)->ruonly = 1;
2337 /* otherwise check that the definition does
2338 not contain any symbols in far space */
2339 // if (isOperandInFarSpace (IC_LEFT (dic)) ||
2340 // isOperandInFarSpace (IC_RIGHT (dic)) ||
2341 // IS_OP_RUONLY (IC_LEFT (ic)) ||
2342 // IS_OP_RUONLY (IC_RIGHT (ic)))
2347 /* if pointer set then make sure the pointer
2350 if (POINTER_SET (dic) &&
2351 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2354 if (POINTER_GET (dic) &&
2355 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2361 /* also make sure the intervenening instructions
2362 don't have any thing in far space */
2363 for (dic = dic->next; dic && dic != ic && sic != ic; dic = dic->next)
2366 /* if there is an intervening function call then no */
2367 if (dic->op == CALL || dic->op == PCALL)
2369 /* if pointer set then make sure the pointer
2372 if (POINTER_SET (dic) &&
2373 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2376 if (POINTER_GET (dic) &&
2377 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2380 /* if address of & the result is remat the okay */
2381 if (dic->op == ADDRESS_OF &&
2382 OP_SYMBOL (IC_RESULT (dic))->remat)
2385 /* if operand has size of three or more & this
2386 operation is a '*','/' or '%' then 'b' may
2389 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
2390 getSize (operandType (op)) >= 3)
2394 /* if left or right or result is in far space */
2395 // if (isOperandInFarSpace (IC_LEFT (dic)) ||
2396 // isOperandInFarSpace (IC_RIGHT (dic)) ||
2397 // isOperandInFarSpace (IC_RESULT (dic)) ||
2398 // IS_OP_RUONLY (IC_LEFT (dic)) ||
2399 // IS_OP_RUONLY (IC_RIGHT (dic)) ||
2400 // IS_OP_RUONLY (IC_RESULT (dic)))
2404 // /* if left or right or result is on stack */
2405 // if (isOperandOnStack(IC_LEFT(dic)) ||
2406 // isOperandOnStack(IC_RIGHT(dic)) ||
2407 // isOperandOnStack(IC_RESULT(dic))) {
2412 OP_SYMBOL (op)->ruonly = 1;
2417 /*-----------------------------------------------------------------*/
2418 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
2419 /*-----------------------------------------------------------------*/
2421 isBitwiseOptimizable (iCode * ic)
2423 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
2424 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
2426 /* bitwise operations are considered optimizable
2427 under the following conditions (Jean-Louis VERN)
2439 if (IS_LITERAL(rtype) ||
2440 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
2446 /*-----------------------------------------------------------------*/
2447 /* isCommutativeOp - tests whether this op cares what order its */
2448 /* operands are in */
2449 /*-----------------------------------------------------------------*/
2450 bool isCommutativeOp2(unsigned int op)
2452 if (op == '+' || op == '*' || op == EQ_OP ||
2453 op == '^' || op == '|' || op == BITWISEAND)
2459 /*-----------------------------------------------------------------*/
2460 /* operandUsesAcc2 - determines whether the code generated for this */
2461 /* operand will have to use the accumulator */
2462 /*-----------------------------------------------------------------*/
2463 bool operandUsesAcc2(operand *op)
2469 symbol *sym = OP_SYMBOL(op);
2473 return TRUE; /* duh! */
2475 // if (IN_STACK(sym->etype) || sym->onStack ||
2476 // (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
2477 // return TRUE; /* acc is used to calc stack offset */
2482 sym = SPIL_LOC(op); /* if spilled, look at spill location */
2484 return FALSE; /* more checks? */
2488 symspace = SPEC_OCLS(sym->etype);
2490 // if (sym->iaccess && symspace->paged)
2491 // return TRUE; /* must fetch paged indirect sym via accumulator */
2493 if (IN_BITSPACE(symspace))
2494 return TRUE; /* fetching bit vars uses the accumulator */
2496 if (IN_FARSPACE(symspace) || IN_CODESPACE(symspace))
2497 return TRUE; /* fetched via accumulator and dptr */
2503 /*-----------------------------------------------------------------*/
2504 /* canDefAccResult - return 1 if the iCode can generate a result */
2506 /*-----------------------------------------------------------------*/
2508 canDefAccResult (iCode * ic)
2512 if (ic->op == IFX || ic->op == JUMPTABLE) /* these iCodes have no result */
2515 if (POINTER_SET (ic))
2518 if (!IC_RESULT (ic))
2521 if (!IS_ITEMP (IC_RESULT (ic)))
2524 /* I don't think an iTemp can be an aggregate, but just in case */
2525 if (IS_AGGREGATE(operandType(IC_RESULT(ic))))
2528 size = getSize (operandType (IC_RESULT (ic)));
2532 /* All 1 byte operations should safely generate an accumulator result */
2541 return isOperandLiteral (IC_RIGHT (ic))
2542 && SPEC_USIGN (operandType (IC_RESULT (ic)));
2547 case '=': /* assignment, since POINTER_SET is already ruled out */
2558 /*-----------------------------------------------------------------*/
2559 /* canUseAccOperand - return 1 if the iCode can use the operand */
2560 /* when passed in A or XA */
2561 /*-----------------------------------------------------------------*/
2563 canUseAccOperand (iCode * ic, operand * op)
2570 if (isOperandEqual (op, IC_COND (ic)))
2576 if (ic->op == JUMPTABLE)
2578 if (isOperandEqual (op, IC_JTCOND (ic)))
2584 if (POINTER_SET (ic) && isOperandEqual (op, IC_RESULT (ic)))
2587 if (isOperandEqual (op, IC_LEFT (ic)))
2588 otherOp = IC_RIGHT (ic);
2589 else if (isOperandEqual (op, IC_RIGHT (ic)))
2590 otherOp = IC_LEFT (ic);
2594 /* Generation of SEND is deferred until CALL; not safe */
2595 /* if there are intermediate iCodes */
2596 if (ic->op == SEND && ic->next && ic->next->op != CALL)
2599 size = getSize (operandType (op));
2602 /* All 1 byte operations should safely use an accumulator operand */
2611 return isOperandLiteral (IC_RIGHT (ic));
2623 /*-----------------------------------------------------------------*/
2624 /* packRegsForAccUse - pack registers for acc use */
2625 /*-----------------------------------------------------------------*/
2627 packRegsForAccUse (iCode * ic)
2632 if (!canDefAccResult (ic))
2635 op = IC_RESULT (ic);
2637 /* has only one definition */
2638 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
2641 /* has only one use */
2642 if (bitVectnBitsOn (OP_USES (op)) > 1)
2649 if (!canUseAccOperand (uic, op))
2653 if ((POINTER_GET(uic))
2654 || (ic->op == ADDRESS_OF && uic->op == '+' && IS_OP_LITERAL (IC_RIGHT (uic))))
2656 OP_SYMBOL (IC_RESULT (ic))->accuse = ACCUSE_HX;
2661 OP_SYMBOL (IC_RESULT (ic))->accuse = ACCUSE_XA;
2665 /*-----------------------------------------------------------------*/
2666 /* packForPush - hueristics to reduce iCode for pushing */
2667 /*-----------------------------------------------------------------*/
2669 packForPush (iCode * ic, eBBlock ** ebpp, int blockno)
2673 struct eBBlock * ebp=ebpp[blockno];
2675 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
2678 /* must have only definition & one usage */
2679 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
2680 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
2683 /* find the definition */
2684 if (!(dic = hTabItemWithKey (iCodehTab,
2685 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
2688 if (dic->op != '=' || POINTER_SET (dic))
2691 if (dic->seq < ebp->fSeq) { // Evelyn did this
2693 for (i=0; i<blockno; i++) {
2694 if (dic->seq >= ebpp[i]->fSeq && dic->seq <= ebpp[i]->lSeq) {
2699 wassert (i!=blockno); // no way to recover from here
2702 if (IS_SYMOP(IC_RIGHT(dic))) {
2703 /* make sure the right side does not have any definitions
2705 dbv = OP_DEFS(IC_RIGHT(dic));
2706 for (lic = ic; lic && lic != dic ; lic = lic->prev) {
2707 if (bitVectBitValue(dbv,lic->key))
2710 /* make sure they have the same type */
2711 if (IS_SPEC(operandType(IC_LEFT(ic))))
2713 sym_link *itype=operandType(IC_LEFT(ic));
2714 sym_link *ditype=operandType(IC_RIGHT(dic));
2716 if (SPEC_USIGN(itype)!=SPEC_USIGN(ditype) ||
2717 SPEC_LONG(itype)!=SPEC_LONG(ditype))
2720 /* extend the live range of replaced operand if needed */
2721 if (OP_SYMBOL(IC_RIGHT(dic))->liveTo < ic->seq) {
2722 OP_SYMBOL(IC_RIGHT(dic))->liveTo = ic->seq;
2724 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2727 /* we now we know that it has one & only one def & use
2728 and the that the definition is an assignment */
2729 ReplaceOpWithCheaperOp(&IC_LEFT (ic), IC_RIGHT (dic));
2730 remiCodeFromeBBlock (ebp, dic);
2731 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2734 /*-----------------------------------------------------------------*/
2735 /* packRegisters - does some transformations to reduce register */
2737 /*-----------------------------------------------------------------*/
2739 packRegisters (eBBlock ** ebpp, int blockno)
2743 eBBlock *ebp=ebpp[blockno];
2750 /* look for assignments of the form */
2751 /* iTempNN = TRueSym (someoperation) SomeOperand */
2753 /* TrueSym := iTempNN:1 */
2754 for (ic = ebp->sch; ic; ic = ic->next)
2756 /* find assignment of the form TrueSym := iTempNN:1 */
2757 if (ic->op == '=' && !POINTER_SET (ic) )
2758 change += packRegsForAssign (ic, ebp);
2765 for (ic = ebp->sch; ic; ic = ic->next)
2767 //packRegsForLiteral (ic);
2769 /* if this is an itemp & result of an address of a true sym
2770 then mark this as rematerialisable */
2771 if (ic->op == ADDRESS_OF &&
2772 IS_ITEMP (IC_RESULT (ic)) &&
2773 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
2774 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2775 !OP_SYMBOL (IC_LEFT (ic))->onStack )
2778 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2779 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2780 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2784 if (ic->op == '=' &&
2785 !POINTER_SET (ic) &&
2786 IS_ITEMP (IC_RESULT (ic)) &&
2787 IS_VALOP (IC_RIGHT (ic)) &&
2788 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1)
2791 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2792 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2793 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2797 /* if straight assignment then carry remat flag if
2798 this is the only definition */
2799 if (ic->op == '=' &&
2800 !POINTER_SET (ic) &&
2801 IS_SYMOP (IC_RIGHT (ic)) &&
2802 OP_SYMBOL (IC_RIGHT (ic))->remat &&
2803 !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode) &&
2804 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
2807 OP_SYMBOL (IC_RESULT (ic))->remat =
2808 OP_SYMBOL (IC_RIGHT (ic))->remat;
2809 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
2810 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
2813 /* if cast to a generic pointer & the pointer being
2814 cast is remat, then we can remat this cast as well */
2815 if (ic->op == CAST &&
2816 IS_SYMOP(IC_RIGHT(ic)) &&
2817 OP_SYMBOL(IC_RIGHT(ic))->remat &&
2818 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1) {
2819 sym_link *to_type = operandType(IC_LEFT(ic));
2820 sym_link *from_type = operandType(IC_RIGHT(ic));
2821 if (IS_GENPTR(to_type) && IS_PTR(from_type)) {
2822 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2823 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2824 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2828 /* if this is a +/- operation with a rematerizable
2829 then mark this as rematerializable as well */
2830 if ((ic->op == '+' || ic->op == '-') &&
2831 (IS_SYMOP (IC_LEFT (ic)) &&
2832 IS_ITEMP (IC_RESULT (ic)) &&
2833 IS_OP_LITERAL (IC_RIGHT (ic))) &&
2834 OP_SYMBOL (IC_LEFT (ic))->remat &&
2835 (!IS_SYMOP (IC_RIGHT (ic)) || !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode)) &&
2836 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1)
2838 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2839 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2840 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2843 /* mark the pointer usages */
2844 if (POINTER_SET (ic))
2845 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
2847 if (POINTER_GET (ic) &&
2848 IS_SYMOP(IC_LEFT (ic)))
2849 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
2854 /* if we are using a symbol on the stack
2855 then we should say hc08_ptrRegReq */
2856 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
2857 hc08_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
2858 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
2859 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
2860 hc08_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
2861 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
2864 if (IS_SYMOP (IC_LEFT (ic)))
2865 hc08_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
2866 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
2867 if (IS_SYMOP (IC_RIGHT (ic)))
2868 hc08_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
2869 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
2870 if (IS_SYMOP (IC_RESULT (ic)))
2871 hc08_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
2872 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
2877 /* if the condition of an if instruction
2878 is defined in the previous instruction and
2879 this is the only usage then
2880 mark the itemp as a conditional */
2881 if ((IS_CONDITIONAL (ic) ||
2882 (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic))) &&
2883 ic->next && ic->next->op == IFX &&
2884 bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
2885 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
2886 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2888 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
2893 /* if the condition of an if instruction
2894 is defined in the previous GET_POINTER instruction and
2895 this is the only usage then
2896 mark the itemp as accumulator use */
2897 if ((POINTER_GET (ic) && getSize (operandType (IC_RESULT (ic))) <=1) &&
2898 ic->next && ic->next->op == IFX &&
2899 bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
2900 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
2901 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2903 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2907 if (ic->op != IFX && ic->op !=JUMPTABLE && !POINTER_SET (ic)
2908 && IC_RESULT (ic) && IS_ITEMP (IC_RESULT (ic))
2909 && getSize (operandType (IC_RESULT (ic))) == 1
2910 && bitVectnBitsOn (OP_USES (IC_RESULT (ic))) == 1
2912 && OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2916 if (ic->next->op == IFX)
2918 if (isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)))
2921 else if (ic->next->op == JUMPTABLE)
2923 if (isOperandEqual (IC_RESULT (ic), IC_JTCOND (ic->next)))
2928 if (isOperandEqual (IC_RESULT (ic), IC_LEFT (ic->next)))
2930 if (isOperandEqual (IC_RESULT (ic), IC_RIGHT (ic->next)))
2936 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2943 /* reduce for support function calls */
2944 if (ic->supportRtn || (ic->op != IFX && ic->op != JUMPTABLE))
2945 packRegsForSupport (ic, ebp);
2948 /* some cases the redundant moves can
2949 can be eliminated for return statements */
2950 if ((ic->op == RETURN || (ic->op == SEND && ic->argreg == 1)) &&
2951 /* !isOperandInFarSpace (IC_LEFT (ic)) && */
2952 options.model == MODEL_SMALL) {
2953 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2956 /* if pointer set & left has a size more than
2957 one and right is not in far space */
2958 if (POINTER_SET (ic) &&
2959 /* !isOperandInFarSpace (IC_RIGHT (ic)) && */
2960 !OP_SYMBOL (IC_RESULT (ic))->remat &&
2961 !IS_OP_RUONLY (IC_RIGHT (ic))
2962 /* && getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1 */ )
2963 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
2965 /* if pointer get */
2966 if (POINTER_GET (ic) &&
2967 IS_SYMOP (IC_LEFT (ic)) &&
2968 /* !isOperandInFarSpace (IC_RESULT (ic)) && */
2969 !OP_SYMBOL (IC_LEFT (ic))->remat &&
2970 !IS_OP_RUONLY (IC_RESULT (ic))
2971 /* && getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1 */)
2972 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2975 /* if this is cast for intergral promotion then
2976 check if only use of the definition of the
2977 operand being casted/ if yes then replace
2978 the result of that arithmetic operation with
2979 this result and get rid of the cast */
2982 sym_link *fromType = operandType (IC_RIGHT (ic));
2983 sym_link *toType = operandType (IC_LEFT (ic));
2985 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
2986 getSize (fromType) != getSize (toType) &&
2987 SPEC_USIGN (fromType) == SPEC_USIGN (toType))
2990 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2993 if (IS_ARITHMETIC_OP (dic))
2995 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2996 ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
2997 remiCodeFromeBBlock (ebp, ic);
2998 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2999 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3000 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3004 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3010 /* if the type from and type to are the same
3011 then if this is the only use then packit */
3012 if (compareType (operandType (IC_RIGHT (ic)),
3013 operandType (IC_LEFT (ic))) == 1)
3015 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3018 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3019 ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
3020 remiCodeFromeBBlock (ebp, ic);
3021 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3022 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3023 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3032 iTempNN := (some variable in farspace) V1
3037 if (ic->op == IPUSH)
3039 packForPush (ic, ebpp, blockno);
3042 packRegsForAccUse (ic);
3046 /*-----------------------------------------------------------------*/
3047 /* assignRegisters - assigns registers to each live range as need */
3048 /*-----------------------------------------------------------------*/
3050 hc08_assignRegisters (eBBlock ** ebbs, int count)
3055 setToNull ((void *) &_G.funcrUsed);
3056 setToNull ((void *) &_G.regAssigned);
3057 setToNull ((void *) &_G.totRegAssigned);
3058 hc08_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3060 hc08_reg_a = hc08_regWithIdx(A_IDX);
3061 hc08_reg_x = hc08_regWithIdx(X_IDX);
3062 hc08_reg_h = hc08_regWithIdx(H_IDX);
3063 hc08_reg_hx = hc08_regWithIdx(HX_IDX);
3064 hc08_reg_xa = hc08_regWithIdx(XA_IDX);
3065 hc08_reg_sp = hc08_regWithIdx(SP_IDX);
3068 /* change assignments this will remove some
3069 live ranges reducing some register pressure */
3070 for (i = 0; i < count; i++)
3071 packRegisters (ebbs, i);
3073 /* liveranges probably changed by register packing
3074 so we compute them again */
3075 recomputeLiveRanges (ebbs, count);
3077 if (options.dump_pack)
3078 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3080 /* first determine for each live range the number of
3081 registers & the type of registers required for each */
3084 /* and serially allocate registers */
3085 serialRegAssign (ebbs, count);
3088 //setToNull ((void *) &_G.regAssigned);
3089 //setToNull ((void *) &_G.totRegAssigned);
3092 /* if stack was extended then tell the user */
3095 /* werror(W_TOOMANY_SPILS,"stack", */
3096 /* _G.stackExtend,currFunc->name,""); */
3102 /* werror(W_TOOMANY_SPILS,"data space", */
3103 /* _G.dataExtend,currFunc->name,""); */
3107 /* after that create the register mask
3108 for each of the instruction */
3109 createRegMask (ebbs, count);
3111 /* redo that offsets for stacked automatic variables */
3113 redoStackOffsets ();
3116 if (options.dump_rassgn)
3118 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3119 dumpLiveRanges (DUMP_LRANGE, liveRanges);
3122 /* do the overlaysegment stuff SDCCmem.c */
3123 doOverlays (ebbs, count);
3125 /* now get back the chain */
3126 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3130 /* free up any _G.stackSpil locations allocated */
3131 applyToSet (_G.stackSpil, deallocStackSpil);
3133 setToNull ((void **) &_G.stackSpil);
3134 setToNull ((void **) &_G.spiltSet);
3135 /* mark all registers as free */