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 - \n", __LINE__);
2181 if (IS_SYMOP (IC_RESULT (dic)) &&
2182 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2184 debugLog (" %d - dic key == ic key -- pointer set=%c\n", __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2185 if (POINTER_SET (dic))
2191 if (IS_SYMOP (IC_RIGHT (dic)) &&
2192 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2193 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2195 debugLog (" %d - \n", __LINE__);
2200 if (IS_SYMOP (IC_LEFT (dic)) &&
2201 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2202 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2204 debugLog (" %d - \n", __LINE__);
2209 if (POINTER_SET (dic) &&
2210 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2212 debugLog (" %d - \n", __LINE__);
2219 return 0; /* did not find */
2221 /* if the result is on stack or iaccess then it must be
2222 the same atleast one of the operands */
2223 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2224 OP_SYMBOL (IC_RESULT (ic))->iaccess)
2227 /* the operation has only one symbol
2228 operator then we can pack */
2229 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2230 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2233 if (!((IC_LEFT (dic) &&
2234 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2236 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2240 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2241 /* found the definition */
2242 /* replace the result with the result of */
2243 /* this assignment and remove this assignment */
2244 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2245 IC_RESULT (dic) = IC_RESULT (ic);
2247 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2249 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2251 /* delete from liverange table also
2252 delete from all the points inbetween and the new
2254 for (sic = dic; sic != ic; sic = sic->next)
2256 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2257 if (IS_ITEMP (IC_RESULT (dic)))
2258 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2261 remiCodeFromeBBlock (ebp, ic);
2262 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2263 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2264 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2270 /*-----------------------------------------------------------------*/
2271 /* findAssignToSym : scanning backwards looks for first assig found */
2272 /*-----------------------------------------------------------------*/
2274 findAssignToSym (operand * op, iCode * ic)
2278 debugLog ("%s\n", __FUNCTION__);
2279 for (dic = ic->prev; dic; dic = dic->prev)
2282 /* if definition by assignment */
2283 if (dic->op == '=' &&
2284 !POINTER_SET (dic) &&
2285 IC_RESULT (dic)->key == op->key
2286 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2290 /* we are interested only if defined in far space */
2291 /* or in stack space in case of + & - */
2293 /* if assigned to a non-symbol then return
2295 if (!IS_SYMOP (IC_RIGHT (dic)))
2298 /* if the symbol is in far space then
2300 if (isOperandInFarSpace (IC_RIGHT (dic)))
2303 /* for + & - operations make sure that
2304 if it is on the stack it is the same
2305 as one of the three operands */
2306 if ((ic->op == '+' || ic->op == '-') &&
2307 OP_SYMBOL (IC_RIGHT (dic))->onStack)
2310 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2311 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2312 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2320 /* if we find an usage then we cannot delete it */
2321 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2324 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2327 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2331 /* now make sure that the right side of dic
2332 is not defined between ic & dic */
2335 iCode *sic = dic->next;
2337 for (; sic != ic; sic = sic->next)
2338 if (IC_RESULT (sic) &&
2339 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2348 /*-----------------------------------------------------------------*/
2349 /* packRegsForSupport :- reduce some registers for support calls */
2350 /*-----------------------------------------------------------------*/
2352 packRegsForSupport (iCode * ic, eBBlock * ebp)
2356 debugLog ("%s\n", __FUNCTION__);
2357 /* for the left & right operand :- look to see if the
2358 left was assigned a true symbol in far space in that
2359 case replace them */
2360 if (IS_ITEMP (IC_LEFT (ic)) &&
2361 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2363 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
2369 debugAopGet ("removing left:", IC_LEFT (ic));
2371 /* found it we need to remove it from the
2373 for (sic = dic; sic != ic; sic = sic->next)
2374 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
2376 IC_LEFT (ic)->operand.symOperand =
2377 IC_RIGHT (dic)->operand.symOperand;
2378 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2379 remiCodeFromeBBlock (ebp, dic);
2380 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2381 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2385 /* do the same for the right operand */
2388 IS_ITEMP (IC_RIGHT (ic)) &&
2389 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2391 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2397 /* if this is a subtraction & the result
2398 is a true symbol in far space then don't pack */
2399 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
2401 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
2402 if (IN_FARSPACE (SPEC_OCLS (etype)))
2406 debugAopGet ("removing right:", IC_RIGHT (ic));
2408 /* found it we need to remove it from the
2410 for (sic = dic; sic != ic; sic = sic->next)
2411 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
2413 IC_RIGHT (ic)->operand.symOperand =
2414 IC_RIGHT (dic)->operand.symOperand;
2415 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2417 remiCodeFromeBBlock (ebp, dic);
2418 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2419 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2426 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
2429 /*-----------------------------------------------------------------*/
2430 /* packRegsForOneuse : - will reduce some registers for single Use */
2431 /*-----------------------------------------------------------------*/
2433 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
2438 debugLog ("%s\n", __FUNCTION__);
2439 /* if returning a literal then do nothing */
2443 /* only upto 2 bytes since we cannot predict
2444 the usage of b, & acc */
2445 if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
2450 /* this routine will mark the a symbol as used in one
2451 instruction use only && if the definition is local
2452 (ie. within the basic block) && has only one definition &&
2453 that definition is either a return value from a
2454 function or does not contain any variables in
2456 uses = bitVectCopy (OP_USES (op));
2457 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
2458 if (!bitVectIsZero (uses)) /* has other uses */
2461 /* if it has only one defintion */
2462 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
2463 return NULL; /* has more than one definition */
2465 /* get that definition */
2467 hTabItemWithKey (iCodehTab,
2468 bitVectFirstBit (OP_DEFS (op)))))
2471 /* found the definition now check if it is local */
2472 if (dic->seq < ebp->fSeq ||
2473 dic->seq > ebp->lSeq)
2474 return NULL; /* non-local */
2476 /* now check if it is the return from
2478 if (dic->op == CALL || dic->op == PCALL)
2480 if (ic->op != SEND && ic->op != RETURN &&
2481 !POINTER_SET(ic) && !POINTER_GET(ic))
2483 OP_SYMBOL (op)->ruonly = 1;
2490 /* otherwise check that the definition does
2491 not contain any symbols in far space */
2492 if (isOperandInFarSpace (IC_LEFT (dic)) ||
2493 isOperandInFarSpace (IC_RIGHT (dic)) ||
2494 IS_OP_RUONLY (IC_LEFT (ic)) ||
2495 IS_OP_RUONLY (IC_RIGHT (ic)))
2500 /* if pointer set then make sure the pointer
2502 if (POINTER_SET (dic) &&
2503 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2506 if (POINTER_GET (dic) &&
2507 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2512 /* also make sure the intervenening instructions
2513 don't have any thing in far space */
2514 for (dic = dic->next; dic && dic != ic; dic = dic->next)
2517 /* if there is an intervening function call then no */
2518 if (dic->op == CALL || dic->op == PCALL)
2520 /* if pointer set then make sure the pointer
2522 if (POINTER_SET (dic) &&
2523 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2526 if (POINTER_GET (dic) &&
2527 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2530 /* if address of & the result is remat then okay */
2531 if (dic->op == ADDRESS_OF &&
2532 OP_SYMBOL (IC_RESULT (dic))->remat)
2535 /* if operand has size of three or more & this
2536 operation is a '*','/' or '%' then 'b' may
2538 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
2539 getSize (operandType (op)) >= 3)
2542 /* if left or right or result is in far space */
2543 if (isOperandInFarSpace (IC_LEFT (dic)) ||
2544 isOperandInFarSpace (IC_RIGHT (dic)) ||
2545 isOperandInFarSpace (IC_RESULT (dic)) ||
2546 IS_OP_RUONLY (IC_LEFT (dic)) ||
2547 IS_OP_RUONLY (IC_RIGHT (dic)) ||
2548 IS_OP_RUONLY (IC_RESULT (dic)))
2554 OP_SYMBOL (op)->ruonly = 1;
2559 /*-----------------------------------------------------------------*/
2560 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
2561 /*-----------------------------------------------------------------*/
2563 isBitwiseOptimizable (iCode * ic)
2565 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
2566 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
2568 debugLog ("%s\n", __FUNCTION__);
2569 /* bitwise operations are considered optimizable
2570 under the following conditions (Jean-Louis VERN)
2582 if (IS_LITERAL (rtype) ||
2583 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
2589 /*-----------------------------------------------------------------*/
2590 /* packRegsForAccUse - pack registers for acc use */
2591 /*-----------------------------------------------------------------*/
2593 packRegsForAccUse (iCode * ic)
2597 debugLog ("%s\n", __FUNCTION__);
2599 /* if this is an aggregate, e.g. a one byte char array */
2600 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
2604 /* if + or - then it has to be one byte result */
2605 if ((ic->op == '+' || ic->op == '-')
2606 && getSize (operandType (IC_RESULT (ic))) > 1)
2609 /* if shift operation make sure right side is not a literal */
2610 if (ic->op == RIGHT_OP &&
2611 (isOperandLiteral (IC_RIGHT (ic)) ||
2612 getSize (operandType (IC_RESULT (ic))) > 1))
2615 if (ic->op == LEFT_OP &&
2616 (isOperandLiteral (IC_RIGHT (ic)) ||
2617 getSize (operandType (IC_RESULT (ic))) > 1))
2620 if (IS_BITWISE_OP (ic) &&
2621 getSize (operandType (IC_RESULT (ic))) > 1)
2625 /* has only one definition */
2626 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
2629 /* has only one use */
2630 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
2633 /* and the usage immediately follows this iCode */
2634 if (!(uic = hTabItemWithKey (iCodehTab,
2635 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
2638 if (ic->next != uic)
2641 /* if it is a conditional branch then we definitely can */
2645 if (uic->op == JUMPTABLE)
2648 /* if the usage is not is an assignment
2649 or an arithmetic / bitwise / shift operation then not */
2650 if (POINTER_SET (uic) &&
2651 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
2654 if (uic->op != '=' &&
2655 !IS_ARITHMETIC_OP (uic) &&
2656 !IS_BITWISE_OP (uic) &&
2657 uic->op != LEFT_OP &&
2658 uic->op != RIGHT_OP)
2661 /* if used in ^ operation then make sure right is not a
2663 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
2666 /* if shift operation make sure right side is not a literal */
2667 if (uic->op == RIGHT_OP &&
2668 (isOperandLiteral (IC_RIGHT (uic)) ||
2669 getSize (operandType (IC_RESULT (uic))) > 1))
2672 if (uic->op == LEFT_OP &&
2673 (isOperandLiteral (IC_RIGHT (uic)) ||
2674 getSize (operandType (IC_RESULT (uic))) > 1))
2677 /* make sure that the result of this icode is not on the
2678 stack, since acc is used to compute stack offset */
2679 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
2680 OP_SYMBOL (IC_RESULT (uic))->onStack)
2683 /* if either one of them in far space then we cannot */
2684 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
2685 isOperandInFarSpace (IC_LEFT (uic))) ||
2686 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
2687 isOperandInFarSpace (IC_RIGHT (uic))))
2690 /* if the usage has only one operand then we can */
2691 if (IC_LEFT (uic) == NULL ||
2692 IC_RIGHT (uic) == NULL)
2695 /* make sure this is on the left side if not
2696 a '+' since '+' is commutative */
2697 if (ic->op != '+' &&
2698 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
2701 /* if one of them is a literal then we can */
2702 if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
2703 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
2705 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2709 /* if the other one is not on stack then we can */
2710 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
2711 (IS_ITEMP (IC_RIGHT (uic)) ||
2712 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
2713 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
2716 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
2717 (IS_ITEMP (IC_LEFT (uic)) ||
2718 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
2719 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
2725 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2730 /*-----------------------------------------------------------------*/
2731 /* packForPush - hueristics to reduce iCode for pushing */
2732 /*-----------------------------------------------------------------*/
2734 packForReceive (iCode * ic, eBBlock * ebp)
2738 debugLog ("%s\n", __FUNCTION__);
2739 debugAopGet (" result:", IC_RESULT (ic));
2740 debugAopGet (" left:", IC_LEFT (ic));
2741 debugAopGet (" right:", IC_RIGHT (ic));
2746 for (dic = ic->next; dic; dic = dic->next)
2751 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
2752 debugLog (" used on left\n");
2753 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
2754 debugLog (" used on right\n");
2755 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
2756 debugLog (" used on result\n");
2758 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
2759 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
2764 debugLog (" hey we can remove this unnecessary assign\n");
2766 /*-----------------------------------------------------------------*/
2767 /* packForPush - hueristics to reduce iCode for pushing */
2768 /*-----------------------------------------------------------------*/
2770 packForPush (iCode * ic, eBBlock * ebp)
2774 debugLog ("%s\n", __FUNCTION__);
2775 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
2778 /* must have only definition & one usage */
2779 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
2780 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
2783 /* find the definition */
2784 if (!(dic = hTabItemWithKey (iCodehTab,
2785 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
2788 if (dic->op != '=' || POINTER_SET (dic))
2791 /* we now we know that it has one & only one def & use
2792 and the that the definition is an assignment */
2793 IC_LEFT (ic) = IC_RIGHT (dic);
2795 remiCodeFromeBBlock (ebp, dic);
2796 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2797 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2800 /*-----------------------------------------------------------------*/
2801 /* packRegisters - does some transformations to reduce register */
2803 /*-----------------------------------------------------------------*/
2805 packRegisters (eBBlock * ebp)
2810 debugLog ("%s\n", __FUNCTION__);
2817 /* look for assignments of the form */
2818 /* iTempNN = TRueSym (someoperation) SomeOperand */
2820 /* TrueSym := iTempNN:1 */
2821 for (ic = ebp->sch; ic; ic = ic->next)
2824 /* find assignment of the form TrueSym := iTempNN:1 */
2825 if (ic->op == '=' && !POINTER_SET (ic))
2826 change += packRegsForAssign (ic, ebp);
2830 if (POINTER_SET (ic))
2831 debugLog ("pointer is set\n");
2832 debugAopGet (" result:", IC_RESULT (ic));
2833 debugAopGet (" left:", IC_LEFT (ic));
2834 debugAopGet (" right:", IC_RIGHT (ic));
2843 for (ic = ebp->sch; ic; ic = ic->next)
2846 /* if this is an itemp & result of a address of a true sym
2847 then mark this as rematerialisable */
2848 if (ic->op == ADDRESS_OF &&
2849 IS_ITEMP (IC_RESULT (ic)) &&
2850 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
2851 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2852 !OP_SYMBOL (IC_LEFT (ic))->onStack)
2855 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
2857 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2858 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2859 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2863 /* if straight assignment then carry remat flag if
2864 this is the only definition */
2865 if (ic->op == '=' &&
2866 !POINTER_SET (ic) &&
2867 IS_SYMOP (IC_RIGHT (ic)) &&
2868 OP_SYMBOL (IC_RIGHT (ic))->remat &&
2869 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
2871 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
2873 OP_SYMBOL (IC_RESULT (ic))->remat =
2874 OP_SYMBOL (IC_RIGHT (ic))->remat;
2875 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
2876 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
2879 /* if this is a +/- operation with a rematerizable
2880 then mark this as rematerializable as well */
2881 if ((ic->op == '+' || ic->op == '-') &&
2882 (IS_SYMOP (IC_LEFT (ic)) &&
2883 IS_ITEMP (IC_RESULT (ic)) &&
2884 OP_SYMBOL (IC_LEFT (ic))->remat &&
2885 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2886 IS_OP_LITERAL (IC_RIGHT (ic))))
2888 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
2890 operandLitValue (IC_RIGHT (ic));
2891 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2892 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2893 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2896 /* mark the pointer usages */
2897 if (POINTER_SET (ic))
2899 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
2900 debugLog (" marking as a pointer (set) =>");
2901 debugAopGet (" result:", IC_RESULT (ic));
2903 if (POINTER_GET (ic))
2905 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
2906 debugLog (" marking as a pointer (get) =>");
2907 debugAopGet (" left:", IC_LEFT (ic));
2912 /* if we are using a symbol on the stack
2913 then we should say pic14_ptrRegReq */
2914 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
2915 pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
2916 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
2917 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
2918 pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
2919 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
2922 if (IS_SYMOP (IC_LEFT (ic)))
2923 pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
2924 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
2925 if (IS_SYMOP (IC_RIGHT (ic)))
2926 pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
2927 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
2928 if (IS_SYMOP (IC_RESULT (ic)))
2929 pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
2930 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
2934 /* if the condition of an if instruction
2935 is defined in the previous instruction then
2936 mark the itemp as a conditional */
2937 if ((IS_CONDITIONAL (ic) ||
2938 ((ic->op == BITWISEAND ||
2941 isBitwiseOptimizable (ic))) &&
2942 ic->next && ic->next->op == IFX &&
2943 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
2944 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2947 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
2951 /* reduce for support function calls */
2952 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
2953 packRegsForSupport (ic, ebp);
2955 /* if a parameter is passed, it's in W, so we may not
2956 need to place a copy in a register */
2957 if (ic->op == RECEIVE)
2958 packForReceive (ic, ebp);
2960 /* some cases the redundant moves can
2961 can be eliminated for return statements */
2962 if ((ic->op == RETURN || ic->op == SEND) &&
2963 !isOperandInFarSpace (IC_LEFT (ic)) &&
2965 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2967 /* if pointer set & left has a size more than
2968 one and right is not in far space */
2969 if (POINTER_SET (ic) &&
2970 !isOperandInFarSpace (IC_RIGHT (ic)) &&
2971 !OP_SYMBOL (IC_RESULT (ic))->remat &&
2972 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
2973 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
2975 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
2977 /* if pointer get */
2978 if (POINTER_GET (ic) &&
2979 !isOperandInFarSpace (IC_RESULT (ic)) &&
2980 !OP_SYMBOL (IC_LEFT (ic))->remat &&
2981 !IS_OP_RUONLY (IC_RESULT (ic)) &&
2982 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
2984 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2987 /* if this is cast for intergral promotion then
2988 check if only use of the definition of the
2989 operand being casted/ if yes then replace
2990 the result of that arithmetic operation with
2991 this result and get rid of the cast */
2994 sym_link *fromType = operandType (IC_RIGHT (ic));
2995 sym_link *toType = operandType (IC_LEFT (ic));
2997 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
2998 getSize (fromType) != getSize (toType))
3001 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3004 if (IS_ARITHMETIC_OP (dic))
3006 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3007 IC_RESULT (dic) = IC_RESULT (ic);
3008 remiCodeFromeBBlock (ebp, ic);
3009 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3010 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3011 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3015 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3021 /* if the type from and type to are the same
3022 then if this is the only use then packit */
3023 if (compareType (operandType (IC_RIGHT (ic)),
3024 operandType (IC_LEFT (ic))) == 1)
3026 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3029 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3030 IC_RESULT (dic) = IC_RESULT (ic);
3031 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3032 remiCodeFromeBBlock (ebp, ic);
3033 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3034 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3042 iTempNN := (some variable in farspace) V1
3047 if (ic->op == IPUSH)
3049 packForPush (ic, ebp);
3053 /* pack registers for accumulator use, when the
3054 result of an arithmetic or bit wise operation
3055 has only one use, that use is immediately following
3056 the defintion and the using iCode has only one
3057 operand or has two operands but one is literal &
3058 the result of that operation is not on stack then
3059 we can leave the result of this operation in acc:b
3061 if ((IS_ARITHMETIC_OP (ic)
3063 || IS_BITWISE_OP (ic)
3065 || ic->op == LEFT_OP || ic->op == RIGHT_OP
3068 IS_ITEMP (IC_RESULT (ic)) &&
3069 getSize (operandType (IC_RESULT (ic))) <= 2)
3071 packRegsForAccUse (ic);
3077 dumpEbbsToDebug (eBBlock ** ebbs, int count)
3081 if (!debug || !debugF)
3084 for (i = 0; i < count; i++)
3086 fprintf (debugF, "\n----------------------------------------------------------------\n");
3087 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
3088 ebbs[i]->entryLabel->name,
3091 ebbs[i]->isLastInLoop);
3092 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
3097 fprintf (debugF, "visited %d : hasFcall = %d\n",
3101 fprintf (debugF, "\ndefines bitVector :");
3102 bitVectDebugOn (ebbs[i]->defSet, debugF);
3103 fprintf (debugF, "\nlocal defines bitVector :");
3104 bitVectDebugOn (ebbs[i]->ldefs, debugF);
3105 fprintf (debugF, "\npointers Set bitvector :");
3106 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
3107 fprintf (debugF, "\nin pointers Set bitvector :");
3108 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
3109 fprintf (debugF, "\ninDefs Set bitvector :");
3110 bitVectDebugOn (ebbs[i]->inDefs, debugF);
3111 fprintf (debugF, "\noutDefs Set bitvector :");
3112 bitVectDebugOn (ebbs[i]->outDefs, debugF);
3113 fprintf (debugF, "\nusesDefs Set bitvector :");
3114 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
3115 fprintf (debugF, "\n----------------------------------------------------------------\n");
3116 printiCChain (ebbs[i]->sch, debugF);
3119 /*-----------------------------------------------------------------*/
3120 /* assignRegisters - assigns registers to each live range as need */
3121 /*-----------------------------------------------------------------*/
3123 pic14_assignRegisters (eBBlock ** ebbs, int count)
3128 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
3129 debugLog ("ebbs before optimizing:\n");
3130 dumpEbbsToDebug (ebbs, count);
3132 setToNull ((void *) &_G.funcrUsed);
3133 pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3136 /* change assignments this will remove some
3137 live ranges reducing some register pressure */
3138 for (i = 0; i < count; i++)
3139 packRegisters (ebbs[i]);
3141 if (options.dump_pack)
3142 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3144 /* first determine for each live range the number of
3145 registers & the type of registers required for each */
3148 /* and serially allocate registers */
3149 serialRegAssign (ebbs, count);
3151 /* if stack was extended then tell the user */
3154 /* werror(W_TOOMANY_SPILS,"stack", */
3155 /* _G.stackExtend,currFunc->name,""); */
3161 /* werror(W_TOOMANY_SPILS,"data space", */
3162 /* _G.dataExtend,currFunc->name,""); */
3166 /* after that create the register mask
3167 for each of the instruction */
3168 createRegMask (ebbs, count);
3170 /* redo that offsets for stacked automatic variables */
3171 redoStackOffsets ();
3173 if (options.dump_rassgn)
3174 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3176 /* now get back the chain */
3177 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3179 debugLog ("ebbs after optimizing:\n");
3180 dumpEbbsToDebug (ebbs, count);
3185 /* free up any _G.stackSpil locations allocated */
3186 applyToSet (_G.stackSpil, deallocStackSpil);
3188 setToNull ((void **) &_G.stackSpil);
3189 setToNull ((void **) &_G.spiltSet);
3190 /* mark all registers as free */
3191 pic14_freeAllRegs ();
3193 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");