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);
622 /*-----------------------------------------------------------------*/
623 /* computeSpillable - given a point find the spillable live ranges */
624 /*-----------------------------------------------------------------*/
626 computeSpillable (iCode * ic)
630 debugLog ("%s\n", __FUNCTION__);
631 /* spillable live ranges are those that are live at this
632 point . the following categories need to be subtracted
634 a) - those that are already spilt
635 b) - if being used by this one
636 c) - defined by this one */
638 spillable = bitVectCopy (ic->rlive);
640 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
642 bitVectCplAnd (spillable, ic->uses); /* used in this one */
643 bitVectUnSetBit (spillable, ic->defKey);
644 spillable = bitVectIntersect (spillable, _G.regAssigned);
649 /*-----------------------------------------------------------------*/
650 /* noSpilLoc - return true if a variable has no spil location */
651 /*-----------------------------------------------------------------*/
653 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
655 debugLog ("%s\n", __FUNCTION__);
656 return (sym->usl.spillLoc ? 0 : 1);
659 /*-----------------------------------------------------------------*/
660 /* hasSpilLoc - will return 1 if the symbol has spil location */
661 /*-----------------------------------------------------------------*/
663 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
665 debugLog ("%s\n", __FUNCTION__);
666 return (sym->usl.spillLoc ? 1 : 0);
669 /*-----------------------------------------------------------------*/
670 /* directSpilLoc - will return 1 if the splilocation is in direct */
671 /*-----------------------------------------------------------------*/
673 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
675 debugLog ("%s\n", __FUNCTION__);
676 if (sym->usl.spillLoc &&
677 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
683 /*-----------------------------------------------------------------*/
684 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
685 /* but is not used as a pointer */
686 /*-----------------------------------------------------------------*/
688 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
690 debugLog ("%s\n", __FUNCTION__);
691 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
694 /*-----------------------------------------------------------------*/
695 /* rematable - will return 1 if the remat flag is set */
696 /*-----------------------------------------------------------------*/
698 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
700 debugLog ("%s\n", __FUNCTION__);
704 /*-----------------------------------------------------------------*/
705 /* notUsedInRemaining - not used or defined in remain of the block */
706 /*-----------------------------------------------------------------*/
708 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
710 debugLog ("%s\n", __FUNCTION__);
711 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
712 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
715 /*-----------------------------------------------------------------*/
716 /* allLRs - return true for all */
717 /*-----------------------------------------------------------------*/
719 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
721 debugLog ("%s\n", __FUNCTION__);
725 /*-----------------------------------------------------------------*/
726 /* liveRangesWith - applies function to a given set of live range */
727 /*-----------------------------------------------------------------*/
729 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
730 eBBlock * ebp, iCode * ic)
735 debugLog ("%s\n", __FUNCTION__);
736 if (!lrs || !lrs->size)
739 for (i = 1; i < lrs->size; i++)
742 if (!bitVectBitValue (lrs, i))
745 /* if we don't find it in the live range
746 hash table we are in serious trouble */
747 if (!(sym = hTabItemWithKey (liveRanges, i)))
749 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
750 "liveRangesWith could not find liveRange");
754 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
755 addSetHead (&rset, sym);
762 /*-----------------------------------------------------------------*/
763 /* leastUsedLR - given a set determines which is the least used */
764 /*-----------------------------------------------------------------*/
766 leastUsedLR (set * sset)
768 symbol *sym = NULL, *lsym = NULL;
770 debugLog ("%s\n", __FUNCTION__);
771 sym = lsym = setFirstItem (sset);
776 for (; lsym; lsym = setNextItem (sset))
779 /* if usage is the same then prefer
780 the spill the smaller of the two */
781 if (lsym->used == sym->used)
782 if (getSize (lsym->type) < getSize (sym->type))
786 if (lsym->used < sym->used)
791 setToNull ((void **) &sset);
796 /*-----------------------------------------------------------------*/
797 /* noOverLap - will iterate through the list looking for over lap */
798 /*-----------------------------------------------------------------*/
800 noOverLap (set * itmpStack, symbol * fsym)
803 debugLog ("%s\n", __FUNCTION__);
806 for (sym = setFirstItem (itmpStack); sym;
807 sym = setNextItem (itmpStack))
809 if (sym->liveTo > fsym->liveFrom)
817 /*-----------------------------------------------------------------*/
818 /* isFree - will return 1 if the a free spil location is found */
819 /*-----------------------------------------------------------------*/
824 V_ARG (symbol **, sloc);
825 V_ARG (symbol *, fsym);
827 debugLog ("%s\n", __FUNCTION__);
828 /* if already found */
832 /* if it is free && and the itmp assigned to
833 this does not have any overlapping live ranges
834 with the one currently being assigned and
835 the size can be accomodated */
837 noOverLap (sym->usl.itmpStack, fsym) &&
838 getSize (sym->type) >= getSize (fsym->type))
847 /*-----------------------------------------------------------------*/
848 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
849 /*-----------------------------------------------------------------*/
851 spillLRWithPtrReg (symbol * forSym)
857 debugLog ("%s\n", __FUNCTION__);
858 if (!_G.regAssigned ||
859 bitVectIsZero (_G.regAssigned))
862 r0 = pic14_regWithIdx (R0_IDX);
863 r1 = pic14_regWithIdx (R1_IDX);
865 /* for all live ranges */
866 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
867 lrsym = hTabNextItem (liveRanges, &k))
871 /* if no registers assigned to it or
873 /* if it does not overlap with this then
874 not need to spill it */
876 if (lrsym->isspilt || !lrsym->nRegs ||
877 (lrsym->liveTo < forSym->liveFrom))
880 /* go thru the registers : if it is either
881 r0 or r1 then spil it */
882 for (j = 0; j < lrsym->nRegs; j++)
883 if (lrsym->regs[j] == r0 ||
884 lrsym->regs[j] == r1)
893 /*-----------------------------------------------------------------*/
894 /* createStackSpil - create a location on the stack to spil */
895 /*-----------------------------------------------------------------*/
897 createStackSpil (symbol * sym)
900 int useXstack, model, noOverlay;
903 debugLog ("%s\n", __FUNCTION__);
905 /* first go try and find a free one that is already
906 existing on the stack */
907 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
909 /* found a free one : just update & return */
910 sym->usl.spillLoc = sloc;
913 addSetHead (&sloc->usl.itmpStack, sym);
917 /* could not then have to create one , this is the hard part
918 we need to allocate this on the stack : this is really a
919 hack!! but cannot think of anything better at this time */
921 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
923 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
928 sloc = newiTemp (slocBuffer);
930 /* set the type to the spilling symbol */
931 sloc->type = copyLinkChain (sym->type);
932 sloc->etype = getSpec (sloc->type);
933 SPEC_SCLS (sloc->etype) = S_DATA;
934 SPEC_EXTR (sloc->etype) = 0;
935 SPEC_STAT (sloc->etype) = 0;
937 /* we don't allow it to be allocated`
938 onto the external stack since : so we
939 temporarily turn it off ; we also
940 turn off memory model to prevent
941 the spil from going to the external storage
942 and turn off overlaying
945 useXstack = options.useXstack;
946 model = options.model;
947 noOverlay = options.noOverlay;
948 options.noOverlay = 1;
949 options.model = options.useXstack = 0;
953 options.useXstack = useXstack;
954 options.model = model;
955 options.noOverlay = noOverlay;
956 sloc->isref = 1; /* to prevent compiler warning */
958 /* if it is on the stack then update the stack */
959 if (IN_STACK (sloc->etype))
961 currFunc->stack += getSize (sloc->type);
962 _G.stackExtend += getSize (sloc->type);
965 _G.dataExtend += getSize (sloc->type);
967 /* add it to the _G.stackSpil set */
968 addSetHead (&_G.stackSpil, sloc);
969 sym->usl.spillLoc = sloc;
972 /* add it to the set of itempStack set
973 of the spill location */
974 addSetHead (&sloc->usl.itmpStack, sym);
978 /*-----------------------------------------------------------------*/
979 /* isSpiltOnStack - returns true if the spil location is on stack */
980 /*-----------------------------------------------------------------*/
982 isSpiltOnStack (symbol * sym)
986 debugLog ("%s\n", __FUNCTION__);
993 /* if (sym->_G.stackSpil) */
996 if (!sym->usl.spillLoc)
999 etype = getSpec (sym->usl.spillLoc->type);
1000 if (IN_STACK (etype))
1006 /*-----------------------------------------------------------------*/
1007 /* spillThis - spils a specific operand */
1008 /*-----------------------------------------------------------------*/
1010 spillThis (symbol * sym)
1013 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1015 /* if this is rematerializable or has a spillLocation
1016 we are okay, else we need to create a spillLocation
1018 if (!(sym->remat || sym->usl.spillLoc))
1019 createStackSpil (sym);
1022 /* mark it has spilt & put it in the spilt set */
1024 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1026 bitVectUnSetBit (_G.regAssigned, sym->key);
1028 for (i = 0; i < sym->nRegs; i++)
1032 freeReg (sym->regs[i]);
1033 sym->regs[i] = NULL;
1036 /* if spilt on stack then free up r0 & r1
1037 if they could have been assigned to some
1039 if (!pic14_ptrRegReq && isSpiltOnStack (sym))
1042 spillLRWithPtrReg (sym);
1045 if (sym->usl.spillLoc && !sym->remat)
1046 sym->usl.spillLoc->allocreq = 1;
1050 /*-----------------------------------------------------------------*/
1051 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1052 /*-----------------------------------------------------------------*/
1054 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1056 bitVect *lrcs = NULL;
1060 debugLog ("%s\n", __FUNCTION__);
1061 /* get the spillable live ranges */
1062 lrcs = computeSpillable (ic);
1064 /* get all live ranges that are rematerizable */
1065 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1068 /* return the least used of these */
1069 return leastUsedLR (selectS);
1072 /* get live ranges with spillLocations in direct space */
1073 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1075 sym = leastUsedLR (selectS);
1076 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1077 sym->usl.spillLoc->rname :
1078 sym->usl.spillLoc->name));
1080 /* mark it as allocation required */
1081 sym->usl.spillLoc->allocreq = 1;
1085 /* if the symbol is local to the block then */
1086 if (forSym->liveTo < ebp->lSeq)
1089 /* check if there are any live ranges allocated
1090 to registers that are not used in this block */
1091 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1093 sym = leastUsedLR (selectS);
1094 /* if this is not rematerializable */
1103 /* check if there are any live ranges that not
1104 used in the remainder of the block */
1105 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1107 sym = leastUsedLR (selectS);
1110 sym->remainSpil = 1;
1117 /* find live ranges with spillocation && not used as pointers */
1118 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1121 sym = leastUsedLR (selectS);
1122 /* mark this as allocation required */
1123 sym->usl.spillLoc->allocreq = 1;
1127 /* find live ranges with spillocation */
1128 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1131 sym = leastUsedLR (selectS);
1132 sym->usl.spillLoc->allocreq = 1;
1136 /* couldn't find then we need to create a spil
1137 location on the stack , for which one? the least
1139 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1142 /* return a created spil location */
1143 sym = createStackSpil (leastUsedLR (selectS));
1144 sym->usl.spillLoc->allocreq = 1;
1148 /* this is an extreme situation we will spill
1149 this one : happens very rarely but it does happen */
1155 /*-----------------------------------------------------------------*/
1156 /* spilSomething - spil some variable & mark registers as free */
1157 /*-----------------------------------------------------------------*/
1159 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1164 debugLog ("%s\n", __FUNCTION__);
1165 /* get something we can spil */
1166 ssym = selectSpil (ic, ebp, forSym);
1168 /* mark it as spilt */
1170 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1172 /* mark it as not register assigned &
1173 take it away from the set */
1174 bitVectUnSetBit (_G.regAssigned, ssym->key);
1176 /* mark the registers as free */
1177 for (i = 0; i < ssym->nRegs; i++)
1179 freeReg (ssym->regs[i]);
1181 /* if spilt on stack then free up r0 & r1
1182 if they could have been assigned to as gprs */
1183 if (!pic14_ptrRegReq && isSpiltOnStack (ssym))
1186 spillLRWithPtrReg (ssym);
1189 /* if this was a block level spil then insert push & pop
1190 at the start & end of block respectively */
1191 if (ssym->blockSpil)
1193 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1194 /* add push to the start of the block */
1195 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1196 ebp->sch->next : ebp->sch));
1197 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1198 /* add pop to the end of the block */
1199 addiCodeToeBBlock (ebp, nic, NULL);
1202 /* if spilt because not used in the remainder of the
1203 block then add a push before this instruction and
1204 a pop at the end of the block */
1205 if (ssym->remainSpil)
1208 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1209 /* add push just before this instruction */
1210 addiCodeToeBBlock (ebp, nic, ic);
1212 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1213 /* add pop to the end of the block */
1214 addiCodeToeBBlock (ebp, nic, NULL);
1223 /*-----------------------------------------------------------------*/
1224 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1225 /*-----------------------------------------------------------------*/
1227 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1231 debugLog ("%s\n", __FUNCTION__);
1233 /* try for a ptr type */
1234 if ((reg = allocReg (REG_PTR)))
1237 /* try for gpr type */
1238 if ((reg = allocReg (REG_GPR)))
1241 /* we have to spil */
1242 if (!spilSomething (ic, ebp, sym))
1245 /* this looks like an infinite loop but
1246 in really selectSpil will abort */
1250 /*-----------------------------------------------------------------*/
1251 /* getRegGpr - will try for GPR if not spil */
1252 /*-----------------------------------------------------------------*/
1254 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1258 debugLog ("%s\n", __FUNCTION__);
1260 /* try for gpr type */
1261 if ((reg = allocReg (REG_GPR)))
1264 if (!pic14_ptrRegReq)
1265 if ((reg = allocReg (REG_PTR)))
1268 /* we have to spil */
1269 if (!spilSomething (ic, ebp, sym))
1272 /* this looks like an infinite loop but
1273 in really selectSpil will abort */
1277 /*-----------------------------------------------------------------*/
1278 /* symHasReg - symbol has a given register */
1279 /*-----------------------------------------------------------------*/
1281 symHasReg (symbol * sym, regs * reg)
1285 debugLog ("%s\n", __FUNCTION__);
1286 for (i = 0; i < sym->nRegs; i++)
1287 if (sym->regs[i] == reg)
1293 /*-----------------------------------------------------------------*/
1294 /* deassignLRs - check the live to and if they have registers & are */
1295 /* not spilt then free up the registers */
1296 /*-----------------------------------------------------------------*/
1298 deassignLRs (iCode * ic, eBBlock * ebp)
1304 debugLog ("%s\n", __FUNCTION__);
1305 for (sym = hTabFirstItem (liveRanges, &k); sym;
1306 sym = hTabNextItem (liveRanges, &k))
1309 symbol *psym = NULL;
1310 /* if it does not end here */
1311 if (sym->liveTo > ic->seq)
1314 /* if it was spilt on stack then we can
1315 mark the stack spil location as free */
1320 sym->usl.spillLoc->isFree = 1;
1326 if (!bitVectBitValue (_G.regAssigned, sym->key))
1329 /* special case check if this is an IFX &
1330 the privious one was a pop and the
1331 previous one was not spilt then keep track
1333 if (ic->op == IFX && ic->prev &&
1334 ic->prev->op == IPOP &&
1335 !ic->prev->parmPush &&
1336 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1337 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1343 bitVectUnSetBit (_G.regAssigned, sym->key);
1345 /* if the result of this one needs registers
1346 and does not have it then assign it right
1348 if (IC_RESULT (ic) &&
1349 !(SKIP_IC2 (ic) || /* not a special icode */
1350 ic->op == JUMPTABLE ||
1355 POINTER_SET (ic)) &&
1356 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1357 result->liveTo > ic->seq && /* and will live beyond this */
1358 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1359 result->regType == sym->regType && /* same register types */
1360 result->nRegs && /* which needs registers */
1361 !result->isspilt && /* and does not already have them */
1363 !bitVectBitValue (_G.regAssigned, result->key) &&
1364 /* the number of free regs + number of regs in this LR
1365 can accomodate the what result Needs */
1366 ((nfreeRegsType (result->regType) +
1367 sym->nRegs) >= result->nRegs)
1371 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1373 result->regs[i] = sym->regs[i];
1375 result->regs[i] = getRegGpr (ic, ebp, result);
1377 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1381 /* free the remaining */
1382 for (; i < sym->nRegs; i++)
1386 if (!symHasReg (psym, sym->regs[i]))
1387 freeReg (sym->regs[i]);
1390 freeReg (sym->regs[i]);
1397 /*-----------------------------------------------------------------*/
1398 /* reassignLR - reassign this to registers */
1399 /*-----------------------------------------------------------------*/
1401 reassignLR (operand * op)
1403 symbol *sym = OP_SYMBOL (op);
1406 debugLog ("%s\n", __FUNCTION__);
1407 /* not spilt any more */
1408 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1409 bitVectUnSetBit (_G.spiltSet, sym->key);
1411 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1415 for (i = 0; i < sym->nRegs; i++)
1416 sym->regs[i]->isFree = 0;
1419 /*-----------------------------------------------------------------*/
1420 /* willCauseSpill - determines if allocating will cause a spill */
1421 /*-----------------------------------------------------------------*/
1423 willCauseSpill (int nr, int rt)
1425 debugLog ("%s\n", __FUNCTION__);
1426 /* first check if there are any avlb registers
1427 of te type required */
1430 /* special case for pointer type
1431 if pointer type not avlb then
1432 check for type gpr */
1433 if (nFreeRegs (rt) >= nr)
1435 if (nFreeRegs (REG_GPR) >= nr)
1440 if (pic14_ptrRegReq)
1442 if (nFreeRegs (rt) >= nr)
1447 if (nFreeRegs (REG_PTR) +
1448 nFreeRegs (REG_GPR) >= nr)
1453 debugLog (" ... yep it will (cause a spill)\n");
1454 /* it will cause a spil */
1458 /*-----------------------------------------------------------------*/
1459 /* positionRegs - the allocator can allocate same registers to res- */
1460 /* ult and operand, if this happens make sure they are in the same */
1461 /* position as the operand otherwise chaos results */
1462 /*-----------------------------------------------------------------*/
1464 positionRegs (symbol * result, symbol * opsym, int lineno)
1466 int count = min (result->nRegs, opsym->nRegs);
1467 int i, j = 0, shared = 0;
1469 debugLog ("%s\n", __FUNCTION__);
1470 /* if the result has been spilt then cannot share */
1475 /* first make sure that they actually share */
1476 for (i = 0; i < count; i++)
1478 for (j = 0; j < count; j++)
1480 if (result->regs[i] == opsym->regs[j] && i != j)
1490 regs *tmp = result->regs[i];
1491 result->regs[i] = result->regs[j];
1492 result->regs[j] = tmp;
1497 /*-----------------------------------------------------------------*/
1498 /* serialRegAssign - serially allocate registers to the variables */
1499 /*-----------------------------------------------------------------*/
1501 serialRegAssign (eBBlock ** ebbs, int count)
1505 debugLog ("%s\n", __FUNCTION__);
1506 /* for all blocks */
1507 for (i = 0; i < count; i++)
1512 if (ebbs[i]->noPath &&
1513 (ebbs[i]->entryLabel != entryLabel &&
1514 ebbs[i]->entryLabel != returnLabel))
1517 /* of all instructions do */
1518 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1521 debugLog (" op: %s\n", decodeOp (ic->op));
1523 /* if this is an ipop that means some live
1524 range will have to be assigned again */
1526 reassignLR (IC_LEFT (ic));
1528 /* if result is present && is a true symbol */
1529 if (IC_RESULT (ic) && ic->op != IFX &&
1530 IS_TRUE_SYMOP (IC_RESULT (ic)))
1531 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
1533 /* take away registers from live
1534 ranges that end at this instruction */
1535 deassignLRs (ic, ebbs[i]);
1537 /* some don't need registers */
1538 if (SKIP_IC2 (ic) ||
1539 ic->op == JUMPTABLE ||
1543 (IC_RESULT (ic) && POINTER_SET (ic)))
1546 /* now we need to allocate registers
1547 only for the result */
1550 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
1556 /* if it does not need or is spilt
1557 or is already assigned to registers
1558 or will not live beyond this instructions */
1561 bitVectBitValue (_G.regAssigned, sym->key) ||
1562 sym->liveTo <= ic->seq)
1565 /* if some liverange has been spilt at the block level
1566 and this one live beyond this block then spil this
1568 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
1573 /* if trying to allocate this will cause
1574 a spill and there is nothing to spill
1575 or this one is rematerializable then
1577 willCS = willCauseSpill (sym->nRegs, sym->regType);
1578 spillable = computeSpillable (ic);
1580 (willCS && bitVectIsZero (spillable)))
1588 /* if it has a spillocation & is used less than
1589 all other live ranges then spill this */
1591 if (sym->usl.spillLoc) {
1592 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
1593 allLRs, ebbs[i], ic));
1594 if (leastUsed && leastUsed->used > sym->used) {
1599 /* if none of the liveRanges have a spillLocation then better
1600 to spill this one than anything else already assigned to registers */
1601 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
1602 /* if this is local to this block then we might find a block spil */
1603 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
1611 if (ic->op == RECEIVE)
1612 debugLog ("When I get clever, I'll optimize the receive logic\n");
1614 /* if we need ptr regs for the right side
1616 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
1617 <= (unsigned) PTRSIZE)
1622 /* else we assign registers to it */
1623 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1625 debugLog (" %d - \n", __LINE__);
1627 bitVectDebugOn(_G.regAssigned, debugF);
1629 for (j = 0; j < sym->nRegs; j++)
1631 if (sym->regType == REG_PTR)
1632 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
1634 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
1636 /* if the allocation falied which means
1637 this was spilt then break */
1641 debugLog (" %d - \n", __LINE__);
1643 /* if it shares registers with operands make sure
1644 that they are in the same position */
1645 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
1646 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
1647 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1648 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
1649 /* do the same for the right operand */
1650 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
1651 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
1652 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1653 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
1655 debugLog (" %d - \n", __LINE__);
1658 debugLog (" %d - \n", __LINE__);
1668 /*-----------------------------------------------------------------*/
1669 /* rUmaskForOp :- returns register mask for an operand */
1670 /*-----------------------------------------------------------------*/
1672 rUmaskForOp (operand * op)
1678 debugLog ("%s\n", __FUNCTION__);
1679 /* only temporaries are assigned registers */
1683 sym = OP_SYMBOL (op);
1685 /* if spilt or no registers assigned to it
1687 if (sym->isspilt || !sym->nRegs)
1690 rumask = newBitVect (pic14_nRegs);
1692 for (j = 0; j < sym->nRegs; j++)
1694 rumask = bitVectSetBit (rumask,
1695 sym->regs[j]->rIdx);
1701 /*-----------------------------------------------------------------*/
1702 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
1703 /*-----------------------------------------------------------------*/
1705 regsUsedIniCode (iCode * ic)
1707 bitVect *rmask = newBitVect (pic14_nRegs);
1709 debugLog ("%s\n", __FUNCTION__);
1710 /* do the special cases first */
1713 rmask = bitVectUnion (rmask,
1714 rUmaskForOp (IC_COND (ic)));
1718 /* for the jumptable */
1719 if (ic->op == JUMPTABLE)
1721 rmask = bitVectUnion (rmask,
1722 rUmaskForOp (IC_JTCOND (ic)));
1727 /* of all other cases */
1729 rmask = bitVectUnion (rmask,
1730 rUmaskForOp (IC_LEFT (ic)));
1734 rmask = bitVectUnion (rmask,
1735 rUmaskForOp (IC_RIGHT (ic)));
1738 rmask = bitVectUnion (rmask,
1739 rUmaskForOp (IC_RESULT (ic)));
1745 /*-----------------------------------------------------------------*/
1746 /* createRegMask - for each instruction will determine the regsUsed */
1747 /*-----------------------------------------------------------------*/
1749 createRegMask (eBBlock ** ebbs, int count)
1753 debugLog ("%s\n", __FUNCTION__);
1754 /* for all blocks */
1755 for (i = 0; i < count; i++)
1759 if (ebbs[i]->noPath &&
1760 (ebbs[i]->entryLabel != entryLabel &&
1761 ebbs[i]->entryLabel != returnLabel))
1764 /* for all instructions */
1765 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1770 if (SKIP_IC2 (ic) || !ic->rlive)
1773 /* first mark the registers used in this
1775 ic->rUsed = regsUsedIniCode (ic);
1776 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
1778 /* now create the register mask for those
1779 registers that are in use : this is a
1780 super set of ic->rUsed */
1781 ic->rMask = newBitVect (pic14_nRegs + 1);
1783 /* for all live Ranges alive at this point */
1784 for (j = 1; j < ic->rlive->size; j++)
1789 /* if not alive then continue */
1790 if (!bitVectBitValue (ic->rlive, j))
1793 /* find the live range we are interested in */
1794 if (!(sym = hTabItemWithKey (liveRanges, j)))
1796 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1797 "createRegMask cannot find live range");
1801 /* if no register assigned to it */
1802 if (!sym->nRegs || sym->isspilt)
1805 /* for all the registers allocated to it */
1806 for (k = 0; k < sym->nRegs; k++)
1809 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
1815 /*-----------------------------------------------------------------*/
1816 /* rematStr - returns the rematerialized string for a remat var */
1817 /*-----------------------------------------------------------------*/
1819 rematStr (symbol * sym)
1822 iCode *ic = sym->rematiCode;
1824 debugLog ("%s\n", __FUNCTION__);
1829 /* if plus or minus print the right hand side */
1831 if (ic->op == '+' || ic->op == '-') {
1832 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
1835 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
1839 if (ic->op == '+' || ic->op == '-')
1841 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1842 sprintf (s, "(%s %c 0x%04x)",
1843 OP_SYMBOL (IC_LEFT (ric))->rname,
1845 (int) operandLitValue (IC_RIGHT (ic)));
1848 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
1853 /* we reached the end */
1854 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
1858 printf ("%s\n", buffer);
1862 /*-----------------------------------------------------------------*/
1863 /* regTypeNum - computes the type & number of registers required */
1864 /*-----------------------------------------------------------------*/
1872 debugLog ("%s\n", __FUNCTION__);
1873 /* for each live range do */
1874 for (sym = hTabFirstItem (liveRanges, &k); sym;
1875 sym = hTabNextItem (liveRanges, &k)) {
1877 debugLog (" %d - %s\n", __LINE__, sym->rname);
1879 /* if used zero times then no registers needed */
1880 if ((sym->liveTo - sym->liveFrom) == 0)
1884 /* if the live range is a temporary */
1887 debugLog (" %d - itemp register\n", __LINE__);
1889 /* if the type is marked as a conditional */
1890 if (sym->regType == REG_CND)
1893 /* if used in return only then we don't
1895 if (sym->ruonly || sym->accuse) {
1896 if (IS_AGGREGATE (sym->type) || sym->isptr)
1897 sym->type = aggrToPtr (sym->type, FALSE);
1898 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
1903 /* if the symbol has only one definition &
1904 that definition is a get_pointer and the
1905 pointer we are getting is rematerializable and
1908 if (bitVectnBitsOn (sym->defs) == 1 &&
1909 (ic = hTabItemWithKey (iCodehTab,
1910 bitVectFirstBit (sym->defs))) &&
1913 !IS_BITVAR (sym->etype)) {
1916 debugLog (" %d - \n", __LINE__);
1918 /* if remat in data space */
1919 if (OP_SYMBOL (IC_LEFT (ic))->remat &&
1920 DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) {
1922 /* create a psuedo symbol & force a spil */
1923 symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
1924 psym->type = sym->type;
1925 psym->etype = sym->etype;
1926 strcpy (psym->rname, psym->name);
1928 sym->usl.spillLoc = psym;
1932 /* if in data space or idata space then try to
1933 allocate pointer register */
1937 /* if not then we require registers */
1938 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
1939 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1940 getSize (sym->type));
1942 if (sym->nRegs > 4) {
1943 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
1944 printTypeChain (sym->type, stderr);
1945 fprintf (stderr, "\n");
1948 /* determine the type of register required */
1949 if (sym->nRegs == 1 &&
1950 IS_PTR (sym->type) &&
1952 sym->regType = REG_PTR;
1954 sym->regType = REG_GPR;
1957 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
1961 /* for the first run we don't provide */
1962 /* registers for true symbols we will */
1963 /* see how things go */
1969 /*-----------------------------------------------------------------*/
1970 /* freeAllRegs - mark all registers as free */
1971 /*-----------------------------------------------------------------*/
1973 pic14_freeAllRegs ()
1977 debugLog ("%s\n", __FUNCTION__);
1978 for (i = 0; i < pic14_nRegs; i++)
1979 regspic14[i].isFree = 1;
1982 /*-----------------------------------------------------------------*/
1983 /*-----------------------------------------------------------------*/
1985 pic14_deallocateAllRegs ()
1989 debugLog ("%s\n", __FUNCTION__);
1990 for (i = 0; i < pic14_nRegs; i++) {
1991 if(regspic14[i].pc_type == PO_GPR_TEMP) {
1992 regspic14[i].isFree = 1;
1993 regspic14[i].wasUsed = 0;
1999 /*-----------------------------------------------------------------*/
2000 /* deallocStackSpil - this will set the stack pointer back */
2001 /*-----------------------------------------------------------------*/
2003 DEFSETFUNC (deallocStackSpil)
2007 debugLog ("%s\n", __FUNCTION__);
2012 /*-----------------------------------------------------------------*/
2013 /* farSpacePackable - returns the packable icode for far variables */
2014 /*-----------------------------------------------------------------*/
2016 farSpacePackable (iCode * ic)
2020 debugLog ("%s\n", __FUNCTION__);
2021 /* go thru till we find a definition for the
2022 symbol on the right */
2023 for (dic = ic->prev; dic; dic = dic->prev)
2026 /* if the definition is a call then no */
2027 if ((dic->op == CALL || dic->op == PCALL) &&
2028 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2033 /* if shift by unknown amount then not */
2034 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2035 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2038 /* if pointer get and size > 1 */
2039 if (POINTER_GET (dic) &&
2040 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2043 if (POINTER_SET (dic) &&
2044 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2047 /* if any three is a true symbol in far space */
2048 if (IC_RESULT (dic) &&
2049 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2050 isOperandInFarSpace (IC_RESULT (dic)))
2053 if (IC_RIGHT (dic) &&
2054 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2055 isOperandInFarSpace (IC_RIGHT (dic)) &&
2056 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2059 if (IC_LEFT (dic) &&
2060 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2061 isOperandInFarSpace (IC_LEFT (dic)) &&
2062 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2065 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2067 if ((dic->op == LEFT_OP ||
2068 dic->op == RIGHT_OP ||
2070 IS_OP_LITERAL (IC_RIGHT (dic)))
2080 /*-----------------------------------------------------------------*/
2081 /* packRegsForAssign - register reduction for assignment */
2082 /*-----------------------------------------------------------------*/
2084 packRegsForAssign (iCode * ic, eBBlock * ebp)
2089 debugLog ("%s\n", __FUNCTION__);
2091 debugAopGet (" result:", IC_RESULT (ic));
2092 debugAopGet (" left:", IC_LEFT (ic));
2093 debugAopGet (" right:", IC_RIGHT (ic));
2095 if (!IS_ITEMP (IC_RIGHT (ic)) ||
2096 OP_SYMBOL (IC_RIGHT (ic))->isind ||
2097 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2099 debugLog (" %d - not packing - right side fails \n", __LINE__);
2103 /* if the true symbol is defined in far space or on stack
2104 then we should not since this will increase register pressure */
2105 if (isOperandInFarSpace (IC_RESULT (ic)))
2107 if ((dic = farSpacePackable (ic)))
2113 /* find the definition of iTempNN scanning backwards if we find a
2114 a use of the true symbol before we find the definition then
2116 for (dic = ic->prev; dic; dic = dic->prev)
2119 /* if there is a function call and this is
2120 a parameter & not my parameter then don't pack it */
2121 if ((dic->op == CALL || dic->op == PCALL) &&
2122 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2123 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2125 debugLog (" %d - \n", __LINE__);
2133 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2134 IS_OP_VOLATILE (IC_RESULT (dic)))
2136 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2141 if (IS_SYMOP (IC_RESULT (dic)) &&
2142 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2144 /* A previous result was assigned to the same register - we'll our definition */
2145 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2146 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2147 if (POINTER_SET (dic))
2153 if (IS_SYMOP (IC_RIGHT (dic)) &&
2154 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2155 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2157 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
2162 if (IS_SYMOP (IC_LEFT (dic)) &&
2163 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2164 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2166 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
2171 if (POINTER_SET (dic) &&
2172 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2174 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
2182 return 0; /* did not find */
2184 /* if the result is on stack or iaccess then it must be
2185 the same atleast one of the operands */
2186 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2187 OP_SYMBOL (IC_RESULT (ic))->iaccess)
2190 /* the operation has only one symbol
2191 operator then we can pack */
2192 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2193 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2196 if (!((IC_LEFT (dic) &&
2197 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2199 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2203 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2204 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
2205 /* found the definition */
2206 /* replace the result with the result of */
2207 /* this assignment and remove this assignment */
2208 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2209 IC_RESULT (dic) = IC_RESULT (ic);
2211 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2213 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2215 /* delete from liverange table also
2216 delete from all the points inbetween and the new
2218 for (sic = dic; sic != ic; sic = sic->next)
2220 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2221 if (IS_ITEMP (IC_RESULT (dic)))
2222 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2225 remiCodeFromeBBlock (ebp, ic);
2226 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2227 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2228 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2234 /*-----------------------------------------------------------------*/
2235 /* findAssignToSym : scanning backwards looks for first assig found */
2236 /*-----------------------------------------------------------------*/
2238 findAssignToSym (operand * op, iCode * ic)
2242 debugLog ("%s\n", __FUNCTION__);
2243 for (dic = ic->prev; dic; dic = dic->prev)
2246 /* if definition by assignment */
2247 if (dic->op == '=' &&
2248 !POINTER_SET (dic) &&
2249 IC_RESULT (dic)->key == op->key
2250 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2254 /* we are interested only if defined in far space */
2255 /* or in stack space in case of + & - */
2257 /* if assigned to a non-symbol then return
2259 if (!IS_SYMOP (IC_RIGHT (dic)))
2262 /* if the symbol is in far space then
2264 if (isOperandInFarSpace (IC_RIGHT (dic)))
2267 /* for + & - operations make sure that
2268 if it is on the stack it is the same
2269 as one of the three operands */
2270 if ((ic->op == '+' || ic->op == '-') &&
2271 OP_SYMBOL (IC_RIGHT (dic))->onStack)
2274 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2275 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2276 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2284 /* if we find an usage then we cannot delete it */
2285 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2288 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2291 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2295 /* now make sure that the right side of dic
2296 is not defined between ic & dic */
2299 iCode *sic = dic->next;
2301 for (; sic != ic; sic = sic->next)
2302 if (IC_RESULT (sic) &&
2303 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2312 /*-----------------------------------------------------------------*/
2313 /* packRegsForSupport :- reduce some registers for support calls */
2314 /*-----------------------------------------------------------------*/
2316 packRegsForSupport (iCode * ic, eBBlock * ebp)
2320 debugLog ("%s\n", __FUNCTION__);
2321 /* for the left & right operand :- look to see if the
2322 left was assigned a true symbol in far space in that
2323 case replace them */
2324 if (IS_ITEMP (IC_LEFT (ic)) &&
2325 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2327 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
2333 debugAopGet ("removing left:", IC_LEFT (ic));
2335 /* found it we need to remove it from the
2337 for (sic = dic; sic != ic; sic = sic->next)
2338 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
2340 IC_LEFT (ic)->operand.symOperand =
2341 IC_RIGHT (dic)->operand.symOperand;
2342 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2343 remiCodeFromeBBlock (ebp, dic);
2344 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2345 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2349 /* do the same for the right operand */
2352 IS_ITEMP (IC_RIGHT (ic)) &&
2353 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2355 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2361 /* if this is a subtraction & the result
2362 is a true symbol in far space then don't pack */
2363 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
2365 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
2366 if (IN_FARSPACE (SPEC_OCLS (etype)))
2370 debugAopGet ("removing right:", IC_RIGHT (ic));
2372 /* found it we need to remove it from the
2374 for (sic = dic; sic != ic; sic = sic->next)
2375 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
2377 IC_RIGHT (ic)->operand.symOperand =
2378 IC_RIGHT (dic)->operand.symOperand;
2379 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2381 remiCodeFromeBBlock (ebp, dic);
2382 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2383 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2390 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
2393 /*-----------------------------------------------------------------*/
2394 /* packRegsForOneuse : - will reduce some registers for single Use */
2395 /*-----------------------------------------------------------------*/
2397 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
2402 debugLog ("%s\n", __FUNCTION__);
2403 /* if returning a literal then do nothing */
2407 /* only upto 2 bytes since we cannot predict
2408 the usage of b, & acc */
2409 if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
2414 /* this routine will mark the a symbol as used in one
2415 instruction use only && if the definition is local
2416 (ie. within the basic block) && has only one definition &&
2417 that definition is either a return value from a
2418 function or does not contain any variables in
2420 uses = bitVectCopy (OP_USES (op));
2421 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
2422 if (!bitVectIsZero (uses)) /* has other uses */
2425 /* if it has only one defintion */
2426 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
2427 return NULL; /* has more than one definition */
2429 /* get that definition */
2431 hTabItemWithKey (iCodehTab,
2432 bitVectFirstBit (OP_DEFS (op)))))
2435 /* found the definition now check if it is local */
2436 if (dic->seq < ebp->fSeq ||
2437 dic->seq > ebp->lSeq)
2438 return NULL; /* non-local */
2440 /* now check if it is the return from
2442 if (dic->op == CALL || dic->op == PCALL)
2444 if (ic->op != SEND && ic->op != RETURN &&
2445 !POINTER_SET(ic) && !POINTER_GET(ic))
2447 OP_SYMBOL (op)->ruonly = 1;
2454 /* otherwise check that the definition does
2455 not contain any symbols in far space */
2456 if (isOperandInFarSpace (IC_LEFT (dic)) ||
2457 isOperandInFarSpace (IC_RIGHT (dic)) ||
2458 IS_OP_RUONLY (IC_LEFT (ic)) ||
2459 IS_OP_RUONLY (IC_RIGHT (ic)))
2464 /* if pointer set then make sure the pointer
2466 if (POINTER_SET (dic) &&
2467 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2470 if (POINTER_GET (dic) &&
2471 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2476 /* also make sure the intervenening instructions
2477 don't have any thing in far space */
2478 for (dic = dic->next; dic && dic != ic; dic = dic->next)
2481 /* if there is an intervening function call then no */
2482 if (dic->op == CALL || dic->op == PCALL)
2484 /* if pointer set then make sure the pointer
2486 if (POINTER_SET (dic) &&
2487 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2490 if (POINTER_GET (dic) &&
2491 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2494 /* if address of & the result is remat then okay */
2495 if (dic->op == ADDRESS_OF &&
2496 OP_SYMBOL (IC_RESULT (dic))->remat)
2499 /* if operand has size of three or more & this
2500 operation is a '*','/' or '%' then 'b' may
2502 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
2503 getSize (operandType (op)) >= 3)
2506 /* if left or right or result is in far space */
2507 if (isOperandInFarSpace (IC_LEFT (dic)) ||
2508 isOperandInFarSpace (IC_RIGHT (dic)) ||
2509 isOperandInFarSpace (IC_RESULT (dic)) ||
2510 IS_OP_RUONLY (IC_LEFT (dic)) ||
2511 IS_OP_RUONLY (IC_RIGHT (dic)) ||
2512 IS_OP_RUONLY (IC_RESULT (dic)))
2518 OP_SYMBOL (op)->ruonly = 1;
2523 /*-----------------------------------------------------------------*/
2524 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
2525 /*-----------------------------------------------------------------*/
2527 isBitwiseOptimizable (iCode * ic)
2529 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
2530 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
2532 debugLog ("%s\n", __FUNCTION__);
2533 /* bitwise operations are considered optimizable
2534 under the following conditions (Jean-Louis VERN)
2546 if (IS_LITERAL (rtype) ||
2547 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
2553 /*-----------------------------------------------------------------*/
2554 /* packRegsForAccUse - pack registers for acc use */
2555 /*-----------------------------------------------------------------*/
2557 packRegsForAccUse (iCode * ic)
2561 debugLog ("%s\n", __FUNCTION__);
2563 /* if this is an aggregate, e.g. a one byte char array */
2564 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
2568 /* if + or - then it has to be one byte result */
2569 if ((ic->op == '+' || ic->op == '-')
2570 && getSize (operandType (IC_RESULT (ic))) > 1)
2573 /* if shift operation make sure right side is not a literal */
2574 if (ic->op == RIGHT_OP &&
2575 (isOperandLiteral (IC_RIGHT (ic)) ||
2576 getSize (operandType (IC_RESULT (ic))) > 1))
2579 if (ic->op == LEFT_OP &&
2580 (isOperandLiteral (IC_RIGHT (ic)) ||
2581 getSize (operandType (IC_RESULT (ic))) > 1))
2584 if (IS_BITWISE_OP (ic) &&
2585 getSize (operandType (IC_RESULT (ic))) > 1)
2589 /* has only one definition */
2590 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
2593 /* has only one use */
2594 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
2597 /* and the usage immediately follows this iCode */
2598 if (!(uic = hTabItemWithKey (iCodehTab,
2599 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
2602 if (ic->next != uic)
2605 /* if it is a conditional branch then we definitely can */
2609 if (uic->op == JUMPTABLE)
2612 /* if the usage is not is an assignment
2613 or an arithmetic / bitwise / shift operation then not */
2614 if (POINTER_SET (uic) &&
2615 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
2618 if (uic->op != '=' &&
2619 !IS_ARITHMETIC_OP (uic) &&
2620 !IS_BITWISE_OP (uic) &&
2621 uic->op != LEFT_OP &&
2622 uic->op != RIGHT_OP)
2625 /* if used in ^ operation then make sure right is not a
2627 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
2630 /* if shift operation make sure right side is not a literal */
2631 if (uic->op == RIGHT_OP &&
2632 (isOperandLiteral (IC_RIGHT (uic)) ||
2633 getSize (operandType (IC_RESULT (uic))) > 1))
2636 if (uic->op == LEFT_OP &&
2637 (isOperandLiteral (IC_RIGHT (uic)) ||
2638 getSize (operandType (IC_RESULT (uic))) > 1))
2641 /* make sure that the result of this icode is not on the
2642 stack, since acc is used to compute stack offset */
2643 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
2644 OP_SYMBOL (IC_RESULT (uic))->onStack)
2647 /* if either one of them in far space then we cannot */
2648 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
2649 isOperandInFarSpace (IC_LEFT (uic))) ||
2650 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
2651 isOperandInFarSpace (IC_RIGHT (uic))))
2654 /* if the usage has only one operand then we can */
2655 if (IC_LEFT (uic) == NULL ||
2656 IC_RIGHT (uic) == NULL)
2659 /* make sure this is on the left side if not
2660 a '+' since '+' is commutative */
2661 if (ic->op != '+' &&
2662 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
2665 /* if one of them is a literal then we can */
2666 if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
2667 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
2669 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2673 /* if the other one is not on stack then we can */
2674 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
2675 (IS_ITEMP (IC_RIGHT (uic)) ||
2676 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
2677 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
2680 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
2681 (IS_ITEMP (IC_LEFT (uic)) ||
2682 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
2683 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
2689 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2694 /*-----------------------------------------------------------------*/
2695 /* packForPush - hueristics to reduce iCode for pushing */
2696 /*-----------------------------------------------------------------*/
2698 packForReceive (iCode * ic, eBBlock * ebp)
2702 debugLog ("%s\n", __FUNCTION__);
2703 debugAopGet (" result:", IC_RESULT (ic));
2704 debugAopGet (" left:", IC_LEFT (ic));
2705 debugAopGet (" right:", IC_RIGHT (ic));
2710 for (dic = ic->next; dic; dic = dic->next)
2715 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
2716 debugLog (" used on left\n");
2717 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
2718 debugLog (" used on right\n");
2719 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
2720 debugLog (" used on result\n");
2722 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
2723 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
2728 debugLog (" hey we can remove this unnecessary assign\n");
2730 /*-----------------------------------------------------------------*/
2731 /* packForPush - hueristics to reduce iCode for pushing */
2732 /*-----------------------------------------------------------------*/
2734 packForPush (iCode * ic, eBBlock * ebp)
2738 debugLog ("%s\n", __FUNCTION__);
2739 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
2742 /* must have only definition & one usage */
2743 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
2744 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
2747 /* find the definition */
2748 if (!(dic = hTabItemWithKey (iCodehTab,
2749 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
2752 if (dic->op != '=' || POINTER_SET (dic))
2755 /* we now we know that it has one & only one def & use
2756 and the that the definition is an assignment */
2757 IC_LEFT (ic) = IC_RIGHT (dic);
2759 remiCodeFromeBBlock (ebp, dic);
2760 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2761 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2764 /*-----------------------------------------------------------------*/
2765 /* packRegisters - does some transformations to reduce register */
2767 /*-----------------------------------------------------------------*/
2769 packRegisters (eBBlock * ebp)
2774 debugLog ("%s\n", __FUNCTION__);
2781 /* look for assignments of the form */
2782 /* iTempNN = TRueSym (someoperation) SomeOperand */
2784 /* TrueSym := iTempNN:1 */
2785 for (ic = ebp->sch; ic; ic = ic->next)
2788 /* find assignment of the form TrueSym := iTempNN:1 */
2789 if (ic->op == '=' && !POINTER_SET (ic))
2790 change += packRegsForAssign (ic, ebp);
2794 if (POINTER_SET (ic))
2795 debugLog ("pointer is set\n");
2796 debugAopGet (" result:", IC_RESULT (ic));
2797 debugAopGet (" left:", IC_LEFT (ic));
2798 debugAopGet (" right:", IC_RIGHT (ic));
2807 for (ic = ebp->sch; ic; ic = ic->next)
2810 /* if this is an itemp & result of a address of a true sym
2811 then mark this as rematerialisable */
2812 if (ic->op == ADDRESS_OF &&
2813 IS_ITEMP (IC_RESULT (ic)) &&
2814 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
2815 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2816 !OP_SYMBOL (IC_LEFT (ic))->onStack)
2819 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
2821 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2822 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2823 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2827 /* if straight assignment then carry remat flag if
2828 this is the only definition */
2829 if (ic->op == '=' &&
2830 !POINTER_SET (ic) &&
2831 IS_SYMOP (IC_RIGHT (ic)) &&
2832 OP_SYMBOL (IC_RIGHT (ic))->remat &&
2833 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
2835 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
2837 OP_SYMBOL (IC_RESULT (ic))->remat =
2838 OP_SYMBOL (IC_RIGHT (ic))->remat;
2839 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
2840 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
2843 /* if this is a +/- operation with a rematerizable
2844 then mark this as rematerializable as well */
2845 if ((ic->op == '+' || ic->op == '-') &&
2846 (IS_SYMOP (IC_LEFT (ic)) &&
2847 IS_ITEMP (IC_RESULT (ic)) &&
2848 OP_SYMBOL (IC_LEFT (ic))->remat &&
2849 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2850 IS_OP_LITERAL (IC_RIGHT (ic))))
2852 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
2854 operandLitValue (IC_RIGHT (ic));
2855 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2856 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2857 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2860 /* mark the pointer usages */
2861 if (POINTER_SET (ic))
2863 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
2864 debugLog (" marking as a pointer (set) =>");
2865 debugAopGet (" result:", IC_RESULT (ic));
2867 if (POINTER_GET (ic))
2869 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
2870 debugLog (" marking as a pointer (get) =>");
2871 debugAopGet (" left:", IC_LEFT (ic));
2876 /* if we are using a symbol on the stack
2877 then we should say pic14_ptrRegReq */
2878 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
2879 pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
2880 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
2881 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
2882 pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
2883 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
2886 if (IS_SYMOP (IC_LEFT (ic)))
2887 pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
2888 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
2889 if (IS_SYMOP (IC_RIGHT (ic)))
2890 pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
2891 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
2892 if (IS_SYMOP (IC_RESULT (ic)))
2893 pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
2894 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
2898 /* if the condition of an if instruction
2899 is defined in the previous instruction then
2900 mark the itemp as a conditional */
2901 if ((IS_CONDITIONAL (ic) ||
2902 ((ic->op == BITWISEAND ||
2905 isBitwiseOptimizable (ic))) &&
2906 ic->next && ic->next->op == IFX &&
2907 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
2908 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2911 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
2915 /* reduce for support function calls */
2916 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
2917 packRegsForSupport (ic, ebp);
2919 /* if a parameter is passed, it's in W, so we may not
2920 need to place a copy in a register */
2921 if (ic->op == RECEIVE)
2922 packForReceive (ic, ebp);
2924 /* some cases the redundant moves can
2925 can be eliminated for return statements */
2926 if ((ic->op == RETURN || ic->op == SEND) &&
2927 !isOperandInFarSpace (IC_LEFT (ic)) &&
2929 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2931 /* if pointer set & left has a size more than
2932 one and right is not in far space */
2933 if (POINTER_SET (ic) &&
2934 !isOperandInFarSpace (IC_RIGHT (ic)) &&
2935 !OP_SYMBOL (IC_RESULT (ic))->remat &&
2936 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
2937 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
2939 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
2941 /* if pointer get */
2942 if (POINTER_GET (ic) &&
2943 !isOperandInFarSpace (IC_RESULT (ic)) &&
2944 !OP_SYMBOL (IC_LEFT (ic))->remat &&
2945 !IS_OP_RUONLY (IC_RESULT (ic)) &&
2946 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
2948 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2951 /* if this is cast for intergral promotion then
2952 check if only use of the definition of the
2953 operand being casted/ if yes then replace
2954 the result of that arithmetic operation with
2955 this result and get rid of the cast */
2958 sym_link *fromType = operandType (IC_RIGHT (ic));
2959 sym_link *toType = operandType (IC_LEFT (ic));
2961 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
2962 getSize (fromType) != getSize (toType))
2965 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2968 if (IS_ARITHMETIC_OP (dic))
2970 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2971 IC_RESULT (dic) = IC_RESULT (ic);
2972 remiCodeFromeBBlock (ebp, ic);
2973 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2974 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2975 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2979 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
2985 /* if the type from and type to are the same
2986 then if this is the only use then packit */
2987 if (compareType (operandType (IC_RIGHT (ic)),
2988 operandType (IC_LEFT (ic))) == 1)
2990 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2993 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2994 IC_RESULT (dic) = IC_RESULT (ic);
2995 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2996 remiCodeFromeBBlock (ebp, ic);
2997 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2998 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3006 iTempNN := (some variable in farspace) V1
3011 if (ic->op == IPUSH)
3013 packForPush (ic, ebp);
3017 /* pack registers for accumulator use, when the
3018 result of an arithmetic or bit wise operation
3019 has only one use, that use is immediately following
3020 the defintion and the using iCode has only one
3021 operand or has two operands but one is literal &
3022 the result of that operation is not on stack then
3023 we can leave the result of this operation in acc:b
3025 if ((IS_ARITHMETIC_OP (ic)
3027 || IS_BITWISE_OP (ic)
3029 || ic->op == LEFT_OP || ic->op == RIGHT_OP
3032 IS_ITEMP (IC_RESULT (ic)) &&
3033 getSize (operandType (IC_RESULT (ic))) <= 2)
3035 packRegsForAccUse (ic);
3041 dumpEbbsToDebug (eBBlock ** ebbs, int count)
3045 if (!debug || !debugF)
3048 for (i = 0; i < count; i++)
3050 fprintf (debugF, "\n----------------------------------------------------------------\n");
3051 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
3052 ebbs[i]->entryLabel->name,
3055 ebbs[i]->isLastInLoop);
3056 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
3061 fprintf (debugF, "visited %d : hasFcall = %d\n",
3065 fprintf (debugF, "\ndefines bitVector :");
3066 bitVectDebugOn (ebbs[i]->defSet, debugF);
3067 fprintf (debugF, "\nlocal defines bitVector :");
3068 bitVectDebugOn (ebbs[i]->ldefs, debugF);
3069 fprintf (debugF, "\npointers Set bitvector :");
3070 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
3071 fprintf (debugF, "\nin pointers Set bitvector :");
3072 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
3073 fprintf (debugF, "\ninDefs Set bitvector :");
3074 bitVectDebugOn (ebbs[i]->inDefs, debugF);
3075 fprintf (debugF, "\noutDefs Set bitvector :");
3076 bitVectDebugOn (ebbs[i]->outDefs, debugF);
3077 fprintf (debugF, "\nusesDefs Set bitvector :");
3078 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
3079 fprintf (debugF, "\n----------------------------------------------------------------\n");
3080 printiCChain (ebbs[i]->sch, debugF);
3083 /*-----------------------------------------------------------------*/
3084 /* assignRegisters - assigns registers to each live range as need */
3085 /*-----------------------------------------------------------------*/
3087 pic14_assignRegisters (eBBlock ** ebbs, int count)
3092 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
3093 debugLog ("\nebbs before optimizing:\n");
3094 dumpEbbsToDebug (ebbs, count);
3096 setToNull ((void *) &_G.funcrUsed);
3097 pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3100 /* change assignments this will remove some
3101 live ranges reducing some register pressure */
3102 for (i = 0; i < count; i++)
3103 packRegisters (ebbs[i]);
3105 if (options.dump_pack)
3106 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3108 /* first determine for each live range the number of
3109 registers & the type of registers required for each */
3112 /* and serially allocate registers */
3113 serialRegAssign (ebbs, count);
3115 /* if stack was extended then tell the user */
3118 /* werror(W_TOOMANY_SPILS,"stack", */
3119 /* _G.stackExtend,currFunc->name,""); */
3125 /* werror(W_TOOMANY_SPILS,"data space", */
3126 /* _G.dataExtend,currFunc->name,""); */
3130 /* after that create the register mask
3131 for each of the instruction */
3132 createRegMask (ebbs, count);
3134 /* redo that offsets for stacked automatic variables */
3135 redoStackOffsets ();
3137 if (options.dump_rassgn)
3138 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3140 /* now get back the chain */
3141 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3143 debugLog ("ebbs after optimizing:\n");
3144 dumpEbbsToDebug (ebbs, count);
3149 /* free up any _G.stackSpil locations allocated */
3150 applyToSet (_G.stackSpil, deallocStackSpil);
3152 setToNull ((void **) &_G.stackSpil);
3153 setToNull ((void **) &_G.spiltSet);
3154 /* mark all registers as free */
3155 pic14_freeAllRegs ();
3157 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");