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, "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 has 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 livernages that was 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));
2546 case '=': /* assignment, since POINTER_SET is already ruled out */
2557 /*-----------------------------------------------------------------*/
2558 /* canUseAccOperand - return 1 if the iCode can use the operand */
2559 /* when passed in A or XA */
2560 /*-----------------------------------------------------------------*/
2562 canUseAccOperand (iCode * ic, operand * op)
2569 if (isOperandEqual (op, IC_COND (ic)))
2575 if (ic->op == JUMPTABLE)
2577 if (isOperandEqual (op, IC_JTCOND (ic)))
2583 if (POINTER_SET (ic) && isOperandEqual (op, IC_RESULT (ic)))
2586 if (isOperandEqual (op, IC_LEFT (ic)))
2587 otherOp = IC_RIGHT (ic);
2588 else if (isOperandEqual (op, IC_RIGHT (ic)))
2589 otherOp = IC_LEFT (ic);
2593 /* Generation of SEND is deferred until CALL; not safe */
2594 /* if there are intermediate iCodes */
2595 if (ic->op == SEND && ic->next && ic->next->op != CALL)
2598 size = getSize (operandType (op));
2601 /* All 1 byte operations should safely use an accumulator operand */
2610 return isOperandLiteral (IC_RIGHT (ic));
2622 /*-----------------------------------------------------------------*/
2623 /* packRegsForAccUse - pack registers for acc use */
2624 /*-----------------------------------------------------------------*/
2626 packRegsForAccUse (iCode * ic)
2631 if (!canDefAccResult (ic))
2634 op = IC_RESULT (ic);
2636 /* has only one definition */
2637 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
2640 /* has only one use */
2641 if (bitVectnBitsOn (OP_USES (op)) > 1)
2648 if (!canUseAccOperand (uic, op))
2652 if ((POINTER_GET(uic))
2653 || (ic->op == ADDRESS_OF && uic->op == '+' && IS_OP_LITERAL (IC_RIGHT (uic))))
2655 OP_SYMBOL (IC_RESULT (ic))->accuse = ACCUSE_HX;
2660 OP_SYMBOL (IC_RESULT (ic))->accuse = ACCUSE_XA;
2664 /*-----------------------------------------------------------------*/
2665 /* packForPush - hueristics to reduce iCode for pushing */
2666 /*-----------------------------------------------------------------*/
2668 packForPush (iCode * ic, eBBlock ** ebpp, int blockno)
2672 struct eBBlock * ebp=ebpp[blockno];
2674 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
2677 /* must have only definition & one usage */
2678 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
2679 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
2682 /* find the definition */
2683 if (!(dic = hTabItemWithKey (iCodehTab,
2684 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
2687 if (dic->op != '=' || POINTER_SET (dic))
2690 if (dic->seq < ebp->fSeq) { // Evelyn did this
2692 for (i=0; i<blockno; i++) {
2693 if (dic->seq >= ebpp[i]->fSeq && dic->seq <= ebpp[i]->lSeq) {
2698 wassert (i!=blockno); // no way to recover from here
2701 if (IS_SYMOP(IC_RIGHT(dic))) {
2702 /* make sure the right side does not have any definitions
2704 dbv = OP_DEFS(IC_RIGHT(dic));
2705 for (lic = ic; lic && lic != dic ; lic = lic->prev) {
2706 if (bitVectBitValue(dbv,lic->key))
2709 /* make sure they have the same type */
2710 if (IS_SPEC(operandType(IC_LEFT(ic))))
2712 sym_link *itype=operandType(IC_LEFT(ic));
2713 sym_link *ditype=operandType(IC_RIGHT(dic));
2715 if (SPEC_USIGN(itype)!=SPEC_USIGN(ditype) ||
2716 SPEC_LONG(itype)!=SPEC_LONG(ditype))
2719 /* extend the live range of replaced operand if needed */
2720 if (OP_SYMBOL(IC_RIGHT(dic))->liveTo < ic->seq) {
2721 OP_SYMBOL(IC_RIGHT(dic))->liveTo = ic->seq;
2723 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2726 /* we now we know that it has one & only one def & use
2727 and the that the definition is an assignment */
2728 ReplaceOpWithCheaperOp(&IC_LEFT (ic), IC_RIGHT (dic));
2729 remiCodeFromeBBlock (ebp, dic);
2730 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2733 /*-----------------------------------------------------------------*/
2734 /* packRegisters - does some transformations to reduce register */
2736 /*-----------------------------------------------------------------*/
2738 packRegisters (eBBlock ** ebpp, int blockno)
2742 eBBlock *ebp=ebpp[blockno];
2749 /* look for assignments of the form */
2750 /* iTempNN = TRueSym (someoperation) SomeOperand */
2752 /* TrueSym := iTempNN:1 */
2753 for (ic = ebp->sch; ic; ic = ic->next)
2755 /* find assignment of the form TrueSym := iTempNN:1 */
2756 if (ic->op == '=' && !POINTER_SET (ic) )
2757 change += packRegsForAssign (ic, ebp);
2764 for (ic = ebp->sch; ic; ic = ic->next)
2766 //packRegsForLiteral (ic);
2768 /* if this is an itemp & result of an address of a true sym
2769 then mark this as rematerialisable */
2770 if (ic->op == ADDRESS_OF &&
2771 IS_ITEMP (IC_RESULT (ic)) &&
2772 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
2773 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2774 !OP_SYMBOL (IC_LEFT (ic))->onStack )
2777 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2778 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2779 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2783 if (ic->op == '=' &&
2784 !POINTER_SET (ic) &&
2785 IS_ITEMP (IC_RESULT (ic)) &&
2786 IS_VALOP (IC_RIGHT (ic)) &&
2787 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1)
2790 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2791 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2792 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2796 /* if straight assignment then carry remat flag if
2797 this is the only definition */
2798 if (ic->op == '=' &&
2799 !POINTER_SET (ic) &&
2800 IS_SYMOP (IC_RIGHT (ic)) &&
2801 OP_SYMBOL (IC_RIGHT (ic))->remat &&
2802 !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode) &&
2803 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
2806 OP_SYMBOL (IC_RESULT (ic))->remat =
2807 OP_SYMBOL (IC_RIGHT (ic))->remat;
2808 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
2809 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
2812 /* if cast to a generic pointer & the pointer being
2813 cast is remat, then we can remat this cast as well */
2814 if (ic->op == CAST &&
2815 IS_SYMOP(IC_RIGHT(ic)) &&
2816 OP_SYMBOL(IC_RIGHT(ic))->remat &&
2817 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1) {
2818 sym_link *to_type = operandType(IC_LEFT(ic));
2819 sym_link *from_type = operandType(IC_RIGHT(ic));
2820 if (IS_GENPTR(to_type) && IS_PTR(from_type)) {
2821 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2822 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2823 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2827 /* if this is a +/- operation with a rematerizable
2828 then mark this as rematerializable as well */
2829 if ((ic->op == '+' || ic->op == '-') &&
2830 (IS_SYMOP (IC_LEFT (ic)) &&
2831 IS_ITEMP (IC_RESULT (ic)) &&
2832 IS_OP_LITERAL (IC_RIGHT (ic))) &&
2833 OP_SYMBOL (IC_LEFT (ic))->remat &&
2834 (!IS_SYMOP (IC_RIGHT (ic)) || !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode)) &&
2835 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1)
2837 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2838 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2839 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2842 /* mark the pointer usages */
2843 if (POINTER_SET (ic))
2844 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
2846 if (POINTER_GET (ic) &&
2847 IS_SYMOP(IC_LEFT (ic)))
2848 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
2853 /* if we are using a symbol on the stack
2854 then we should say hc08_ptrRegReq */
2855 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
2856 hc08_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
2857 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
2858 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
2859 hc08_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
2860 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
2863 if (IS_SYMOP (IC_LEFT (ic)))
2864 hc08_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
2865 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
2866 if (IS_SYMOP (IC_RIGHT (ic)))
2867 hc08_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
2868 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
2869 if (IS_SYMOP (IC_RESULT (ic)))
2870 hc08_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
2871 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
2876 /* if the condition of an if instruction
2877 is defined in the previous instruction and
2878 this is the only usage then
2879 mark the itemp as a conditional */
2880 if ((IS_CONDITIONAL (ic) ||
2881 (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic))) &&
2882 ic->next && ic->next->op == IFX &&
2883 bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
2884 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
2885 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2887 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
2892 /* if the condition of an if instruction
2893 is defined in the previous GET_POINTER instruction and
2894 this is the only usage then
2895 mark the itemp as accumulator use */
2896 if ((POINTER_GET (ic) && getSize (operandType (IC_RESULT (ic))) <=1) &&
2897 ic->next && ic->next->op == IFX &&
2898 bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
2899 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
2900 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2902 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2906 if (ic->op != IFX && ic->op !=JUMPTABLE && !POINTER_SET (ic)
2907 && IC_RESULT (ic) && IS_ITEMP (IC_RESULT (ic))
2908 && getSize (operandType (IC_RESULT (ic))) == 1
2909 && bitVectnBitsOn (OP_USES (IC_RESULT (ic))) == 1
2911 && OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2915 if (ic->next->op == IFX)
2917 if (isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)))
2920 else if (ic->next->op == JUMPTABLE)
2922 if (isOperandEqual (IC_RESULT (ic), IC_JTCOND (ic->next)))
2927 if (isOperandEqual (IC_RESULT (ic), IC_LEFT (ic->next)))
2929 if (isOperandEqual (IC_RESULT (ic), IC_RIGHT (ic->next)))
2935 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2942 /* reduce for support function calls */
2943 if (ic->supportRtn || (ic->op != IFX && ic->op != JUMPTABLE))
2944 packRegsForSupport (ic, ebp);
2947 /* some cases the redundant moves can
2948 can be eliminated for return statements */
2949 if ((ic->op == RETURN || (ic->op == SEND && ic->argreg == 1)) &&
2950 /* !isOperandInFarSpace (IC_LEFT (ic)) && */
2951 options.model == MODEL_SMALL) {
2952 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2955 /* if pointer set & left has a size more than
2956 one and right is not in far space */
2957 if (POINTER_SET (ic) &&
2958 /* !isOperandInFarSpace (IC_RIGHT (ic)) && */
2959 !OP_SYMBOL (IC_RESULT (ic))->remat &&
2960 !IS_OP_RUONLY (IC_RIGHT (ic))
2961 /* && getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1 */ )
2962 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
2964 /* if pointer get */
2965 if (POINTER_GET (ic) &&
2966 IS_SYMOP (IC_LEFT (ic)) &&
2967 /* !isOperandInFarSpace (IC_RESULT (ic)) && */
2968 !OP_SYMBOL (IC_LEFT (ic))->remat &&
2969 !IS_OP_RUONLY (IC_RESULT (ic))
2970 /* && getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1 */)
2971 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2974 /* if this is cast for intergral promotion then
2975 check if only use of the definition of the
2976 operand being casted/ if yes then replace
2977 the result of that arithmetic operation with
2978 this result and get rid of the cast */
2981 sym_link *fromType = operandType (IC_RIGHT (ic));
2982 sym_link *toType = operandType (IC_LEFT (ic));
2984 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
2985 getSize (fromType) != getSize (toType) &&
2986 SPEC_USIGN (fromType) == SPEC_USIGN (toType))
2989 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2992 if (IS_ARITHMETIC_OP (dic))
2994 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2995 ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
2996 remiCodeFromeBBlock (ebp, ic);
2997 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2998 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2999 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3003 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3009 /* if the type from and type to are the same
3010 then if this is the only use then packit */
3011 if (compareType (operandType (IC_RIGHT (ic)),
3012 operandType (IC_LEFT (ic))) == 1)
3014 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3017 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3018 ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
3019 remiCodeFromeBBlock (ebp, ic);
3020 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3021 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3022 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3031 iTempNN := (some variable in farspace) V1
3036 if (ic->op == IPUSH)
3038 packForPush (ic, ebpp, blockno);
3041 packRegsForAccUse (ic);
3045 /*-----------------------------------------------------------------*/
3046 /* assignRegisters - assigns registers to each live range as need */
3047 /*-----------------------------------------------------------------*/
3049 hc08_assignRegisters (eBBlock ** ebbs, int count)
3054 setToNull ((void *) &_G.funcrUsed);
3055 setToNull ((void *) &_G.regAssigned);
3056 setToNull ((void *) &_G.totRegAssigned);
3057 hc08_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3059 hc08_reg_a = hc08_regWithIdx(A_IDX);
3060 hc08_reg_x = hc08_regWithIdx(X_IDX);
3061 hc08_reg_h = hc08_regWithIdx(H_IDX);
3062 hc08_reg_hx = hc08_regWithIdx(HX_IDX);
3063 hc08_reg_xa = hc08_regWithIdx(XA_IDX);
3064 hc08_reg_sp = hc08_regWithIdx(SP_IDX);
3067 /* change assignments this will remove some
3068 live ranges reducing some register pressure */
3069 for (i = 0; i < count; i++)
3070 packRegisters (ebbs, i);
3072 /* liveranges probably changed by register packing
3073 so we compute them again */
3074 recomputeLiveRanges (ebbs, count);
3076 if (options.dump_pack)
3077 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3079 /* first determine for each live range the number of
3080 registers & the type of registers required for each */
3083 /* and serially allocate registers */
3084 serialRegAssign (ebbs, count);
3087 //setToNull ((void *) &_G.regAssigned);
3088 //setToNull ((void *) &_G.totRegAssigned);
3091 /* if stack was extended then tell the user */
3094 /* werror(W_TOOMANY_SPILS,"stack", */
3095 /* _G.stackExtend,currFunc->name,""); */
3101 /* werror(W_TOOMANY_SPILS,"data space", */
3102 /* _G.dataExtend,currFunc->name,""); */
3106 /* after that create the register mask
3107 for each of the instruction */
3108 createRegMask (ebbs, count);
3110 /* redo that offsets for stacked automatic variables */
3112 redoStackOffsets ();
3115 if (options.dump_rassgn)
3117 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3118 dumpLiveRanges (DUMP_LRANGE, liveRanges);
3121 /* do the overlaysegment stuff SDCCmem.c */
3122 doOverlays (ebbs, count);
3124 /* now get back the chain */
3125 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3129 /* free up any _G.stackSpil locations allocated */
3130 applyToSet (_G.stackSpil, deallocStackSpil);
3132 setToNull ((void **) &_G.stackSpil);
3133 setToNull ((void **) &_G.spiltSet);
3134 /* mark all registers as free */