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->regType == sym->regType && /* same register types */
1036 result->nRegs && /* which needs registers */
1037 !result->isspilt && /* and does not already have them */
1039 !bitVectBitValue (_G.regAssigned, result->key) &&
1040 /* the number of free regs + number of regs in this LR
1041 can accomodate the what result Needs */
1042 ((nfreeRegsType (result->regType) +
1043 sym->nRegs) >= result->nRegs)
1047 for (i = 0; i < result->nRegs; i++)
1049 result->regs[i] = sym->regs[i];
1051 result->regs[i] = getRegGpr (ic, ebp, result);
1053 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1054 _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, result->key);
1058 /* free the remaining */
1059 for (; i < sym->nRegs; i++)
1063 if (!symHasReg (psym, sym->regs[i]))
1064 hc08_freeReg (sym->regs[i]);
1067 hc08_freeReg (sym->regs[i]);
1074 /*-----------------------------------------------------------------*/
1075 /* reassignLR - reassign this to registers */
1076 /*-----------------------------------------------------------------*/
1078 reassignLR (operand * op)
1080 symbol *sym = OP_SYMBOL (op);
1083 /* not spilt any more */
1084 sym->isspilt = sym->spillA = sym->blockSpil = sym->remainSpil = 0;
1085 bitVectUnSetBit (_G.spiltSet, sym->key);
1087 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1088 _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key);
1092 for (i = 0; i < sym->nRegs; i++)
1093 sym->regs[i]->isFree = 0;
1096 /*-----------------------------------------------------------------*/
1097 /* willCauseSpill - determines if allocating will cause a spill */
1098 /*-----------------------------------------------------------------*/
1100 willCauseSpill (int nr, int rt)
1102 /* first check if there are any avlb registers
1103 of te type required */
1106 /* special case for pointer type
1107 if pointer type not avlb then
1108 check for type gpr */
1109 if (nFreeRegs (rt) >= nr)
1111 if (nFreeRegs (REG_GPR) >= nr)
1118 if (nFreeRegs (rt) >= nr)
1123 if (nFreeRegs (REG_PTR) +
1124 nFreeRegs (REG_GPR) >= nr)
1129 /* it will cause a spil */
1133 /*-----------------------------------------------------------------*/
1134 /* positionRegs - the allocator can allocate same registers to res- */
1135 /* ult and operand, if this happens make sure they are in the same */
1136 /* position as the operand otherwise chaos results */
1137 /*-----------------------------------------------------------------*/
1139 positionRegs (symbol * result, symbol * opsym)
1141 int count = min (result->nRegs, opsym->nRegs);
1142 int i, j = 0, shared = 0;
1145 /* if the result has been spilt then cannot share */
1150 /* first make sure that they actually share */
1151 for (i = 0; i < count; i++)
1153 for (j = 0; j < count; j++)
1155 if (result->regs[i] == opsym->regs[j] && i != j)
1165 regs *tmp = result->regs[i];
1166 result->regs[i] = result->regs[j];
1167 result->regs[j] = tmp;
1174 /*------------------------------------------------------------------*/
1175 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
1176 /* it should either have registers or have beed spilled. Otherwise, */
1177 /* there was an uninitialized variable, so just spill this to get */
1178 /* the operand in a valid state. */
1179 /*------------------------------------------------------------------*/
1181 verifyRegsAssigned (operand *op, iCode * ic)
1186 if (!IS_ITEMP (op)) return;
1188 sym = OP_SYMBOL (op);
1189 if (sym->isspilt) return;
1190 if (!sym->nRegs) return;
1191 if (sym->regs[0]) return;
1193 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
1194 sym->prereqv ? sym->prereqv->name : sym->name);
1200 /*-----------------------------------------------------------------*/
1201 /* serialRegAssign - serially allocate registers to the variables */
1202 /*-----------------------------------------------------------------*/
1204 serialRegAssign (eBBlock ** ebbs, int count)
1208 /* for all blocks */
1209 for (i = 0; i < count; i++) {
1213 if (ebbs[i]->noPath &&
1214 (ebbs[i]->entryLabel != entryLabel &&
1215 ebbs[i]->entryLabel != returnLabel))
1218 /* of all instructions do */
1219 for (ic = ebbs[i]->sch; ic; ic = ic->next) {
1223 // update the registers in use at the start of this icode
1224 for (reg=0; reg<hc08_nRegs; reg++) {
1225 if (regshc08[reg].isFree) {
1226 ic->riu &= ~(regshc08[reg].mask);
1228 ic->riu |= (regshc08[reg].mask);
1233 /* if this is an ipop that means some live
1234 range will have to be assigned again */
1236 reassignLR (IC_LEFT (ic));
1238 /* if result is present && is a true symbol */
1239 if (IC_RESULT (ic) && ic->op != IFX &&
1240 IS_TRUE_SYMOP (IC_RESULT (ic)))
1241 OP_SYMBOL (IC_RESULT (ic))->allocreq++;
1243 /* take away registers from live
1244 ranges that end at this instruction */
1245 deassignLRs (ic, ebbs[i]);
1247 /* some don't need registers */
1248 if (SKIP_IC2 (ic) ||
1249 ic->op == JUMPTABLE ||
1253 (IC_RESULT (ic) && POINTER_SET (ic)))
1256 /* now we need to allocate registers
1257 only for the result */
1258 if (IC_RESULT (ic)) {
1259 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
1265 /* if it does not need or is spilt
1266 or is already assigned to registers
1267 or will not live beyond this instructions */
1270 bitVectBitValue (_G.regAssigned, sym->key) ||
1271 sym->liveTo <= ic->seq)
1274 /* if some liverange has been spilt at the block level
1275 and this one live beyond this block then spil this
1277 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq) {
1281 /* if trying to allocate this will cause
1282 a spill and there is nothing to spill
1283 or this one is rematerializable then
1285 willCS = willCauseSpill (sym->nRegs, sym->regType);
1286 spillable = computeSpillable (ic);
1287 if (sym->remat || (willCS && bitVectIsZero (spillable))) {
1292 /* If the live range preceeds the point of definition
1293 then ideally we must take into account registers that
1294 have been allocated after sym->liveFrom but freed
1295 before ic->seq. This is complicated, so spill this
1296 symbol instead and let fillGaps handle the allocation. */
1297 if (sym->liveFrom < ic->seq) {
1302 /* if it has a spillocation & is used less than
1303 all other live ranges then spill this */
1305 if (sym->usl.spillLoc) {
1306 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
1307 allLRs, ebbs[i], ic));
1308 if (leastUsed && leastUsed->used > sym->used) {
1313 /* if none of the liveRanges have a spillLocation then better
1314 to spill this one than anything else already assigned to registers */
1315 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
1316 /* if this is local to this block then we might find a block spil */
1317 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
1324 /* if we need ptr regs for the right side
1326 if (POINTER_GET (ic) && IS_SYMOP (IC_LEFT (ic))
1327 && getSize (OP_SYMBOL (IC_LEFT (ic))->type) <= (unsigned int) PTRSIZE) {
1331 /* else we assign registers to it */
1332 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1333 _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key);
1335 for (j = 0; j < sym->nRegs; j++) {
1336 if (sym->regType == REG_PTR)
1337 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
1339 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
1341 /* if the allocation failed which means
1342 this was spilt then break */
1343 if (!sym->regs[j]) {
1348 /* if it shares registers with operands make sure
1349 that they are in the same position */
1350 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
1351 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=') {
1352 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1353 OP_SYMBOL (IC_LEFT (ic)));
1355 /* do the same for the right operand */
1356 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
1357 OP_SYMBOL (IC_RIGHT (ic))->nRegs) {
1358 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1359 OP_SYMBOL (IC_RIGHT (ic)));
1371 /* Check for and fix any problems with uninitialized operands */
1372 for (i = 0; i < count; i++)
1376 if (ebbs[i]->noPath &&
1377 (ebbs[i]->entryLabel != entryLabel &&
1378 ebbs[i]->entryLabel != returnLabel))
1381 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1388 verifyRegsAssigned (IC_COND (ic), ic);
1392 if (ic->op == JUMPTABLE)
1394 verifyRegsAssigned (IC_JTCOND (ic), ic);
1398 verifyRegsAssigned (IC_RESULT (ic), ic);
1399 verifyRegsAssigned (IC_LEFT (ic), ic);
1400 verifyRegsAssigned (IC_RIGHT (ic), ic);
1406 /*-----------------------------------------------------------------*/
1407 /* fillGaps - Try to fill in the Gaps left by Pass1 */
1408 /*-----------------------------------------------------------------*/
1409 static void fillGaps()
1414 if (getenv("DISABLE_FILL_GAPS")) return;
1416 /* look for livernages that was spilt by the allocator */
1417 for (sym = hTabFirstItem(liveRanges,&key) ; sym ;
1418 sym = hTabNextItem(liveRanges,&key)) {
1423 if (!sym->spillA || !sym->clashes || sym->remat) continue ;
1425 /* find the liveRanges this one clashes with, that are
1426 still assigned to registers & mark the registers as used*/
1427 for ( i = 0 ; i < sym->clashes->size ; i ++) {
1431 if (bitVectBitValue(sym->clashes,i) == 0 || /* those that clash with this */
1432 bitVectBitValue(_G.totRegAssigned,i) == 0) /* and are still assigned to registers */
1435 clr = hTabItemWithKey(liveRanges,i);
1438 /* mark these registers as used */
1439 for (k = 0 ; k < clr->nRegs ; k++ )
1440 hc08_useReg(clr->regs[k]);
1443 if (willCauseSpill(sym->nRegs,sym->regType)) {
1444 /* NOPE :( clear all registers & and continue */
1449 /* THERE IS HOPE !!!! */
1450 for (i=0; i < sym->nRegs ; i++ ) {
1451 if (sym->regType == REG_PTR)
1452 sym->regs[i] = getRegPtrNoSpil ();
1454 sym->regs[i] = getRegGprNoSpil ();
1457 /* for all its definitions check if the registers
1458 allocated needs positioning NOTE: we can position
1459 only ONCE if more than One positioning required
1462 for (i = 0 ; i < sym->defs->size ; i++ ) {
1463 if (bitVectBitValue(sym->defs,i)) {
1465 if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
1466 if (SKIP_IC(ic)) continue;
1467 assert(isSymbolEqual(sym,OP_SYMBOL(IC_RESULT(ic)))); /* just making sure */
1468 /* if left is assigned to registers */
1469 if (IS_SYMOP(IC_LEFT(ic)) &&
1470 bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_LEFT(ic))->key)) {
1471 pdone += positionRegs(sym,OP_SYMBOL(IC_LEFT(ic)));
1473 if (IS_SYMOP(IC_RIGHT(ic)) &&
1474 bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RIGHT(ic))->key)) {
1475 pdone += positionRegs(sym,OP_SYMBOL(IC_RIGHT(ic)));
1477 if (pdone > 1) break;
1480 for (i = 0 ; i < sym->uses->size ; i++ ) {
1481 if (bitVectBitValue(sym->uses,i)) {
1483 if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
1484 if (SKIP_IC(ic)) continue;
1485 if (!IS_ASSIGN_ICODE(ic)) continue ;
1487 /* if result is assigned to registers */
1488 if (IS_SYMOP(IC_RESULT(ic)) &&
1489 bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RESULT(ic))->key)) {
1490 pdone += positionRegs(sym,OP_SYMBOL(IC_RESULT(ic)));
1492 if (pdone > 1) break;
1495 /* had to position more than once GIVE UP */
1497 /* UNDO all the changes we made to try this */
1499 for (i=0; i < sym->nRegs ; i++ ) {
1500 sym->regs[i] = NULL;
1503 D(printf ("Fill Gap gave up due to positioning for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN"));
1506 D(printf ("FILLED GAP for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN"));
1507 _G.totRegAssigned = bitVectSetBit(_G.totRegAssigned,sym->key);
1508 sym->isspilt = sym->spillA = 0 ;
1509 sym->usl.spillLoc->allocreq--;
1514 /*-----------------------------------------------------------------*/
1515 /* rUmaskForOp :- returns register mask for an operand */
1516 /*-----------------------------------------------------------------*/
1518 hc08_rUmaskForOp (operand * op)
1524 /* only temporaries are assigned registers */
1528 sym = OP_SYMBOL (op);
1530 /* if spilt or no registers assigned to it
1532 if (sym->isspilt || !sym->nRegs)
1535 rumask = newBitVect (hc08_nRegs);
1537 for (j = 0; j < sym->nRegs; j++)
1539 rumask = bitVectSetBit (rumask,
1540 sym->regs[j]->rIdx);
1546 /*-----------------------------------------------------------------*/
1547 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
1548 /*-----------------------------------------------------------------*/
1550 regsUsedIniCode (iCode * ic)
1552 bitVect *rmask = newBitVect (hc08_nRegs);
1554 /* do the special cases first */
1557 rmask = bitVectUnion (rmask,
1558 hc08_rUmaskForOp (IC_COND (ic)));
1562 /* for the jumptable */
1563 if (ic->op == JUMPTABLE)
1565 rmask = bitVectUnion (rmask,
1566 hc08_rUmaskForOp (IC_JTCOND (ic)));
1571 /* of all other cases */
1573 rmask = bitVectUnion (rmask,
1574 hc08_rUmaskForOp (IC_LEFT (ic)));
1578 rmask = bitVectUnion (rmask,
1579 hc08_rUmaskForOp (IC_RIGHT (ic)));
1582 rmask = bitVectUnion (rmask,
1583 hc08_rUmaskForOp (IC_RESULT (ic)));
1589 /*-----------------------------------------------------------------*/
1590 /* createRegMask - for each instruction will determine the regsUsed */
1591 /*-----------------------------------------------------------------*/
1593 createRegMask (eBBlock ** ebbs, int count)
1597 /* for all blocks */
1598 for (i = 0; i < count; i++)
1602 if (ebbs[i]->noPath &&
1603 (ebbs[i]->entryLabel != entryLabel &&
1604 ebbs[i]->entryLabel != returnLabel))
1607 /* for all instructions */
1608 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1613 if (SKIP_IC2 (ic) || !ic->rlive)
1616 /* first mark the registers used in this
1618 ic->rUsed = regsUsedIniCode (ic);
1619 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
1621 /* now create the register mask for those
1622 registers that are in use : this is a
1623 super set of ic->rUsed */
1624 ic->rMask = newBitVect (hc08_nRegs + 1);
1626 /* for all live Ranges alive at this point */
1627 for (j = 1; j < ic->rlive->size; j++)
1632 /* if not alive then continue */
1633 if (!bitVectBitValue (ic->rlive, j))
1636 /* find the live range we are interested in */
1637 if (!(sym = hTabItemWithKey (liveRanges, j)))
1639 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1640 "createRegMask cannot find live range");
1641 fprintf(stderr, "\tmissing live range: key=%d\n", j);
1645 /* if no register assigned to it */
1646 if (!sym->nRegs || sym->isspilt)
1649 /* for all the registers allocated to it */
1650 for (k = 0; k < sym->nRegs; k++)
1653 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
1659 /*-----------------------------------------------------------------*/
1660 /* rematStr - returns the rematerialized string for a remat var */
1661 /*-----------------------------------------------------------------*/
1663 rematStr (symbol * sym)
1666 iCode *ic = sym->rematiCode;
1671 /* if plus or minus print the right hand side */
1672 if (ic->op == '+' || ic->op == '-')
1674 sprintf (s, "0x%04x %c ", (int) operandLitValue (IC_RIGHT (ic)),
1677 ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1684 offset += operandLitValue (IC_RIGHT (ic));
1685 ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1690 offset -= operandLitValue (IC_RIGHT (ic));
1691 ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1695 /* cast then continue */
1696 if (IS_CAST_ICODE(ic)) {
1697 ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
1700 /* we reached the end */
1701 if (ic->op == ADDRESS_OF)
1702 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
1703 else if (ic->op == '=')
1704 sprintf (s, "0x%04x", (int) operandLitValue (IC_RIGHT (ic)) );
1711 /*-----------------------------------------------------------------*/
1712 /* regTypeNum - computes the type & number of registers required */
1713 /*-----------------------------------------------------------------*/
1715 regTypeNum (eBBlock *ebbs)
1721 /* for each live range do */
1722 for (sym = hTabFirstItem (liveRanges, &k); sym;
1723 sym = hTabNextItem (liveRanges, &k))
1726 /* if used zero times then no registers needed */
1727 if ((sym->liveTo - sym->liveFrom) == 0)
1731 /* if the live range is a temporary */
1735 /* if the type is marked as a conditional */
1736 if (sym->regType == REG_CND)
1739 /* if used in return only then we don't
1741 if (sym->ruonly || sym->accuse)
1743 if (IS_AGGREGATE (sym->type) || sym->isptr)
1744 sym->type = aggrToPtr (sym->type, FALSE);
1748 /* if the symbol has only one definition &
1749 that definition is a get_pointer */
1750 if (bitVectnBitsOn (sym->defs) == 1 &&
1751 (ic = hTabItemWithKey (iCodehTab,
1752 bitVectFirstBit (sym->defs))) &&
1754 !IS_BITVAR (sym->etype) &&
1755 (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER))
1758 if (ptrPseudoSymSafe (sym, ic))
1760 ptrPseudoSymConvert (sym, ic, rematStr (OP_SYMBOL (IC_LEFT (ic))));
1764 /* if in data space or idata space then try to
1765 allocate pointer register */
1769 /* if not then we require registers */
1770 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
1771 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1772 getSize (sym->type));
1776 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
1777 printTypeChain (sym->type, stderr);
1778 fprintf (stderr, "\n");
1781 /* determine the type of register required */
1782 if (sym->nRegs == 1 &&
1783 IS_PTR (sym->type) &&
1785 sym->regType = REG_PTR;
1787 sym->regType = REG_GPR;
1791 /* for the first run we don't provide */
1792 /* registers for true symbols we will */
1793 /* see how things go */
1799 /*-----------------------------------------------------------------*/
1800 /* freeAllRegs - mark all registers as free */
1801 /*-----------------------------------------------------------------*/
1807 for (i = 0; i < hc08_nRegs; i++) {
1808 regshc08[i].isFree = 1;
1809 regshc08[i].aop = NULL;
1813 /*-----------------------------------------------------------------*/
1814 /* deallocStackSpil - this will set the stack pointer back */
1815 /*-----------------------------------------------------------------*/
1817 DEFSETFUNC (deallocStackSpil)
1826 /*-----------------------------------------------------------------*/
1827 /* farSpacePackable - returns the packable icode for far variables */
1828 /*-----------------------------------------------------------------*/
1830 farSpacePackable (iCode * ic)
1834 /* go thru till we find a definition for the
1835 symbol on the right */
1836 for (dic = ic->prev; dic; dic = dic->prev)
1838 /* if the definition is a call then no */
1839 if ((dic->op == CALL || dic->op == PCALL) &&
1840 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1845 /* if shift by unknown amount then not */
1846 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
1847 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1851 /* if pointer get and size > 1 */
1852 if (POINTER_GET (dic) &&
1853 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
1856 if (POINTER_SET (dic) &&
1857 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
1861 /* if any three is a true symbol in far space */
1862 if (IC_RESULT (dic) &&
1863 IS_TRUE_SYMOP (IC_RESULT (dic)) /* &&
1864 isOperandInFarSpace (IC_RESULT (dic)) */)
1867 if (IC_RIGHT (dic) &&
1868 IS_TRUE_SYMOP (IC_RIGHT (dic)) /* &&
1869 isOperandInFarSpace (IC_RIGHT (dic)) */ &&
1870 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
1873 if (IC_LEFT (dic) &&
1874 IS_TRUE_SYMOP (IC_LEFT (dic)) /* &&
1875 isOperandInFarSpace (IC_LEFT (dic)) */ &&
1876 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
1879 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
1881 if ((dic->op == LEFT_OP ||
1882 dic->op == RIGHT_OP ||
1884 IS_OP_LITERAL (IC_RIGHT (dic)))
1897 packRegsForLiteral (iCode * ic)
1904 if (POINTER_SET (ic))
1906 if (!IS_LITERAL (getSpec (operandType (IC_RIGHT (ic)))))
1908 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
1911 for (k=0; k< OP_USES (IC_RESULT (ic))->size; k++)
1912 if (bitVectBitValue (OP_USES (IC_RESULT (ic)), k))
1914 uic = hTabItemWithKey (iCodehTab, k);
1917 if (uic->op != IFX && uic->op != JUMPTABLE)
1919 if (IC_LEFT (uic) && IC_LEFT (uic)->key == IC_RESULT (ic)->key)
1920 ReplaceOpWithCheaperOp(&IC_LEFT(uic), IC_RIGHT(ic));
1921 if (IC_RIGHT (uic) && IC_RIGHT (uic)->key == IC_RESULT (ic)->key)
1922 ReplaceOpWithCheaperOp(&IC_RIGHT(uic), IC_RIGHT(ic));
1923 if (IC_RESULT (uic) && IC_RESULT (uic)->key == IC_RESULT (ic)->key)
1924 ReplaceOpWithCheaperOp(&IC_RESULT(uic), IC_RIGHT(ic));
1932 /*-----------------------------------------------------------------*/
1933 /* packRegsForAssign - register reduction for assignment */
1934 /*-----------------------------------------------------------------*/
1936 packRegsForAssign (iCode * ic, eBBlock * ebp)
1940 if (!IS_ITEMP (IC_RIGHT (ic)) ||
1941 OP_SYMBOL (IC_RIGHT (ic))->isind ||
1942 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
1948 /* if the true symbol is defined in far space or on stack
1949 then we should not since this will increase register pressure */
1951 if (isOperandInFarSpace(IC_RESULT(ic)) && !farSpacePackable(ic)) {
1956 /* find the definition of iTempNN scanning backwards if we find a
1957 a use of the true symbol in before we find the definition then
1959 for (dic = ic->prev; dic; dic = dic->prev)
1962 #if 0 /* jwk: This collides with 1.43 but I really see no need for
1963 this anymore. It fixes bug #716790 and substantially improves
1964 redundant register usage around function calls.
1967 /* if there is a function call then don't pack it */
1968 if ((dic->op == CALL || dic->op == PCALL))
1978 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
1979 IS_OP_VOLATILE (IC_RESULT (dic)))
1985 if (IS_SYMOP (IC_RESULT (dic)) &&
1986 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
1988 if (POINTER_SET (dic))
1994 if (IS_SYMOP (IC_RIGHT (dic)) &&
1995 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
1996 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2002 if (IS_SYMOP (IC_LEFT (dic)) &&
2003 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2004 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2010 if (POINTER_SET (dic) &&
2011 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2019 return 0; /* did not find */
2021 /* if assignment then check that right is not a bit */
2022 if (ASSIGNMENT (dic) && !POINTER_SET (dic))
2024 sym_link *etype = operandType (IC_RIGHT (dic));
2025 if (IS_BITFIELD (etype))
2027 /* if result is a bit too then it's ok */
2028 etype = operandType (IC_RESULT (dic));
2029 if (!IS_BITFIELD (etype))
2033 /* if the result is on stack or iaccess then it must be
2034 the same atleast one of the operands */
2035 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2036 OP_SYMBOL (IC_RESULT (ic))->iaccess)
2039 /* the operation has only one symbol
2040 operator then we can pack */
2041 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2042 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2045 if (!((IC_LEFT (dic) &&
2046 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2048 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2052 /* found the definition */
2053 /* replace the result with the result of */
2054 /* this assignment and remove this assignment */
2055 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2056 ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
2058 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2060 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2062 // TODO: and the otherway around?
2064 /* delete from liverange table also
2065 delete from all the points inbetween and the new
2067 for (sic = dic; sic != ic; sic = sic->next)
2069 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2070 if (IS_ITEMP (IC_RESULT (dic)))
2071 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2074 remiCodeFromeBBlock (ebp, ic);
2075 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2076 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2077 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2082 /*------------------------------------------------------------------*/
2083 /* findAssignToSym : scanning backwards looks for first assig found */
2084 /*------------------------------------------------------------------*/
2086 findAssignToSym (operand * op, iCode * ic)
2090 /* This routine is used to find sequences like
2092 ...; (intervening ops don't use iTempAA or modify FOO)
2093 blah = blah + iTempAA;
2095 and eliminate the use of iTempAA, freeing up its register for
2100 for (dic = ic->prev; dic; dic = dic->prev)
2103 /* if definition by assignment */
2104 if (dic->op == '=' &&
2105 !POINTER_SET (dic) &&
2106 IC_RESULT (dic)->key == op->key
2107 && IS_TRUE_SYMOP(IC_RIGHT(dic))
2109 break; /* found where this temp was defined */
2111 /* if we find an usage then we cannot delete it */
2112 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2115 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2118 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2123 return NULL; /* didn't find any assignment to op */
2125 /* we are interested only if defined in far space */
2126 /* or in stack space in case of + & - */
2128 /* if assigned to a non-symbol then don't repack regs */
2129 if (!IS_SYMOP (IC_RIGHT (dic)))
2132 /* if the symbol is volatile then we should not */
2133 if (isOperandVolatile (IC_RIGHT (dic), TRUE))
2135 /* XXX TODO --- should we be passing FALSE to isOperandVolatile()?
2136 What does it mean for an iTemp to be volatile, anyway? Passing
2137 TRUE is more cautious but may prevent possible optimizations */
2139 /* if the symbol is in far space then we should not */
2140 /* if (isOperandInFarSpace (IC_RIGHT (dic)))
2143 /* for + & - operations make sure that
2144 if it is on the stack it is the same
2145 as one of the three operands */
2147 if ((ic->op == '+' || ic->op == '-') &&
2148 OP_SYMBOL (IC_RIGHT (dic))->onStack)
2151 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2152 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2153 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2158 /* now make sure that the right side of dic
2159 is not defined between ic & dic */
2162 iCode *sic = dic->next;
2164 for (; sic != ic; sic = sic->next)
2165 if (IC_RESULT (sic) &&
2166 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2173 /*-----------------------------------------------------------------*/
2174 /* reassignAliasedSym - used by packRegsForSupport to replace */
2175 /* redundant iTemp with equivalent symbol */
2176 /*-----------------------------------------------------------------*/
2178 reassignAliasedSym (eBBlock *ebp, iCode *assignment, iCode *use, operand *op)
2181 unsigned oldSymKey, newSymKey;
2183 oldSymKey = op->key;
2184 newSymKey = IC_RIGHT(assignment)->key;
2186 /* only track live ranges of compiler-generated temporaries */
2187 if (!IS_ITEMP(IC_RIGHT(assignment)))
2190 /* update the live-value bitmaps */
2191 for (ic = assignment; ic != use; ic = ic->next) {
2192 bitVectUnSetBit (ic->rlive, oldSymKey);
2194 ic->rlive = bitVectSetBit (ic->rlive, newSymKey);
2197 /* update the sym of the used operand */
2198 OP_SYMBOL(op) = OP_SYMBOL(IC_RIGHT(assignment));
2199 op->key = OP_SYMBOL(op)->key;
2201 /* update the sym's liverange */
2202 if ( OP_LIVETO(op) < ic->seq )
2203 setToRange(op, ic->seq, FALSE);
2205 /* remove the assignment iCode now that its result is unused */
2206 remiCodeFromeBBlock (ebp, assignment);
2207 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(assignment))->defs, assignment->key);
2208 hTabDeleteItem (&iCodehTab, assignment->key, assignment, DELETE_ITEM, NULL);
2212 /*-----------------------------------------------------------------*/
2213 /* packRegsForSupport :- reduce some registers for support calls */
2214 /*-----------------------------------------------------------------*/
2216 packRegsForSupport (iCode * ic, eBBlock * ebp)
2221 /* for the left & right operand :- look to see if the
2222 left was assigned a true symbol in far space in that
2223 case replace them */
2225 if (IS_ITEMP (IC_LEFT (ic)) &&
2226 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2228 dic = findAssignToSym (IC_LEFT (ic), ic);
2232 /* found it we need to remove it from the block */
2233 reassignAliasedSym (ebp, dic, ic, IC_LEFT(ic));
2238 /* do the same for the right operand */
2239 if (IS_ITEMP (IC_RIGHT (ic)) &&
2240 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2242 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2246 /* found it we need to remove it from the block */
2247 reassignAliasedSym (ebp, dic, ic, IC_RIGHT(ic));
2255 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
2259 /*-----------------------------------------------------------------*/
2260 /* packRegsForOneuse : - will reduce some registers for single Use */
2261 /*-----------------------------------------------------------------*/
2263 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
2268 /* if returning a literal then do nothing */
2272 /* only up to 2 bytes */
2273 if (getSize (operandType (op)) > (fReturnSizeHC08 - 2))
2278 if (ic->op != SEND //RETURN
2280 && !POINTER_SET (ic)
2281 && !POINTER_GET (ic) )
2284 if (ic->op == SEND && ic->argreg != 1) return NULL;
2286 /* this routine will mark the a symbol as used in one
2287 instruction use only && if the defintion is local
2288 (ie. within the basic block) && has only one definition &&
2289 that definiion is either a return value from a
2290 function or does not contain any variables in
2292 uses = bitVectCopy (OP_USES (op));
2293 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
2294 if (!bitVectIsZero (uses)) /* has other uses */
2297 /* if it has only one defintion */
2298 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
2299 return NULL; /* has more than one definition */
2301 /* get that definition */
2303 hTabItemWithKey (iCodehTab,
2304 bitVectFirstBit (OP_DEFS (op)))))
2307 /* if that only usage is a cast */
2308 if (dic->op == CAST) {
2309 /* to a bigger type */
2310 if (getSize(OP_SYM_TYPE(IC_RESULT(dic))) >
2311 getSize(OP_SYM_TYPE(IC_RIGHT(dic)))) {
2312 /* than we can not, since we cannot predict the usage of b & acc */
2317 /* found the definition now check if it is local */
2318 if (dic->seq < ebp->fSeq ||
2319 dic->seq > ebp->lSeq)
2320 return NULL; /* non-local */
2322 /* now check if it is the return from
2324 if (dic->op == CALL || dic->op == PCALL)
2326 if (ic->op != SEND && ic->op != RETURN &&
2327 !POINTER_SET(ic) && !POINTER_GET(ic))
2329 OP_SYMBOL (op)->ruonly = 1;
2336 /* otherwise check that the definition does
2337 not contain any symbols in far space */
2338 // if (isOperandInFarSpace (IC_LEFT (dic)) ||
2339 // isOperandInFarSpace (IC_RIGHT (dic)) ||
2340 // IS_OP_RUONLY (IC_LEFT (ic)) ||
2341 // IS_OP_RUONLY (IC_RIGHT (ic)))
2346 /* if pointer set then make sure the pointer
2349 if (POINTER_SET (dic) &&
2350 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2353 if (POINTER_GET (dic) &&
2354 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2360 /* also make sure the intervenening instructions
2361 don't have any thing in far space */
2362 for (dic = dic->next; dic && dic != ic && sic != ic; dic = dic->next)
2365 /* if there is an intervening function call then no */
2366 if (dic->op == CALL || dic->op == PCALL)
2368 /* if pointer set then make sure the pointer
2371 if (POINTER_SET (dic) &&
2372 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2375 if (POINTER_GET (dic) &&
2376 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2379 /* if address of & the result is remat the okay */
2380 if (dic->op == ADDRESS_OF &&
2381 OP_SYMBOL (IC_RESULT (dic))->remat)
2384 /* if operand has size of three or more & this
2385 operation is a '*','/' or '%' then 'b' may
2388 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
2389 getSize (operandType (op)) >= 3)
2393 /* if left or right or result is in far space */
2394 // if (isOperandInFarSpace (IC_LEFT (dic)) ||
2395 // isOperandInFarSpace (IC_RIGHT (dic)) ||
2396 // isOperandInFarSpace (IC_RESULT (dic)) ||
2397 // IS_OP_RUONLY (IC_LEFT (dic)) ||
2398 // IS_OP_RUONLY (IC_RIGHT (dic)) ||
2399 // IS_OP_RUONLY (IC_RESULT (dic)))
2403 // /* if left or right or result is on stack */
2404 // if (isOperandOnStack(IC_LEFT(dic)) ||
2405 // isOperandOnStack(IC_RIGHT(dic)) ||
2406 // isOperandOnStack(IC_RESULT(dic))) {
2411 OP_SYMBOL (op)->ruonly = 1;
2416 /*-----------------------------------------------------------------*/
2417 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
2418 /*-----------------------------------------------------------------*/
2420 isBitwiseOptimizable (iCode * ic)
2422 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
2423 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
2425 /* bitwise operations are considered optimizable
2426 under the following conditions (Jean-Louis VERN)
2438 if (IS_LITERAL(rtype) ||
2439 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
2445 /*-----------------------------------------------------------------*/
2446 /* isCommutativeOp - tests whether this op cares what order its */
2447 /* operands are in */
2448 /*-----------------------------------------------------------------*/
2449 bool isCommutativeOp2(unsigned int op)
2451 if (op == '+' || op == '*' || op == EQ_OP ||
2452 op == '^' || op == '|' || op == BITWISEAND)
2458 /*-----------------------------------------------------------------*/
2459 /* operandUsesAcc2 - determines whether the code generated for this */
2460 /* operand will have to use the accumulator */
2461 /*-----------------------------------------------------------------*/
2462 bool operandUsesAcc2(operand *op)
2468 symbol *sym = OP_SYMBOL(op);
2472 return TRUE; /* duh! */
2474 // if (IN_STACK(sym->etype) || sym->onStack ||
2475 // (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
2476 // return TRUE; /* acc is used to calc stack offset */
2481 sym = SPIL_LOC(op); /* if spilled, look at spill location */
2483 return FALSE; /* more checks? */
2487 symspace = SPEC_OCLS(sym->etype);
2489 // if (sym->iaccess && symspace->paged)
2490 // return TRUE; /* must fetch paged indirect sym via accumulator */
2492 if (IN_BITSPACE(symspace))
2493 return TRUE; /* fetching bit vars uses the accumulator */
2495 if (IN_FARSPACE(symspace) || IN_CODESPACE(symspace))
2496 return TRUE; /* fetched via accumulator and dptr */
2502 /*-----------------------------------------------------------------*/
2503 /* packRegsForAccUse - pack registers for acc use */
2504 /*-----------------------------------------------------------------*/
2506 packRegsForAccUse (iCode * ic)
2510 /* if this is an aggregate, e.g. a one byte char array */
2511 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
2515 /* if we are calling a reentrant function that has stack parameters */
2517 if (ic->op == CALL &&
2518 IFFUNC_ISREENT(operandType(IC_LEFT(ic))) &&
2519 FUNC_HASSTACKPARM(operandType(IC_LEFT(ic))))
2522 if (ic->op == PCALL &&
2523 IFFUNC_ISREENT(operandType(IC_LEFT(ic))->next) &&
2524 FUNC_HASSTACKPARM(operandType(IC_LEFT(ic))->next))
2528 /* if + or - then it has to be one byte result */
2529 if ((ic->op == '+' || ic->op == '-')
2530 && getSize (operandType (IC_RESULT (ic))) > 1)
2534 /* if shift operation make sure right side is a literal */
2535 if (ic->op == RIGHT_OP &&
2536 (!isOperandLiteral (IC_RIGHT (ic)) ||
2537 (getSize (operandType (IC_RESULT (ic) )) > 1)))
2540 if (ic->op == LEFT_OP &&
2541 (!isOperandLiteral (IC_RIGHT (ic)) ||
2542 (getSize (operandType (IC_RESULT (ic) )) > 1)))
2545 if (IS_BITWISE_OP (ic) &&
2546 getSize (operandType (IC_RESULT (ic))) > 1)
2550 /* has only one definition */
2551 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
2554 /* has only one use */
2555 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
2558 /* and the usage immediately follows this iCode */
2559 if (!(uic = hTabItemWithKey (iCodehTab,
2560 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
2563 if (ic->next != uic)
2566 /* if it is a conditional branch then we definitely can */
2570 if (uic->op == JUMPTABLE)
2574 if (POINTER_SET (uic) &&
2575 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
2579 /* if the usage is not is an assignment
2580 or an arithmetic / bitwise / shift operation then not */
2581 if (uic->op != '=' &&
2582 !IS_ARITHMETIC_OP (uic) &&
2583 !IS_BITWISE_OP (uic) &&
2584 (uic->op != LEFT_OP) &&
2585 (uic->op != RIGHT_OP) &&
2586 (uic->op != GETHBIT) &&
2587 (uic->op != RETURN) &&
2593 /* if used in ^ operation then make sure right is not a
2594 literal (WIML: Why is this?) */
2595 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
2598 /* if shift operation make sure right side is not a literal */
2599 /* WIML: Why is this? */
2600 if (uic->op == RIGHT_OP &&
2601 (isOperandLiteral (IC_RIGHT (uic)) ||
2602 getSize (operandType (IC_RESULT (uic))) > 1))
2604 if (uic->op == LEFT_OP &&
2605 (isOperandLiteral (IC_RIGHT (uic)) ||
2606 getSize (operandType (IC_RESULT (uic))) > 1))
2610 /* make sure that the result of this icode is not on the
2611 stack, since acc is used to compute stack offset */
2613 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
2614 OP_SYMBOL (IC_RESULT (uic))->onStack)
2617 // if (isOperandOnStack(IC_RESULT(uic)))
2621 /* if the usage has only one operand then we can */
2622 if (IC_LEFT (uic) == NULL ||
2623 IC_RIGHT (uic) == NULL)
2627 /* if the other operand uses the accumulator then we cannot */
2628 if ( (IC_LEFT(uic)->key == IC_RESULT(ic)->key &&
2629 operandUsesAcc2(IC_RIGHT(uic))) ||
2630 (IC_RIGHT(uic)->key == IC_RESULT(ic)->key &&
2631 operandUsesAcc2(IC_LEFT(uic))) )
2634 /* make sure this is on the left side if not commutative */
2635 /* except for '-', which has been written to be able to
2636 handle reversed operands */
2637 if (!(isCommutativeOp2(ic->op) || ic->op == '-') &&
2638 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
2643 // this is too dangerous and need further restrictions
2646 /* if one of them is a literal then we can */
2647 if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
2648 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
2650 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2657 if ((POINTER_GET(uic))
2658 || (ic->op == ADDRESS_OF && uic->op == '+' && IS_OP_LITERAL (IC_RIGHT (uic))))
2660 OP_SYMBOL (IC_RESULT (ic))->accuse = ACCUSE_HX;
2664 OP_SYMBOL (IC_RESULT (ic))->accuse = ACCUSE_XA;
2667 /*-----------------------------------------------------------------*/
2668 /* packForPush - hueristics to reduce iCode for pushing */
2669 /*-----------------------------------------------------------------*/
2671 packForPush (iCode * ic, eBBlock ** ebpp, int blockno)
2675 struct eBBlock * ebp=ebpp[blockno];
2677 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
2680 /* must have only definition & one usage */
2681 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
2682 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
2685 /* find the definition */
2686 if (!(dic = hTabItemWithKey (iCodehTab,
2687 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
2690 if (dic->op != '=' || POINTER_SET (dic))
2693 if (dic->seq < ebp->fSeq) { // Evelyn did this
2695 for (i=0; i<blockno; i++) {
2696 if (dic->seq >= ebpp[i]->fSeq && dic->seq <= ebpp[i]->lSeq) {
2701 wassert (i!=blockno); // no way to recover from here
2704 if (IS_SYMOP(IC_RIGHT(dic))) {
2705 /* make sure the right side does not have any definitions
2707 dbv = OP_DEFS(IC_RIGHT(dic));
2708 for (lic = ic; lic && lic != dic ; lic = lic->prev) {
2709 if (bitVectBitValue(dbv,lic->key))
2712 /* make sure they have the same type */
2713 if (IS_SPEC(operandType(IC_LEFT(ic))))
2715 sym_link *itype=operandType(IC_LEFT(ic));
2716 sym_link *ditype=operandType(IC_RIGHT(dic));
2718 if (SPEC_USIGN(itype)!=SPEC_USIGN(ditype) ||
2719 SPEC_LONG(itype)!=SPEC_LONG(ditype))
2722 /* extend the live range of replaced operand if needed */
2723 if (OP_SYMBOL(IC_RIGHT(dic))->liveTo < ic->seq) {
2724 OP_SYMBOL(IC_RIGHT(dic))->liveTo = ic->seq;
2726 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2729 /* we now we know that it has one & only one def & use
2730 and the that the definition is an assignment */
2731 ReplaceOpWithCheaperOp(&IC_LEFT (ic), IC_RIGHT (dic));
2732 remiCodeFromeBBlock (ebp, dic);
2733 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2736 /*-----------------------------------------------------------------*/
2737 /* packRegisters - does some transformations to reduce register */
2739 /*-----------------------------------------------------------------*/
2741 packRegisters (eBBlock ** ebpp, int blockno)
2745 eBBlock *ebp=ebpp[blockno];
2752 /* look for assignments of the form */
2753 /* iTempNN = TRueSym (someoperation) SomeOperand */
2755 /* TrueSym := iTempNN:1 */
2756 for (ic = ebp->sch; ic; ic = ic->next)
2758 /* find assignment of the form TrueSym := iTempNN:1 */
2759 if (ic->op == '=' && !POINTER_SET (ic) )
2760 change += packRegsForAssign (ic, ebp);
2767 for (ic = ebp->sch; ic; ic = ic->next)
2769 //packRegsForLiteral (ic);
2771 /* if this is an itemp & result of an address of a true sym
2772 then mark this as rematerialisable */
2773 if (ic->op == ADDRESS_OF &&
2774 IS_ITEMP (IC_RESULT (ic)) &&
2775 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
2776 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2777 !OP_SYMBOL (IC_LEFT (ic))->onStack )
2780 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2781 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2782 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2786 if (ic->op == '=' &&
2787 !POINTER_SET (ic) &&
2788 IS_ITEMP (IC_RESULT (ic)) &&
2789 IS_VALOP (IC_RIGHT (ic)) &&
2790 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1)
2793 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2794 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2795 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2799 /* if straight assignment then carry remat flag if
2800 this is the only definition */
2801 if (ic->op == '=' &&
2802 !POINTER_SET (ic) &&
2803 IS_SYMOP (IC_RIGHT (ic)) &&
2804 OP_SYMBOL (IC_RIGHT (ic))->remat &&
2805 !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode) &&
2806 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
2809 OP_SYMBOL (IC_RESULT (ic))->remat =
2810 OP_SYMBOL (IC_RIGHT (ic))->remat;
2811 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
2812 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
2815 /* if cast to a generic pointer & the pointer being
2816 cast is remat, then we can remat this cast as well */
2817 if (ic->op == CAST &&
2818 IS_SYMOP(IC_RIGHT(ic)) &&
2819 OP_SYMBOL(IC_RIGHT(ic))->remat &&
2820 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1) {
2821 sym_link *to_type = operandType(IC_LEFT(ic));
2822 sym_link *from_type = operandType(IC_RIGHT(ic));
2823 if (IS_GENPTR(to_type) && IS_PTR(from_type)) {
2824 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2825 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2826 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2830 /* if this is a +/- operation with a rematerizable
2831 then mark this as rematerializable as well */
2832 if ((ic->op == '+' || ic->op == '-') &&
2833 (IS_SYMOP (IC_LEFT (ic)) &&
2834 IS_ITEMP (IC_RESULT (ic)) &&
2835 IS_OP_LITERAL (IC_RIGHT (ic))) &&
2836 OP_SYMBOL (IC_LEFT (ic))->remat &&
2837 (!IS_SYMOP (IC_RIGHT (ic)) || !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode)) &&
2838 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1)
2840 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2841 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2842 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2845 /* mark the pointer usages */
2846 if (POINTER_SET (ic))
2847 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
2849 if (POINTER_GET (ic) &&
2850 IS_SYMOP(IC_LEFT (ic)))
2851 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
2856 /* if we are using a symbol on the stack
2857 then we should say hc08_ptrRegReq */
2858 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
2859 hc08_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
2860 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
2861 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
2862 hc08_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
2863 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
2866 if (IS_SYMOP (IC_LEFT (ic)))
2867 hc08_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
2868 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
2869 if (IS_SYMOP (IC_RIGHT (ic)))
2870 hc08_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
2871 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
2872 if (IS_SYMOP (IC_RESULT (ic)))
2873 hc08_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
2874 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
2879 /* if the condition of an if instruction
2880 is defined in the previous instruction and
2881 this is the only usage then
2882 mark the itemp as a conditional */
2883 if ((IS_CONDITIONAL (ic) ||
2884 (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic))) &&
2885 ic->next && ic->next->op == IFX &&
2886 bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
2887 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
2888 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2890 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
2894 /* reduce for support function calls */
2895 if (ic->supportRtn || (ic->op != IFX && ic->op != JUMPTABLE))
2896 packRegsForSupport (ic, ebp);
2899 /* some cases the redundant moves can
2900 can be eliminated for return statements */
2901 if ((ic->op == RETURN || (ic->op == SEND && ic->argreg == 1)) &&
2902 /* !isOperandInFarSpace (IC_LEFT (ic)) && */
2903 options.model == MODEL_SMALL) {
2904 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2907 /* if pointer set & left has a size more than
2908 one and right is not in far space */
2909 if (POINTER_SET (ic) &&
2910 /* !isOperandInFarSpace (IC_RIGHT (ic)) && */
2911 !OP_SYMBOL (IC_RESULT (ic))->remat &&
2912 !IS_OP_RUONLY (IC_RIGHT (ic))
2913 /* && getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1 */ )
2914 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
2916 /* if pointer get */
2917 if (POINTER_GET (ic) &&
2918 IS_SYMOP (IC_LEFT (ic)) &&
2919 /* !isOperandInFarSpace (IC_RESULT (ic)) && */
2920 !OP_SYMBOL (IC_LEFT (ic))->remat &&
2921 !IS_OP_RUONLY (IC_RESULT (ic))
2922 /* && getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1 */)
2923 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2926 /* if this is cast for intergral promotion then
2927 check if only use of the definition of the
2928 operand being casted/ if yes then replace
2929 the result of that arithmetic operation with
2930 this result and get rid of the cast */
2933 sym_link *fromType = operandType (IC_RIGHT (ic));
2934 sym_link *toType = operandType (IC_LEFT (ic));
2936 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
2937 getSize (fromType) != getSize (toType) &&
2938 SPEC_USIGN (fromType) == SPEC_USIGN (toType))
2941 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2944 if (IS_ARITHMETIC_OP (dic))
2946 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2947 ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
2948 remiCodeFromeBBlock (ebp, ic);
2949 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2950 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2951 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2955 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
2961 /* if the type from and type to are the same
2962 then if this is the only use then packit */
2963 if (compareType (operandType (IC_RIGHT (ic)),
2964 operandType (IC_LEFT (ic))) == 1)
2966 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2969 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2970 ReplaceOpWithCheaperOp(&IC_RESULT (dic), IC_RESULT (ic));
2971 remiCodeFromeBBlock (ebp, ic);
2972 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2973 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2974 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2983 iTempNN := (some variable in farspace) V1
2988 if (ic->op == IPUSH)
2990 packForPush (ic, ebpp, blockno);
2995 /* pack registers for accumulator use, when the
2996 result of an arithmetic or bit wise operation
2997 has only one use, that use is immediately following
2998 the defintion and the using iCode has only one
2999 operand or has two operands but one is literal &
3000 the result of that operation is not on stack then
3001 we can leave the result of this operation in x:a
3003 if ((IS_ARITHMETIC_OP (ic)
3004 || IS_CONDITIONAL(ic)
3005 || IS_BITWISE_OP (ic)
3009 || ic->op == GETHBIT
3010 || ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == CALL
3011 || (ic->op == ADDRESS_OF && isOperandOnStack (IC_LEFT (ic)))
3012 || ic->op == RECEIVE
3014 IS_ITEMP (IC_RESULT (ic)) &&
3015 getSize (operandType (IC_RESULT (ic))) <= 1)
3017 packRegsForAccUse (ic);
3022 /*-----------------------------------------------------------------*/
3023 /* assignRegisters - assigns registers to each live range as need */
3024 /*-----------------------------------------------------------------*/
3026 hc08_assignRegisters (eBBlock ** ebbs, int count)
3031 setToNull ((void *) &_G.funcrUsed);
3032 setToNull ((void *) &_G.regAssigned);
3033 setToNull ((void *) &_G.totRegAssigned);
3034 hc08_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3036 hc08_reg_a = hc08_regWithIdx(A_IDX);
3037 hc08_reg_x = hc08_regWithIdx(X_IDX);
3038 hc08_reg_h = hc08_regWithIdx(H_IDX);
3039 hc08_reg_hx = hc08_regWithIdx(HX_IDX);
3040 hc08_reg_xa = hc08_regWithIdx(XA_IDX);
3041 hc08_reg_sp = hc08_regWithIdx(SP_IDX);
3044 /* change assignments this will remove some
3045 live ranges reducing some register pressure */
3046 for (i = 0; i < count; i++)
3047 packRegisters (ebbs, i);
3049 /* liveranges probably changed by register packing
3050 so we compute them again */
3051 recomputeLiveRanges (ebbs, count);
3053 if (options.dump_pack)
3054 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3056 /* first determine for each live range the number of
3057 registers & the type of registers required for each */
3060 /* and serially allocate registers */
3061 serialRegAssign (ebbs, count);
3064 //setToNull ((void *) &_G.regAssigned);
3065 //setToNull ((void *) &_G.totRegAssigned);
3068 /* if stack was extended then tell the user */
3071 /* werror(W_TOOMANY_SPILS,"stack", */
3072 /* _G.stackExtend,currFunc->name,""); */
3078 /* werror(W_TOOMANY_SPILS,"data space", */
3079 /* _G.dataExtend,currFunc->name,""); */
3083 /* after that create the register mask
3084 for each of the instruction */
3085 createRegMask (ebbs, count);
3087 /* redo that offsets for stacked automatic variables */
3089 redoStackOffsets ();
3092 if (options.dump_rassgn)
3094 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3095 dumpLiveRanges (DUMP_LRANGE, liveRanges);
3098 /* do the overlaysegment stuff SDCCmem.c */
3099 doOverlays (ebbs, count);
3101 /* now get back the chain */
3102 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3106 /* free up any _G.stackSpil locations allocated */
3107 applyToSet (_G.stackSpil, deallocStackSpil);
3109 setToNull ((void **) &_G.stackSpil);
3110 setToNull ((void **) &_G.spiltSet);
3111 /* mark all registers as free */