1 /*------------------------------------------------------------------------
3 SDCCralloc.c - source file for register allocation. (8051) specific
5 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 Added Pic Port T.scott Dattalo scott@dattalo.com (2000)
8 This program is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 In other words, you are welcome to use, share and improve this program.
23 You are forbidden to forbid anyone else to use, share and improve
24 what you give them. Help stamp out software-hoarding!
25 -------------------------------------------------------------------------*/
32 /*-----------------------------------------------------------------*/
33 /* At this point we start getting processor specific although */
34 /* some routines are non-processor specific & can be reused when */
35 /* targetting other processors. The decision for this will have */
36 /* to be made on a routine by routine basis */
37 /* routines used to pack registers are most definitely not reusable */
38 /* since the pack the registers depending strictly on the MCU */
39 /*-----------------------------------------------------------------*/
41 extern void genpic14Code (iCode *);
51 bitVect *funcrUsed; /* registers used in a function */
57 /* Shared with gen.c */
58 int pic14_ptrRegReq; /* one byte pointer register required */
61 /* A nasty, awful, disgusting hack for register declarations */
67 {REG_GPR, PO_GPR_TEMP, 0x0C, "r0x0C", "r0x0C", 0x0C, 1, 0},
68 {REG_GPR, PO_GPR_TEMP, 0x0D, "r0x0D", "r0x0C", 0x0D, 1, 0},
69 {REG_GPR, PO_GPR_TEMP, 0x0E, "r0x0E", "r0x0C", 0x0E, 1, 0},
70 {REG_GPR, PO_GPR_TEMP, 0x0F, "r0x0F", "r0x0C", 0x0F, 1, 0},
71 {REG_GPR, PO_GPR_TEMP, 0x10, "r0x10", "r0x10", 0x10, 1, 0},
72 {REG_GPR, PO_GPR_TEMP, 0x11, "r0x11", "r0x11", 0x11, 1, 0},
73 {REG_GPR, PO_GPR_TEMP, 0x12, "r0x12", "r0x12", 0x12, 1, 0},
74 {REG_GPR, PO_GPR_TEMP, 0x13, "r0x13", "r0x13", 0x13, 1, 0},
75 {REG_GPR, PO_GPR_TEMP, 0x14, "r0x14", "r0x14", 0x14, 1, 0},
76 {REG_GPR, PO_GPR_TEMP, 0x15, "r0x15", "r0x15", 0x15, 1, 0},
77 {REG_GPR, PO_GPR_TEMP, 0x16, "r0x16", "r0x16", 0x16, 1, 0},
78 {REG_GPR, PO_GPR_TEMP, 0x17, "r0x17", "r0x17", 0x17, 1, 0},
79 {REG_GPR, PO_GPR_TEMP, 0x18, "r0x18", "r0x18", 0x18, 1, 0},
80 {REG_GPR, PO_GPR_TEMP, 0x19, "r0x19", "r0x19", 0x19, 1, 0},
81 {REG_GPR, PO_GPR_TEMP, 0x1A, "r0x1A", "r0x1A", 0x1A, 1, 0},
82 {REG_GPR, PO_GPR_TEMP, 0x1B, "r0x1B", "r0x1B", 0x1B, 1, 0},
83 {REG_GPR, PO_GPR_TEMP, 0x1C, "r0x1C", "r0x1C", 0x1C, 1, 0},
84 {REG_GPR, PO_GPR_TEMP, 0x1D, "r0x1D", "r0x1D", 0x1D, 1, 0},
85 {REG_GPR, PO_GPR_TEMP, 0x1E, "r0x1E", "r0x1E", 0x1E, 1, 0},
86 {REG_GPR, PO_GPR_TEMP, 0x1F, "r0x1F", "r0x1F", 0x1F, 1, 0},
87 {REG_PTR, PO_FSR, 4, "FSR", "FSR", 4, 1, 0},
92 int Gstack_base_addr=0x38; /* The starting address of registers that
93 * are used to pass and return parameters */
96 {REG_GPR, PO_GPR_TEMP, 0x20, "r0x20", "r0x20", 0x20, 1, 0},
97 {REG_GPR, PO_GPR_TEMP, 0x21, "r0x21", "r0x21", 0x21, 1, 0},
98 {REG_GPR, PO_GPR_TEMP, 0x22, "r0x22", "r0x22", 0x22, 1, 0},
99 {REG_GPR, PO_GPR_TEMP, 0x23, "r0x23", "r0x23", 0x23, 1, 0},
100 {REG_GPR, PO_GPR_TEMP, 0x24, "r0x24", "r0x24", 0x24, 1, 0},
101 {REG_GPR, PO_GPR_TEMP, 0x25, "r0x25", "r0x25", 0x25, 1, 0},
102 {REG_GPR, PO_GPR_TEMP, 0x26, "r0x26", "r0x26", 0x26, 1, 0},
103 {REG_GPR, PO_GPR_TEMP, 0x27, "r0x27", "r0x27", 0x27, 1, 0},
104 {REG_GPR, PO_GPR_TEMP, 0x28, "r0x28", "r0x28", 0x28, 1, 0},
105 {REG_GPR, PO_GPR_TEMP, 0x29, "r0x29", "r0x29", 0x29, 1, 0},
106 {REG_GPR, PO_GPR_TEMP, 0x2A, "r0x2A", "r0x2A", 0x2A, 1, 0},
107 {REG_GPR, PO_GPR_TEMP, 0x2B, "r0x2B", "r0x2B", 0x2B, 1, 0},
108 {REG_GPR, PO_GPR_TEMP, 0x2C, "r0x2C", "r0x2C", 0x2C, 1, 0},
109 {REG_GPR, PO_GPR_TEMP, 0x2D, "r0x2D", "r0x2D", 0x2D, 1, 0},
110 {REG_GPR, PO_GPR_TEMP, 0x2E, "r0x2E", "r0x2E", 0x2E, 1, 0},
111 {REG_GPR, PO_GPR_TEMP, 0x2F, "r0x2F", "r0x2F", 0x2F, 1, 0},
112 {REG_GPR, PO_GPR_TEMP, 0x30, "r0x30", "r0x30", 0x30, 1, 0},
113 {REG_GPR, PO_GPR_TEMP, 0x31, "r0x31", "r0x31", 0x31, 1, 0},
114 {REG_GPR, PO_GPR_TEMP, 0x32, "r0x32", "r0x32", 0x32, 1, 0},
115 {REG_GPR, PO_GPR_TEMP, 0x33, "r0x33", "r0x33", 0x33, 1, 0},
116 {REG_GPR, PO_GPR_TEMP, 0x34, "r0x34", "r0x34", 0x34, 1, 0},
117 {REG_GPR, PO_GPR_TEMP, 0x35, "r0x35", "r0x35", 0x35, 1, 0},
118 {REG_GPR, PO_GPR_TEMP, 0x36, "r0x36", "r0x36", 0x36, 1, 0},
119 {REG_GPR, PO_GPR_TEMP, 0x37, "r0x37", "r0x37", 0x37, 1, 0},
120 {REG_STK, PO_GPR_TEMP, 0x38, "r0x38", "r0x38", 0x38, 1, 0},
121 {REG_STK, PO_GPR_TEMP, 0x39, "r0x39", "r0x39", 0x39, 1, 0},
122 {REG_STK, PO_GPR_TEMP, 0x3A, "r0x3A", "r0x3A", 0x3A, 1, 0},
123 {REG_STK, PO_GPR_TEMP, 0x3B, "r0x3B", "r0x3B", 0x3B, 1, 0},
124 {REG_STK, PO_GPR_TEMP, 0x3C, "r0x3C", "r0x3C", 0x3C, 1, 0},
125 {REG_STK, PO_GPR_TEMP, 0x3D, "r0x3D", "r0x3D", 0x3D, 1, 0},
126 {REG_STK, PO_GPR_TEMP, 0x3E, "r0x3E", "r0x3E", 0x3E, 1, 0},
127 {REG_STK, PO_GPR_TEMP, 0x3F, "r0x3F", "r0x3F", 0x3F, 1, 0},
128 {REG_STK, PO_GPR_TEMP, 0x40, "r0x40", "r0x40", 0x40, 1, 0},
129 {REG_STK, PO_GPR_TEMP, 0x41, "r0x41", "r0x41", 0x41, 1, 0},
130 {REG_STK, PO_GPR_TEMP, 0x42, "r0x42", "r0x42", 0x42, 1, 0},
131 {REG_STK, PO_GPR_TEMP, 0x43, "r0x43", "r0x43", 0x43, 1, 0},
132 {REG_STK, PO_GPR_TEMP, 0x44, "r0x44", "r0x44", 0x44, 1, 0},
133 {REG_STK, PO_GPR_TEMP, 0x45, "r0x45", "r0x45", 0x45, 1, 0},
134 {REG_STK, PO_GPR_TEMP, 0x46, "r0x46", "r0x46", 0x46, 1, 0},
135 {REG_STK, PO_GPR_TEMP, 0x47, "r0x47", "r0x47", 0x47, 1, 0},
137 {REG_SFR, PO_GPR_REGISTER, IDX_KZ, "KZ", "KZ", IDX_KZ, 1, 0}, /* Known zero */
140 {REG_STK, PO_FSR, IDX_FSR, "FSR", "FSR", IDX_FSR, 1, 0},
141 {REG_STK, PO_INDF, IDX_INDF, "INDF", "INDF", IDX_INDF, 1, 0},
148 int pic14_nRegs = sizeof (regspic14) / sizeof (regs);
149 static void spillThis (symbol *);
150 static int debug = 1;
151 static FILE *debugF = NULL;
152 /*-----------------------------------------------------------------*/
153 /* debugLog - open a file for debugging information */
154 /*-----------------------------------------------------------------*/
155 //static void debugLog(char *inst,char *fmt, ...)
157 debugLog (char *fmt,...)
159 static int append = 0; // First time through, open the file without append.
162 //char *bufferP=buffer;
165 if (!debug || !srcFileName)
171 /* create the file name */
172 strcpy (buffer, srcFileName);
173 strcat (buffer, ".d");
175 if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
177 werror (E_FILE_OPEN_ERR, buffer);
180 append = 1; // Next time debubLog is called, we'll append the debug info
186 vsprintf (buffer, fmt, ap);
188 fprintf (debugF, "%s", buffer);
190 while (isspace(*bufferP)) bufferP++;
192 if (bufferP && *bufferP)
193 lineCurr = (lineCurr ?
194 connectLine(lineCurr,newLineNode(lb)) :
195 (lineHead = newLineNode(lb)));
196 lineCurr->isInline = _G.inLine;
197 lineCurr->isDebug = _G.debugLine;
207 fputc ('\n', debugF);
209 /*-----------------------------------------------------------------*/
210 /* debugLogClose - closes the debug log file (if opened) */
211 /*-----------------------------------------------------------------*/
221 #define AOP(op) op->aop
224 debugAopGet (char *str, operand * op)
229 printOperand (op, debugF);
237 decodeOp (unsigned int op)
240 if (op < 128 && op > ' ')
242 buffer[0] = (op & 0xff);
256 return "STRING_LITERAL";
292 return "LEFT_ASSIGN";
294 return "RIGHT_ASSIGN";
409 case GET_VALUE_AT_ADDRESS:
410 return "GET_VALUE_AT_ADDRESS";
428 return "ENDFUNCTION";
452 sprintf (buffer, "unkown op %d %c", op, op & 0xff);
455 /*-----------------------------------------------------------------*/
456 /*-----------------------------------------------------------------*/
458 debugLogRegType (short type)
471 sprintf (buffer, "unkown reg type %d", type);
475 /*-----------------------------------------------------------------*/
476 /* allocReg - allocates register of given type */
477 /*-----------------------------------------------------------------*/
479 allocReg (short type)
483 debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
485 for (i = 0; i < pic14_nRegs; i++)
488 /* if type is given as 0 then any
489 free register will do */
493 regspic14[i].isFree = 0;
494 regspic14[i].wasUsed = 1;
497 bitVectSetBit (currFunc->regsUsed, i);
498 debugLog (" returning %s\n", regspic14[i].name);
499 return ®spic14[i];
501 /* other wise look for specific type
503 if (regspic14[i].isFree &&
504 regspic14[i].type == type)
506 regspic14[i].isFree = 0;
507 regspic14[i].wasUsed = 1;
510 bitVectSetBit (currFunc->regsUsed, i);
511 debugLog (" returning %s\n", regspic14[i].name);
512 return ®spic14[i];
518 /*-----------------------------------------------------------------*/
519 /* pic14_regWithIdx - returns pointer to register wit index number */
520 /*-----------------------------------------------------------------*/
522 pic14_regWithIdx (int idx)
526 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
528 for (i = 0; i < pic14_nRegs; i++)
529 if (regspic14[i].rIdx == idx)
530 return ®spic14[i];
532 //return ®spic14[0];
533 fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
534 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
535 "regWithIdx not found");
539 /*-----------------------------------------------------------------*/
540 /* pic14_regWithIdx - returns pointer to register wit index number */
541 /*-----------------------------------------------------------------*/
543 pic14_allocWithIdx (int idx)
547 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
549 for (i = 0; i < pic14_nRegs; i++)
550 if (regspic14[i].rIdx == idx){
551 debugLog ("%s - alloc fount index = 0x%x\n", __FUNCTION__,idx);
552 regspic14[i].wasUsed = 1;
553 regspic14[i].isFree = 0;
554 return ®spic14[i];
556 //return ®spic14[0];
557 fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
558 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
559 "regWithIdx not found");
562 /*-----------------------------------------------------------------*/
563 /*-----------------------------------------------------------------*/
565 pic14_findFreeReg(short type)
569 for (i = 0; i < pic14_nRegs; i++) {
570 if (!type && regspic14[i].isFree)
571 return ®spic14[i];
572 if (regspic14[i].isFree &&
573 regspic14[i].type == type)
574 return ®spic14[i];
578 /*-----------------------------------------------------------------*/
579 /* freeReg - frees a register */
580 /*-----------------------------------------------------------------*/
584 debugLog ("%s\n", __FUNCTION__);
589 /*-----------------------------------------------------------------*/
590 /* nFreeRegs - returns number of free registers */
591 /*-----------------------------------------------------------------*/
598 debugLog ("%s\n", __FUNCTION__);
599 for (i = 0; i < pic14_nRegs; i++)
600 if (regspic14[i].isFree && regspic14[i].type == type)
605 /*-----------------------------------------------------------------*/
606 /* nfreeRegsType - free registers with type */
607 /*-----------------------------------------------------------------*/
609 nfreeRegsType (int type)
612 debugLog ("%s\n", __FUNCTION__);
615 if ((nfr = nFreeRegs (type)) == 0)
616 return nFreeRegs (REG_GPR);
619 return nFreeRegs (type);
623 /*-----------------------------------------------------------------*/
624 /* allDefsOutOfRange - all definitions are out of a range */
625 /*-----------------------------------------------------------------*/
627 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
631 debugLog ("%s\n", __FUNCTION__);
635 for (i = 0; i < defs->size; i++)
639 if (bitVectBitValue (defs, i) &&
640 (ic = hTabItemWithKey (iCodehTab, i)) &&
641 (ic->seq >= fseq && ic->seq <= toseq))
650 /*-----------------------------------------------------------------*/
651 /* computeSpillable - given a point find the spillable live ranges */
652 /*-----------------------------------------------------------------*/
654 computeSpillable (iCode * ic)
658 debugLog ("%s\n", __FUNCTION__);
659 /* spillable live ranges are those that are live at this
660 point . the following categories need to be subtracted
662 a) - those that are already spilt
663 b) - if being used by this one
664 c) - defined by this one */
666 spillable = bitVectCopy (ic->rlive);
668 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
670 bitVectCplAnd (spillable, ic->uses); /* used in this one */
671 bitVectUnSetBit (spillable, ic->defKey);
672 spillable = bitVectIntersect (spillable, _G.regAssigned);
677 /*-----------------------------------------------------------------*/
678 /* noSpilLoc - return true if a variable has no spil location */
679 /*-----------------------------------------------------------------*/
681 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
683 debugLog ("%s\n", __FUNCTION__);
684 return (sym->usl.spillLoc ? 0 : 1);
687 /*-----------------------------------------------------------------*/
688 /* hasSpilLoc - will return 1 if the symbol has spil location */
689 /*-----------------------------------------------------------------*/
691 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
693 debugLog ("%s\n", __FUNCTION__);
694 return (sym->usl.spillLoc ? 1 : 0);
697 /*-----------------------------------------------------------------*/
698 /* directSpilLoc - will return 1 if the splilocation is in direct */
699 /*-----------------------------------------------------------------*/
701 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
703 debugLog ("%s\n", __FUNCTION__);
704 if (sym->usl.spillLoc &&
705 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
711 /*-----------------------------------------------------------------*/
712 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
713 /* but is not used as a pointer */
714 /*-----------------------------------------------------------------*/
716 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
718 debugLog ("%s\n", __FUNCTION__);
719 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
722 /*-----------------------------------------------------------------*/
723 /* rematable - will return 1 if the remat flag is set */
724 /*-----------------------------------------------------------------*/
726 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
728 debugLog ("%s\n", __FUNCTION__);
732 /*-----------------------------------------------------------------*/
733 /* notUsedInBlock - not used in this block */
734 /*-----------------------------------------------------------------*/
736 notUsedInBlock (symbol * sym, eBBlock * ebp, iCode * ic)
738 debugLog ("%s\n", __FUNCTION__);
739 return (!bitVectBitsInCommon (sym->defs, ebp->usesDefs) &&
740 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
741 /* return (!bitVectBitsInCommon(sym->defs,ebp->usesDefs)); */
744 /*-----------------------------------------------------------------*/
745 /* notUsedInRemaining - not used or defined in remain of the block */
746 /*-----------------------------------------------------------------*/
748 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
750 debugLog ("%s\n", __FUNCTION__);
751 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
752 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
755 /*-----------------------------------------------------------------*/
756 /* allLRs - return true for all */
757 /*-----------------------------------------------------------------*/
759 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
761 debugLog ("%s\n", __FUNCTION__);
765 /*-----------------------------------------------------------------*/
766 /* liveRangesWith - applies function to a given set of live range */
767 /*-----------------------------------------------------------------*/
769 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
770 eBBlock * ebp, iCode * ic)
775 debugLog ("%s\n", __FUNCTION__);
776 if (!lrs || !lrs->size)
779 for (i = 1; i < lrs->size; i++)
782 if (!bitVectBitValue (lrs, i))
785 /* if we don't find it in the live range
786 hash table we are in serious trouble */
787 if (!(sym = hTabItemWithKey (liveRanges, i)))
789 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
790 "liveRangesWith could not find liveRange");
794 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
795 addSetHead (&rset, sym);
802 /*-----------------------------------------------------------------*/
803 /* leastUsedLR - given a set determines which is the least used */
804 /*-----------------------------------------------------------------*/
806 leastUsedLR (set * sset)
808 symbol *sym = NULL, *lsym = NULL;
810 debugLog ("%s\n", __FUNCTION__);
811 sym = lsym = setFirstItem (sset);
816 for (; lsym; lsym = setNextItem (sset))
819 /* if usage is the same then prefer
820 the spill the smaller of the two */
821 if (lsym->used == sym->used)
822 if (getSize (lsym->type) < getSize (sym->type))
826 if (lsym->used < sym->used)
831 setToNull ((void **) &sset);
836 /*-----------------------------------------------------------------*/
837 /* noOverLap - will iterate through the list looking for over lap */
838 /*-----------------------------------------------------------------*/
840 noOverLap (set * itmpStack, symbol * fsym)
843 debugLog ("%s\n", __FUNCTION__);
846 for (sym = setFirstItem (itmpStack); sym;
847 sym = setNextItem (itmpStack))
849 if (sym->liveTo > fsym->liveFrom)
857 /*-----------------------------------------------------------------*/
858 /* isFree - will return 1 if the a free spil location is found */
859 /*-----------------------------------------------------------------*/
864 V_ARG (symbol **, sloc);
865 V_ARG (symbol *, fsym);
867 debugLog ("%s\n", __FUNCTION__);
868 /* if already found */
872 /* if it is free && and the itmp assigned to
873 this does not have any overlapping live ranges
874 with the one currently being assigned and
875 the size can be accomodated */
877 noOverLap (sym->usl.itmpStack, fsym) &&
878 getSize (sym->type) >= getSize (fsym->type))
887 /*-----------------------------------------------------------------*/
888 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
889 /*-----------------------------------------------------------------*/
891 spillLRWithPtrReg (symbol * forSym)
897 debugLog ("%s\n", __FUNCTION__);
898 if (!_G.regAssigned ||
899 bitVectIsZero (_G.regAssigned))
902 r0 = pic14_regWithIdx (R0_IDX);
903 r1 = pic14_regWithIdx (R1_IDX);
905 /* for all live ranges */
906 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
907 lrsym = hTabNextItem (liveRanges, &k))
911 /* if no registers assigned to it or
913 /* if it does not overlap with this then
914 not need to spill it */
916 if (lrsym->isspilt || !lrsym->nRegs ||
917 (lrsym->liveTo < forSym->liveFrom))
920 /* go thru the registers : if it is either
921 r0 or r1 then spil it */
922 for (j = 0; j < lrsym->nRegs; j++)
923 if (lrsym->regs[j] == r0 ||
924 lrsym->regs[j] == r1)
933 /*-----------------------------------------------------------------*/
934 /* createStackSpil - create a location on the stack to spil */
935 /*-----------------------------------------------------------------*/
937 createStackSpil (symbol * sym)
940 int useXstack, model, noOverlay;
943 debugLog ("%s\n", __FUNCTION__);
945 /* first go try and find a free one that is already
946 existing on the stack */
947 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
949 /* found a free one : just update & return */
950 sym->usl.spillLoc = sloc;
953 addSetHead (&sloc->usl.itmpStack, sym);
957 /* could not then have to create one , this is the hard part
958 we need to allocate this on the stack : this is really a
959 hack!! but cannot think of anything better at this time */
961 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
963 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
968 sloc = newiTemp (slocBuffer);
970 /* set the type to the spilling symbol */
971 sloc->type = copyLinkChain (sym->type);
972 sloc->etype = getSpec (sloc->type);
973 SPEC_SCLS (sloc->etype) = S_DATA;
974 SPEC_EXTR (sloc->etype) = 0;
975 SPEC_STAT (sloc->etype) = 0;
977 /* we don't allow it to be allocated`
978 onto the external stack since : so we
979 temporarily turn it off ; we also
980 turn off memory model to prevent
981 the spil from going to the external storage
982 and turn off overlaying
985 useXstack = options.useXstack;
986 model = options.model;
987 noOverlay = options.noOverlay;
988 options.noOverlay = 1;
989 options.model = options.useXstack = 0;
993 options.useXstack = useXstack;
994 options.model = model;
995 options.noOverlay = noOverlay;
996 sloc->isref = 1; /* to prevent compiler warning */
998 /* if it is on the stack then update the stack */
999 if (IN_STACK (sloc->etype))
1001 currFunc->stack += getSize (sloc->type);
1002 _G.stackExtend += getSize (sloc->type);
1005 _G.dataExtend += getSize (sloc->type);
1007 /* add it to the _G.stackSpil set */
1008 addSetHead (&_G.stackSpil, sloc);
1009 sym->usl.spillLoc = sloc;
1012 /* add it to the set of itempStack set
1013 of the spill location */
1014 addSetHead (&sloc->usl.itmpStack, sym);
1018 /*-----------------------------------------------------------------*/
1019 /* isSpiltOnStack - returns true if the spil location is on stack */
1020 /*-----------------------------------------------------------------*/
1022 isSpiltOnStack (symbol * sym)
1026 debugLog ("%s\n", __FUNCTION__);
1033 /* if (sym->_G.stackSpil) */
1036 if (!sym->usl.spillLoc)
1039 etype = getSpec (sym->usl.spillLoc->type);
1040 if (IN_STACK (etype))
1046 /*-----------------------------------------------------------------*/
1047 /* spillThis - spils a specific operand */
1048 /*-----------------------------------------------------------------*/
1050 spillThis (symbol * sym)
1053 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1055 /* if this is rematerializable or has a spillLocation
1056 we are okay, else we need to create a spillLocation
1058 if (!(sym->remat || sym->usl.spillLoc))
1059 createStackSpil (sym);
1062 /* mark it has spilt & put it in the spilt set */
1064 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1066 bitVectUnSetBit (_G.regAssigned, sym->key);
1068 for (i = 0; i < sym->nRegs; i++)
1072 freeReg (sym->regs[i]);
1073 sym->regs[i] = NULL;
1076 /* if spilt on stack then free up r0 & r1
1077 if they could have been assigned to some
1079 if (!pic14_ptrRegReq && isSpiltOnStack (sym))
1082 spillLRWithPtrReg (sym);
1085 if (sym->usl.spillLoc && !sym->remat)
1086 sym->usl.spillLoc->allocreq = 1;
1090 /*-----------------------------------------------------------------*/
1091 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1092 /*-----------------------------------------------------------------*/
1094 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1096 bitVect *lrcs = NULL;
1100 debugLog ("%s\n", __FUNCTION__);
1101 /* get the spillable live ranges */
1102 lrcs = computeSpillable (ic);
1104 /* get all live ranges that are rematerizable */
1105 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1108 /* return the least used of these */
1109 return leastUsedLR (selectS);
1112 /* get live ranges with spillLocations in direct space */
1113 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1115 sym = leastUsedLR (selectS);
1116 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1117 sym->usl.spillLoc->rname :
1118 sym->usl.spillLoc->name));
1120 /* mark it as allocation required */
1121 sym->usl.spillLoc->allocreq = 1;
1125 /* if the symbol is local to the block then */
1126 if (forSym->liveTo < ebp->lSeq)
1129 /* check if there are any live ranges allocated
1130 to registers that are not used in this block */
1131 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1133 sym = leastUsedLR (selectS);
1134 /* if this is not rematerializable */
1143 /* check if there are any live ranges that not
1144 used in the remainder of the block */
1145 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1147 sym = leastUsedLR (selectS);
1150 sym->remainSpil = 1;
1157 /* find live ranges with spillocation && not used as pointers */
1158 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1161 sym = leastUsedLR (selectS);
1162 /* mark this as allocation required */
1163 sym->usl.spillLoc->allocreq = 1;
1167 /* find live ranges with spillocation */
1168 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1171 sym = leastUsedLR (selectS);
1172 sym->usl.spillLoc->allocreq = 1;
1176 /* couldn't find then we need to create a spil
1177 location on the stack , for which one? the least
1179 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1182 /* return a created spil location */
1183 sym = createStackSpil (leastUsedLR (selectS));
1184 sym->usl.spillLoc->allocreq = 1;
1188 /* this is an extreme situation we will spill
1189 this one : happens very rarely but it does happen */
1195 /*-----------------------------------------------------------------*/
1196 /* spilSomething - spil some variable & mark registers as free */
1197 /*-----------------------------------------------------------------*/
1199 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1204 debugLog ("%s\n", __FUNCTION__);
1205 /* get something we can spil */
1206 ssym = selectSpil (ic, ebp, forSym);
1208 /* mark it as spilt */
1210 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1212 /* mark it as not register assigned &
1213 take it away from the set */
1214 bitVectUnSetBit (_G.regAssigned, ssym->key);
1216 /* mark the registers as free */
1217 for (i = 0; i < ssym->nRegs; i++)
1219 freeReg (ssym->regs[i]);
1221 /* if spilt on stack then free up r0 & r1
1222 if they could have been assigned to as gprs */
1223 if (!pic14_ptrRegReq && isSpiltOnStack (ssym))
1226 spillLRWithPtrReg (ssym);
1229 /* if this was a block level spil then insert push & pop
1230 at the start & end of block respectively */
1231 if (ssym->blockSpil)
1233 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1234 /* add push to the start of the block */
1235 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1236 ebp->sch->next : ebp->sch));
1237 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1238 /* add pop to the end of the block */
1239 addiCodeToeBBlock (ebp, nic, NULL);
1242 /* if spilt because not used in the remainder of the
1243 block then add a push before this instruction and
1244 a pop at the end of the block */
1245 if (ssym->remainSpil)
1248 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1249 /* add push just before this instruction */
1250 addiCodeToeBBlock (ebp, nic, ic);
1252 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1253 /* add pop to the end of the block */
1254 addiCodeToeBBlock (ebp, nic, NULL);
1263 /*-----------------------------------------------------------------*/
1264 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1265 /*-----------------------------------------------------------------*/
1267 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1271 debugLog ("%s\n", __FUNCTION__);
1273 /* try for a ptr type */
1274 if ((reg = allocReg (REG_PTR)))
1277 /* try for gpr type */
1278 if ((reg = allocReg (REG_GPR)))
1281 /* we have to spil */
1282 if (!spilSomething (ic, ebp, sym))
1285 /* this looks like an infinite loop but
1286 in really selectSpil will abort */
1290 /*-----------------------------------------------------------------*/
1291 /* getRegGpr - will try for GPR if not spil */
1292 /*-----------------------------------------------------------------*/
1294 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1298 debugLog ("%s\n", __FUNCTION__);
1300 /* try for gpr type */
1301 if ((reg = allocReg (REG_GPR)))
1304 if (!pic14_ptrRegReq)
1305 if ((reg = allocReg (REG_PTR)))
1308 /* we have to spil */
1309 if (!spilSomething (ic, ebp, sym))
1312 /* this looks like an infinite loop but
1313 in really selectSpil will abort */
1317 /*-----------------------------------------------------------------*/
1318 /* symHasReg - symbol has a given register */
1319 /*-----------------------------------------------------------------*/
1321 symHasReg (symbol * sym, regs * reg)
1325 debugLog ("%s\n", __FUNCTION__);
1326 for (i = 0; i < sym->nRegs; i++)
1327 if (sym->regs[i] == reg)
1333 /*-----------------------------------------------------------------*/
1334 /* deassignLRs - check the live to and if they have registers & are */
1335 /* not spilt then free up the registers */
1336 /*-----------------------------------------------------------------*/
1338 deassignLRs (iCode * ic, eBBlock * ebp)
1344 debugLog ("%s\n", __FUNCTION__);
1345 for (sym = hTabFirstItem (liveRanges, &k); sym;
1346 sym = hTabNextItem (liveRanges, &k))
1349 symbol *psym = NULL;
1350 /* if it does not end here */
1351 if (sym->liveTo > ic->seq)
1354 /* if it was spilt on stack then we can
1355 mark the stack spil location as free */
1360 sym->usl.spillLoc->isFree = 1;
1366 if (!bitVectBitValue (_G.regAssigned, sym->key))
1369 /* special case check if this is an IFX &
1370 the privious one was a pop and the
1371 previous one was not spilt then keep track
1373 if (ic->op == IFX && ic->prev &&
1374 ic->prev->op == IPOP &&
1375 !ic->prev->parmPush &&
1376 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1377 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1383 bitVectUnSetBit (_G.regAssigned, sym->key);
1385 /* if the result of this one needs registers
1386 and does not have it then assign it right
1388 if (IC_RESULT (ic) &&
1389 !(SKIP_IC2 (ic) || /* not a special icode */
1390 ic->op == JUMPTABLE ||
1395 POINTER_SET (ic)) &&
1396 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1397 result->liveTo > ic->seq && /* and will live beyond this */
1398 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1399 result->regType == sym->regType && /* same register types */
1400 result->nRegs && /* which needs registers */
1401 !result->isspilt && /* and does not already have them */
1403 !bitVectBitValue (_G.regAssigned, result->key) &&
1404 /* the number of free regs + number of regs in this LR
1405 can accomodate the what result Needs */
1406 ((nfreeRegsType (result->regType) +
1407 sym->nRegs) >= result->nRegs)
1411 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1413 result->regs[i] = sym->regs[i];
1415 result->regs[i] = getRegGpr (ic, ebp, result);
1417 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1421 /* free the remaining */
1422 for (; i < sym->nRegs; i++)
1426 if (!symHasReg (psym, sym->regs[i]))
1427 freeReg (sym->regs[i]);
1430 freeReg (sym->regs[i]);
1437 /*-----------------------------------------------------------------*/
1438 /* reassignLR - reassign this to registers */
1439 /*-----------------------------------------------------------------*/
1441 reassignLR (operand * op)
1443 symbol *sym = OP_SYMBOL (op);
1446 debugLog ("%s\n", __FUNCTION__);
1447 /* not spilt any more */
1448 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1449 bitVectUnSetBit (_G.spiltSet, sym->key);
1451 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1455 for (i = 0; i < sym->nRegs; i++)
1456 sym->regs[i]->isFree = 0;
1459 /*-----------------------------------------------------------------*/
1460 /* willCauseSpill - determines if allocating will cause a spill */
1461 /*-----------------------------------------------------------------*/
1463 willCauseSpill (int nr, int rt)
1465 debugLog ("%s\n", __FUNCTION__);
1466 /* first check if there are any avlb registers
1467 of te type required */
1470 /* special case for pointer type
1471 if pointer type not avlb then
1472 check for type gpr */
1473 if (nFreeRegs (rt) >= nr)
1475 if (nFreeRegs (REG_GPR) >= nr)
1480 if (pic14_ptrRegReq)
1482 if (nFreeRegs (rt) >= nr)
1487 if (nFreeRegs (REG_PTR) +
1488 nFreeRegs (REG_GPR) >= nr)
1493 debugLog (" ... yep it will (cause a spill)\n");
1494 /* it will cause a spil */
1498 /*-----------------------------------------------------------------*/
1499 /* positionRegs - the allocator can allocate same registers to res- */
1500 /* ult and operand, if this happens make sure they are in the same */
1501 /* position as the operand otherwise chaos results */
1502 /*-----------------------------------------------------------------*/
1504 positionRegs (symbol * result, symbol * opsym, int lineno)
1506 int count = min (result->nRegs, opsym->nRegs);
1507 int i, j = 0, shared = 0;
1509 debugLog ("%s\n", __FUNCTION__);
1510 /* if the result has been spilt then cannot share */
1515 /* first make sure that they actually share */
1516 for (i = 0; i < count; i++)
1518 for (j = 0; j < count; j++)
1520 if (result->regs[i] == opsym->regs[j] && i != j)
1530 regs *tmp = result->regs[i];
1531 result->regs[i] = result->regs[j];
1532 result->regs[j] = tmp;
1537 /*-----------------------------------------------------------------*/
1538 /* serialRegAssign - serially allocate registers to the variables */
1539 /*-----------------------------------------------------------------*/
1541 serialRegAssign (eBBlock ** ebbs, int count)
1545 debugLog ("%s\n", __FUNCTION__);
1546 /* for all blocks */
1547 for (i = 0; i < count; i++)
1552 if (ebbs[i]->noPath &&
1553 (ebbs[i]->entryLabel != entryLabel &&
1554 ebbs[i]->entryLabel != returnLabel))
1557 /* of all instructions do */
1558 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1561 debugLog (" op: %s\n", decodeOp (ic->op));
1563 /* if this is an ipop that means some live
1564 range will have to be assigned again */
1566 reassignLR (IC_LEFT (ic));
1568 /* if result is present && is a true symbol */
1569 if (IC_RESULT (ic) && ic->op != IFX &&
1570 IS_TRUE_SYMOP (IC_RESULT (ic)))
1571 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
1573 /* take away registers from live
1574 ranges that end at this instruction */
1575 deassignLRs (ic, ebbs[i]);
1577 /* some don't need registers */
1578 if (SKIP_IC2 (ic) ||
1579 ic->op == JUMPTABLE ||
1583 (IC_RESULT (ic) && POINTER_SET (ic)))
1586 /* now we need to allocate registers
1587 only for the result */
1590 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
1596 /* if it does not need or is spilt
1597 or is already assigned to registers
1598 or will not live beyond this instructions */
1601 bitVectBitValue (_G.regAssigned, sym->key) ||
1602 sym->liveTo <= ic->seq)
1605 /* if some liverange has been spilt at the block level
1606 and this one live beyond this block then spil this
1608 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
1613 /* if trying to allocate this will cause
1614 a spill and there is nothing to spill
1615 or this one is rematerializable then
1617 willCS = willCauseSpill (sym->nRegs, sym->regType);
1618 spillable = computeSpillable (ic);
1620 (willCS && bitVectIsZero (spillable)))
1628 /* if it has a spillocation & is used less than
1629 all other live ranges then spill this */
1631 if (sym->usl.spillLoc) {
1632 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
1633 allLRs, ebbs[i], ic));
1634 if (leastUsed && leastUsed->used > sym->used) {
1639 /* if none of the liveRanges have a spillLocation then better
1640 to spill this one than anything else already assigned to registers */
1641 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
1642 /* if this is local to this block then we might find a block spil */
1643 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
1651 if (ic->op == RECEIVE)
1652 debugLog ("When I get clever, I'll optimize the receive logic\n");
1654 /* if we need ptr regs for the right side
1656 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
1657 <= (unsigned) PTRSIZE)
1662 /* else we assign registers to it */
1663 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1665 debugLog (" %d - \n", __LINE__);
1667 bitVectDebugOn(_G.regAssigned, debugF);
1669 for (j = 0; j < sym->nRegs; j++)
1671 if (sym->regType == REG_PTR)
1672 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
1674 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
1676 /* if the allocation falied which means
1677 this was spilt then break */
1681 debugLog (" %d - \n", __LINE__);
1683 /* if it shares registers with operands make sure
1684 that they are in the same position */
1685 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
1686 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
1687 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1688 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
1689 /* do the same for the right operand */
1690 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
1691 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
1692 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1693 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
1695 debugLog (" %d - \n", __LINE__);
1698 debugLog (" %d - \n", __LINE__);
1708 /*-----------------------------------------------------------------*/
1709 /* rUmaskForOp :- returns register mask for an operand */
1710 /*-----------------------------------------------------------------*/
1712 rUmaskForOp (operand * op)
1718 debugLog ("%s\n", __FUNCTION__);
1719 /* only temporaries are assigned registers */
1723 sym = OP_SYMBOL (op);
1725 /* if spilt or no registers assigned to it
1727 if (sym->isspilt || !sym->nRegs)
1730 rumask = newBitVect (pic14_nRegs);
1732 for (j = 0; j < sym->nRegs; j++)
1734 rumask = bitVectSetBit (rumask,
1735 sym->regs[j]->rIdx);
1741 /*-----------------------------------------------------------------*/
1742 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
1743 /*-----------------------------------------------------------------*/
1745 regsUsedIniCode (iCode * ic)
1747 bitVect *rmask = newBitVect (pic14_nRegs);
1749 debugLog ("%s\n", __FUNCTION__);
1750 /* do the special cases first */
1753 rmask = bitVectUnion (rmask,
1754 rUmaskForOp (IC_COND (ic)));
1758 /* for the jumptable */
1759 if (ic->op == JUMPTABLE)
1761 rmask = bitVectUnion (rmask,
1762 rUmaskForOp (IC_JTCOND (ic)));
1767 /* of all other cases */
1769 rmask = bitVectUnion (rmask,
1770 rUmaskForOp (IC_LEFT (ic)));
1774 rmask = bitVectUnion (rmask,
1775 rUmaskForOp (IC_RIGHT (ic)));
1778 rmask = bitVectUnion (rmask,
1779 rUmaskForOp (IC_RESULT (ic)));
1785 /*-----------------------------------------------------------------*/
1786 /* createRegMask - for each instruction will determine the regsUsed */
1787 /*-----------------------------------------------------------------*/
1789 createRegMask (eBBlock ** ebbs, int count)
1793 debugLog ("%s\n", __FUNCTION__);
1794 /* for all blocks */
1795 for (i = 0; i < count; i++)
1799 if (ebbs[i]->noPath &&
1800 (ebbs[i]->entryLabel != entryLabel &&
1801 ebbs[i]->entryLabel != returnLabel))
1804 /* for all instructions */
1805 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1810 if (SKIP_IC2 (ic) || !ic->rlive)
1813 /* first mark the registers used in this
1815 ic->rUsed = regsUsedIniCode (ic);
1816 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
1818 /* now create the register mask for those
1819 registers that are in use : this is a
1820 super set of ic->rUsed */
1821 ic->rMask = newBitVect (pic14_nRegs + 1);
1823 /* for all live Ranges alive at this point */
1824 for (j = 1; j < ic->rlive->size; j++)
1829 /* if not alive then continue */
1830 if (!bitVectBitValue (ic->rlive, j))
1833 /* find the live range we are interested in */
1834 if (!(sym = hTabItemWithKey (liveRanges, j)))
1836 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1837 "createRegMask cannot find live range");
1841 /* if no register assigned to it */
1842 if (!sym->nRegs || sym->isspilt)
1845 /* for all the registers allocated to it */
1846 for (k = 0; k < sym->nRegs; k++)
1849 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
1855 /*-----------------------------------------------------------------*/
1856 /* rematStr - returns the rematerialized string for a remat var */
1857 /*-----------------------------------------------------------------*/
1859 rematStr (symbol * sym)
1862 iCode *ic = sym->rematiCode;
1864 debugLog ("%s\n", __FUNCTION__);
1869 /* if plus or minus print the right hand side */
1871 if (ic->op == '+' || ic->op == '-') {
1872 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
1875 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
1879 if (ic->op == '+' || ic->op == '-')
1881 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1882 sprintf (s, "(%s %c 0x%04x)",
1883 OP_SYMBOL (IC_LEFT (ric))->rname,
1885 (int) operandLitValue (IC_RIGHT (ic)));
1888 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
1893 /* we reached the end */
1894 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
1898 printf ("%s\n", buffer);
1902 /*-----------------------------------------------------------------*/
1903 /* regTypeNum - computes the type & number of registers required */
1904 /*-----------------------------------------------------------------*/
1912 debugLog ("%s\n", __FUNCTION__);
1913 /* for each live range do */
1914 for (sym = hTabFirstItem (liveRanges, &k); sym;
1915 sym = hTabNextItem (liveRanges, &k)) {
1917 debugLog (" %d - %s\n", __LINE__, sym->rname);
1919 /* if used zero times then no registers needed */
1920 if ((sym->liveTo - sym->liveFrom) == 0)
1924 /* if the live range is a temporary */
1927 debugLog (" %d - itemp register\n", __LINE__);
1929 /* if the type is marked as a conditional */
1930 if (sym->regType == REG_CND)
1933 /* if used in return only then we don't
1935 if (sym->ruonly || sym->accuse) {
1936 if (IS_AGGREGATE (sym->type) || sym->isptr)
1937 sym->type = aggrToPtr (sym->type, FALSE);
1938 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
1943 /* if the symbol has only one definition &
1944 that definition is a get_pointer and the
1945 pointer we are getting is rematerializable and
1948 if (bitVectnBitsOn (sym->defs) == 1 &&
1949 (ic = hTabItemWithKey (iCodehTab,
1950 bitVectFirstBit (sym->defs))) &&
1953 !IS_BITVAR (sym->etype)) {
1956 debugLog (" %d - \n", __LINE__);
1958 /* if remat in data space */
1959 if (OP_SYMBOL (IC_LEFT (ic))->remat &&
1960 DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) {
1962 /* create a psuedo symbol & force a spil */
1963 symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
1964 psym->type = sym->type;
1965 psym->etype = sym->etype;
1966 strcpy (psym->rname, psym->name);
1968 sym->usl.spillLoc = psym;
1972 /* if in data space or idata space then try to
1973 allocate pointer register */
1977 /* if not then we require registers */
1978 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
1979 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1980 getSize (sym->type));
1982 if (sym->nRegs > 4) {
1983 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
1984 printTypeChain (sym->type, stderr);
1985 fprintf (stderr, "\n");
1988 /* determine the type of register required */
1989 if (sym->nRegs == 1 &&
1990 IS_PTR (sym->type) &&
1992 sym->regType = REG_PTR;
1994 sym->regType = REG_GPR;
1997 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2001 /* for the first run we don't provide */
2002 /* registers for true symbols we will */
2003 /* see how things go */
2009 /*-----------------------------------------------------------------*/
2010 /* freeAllRegs - mark all registers as free */
2011 /*-----------------------------------------------------------------*/
2013 pic14_freeAllRegs ()
2017 debugLog ("%s\n", __FUNCTION__);
2018 for (i = 0; i < pic14_nRegs; i++)
2019 regspic14[i].isFree = 1;
2022 /*-----------------------------------------------------------------*/
2023 /*-----------------------------------------------------------------*/
2025 pic14_deallocateAllRegs ()
2029 debugLog ("%s\n", __FUNCTION__);
2030 for (i = 0; i < pic14_nRegs; i++) {
2031 if(regspic14[i].pc_type == PO_GPR_TEMP) {
2032 regspic14[i].isFree = 1;
2033 regspic14[i].wasUsed = 0;
2039 /*-----------------------------------------------------------------*/
2040 /* deallocStackSpil - this will set the stack pointer back */
2041 /*-----------------------------------------------------------------*/
2043 DEFSETFUNC (deallocStackSpil)
2047 debugLog ("%s\n", __FUNCTION__);
2052 /*-----------------------------------------------------------------*/
2053 /* farSpacePackable - returns the packable icode for far variables */
2054 /*-----------------------------------------------------------------*/
2056 farSpacePackable (iCode * ic)
2060 debugLog ("%s\n", __FUNCTION__);
2061 /* go thru till we find a definition for the
2062 symbol on the right */
2063 for (dic = ic->prev; dic; dic = dic->prev)
2066 /* if the definition is a call then no */
2067 if ((dic->op == CALL || dic->op == PCALL) &&
2068 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2073 /* if shift by unknown amount then not */
2074 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2075 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2078 /* if pointer get and size > 1 */
2079 if (POINTER_GET (dic) &&
2080 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2083 if (POINTER_SET (dic) &&
2084 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2087 /* if any three is a true symbol in far space */
2088 if (IC_RESULT (dic) &&
2089 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2090 isOperandInFarSpace (IC_RESULT (dic)))
2093 if (IC_RIGHT (dic) &&
2094 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2095 isOperandInFarSpace (IC_RIGHT (dic)) &&
2096 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2099 if (IC_LEFT (dic) &&
2100 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2101 isOperandInFarSpace (IC_LEFT (dic)) &&
2102 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2105 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2107 if ((dic->op == LEFT_OP ||
2108 dic->op == RIGHT_OP ||
2110 IS_OP_LITERAL (IC_RIGHT (dic)))
2120 /*-----------------------------------------------------------------*/
2121 /* packRegsForAssign - register reduction for assignment */
2122 /*-----------------------------------------------------------------*/
2124 packRegsForAssign (iCode * ic, eBBlock * ebp)
2129 debugLog ("%s\n", __FUNCTION__);
2131 debugAopGet (" result:", IC_RESULT (ic));
2132 debugAopGet (" left:", IC_LEFT (ic));
2133 debugAopGet (" right:", IC_RIGHT (ic));
2135 if (!IS_ITEMP (IC_RIGHT (ic)) ||
2136 OP_SYMBOL (IC_RIGHT (ic))->isind ||
2137 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2139 debugLog (" %d - not packing - right side fails \n", __LINE__);
2143 /* if the true symbol is defined in far space or on stack
2144 then we should not since this will increase register pressure */
2145 if (isOperandInFarSpace (IC_RESULT (ic)))
2147 if ((dic = farSpacePackable (ic)))
2153 /* find the definition of iTempNN scanning backwards if we find a
2154 a use of the true symbol before we find the definition then
2156 for (dic = ic->prev; dic; dic = dic->prev)
2159 /* if there is a function call and this is
2160 a parameter & not my parameter then don't pack it */
2161 if ((dic->op == CALL || dic->op == PCALL) &&
2162 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2163 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2165 debugLog (" %d - \n", __LINE__);
2173 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2174 IS_OP_VOLATILE (IC_RESULT (dic)))
2176 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2181 if (IS_SYMOP (IC_RESULT (dic)) &&
2182 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2184 /* A previous result was assigned to the same register - we'll our definition */
2185 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2186 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2187 if (POINTER_SET (dic))
2193 if (IS_SYMOP (IC_RIGHT (dic)) &&
2194 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2195 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2197 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
2202 if (IS_SYMOP (IC_LEFT (dic)) &&
2203 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2204 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2206 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
2211 if (POINTER_SET (dic) &&
2212 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2214 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
2222 return 0; /* did not find */
2224 /* if the result is on stack or iaccess then it must be
2225 the same atleast one of the operands */
2226 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2227 OP_SYMBOL (IC_RESULT (ic))->iaccess)
2230 /* the operation has only one symbol
2231 operator then we can pack */
2232 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2233 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2236 if (!((IC_LEFT (dic) &&
2237 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2239 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2243 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2244 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
2245 /* found the definition */
2246 /* replace the result with the result of */
2247 /* this assignment and remove this assignment */
2248 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2249 IC_RESULT (dic) = IC_RESULT (ic);
2251 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2253 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2255 /* delete from liverange table also
2256 delete from all the points inbetween and the new
2258 for (sic = dic; sic != ic; sic = sic->next)
2260 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2261 if (IS_ITEMP (IC_RESULT (dic)))
2262 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2265 remiCodeFromeBBlock (ebp, ic);
2266 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2267 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2268 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2274 /*-----------------------------------------------------------------*/
2275 /* findAssignToSym : scanning backwards looks for first assig found */
2276 /*-----------------------------------------------------------------*/
2278 findAssignToSym (operand * op, iCode * ic)
2282 debugLog ("%s\n", __FUNCTION__);
2283 for (dic = ic->prev; dic; dic = dic->prev)
2286 /* if definition by assignment */
2287 if (dic->op == '=' &&
2288 !POINTER_SET (dic) &&
2289 IC_RESULT (dic)->key == op->key
2290 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2294 /* we are interested only if defined in far space */
2295 /* or in stack space in case of + & - */
2297 /* if assigned to a non-symbol then return
2299 if (!IS_SYMOP (IC_RIGHT (dic)))
2302 /* if the symbol is in far space then
2304 if (isOperandInFarSpace (IC_RIGHT (dic)))
2307 /* for + & - operations make sure that
2308 if it is on the stack it is the same
2309 as one of the three operands */
2310 if ((ic->op == '+' || ic->op == '-') &&
2311 OP_SYMBOL (IC_RIGHT (dic))->onStack)
2314 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2315 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2316 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2324 /* if we find an usage then we cannot delete it */
2325 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2328 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2331 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2335 /* now make sure that the right side of dic
2336 is not defined between ic & dic */
2339 iCode *sic = dic->next;
2341 for (; sic != ic; sic = sic->next)
2342 if (IC_RESULT (sic) &&
2343 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2352 /*-----------------------------------------------------------------*/
2353 /* packRegsForSupport :- reduce some registers for support calls */
2354 /*-----------------------------------------------------------------*/
2356 packRegsForSupport (iCode * ic, eBBlock * ebp)
2360 debugLog ("%s\n", __FUNCTION__);
2361 /* for the left & right operand :- look to see if the
2362 left was assigned a true symbol in far space in that
2363 case replace them */
2364 if (IS_ITEMP (IC_LEFT (ic)) &&
2365 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2367 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
2373 debugAopGet ("removing left:", IC_LEFT (ic));
2375 /* found it we need to remove it from the
2377 for (sic = dic; sic != ic; sic = sic->next)
2378 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
2380 IC_LEFT (ic)->operand.symOperand =
2381 IC_RIGHT (dic)->operand.symOperand;
2382 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2383 remiCodeFromeBBlock (ebp, dic);
2384 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2385 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2389 /* do the same for the right operand */
2392 IS_ITEMP (IC_RIGHT (ic)) &&
2393 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2395 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2401 /* if this is a subtraction & the result
2402 is a true symbol in far space then don't pack */
2403 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
2405 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
2406 if (IN_FARSPACE (SPEC_OCLS (etype)))
2410 debugAopGet ("removing right:", IC_RIGHT (ic));
2412 /* found it we need to remove it from the
2414 for (sic = dic; sic != ic; sic = sic->next)
2415 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
2417 IC_RIGHT (ic)->operand.symOperand =
2418 IC_RIGHT (dic)->operand.symOperand;
2419 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2421 remiCodeFromeBBlock (ebp, dic);
2422 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2423 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2430 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
2433 /*-----------------------------------------------------------------*/
2434 /* packRegsForOneuse : - will reduce some registers for single Use */
2435 /*-----------------------------------------------------------------*/
2437 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
2442 debugLog ("%s\n", __FUNCTION__);
2443 /* if returning a literal then do nothing */
2447 /* only upto 2 bytes since we cannot predict
2448 the usage of b, & acc */
2449 if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
2454 /* this routine will mark the a symbol as used in one
2455 instruction use only && if the definition is local
2456 (ie. within the basic block) && has only one definition &&
2457 that definition is either a return value from a
2458 function or does not contain any variables in
2460 uses = bitVectCopy (OP_USES (op));
2461 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
2462 if (!bitVectIsZero (uses)) /* has other uses */
2465 /* if it has only one defintion */
2466 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
2467 return NULL; /* has more than one definition */
2469 /* get that definition */
2471 hTabItemWithKey (iCodehTab,
2472 bitVectFirstBit (OP_DEFS (op)))))
2475 /* found the definition now check if it is local */
2476 if (dic->seq < ebp->fSeq ||
2477 dic->seq > ebp->lSeq)
2478 return NULL; /* non-local */
2480 /* now check if it is the return from
2482 if (dic->op == CALL || dic->op == PCALL)
2484 if (ic->op != SEND && ic->op != RETURN &&
2485 !POINTER_SET(ic) && !POINTER_GET(ic))
2487 OP_SYMBOL (op)->ruonly = 1;
2494 /* otherwise check that the definition does
2495 not contain any symbols in far space */
2496 if (isOperandInFarSpace (IC_LEFT (dic)) ||
2497 isOperandInFarSpace (IC_RIGHT (dic)) ||
2498 IS_OP_RUONLY (IC_LEFT (ic)) ||
2499 IS_OP_RUONLY (IC_RIGHT (ic)))
2504 /* if pointer set then make sure the pointer
2506 if (POINTER_SET (dic) &&
2507 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2510 if (POINTER_GET (dic) &&
2511 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2516 /* also make sure the intervenening instructions
2517 don't have any thing in far space */
2518 for (dic = dic->next; dic && dic != ic; dic = dic->next)
2521 /* if there is an intervening function call then no */
2522 if (dic->op == CALL || dic->op == PCALL)
2524 /* if pointer set then make sure the pointer
2526 if (POINTER_SET (dic) &&
2527 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2530 if (POINTER_GET (dic) &&
2531 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2534 /* if address of & the result is remat then okay */
2535 if (dic->op == ADDRESS_OF &&
2536 OP_SYMBOL (IC_RESULT (dic))->remat)
2539 /* if operand has size of three or more & this
2540 operation is a '*','/' or '%' then 'b' may
2542 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
2543 getSize (operandType (op)) >= 3)
2546 /* if left or right or result is in far space */
2547 if (isOperandInFarSpace (IC_LEFT (dic)) ||
2548 isOperandInFarSpace (IC_RIGHT (dic)) ||
2549 isOperandInFarSpace (IC_RESULT (dic)) ||
2550 IS_OP_RUONLY (IC_LEFT (dic)) ||
2551 IS_OP_RUONLY (IC_RIGHT (dic)) ||
2552 IS_OP_RUONLY (IC_RESULT (dic)))
2558 OP_SYMBOL (op)->ruonly = 1;
2563 /*-----------------------------------------------------------------*/
2564 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
2565 /*-----------------------------------------------------------------*/
2567 isBitwiseOptimizable (iCode * ic)
2569 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
2570 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
2572 debugLog ("%s\n", __FUNCTION__);
2573 /* bitwise operations are considered optimizable
2574 under the following conditions (Jean-Louis VERN)
2586 if (IS_LITERAL (rtype) ||
2587 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
2593 /*-----------------------------------------------------------------*/
2594 /* packRegsForAccUse - pack registers for acc use */
2595 /*-----------------------------------------------------------------*/
2597 packRegsForAccUse (iCode * ic)
2601 debugLog ("%s\n", __FUNCTION__);
2603 /* if this is an aggregate, e.g. a one byte char array */
2604 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
2608 /* if + or - then it has to be one byte result */
2609 if ((ic->op == '+' || ic->op == '-')
2610 && getSize (operandType (IC_RESULT (ic))) > 1)
2613 /* if shift operation make sure right side is not a literal */
2614 if (ic->op == RIGHT_OP &&
2615 (isOperandLiteral (IC_RIGHT (ic)) ||
2616 getSize (operandType (IC_RESULT (ic))) > 1))
2619 if (ic->op == LEFT_OP &&
2620 (isOperandLiteral (IC_RIGHT (ic)) ||
2621 getSize (operandType (IC_RESULT (ic))) > 1))
2624 if (IS_BITWISE_OP (ic) &&
2625 getSize (operandType (IC_RESULT (ic))) > 1)
2629 /* has only one definition */
2630 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
2633 /* has only one use */
2634 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
2637 /* and the usage immediately follows this iCode */
2638 if (!(uic = hTabItemWithKey (iCodehTab,
2639 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
2642 if (ic->next != uic)
2645 /* if it is a conditional branch then we definitely can */
2649 if (uic->op == JUMPTABLE)
2652 /* if the usage is not is an assignment
2653 or an arithmetic / bitwise / shift operation then not */
2654 if (POINTER_SET (uic) &&
2655 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
2658 if (uic->op != '=' &&
2659 !IS_ARITHMETIC_OP (uic) &&
2660 !IS_BITWISE_OP (uic) &&
2661 uic->op != LEFT_OP &&
2662 uic->op != RIGHT_OP)
2665 /* if used in ^ operation then make sure right is not a
2667 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
2670 /* if shift operation make sure right side is not a literal */
2671 if (uic->op == RIGHT_OP &&
2672 (isOperandLiteral (IC_RIGHT (uic)) ||
2673 getSize (operandType (IC_RESULT (uic))) > 1))
2676 if (uic->op == LEFT_OP &&
2677 (isOperandLiteral (IC_RIGHT (uic)) ||
2678 getSize (operandType (IC_RESULT (uic))) > 1))
2681 /* make sure that the result of this icode is not on the
2682 stack, since acc is used to compute stack offset */
2683 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
2684 OP_SYMBOL (IC_RESULT (uic))->onStack)
2687 /* if either one of them in far space then we cannot */
2688 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
2689 isOperandInFarSpace (IC_LEFT (uic))) ||
2690 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
2691 isOperandInFarSpace (IC_RIGHT (uic))))
2694 /* if the usage has only one operand then we can */
2695 if (IC_LEFT (uic) == NULL ||
2696 IC_RIGHT (uic) == NULL)
2699 /* make sure this is on the left side if not
2700 a '+' since '+' is commutative */
2701 if (ic->op != '+' &&
2702 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
2705 /* if one of them is a literal then we can */
2706 if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
2707 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
2709 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2713 /* if the other one is not on stack then we can */
2714 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
2715 (IS_ITEMP (IC_RIGHT (uic)) ||
2716 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
2717 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
2720 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
2721 (IS_ITEMP (IC_LEFT (uic)) ||
2722 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
2723 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
2729 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2734 /*-----------------------------------------------------------------*/
2735 /* packForPush - hueristics to reduce iCode for pushing */
2736 /*-----------------------------------------------------------------*/
2738 packForReceive (iCode * ic, eBBlock * ebp)
2742 debugLog ("%s\n", __FUNCTION__);
2743 debugAopGet (" result:", IC_RESULT (ic));
2744 debugAopGet (" left:", IC_LEFT (ic));
2745 debugAopGet (" right:", IC_RIGHT (ic));
2750 for (dic = ic->next; dic; dic = dic->next)
2755 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
2756 debugLog (" used on left\n");
2757 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
2758 debugLog (" used on right\n");
2759 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
2760 debugLog (" used on result\n");
2762 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
2763 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
2768 debugLog (" hey we can remove this unnecessary assign\n");
2770 /*-----------------------------------------------------------------*/
2771 /* packForPush - hueristics to reduce iCode for pushing */
2772 /*-----------------------------------------------------------------*/
2774 packForPush (iCode * ic, eBBlock * ebp)
2778 debugLog ("%s\n", __FUNCTION__);
2779 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
2782 /* must have only definition & one usage */
2783 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
2784 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
2787 /* find the definition */
2788 if (!(dic = hTabItemWithKey (iCodehTab,
2789 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
2792 if (dic->op != '=' || POINTER_SET (dic))
2795 /* we now we know that it has one & only one def & use
2796 and the that the definition is an assignment */
2797 IC_LEFT (ic) = IC_RIGHT (dic);
2799 remiCodeFromeBBlock (ebp, dic);
2800 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2801 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2804 /*-----------------------------------------------------------------*/
2805 /* packRegisters - does some transformations to reduce register */
2807 /*-----------------------------------------------------------------*/
2809 packRegisters (eBBlock * ebp)
2814 debugLog ("%s\n", __FUNCTION__);
2821 /* look for assignments of the form */
2822 /* iTempNN = TRueSym (someoperation) SomeOperand */
2824 /* TrueSym := iTempNN:1 */
2825 for (ic = ebp->sch; ic; ic = ic->next)
2828 /* find assignment of the form TrueSym := iTempNN:1 */
2829 if (ic->op == '=' && !POINTER_SET (ic))
2830 change += packRegsForAssign (ic, ebp);
2834 if (POINTER_SET (ic))
2835 debugLog ("pointer is set\n");
2836 debugAopGet (" result:", IC_RESULT (ic));
2837 debugAopGet (" left:", IC_LEFT (ic));
2838 debugAopGet (" right:", IC_RIGHT (ic));
2847 for (ic = ebp->sch; ic; ic = ic->next)
2850 /* if this is an itemp & result of a address of a true sym
2851 then mark this as rematerialisable */
2852 if (ic->op == ADDRESS_OF &&
2853 IS_ITEMP (IC_RESULT (ic)) &&
2854 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
2855 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2856 !OP_SYMBOL (IC_LEFT (ic))->onStack)
2859 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
2861 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2862 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2863 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2867 /* if straight assignment then carry remat flag if
2868 this is the only definition */
2869 if (ic->op == '=' &&
2870 !POINTER_SET (ic) &&
2871 IS_SYMOP (IC_RIGHT (ic)) &&
2872 OP_SYMBOL (IC_RIGHT (ic))->remat &&
2873 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
2875 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
2877 OP_SYMBOL (IC_RESULT (ic))->remat =
2878 OP_SYMBOL (IC_RIGHT (ic))->remat;
2879 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
2880 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
2883 /* if this is a +/- operation with a rematerizable
2884 then mark this as rematerializable as well */
2885 if ((ic->op == '+' || ic->op == '-') &&
2886 (IS_SYMOP (IC_LEFT (ic)) &&
2887 IS_ITEMP (IC_RESULT (ic)) &&
2888 OP_SYMBOL (IC_LEFT (ic))->remat &&
2889 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2890 IS_OP_LITERAL (IC_RIGHT (ic))))
2892 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
2894 operandLitValue (IC_RIGHT (ic));
2895 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2896 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2897 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2900 /* mark the pointer usages */
2901 if (POINTER_SET (ic))
2903 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
2904 debugLog (" marking as a pointer (set) =>");
2905 debugAopGet (" result:", IC_RESULT (ic));
2907 if (POINTER_GET (ic))
2909 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
2910 debugLog (" marking as a pointer (get) =>");
2911 debugAopGet (" left:", IC_LEFT (ic));
2916 /* if we are using a symbol on the stack
2917 then we should say pic14_ptrRegReq */
2918 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
2919 pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
2920 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
2921 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
2922 pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
2923 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
2926 if (IS_SYMOP (IC_LEFT (ic)))
2927 pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
2928 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
2929 if (IS_SYMOP (IC_RIGHT (ic)))
2930 pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
2931 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
2932 if (IS_SYMOP (IC_RESULT (ic)))
2933 pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
2934 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
2938 /* if the condition of an if instruction
2939 is defined in the previous instruction then
2940 mark the itemp as a conditional */
2941 if ((IS_CONDITIONAL (ic) ||
2942 ((ic->op == BITWISEAND ||
2945 isBitwiseOptimizable (ic))) &&
2946 ic->next && ic->next->op == IFX &&
2947 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
2948 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2951 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
2955 /* reduce for support function calls */
2956 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
2957 packRegsForSupport (ic, ebp);
2959 /* if a parameter is passed, it's in W, so we may not
2960 need to place a copy in a register */
2961 if (ic->op == RECEIVE)
2962 packForReceive (ic, ebp);
2964 /* some cases the redundant moves can
2965 can be eliminated for return statements */
2966 if ((ic->op == RETURN || ic->op == SEND) &&
2967 !isOperandInFarSpace (IC_LEFT (ic)) &&
2969 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2971 /* if pointer set & left has a size more than
2972 one and right is not in far space */
2973 if (POINTER_SET (ic) &&
2974 !isOperandInFarSpace (IC_RIGHT (ic)) &&
2975 !OP_SYMBOL (IC_RESULT (ic))->remat &&
2976 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
2977 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
2979 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
2981 /* if pointer get */
2982 if (POINTER_GET (ic) &&
2983 !isOperandInFarSpace (IC_RESULT (ic)) &&
2984 !OP_SYMBOL (IC_LEFT (ic))->remat &&
2985 !IS_OP_RUONLY (IC_RESULT (ic)) &&
2986 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
2988 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2991 /* if this is cast for intergral promotion then
2992 check if only use of the definition of the
2993 operand being casted/ if yes then replace
2994 the result of that arithmetic operation with
2995 this result and get rid of the cast */
2998 sym_link *fromType = operandType (IC_RIGHT (ic));
2999 sym_link *toType = operandType (IC_LEFT (ic));
3001 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3002 getSize (fromType) != getSize (toType))
3005 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3008 if (IS_ARITHMETIC_OP (dic))
3010 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3011 IC_RESULT (dic) = IC_RESULT (ic);
3012 remiCodeFromeBBlock (ebp, ic);
3013 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3014 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3015 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3019 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3025 /* if the type from and type to are the same
3026 then if this is the only use then packit */
3027 if (compareType (operandType (IC_RIGHT (ic)),
3028 operandType (IC_LEFT (ic))) == 1)
3030 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3033 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3034 IC_RESULT (dic) = IC_RESULT (ic);
3035 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3036 remiCodeFromeBBlock (ebp, ic);
3037 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3038 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3046 iTempNN := (some variable in farspace) V1
3051 if (ic->op == IPUSH)
3053 packForPush (ic, ebp);
3057 /* pack registers for accumulator use, when the
3058 result of an arithmetic or bit wise operation
3059 has only one use, that use is immediately following
3060 the defintion and the using iCode has only one
3061 operand or has two operands but one is literal &
3062 the result of that operation is not on stack then
3063 we can leave the result of this operation in acc:b
3065 if ((IS_ARITHMETIC_OP (ic)
3067 || IS_BITWISE_OP (ic)
3069 || ic->op == LEFT_OP || ic->op == RIGHT_OP
3072 IS_ITEMP (IC_RESULT (ic)) &&
3073 getSize (operandType (IC_RESULT (ic))) <= 2)
3075 packRegsForAccUse (ic);
3081 dumpEbbsToDebug (eBBlock ** ebbs, int count)
3085 if (!debug || !debugF)
3088 for (i = 0; i < count; i++)
3090 fprintf (debugF, "\n----------------------------------------------------------------\n");
3091 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
3092 ebbs[i]->entryLabel->name,
3095 ebbs[i]->isLastInLoop);
3096 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
3101 fprintf (debugF, "visited %d : hasFcall = %d\n",
3105 fprintf (debugF, "\ndefines bitVector :");
3106 bitVectDebugOn (ebbs[i]->defSet, debugF);
3107 fprintf (debugF, "\nlocal defines bitVector :");
3108 bitVectDebugOn (ebbs[i]->ldefs, debugF);
3109 fprintf (debugF, "\npointers Set bitvector :");
3110 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
3111 fprintf (debugF, "\nin pointers Set bitvector :");
3112 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
3113 fprintf (debugF, "\ninDefs Set bitvector :");
3114 bitVectDebugOn (ebbs[i]->inDefs, debugF);
3115 fprintf (debugF, "\noutDefs Set bitvector :");
3116 bitVectDebugOn (ebbs[i]->outDefs, debugF);
3117 fprintf (debugF, "\nusesDefs Set bitvector :");
3118 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
3119 fprintf (debugF, "\n----------------------------------------------------------------\n");
3120 printiCChain (ebbs[i]->sch, debugF);
3123 /*-----------------------------------------------------------------*/
3124 /* assignRegisters - assigns registers to each live range as need */
3125 /*-----------------------------------------------------------------*/
3127 pic14_assignRegisters (eBBlock ** ebbs, int count)
3132 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
3133 debugLog ("\nebbs before optimizing:\n");
3134 dumpEbbsToDebug (ebbs, count);
3136 setToNull ((void *) &_G.funcrUsed);
3137 pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3140 /* change assignments this will remove some
3141 live ranges reducing some register pressure */
3142 for (i = 0; i < count; i++)
3143 packRegisters (ebbs[i]);
3145 if (options.dump_pack)
3146 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3148 /* first determine for each live range the number of
3149 registers & the type of registers required for each */
3152 /* and serially allocate registers */
3153 serialRegAssign (ebbs, count);
3155 /* if stack was extended then tell the user */
3158 /* werror(W_TOOMANY_SPILS,"stack", */
3159 /* _G.stackExtend,currFunc->name,""); */
3165 /* werror(W_TOOMANY_SPILS,"data space", */
3166 /* _G.dataExtend,currFunc->name,""); */
3170 /* after that create the register mask
3171 for each of the instruction */
3172 createRegMask (ebbs, count);
3174 /* redo that offsets for stacked automatic variables */
3175 redoStackOffsets ();
3177 if (options.dump_rassgn)
3178 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3180 /* now get back the chain */
3181 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3183 debugLog ("ebbs after optimizing:\n");
3184 dumpEbbsToDebug (ebbs, count);
3189 /* free up any _G.stackSpil locations allocated */
3190 applyToSet (_G.stackSpil, deallocStackSpil);
3192 setToNull ((void **) &_G.stackSpil);
3193 setToNull ((void **) &_G.spiltSet);
3194 /* mark all registers as free */
3195 pic14_freeAllRegs ();
3197 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");