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));
527 allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
530 //fprintf(stderr,"allocProcessorRegister %s addr =0x%x\n",name,rIdx);
531 return addSet(&dynProcessorRegs,newReg(REG_SFR, po_type, rIdx, name,1,alias));
535 allocInternalRegister(int rIdx, char * name, short po_type, int alias)
537 regs * reg = newReg(REG_SFR, po_type, rIdx, name,1,alias);
539 //fprintf(stderr,"allocInternalRegister %s addr =0x%x\n",name,rIdx);
542 return addSet(&dynInternalRegs,reg);
547 /*-----------------------------------------------------------------*/
548 /* allocReg - allocates register of given type */
549 /*-----------------------------------------------------------------*/
551 allocReg (short type)
554 debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
555 //fprintf(stderr,"allocReg\n");
558 return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
563 /*-----------------------------------------------------------------*/
564 /* dirregWithName - search for register by name */
565 /*-----------------------------------------------------------------*/
567 dirregWithName (char *name)
575 /* hash the name to get a key */
577 hkey = regname2key(name);
579 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
583 if(STRCASECMP(reg->name, name) == 0) {
587 reg = hTabNextItemWK (dynDirectRegNames);
591 return NULL; // name wasn't found in the hash table
594 int IS_CONFIG_ADDRESS(int address)
597 return address == 0x2007;
600 /*-----------------------------------------------------------------*/
601 /* allocDirReg - allocates register of given type */
602 /*-----------------------------------------------------------------*/
604 allocDirReg (operand *op )
611 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
615 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
617 /* If the symbol is at a fixed address, then remove the leading underscore
618 * from the name. This is hack to allow the .asm include file named registers
619 * to match the .c declared register names */
621 //if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && (*name == '_'))
624 debugLog ("%s symbol name %s\n", __FUNCTION__,name);
626 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
627 debugLog(" %d const char\n",__LINE__);
628 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
631 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
632 if (IS_CODE ( OP_SYM_ETYPE(op)) )
633 debugLog(" %d code space\n",__LINE__);
635 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
636 debugLog(" %d integral\n",__LINE__);
637 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
638 debugLog(" %d literal\n",__LINE__);
639 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
640 debugLog(" %d specifier\n",__LINE__);
641 debugAopGet(NULL, op);
644 if (IS_CODE ( OP_SYM_ETYPE(op)) )
647 /* First, search the hash table to see if there is a register with this name */
648 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && !(IS_BITVAR (OP_SYM_ETYPE(op))) ) {
649 reg = regWithIdx (dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1);
652 fprintf(stderr,"ralloc %s is at fixed address but not a processor reg, addr=0x%x\n",
653 name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
655 fprintf(stderr,"ralloc %s at fixed address has already been declared, addr=0x%x\n",
656 name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
659 //fprintf(stderr,"ralloc %s \n", name);
661 reg = dirregWithName(name);
667 /* if this is at an absolute address, then get the address. */
668 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
669 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
672 /* Register wasn't found in hash, so let's create
673 * a new one and put it in the hash table AND in the
674 * dynDirectRegNames set */
675 if(!IS_CONFIG_ADDRESS(address)) {
676 //fprintf(stderr,"allocating new reg %s\n",name);
678 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0 );
679 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
681 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
683 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
685 //fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
689 if (IS_BITVAR (OP_SYM_ETYPE(op)))
690 addSet(&dynDirectBitRegs, reg);
692 addSet(&dynDirectRegs, reg);
695 debugLog (" -- %s is declared at address 0x2007\n",name);
700 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
702 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
703 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
709 /*-----------------------------------------------------------------*/
710 /* allocDirReg - allocates register of given type */
711 /*-----------------------------------------------------------------*/
713 allocRegByName (char *name, int size)
719 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
723 /* First, search the hash table to see if there is a register with this name */
724 reg = dirregWithName(name);
728 /* Register wasn't found in hash, so let's create
729 * a new one and put it in the hash table AND in the
730 * dynDirectRegNames set */
731 //fprintf (stderr,"%s symbol name %s\n", __FUNCTION__,name);
732 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0 );
734 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
736 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
737 addSet(&dynDirectRegs, reg);
743 /*-----------------------------------------------------------------*/
744 /* RegWithIdx - returns pointer to register with index number */
745 /*-----------------------------------------------------------------*/
747 typeRegWithIdx (int idx, int type, int fixed)
752 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
757 if( (dReg = regWithIdx ( dynAllocRegs, idx, fixed)) != NULL) {
759 debugLog ("Found a Dynamic Register!\n");
762 if( (dReg = regWithIdx ( dynDirectRegs, idx, fixed)) != NULL ) {
763 debugLog ("Found a Direct Register!\n");
769 if( (dReg = regWithIdx ( dynStackRegs, idx, fixed)) != NULL ) {
770 debugLog ("Found a Stack Register!\n");
775 if( (dReg = regWithIdx ( dynProcessorRegs, idx, fixed)) != NULL ) {
776 debugLog ("Found a Processor Register!\n");
790 /*-----------------------------------------------------------------*/
791 /* pic14_regWithIdx - returns pointer to register with index number*/
792 /*-----------------------------------------------------------------*/
794 pic14_regWithIdx (int idx)
798 if( (dReg = typeRegWithIdx(idx,REG_GPR,0)) != NULL)
801 if( (dReg = typeRegWithIdx(idx,REG_SFR,0)) != NULL)
804 if( (dReg = typeRegWithIdx(idx,REG_STK,0)) != NULL)
810 /*-----------------------------------------------------------------*/
811 /* pic14_regWithIdx - returns pointer to register with index number */
812 /*-----------------------------------------------------------------*/
814 pic14_allocWithIdx (int idx)
819 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
821 if( (dReg = regWithIdx ( dynAllocRegs, idx,0)) != NULL) {
823 debugLog ("Found a Dynamic Register!\n");
824 } else if( (dReg = regWithIdx ( dynStackRegs, idx,0)) != NULL ) {
825 debugLog ("Found a Stack Register!\n");
826 } else if( (dReg = regWithIdx ( dynProcessorRegs, idx,0)) != NULL ) {
827 debugLog ("Found a Processor Register!\n");
828 } else if( (dReg = regWithIdx ( dynInternalRegs, idx,0)) != NULL ) {
829 debugLog ("Found an Internal Register!\n");
832 debugLog ("Dynamic Register not found\n");
835 fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
836 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
837 "regWithIdx not found");
847 /*-----------------------------------------------------------------*/
848 /*-----------------------------------------------------------------*/
850 pic14_findFreeReg(short type)
857 if((dReg = regFindFree(dynAllocRegs)) != NULL)
859 //fprintf(stderr,"findfreereg\n");
860 return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
864 if((dReg = regFindFree(dynStackRegs)) != NULL)
876 /*-----------------------------------------------------------------*/
877 /* freeReg - frees a register */
878 /*-----------------------------------------------------------------*/
882 debugLog ("%s\n", __FUNCTION__);
887 /*-----------------------------------------------------------------*/
888 /* nFreeRegs - returns number of free registers */
889 /*-----------------------------------------------------------------*/
893 /* dynamically allocate as many as we need and worry about
894 * fitting them into a PIC later */
901 debugLog ("%s\n", __FUNCTION__);
902 for (i = 0; i < pic14_nRegs; i++)
903 if (regspic14[i].isFree && regspic14[i].type == type)
909 /*-----------------------------------------------------------------*/
910 /* nfreeRegsType - free registers with type */
911 /*-----------------------------------------------------------------*/
913 nfreeRegsType (int type)
916 debugLog ("%s\n", __FUNCTION__);
919 if ((nfr = nFreeRegs (type)) == 0)
920 return nFreeRegs (REG_GPR);
923 return nFreeRegs (type);
926 void writeSetUsedRegs(FILE *of, set *dRegs)
931 for (dReg = setFirstItem(dRegs) ; dReg ;
932 dReg = setNextItem(dRegs)) {
935 fprintf (of, "\t%s\n",dReg->name);
939 extern void assignFixedRegisters(set *regset);
940 extern void assignRelocatableRegisters(set *regset,int used);
941 extern void dump_map(void);
942 extern void dump_cblock(FILE *of);
945 void packBits(set *bregs)
950 regs *relocbitfield=NULL;
956 for (regset = bregs ; regset ;
957 regset = regset->next) {
960 breg->isBitField = 1;
961 //fprintf(stderr,"bit reg: %s\n",breg->name);
964 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
966 bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1);
967 breg->rIdx = breg->address & 7;
971 sprintf (buffer, "fbitfield%02x", breg->address);
972 //fprintf(stderr,"new bit field\n");
973 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0);
974 bitfield->isBitField = 1;
975 bitfield->isFixed = 1;
976 bitfield->address = breg->address;
977 addSet(&dynDirectRegs,bitfield);
978 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
980 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
983 breg->reg_alias = bitfield;
987 if(!relocbitfield || bit_no >7) {
990 sprintf (buffer, "bitfield%d", byte_no);
991 //fprintf(stderr,"new relocatable bit field\n");
992 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0);
993 relocbitfield->isBitField = 1;
994 addSet(&dynDirectRegs,relocbitfield);
995 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
999 breg->reg_alias = relocbitfield;
1000 breg->address = rDirectIdx; /* byte_no; */
1001 breg->rIdx = bit_no++;
1009 void bitEQUs(FILE *of, set *bregs)
1011 regs *breg,*bytereg;
1014 //fprintf(stderr," %s\n",__FUNCTION__);
1015 for (breg = setFirstItem(bregs) ; breg ;
1016 breg = setNextItem(bregs)) {
1018 //fprintf(stderr,"bit reg: %s\n",breg->name);
1020 bytereg = breg->reg_alias;
1022 fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
1025 breg->rIdx & 0x0007);
1028 fprintf(stderr, "bit field is not assigned to a register\n");
1029 fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
1039 void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
1044 for (reg = setFirstItem(fregs) ; reg ;
1045 reg = setNextItem(fregs)) {
1047 if(!reg->isEmitted && reg->wasUsed) {
1049 fprintf (of, "%s\tEQU\t0x%03x\n",
1053 fprintf (of, "%s\tEQU\t0x%03x\n",
1061 void writeUsedRegs(FILE *of)
1063 packBits(dynDirectBitRegs);
1065 assignFixedRegisters(dynAllocRegs);
1066 assignFixedRegisters(dynStackRegs);
1067 assignFixedRegisters(dynDirectRegs);
1069 assignRelocatableRegisters(dynInternalRegs,0);
1070 assignRelocatableRegisters(dynAllocRegs,0);
1071 assignRelocatableRegisters(dynStackRegs,0);
1072 assignRelocatableRegisters(dynDirectRegs,0);
1077 bitEQUs(of,dynDirectBitRegs);
1078 aliasEQUs(of,dynAllocRegs,0);
1079 aliasEQUs(of,dynDirectRegs,0);
1080 aliasEQUs(of,dynStackRegs,0);
1081 aliasEQUs(of,dynProcessorRegs,1);
1086 /*-----------------------------------------------------------------*/
1087 /* allDefsOutOfRange - all definitions are out of a range */
1088 /*-----------------------------------------------------------------*/
1090 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
1094 debugLog ("%s\n", __FUNCTION__);
1098 for (i = 0; i < defs->size; i++)
1102 if (bitVectBitValue (defs, i) &&
1103 (ic = hTabItemWithKey (iCodehTab, i)) &&
1104 (ic->seq >= fseq && ic->seq <= toseq))
1114 /*-----------------------------------------------------------------*/
1115 /* computeSpillable - given a point find the spillable live ranges */
1116 /*-----------------------------------------------------------------*/
1118 computeSpillable (iCode * ic)
1122 debugLog ("%s\n", __FUNCTION__);
1123 /* spillable live ranges are those that are live at this
1124 point . the following categories need to be subtracted
1126 a) - those that are already spilt
1127 b) - if being used by this one
1128 c) - defined by this one */
1130 spillable = bitVectCopy (ic->rlive);
1132 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1134 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1135 bitVectUnSetBit (spillable, ic->defKey);
1136 spillable = bitVectIntersect (spillable, _G.regAssigned);
1141 /*-----------------------------------------------------------------*/
1142 /* noSpilLoc - return true if a variable has no spil location */
1143 /*-----------------------------------------------------------------*/
1145 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1147 debugLog ("%s\n", __FUNCTION__);
1148 return (sym->usl.spillLoc ? 0 : 1);
1151 /*-----------------------------------------------------------------*/
1152 /* hasSpilLoc - will return 1 if the symbol has spil location */
1153 /*-----------------------------------------------------------------*/
1155 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1157 debugLog ("%s\n", __FUNCTION__);
1158 return (sym->usl.spillLoc ? 1 : 0);
1161 /*-----------------------------------------------------------------*/
1162 /* directSpilLoc - will return 1 if the splilocation is in direct */
1163 /*-----------------------------------------------------------------*/
1165 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1167 debugLog ("%s\n", __FUNCTION__);
1168 if (sym->usl.spillLoc &&
1169 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1175 /*-----------------------------------------------------------------*/
1176 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1177 /* but is not used as a pointer */
1178 /*-----------------------------------------------------------------*/
1180 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1182 debugLog ("%s\n", __FUNCTION__);
1183 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1186 /*-----------------------------------------------------------------*/
1187 /* rematable - will return 1 if the remat flag is set */
1188 /*-----------------------------------------------------------------*/
1190 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1192 debugLog ("%s\n", __FUNCTION__);
1196 /*-----------------------------------------------------------------*/
1197 /* notUsedInRemaining - not used or defined in remain of the block */
1198 /*-----------------------------------------------------------------*/
1200 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1202 debugLog ("%s\n", __FUNCTION__);
1203 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1204 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1207 /*-----------------------------------------------------------------*/
1208 /* allLRs - return true for all */
1209 /*-----------------------------------------------------------------*/
1211 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1213 debugLog ("%s\n", __FUNCTION__);
1217 /*-----------------------------------------------------------------*/
1218 /* liveRangesWith - applies function to a given set of live range */
1219 /*-----------------------------------------------------------------*/
1221 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1222 eBBlock * ebp, iCode * ic)
1227 debugLog ("%s\n", __FUNCTION__);
1228 if (!lrs || !lrs->size)
1231 for (i = 1; i < lrs->size; i++)
1234 if (!bitVectBitValue (lrs, i))
1237 /* if we don't find it in the live range
1238 hash table we are in serious trouble */
1239 if (!(sym = hTabItemWithKey (liveRanges, i)))
1241 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1242 "liveRangesWith could not find liveRange");
1246 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1247 addSetHead (&rset, sym);
1254 /*-----------------------------------------------------------------*/
1255 /* leastUsedLR - given a set determines which is the least used */
1256 /*-----------------------------------------------------------------*/
1258 leastUsedLR (set * sset)
1260 symbol *sym = NULL, *lsym = NULL;
1262 debugLog ("%s\n", __FUNCTION__);
1263 sym = lsym = setFirstItem (sset);
1268 for (; lsym; lsym = setNextItem (sset))
1271 /* if usage is the same then prefer
1272 the spill the smaller of the two */
1273 if (lsym->used == sym->used)
1274 if (getSize (lsym->type) < getSize (sym->type))
1278 if (lsym->used < sym->used)
1283 setToNull ((void **) &sset);
1288 /*-----------------------------------------------------------------*/
1289 /* noOverLap - will iterate through the list looking for over lap */
1290 /*-----------------------------------------------------------------*/
1292 noOverLap (set * itmpStack, symbol * fsym)
1295 debugLog ("%s\n", __FUNCTION__);
1298 for (sym = setFirstItem (itmpStack); sym;
1299 sym = setNextItem (itmpStack))
1301 if (sym->liveTo > fsym->liveFrom)
1309 /*-----------------------------------------------------------------*/
1310 /* isFree - will return 1 if the a free spil location is found */
1311 /*-----------------------------------------------------------------*/
1316 V_ARG (symbol **, sloc);
1317 V_ARG (symbol *, fsym);
1319 debugLog ("%s\n", __FUNCTION__);
1320 /* if already found */
1324 /* if it is free && and the itmp assigned to
1325 this does not have any overlapping live ranges
1326 with the one currently being assigned and
1327 the size can be accomodated */
1329 noOverLap (sym->usl.itmpStack, fsym) &&
1330 getSize (sym->type) >= getSize (fsym->type))
1339 /*-----------------------------------------------------------------*/
1340 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1341 /*-----------------------------------------------------------------*/
1343 spillLRWithPtrReg (symbol * forSym)
1349 debugLog ("%s\n", __FUNCTION__);
1350 if (!_G.regAssigned ||
1351 bitVectIsZero (_G.regAssigned))
1354 r0 = pic14_regWithIdx (R0_IDX);
1355 r1 = pic14_regWithIdx (R1_IDX);
1357 /* for all live ranges */
1358 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1359 lrsym = hTabNextItem (liveRanges, &k))
1363 /* if no registers assigned to it or
1365 /* if it does not overlap with this then
1366 not need to spill it */
1368 if (lrsym->isspilt || !lrsym->nRegs ||
1369 (lrsym->liveTo < forSym->liveFrom))
1372 /* go thru the registers : if it is either
1373 r0 or r1 then spil it */
1374 for (j = 0; j < lrsym->nRegs; j++)
1375 if (lrsym->regs[j] == r0 ||
1376 lrsym->regs[j] == r1)
1385 /*-----------------------------------------------------------------*/
1386 /* createStackSpil - create a location on the stack to spil */
1387 /*-----------------------------------------------------------------*/
1389 createStackSpil (symbol * sym)
1391 symbol *sloc = NULL;
1392 int useXstack, model, noOverlay;
1394 char slocBuffer[30];
1395 debugLog ("%s\n", __FUNCTION__);
1397 /* first go try and find a free one that is already
1398 existing on the stack */
1399 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1401 /* found a free one : just update & return */
1402 sym->usl.spillLoc = sloc;
1405 addSetHead (&sloc->usl.itmpStack, sym);
1409 /* could not then have to create one , this is the hard part
1410 we need to allocate this on the stack : this is really a
1411 hack!! but cannot think of anything better at this time */
1413 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1415 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1416 __FILE__, __LINE__);
1420 sloc = newiTemp (slocBuffer);
1422 /* set the type to the spilling symbol */
1423 sloc->type = copyLinkChain (sym->type);
1424 sloc->etype = getSpec (sloc->type);
1425 SPEC_SCLS (sloc->etype) = S_DATA;
1426 SPEC_EXTR (sloc->etype) = 0;
1427 SPEC_STAT (sloc->etype) = 0;
1429 /* we don't allow it to be allocated`
1430 onto the external stack since : so we
1431 temporarily turn it off ; we also
1432 turn off memory model to prevent
1433 the spil from going to the external storage
1434 and turn off overlaying
1437 useXstack = options.useXstack;
1438 model = options.model;
1439 noOverlay = options.noOverlay;
1440 options.noOverlay = 1;
1441 options.model = options.useXstack = 0;
1445 options.useXstack = useXstack;
1446 options.model = model;
1447 options.noOverlay = noOverlay;
1448 sloc->isref = 1; /* to prevent compiler warning */
1450 /* if it is on the stack then update the stack */
1451 if (IN_STACK (sloc->etype))
1453 currFunc->stack += getSize (sloc->type);
1454 _G.stackExtend += getSize (sloc->type);
1457 _G.dataExtend += getSize (sloc->type);
1459 /* add it to the _G.stackSpil set */
1460 addSetHead (&_G.stackSpil, sloc);
1461 sym->usl.spillLoc = sloc;
1464 /* add it to the set of itempStack set
1465 of the spill location */
1466 addSetHead (&sloc->usl.itmpStack, sym);
1470 /*-----------------------------------------------------------------*/
1471 /* isSpiltOnStack - returns true if the spil location is on stack */
1472 /*-----------------------------------------------------------------*/
1474 isSpiltOnStack (symbol * sym)
1478 debugLog ("%s\n", __FUNCTION__);
1485 /* if (sym->_G.stackSpil) */
1488 if (!sym->usl.spillLoc)
1491 etype = getSpec (sym->usl.spillLoc->type);
1492 if (IN_STACK (etype))
1498 /*-----------------------------------------------------------------*/
1499 /* spillThis - spils a specific operand */
1500 /*-----------------------------------------------------------------*/
1502 spillThis (symbol * sym)
1505 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1507 /* if this is rematerializable or has a spillLocation
1508 we are okay, else we need to create a spillLocation
1510 if (!(sym->remat || sym->usl.spillLoc))
1511 createStackSpil (sym);
1514 /* mark it has spilt & put it in the spilt set */
1516 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1518 bitVectUnSetBit (_G.regAssigned, sym->key);
1520 for (i = 0; i < sym->nRegs; i++)
1524 freeReg (sym->regs[i]);
1525 sym->regs[i] = NULL;
1528 /* if spilt on stack then free up r0 & r1
1529 if they could have been assigned to some
1531 if (!pic14_ptrRegReq && isSpiltOnStack (sym))
1534 spillLRWithPtrReg (sym);
1537 if (sym->usl.spillLoc && !sym->remat)
1538 sym->usl.spillLoc->allocreq = 1;
1542 /*-----------------------------------------------------------------*/
1543 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1544 /*-----------------------------------------------------------------*/
1546 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1548 bitVect *lrcs = NULL;
1552 debugLog ("%s\n", __FUNCTION__);
1553 /* get the spillable live ranges */
1554 lrcs = computeSpillable (ic);
1556 /* get all live ranges that are rematerizable */
1557 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1560 /* return the least used of these */
1561 return leastUsedLR (selectS);
1564 /* get live ranges with spillLocations in direct space */
1565 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1567 sym = leastUsedLR (selectS);
1568 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1569 sym->usl.spillLoc->rname :
1570 sym->usl.spillLoc->name));
1572 /* mark it as allocation required */
1573 sym->usl.spillLoc->allocreq = 1;
1577 /* if the symbol is local to the block then */
1578 if (forSym->liveTo < ebp->lSeq)
1581 /* check if there are any live ranges allocated
1582 to registers that are not used in this block */
1583 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1585 sym = leastUsedLR (selectS);
1586 /* if this is not rematerializable */
1595 /* check if there are any live ranges that not
1596 used in the remainder of the block */
1597 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1599 sym = leastUsedLR (selectS);
1602 sym->remainSpil = 1;
1609 /* find live ranges with spillocation && not used as pointers */
1610 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1613 sym = leastUsedLR (selectS);
1614 /* mark this as allocation required */
1615 sym->usl.spillLoc->allocreq = 1;
1619 /* find live ranges with spillocation */
1620 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1623 sym = leastUsedLR (selectS);
1624 sym->usl.spillLoc->allocreq = 1;
1628 /* couldn't find then we need to create a spil
1629 location on the stack , for which one? the least
1631 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1634 /* return a created spil location */
1635 sym = createStackSpil (leastUsedLR (selectS));
1636 sym->usl.spillLoc->allocreq = 1;
1640 /* this is an extreme situation we will spill
1641 this one : happens very rarely but it does happen */
1647 /*-----------------------------------------------------------------*/
1648 /* spilSomething - spil some variable & mark registers as free */
1649 /*-----------------------------------------------------------------*/
1651 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1656 debugLog ("%s\n", __FUNCTION__);
1657 /* get something we can spil */
1658 ssym = selectSpil (ic, ebp, forSym);
1660 /* mark it as spilt */
1662 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1664 /* mark it as not register assigned &
1665 take it away from the set */
1666 bitVectUnSetBit (_G.regAssigned, ssym->key);
1668 /* mark the registers as free */
1669 for (i = 0; i < ssym->nRegs; i++)
1671 freeReg (ssym->regs[i]);
1673 /* if spilt on stack then free up r0 & r1
1674 if they could have been assigned to as gprs */
1675 if (!pic14_ptrRegReq && isSpiltOnStack (ssym))
1678 spillLRWithPtrReg (ssym);
1681 /* if this was a block level spil then insert push & pop
1682 at the start & end of block respectively */
1683 if (ssym->blockSpil)
1685 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1686 /* add push to the start of the block */
1687 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1688 ebp->sch->next : ebp->sch));
1689 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1690 /* add pop to the end of the block */
1691 addiCodeToeBBlock (ebp, nic, NULL);
1694 /* if spilt because not used in the remainder of the
1695 block then add a push before this instruction and
1696 a pop at the end of the block */
1697 if (ssym->remainSpil)
1700 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1701 /* add push just before this instruction */
1702 addiCodeToeBBlock (ebp, nic, ic);
1704 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1705 /* add pop to the end of the block */
1706 addiCodeToeBBlock (ebp, nic, NULL);
1715 /*-----------------------------------------------------------------*/
1716 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1717 /*-----------------------------------------------------------------*/
1719 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1723 debugLog ("%s\n", __FUNCTION__);
1725 /* try for a ptr type */
1726 if ((reg = allocReg (REG_PTR)))
1729 /* try for gpr type */
1730 if ((reg = allocReg (REG_GPR)))
1733 /* we have to spil */
1734 if (!spilSomething (ic, ebp, sym))
1737 /* this looks like an infinite loop but
1738 in really selectSpil will abort */
1742 /*-----------------------------------------------------------------*/
1743 /* getRegGpr - will try for GPR if not spil */
1744 /*-----------------------------------------------------------------*/
1746 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1750 debugLog ("%s\n", __FUNCTION__);
1752 /* try for gpr type */
1753 if ((reg = allocReg (REG_GPR)))
1756 if (!pic14_ptrRegReq)
1757 if ((reg = allocReg (REG_PTR)))
1760 /* we have to spil */
1761 if (!spilSomething (ic, ebp, sym))
1764 /* this looks like an infinite loop but
1765 in really selectSpil will abort */
1769 /*-----------------------------------------------------------------*/
1770 /* symHasReg - symbol has a given register */
1771 /*-----------------------------------------------------------------*/
1773 symHasReg (symbol * sym, regs * reg)
1777 debugLog ("%s\n", __FUNCTION__);
1778 for (i = 0; i < sym->nRegs; i++)
1779 if (sym->regs[i] == reg)
1785 /*-----------------------------------------------------------------*/
1786 /* deassignLRs - check the live to and if they have registers & are */
1787 /* not spilt then free up the registers */
1788 /*-----------------------------------------------------------------*/
1790 deassignLRs (iCode * ic, eBBlock * ebp)
1796 debugLog ("%s\n", __FUNCTION__);
1797 for (sym = hTabFirstItem (liveRanges, &k); sym;
1798 sym = hTabNextItem (liveRanges, &k))
1801 symbol *psym = NULL;
1802 /* if it does not end here */
1803 if (sym->liveTo > ic->seq)
1806 /* if it was spilt on stack then we can
1807 mark the stack spil location as free */
1812 sym->usl.spillLoc->isFree = 1;
1818 if (!bitVectBitValue (_G.regAssigned, sym->key))
1821 /* special case check if this is an IFX &
1822 the privious one was a pop and the
1823 previous one was not spilt then keep track
1825 if (ic->op == IFX && ic->prev &&
1826 ic->prev->op == IPOP &&
1827 !ic->prev->parmPush &&
1828 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1829 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1835 bitVectUnSetBit (_G.regAssigned, sym->key);
1837 /* if the result of this one needs registers
1838 and does not have it then assign it right
1840 if (IC_RESULT (ic) &&
1841 !(SKIP_IC2 (ic) || /* not a special icode */
1842 ic->op == JUMPTABLE ||
1847 POINTER_SET (ic)) &&
1848 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1849 result->liveTo > ic->seq && /* and will live beyond this */
1850 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1851 result->regType == sym->regType && /* same register types */
1852 result->nRegs && /* which needs registers */
1853 !result->isspilt && /* and does not already have them */
1855 !bitVectBitValue (_G.regAssigned, result->key) &&
1856 /* the number of free regs + number of regs in this LR
1857 can accomodate the what result Needs */
1858 ((nfreeRegsType (result->regType) +
1859 sym->nRegs) >= result->nRegs)
1863 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1865 result->regs[i] = sym->regs[i];
1867 result->regs[i] = getRegGpr (ic, ebp, result);
1869 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1873 /* free the remaining */
1874 for (; i < sym->nRegs; i++)
1878 if (!symHasReg (psym, sym->regs[i]))
1879 freeReg (sym->regs[i]);
1882 freeReg (sym->regs[i]);
1889 /*-----------------------------------------------------------------*/
1890 /* reassignLR - reassign this to registers */
1891 /*-----------------------------------------------------------------*/
1893 reassignLR (operand * op)
1895 symbol *sym = OP_SYMBOL (op);
1898 debugLog ("%s\n", __FUNCTION__);
1899 /* not spilt any more */
1900 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1901 bitVectUnSetBit (_G.spiltSet, sym->key);
1903 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1907 for (i = 0; i < sym->nRegs; i++)
1908 sym->regs[i]->isFree = 0;
1911 /*-----------------------------------------------------------------*/
1912 /* willCauseSpill - determines if allocating will cause a spill */
1913 /*-----------------------------------------------------------------*/
1915 willCauseSpill (int nr, int rt)
1917 debugLog ("%s\n", __FUNCTION__);
1918 /* first check if there are any avlb registers
1919 of te type required */
1922 /* special case for pointer type
1923 if pointer type not avlb then
1924 check for type gpr */
1925 if (nFreeRegs (rt) >= nr)
1927 if (nFreeRegs (REG_GPR) >= nr)
1932 if (pic14_ptrRegReq)
1934 if (nFreeRegs (rt) >= nr)
1939 if (nFreeRegs (REG_PTR) +
1940 nFreeRegs (REG_GPR) >= nr)
1945 debugLog (" ... yep it will (cause a spill)\n");
1946 /* it will cause a spil */
1950 /*-----------------------------------------------------------------*/
1951 /* positionRegs - the allocator can allocate same registers to res- */
1952 /* ult and operand, if this happens make sure they are in the same */
1953 /* position as the operand otherwise chaos results */
1954 /*-----------------------------------------------------------------*/
1956 positionRegs (symbol * result, symbol * opsym, int lineno)
1958 int count = min (result->nRegs, opsym->nRegs);
1959 int i, j = 0, shared = 0;
1961 debugLog ("%s\n", __FUNCTION__);
1962 /* if the result has been spilt then cannot share */
1967 /* first make sure that they actually share */
1968 for (i = 0; i < count; i++)
1970 for (j = 0; j < count; j++)
1972 if (result->regs[i] == opsym->regs[j] && i != j)
1982 regs *tmp = result->regs[i];
1983 result->regs[i] = result->regs[j];
1984 result->regs[j] = tmp;
1989 /*-----------------------------------------------------------------*/
1990 /* serialRegAssign - serially allocate registers to the variables */
1991 /*-----------------------------------------------------------------*/
1993 serialRegAssign (eBBlock ** ebbs, int count)
1997 debugLog ("%s\n", __FUNCTION__);
1998 /* for all blocks */
1999 for (i = 0; i < count; i++)
2004 if (ebbs[i]->noPath &&
2005 (ebbs[i]->entryLabel != entryLabel &&
2006 ebbs[i]->entryLabel != returnLabel))
2009 /* of all instructions do */
2010 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2013 debugLog (" op: %s\n", decodeOp (ic->op));
2015 /* if this is an ipop that means some live
2016 range will have to be assigned again */
2018 reassignLR (IC_LEFT (ic));
2020 /* if result is present && is a true symbol */
2021 if (IC_RESULT (ic) && ic->op != IFX &&
2022 IS_TRUE_SYMOP (IC_RESULT (ic)))
2023 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2025 /* take away registers from live
2026 ranges that end at this instruction */
2027 deassignLRs (ic, ebbs[i]);
2029 /* some don't need registers */
2030 if (SKIP_IC2 (ic) ||
2031 ic->op == JUMPTABLE ||
2035 (IC_RESULT (ic) && POINTER_SET (ic)))
2038 /* now we need to allocate registers
2039 only for the result */
2042 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2048 /* if it does not need or is spilt
2049 or is already assigned to registers
2050 or will not live beyond this instructions */
2053 bitVectBitValue (_G.regAssigned, sym->key) ||
2054 sym->liveTo <= ic->seq)
2057 /* if some liverange has been spilt at the block level
2058 and this one live beyond this block then spil this
2060 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2065 /* if trying to allocate this will cause
2066 a spill and there is nothing to spill
2067 or this one is rematerializable then
2069 willCS = willCauseSpill (sym->nRegs, sym->regType);
2070 spillable = computeSpillable (ic);
2072 (willCS && bitVectIsZero (spillable)))
2080 /* if it has a spillocation & is used less than
2081 all other live ranges then spill this */
2083 if (sym->usl.spillLoc) {
2084 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2085 allLRs, ebbs[i], ic));
2086 if (leastUsed && leastUsed->used > sym->used) {
2091 /* if none of the liveRanges have a spillLocation then better
2092 to spill this one than anything else already assigned to registers */
2093 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2094 /* if this is local to this block then we might find a block spil */
2095 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2103 if (ic->op == RECEIVE)
2104 debugLog ("When I get clever, I'll optimize the receive logic\n");
2106 /* if we need ptr regs for the right side
2108 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2109 <= (unsigned) PTRSIZE)
2114 /* else we assign registers to it */
2115 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2117 debugLog (" %d - \n", __LINE__);
2119 bitVectDebugOn(_G.regAssigned, debugF);
2121 for (j = 0; j < sym->nRegs; j++)
2123 if (sym->regType == REG_PTR)
2124 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2126 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2128 /* if the allocation falied which means
2129 this was spilt then break */
2133 debugLog (" %d - \n", __LINE__);
2135 /* if it shares registers with operands make sure
2136 that they are in the same position */
2137 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2138 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2139 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2140 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2141 /* do the same for the right operand */
2142 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2143 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2144 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2145 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2147 debugLog (" %d - \n", __LINE__);
2150 debugLog (" %d - \n", __LINE__);
2160 /*-----------------------------------------------------------------*/
2161 /* rUmaskForOp :- returns register mask for an operand */
2162 /*-----------------------------------------------------------------*/
2164 rUmaskForOp (operand * op)
2170 debugLog ("%s\n", __FUNCTION__);
2171 /* only temporaries are assigned registers */
2175 sym = OP_SYMBOL (op);
2177 /* if spilt or no registers assigned to it
2179 if (sym->isspilt || !sym->nRegs)
2182 rumask = newBitVect (pic14_nRegs);
2184 for (j = 0; j < sym->nRegs; j++)
2186 rumask = bitVectSetBit (rumask,
2187 sym->regs[j]->rIdx);
2193 /*-----------------------------------------------------------------*/
2194 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2195 /*-----------------------------------------------------------------*/
2197 regsUsedIniCode (iCode * ic)
2199 bitVect *rmask = newBitVect (pic14_nRegs);
2201 debugLog ("%s\n", __FUNCTION__);
2202 /* do the special cases first */
2205 rmask = bitVectUnion (rmask,
2206 rUmaskForOp (IC_COND (ic)));
2210 /* for the jumptable */
2211 if (ic->op == JUMPTABLE)
2213 rmask = bitVectUnion (rmask,
2214 rUmaskForOp (IC_JTCOND (ic)));
2219 /* of all other cases */
2221 rmask = bitVectUnion (rmask,
2222 rUmaskForOp (IC_LEFT (ic)));
2226 rmask = bitVectUnion (rmask,
2227 rUmaskForOp (IC_RIGHT (ic)));
2230 rmask = bitVectUnion (rmask,
2231 rUmaskForOp (IC_RESULT (ic)));
2237 /*-----------------------------------------------------------------*/
2238 /* createRegMask - for each instruction will determine the regsUsed */
2239 /*-----------------------------------------------------------------*/
2241 createRegMask (eBBlock ** ebbs, int count)
2245 debugLog ("%s\n", __FUNCTION__);
2246 /* for all blocks */
2247 for (i = 0; i < count; i++)
2251 if (ebbs[i]->noPath &&
2252 (ebbs[i]->entryLabel != entryLabel &&
2253 ebbs[i]->entryLabel != returnLabel))
2256 /* for all instructions */
2257 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2262 if (SKIP_IC2 (ic) || !ic->rlive)
2265 /* first mark the registers used in this
2267 ic->rUsed = regsUsedIniCode (ic);
2268 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2270 /* now create the register mask for those
2271 registers that are in use : this is a
2272 super set of ic->rUsed */
2273 ic->rMask = newBitVect (pic14_nRegs + 1);
2275 /* for all live Ranges alive at this point */
2276 for (j = 1; j < ic->rlive->size; j++)
2281 /* if not alive then continue */
2282 if (!bitVectBitValue (ic->rlive, j))
2285 /* find the live range we are interested in */
2286 if (!(sym = hTabItemWithKey (liveRanges, j)))
2288 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2289 "createRegMask cannot find live range");
2293 /* if no register assigned to it */
2294 if (!sym->nRegs || sym->isspilt)
2297 /* for all the registers allocated to it */
2298 for (k = 0; k < sym->nRegs; k++)
2301 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2307 /*-----------------------------------------------------------------*/
2308 /* rematStr - returns the rematerialized string for a remat var */
2309 /*-----------------------------------------------------------------*/
2311 rematStr (symbol * sym)
2314 iCode *ic = sym->rematiCode;
2315 symbol *psym = NULL;
2317 debugLog ("%s\n", __FUNCTION__);
2319 //printf ("%s\n", s);
2321 /* if plus or minus print the right hand side */
2323 if (ic->op == '+' || ic->op == '-') {
2325 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2327 sprintf (s, "(%s %c 0x%04x)",
2328 OP_SYMBOL (IC_LEFT (ric))->rname,
2330 (int) operandLitValue (IC_RIGHT (ic)));
2333 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2335 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2336 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2341 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2342 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2344 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2349 /*-----------------------------------------------------------------*/
2350 /* rematStr - returns the rematerialized string for a remat var */
2351 /*-----------------------------------------------------------------*/
2353 rematStr (symbol * sym)
2356 iCode *ic = sym->rematiCode;
2358 debugLog ("%s\n", __FUNCTION__);
2363 /* if plus or minus print the right hand side */
2365 if (ic->op == '+' || ic->op == '-') {
2366 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2369 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2373 if (ic->op == '+' || ic->op == '-')
2375 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2376 sprintf (s, "(%s %c 0x%04x)",
2377 OP_SYMBOL (IC_LEFT (ric))->rname,
2379 (int) operandLitValue (IC_RIGHT (ic)));
2382 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2384 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2388 /* we reached the end */
2389 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2393 printf ("%s\n", buffer);
2398 /*-----------------------------------------------------------------*/
2399 /* regTypeNum - computes the type & number of registers required */
2400 /*-----------------------------------------------------------------*/
2408 debugLog ("%s\n", __FUNCTION__);
2409 /* for each live range do */
2410 for (sym = hTabFirstItem (liveRanges, &k); sym;
2411 sym = hTabNextItem (liveRanges, &k)) {
2413 debugLog (" %d - %s\n", __LINE__, sym->rname);
2415 /* if used zero times then no registers needed */
2416 if ((sym->liveTo - sym->liveFrom) == 0)
2420 /* if the live range is a temporary */
2423 debugLog (" %d - itemp register\n", __LINE__);
2425 /* if the type is marked as a conditional */
2426 if (sym->regType == REG_CND)
2429 /* if used in return only then we don't
2431 if (sym->ruonly || sym->accuse) {
2432 if (IS_AGGREGATE (sym->type) || sym->isptr)
2433 sym->type = aggrToPtr (sym->type, FALSE);
2434 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
2439 /* if the symbol has only one definition &
2440 that definition is a get_pointer and the
2441 pointer we are getting is rematerializable and
2444 if (bitVectnBitsOn (sym->defs) == 1 &&
2445 (ic = hTabItemWithKey (iCodehTab,
2446 bitVectFirstBit (sym->defs))) &&
2449 !IS_BITVAR (sym->etype)) {
2452 debugLog (" %d - \n", __LINE__);
2454 /* if remat in data space */
2455 if (OP_SYMBOL (IC_LEFT (ic))->remat &&
2456 DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) {
2458 /* create a psuedo symbol & force a spil */
2459 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2460 symbol *psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2461 psym->type = sym->type;
2462 psym->etype = sym->etype;
2463 strcpy (psym->rname, psym->name);
2465 sym->usl.spillLoc = psym;
2469 /* if in data space or idata space then try to
2470 allocate pointer register */
2474 /* if not then we require registers */
2475 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2476 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2477 getSize (sym->type));
2480 if(IS_PTR_CONST (sym->type)) {
2481 debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2485 if (sym->nRegs > 4) {
2486 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2487 printTypeChain (sym->type, stderr);
2488 fprintf (stderr, "\n");
2491 /* determine the type of register required */
2492 if (sym->nRegs == 1 &&
2493 IS_PTR (sym->type) &&
2495 sym->regType = REG_PTR;
2497 sym->regType = REG_GPR;
2500 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2504 /* for the first run we don't provide */
2505 /* registers for true symbols we will */
2506 /* see how things go */
2511 DEFSETFUNC (markRegFree)
2513 ((regs *)item)->isFree = 1;
2518 DEFSETFUNC (deallocReg)
2520 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2521 ((regs *)item)->isFree = 1;
2522 ((regs *)item)->wasUsed = 0;
2526 /*-----------------------------------------------------------------*/
2527 /* freeAllRegs - mark all registers as free */
2528 /*-----------------------------------------------------------------*/
2530 pic14_freeAllRegs ()
2534 debugLog ("%s\n", __FUNCTION__);
2536 applyToSet(dynAllocRegs,markRegFree);
2537 applyToSet(dynStackRegs,markRegFree);
2540 for (i = 0; i < pic14_nRegs; i++)
2541 regspic14[i].isFree = 1;
2545 /*-----------------------------------------------------------------*/
2546 /*-----------------------------------------------------------------*/
2548 pic14_deallocateAllRegs ()
2552 debugLog ("%s\n", __FUNCTION__);
2554 applyToSet(dynAllocRegs,deallocReg);
2557 for (i = 0; i < pic14_nRegs; i++) {
2558 if(regspic14[i].pc_type == PO_GPR_TEMP) {
2559 regspic14[i].isFree = 1;
2560 regspic14[i].wasUsed = 0;
2567 /*-----------------------------------------------------------------*/
2568 /* deallocStackSpil - this will set the stack pointer back */
2569 /*-----------------------------------------------------------------*/
2571 DEFSETFUNC (deallocStackSpil)
2575 debugLog ("%s\n", __FUNCTION__);
2580 /*-----------------------------------------------------------------*/
2581 /* farSpacePackable - returns the packable icode for far variables */
2582 /*-----------------------------------------------------------------*/
2584 farSpacePackable (iCode * ic)
2588 debugLog ("%s\n", __FUNCTION__);
2589 /* go thru till we find a definition for the
2590 symbol on the right */
2591 for (dic = ic->prev; dic; dic = dic->prev)
2594 /* if the definition is a call then no */
2595 if ((dic->op == CALL || dic->op == PCALL) &&
2596 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2601 /* if shift by unknown amount then not */
2602 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2603 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2606 /* if pointer get and size > 1 */
2607 if (POINTER_GET (dic) &&
2608 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2611 if (POINTER_SET (dic) &&
2612 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2615 /* if any three is a true symbol in far space */
2616 if (IC_RESULT (dic) &&
2617 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2618 isOperandInFarSpace (IC_RESULT (dic)))
2621 if (IC_RIGHT (dic) &&
2622 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2623 isOperandInFarSpace (IC_RIGHT (dic)) &&
2624 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2627 if (IC_LEFT (dic) &&
2628 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2629 isOperandInFarSpace (IC_LEFT (dic)) &&
2630 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2633 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2635 if ((dic->op == LEFT_OP ||
2636 dic->op == RIGHT_OP ||
2638 IS_OP_LITERAL (IC_RIGHT (dic)))
2648 /*-----------------------------------------------------------------*/
2649 /* packRegsForAssign - register reduction for assignment */
2650 /*-----------------------------------------------------------------*/
2652 packRegsForAssign (iCode * ic, eBBlock * ebp)
2657 debugLog ("%s\n", __FUNCTION__);
2659 debugAopGet (" result:", IC_RESULT (ic));
2660 debugAopGet (" left:", IC_LEFT (ic));
2661 debugAopGet (" right:", IC_RIGHT (ic));
2663 /* if this is at an absolute address, then get the address. */
2664 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2665 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2666 debugLog (" %d - found config word declaration\n", __LINE__);
2667 if(IS_VALOP(IC_RIGHT(ic))) {
2668 debugLog (" setting config word to %x\n",
2669 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2670 assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2671 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2674 /* remove the assignment from the iCode chain. */
2676 remiCodeFromeBBlock (ebp, ic);
2677 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2678 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2685 if (!IS_ITEMP (IC_RESULT (ic))) {
2686 allocDirReg(IC_RESULT (ic));
2687 debugLog (" %d - result is not temp\n", __LINE__);
2690 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2691 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2692 allocDirReg(IC_LEFT (ic));
2696 if (!IS_ITEMP (IC_RIGHT (ic))) {
2697 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2698 allocDirReg(IC_RIGHT (ic));
2702 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2703 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2705 debugLog (" %d - not packing - right side fails \n", __LINE__);
2709 /* if the true symbol is defined in far space or on stack
2710 then we should not since this will increase register pressure */
2711 if (isOperandInFarSpace (IC_RESULT (ic)))
2713 if ((dic = farSpacePackable (ic)))
2719 /* find the definition of iTempNN scanning backwards if we find a
2720 a use of the true symbol before we find the definition then
2722 for (dic = ic->prev; dic; dic = dic->prev)
2725 /* if there is a function call and this is
2726 a parameter & not my parameter then don't pack it */
2727 if ((dic->op == CALL || dic->op == PCALL) &&
2728 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2729 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2731 debugLog (" %d - \n", __LINE__);
2739 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2740 IS_OP_VOLATILE (IC_RESULT (dic)))
2742 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2747 if (IS_SYMOP (IC_RESULT (dic)) &&
2748 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2750 /* A previous result was assigned to the same register - we'll our definition */
2751 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2752 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2753 if (POINTER_SET (dic))
2759 if (IS_SYMOP (IC_RIGHT (dic)) &&
2760 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2761 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2763 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
2768 if (IS_SYMOP (IC_LEFT (dic)) &&
2769 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2770 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2772 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
2777 if (POINTER_SET (dic) &&
2778 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2780 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
2788 return 0; /* did not find */
2790 /* if the result is on stack or iaccess then it must be
2791 the same atleast one of the operands */
2792 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2793 OP_SYMBOL (IC_RESULT (ic))->iaccess)
2796 /* the operation has only one symbol
2797 operator then we can pack */
2798 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2799 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2802 if (!((IC_LEFT (dic) &&
2803 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2805 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2809 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2810 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
2811 /* found the definition */
2812 /* replace the result with the result of */
2813 /* this assignment and remove this assignment */
2814 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2815 IC_RESULT (dic) = IC_RESULT (ic);
2817 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2819 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2821 /* delete from liverange table also
2822 delete from all the points inbetween and the new
2824 for (sic = dic; sic != ic; sic = sic->next)
2826 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2827 if (IS_ITEMP (IC_RESULT (dic)))
2828 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2831 remiCodeFromeBBlock (ebp, ic);
2832 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2833 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2834 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2840 /*-----------------------------------------------------------------*/
2841 /* findAssignToSym : scanning backwards looks for first assig found */
2842 /*-----------------------------------------------------------------*/
2844 findAssignToSym (operand * op, iCode * ic)
2848 debugLog ("%s\n", __FUNCTION__);
2849 for (dic = ic->prev; dic; dic = dic->prev)
2852 /* if definition by assignment */
2853 if (dic->op == '=' &&
2854 !POINTER_SET (dic) &&
2855 IC_RESULT (dic)->key == op->key
2856 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2860 /* we are interested only if defined in far space */
2861 /* or in stack space in case of + & - */
2863 /* if assigned to a non-symbol then return
2865 if (!IS_SYMOP (IC_RIGHT (dic)))
2868 /* if the symbol is in far space then
2870 if (isOperandInFarSpace (IC_RIGHT (dic)))
2873 /* for + & - operations make sure that
2874 if it is on the stack it is the same
2875 as one of the three operands */
2876 if ((ic->op == '+' || ic->op == '-') &&
2877 OP_SYMBOL (IC_RIGHT (dic))->onStack)
2880 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2881 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2882 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2890 /* if we find an usage then we cannot delete it */
2891 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2894 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2897 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2901 /* now make sure that the right side of dic
2902 is not defined between ic & dic */
2905 iCode *sic = dic->next;
2907 for (; sic != ic; sic = sic->next)
2908 if (IC_RESULT (sic) &&
2909 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2918 /*-----------------------------------------------------------------*/
2919 /* packRegsForSupport :- reduce some registers for support calls */
2920 /*-----------------------------------------------------------------*/
2922 packRegsForSupport (iCode * ic, eBBlock * ebp)
2926 debugLog ("%s\n", __FUNCTION__);
2927 /* for the left & right operand :- look to see if the
2928 left was assigned a true symbol in far space in that
2929 case replace them */
2930 if (IS_ITEMP (IC_LEFT (ic)) &&
2931 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2933 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
2939 debugAopGet ("removing left:", IC_LEFT (ic));
2941 /* found it we need to remove it from the
2943 for (sic = dic; sic != ic; sic = sic->next)
2944 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
2946 IC_LEFT (ic)->operand.symOperand =
2947 IC_RIGHT (dic)->operand.symOperand;
2948 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2949 remiCodeFromeBBlock (ebp, dic);
2950 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2951 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2955 /* do the same for the right operand */
2958 IS_ITEMP (IC_RIGHT (ic)) &&
2959 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2961 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2967 /* if this is a subtraction & the result
2968 is a true symbol in far space then don't pack */
2969 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
2971 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
2972 if (IN_FARSPACE (SPEC_OCLS (etype)))
2976 debugAopGet ("removing right:", IC_RIGHT (ic));
2978 /* found it we need to remove it from the
2980 for (sic = dic; sic != ic; sic = sic->next)
2981 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
2983 IC_RIGHT (ic)->operand.symOperand =
2984 IC_RIGHT (dic)->operand.symOperand;
2985 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2987 remiCodeFromeBBlock (ebp, dic);
2988 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2989 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2996 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
2999 /*-----------------------------------------------------------------*/
3000 /* packRegsForOneuse : - will reduce some registers for single Use */
3001 /*-----------------------------------------------------------------*/
3003 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3008 debugLog ("%s\n", __FUNCTION__);
3009 /* if returning a literal then do nothing */
3013 /* only upto 2 bytes since we cannot predict
3014 the usage of b, & acc */
3015 if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
3020 /* this routine will mark the a symbol as used in one
3021 instruction use only && if the definition is local
3022 (ie. within the basic block) && has only one definition &&
3023 that definition is either a return value from a
3024 function or does not contain any variables in
3026 uses = bitVectCopy (OP_USES (op));
3027 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3028 if (!bitVectIsZero (uses)) /* has other uses */
3031 /* if it has only one defintion */
3032 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3033 return NULL; /* has more than one definition */
3035 /* get that definition */
3037 hTabItemWithKey (iCodehTab,
3038 bitVectFirstBit (OP_DEFS (op)))))
3041 /* found the definition now check if it is local */
3042 if (dic->seq < ebp->fSeq ||
3043 dic->seq > ebp->lSeq)
3044 return NULL; /* non-local */
3046 /* now check if it is the return from
3048 if (dic->op == CALL || dic->op == PCALL)
3050 if (ic->op != SEND && ic->op != RETURN &&
3051 !POINTER_SET(ic) && !POINTER_GET(ic))
3053 OP_SYMBOL (op)->ruonly = 1;
3060 /* otherwise check that the definition does
3061 not contain any symbols in far space */
3062 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3063 isOperandInFarSpace (IC_RIGHT (dic)) ||
3064 IS_OP_RUONLY (IC_LEFT (ic)) ||
3065 IS_OP_RUONLY (IC_RIGHT (ic)))
3070 /* if pointer set then make sure the pointer
3072 if (POINTER_SET (dic) &&
3073 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3076 if (POINTER_GET (dic) &&
3077 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3082 /* also make sure the intervenening instructions
3083 don't have any thing in far space */
3084 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3087 /* if there is an intervening function call then no */
3088 if (dic->op == CALL || dic->op == PCALL)
3090 /* if pointer set then make sure the pointer
3092 if (POINTER_SET (dic) &&
3093 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3096 if (POINTER_GET (dic) &&
3097 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3100 /* if address of & the result is remat then okay */
3101 if (dic->op == ADDRESS_OF &&
3102 OP_SYMBOL (IC_RESULT (dic))->remat)
3105 /* if operand has size of three or more & this
3106 operation is a '*','/' or '%' then 'b' may
3108 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3109 getSize (operandType (op)) >= 3)
3112 /* if left or right or result is in far space */
3113 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3114 isOperandInFarSpace (IC_RIGHT (dic)) ||
3115 isOperandInFarSpace (IC_RESULT (dic)) ||
3116 IS_OP_RUONLY (IC_LEFT (dic)) ||
3117 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3118 IS_OP_RUONLY (IC_RESULT (dic)))
3124 OP_SYMBOL (op)->ruonly = 1;
3129 /*-----------------------------------------------------------------*/
3130 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3131 /*-----------------------------------------------------------------*/
3133 isBitwiseOptimizable (iCode * ic)
3135 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3136 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3138 debugLog ("%s\n", __FUNCTION__);
3139 /* bitwise operations are considered optimizable
3140 under the following conditions (Jean-Louis VERN)
3152 if (IS_LITERAL (rtype) ||
3153 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3159 /*-----------------------------------------------------------------*/
3160 /* packRegsForAccUse - pack registers for acc use */
3161 /*-----------------------------------------------------------------*/
3163 packRegsForAccUse (iCode * ic)
3167 debugLog ("%s\n", __FUNCTION__);
3169 /* if this is an aggregate, e.g. a one byte char array */
3170 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3173 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3175 /* if + or - then it has to be one byte result */
3176 if ((ic->op == '+' || ic->op == '-')
3177 && getSize (operandType (IC_RESULT (ic))) > 1)
3180 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3181 /* if shift operation make sure right side is not a literal */
3182 if (ic->op == RIGHT_OP &&
3183 (isOperandLiteral (IC_RIGHT (ic)) ||
3184 getSize (operandType (IC_RESULT (ic))) > 1))
3187 if (ic->op == LEFT_OP &&
3188 (isOperandLiteral (IC_RIGHT (ic)) ||
3189 getSize (operandType (IC_RESULT (ic))) > 1))
3192 if (IS_BITWISE_OP (ic) &&
3193 getSize (operandType (IC_RESULT (ic))) > 1)
3197 /* has only one definition */
3198 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3201 /* has only one use */
3202 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3205 /* and the usage immediately follows this iCode */
3206 if (!(uic = hTabItemWithKey (iCodehTab,
3207 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3210 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3211 if (ic->next != uic)
3214 /* if it is a conditional branch then we definitely can */
3218 if (uic->op == JUMPTABLE)
3221 /* if the usage is not is an assignment
3222 or an arithmetic / bitwise / shift operation then not */
3223 if (POINTER_SET (uic) &&
3224 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3227 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3228 if (uic->op != '=' &&
3229 !IS_ARITHMETIC_OP (uic) &&
3230 !IS_BITWISE_OP (uic) &&
3231 uic->op != LEFT_OP &&
3232 uic->op != RIGHT_OP)
3235 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3236 /* if used in ^ operation then make sure right is not a
3238 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3241 /* if shift operation make sure right side is not a literal */
3242 if (uic->op == RIGHT_OP &&
3243 (isOperandLiteral (IC_RIGHT (uic)) ||
3244 getSize (operandType (IC_RESULT (uic))) > 1))
3247 if (uic->op == LEFT_OP &&
3248 (isOperandLiteral (IC_RIGHT (uic)) ||
3249 getSize (operandType (IC_RESULT (uic))) > 1))
3252 /* make sure that the result of this icode is not on the
3253 stack, since acc is used to compute stack offset */
3254 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3255 OP_SYMBOL (IC_RESULT (uic))->onStack)
3258 /* if either one of them in far space then we cannot */
3259 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3260 isOperandInFarSpace (IC_LEFT (uic))) ||
3261 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3262 isOperandInFarSpace (IC_RIGHT (uic))))
3265 /* if the usage has only one operand then we can */
3266 if (IC_LEFT (uic) == NULL ||
3267 IC_RIGHT (uic) == NULL)
3270 /* make sure this is on the left side if not
3271 a '+' since '+' is commutative */
3272 if (ic->op != '+' &&
3273 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3276 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3277 /* if one of them is a literal then we can */
3278 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3279 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3280 (getSize (operandType (IC_RESULT (uic))) <= 1))
3282 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3286 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3287 /* if the other one is not on stack then we can */
3288 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3289 (IS_ITEMP (IC_RIGHT (uic)) ||
3290 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3291 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3294 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3295 (IS_ITEMP (IC_LEFT (uic)) ||
3296 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3297 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3303 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3304 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3309 /*-----------------------------------------------------------------*/
3310 /* packForPush - hueristics to reduce iCode for pushing */
3311 /*-----------------------------------------------------------------*/
3313 packForReceive (iCode * ic, eBBlock * ebp)
3317 debugLog ("%s\n", __FUNCTION__);
3318 debugAopGet (" result:", IC_RESULT (ic));
3319 debugAopGet (" left:", IC_LEFT (ic));
3320 debugAopGet (" right:", IC_RIGHT (ic));
3325 for (dic = ic->next; dic; dic = dic->next)
3330 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3331 debugLog (" used on left\n");
3332 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3333 debugLog (" used on right\n");
3334 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3335 debugLog (" used on result\n");
3337 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3338 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3343 debugLog (" hey we can remove this unnecessary assign\n");
3345 /*-----------------------------------------------------------------*/
3346 /* packForPush - hueristics to reduce iCode for pushing */
3347 /*-----------------------------------------------------------------*/
3349 packForPush (iCode * ic, eBBlock * ebp)
3353 debugLog ("%s\n", __FUNCTION__);
3354 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3357 /* must have only definition & one usage */
3358 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3359 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3362 /* find the definition */
3363 if (!(dic = hTabItemWithKey (iCodehTab,
3364 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3367 if (dic->op != '=' || POINTER_SET (dic))
3370 /* we now we know that it has one & only one def & use
3371 and the that the definition is an assignment */
3372 IC_LEFT (ic) = IC_RIGHT (dic);
3374 remiCodeFromeBBlock (ebp, dic);
3375 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3376 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3379 void printSymType(char * str, sym_link *sl)
3381 debugLog (" %s Symbol type: ",str);
3382 printTypeChain( sl, debugF);
3387 /*-----------------------------------------------------------------*/
3388 /* packRegisters - does some transformations to reduce register */
3390 /*-----------------------------------------------------------------*/
3392 packRegisters (eBBlock * ebp)
3397 debugLog ("%s\n", __FUNCTION__);
3403 /* look for assignments of the form */
3404 /* iTempNN = TRueSym (someoperation) SomeOperand */
3406 /* TrueSym := iTempNN:1 */
3407 for (ic = ebp->sch; ic; ic = ic->next)
3410 /* find assignment of the form TrueSym := iTempNN:1 */
3411 if (ic->op == '=' && !POINTER_SET (ic))
3412 change += packRegsForAssign (ic, ebp);
3416 if (POINTER_SET (ic))
3417 debugLog ("pointer is set\n");
3418 debugAopGet (" result:", IC_RESULT (ic));
3419 debugAopGet (" left:", IC_LEFT (ic));
3420 debugAopGet (" right:", IC_RIGHT (ic));
3429 for (ic = ebp->sch; ic; ic = ic->next) {
3431 if(IS_SYMOP ( IC_LEFT(ic))) {
3432 //sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3434 debugAopGet (" left:", IC_LEFT (ic));
3435 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3436 debugLog (" is a pointer");
3438 printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
3441 if(IS_SYMOP ( IC_RIGHT(ic))) {
3442 debugAopGet (" right:", IC_RIGHT (ic));
3443 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3446 if(IS_SYMOP ( IC_RESULT(ic))) {
3447 debugAopGet (" result:", IC_RESULT (ic));
3448 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3451 if (POINTER_SET (ic))
3452 debugLog (" %d - Pointer set\n", __LINE__);
3455 /* if this is an itemp & result of a address of a true sym
3456 then mark this as rematerialisable */
3457 if (ic->op == ADDRESS_OF &&
3458 IS_ITEMP (IC_RESULT (ic)) &&
3459 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3460 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3461 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3464 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3466 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3467 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3468 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3472 /* if straight assignment then carry remat flag if
3473 this is the only definition */
3474 if (ic->op == '=' &&
3475 !POINTER_SET (ic) &&
3476 IS_SYMOP (IC_RIGHT (ic)) &&
3477 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3478 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3480 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3482 OP_SYMBOL (IC_RESULT (ic))->remat =
3483 OP_SYMBOL (IC_RIGHT (ic))->remat;
3484 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3485 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3488 /* if this is a +/- operation with a rematerizable
3489 then mark this as rematerializable as well */
3490 if ((ic->op == '+' || ic->op == '-') &&
3491 (IS_SYMOP (IC_LEFT (ic)) &&
3492 IS_ITEMP (IC_RESULT (ic)) &&
3493 OP_SYMBOL (IC_LEFT (ic))->remat &&
3494 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3495 IS_OP_LITERAL (IC_RIGHT (ic))))
3497 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3499 operandLitValue (IC_RIGHT (ic));
3500 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3501 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3502 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3505 /* mark the pointer usages */
3506 if (POINTER_SET (ic))
3508 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3509 debugLog (" marking as a pointer (set) =>");
3510 debugAopGet (" result:", IC_RESULT (ic));
3512 if (POINTER_GET (ic))
3514 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3515 debugLog (" marking as a pointer (get) =>");
3516 debugAopGet (" left:", IC_LEFT (ic));
3521 /* if we are using a symbol on the stack
3522 then we should say pic14_ptrRegReq */
3523 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3524 pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3525 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3526 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3527 pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3528 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3531 if (IS_SYMOP (IC_LEFT (ic)))
3532 pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3533 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3534 if (IS_SYMOP (IC_RIGHT (ic)))
3535 pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3536 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3537 if (IS_SYMOP (IC_RESULT (ic)))
3538 pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3539 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3542 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
3546 /* if the condition of an if instruction
3547 is defined in the previous instruction then
3548 mark the itemp as a conditional */
3549 if ((IS_CONDITIONAL (ic) ||
3550 ((ic->op == BITWISEAND ||
3553 isBitwiseOptimizable (ic))) &&
3554 ic->next && ic->next->op == IFX &&
3555 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3556 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3559 debugLog (" %d\n", __LINE__);
3560 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3564 /* reduce for support function calls */
3565 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3566 packRegsForSupport (ic, ebp);
3568 /* if a parameter is passed, it's in W, so we may not
3569 need to place a copy in a register */
3570 if (ic->op == RECEIVE)
3571 packForReceive (ic, ebp);
3573 /* some cases the redundant moves can
3574 can be eliminated for return statements */
3575 if ((ic->op == RETURN || ic->op == SEND) &&
3576 !isOperandInFarSpace (IC_LEFT (ic)) &&
3578 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3580 /* if pointer set & left has a size more than
3581 one and right is not in far space */
3582 if (POINTER_SET (ic) &&
3583 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3584 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3585 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3586 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3588 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3590 /* if pointer get */
3591 if (POINTER_GET (ic) &&
3592 !isOperandInFarSpace (IC_RESULT (ic)) &&
3593 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3594 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3595 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3597 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3600 /* if this is cast for intergral promotion then
3601 check if only use of the definition of the
3602 operand being casted/ if yes then replace
3603 the result of that arithmetic operation with
3604 this result and get rid of the cast */
3605 if (ic->op == CAST) {
3607 sym_link *fromType = operandType (IC_RIGHT (ic));
3608 sym_link *toType = operandType (IC_LEFT (ic));
3610 debugLog (" %d - casting\n", __LINE__);
3612 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3613 getSize (fromType) != getSize (toType)) {
3616 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3619 if (IS_ARITHMETIC_OP (dic)) {
3621 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3622 IC_RESULT (dic) = IC_RESULT (ic);
3623 remiCodeFromeBBlock (ebp, ic);
3624 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3625 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3626 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3630 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3634 /* if the type from and type to are the same
3635 then if this is the only use then packit */
3636 if (compareType (operandType (IC_RIGHT (ic)),
3637 operandType (IC_LEFT (ic))) == 1) {
3639 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3642 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3643 IC_RESULT (dic) = IC_RESULT (ic);
3644 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3645 remiCodeFromeBBlock (ebp, ic);
3646 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3647 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3655 iTempNN := (some variable in farspace) V1
3660 if (ic->op == IPUSH)
3662 packForPush (ic, ebp);
3666 /* pack registers for accumulator use, when the
3667 result of an arithmetic or bit wise operation
3668 has only one use, that use is immediately following
3669 the defintion and the using iCode has only one
3670 operand or has two operands but one is literal &
3671 the result of that operation is not on stack then
3672 we can leave the result of this operation in acc:b
3674 if ((IS_ARITHMETIC_OP (ic)
3676 || IS_BITWISE_OP (ic)
3678 || ic->op == LEFT_OP || ic->op == RIGHT_OP
3681 IS_ITEMP (IC_RESULT (ic)) &&
3682 getSize (operandType (IC_RESULT (ic))) <= 2)
3684 packRegsForAccUse (ic);
3690 dumpEbbsToDebug (eBBlock ** ebbs, int count)
3694 if (!debug || !debugF)
3697 for (i = 0; i < count; i++)
3699 fprintf (debugF, "\n----------------------------------------------------------------\n");
3700 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
3701 ebbs[i]->entryLabel->name,
3704 ebbs[i]->isLastInLoop);
3705 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
3710 fprintf (debugF, "visited %d : hasFcall = %d\n",
3714 fprintf (debugF, "\ndefines bitVector :");
3715 bitVectDebugOn (ebbs[i]->defSet, debugF);
3716 fprintf (debugF, "\nlocal defines bitVector :");
3717 bitVectDebugOn (ebbs[i]->ldefs, debugF);
3718 fprintf (debugF, "\npointers Set bitvector :");
3719 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
3720 fprintf (debugF, "\nin pointers Set bitvector :");
3721 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
3722 fprintf (debugF, "\ninDefs Set bitvector :");
3723 bitVectDebugOn (ebbs[i]->inDefs, debugF);
3724 fprintf (debugF, "\noutDefs Set bitvector :");
3725 bitVectDebugOn (ebbs[i]->outDefs, debugF);
3726 fprintf (debugF, "\nusesDefs Set bitvector :");
3727 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
3728 fprintf (debugF, "\n----------------------------------------------------------------\n");
3729 printiCChain (ebbs[i]->sch, debugF);
3732 /*-----------------------------------------------------------------*/
3733 /* assignRegisters - assigns registers to each live range as need */
3734 /*-----------------------------------------------------------------*/
3736 pic14_assignRegisters (eBBlock ** ebbs, int count)
3741 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
3742 debugLog ("\nebbs before optimizing:\n");
3743 dumpEbbsToDebug (ebbs, count);
3745 setToNull ((void *) &_G.funcrUsed);
3746 pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3749 /* change assignments this will remove some
3750 live ranges reducing some register pressure */
3751 for (i = 0; i < count; i++)
3752 packRegisters (ebbs[i]);
3759 debugLog("dir registers allocated so far:\n");
3760 reg = hTabFirstItem(dynDirectRegNames, &hkey);
3763 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
3764 reg = hTabNextItem(dynDirectRegNames, &hkey);
3769 if (options.dump_pack)
3770 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3772 /* first determine for each live range the number of
3773 registers & the type of registers required for each */
3776 /* and serially allocate registers */
3777 serialRegAssign (ebbs, count);
3779 /* if stack was extended then tell the user */
3782 /* werror(W_TOOMANY_SPILS,"stack", */
3783 /* _G.stackExtend,currFunc->name,""); */
3789 /* werror(W_TOOMANY_SPILS,"data space", */
3790 /* _G.dataExtend,currFunc->name,""); */
3794 /* after that create the register mask
3795 for each of the instruction */
3796 createRegMask (ebbs, count);
3798 /* redo that offsets for stacked automatic variables */
3799 redoStackOffsets ();
3801 if (options.dump_rassgn)
3802 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3804 /* now get back the chain */
3805 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3807 debugLog ("ebbs after optimizing:\n");
3808 dumpEbbsToDebug (ebbs, count);
3813 /* free up any _G.stackSpil locations allocated */
3814 applyToSet (_G.stackSpil, deallocStackSpil);
3816 setToNull ((void **) &_G.stackSpil);
3817 setToNull ((void **) &_G.spiltSet);
3818 /* mark all registers as free */
3819 //pic14_freeAllRegs ();
3821 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");