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 #if defined(__BORLANDC__) || defined(_MSC_VER)
33 #define STRCASECMP stricmp
35 #define STRCASECMP strcasecmp
38 /*-----------------------------------------------------------------*/
39 /* At this point we start getting processor specific although */
40 /* some routines are non-processor specific & can be reused when */
41 /* targetting other processors. The decision for this will have */
42 /* to be made on a routine by routine basis */
43 /* routines used to pack registers are most definitely not reusable */
44 /* since the pack the registers depending strictly on the MCU */
45 /*-----------------------------------------------------------------*/
47 extern void genpic14Code (iCode *);
48 extern void assignConfigWordValue(int address, int value);
58 bitVect *funcrUsed; /* registers used in a function */
64 /* Shared with gen.c */
65 int pic14_ptrRegReq; /* one byte pointer register required */
68 set *dynAllocRegs=NULL;
69 set *dynStackRegs=NULL;
70 set *dynProcessorRegs=NULL;
71 set *dynDirectRegs=NULL;
72 set *dynDirectBitRegs=NULL;
73 set *dynInternalRegs=NULL;
75 static hTab *dynDirectRegNames= NULL;
77 static int dynrIdx=0x20;
78 static int rDirectIdx=0;
80 int pic14_nRegs = 128; // = sizeof (regspic14) / sizeof (regs);
82 int Gstack_base_addr=0; /* The starting address of registers that
83 * are used to pass and return parameters */
88 static void spillThis (symbol *);
90 static FILE *debugF = NULL;
91 /*-----------------------------------------------------------------*/
92 /* debugLog - open a file for debugging information */
93 /*-----------------------------------------------------------------*/
94 //static void debugLog(char *inst,char *fmt, ...)
96 debugLog (char *fmt,...)
98 static int append = 0; // First time through, open the file without append.
101 //char *bufferP=buffer;
104 if (!debug || !srcFileName)
110 /* create the file name */
111 strcpy (buffer, srcFileName);
112 strcat (buffer, ".d");
114 if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
116 werror (E_FILE_OPEN_ERR, buffer);
119 append = 1; // Next time debubLog is called, we'll append the debug info
125 vsprintf (buffer, fmt, ap);
127 fprintf (debugF, "%s", buffer);
129 while (isspace(*bufferP)) bufferP++;
131 if (bufferP && *bufferP)
132 lineCurr = (lineCurr ?
133 connectLine(lineCurr,newLineNode(lb)) :
134 (lineHead = newLineNode(lb)));
135 lineCurr->isInline = _G.inLine;
136 lineCurr->isDebug = _G.debugLine;
146 fputc ('\n', debugF);
148 /*-----------------------------------------------------------------*/
149 /* debugLogClose - closes the debug log file (if opened) */
150 /*-----------------------------------------------------------------*/
160 #define AOP(op) op->aop
163 debugAopGet (char *str, operand * op)
168 printOperand (op, debugF);
176 decodeOp (unsigned int op)
179 if (op < 128 && op > ' ')
181 buffer[0] = (op & 0xff);
195 return "STRING_LITERAL";
231 return "LEFT_ASSIGN";
233 return "RIGHT_ASSIGN";
348 case GET_VALUE_AT_ADDRESS:
349 return "GET_VALUE_AT_ADDRESS";
367 return "ENDFUNCTION";
391 sprintf (buffer, "unkown op %d %c", op, op & 0xff);
394 /*-----------------------------------------------------------------*/
395 /*-----------------------------------------------------------------*/
397 debugLogRegType (short type)
410 sprintf (buffer, "unknown reg type %d", type);
414 /*-----------------------------------------------------------------*/
415 /*-----------------------------------------------------------------*/
416 static int regname2key(char const *name)
425 key += (*name++) + 1;
429 return ( (key + (key >> 4) + (key>>8)) & 0x3f);
433 /*-----------------------------------------------------------------*/
434 /* newReg - allocate and init memory for a new register */
435 /*-----------------------------------------------------------------*/
436 static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias)
441 dReg = Safe_calloc(1,sizeof(regs));
443 dReg->pc_type = pc_type;
446 dReg->name = Safe_strdup(name);
448 sprintf(buffer,"r0x%02X", dReg->rIdx);
451 dReg->name = Safe_strdup(buffer);
453 //fprintf(stderr,"newReg: %s, rIdx = 0x%02x\n",dReg->name,rIdx);
466 dReg->reg_alias = NULL;
467 dReg->reglives.usedpFlows = newSet();
468 dReg->reglives.assignedpFlows = newSet();
470 hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
475 /*-----------------------------------------------------------------*/
476 /* regWithIdx - Search through a set of registers that matches idx */
477 /*-----------------------------------------------------------------*/
479 regWithIdx (set *dRegs, int idx, int fixed)
483 for (dReg = setFirstItem(dRegs) ; dReg ;
484 dReg = setNextItem(dRegs)) {
486 if(idx == dReg->rIdx && (fixed == dReg->isFixed)) {
494 /*-----------------------------------------------------------------*/
495 /* regFindFree - Search for a free register in a set of registers */
496 /*-----------------------------------------------------------------*/
498 regFindFree (set *dRegs)
502 for (dReg = setFirstItem(dRegs) ; dReg ;
503 dReg = setNextItem(dRegs)) {
511 /*-----------------------------------------------------------------*/
512 /* initStack - allocate registers for a psuedo stack */
513 /*-----------------------------------------------------------------*/
514 void initStack(int base_address, int size)
519 Gstack_base_addr = base_address;
520 //fprintf(stderr,"initStack");
522 for(i = 0; i<size; i++)
523 addSet(&dynStackRegs,newReg(REG_STK, PO_GPR_TEMP,base_address++,NULL,1,0));
526 /*-----------------------------------------------------------------*
527 *-----------------------------------------------------------------*/
529 allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
532 //fprintf(stderr,"allocProcessorRegister %s addr =0x%x\n",name,rIdx);
533 return addSet(&dynProcessorRegs,newReg(REG_SFR, po_type, rIdx, name,1,alias));
536 /*-----------------------------------------------------------------*
537 *-----------------------------------------------------------------*/
540 allocInternalRegister(int rIdx, char * name, short po_type, int alias)
542 regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias);
544 //fprintf(stderr,"allocInternalRegister %s addr =0x%x\n",name,rIdx);
547 return addSet(&dynInternalRegs,reg);
552 /*-----------------------------------------------------------------*/
553 /* allocReg - allocates register of given type */
554 /*-----------------------------------------------------------------*/
556 allocReg (short type)
559 debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
560 //fprintf(stderr,"allocReg\n");
563 return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
568 /*-----------------------------------------------------------------*/
569 /* dirregWithName - search for register by name */
570 /*-----------------------------------------------------------------*/
572 dirregWithName (char *name)
580 /* hash the name to get a key */
582 hkey = regname2key(name);
584 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
588 if(STRCASECMP(reg->name, name) == 0) {
592 reg = hTabNextItemWK (dynDirectRegNames);
596 return NULL; // name wasn't found in the hash table
599 int IS_CONFIG_ADDRESS(int address)
602 return address == 0x2007;
605 /*-----------------------------------------------------------------*/
606 /* allocDirReg - allocates register of given type */
607 /*-----------------------------------------------------------------*/
609 allocDirReg (operand *op )
616 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
620 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
622 /* If the symbol is at a fixed address, then remove the leading underscore
623 * from the name. This is hack to allow the .asm include file named registers
624 * to match the .c declared register names */
626 //if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && (*name == '_'))
629 debugLog ("%s symbol name %s\n", __FUNCTION__,name);
631 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
632 debugLog(" %d const char\n",__LINE__);
633 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
636 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
637 if (IS_CODE ( OP_SYM_ETYPE(op)) )
638 debugLog(" %d code space\n",__LINE__);
640 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
641 debugLog(" %d integral\n",__LINE__);
642 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
643 debugLog(" %d literal\n",__LINE__);
644 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
645 debugLog(" %d specifier\n",__LINE__);
646 debugAopGet(NULL, op);
649 if (IS_CODE ( OP_SYM_ETYPE(op)) )
652 /* First, search the hash table to see if there is a register with this name */
653 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && !(IS_BITVAR (OP_SYM_ETYPE(op))) ) {
654 reg = regWithIdx (dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1);
657 fprintf(stderr,"ralloc %s is at fixed address but not a processor reg, addr=0x%x\n",
658 name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
660 fprintf(stderr,"ralloc %s at fixed address has already been declared, addr=0x%x\n",
661 name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
664 //fprintf(stderr,"ralloc %s \n", name);
666 reg = dirregWithName(name);
672 /* if this is at an absolute address, then get the address. */
673 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
674 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
677 /* Register wasn't found in hash, so let's create
678 * a new one and put it in the hash table AND in the
679 * dynDirectRegNames set */
680 if(!IS_CONFIG_ADDRESS(address)) {
681 //fprintf(stderr,"allocating new reg %s\n",name);
683 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0 );
684 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
686 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
688 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
690 //fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
694 if (IS_BITVAR (OP_SYM_ETYPE(op)))
695 addSet(&dynDirectBitRegs, reg);
697 addSet(&dynDirectRegs, reg);
700 debugLog (" -- %s is declared at address 0x2007\n",name);
705 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
707 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
708 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
714 /*-----------------------------------------------------------------*/
715 /* allocDirReg - allocates register of given type */
716 /*-----------------------------------------------------------------*/
718 allocRegByName (char *name, int size)
724 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
728 /* First, search the hash table to see if there is a register with this name */
729 reg = dirregWithName(name);
733 /* Register wasn't found in hash, so let's create
734 * a new one and put it in the hash table AND in the
735 * dynDirectRegNames set */
736 //fprintf (stderr,"%s symbol name %s\n", __FUNCTION__,name);
737 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0 );
739 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
741 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
742 addSet(&dynDirectRegs, reg);
748 /*-----------------------------------------------------------------*/
749 /* RegWithIdx - returns pointer to register with index number */
750 /*-----------------------------------------------------------------*/
752 typeRegWithIdx (int idx, int type, int fixed)
757 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
762 if( (dReg = regWithIdx ( dynAllocRegs, idx, fixed)) != NULL) {
764 debugLog ("Found a Dynamic Register!\n");
767 if( (dReg = regWithIdx ( dynDirectRegs, idx, fixed)) != NULL ) {
768 debugLog ("Found a Direct Register!\n");
774 if( (dReg = regWithIdx ( dynStackRegs, idx, fixed)) != NULL ) {
775 debugLog ("Found a Stack Register!\n");
780 if( (dReg = regWithIdx ( dynProcessorRegs, idx, fixed)) != NULL ) {
781 debugLog ("Found a Processor Register!\n");
795 /*-----------------------------------------------------------------*/
796 /* pic14_regWithIdx - returns pointer to register with index number*/
797 /*-----------------------------------------------------------------*/
799 pic14_regWithIdx (int idx)
803 if( (dReg = typeRegWithIdx(idx,REG_GPR,0)) != NULL)
806 if( (dReg = typeRegWithIdx(idx,REG_SFR,0)) != NULL)
809 if( (dReg = typeRegWithIdx(idx,REG_STK,0)) != NULL)
815 /*-----------------------------------------------------------------*/
816 /* pic14_regWithIdx - returns pointer to register with index number */
817 /*-----------------------------------------------------------------*/
819 pic14_allocWithIdx (int idx)
824 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
826 if( (dReg = regWithIdx ( dynAllocRegs, idx,0)) != NULL) {
828 debugLog ("Found a Dynamic Register!\n");
829 } else if( (dReg = regWithIdx ( dynStackRegs, idx,0)) != NULL ) {
830 debugLog ("Found a Stack Register!\n");
831 } else if( (dReg = regWithIdx ( dynProcessorRegs, idx,0)) != NULL ) {
832 debugLog ("Found a Processor Register!\n");
833 } else if( (dReg = regWithIdx ( dynInternalRegs, idx,0)) != NULL ) {
834 debugLog ("Found an Internal Register!\n");
837 debugLog ("Dynamic Register not found\n");
840 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
841 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
842 "regWithIdx not found");
852 /*-----------------------------------------------------------------*/
853 /*-----------------------------------------------------------------*/
855 pic14_findFreeReg(short type)
862 if((dReg = regFindFree(dynAllocRegs)) != NULL)
864 //fprintf(stderr,"findfreereg\n");
865 return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
869 if((dReg = regFindFree(dynStackRegs)) != NULL)
881 /*-----------------------------------------------------------------*/
882 /* freeReg - frees a register */
883 /*-----------------------------------------------------------------*/
887 debugLog ("%s\n", __FUNCTION__);
892 /*-----------------------------------------------------------------*/
893 /* nFreeRegs - returns number of free registers */
894 /*-----------------------------------------------------------------*/
898 /* dynamically allocate as many as we need and worry about
899 * fitting them into a PIC later */
906 debugLog ("%s\n", __FUNCTION__);
907 for (i = 0; i < pic14_nRegs; i++)
908 if (regspic14[i].isFree && regspic14[i].type == type)
914 /*-----------------------------------------------------------------*/
915 /* nfreeRegsType - free registers with type */
916 /*-----------------------------------------------------------------*/
918 nfreeRegsType (int type)
921 debugLog ("%s\n", __FUNCTION__);
924 if ((nfr = nFreeRegs (type)) == 0)
925 return nFreeRegs (REG_GPR);
928 return nFreeRegs (type);
931 void writeSetUsedRegs(FILE *of, set *dRegs)
936 for (dReg = setFirstItem(dRegs) ; dReg ;
937 dReg = setNextItem(dRegs)) {
940 fprintf (of, "\t%s\n",dReg->name);
944 extern void assignFixedRegisters(set *regset);
945 extern void assignRelocatableRegisters(set *regset,int used);
946 extern void dump_map(void);
947 extern void dump_cblock(FILE *of);
950 void packBits(set *bregs)
955 regs *relocbitfield=NULL;
961 for (regset = bregs ; regset ;
962 regset = regset->next) {
965 breg->isBitField = 1;
966 //fprintf(stderr,"bit reg: %s\n",breg->name);
969 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
971 bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1);
972 breg->rIdx = breg->address & 7;
976 sprintf (buffer, "fbitfield%02x", breg->address);
977 //fprintf(stderr,"new bit field\n");
978 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0);
979 bitfield->isBitField = 1;
980 bitfield->isFixed = 1;
981 bitfield->address = breg->address;
982 addSet(&dynDirectRegs,bitfield);
983 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
985 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
988 breg->reg_alias = bitfield;
992 if(!relocbitfield || bit_no >7) {
995 sprintf (buffer, "bitfield%d", byte_no);
996 //fprintf(stderr,"new relocatable bit field\n");
997 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0);
998 relocbitfield->isBitField = 1;
999 addSet(&dynDirectRegs,relocbitfield);
1000 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1004 breg->reg_alias = relocbitfield;
1005 breg->address = rDirectIdx; /* byte_no; */
1006 breg->rIdx = bit_no++;
1014 void bitEQUs(FILE *of, set *bregs)
1016 regs *breg,*bytereg;
1019 //fprintf(stderr," %s\n",__FUNCTION__);
1020 for (breg = setFirstItem(bregs) ; breg ;
1021 breg = setNextItem(bregs)) {
1023 //fprintf(stderr,"bit reg: %s\n",breg->name);
1025 bytereg = breg->reg_alias;
1027 fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
1030 breg->rIdx & 0x0007);
1033 fprintf(stderr, "bit field is not assigned to a register\n");
1034 fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
1044 void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
1049 for (reg = setFirstItem(fregs) ; reg ;
1050 reg = setNextItem(fregs)) {
1052 if(!reg->isEmitted && reg->wasUsed) {
1054 fprintf (of, "%s\tEQU\t0x%03x\n",
1058 fprintf (of, "%s\tEQU\t0x%03x\n",
1066 void writeUsedRegs(FILE *of)
1068 packBits(dynDirectBitRegs);
1071 assignFixedRegisters(dynAllocRegs);
1072 assignFixedRegisters(dynStackRegs);
1073 assignFixedRegisters(dynDirectRegs);
1075 assignRelocatableRegisters(dynInternalRegs,0);
1076 assignRelocatableRegisters(dynAllocRegs,0);
1077 assignRelocatableRegisters(dynStackRegs,0);
1078 assignRelocatableRegisters(dynDirectRegs,0);
1083 bitEQUs(of,dynDirectBitRegs);
1084 aliasEQUs(of,dynAllocRegs,0);
1085 aliasEQUs(of,dynDirectRegs,0);
1086 aliasEQUs(of,dynStackRegs,0);
1087 aliasEQUs(of,dynProcessorRegs,1);
1092 /*-----------------------------------------------------------------*/
1093 /* allDefsOutOfRange - all definitions are out of a range */
1094 /*-----------------------------------------------------------------*/
1096 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
1100 debugLog ("%s\n", __FUNCTION__);
1104 for (i = 0; i < defs->size; i++)
1108 if (bitVectBitValue (defs, i) &&
1109 (ic = hTabItemWithKey (iCodehTab, i)) &&
1110 (ic->seq >= fseq && ic->seq <= toseq))
1120 /*-----------------------------------------------------------------*/
1121 /* computeSpillable - given a point find the spillable live ranges */
1122 /*-----------------------------------------------------------------*/
1124 computeSpillable (iCode * ic)
1128 debugLog ("%s\n", __FUNCTION__);
1129 /* spillable live ranges are those that are live at this
1130 point . the following categories need to be subtracted
1132 a) - those that are already spilt
1133 b) - if being used by this one
1134 c) - defined by this one */
1136 spillable = bitVectCopy (ic->rlive);
1138 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1140 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1141 bitVectUnSetBit (spillable, ic->defKey);
1142 spillable = bitVectIntersect (spillable, _G.regAssigned);
1147 /*-----------------------------------------------------------------*/
1148 /* noSpilLoc - return true if a variable has no spil location */
1149 /*-----------------------------------------------------------------*/
1151 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1153 debugLog ("%s\n", __FUNCTION__);
1154 return (sym->usl.spillLoc ? 0 : 1);
1157 /*-----------------------------------------------------------------*/
1158 /* hasSpilLoc - will return 1 if the symbol has spil location */
1159 /*-----------------------------------------------------------------*/
1161 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1163 debugLog ("%s\n", __FUNCTION__);
1164 return (sym->usl.spillLoc ? 1 : 0);
1167 /*-----------------------------------------------------------------*/
1168 /* directSpilLoc - will return 1 if the splilocation is in direct */
1169 /*-----------------------------------------------------------------*/
1171 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1173 debugLog ("%s\n", __FUNCTION__);
1174 if (sym->usl.spillLoc &&
1175 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1181 /*-----------------------------------------------------------------*/
1182 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1183 /* but is not used as a pointer */
1184 /*-----------------------------------------------------------------*/
1186 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1188 debugLog ("%s\n", __FUNCTION__);
1189 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1192 /*-----------------------------------------------------------------*/
1193 /* rematable - will return 1 if the remat flag is set */
1194 /*-----------------------------------------------------------------*/
1196 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1198 debugLog ("%s\n", __FUNCTION__);
1202 /*-----------------------------------------------------------------*/
1203 /* notUsedInRemaining - not used or defined in remain of the block */
1204 /*-----------------------------------------------------------------*/
1206 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1208 debugLog ("%s\n", __FUNCTION__);
1209 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1210 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1213 /*-----------------------------------------------------------------*/
1214 /* allLRs - return true for all */
1215 /*-----------------------------------------------------------------*/
1217 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1219 debugLog ("%s\n", __FUNCTION__);
1223 /*-----------------------------------------------------------------*/
1224 /* liveRangesWith - applies function to a given set of live range */
1225 /*-----------------------------------------------------------------*/
1227 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1228 eBBlock * ebp, iCode * ic)
1233 debugLog ("%s\n", __FUNCTION__);
1234 if (!lrs || !lrs->size)
1237 for (i = 1; i < lrs->size; i++)
1240 if (!bitVectBitValue (lrs, i))
1243 /* if we don't find it in the live range
1244 hash table we are in serious trouble */
1245 if (!(sym = hTabItemWithKey (liveRanges, i)))
1247 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1248 "liveRangesWith could not find liveRange");
1252 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1253 addSetHead (&rset, sym);
1260 /*-----------------------------------------------------------------*/
1261 /* leastUsedLR - given a set determines which is the least used */
1262 /*-----------------------------------------------------------------*/
1264 leastUsedLR (set * sset)
1266 symbol *sym = NULL, *lsym = NULL;
1268 debugLog ("%s\n", __FUNCTION__);
1269 sym = lsym = setFirstItem (sset);
1274 for (; lsym; lsym = setNextItem (sset))
1277 /* if usage is the same then prefer
1278 the spill the smaller of the two */
1279 if (lsym->used == sym->used)
1280 if (getSize (lsym->type) < getSize (sym->type))
1284 if (lsym->used < sym->used)
1289 setToNull ((void **) &sset);
1294 /*-----------------------------------------------------------------*/
1295 /* noOverLap - will iterate through the list looking for over lap */
1296 /*-----------------------------------------------------------------*/
1298 noOverLap (set * itmpStack, symbol * fsym)
1301 debugLog ("%s\n", __FUNCTION__);
1304 for (sym = setFirstItem (itmpStack); sym;
1305 sym = setNextItem (itmpStack))
1307 if (sym->liveTo > fsym->liveFrom)
1315 /*-----------------------------------------------------------------*/
1316 /* isFree - will return 1 if the a free spil location is found */
1317 /*-----------------------------------------------------------------*/
1322 V_ARG (symbol **, sloc);
1323 V_ARG (symbol *, fsym);
1325 debugLog ("%s\n", __FUNCTION__);
1326 /* if already found */
1330 /* if it is free && and the itmp assigned to
1331 this does not have any overlapping live ranges
1332 with the one currently being assigned and
1333 the size can be accomodated */
1335 noOverLap (sym->usl.itmpStack, fsym) &&
1336 getSize (sym->type) >= getSize (fsym->type))
1345 /*-----------------------------------------------------------------*/
1346 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1347 /*-----------------------------------------------------------------*/
1349 spillLRWithPtrReg (symbol * forSym)
1355 debugLog ("%s\n", __FUNCTION__);
1356 if (!_G.regAssigned ||
1357 bitVectIsZero (_G.regAssigned))
1360 r0 = pic14_regWithIdx (R0_IDX);
1361 r1 = pic14_regWithIdx (R1_IDX);
1363 /* for all live ranges */
1364 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1365 lrsym = hTabNextItem (liveRanges, &k))
1369 /* if no registers assigned to it or
1371 /* if it does not overlap with this then
1372 not need to spill it */
1374 if (lrsym->isspilt || !lrsym->nRegs ||
1375 (lrsym->liveTo < forSym->liveFrom))
1378 /* go thru the registers : if it is either
1379 r0 or r1 then spil it */
1380 for (j = 0; j < lrsym->nRegs; j++)
1381 if (lrsym->regs[j] == r0 ||
1382 lrsym->regs[j] == r1)
1391 /*-----------------------------------------------------------------*/
1392 /* createStackSpil - create a location on the stack to spil */
1393 /*-----------------------------------------------------------------*/
1395 createStackSpil (symbol * sym)
1397 symbol *sloc = NULL;
1398 int useXstack, model, noOverlay;
1400 char slocBuffer[30];
1401 debugLog ("%s\n", __FUNCTION__);
1403 /* first go try and find a free one that is already
1404 existing on the stack */
1405 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1407 /* found a free one : just update & return */
1408 sym->usl.spillLoc = sloc;
1411 addSetHead (&sloc->usl.itmpStack, sym);
1415 /* could not then have to create one , this is the hard part
1416 we need to allocate this on the stack : this is really a
1417 hack!! but cannot think of anything better at this time */
1419 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1421 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1422 __FILE__, __LINE__);
1426 sloc = newiTemp (slocBuffer);
1428 /* set the type to the spilling symbol */
1429 sloc->type = copyLinkChain (sym->type);
1430 sloc->etype = getSpec (sloc->type);
1431 SPEC_SCLS (sloc->etype) = S_DATA;
1432 SPEC_EXTR (sloc->etype) = 0;
1433 SPEC_STAT (sloc->etype) = 0;
1435 /* we don't allow it to be allocated`
1436 onto the external stack since : so we
1437 temporarily turn it off ; we also
1438 turn off memory model to prevent
1439 the spil from going to the external storage
1440 and turn off overlaying
1443 useXstack = options.useXstack;
1444 model = options.model;
1445 noOverlay = options.noOverlay;
1446 options.noOverlay = 1;
1447 options.model = options.useXstack = 0;
1451 options.useXstack = useXstack;
1452 options.model = model;
1453 options.noOverlay = noOverlay;
1454 sloc->isref = 1; /* to prevent compiler warning */
1456 /* if it is on the stack then update the stack */
1457 if (IN_STACK (sloc->etype))
1459 currFunc->stack += getSize (sloc->type);
1460 _G.stackExtend += getSize (sloc->type);
1463 _G.dataExtend += getSize (sloc->type);
1465 /* add it to the _G.stackSpil set */
1466 addSetHead (&_G.stackSpil, sloc);
1467 sym->usl.spillLoc = sloc;
1470 /* add it to the set of itempStack set
1471 of the spill location */
1472 addSetHead (&sloc->usl.itmpStack, sym);
1476 /*-----------------------------------------------------------------*/
1477 /* isSpiltOnStack - returns true if the spil location is on stack */
1478 /*-----------------------------------------------------------------*/
1480 isSpiltOnStack (symbol * sym)
1484 debugLog ("%s\n", __FUNCTION__);
1491 /* if (sym->_G.stackSpil) */
1494 if (!sym->usl.spillLoc)
1497 etype = getSpec (sym->usl.spillLoc->type);
1498 if (IN_STACK (etype))
1504 /*-----------------------------------------------------------------*/
1505 /* spillThis - spils a specific operand */
1506 /*-----------------------------------------------------------------*/
1508 spillThis (symbol * sym)
1511 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1513 /* if this is rematerializable or has a spillLocation
1514 we are okay, else we need to create a spillLocation
1516 if (!(sym->remat || sym->usl.spillLoc))
1517 createStackSpil (sym);
1520 /* mark it has spilt & put it in the spilt set */
1522 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1524 bitVectUnSetBit (_G.regAssigned, sym->key);
1526 for (i = 0; i < sym->nRegs; i++)
1530 freeReg (sym->regs[i]);
1531 sym->regs[i] = NULL;
1534 /* if spilt on stack then free up r0 & r1
1535 if they could have been assigned to some
1537 if (!pic14_ptrRegReq && isSpiltOnStack (sym))
1540 spillLRWithPtrReg (sym);
1543 if (sym->usl.spillLoc && !sym->remat)
1544 sym->usl.spillLoc->allocreq = 1;
1548 /*-----------------------------------------------------------------*/
1549 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1550 /*-----------------------------------------------------------------*/
1552 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1554 bitVect *lrcs = NULL;
1558 debugLog ("%s\n", __FUNCTION__);
1559 /* get the spillable live ranges */
1560 lrcs = computeSpillable (ic);
1562 /* get all live ranges that are rematerizable */
1563 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1566 /* return the least used of these */
1567 return leastUsedLR (selectS);
1570 /* get live ranges with spillLocations in direct space */
1571 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1573 sym = leastUsedLR (selectS);
1574 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1575 sym->usl.spillLoc->rname :
1576 sym->usl.spillLoc->name));
1578 /* mark it as allocation required */
1579 sym->usl.spillLoc->allocreq = 1;
1583 /* if the symbol is local to the block then */
1584 if (forSym->liveTo < ebp->lSeq)
1587 /* check if there are any live ranges allocated
1588 to registers that are not used in this block */
1589 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1591 sym = leastUsedLR (selectS);
1592 /* if this is not rematerializable */
1601 /* check if there are any live ranges that not
1602 used in the remainder of the block */
1603 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1605 sym = leastUsedLR (selectS);
1608 sym->remainSpil = 1;
1615 /* find live ranges with spillocation && not used as pointers */
1616 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1619 sym = leastUsedLR (selectS);
1620 /* mark this as allocation required */
1621 sym->usl.spillLoc->allocreq = 1;
1625 /* find live ranges with spillocation */
1626 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1629 sym = leastUsedLR (selectS);
1630 sym->usl.spillLoc->allocreq = 1;
1634 /* couldn't find then we need to create a spil
1635 location on the stack , for which one? the least
1637 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1640 /* return a created spil location */
1641 sym = createStackSpil (leastUsedLR (selectS));
1642 sym->usl.spillLoc->allocreq = 1;
1646 /* this is an extreme situation we will spill
1647 this one : happens very rarely but it does happen */
1653 /*-----------------------------------------------------------------*/
1654 /* spilSomething - spil some variable & mark registers as free */
1655 /*-----------------------------------------------------------------*/
1657 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1662 debugLog ("%s\n", __FUNCTION__);
1663 /* get something we can spil */
1664 ssym = selectSpil (ic, ebp, forSym);
1666 /* mark it as spilt */
1668 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1670 /* mark it as not register assigned &
1671 take it away from the set */
1672 bitVectUnSetBit (_G.regAssigned, ssym->key);
1674 /* mark the registers as free */
1675 for (i = 0; i < ssym->nRegs; i++)
1677 freeReg (ssym->regs[i]);
1679 /* if spilt on stack then free up r0 & r1
1680 if they could have been assigned to as gprs */
1681 if (!pic14_ptrRegReq && isSpiltOnStack (ssym))
1684 spillLRWithPtrReg (ssym);
1687 /* if this was a block level spil then insert push & pop
1688 at the start & end of block respectively */
1689 if (ssym->blockSpil)
1691 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1692 /* add push to the start of the block */
1693 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1694 ebp->sch->next : ebp->sch));
1695 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1696 /* add pop to the end of the block */
1697 addiCodeToeBBlock (ebp, nic, NULL);
1700 /* if spilt because not used in the remainder of the
1701 block then add a push before this instruction and
1702 a pop at the end of the block */
1703 if (ssym->remainSpil)
1706 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1707 /* add push just before this instruction */
1708 addiCodeToeBBlock (ebp, nic, ic);
1710 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1711 /* add pop to the end of the block */
1712 addiCodeToeBBlock (ebp, nic, NULL);
1721 /*-----------------------------------------------------------------*/
1722 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1723 /*-----------------------------------------------------------------*/
1725 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1729 debugLog ("%s\n", __FUNCTION__);
1731 /* try for a ptr type */
1732 if ((reg = allocReg (REG_PTR)))
1735 /* try for gpr type */
1736 if ((reg = allocReg (REG_GPR)))
1739 /* we have to spil */
1740 if (!spilSomething (ic, ebp, sym))
1743 /* this looks like an infinite loop but
1744 in really selectSpil will abort */
1748 /*-----------------------------------------------------------------*/
1749 /* getRegGpr - will try for GPR if not spil */
1750 /*-----------------------------------------------------------------*/
1752 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1756 debugLog ("%s\n", __FUNCTION__);
1758 /* try for gpr type */
1759 if ((reg = allocReg (REG_GPR)))
1762 if (!pic14_ptrRegReq)
1763 if ((reg = allocReg (REG_PTR)))
1766 /* we have to spil */
1767 if (!spilSomething (ic, ebp, sym))
1770 /* this looks like an infinite loop but
1771 in really selectSpil will abort */
1775 /*-----------------------------------------------------------------*/
1776 /* symHasReg - symbol has a given register */
1777 /*-----------------------------------------------------------------*/
1779 symHasReg (symbol * sym, regs * reg)
1783 debugLog ("%s\n", __FUNCTION__);
1784 for (i = 0; i < sym->nRegs; i++)
1785 if (sym->regs[i] == reg)
1791 /*-----------------------------------------------------------------*/
1792 /* deassignLRs - check the live to and if they have registers & are */
1793 /* not spilt then free up the registers */
1794 /*-----------------------------------------------------------------*/
1796 deassignLRs (iCode * ic, eBBlock * ebp)
1802 debugLog ("%s\n", __FUNCTION__);
1803 for (sym = hTabFirstItem (liveRanges, &k); sym;
1804 sym = hTabNextItem (liveRanges, &k))
1807 symbol *psym = NULL;
1808 /* if it does not end here */
1809 if (sym->liveTo > ic->seq)
1812 /* if it was spilt on stack then we can
1813 mark the stack spil location as free */
1818 sym->usl.spillLoc->isFree = 1;
1824 if (!bitVectBitValue (_G.regAssigned, sym->key))
1827 /* special case check if this is an IFX &
1828 the privious one was a pop and the
1829 previous one was not spilt then keep track
1831 if (ic->op == IFX && ic->prev &&
1832 ic->prev->op == IPOP &&
1833 !ic->prev->parmPush &&
1834 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1835 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1841 bitVectUnSetBit (_G.regAssigned, sym->key);
1843 /* if the result of this one needs registers
1844 and does not have it then assign it right
1846 if (IC_RESULT (ic) &&
1847 !(SKIP_IC2 (ic) || /* not a special icode */
1848 ic->op == JUMPTABLE ||
1853 POINTER_SET (ic)) &&
1854 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1855 result->liveTo > ic->seq && /* and will live beyond this */
1856 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1857 result->regType == sym->regType && /* same register types */
1858 result->nRegs && /* which needs registers */
1859 !result->isspilt && /* and does not already have them */
1861 !bitVectBitValue (_G.regAssigned, result->key) &&
1862 /* the number of free regs + number of regs in this LR
1863 can accomodate the what result Needs */
1864 ((nfreeRegsType (result->regType) +
1865 sym->nRegs) >= result->nRegs)
1869 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1871 result->regs[i] = sym->regs[i];
1873 result->regs[i] = getRegGpr (ic, ebp, result);
1875 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1879 /* free the remaining */
1880 for (; i < sym->nRegs; i++)
1884 if (!symHasReg (psym, sym->regs[i]))
1885 freeReg (sym->regs[i]);
1888 freeReg (sym->regs[i]);
1895 /*-----------------------------------------------------------------*/
1896 /* reassignLR - reassign this to registers */
1897 /*-----------------------------------------------------------------*/
1899 reassignLR (operand * op)
1901 symbol *sym = OP_SYMBOL (op);
1904 debugLog ("%s\n", __FUNCTION__);
1905 /* not spilt any more */
1906 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1907 bitVectUnSetBit (_G.spiltSet, sym->key);
1909 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1913 for (i = 0; i < sym->nRegs; i++)
1914 sym->regs[i]->isFree = 0;
1917 /*-----------------------------------------------------------------*/
1918 /* willCauseSpill - determines if allocating will cause a spill */
1919 /*-----------------------------------------------------------------*/
1921 willCauseSpill (int nr, int rt)
1923 debugLog ("%s\n", __FUNCTION__);
1924 /* first check if there are any avlb registers
1925 of te type required */
1928 /* special case for pointer type
1929 if pointer type not avlb then
1930 check for type gpr */
1931 if (nFreeRegs (rt) >= nr)
1933 if (nFreeRegs (REG_GPR) >= nr)
1938 if (pic14_ptrRegReq)
1940 if (nFreeRegs (rt) >= nr)
1945 if (nFreeRegs (REG_PTR) +
1946 nFreeRegs (REG_GPR) >= nr)
1951 debugLog (" ... yep it will (cause a spill)\n");
1952 /* it will cause a spil */
1956 /*-----------------------------------------------------------------*/
1957 /* positionRegs - the allocator can allocate same registers to res- */
1958 /* ult and operand, if this happens make sure they are in the same */
1959 /* position as the operand otherwise chaos results */
1960 /*-----------------------------------------------------------------*/
1962 positionRegs (symbol * result, symbol * opsym, int lineno)
1964 int count = min (result->nRegs, opsym->nRegs);
1965 int i, j = 0, shared = 0;
1967 debugLog ("%s\n", __FUNCTION__);
1968 /* if the result has been spilt then cannot share */
1973 /* first make sure that they actually share */
1974 for (i = 0; i < count; i++)
1976 for (j = 0; j < count; j++)
1978 if (result->regs[i] == opsym->regs[j] && i != j)
1988 regs *tmp = result->regs[i];
1989 result->regs[i] = result->regs[j];
1990 result->regs[j] = tmp;
1995 /*-----------------------------------------------------------------*/
1996 /* serialRegAssign - serially allocate registers to the variables */
1997 /*-----------------------------------------------------------------*/
1999 serialRegAssign (eBBlock ** ebbs, int count)
2003 debugLog ("%s\n", __FUNCTION__);
2004 /* for all blocks */
2005 for (i = 0; i < count; i++)
2010 if (ebbs[i]->noPath &&
2011 (ebbs[i]->entryLabel != entryLabel &&
2012 ebbs[i]->entryLabel != returnLabel))
2015 /* of all instructions do */
2016 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2019 debugLog (" op: %s\n", decodeOp (ic->op));
2021 /* if this is an ipop that means some live
2022 range will have to be assigned again */
2024 reassignLR (IC_LEFT (ic));
2026 /* if result is present && is a true symbol */
2027 if (IC_RESULT (ic) && ic->op != IFX &&
2028 IS_TRUE_SYMOP (IC_RESULT (ic)))
2029 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2031 /* take away registers from live
2032 ranges that end at this instruction */
2033 deassignLRs (ic, ebbs[i]);
2035 /* some don't need registers */
2036 if (SKIP_IC2 (ic) ||
2037 ic->op == JUMPTABLE ||
2041 (IC_RESULT (ic) && POINTER_SET (ic)))
2044 /* now we need to allocate registers
2045 only for the result */
2048 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2054 /* if it does not need or is spilt
2055 or is already assigned to registers
2056 or will not live beyond this instructions */
2059 bitVectBitValue (_G.regAssigned, sym->key) ||
2060 sym->liveTo <= ic->seq)
2063 /* if some liverange has been spilt at the block level
2064 and this one live beyond this block then spil this
2066 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2071 /* if trying to allocate this will cause
2072 a spill and there is nothing to spill
2073 or this one is rematerializable then
2075 willCS = willCauseSpill (sym->nRegs, sym->regType);
2076 spillable = computeSpillable (ic);
2078 (willCS && bitVectIsZero (spillable)))
2086 /* if it has a spillocation & is used less than
2087 all other live ranges then spill this */
2089 if (sym->usl.spillLoc) {
2090 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2091 allLRs, ebbs[i], ic));
2092 if (leastUsed && leastUsed->used > sym->used) {
2097 /* if none of the liveRanges have a spillLocation then better
2098 to spill this one than anything else already assigned to registers */
2099 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2100 /* if this is local to this block then we might find a block spil */
2101 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2109 if (ic->op == RECEIVE)
2110 debugLog ("When I get clever, I'll optimize the receive logic\n");
2112 /* if we need ptr regs for the right side
2114 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2115 <= (unsigned) PTRSIZE)
2120 /* else we assign registers to it */
2121 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2123 debugLog (" %d - \n", __LINE__);
2125 bitVectDebugOn(_G.regAssigned, debugF);
2127 for (j = 0; j < sym->nRegs; j++)
2129 if (sym->regType == REG_PTR)
2130 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2132 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2134 /* if the allocation falied which means
2135 this was spilt then break */
2139 debugLog (" %d - \n", __LINE__);
2141 /* if it shares registers with operands make sure
2142 that they are in the same position */
2143 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2144 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2145 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2146 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2147 /* do the same for the right operand */
2148 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2149 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2150 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2151 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2153 debugLog (" %d - \n", __LINE__);
2156 debugLog (" %d - \n", __LINE__);
2166 /*-----------------------------------------------------------------*/
2167 /* rUmaskForOp :- returns register mask for an operand */
2168 /*-----------------------------------------------------------------*/
2170 rUmaskForOp (operand * op)
2176 debugLog ("%s\n", __FUNCTION__);
2177 /* only temporaries are assigned registers */
2181 sym = OP_SYMBOL (op);
2183 /* if spilt or no registers assigned to it
2185 if (sym->isspilt || !sym->nRegs)
2188 rumask = newBitVect (pic14_nRegs);
2190 for (j = 0; j < sym->nRegs; j++)
2192 rumask = bitVectSetBit (rumask,
2193 sym->regs[j]->rIdx);
2199 /*-----------------------------------------------------------------*/
2200 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2201 /*-----------------------------------------------------------------*/
2203 regsUsedIniCode (iCode * ic)
2205 bitVect *rmask = newBitVect (pic14_nRegs);
2207 debugLog ("%s\n", __FUNCTION__);
2208 /* do the special cases first */
2211 rmask = bitVectUnion (rmask,
2212 rUmaskForOp (IC_COND (ic)));
2216 /* for the jumptable */
2217 if (ic->op == JUMPTABLE)
2219 rmask = bitVectUnion (rmask,
2220 rUmaskForOp (IC_JTCOND (ic)));
2225 /* of all other cases */
2227 rmask = bitVectUnion (rmask,
2228 rUmaskForOp (IC_LEFT (ic)));
2232 rmask = bitVectUnion (rmask,
2233 rUmaskForOp (IC_RIGHT (ic)));
2236 rmask = bitVectUnion (rmask,
2237 rUmaskForOp (IC_RESULT (ic)));
2243 /*-----------------------------------------------------------------*/
2244 /* createRegMask - for each instruction will determine the regsUsed */
2245 /*-----------------------------------------------------------------*/
2247 createRegMask (eBBlock ** ebbs, int count)
2251 debugLog ("%s\n", __FUNCTION__);
2252 /* for all blocks */
2253 for (i = 0; i < count; i++)
2257 if (ebbs[i]->noPath &&
2258 (ebbs[i]->entryLabel != entryLabel &&
2259 ebbs[i]->entryLabel != returnLabel))
2262 /* for all instructions */
2263 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2268 if (SKIP_IC2 (ic) || !ic->rlive)
2271 /* first mark the registers used in this
2273 ic->rUsed = regsUsedIniCode (ic);
2274 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2276 /* now create the register mask for those
2277 registers that are in use : this is a
2278 super set of ic->rUsed */
2279 ic->rMask = newBitVect (pic14_nRegs + 1);
2281 /* for all live Ranges alive at this point */
2282 for (j = 1; j < ic->rlive->size; j++)
2287 /* if not alive then continue */
2288 if (!bitVectBitValue (ic->rlive, j))
2291 /* find the live range we are interested in */
2292 if (!(sym = hTabItemWithKey (liveRanges, j)))
2294 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2295 "createRegMask cannot find live range");
2299 /* if no register assigned to it */
2300 if (!sym->nRegs || sym->isspilt)
2303 /* for all the registers allocated to it */
2304 for (k = 0; k < sym->nRegs; k++)
2307 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2313 /*-----------------------------------------------------------------*/
2314 /* rematStr - returns the rematerialized string for a remat var */
2315 /*-----------------------------------------------------------------*/
2317 rematStr (symbol * sym)
2320 iCode *ic = sym->rematiCode;
2321 symbol *psym = NULL;
2323 debugLog ("%s\n", __FUNCTION__);
2325 //printf ("%s\n", s);
2327 /* if plus or minus print the right hand side */
2329 if (ic->op == '+' || ic->op == '-') {
2331 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2333 sprintf (s, "(%s %c 0x%04x)",
2334 OP_SYMBOL (IC_LEFT (ric))->rname,
2336 (int) operandLitValue (IC_RIGHT (ic)));
2339 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2341 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2342 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2347 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2348 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2350 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2355 /*-----------------------------------------------------------------*/
2356 /* rematStr - returns the rematerialized string for a remat var */
2357 /*-----------------------------------------------------------------*/
2359 rematStr (symbol * sym)
2362 iCode *ic = sym->rematiCode;
2364 debugLog ("%s\n", __FUNCTION__);
2369 /* if plus or minus print the right hand side */
2371 if (ic->op == '+' || ic->op == '-') {
2372 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2375 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2379 if (ic->op == '+' || ic->op == '-')
2381 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2382 sprintf (s, "(%s %c 0x%04x)",
2383 OP_SYMBOL (IC_LEFT (ric))->rname,
2385 (int) operandLitValue (IC_RIGHT (ic)));
2388 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2390 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2394 /* we reached the end */
2395 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2399 printf ("%s\n", buffer);
2404 /*-----------------------------------------------------------------*/
2405 /* regTypeNum - computes the type & number of registers required */
2406 /*-----------------------------------------------------------------*/
2414 debugLog ("%s\n", __FUNCTION__);
2415 /* for each live range do */
2416 for (sym = hTabFirstItem (liveRanges, &k); sym;
2417 sym = hTabNextItem (liveRanges, &k)) {
2419 debugLog (" %d - %s\n", __LINE__, sym->rname);
2421 /* if used zero times then no registers needed */
2422 if ((sym->liveTo - sym->liveFrom) == 0)
2426 /* if the live range is a temporary */
2429 debugLog (" %d - itemp register\n", __LINE__);
2431 /* if the type is marked as a conditional */
2432 if (sym->regType == REG_CND)
2435 /* if used in return only then we don't
2437 if (sym->ruonly || sym->accuse) {
2438 if (IS_AGGREGATE (sym->type) || sym->isptr)
2439 sym->type = aggrToPtr (sym->type, FALSE);
2440 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
2445 /* if the symbol has only one definition &
2446 that definition is a get_pointer and the
2447 pointer we are getting is rematerializable and
2450 if (bitVectnBitsOn (sym->defs) == 1 &&
2451 (ic = hTabItemWithKey (iCodehTab,
2452 bitVectFirstBit (sym->defs))) &&
2455 !IS_BITVAR (sym->etype)) {
2458 debugLog (" %d - \n", __LINE__);
2460 /* if remat in data space */
2461 if (OP_SYMBOL (IC_LEFT (ic))->remat &&
2462 DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) {
2464 /* create a psuedo symbol & force a spil */
2465 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2466 symbol *psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2467 psym->type = sym->type;
2468 psym->etype = sym->etype;
2469 strcpy (psym->rname, psym->name);
2471 sym->usl.spillLoc = psym;
2475 /* if in data space or idata space then try to
2476 allocate pointer register */
2480 /* if not then we require registers */
2481 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2482 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2483 getSize (sym->type));
2486 if(IS_PTR_CONST (sym->type)) {
2487 debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2491 if (sym->nRegs > 4) {
2492 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2493 printTypeChain (sym->type, stderr);
2494 fprintf (stderr, "\n");
2497 /* determine the type of register required */
2498 if (sym->nRegs == 1 &&
2499 IS_PTR (sym->type) &&
2501 sym->regType = REG_PTR;
2503 sym->regType = REG_GPR;
2506 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2510 /* for the first run we don't provide */
2511 /* registers for true symbols we will */
2512 /* see how things go */
2517 DEFSETFUNC (markRegFree)
2519 ((regs *)item)->isFree = 1;
2524 DEFSETFUNC (deallocReg)
2526 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2527 ((regs *)item)->isFree = 1;
2528 ((regs *)item)->wasUsed = 0;
2532 /*-----------------------------------------------------------------*/
2533 /* freeAllRegs - mark all registers as free */
2534 /*-----------------------------------------------------------------*/
2536 pic14_freeAllRegs ()
2540 debugLog ("%s\n", __FUNCTION__);
2542 applyToSet(dynAllocRegs,markRegFree);
2543 applyToSet(dynStackRegs,markRegFree);
2546 for (i = 0; i < pic14_nRegs; i++)
2547 regspic14[i].isFree = 1;
2551 /*-----------------------------------------------------------------*/
2552 /*-----------------------------------------------------------------*/
2554 pic14_deallocateAllRegs ()
2558 debugLog ("%s\n", __FUNCTION__);
2560 applyToSet(dynAllocRegs,deallocReg);
2563 for (i = 0; i < pic14_nRegs; i++) {
2564 if(regspic14[i].pc_type == PO_GPR_TEMP) {
2565 regspic14[i].isFree = 1;
2566 regspic14[i].wasUsed = 0;
2573 /*-----------------------------------------------------------------*/
2574 /* deallocStackSpil - this will set the stack pointer back */
2575 /*-----------------------------------------------------------------*/
2577 DEFSETFUNC (deallocStackSpil)
2581 debugLog ("%s\n", __FUNCTION__);
2586 /*-----------------------------------------------------------------*/
2587 /* farSpacePackable - returns the packable icode for far variables */
2588 /*-----------------------------------------------------------------*/
2590 farSpacePackable (iCode * ic)
2594 debugLog ("%s\n", __FUNCTION__);
2595 /* go thru till we find a definition for the
2596 symbol on the right */
2597 for (dic = ic->prev; dic; dic = dic->prev)
2600 /* if the definition is a call then no */
2601 if ((dic->op == CALL || dic->op == PCALL) &&
2602 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2607 /* if shift by unknown amount then not */
2608 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2609 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2612 /* if pointer get and size > 1 */
2613 if (POINTER_GET (dic) &&
2614 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2617 if (POINTER_SET (dic) &&
2618 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2621 /* if any three is a true symbol in far space */
2622 if (IC_RESULT (dic) &&
2623 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2624 isOperandInFarSpace (IC_RESULT (dic)))
2627 if (IC_RIGHT (dic) &&
2628 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2629 isOperandInFarSpace (IC_RIGHT (dic)) &&
2630 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2633 if (IC_LEFT (dic) &&
2634 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2635 isOperandInFarSpace (IC_LEFT (dic)) &&
2636 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2639 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2641 if ((dic->op == LEFT_OP ||
2642 dic->op == RIGHT_OP ||
2644 IS_OP_LITERAL (IC_RIGHT (dic)))
2654 /*-----------------------------------------------------------------*/
2655 /* packRegsForAssign - register reduction for assignment */
2656 /*-----------------------------------------------------------------*/
2658 packRegsForAssign (iCode * ic, eBBlock * ebp)
2663 debugLog ("%s\n", __FUNCTION__);
2665 debugAopGet (" result:", IC_RESULT (ic));
2666 debugAopGet (" left:", IC_LEFT (ic));
2667 debugAopGet (" right:", IC_RIGHT (ic));
2669 /* if this is at an absolute address, then get the address. */
2670 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2671 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2672 debugLog (" %d - found config word declaration\n", __LINE__);
2673 if(IS_VALOP(IC_RIGHT(ic))) {
2674 debugLog (" setting config word to %x\n",
2675 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2676 assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2677 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2680 /* remove the assignment from the iCode chain. */
2682 remiCodeFromeBBlock (ebp, ic);
2683 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2684 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2691 if (!IS_ITEMP (IC_RESULT (ic))) {
2692 allocDirReg(IC_RESULT (ic));
2693 debugLog (" %d - result is not temp\n", __LINE__);
2696 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2697 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2698 allocDirReg(IC_LEFT (ic));
2702 if (!IS_ITEMP (IC_RIGHT (ic))) {
2703 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2704 allocDirReg(IC_RIGHT (ic));
2708 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2709 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2711 debugLog (" %d - not packing - right side fails \n", __LINE__);
2715 /* if the true symbol is defined in far space or on stack
2716 then we should not since this will increase register pressure */
2717 if (isOperandInFarSpace (IC_RESULT (ic)))
2719 if ((dic = farSpacePackable (ic)))
2725 /* find the definition of iTempNN scanning backwards if we find a
2726 a use of the true symbol before we find the definition then
2728 for (dic = ic->prev; dic; dic = dic->prev)
2731 /* if there is a function call and this is
2732 a parameter & not my parameter then don't pack it */
2733 if ((dic->op == CALL || dic->op == PCALL) &&
2734 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2735 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2737 debugLog (" %d - \n", __LINE__);
2745 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2746 IS_OP_VOLATILE (IC_RESULT (dic)))
2748 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2753 if (IS_SYMOP (IC_RESULT (dic)) &&
2754 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2756 /* A previous result was assigned to the same register - we'll our definition */
2757 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2758 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2759 if (POINTER_SET (dic))
2765 if (IS_SYMOP (IC_RIGHT (dic)) &&
2766 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2767 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2769 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
2774 if (IS_SYMOP (IC_LEFT (dic)) &&
2775 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2776 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2778 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
2783 if (POINTER_SET (dic) &&
2784 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2786 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
2794 return 0; /* did not find */
2796 /* if the result is on stack or iaccess then it must be
2797 the same atleast one of the operands */
2798 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2799 OP_SYMBOL (IC_RESULT (ic))->iaccess)
2802 /* the operation has only one symbol
2803 operator then we can pack */
2804 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2805 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2808 if (!((IC_LEFT (dic) &&
2809 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2811 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2815 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2816 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
2817 /* found the definition */
2818 /* replace the result with the result of */
2819 /* this assignment and remove this assignment */
2820 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2821 IC_RESULT (dic) = IC_RESULT (ic);
2823 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2825 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2827 /* delete from liverange table also
2828 delete from all the points inbetween and the new
2830 for (sic = dic; sic != ic; sic = sic->next)
2832 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2833 if (IS_ITEMP (IC_RESULT (dic)))
2834 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2837 remiCodeFromeBBlock (ebp, ic);
2838 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2839 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2840 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2846 /*-----------------------------------------------------------------*/
2847 /* findAssignToSym : scanning backwards looks for first assig found */
2848 /*-----------------------------------------------------------------*/
2850 findAssignToSym (operand * op, iCode * ic)
2854 debugLog ("%s\n", __FUNCTION__);
2855 for (dic = ic->prev; dic; dic = dic->prev)
2858 /* if definition by assignment */
2859 if (dic->op == '=' &&
2860 !POINTER_SET (dic) &&
2861 IC_RESULT (dic)->key == op->key
2862 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2866 /* we are interested only if defined in far space */
2867 /* or in stack space in case of + & - */
2869 /* if assigned to a non-symbol then return
2871 if (!IS_SYMOP (IC_RIGHT (dic)))
2874 /* if the symbol is in far space then
2876 if (isOperandInFarSpace (IC_RIGHT (dic)))
2879 /* for + & - operations make sure that
2880 if it is on the stack it is the same
2881 as one of the three operands */
2882 if ((ic->op == '+' || ic->op == '-') &&
2883 OP_SYMBOL (IC_RIGHT (dic))->onStack)
2886 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2887 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2888 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2896 /* if we find an usage then we cannot delete it */
2897 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2900 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2903 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2907 /* now make sure that the right side of dic
2908 is not defined between ic & dic */
2911 iCode *sic = dic->next;
2913 for (; sic != ic; sic = sic->next)
2914 if (IC_RESULT (sic) &&
2915 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2924 /*-----------------------------------------------------------------*/
2925 /* packRegsForSupport :- reduce some registers for support calls */
2926 /*-----------------------------------------------------------------*/
2928 packRegsForSupport (iCode * ic, eBBlock * ebp)
2932 debugLog ("%s\n", __FUNCTION__);
2933 /* for the left & right operand :- look to see if the
2934 left was assigned a true symbol in far space in that
2935 case replace them */
2936 if (IS_ITEMP (IC_LEFT (ic)) &&
2937 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2939 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
2945 debugAopGet ("removing left:", IC_LEFT (ic));
2947 /* found it we need to remove it from the
2949 for (sic = dic; sic != ic; sic = sic->next)
2950 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
2952 IC_LEFT (ic)->operand.symOperand =
2953 IC_RIGHT (dic)->operand.symOperand;
2954 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2955 remiCodeFromeBBlock (ebp, dic);
2956 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2957 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2961 /* do the same for the right operand */
2964 IS_ITEMP (IC_RIGHT (ic)) &&
2965 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2967 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2973 /* if this is a subtraction & the result
2974 is a true symbol in far space then don't pack */
2975 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
2977 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
2978 if (IN_FARSPACE (SPEC_OCLS (etype)))
2982 debugAopGet ("removing right:", IC_RIGHT (ic));
2984 /* found it we need to remove it from the
2986 for (sic = dic; sic != ic; sic = sic->next)
2987 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
2989 IC_RIGHT (ic)->operand.symOperand =
2990 IC_RIGHT (dic)->operand.symOperand;
2991 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2993 remiCodeFromeBBlock (ebp, dic);
2994 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2995 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3002 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3005 /*-----------------------------------------------------------------*/
3006 /* packRegsForOneuse : - will reduce some registers for single Use */
3007 /*-----------------------------------------------------------------*/
3009 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3014 debugLog ("%s\n", __FUNCTION__);
3015 /* if returning a literal then do nothing */
3019 /* only upto 2 bytes since we cannot predict
3020 the usage of b, & acc */
3021 if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
3026 /* this routine will mark the a symbol as used in one
3027 instruction use only && if the definition is local
3028 (ie. within the basic block) && has only one definition &&
3029 that definition is either a return value from a
3030 function or does not contain any variables in
3032 uses = bitVectCopy (OP_USES (op));
3033 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3034 if (!bitVectIsZero (uses)) /* has other uses */
3037 /* if it has only one defintion */
3038 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3039 return NULL; /* has more than one definition */
3041 /* get that definition */
3043 hTabItemWithKey (iCodehTab,
3044 bitVectFirstBit (OP_DEFS (op)))))
3047 /* found the definition now check if it is local */
3048 if (dic->seq < ebp->fSeq ||
3049 dic->seq > ebp->lSeq)
3050 return NULL; /* non-local */
3052 /* now check if it is the return from
3054 if (dic->op == CALL || dic->op == PCALL)
3056 if (ic->op != SEND && ic->op != RETURN &&
3057 !POINTER_SET(ic) && !POINTER_GET(ic))
3059 OP_SYMBOL (op)->ruonly = 1;
3066 /* otherwise check that the definition does
3067 not contain any symbols in far space */
3068 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3069 isOperandInFarSpace (IC_RIGHT (dic)) ||
3070 IS_OP_RUONLY (IC_LEFT (ic)) ||
3071 IS_OP_RUONLY (IC_RIGHT (ic)))
3076 /* if pointer set then make sure the pointer
3078 if (POINTER_SET (dic) &&
3079 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3082 if (POINTER_GET (dic) &&
3083 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3088 /* also make sure the intervenening instructions
3089 don't have any thing in far space */
3090 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3093 /* if there is an intervening function call then no */
3094 if (dic->op == CALL || dic->op == PCALL)
3096 /* if pointer set then make sure the pointer
3098 if (POINTER_SET (dic) &&
3099 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3102 if (POINTER_GET (dic) &&
3103 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3106 /* if address of & the result is remat then okay */
3107 if (dic->op == ADDRESS_OF &&
3108 OP_SYMBOL (IC_RESULT (dic))->remat)
3111 /* if operand has size of three or more & this
3112 operation is a '*','/' or '%' then 'b' may
3114 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3115 getSize (operandType (op)) >= 3)
3118 /* if left or right or result is in far space */
3119 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3120 isOperandInFarSpace (IC_RIGHT (dic)) ||
3121 isOperandInFarSpace (IC_RESULT (dic)) ||
3122 IS_OP_RUONLY (IC_LEFT (dic)) ||
3123 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3124 IS_OP_RUONLY (IC_RESULT (dic)))
3130 OP_SYMBOL (op)->ruonly = 1;
3135 /*-----------------------------------------------------------------*/
3136 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3137 /*-----------------------------------------------------------------*/
3139 isBitwiseOptimizable (iCode * ic)
3141 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3142 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3144 debugLog ("%s\n", __FUNCTION__);
3145 /* bitwise operations are considered optimizable
3146 under the following conditions (Jean-Louis VERN)
3158 if (IS_LITERAL (rtype) ||
3159 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3165 /*-----------------------------------------------------------------*/
3166 /* packRegsForAccUse - pack registers for acc use */
3167 /*-----------------------------------------------------------------*/
3169 packRegsForAccUse (iCode * ic)
3173 debugLog ("%s\n", __FUNCTION__);
3175 /* if this is an aggregate, e.g. a one byte char array */
3176 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3179 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3181 /* if + or - then it has to be one byte result */
3182 if ((ic->op == '+' || ic->op == '-')
3183 && getSize (operandType (IC_RESULT (ic))) > 1)
3186 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3187 /* if shift operation make sure right side is not a literal */
3188 if (ic->op == RIGHT_OP &&
3189 (isOperandLiteral (IC_RIGHT (ic)) ||
3190 getSize (operandType (IC_RESULT (ic))) > 1))
3193 if (ic->op == LEFT_OP &&
3194 (isOperandLiteral (IC_RIGHT (ic)) ||
3195 getSize (operandType (IC_RESULT (ic))) > 1))
3198 if (IS_BITWISE_OP (ic) &&
3199 getSize (operandType (IC_RESULT (ic))) > 1)
3203 /* has only one definition */
3204 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3207 /* has only one use */
3208 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3211 /* and the usage immediately follows this iCode */
3212 if (!(uic = hTabItemWithKey (iCodehTab,
3213 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3216 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3217 if (ic->next != uic)
3220 /* if it is a conditional branch then we definitely can */
3224 if (uic->op == JUMPTABLE)
3227 /* if the usage is not is an assignment
3228 or an arithmetic / bitwise / shift operation then not */
3229 if (POINTER_SET (uic) &&
3230 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3233 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3234 if (uic->op != '=' &&
3235 !IS_ARITHMETIC_OP (uic) &&
3236 !IS_BITWISE_OP (uic) &&
3237 uic->op != LEFT_OP &&
3238 uic->op != RIGHT_OP)
3241 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3242 /* if used in ^ operation then make sure right is not a
3244 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3247 /* if shift operation make sure right side is not a literal */
3248 if (uic->op == RIGHT_OP &&
3249 (isOperandLiteral (IC_RIGHT (uic)) ||
3250 getSize (operandType (IC_RESULT (uic))) > 1))
3253 if (uic->op == LEFT_OP &&
3254 (isOperandLiteral (IC_RIGHT (uic)) ||
3255 getSize (operandType (IC_RESULT (uic))) > 1))
3258 /* make sure that the result of this icode is not on the
3259 stack, since acc is used to compute stack offset */
3260 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3261 OP_SYMBOL (IC_RESULT (uic))->onStack)
3264 /* if either one of them in far space then we cannot */
3265 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3266 isOperandInFarSpace (IC_LEFT (uic))) ||
3267 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3268 isOperandInFarSpace (IC_RIGHT (uic))))
3271 /* if the usage has only one operand then we can */
3272 if (IC_LEFT (uic) == NULL ||
3273 IC_RIGHT (uic) == NULL)
3276 /* make sure this is on the left side if not
3277 a '+' since '+' is commutative */
3278 if (ic->op != '+' &&
3279 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3282 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3283 /* if one of them is a literal then we can */
3284 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3285 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3286 (getSize (operandType (IC_RESULT (uic))) <= 1))
3288 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3292 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3293 /* if the other one is not on stack then we can */
3294 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3295 (IS_ITEMP (IC_RIGHT (uic)) ||
3296 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3297 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3300 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3301 (IS_ITEMP (IC_LEFT (uic)) ||
3302 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3303 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3309 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3310 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3315 /*-----------------------------------------------------------------*/
3316 /* packForPush - hueristics to reduce iCode for pushing */
3317 /*-----------------------------------------------------------------*/
3319 packForReceive (iCode * ic, eBBlock * ebp)
3323 debugLog ("%s\n", __FUNCTION__);
3324 debugAopGet (" result:", IC_RESULT (ic));
3325 debugAopGet (" left:", IC_LEFT (ic));
3326 debugAopGet (" right:", IC_RIGHT (ic));
3331 for (dic = ic->next; dic; dic = dic->next)
3336 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3337 debugLog (" used on left\n");
3338 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3339 debugLog (" used on right\n");
3340 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3341 debugLog (" used on result\n");
3343 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3344 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3349 debugLog (" hey we can remove this unnecessary assign\n");
3351 /*-----------------------------------------------------------------*/
3352 /* packForPush - hueristics to reduce iCode for pushing */
3353 /*-----------------------------------------------------------------*/
3355 packForPush (iCode * ic, eBBlock * ebp)
3359 debugLog ("%s\n", __FUNCTION__);
3360 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3363 /* must have only definition & one usage */
3364 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3365 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3368 /* find the definition */
3369 if (!(dic = hTabItemWithKey (iCodehTab,
3370 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3373 if (dic->op != '=' || POINTER_SET (dic))
3376 /* we now we know that it has one & only one def & use
3377 and the that the definition is an assignment */
3378 IC_LEFT (ic) = IC_RIGHT (dic);
3380 remiCodeFromeBBlock (ebp, dic);
3381 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3382 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3385 void printSymType(char * str, sym_link *sl)
3387 debugLog (" %s Symbol type: ",str);
3388 printTypeChain( sl, debugF);
3393 /*-----------------------------------------------------------------*/
3394 /* packRegisters - does some transformations to reduce register */
3396 /*-----------------------------------------------------------------*/
3398 packRegisters (eBBlock * ebp)
3403 debugLog ("%s\n", __FUNCTION__);
3409 /* look for assignments of the form */
3410 /* iTempNN = TRueSym (someoperation) SomeOperand */
3412 /* TrueSym := iTempNN:1 */
3413 for (ic = ebp->sch; ic; ic = ic->next)
3416 /* find assignment of the form TrueSym := iTempNN:1 */
3417 if (ic->op == '=' && !POINTER_SET (ic))
3418 change += packRegsForAssign (ic, ebp);
3422 if (POINTER_SET (ic))
3423 debugLog ("pointer is set\n");
3424 debugAopGet (" result:", IC_RESULT (ic));
3425 debugAopGet (" left:", IC_LEFT (ic));
3426 debugAopGet (" right:", IC_RIGHT (ic));
3435 for (ic = ebp->sch; ic; ic = ic->next) {
3437 if(IS_SYMOP ( IC_LEFT(ic))) {
3438 //sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3440 debugAopGet (" left:", IC_LEFT (ic));
3441 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3442 debugLog (" is a pointer");
3444 printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
3447 if(IS_SYMOP ( IC_RIGHT(ic))) {
3448 debugAopGet (" right:", IC_RIGHT (ic));
3449 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3452 if(IS_SYMOP ( IC_RESULT(ic))) {
3453 debugAopGet (" result:", IC_RESULT (ic));
3454 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3457 if (POINTER_SET (ic))
3458 debugLog (" %d - Pointer set\n", __LINE__);
3461 /* if this is an itemp & result of a address of a true sym
3462 then mark this as rematerialisable */
3463 if (ic->op == ADDRESS_OF &&
3464 IS_ITEMP (IC_RESULT (ic)) &&
3465 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3466 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3467 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3470 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3472 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3473 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3474 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3478 /* if straight assignment then carry remat flag if
3479 this is the only definition */
3480 if (ic->op == '=' &&
3481 !POINTER_SET (ic) &&
3482 IS_SYMOP (IC_RIGHT (ic)) &&
3483 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3484 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3486 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3488 OP_SYMBOL (IC_RESULT (ic))->remat =
3489 OP_SYMBOL (IC_RIGHT (ic))->remat;
3490 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3491 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3494 /* if this is a +/- operation with a rematerizable
3495 then mark this as rematerializable as well */
3496 if ((ic->op == '+' || ic->op == '-') &&
3497 (IS_SYMOP (IC_LEFT (ic)) &&
3498 IS_ITEMP (IC_RESULT (ic)) &&
3499 OP_SYMBOL (IC_LEFT (ic))->remat &&
3500 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3501 IS_OP_LITERAL (IC_RIGHT (ic))))
3503 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3505 operandLitValue (IC_RIGHT (ic));
3506 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3507 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3508 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3511 /* mark the pointer usages */
3512 if (POINTER_SET (ic))
3514 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3515 debugLog (" marking as a pointer (set) =>");
3516 debugAopGet (" result:", IC_RESULT (ic));
3518 if (POINTER_GET (ic))
3520 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3521 debugLog (" marking as a pointer (get) =>");
3522 debugAopGet (" left:", IC_LEFT (ic));
3527 /* if we are using a symbol on the stack
3528 then we should say pic14_ptrRegReq */
3529 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3530 pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3531 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3532 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3533 pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3534 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3537 if (IS_SYMOP (IC_LEFT (ic)))
3538 pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3539 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3540 if (IS_SYMOP (IC_RIGHT (ic)))
3541 pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3542 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3543 if (IS_SYMOP (IC_RESULT (ic)))
3544 pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3545 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3548 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
3552 /* if the condition of an if instruction
3553 is defined in the previous instruction then
3554 mark the itemp as a conditional */
3555 if ((IS_CONDITIONAL (ic) ||
3556 ((ic->op == BITWISEAND ||
3559 isBitwiseOptimizable (ic))) &&
3560 ic->next && ic->next->op == IFX &&
3561 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3562 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3565 debugLog (" %d\n", __LINE__);
3566 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3570 /* reduce for support function calls */
3571 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3572 packRegsForSupport (ic, ebp);
3574 /* if a parameter is passed, it's in W, so we may not
3575 need to place a copy in a register */
3576 if (ic->op == RECEIVE)
3577 packForReceive (ic, ebp);
3579 /* some cases the redundant moves can
3580 can be eliminated for return statements */
3581 if ((ic->op == RETURN || ic->op == SEND) &&
3582 !isOperandInFarSpace (IC_LEFT (ic)) &&
3584 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3586 /* if pointer set & left has a size more than
3587 one and right is not in far space */
3588 if (POINTER_SET (ic) &&
3589 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3590 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3591 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3592 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3594 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3596 /* if pointer get */
3597 if (POINTER_GET (ic) &&
3598 !isOperandInFarSpace (IC_RESULT (ic)) &&
3599 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3600 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3601 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3603 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3606 /* if this is cast for intergral promotion then
3607 check if only use of the definition of the
3608 operand being casted/ if yes then replace
3609 the result of that arithmetic operation with
3610 this result and get rid of the cast */
3611 if (ic->op == CAST) {
3613 sym_link *fromType = operandType (IC_RIGHT (ic));
3614 sym_link *toType = operandType (IC_LEFT (ic));
3616 debugLog (" %d - casting\n", __LINE__);
3618 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3619 getSize (fromType) != getSize (toType)) {
3622 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3625 if (IS_ARITHMETIC_OP (dic)) {
3627 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3628 IC_RESULT (dic) = IC_RESULT (ic);
3629 remiCodeFromeBBlock (ebp, ic);
3630 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3631 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3632 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3636 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3640 /* if the type from and type to are the same
3641 then if this is the only use then packit */
3642 if (compareType (operandType (IC_RIGHT (ic)),
3643 operandType (IC_LEFT (ic))) == 1) {
3645 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3648 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3649 IC_RESULT (dic) = IC_RESULT (ic);
3650 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3651 remiCodeFromeBBlock (ebp, ic);
3652 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3653 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3661 iTempNN := (some variable in farspace) V1
3666 if (ic->op == IPUSH)
3668 packForPush (ic, ebp);
3672 /* pack registers for accumulator use, when the
3673 result of an arithmetic or bit wise operation
3674 has only one use, that use is immediately following
3675 the defintion and the using iCode has only one
3676 operand or has two operands but one is literal &
3677 the result of that operation is not on stack then
3678 we can leave the result of this operation in acc:b
3680 if ((IS_ARITHMETIC_OP (ic)
3682 || IS_BITWISE_OP (ic)
3684 || ic->op == LEFT_OP || ic->op == RIGHT_OP
3687 IS_ITEMP (IC_RESULT (ic)) &&
3688 getSize (operandType (IC_RESULT (ic))) <= 2)
3690 packRegsForAccUse (ic);
3696 dumpEbbsToDebug (eBBlock ** ebbs, int count)
3700 if (!debug || !debugF)
3703 for (i = 0; i < count; i++)
3705 fprintf (debugF, "\n----------------------------------------------------------------\n");
3706 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
3707 ebbs[i]->entryLabel->name,
3710 ebbs[i]->isLastInLoop);
3711 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
3716 fprintf (debugF, "visited %d : hasFcall = %d\n",
3720 fprintf (debugF, "\ndefines bitVector :");
3721 bitVectDebugOn (ebbs[i]->defSet, debugF);
3722 fprintf (debugF, "\nlocal defines bitVector :");
3723 bitVectDebugOn (ebbs[i]->ldefs, debugF);
3724 fprintf (debugF, "\npointers Set bitvector :");
3725 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
3726 fprintf (debugF, "\nin pointers Set bitvector :");
3727 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
3728 fprintf (debugF, "\ninDefs Set bitvector :");
3729 bitVectDebugOn (ebbs[i]->inDefs, debugF);
3730 fprintf (debugF, "\noutDefs Set bitvector :");
3731 bitVectDebugOn (ebbs[i]->outDefs, debugF);
3732 fprintf (debugF, "\nusesDefs Set bitvector :");
3733 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
3734 fprintf (debugF, "\n----------------------------------------------------------------\n");
3735 printiCChain (ebbs[i]->sch, debugF);
3738 /*-----------------------------------------------------------------*/
3739 /* assignRegisters - assigns registers to each live range as need */
3740 /*-----------------------------------------------------------------*/
3742 pic14_assignRegisters (eBBlock ** ebbs, int count)
3747 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
3748 debugLog ("\nebbs before optimizing:\n");
3749 dumpEbbsToDebug (ebbs, count);
3751 setToNull ((void *) &_G.funcrUsed);
3752 pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3755 /* change assignments this will remove some
3756 live ranges reducing some register pressure */
3757 for (i = 0; i < count; i++)
3758 packRegisters (ebbs[i]);
3765 debugLog("dir registers allocated so far:\n");
3766 reg = hTabFirstItem(dynDirectRegNames, &hkey);
3769 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
3770 reg = hTabNextItem(dynDirectRegNames, &hkey);
3775 if (options.dump_pack)
3776 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3778 /* first determine for each live range the number of
3779 registers & the type of registers required for each */
3782 /* and serially allocate registers */
3783 serialRegAssign (ebbs, count);
3785 /* if stack was extended then tell the user */
3788 /* werror(W_TOOMANY_SPILS,"stack", */
3789 /* _G.stackExtend,currFunc->name,""); */
3795 /* werror(W_TOOMANY_SPILS,"data space", */
3796 /* _G.dataExtend,currFunc->name,""); */
3800 /* after that create the register mask
3801 for each of the instruction */
3802 createRegMask (ebbs, count);
3804 /* redo that offsets for stacked automatic variables */
3805 redoStackOffsets ();
3807 if (options.dump_rassgn)
3808 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3810 /* now get back the chain */
3811 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3813 debugLog ("ebbs after optimizing:\n");
3814 dumpEbbsToDebug (ebbs, count);
3819 /* free up any _G.stackSpil locations allocated */
3820 applyToSet (_G.stackSpil, deallocStackSpil);
3822 setToNull ((void **) &_G.stackSpil);
3823 setToNull ((void **) &_G.spiltSet);
3824 /* mark all registers as free */
3825 //pic14_freeAllRegs ();
3827 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");