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;
76 // static hTab *regHash = NULL; /* a hash table containing ALL registers */
78 static int dynrIdx=0x20;
79 static int rDirectIdx=0;
81 int pic14_nRegs = 128; // = sizeof (regspic14) / sizeof (regs);
83 int Gstack_base_addr=0; /* The starting address of registers that
84 * are used to pass and return parameters */
89 static void spillThis (symbol *);
91 static FILE *debugF = NULL;
92 /*-----------------------------------------------------------------*/
93 /* debugLog - open a file for debugging information */
94 /*-----------------------------------------------------------------*/
95 //static void debugLog(char *inst,char *fmt, ...)
97 debugLog (char *fmt,...)
99 static int append = 0; // First time through, open the file without append.
102 //char *bufferP=buffer;
105 if (!debug || !dstFileName)
111 /* create the file name */
112 strcpy (buffer, dstFileName);
113 strcat (buffer, ".d");
115 if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
117 werror (E_FILE_OPEN_ERR, buffer);
120 append = 1; // Next time debubLog is called, we'll append the debug info
126 vsprintf (buffer, fmt, ap);
128 fprintf (debugF, "%s", buffer);
130 while (isspace(*bufferP)) bufferP++;
132 if (bufferP && *bufferP)
133 lineCurr = (lineCurr ?
134 connectLine(lineCurr,newLineNode(lb)) :
135 (lineHead = newLineNode(lb)));
136 lineCurr->isInline = _G.inLine;
137 lineCurr->isDebug = _G.debugLine;
147 fputc ('\n', debugF);
149 /*-----------------------------------------------------------------*/
150 /* debugLogClose - closes the debug log file (if opened) */
151 /*-----------------------------------------------------------------*/
161 #define AOP(op) op->aop
164 debugAopGet (char *str, operand * op)
169 printOperand (op, debugF);
177 decodeOp (unsigned int op)
180 if (op < 128 && op > ' ')
182 buffer[0] = (op & 0xff);
196 return "STRING_LITERAL";
232 return "LEFT_ASSIGN";
234 return "RIGHT_ASSIGN";
349 case GET_VALUE_AT_ADDRESS:
350 return "GET_VALUE_AT_ADDRESS";
368 return "ENDFUNCTION";
392 sprintf (buffer, "unkown op %d %c", op, op & 0xff);
395 /*-----------------------------------------------------------------*/
396 /*-----------------------------------------------------------------*/
398 debugLogRegType (short type)
411 sprintf (buffer, "unknown reg type %d", type);
415 /*-----------------------------------------------------------------*/
416 /*-----------------------------------------------------------------*/
417 static int regname2key(char const *name)
426 key += (*name++) + 1;
430 return ( (key + (key >> 4) + (key>>8)) & 0x3f);
434 /*-----------------------------------------------------------------*/
435 /* newReg - allocate and init memory for a new register */
436 /*-----------------------------------------------------------------*/
437 static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias)
442 dReg = Safe_calloc(1,sizeof(regs));
444 dReg->pc_type = pc_type;
447 dReg->name = Safe_strdup(name);
449 sprintf(buffer,"r0x%02X", dReg->rIdx);
452 dReg->name = Safe_strdup(buffer);
454 //fprintf(stderr,"newReg: %s, rIdx = 0x%02x\n",dReg->name,rIdx);
467 dReg->reg_alias = NULL;
468 dReg->reglives.usedpFlows = newSet();
469 dReg->reglives.assignedpFlows = newSet();
471 hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
476 /*-----------------------------------------------------------------*/
477 /* regWithIdx - Search through a set of registers that matches idx */
478 /*-----------------------------------------------------------------*/
480 regWithIdx (set *dRegs, int idx, int fixed)
484 for (dReg = setFirstItem(dRegs) ; dReg ;
485 dReg = setNextItem(dRegs)) {
487 if(idx == dReg->rIdx && (fixed == dReg->isFixed)) {
495 /*-----------------------------------------------------------------*/
496 /* regFindFree - Search for a free register in a set of registers */
497 /*-----------------------------------------------------------------*/
499 regFindFree (set *dRegs)
503 for (dReg = setFirstItem(dRegs) ; dReg ;
504 dReg = setNextItem(dRegs)) {
512 /*-----------------------------------------------------------------*/
513 /* initStack - allocate registers for a psuedo stack */
514 /*-----------------------------------------------------------------*/
515 void initStack(int base_address, int size)
520 Gstack_base_addr = base_address;
521 //fprintf(stderr,"initStack");
523 for(i = 0; i<size; i++)
524 addSet(&dynStackRegs,newReg(REG_STK, PO_GPR_TEMP,base_address++,NULL,1,0));
527 /*-----------------------------------------------------------------*
528 *-----------------------------------------------------------------*/
530 allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
533 //fprintf(stderr,"allocProcessorRegister %s addr =0x%x\n",name,rIdx);
534 return addSet(&dynProcessorRegs,newReg(REG_SFR, po_type, rIdx, name,1,alias));
537 /*-----------------------------------------------------------------*
538 *-----------------------------------------------------------------*/
541 allocInternalRegister(int rIdx, char * name, short po_type, int alias)
543 regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias);
545 //fprintf(stderr,"allocInternalRegister %s addr =0x%x\n",name,rIdx);
548 return addSet(&dynInternalRegs,reg);
553 /*-----------------------------------------------------------------*/
554 /* allocReg - allocates register of given type */
555 /*-----------------------------------------------------------------*/
557 allocReg (short type)
560 debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
561 //fprintf(stderr,"allocReg\n");
564 return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
569 /*-----------------------------------------------------------------*/
570 /* dirregWithName - search for register by name */
571 /*-----------------------------------------------------------------*/
573 dirregWithName (char *name)
581 /* hash the name to get a key */
583 hkey = regname2key(name);
585 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
589 if(STRCASECMP(reg->name, name) == 0) {
593 reg = hTabNextItemWK (dynDirectRegNames);
597 return NULL; // name wasn't found in the hash table
600 int IS_CONFIG_ADDRESS(int address)
603 return address == 0x2007;
606 /*-----------------------------------------------------------------*/
607 /* allocDirReg - allocates register of given type */
608 /*-----------------------------------------------------------------*/
610 allocDirReg (operand *op )
617 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
621 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
623 /* If the symbol is at a fixed address, then remove the leading underscore
624 * from the name. This is hack to allow the .asm include file named registers
625 * to match the .c declared register names */
627 //if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && (*name == '_'))
630 debugLog ("%s symbol name %s\n", __FUNCTION__,name);
632 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
633 debugLog(" %d const char\n",__LINE__);
634 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
637 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
638 if (IS_CODE ( OP_SYM_ETYPE(op)) )
639 debugLog(" %d code space\n",__LINE__);
641 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
642 debugLog(" %d integral\n",__LINE__);
643 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
644 debugLog(" %d literal\n",__LINE__);
645 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
646 debugLog(" %d specifier\n",__LINE__);
647 debugAopGet(NULL, op);
650 if (IS_CODE ( OP_SYM_ETYPE(op)) )
653 /* First, search the hash table to see if there is a register with this name */
654 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && !(IS_BITVAR (OP_SYM_ETYPE(op))) ) {
655 reg = regWithIdx (dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1);
658 fprintf(stderr,"ralloc %s is at fixed address but not a processor reg, addr=0x%x\n",
659 name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
661 fprintf(stderr,"ralloc %s at fixed address has already been declared, addr=0x%x\n",
662 name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
665 //fprintf(stderr,"ralloc:%d %s \n", __LINE__,name);
667 reg = dirregWithName(name);
673 /* if this is at an absolute address, then get the address. */
674 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
675 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
676 //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
679 /* Register wasn't found in hash, so let's create
680 * a new one and put it in the hash table AND in the
681 * dynDirectRegNames set */
682 if(!IS_CONFIG_ADDRESS(address)) {
683 //fprintf(stderr,"allocating new reg %s\n",name);
685 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0 );
686 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
688 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
690 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
692 //fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
696 if (IS_BITVAR (OP_SYM_ETYPE(op))) {
697 addSet(&dynDirectBitRegs, reg);
700 addSet(&dynDirectRegs, reg);
703 debugLog (" -- %s is declared at address 0x2007\n",name);
708 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
710 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
711 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
717 /*-----------------------------------------------------------------*/
718 /* allocDirReg - allocates register of given type */
719 /*-----------------------------------------------------------------*/
721 allocRegByName (char *name, int size)
727 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
731 /* First, search the hash table to see if there is a register with this name */
732 reg = dirregWithName(name);
736 /* Register wasn't found in hash, so let's create
737 * a new one and put it in the hash table AND in the
738 * dynDirectRegNames set */
739 //fprintf (stderr,"%s symbol name %s\n", __FUNCTION__,name);
740 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0 );
742 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
744 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
745 addSet(&dynDirectRegs, reg);
751 /*-----------------------------------------------------------------*/
752 /* RegWithIdx - returns pointer to register with index number */
753 /*-----------------------------------------------------------------*/
755 typeRegWithIdx (int idx, int type, int fixed)
760 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
765 if( (dReg = regWithIdx ( dynAllocRegs, idx, fixed)) != NULL) {
767 debugLog ("Found a Dynamic Register!\n");
770 if( (dReg = regWithIdx ( dynDirectRegs, idx, fixed)) != NULL ) {
771 debugLog ("Found a Direct Register!\n");
777 if( (dReg = regWithIdx ( dynStackRegs, idx, fixed)) != NULL ) {
778 debugLog ("Found a Stack Register!\n");
783 if( (dReg = regWithIdx ( dynProcessorRegs, idx, fixed)) != NULL ) {
784 debugLog ("Found a Processor Register!\n");
798 /*-----------------------------------------------------------------*/
799 /* pic14_regWithIdx - returns pointer to register with index number*/
800 /*-----------------------------------------------------------------*/
802 pic14_regWithIdx (int idx)
806 if( (dReg = typeRegWithIdx(idx,REG_GPR,0)) != NULL)
809 if( (dReg = typeRegWithIdx(idx,REG_SFR,0)) != NULL)
812 if( (dReg = typeRegWithIdx(idx,REG_STK,0)) != NULL)
818 /*-----------------------------------------------------------------*/
819 /* pic14_regWithIdx - returns pointer to register with index number */
820 /*-----------------------------------------------------------------*/
822 pic14_allocWithIdx (int idx)
827 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
829 if( (dReg = regWithIdx ( dynAllocRegs, idx,0)) != NULL) {
831 debugLog ("Found a Dynamic Register!\n");
832 } else if( (dReg = regWithIdx ( dynStackRegs, idx,0)) != NULL ) {
833 debugLog ("Found a Stack Register!\n");
834 } else if( (dReg = regWithIdx ( dynProcessorRegs, idx,0)) != NULL ) {
835 debugLog ("Found a Processor Register!\n");
836 } else if( (dReg = regWithIdx ( dynInternalRegs, idx,0)) != NULL ) {
837 debugLog ("Found an Internal Register!\n");
840 debugLog ("Dynamic Register not found\n");
843 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
844 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
845 "regWithIdx not found");
855 /*-----------------------------------------------------------------*/
856 /*-----------------------------------------------------------------*/
858 pic14_findFreeReg(short type)
865 if((dReg = regFindFree(dynAllocRegs)) != NULL)
867 return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
871 if((dReg = regFindFree(dynStackRegs)) != NULL)
883 /*-----------------------------------------------------------------*/
884 /* freeReg - frees a register */
885 /*-----------------------------------------------------------------*/
889 debugLog ("%s\n", __FUNCTION__);
894 /*-----------------------------------------------------------------*/
895 /* nFreeRegs - returns number of free registers */
896 /*-----------------------------------------------------------------*/
900 /* dynamically allocate as many as we need and worry about
901 * fitting them into a PIC later */
908 debugLog ("%s\n", __FUNCTION__);
909 for (i = 0; i < pic14_nRegs; i++)
910 if (regspic14[i].isFree && regspic14[i].type == type)
916 /*-----------------------------------------------------------------*/
917 /* nfreeRegsType - free registers with type */
918 /*-----------------------------------------------------------------*/
920 nfreeRegsType (int type)
923 debugLog ("%s\n", __FUNCTION__);
926 if ((nfr = nFreeRegs (type)) == 0)
927 return nFreeRegs (REG_GPR);
930 return nFreeRegs (type);
933 void writeSetUsedRegs(FILE *of, set *dRegs)
938 for (dReg = setFirstItem(dRegs) ; dReg ;
939 dReg = setNextItem(dRegs)) {
942 fprintf (of, "\t%s\n",dReg->name);
946 extern void assignFixedRegisters(set *regset);
947 extern void assignRelocatableRegisters(set *regset,int used);
948 extern void dump_map(void);
949 extern void dump_cblock(FILE *of);
952 void packBits(set *bregs)
957 regs *relocbitfield=NULL;
963 for (regset = bregs ; regset ;
964 regset = regset->next) {
967 breg->isBitField = 1;
968 //fprintf(stderr,"bit reg: %s\n",breg->name);
971 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
973 bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1);
974 breg->rIdx = breg->address & 7;
978 sprintf (buffer, "fbitfield%02x", breg->address);
979 //fprintf(stderr,"new bit field\n");
980 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0);
981 bitfield->isBitField = 1;
982 bitfield->isFixed = 1;
983 bitfield->address = breg->address;
984 addSet(&dynDirectRegs,bitfield);
985 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
987 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
990 breg->reg_alias = bitfield;
994 if(!relocbitfield || bit_no >7) {
997 sprintf (buffer, "bitfield%d", byte_no);
998 //fprintf(stderr,"new relocatable bit field\n");
999 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0);
1000 relocbitfield->isBitField = 1;
1001 addSet(&dynDirectRegs,relocbitfield);
1002 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1006 breg->reg_alias = relocbitfield;
1007 breg->address = rDirectIdx; /* byte_no; */
1008 breg->rIdx = bit_no++;
1016 void bitEQUs(FILE *of, set *bregs)
1018 regs *breg,*bytereg;
1021 //fprintf(stderr," %s\n",__FUNCTION__);
1022 for (breg = setFirstItem(bregs) ; breg ;
1023 breg = setNextItem(bregs)) {
1025 //fprintf(stderr,"bit reg: %s\n",breg->name);
1027 bytereg = breg->reg_alias;
1029 fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
1032 breg->rIdx & 0x0007);
1035 fprintf(stderr, "bit field is not assigned to a register\n");
1036 fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
1046 void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
1051 for (reg = setFirstItem(fregs) ; reg ;
1052 reg = setNextItem(fregs)) {
1054 if(!reg->isEmitted && reg->wasUsed) {
1056 fprintf (of, "%s\tEQU\t0x%03x\n",
1060 fprintf (of, "%s\tEQU\t0x%03x\n",
1068 void writeUsedRegs(FILE *of)
1070 packBits(dynDirectBitRegs);
1073 assignFixedRegisters(dynAllocRegs);
1074 assignFixedRegisters(dynStackRegs);
1075 assignFixedRegisters(dynDirectRegs);
1077 assignRelocatableRegisters(dynInternalRegs,0);
1078 assignRelocatableRegisters(dynAllocRegs,0);
1079 assignRelocatableRegisters(dynStackRegs,0);
1080 assignRelocatableRegisters(dynDirectRegs,0);
1085 bitEQUs(of,dynDirectBitRegs);
1086 aliasEQUs(of,dynAllocRegs,0);
1087 aliasEQUs(of,dynDirectRegs,0);
1088 aliasEQUs(of,dynStackRegs,0);
1089 aliasEQUs(of,dynProcessorRegs,1);
1094 /*-----------------------------------------------------------------*/
1095 /* allDefsOutOfRange - all definitions are out of a range */
1096 /*-----------------------------------------------------------------*/
1098 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
1102 debugLog ("%s\n", __FUNCTION__);
1106 for (i = 0; i < defs->size; i++)
1110 if (bitVectBitValue (defs, i) &&
1111 (ic = hTabItemWithKey (iCodehTab, i)) &&
1112 (ic->seq >= fseq && ic->seq <= toseq))
1122 /*-----------------------------------------------------------------*/
1123 /* computeSpillable - given a point find the spillable live ranges */
1124 /*-----------------------------------------------------------------*/
1126 computeSpillable (iCode * ic)
1130 debugLog ("%s\n", __FUNCTION__);
1131 /* spillable live ranges are those that are live at this
1132 point . the following categories need to be subtracted
1134 a) - those that are already spilt
1135 b) - if being used by this one
1136 c) - defined by this one */
1138 spillable = bitVectCopy (ic->rlive);
1140 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1142 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1143 bitVectUnSetBit (spillable, ic->defKey);
1144 spillable = bitVectIntersect (spillable, _G.regAssigned);
1149 /*-----------------------------------------------------------------*/
1150 /* noSpilLoc - return true if a variable has no spil location */
1151 /*-----------------------------------------------------------------*/
1153 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1155 debugLog ("%s\n", __FUNCTION__);
1156 return (sym->usl.spillLoc ? 0 : 1);
1159 /*-----------------------------------------------------------------*/
1160 /* hasSpilLoc - will return 1 if the symbol has spil location */
1161 /*-----------------------------------------------------------------*/
1163 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1165 debugLog ("%s\n", __FUNCTION__);
1166 return (sym->usl.spillLoc ? 1 : 0);
1169 /*-----------------------------------------------------------------*/
1170 /* directSpilLoc - will return 1 if the splilocation is in direct */
1171 /*-----------------------------------------------------------------*/
1173 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1175 debugLog ("%s\n", __FUNCTION__);
1176 if (sym->usl.spillLoc &&
1177 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1183 /*-----------------------------------------------------------------*/
1184 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1185 /* but is not used as a pointer */
1186 /*-----------------------------------------------------------------*/
1188 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1190 debugLog ("%s\n", __FUNCTION__);
1191 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1194 /*-----------------------------------------------------------------*/
1195 /* rematable - will return 1 if the remat flag is set */
1196 /*-----------------------------------------------------------------*/
1198 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1200 debugLog ("%s\n", __FUNCTION__);
1204 /*-----------------------------------------------------------------*/
1205 /* notUsedInRemaining - not used or defined in remain of the block */
1206 /*-----------------------------------------------------------------*/
1208 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1210 debugLog ("%s\n", __FUNCTION__);
1211 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1212 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1215 /*-----------------------------------------------------------------*/
1216 /* allLRs - return true for all */
1217 /*-----------------------------------------------------------------*/
1219 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1221 debugLog ("%s\n", __FUNCTION__);
1225 /*-----------------------------------------------------------------*/
1226 /* liveRangesWith - applies function to a given set of live range */
1227 /*-----------------------------------------------------------------*/
1229 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1230 eBBlock * ebp, iCode * ic)
1235 debugLog ("%s\n", __FUNCTION__);
1236 if (!lrs || !lrs->size)
1239 for (i = 1; i < lrs->size; i++)
1242 if (!bitVectBitValue (lrs, i))
1245 /* if we don't find it in the live range
1246 hash table we are in serious trouble */
1247 if (!(sym = hTabItemWithKey (liveRanges, i)))
1249 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1250 "liveRangesWith could not find liveRange");
1254 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1255 addSetHead (&rset, sym);
1262 /*-----------------------------------------------------------------*/
1263 /* leastUsedLR - given a set determines which is the least used */
1264 /*-----------------------------------------------------------------*/
1266 leastUsedLR (set * sset)
1268 symbol *sym = NULL, *lsym = NULL;
1270 debugLog ("%s\n", __FUNCTION__);
1271 sym = lsym = setFirstItem (sset);
1276 for (; lsym; lsym = setNextItem (sset))
1279 /* if usage is the same then prefer
1280 the spill the smaller of the two */
1281 if (lsym->used == sym->used)
1282 if (getSize (lsym->type) < getSize (sym->type))
1286 if (lsym->used < sym->used)
1291 setToNull ((void **) &sset);
1296 /*-----------------------------------------------------------------*/
1297 /* noOverLap - will iterate through the list looking for over lap */
1298 /*-----------------------------------------------------------------*/
1300 noOverLap (set * itmpStack, symbol * fsym)
1303 debugLog ("%s\n", __FUNCTION__);
1306 for (sym = setFirstItem (itmpStack); sym;
1307 sym = setNextItem (itmpStack))
1309 if (sym->liveTo > fsym->liveFrom)
1317 /*-----------------------------------------------------------------*/
1318 /* isFree - will return 1 if the a free spil location is found */
1319 /*-----------------------------------------------------------------*/
1324 V_ARG (symbol **, sloc);
1325 V_ARG (symbol *, fsym);
1327 debugLog ("%s\n", __FUNCTION__);
1328 /* if already found */
1332 /* if it is free && and the itmp assigned to
1333 this does not have any overlapping live ranges
1334 with the one currently being assigned and
1335 the size can be accomodated */
1337 noOverLap (sym->usl.itmpStack, fsym) &&
1338 getSize (sym->type) >= getSize (fsym->type))
1347 /*-----------------------------------------------------------------*/
1348 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1349 /*-----------------------------------------------------------------*/
1351 spillLRWithPtrReg (symbol * forSym)
1357 debugLog ("%s\n", __FUNCTION__);
1358 if (!_G.regAssigned ||
1359 bitVectIsZero (_G.regAssigned))
1362 r0 = pic14_regWithIdx (R0_IDX);
1363 r1 = pic14_regWithIdx (R1_IDX);
1365 /* for all live ranges */
1366 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1367 lrsym = hTabNextItem (liveRanges, &k))
1371 /* if no registers assigned to it or
1373 /* if it does not overlap with this then
1374 not need to spill it */
1376 if (lrsym->isspilt || !lrsym->nRegs ||
1377 (lrsym->liveTo < forSym->liveFrom))
1380 /* go thru the registers : if it is either
1381 r0 or r1 then spil it */
1382 for (j = 0; j < lrsym->nRegs; j++)
1383 if (lrsym->regs[j] == r0 ||
1384 lrsym->regs[j] == r1)
1393 /*-----------------------------------------------------------------*/
1394 /* createStackSpil - create a location on the stack to spil */
1395 /*-----------------------------------------------------------------*/
1397 createStackSpil (symbol * sym)
1399 symbol *sloc = NULL;
1400 int useXstack, model, noOverlay;
1402 char slocBuffer[30];
1403 debugLog ("%s\n", __FUNCTION__);
1405 /* first go try and find a free one that is already
1406 existing on the stack */
1407 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1409 /* found a free one : just update & return */
1410 sym->usl.spillLoc = sloc;
1413 addSetHead (&sloc->usl.itmpStack, sym);
1417 /* could not then have to create one , this is the hard part
1418 we need to allocate this on the stack : this is really a
1419 hack!! but cannot think of anything better at this time */
1421 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1423 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1424 __FILE__, __LINE__);
1428 sloc = newiTemp (slocBuffer);
1430 /* set the type to the spilling symbol */
1431 sloc->type = copyLinkChain (sym->type);
1432 sloc->etype = getSpec (sloc->type);
1433 SPEC_SCLS (sloc->etype) = S_DATA;
1434 SPEC_EXTR (sloc->etype) = 0;
1435 SPEC_STAT (sloc->etype) = 0;
1437 /* we don't allow it to be allocated`
1438 onto the external stack since : so we
1439 temporarily turn it off ; we also
1440 turn off memory model to prevent
1441 the spil from going to the external storage
1442 and turn off overlaying
1445 useXstack = options.useXstack;
1446 model = options.model;
1447 noOverlay = options.noOverlay;
1448 options.noOverlay = 1;
1449 options.model = options.useXstack = 0;
1453 options.useXstack = useXstack;
1454 options.model = model;
1455 options.noOverlay = noOverlay;
1456 sloc->isref = 1; /* to prevent compiler warning */
1458 /* if it is on the stack then update the stack */
1459 if (IN_STACK (sloc->etype))
1461 currFunc->stack += getSize (sloc->type);
1462 _G.stackExtend += getSize (sloc->type);
1465 _G.dataExtend += getSize (sloc->type);
1467 /* add it to the _G.stackSpil set */
1468 addSetHead (&_G.stackSpil, sloc);
1469 sym->usl.spillLoc = sloc;
1472 /* add it to the set of itempStack set
1473 of the spill location */
1474 addSetHead (&sloc->usl.itmpStack, sym);
1478 /*-----------------------------------------------------------------*/
1479 /* isSpiltOnStack - returns true if the spil location is on stack */
1480 /*-----------------------------------------------------------------*/
1482 isSpiltOnStack (symbol * sym)
1486 debugLog ("%s\n", __FUNCTION__);
1493 /* if (sym->_G.stackSpil) */
1496 if (!sym->usl.spillLoc)
1499 etype = getSpec (sym->usl.spillLoc->type);
1500 if (IN_STACK (etype))
1506 /*-----------------------------------------------------------------*/
1507 /* spillThis - spils a specific operand */
1508 /*-----------------------------------------------------------------*/
1510 spillThis (symbol * sym)
1513 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1515 /* if this is rematerializable or has a spillLocation
1516 we are okay, else we need to create a spillLocation
1518 if (!(sym->remat || sym->usl.spillLoc))
1519 createStackSpil (sym);
1522 /* mark it has spilt & put it in the spilt set */
1524 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1526 bitVectUnSetBit (_G.regAssigned, sym->key);
1528 for (i = 0; i < sym->nRegs; i++)
1532 freeReg (sym->regs[i]);
1533 sym->regs[i] = NULL;
1536 /* if spilt on stack then free up r0 & r1
1537 if they could have been assigned to some
1539 if (!pic14_ptrRegReq && isSpiltOnStack (sym))
1542 spillLRWithPtrReg (sym);
1545 if (sym->usl.spillLoc && !sym->remat)
1546 sym->usl.spillLoc->allocreq = 1;
1550 /*-----------------------------------------------------------------*/
1551 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1552 /*-----------------------------------------------------------------*/
1554 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1556 bitVect *lrcs = NULL;
1560 debugLog ("%s\n", __FUNCTION__);
1561 /* get the spillable live ranges */
1562 lrcs = computeSpillable (ic);
1564 /* get all live ranges that are rematerizable */
1565 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1568 /* return the least used of these */
1569 return leastUsedLR (selectS);
1572 /* get live ranges with spillLocations in direct space */
1573 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1575 sym = leastUsedLR (selectS);
1576 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1577 sym->usl.spillLoc->rname :
1578 sym->usl.spillLoc->name));
1580 /* mark it as allocation required */
1581 sym->usl.spillLoc->allocreq = 1;
1585 /* if the symbol is local to the block then */
1586 if (forSym->liveTo < ebp->lSeq)
1589 /* check if there are any live ranges allocated
1590 to registers that are not used in this block */
1591 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1593 sym = leastUsedLR (selectS);
1594 /* if this is not rematerializable */
1603 /* check if there are any live ranges that not
1604 used in the remainder of the block */
1605 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1607 sym = leastUsedLR (selectS);
1610 sym->remainSpil = 1;
1617 /* find live ranges with spillocation && not used as pointers */
1618 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1621 sym = leastUsedLR (selectS);
1622 /* mark this as allocation required */
1623 sym->usl.spillLoc->allocreq = 1;
1627 /* find live ranges with spillocation */
1628 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1631 sym = leastUsedLR (selectS);
1632 sym->usl.spillLoc->allocreq = 1;
1636 /* couldn't find then we need to create a spil
1637 location on the stack , for which one? the least
1639 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1642 /* return a created spil location */
1643 sym = createStackSpil (leastUsedLR (selectS));
1644 sym->usl.spillLoc->allocreq = 1;
1648 /* this is an extreme situation we will spill
1649 this one : happens very rarely but it does happen */
1655 /*-----------------------------------------------------------------*/
1656 /* spilSomething - spil some variable & mark registers as free */
1657 /*-----------------------------------------------------------------*/
1659 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1664 debugLog ("%s\n", __FUNCTION__);
1665 /* get something we can spil */
1666 ssym = selectSpil (ic, ebp, forSym);
1668 /* mark it as spilt */
1670 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1672 /* mark it as not register assigned &
1673 take it away from the set */
1674 bitVectUnSetBit (_G.regAssigned, ssym->key);
1676 /* mark the registers as free */
1677 for (i = 0; i < ssym->nRegs; i++)
1679 freeReg (ssym->regs[i]);
1681 /* if spilt on stack then free up r0 & r1
1682 if they could have been assigned to as gprs */
1683 if (!pic14_ptrRegReq && isSpiltOnStack (ssym))
1686 spillLRWithPtrReg (ssym);
1689 /* if this was a block level spil then insert push & pop
1690 at the start & end of block respectively */
1691 if (ssym->blockSpil)
1693 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1694 /* add push to the start of the block */
1695 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1696 ebp->sch->next : ebp->sch));
1697 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1698 /* add pop to the end of the block */
1699 addiCodeToeBBlock (ebp, nic, NULL);
1702 /* if spilt because not used in the remainder of the
1703 block then add a push before this instruction and
1704 a pop at the end of the block */
1705 if (ssym->remainSpil)
1708 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1709 /* add push just before this instruction */
1710 addiCodeToeBBlock (ebp, nic, ic);
1712 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1713 /* add pop to the end of the block */
1714 addiCodeToeBBlock (ebp, nic, NULL);
1723 /*-----------------------------------------------------------------*/
1724 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1725 /*-----------------------------------------------------------------*/
1727 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1731 debugLog ("%s\n", __FUNCTION__);
1733 /* try for a ptr type */
1734 if ((reg = allocReg (REG_PTR)))
1737 /* try for gpr type */
1738 if ((reg = allocReg (REG_GPR)))
1741 /* we have to spil */
1742 if (!spilSomething (ic, ebp, sym))
1745 /* this looks like an infinite loop but
1746 in really selectSpil will abort */
1750 /*-----------------------------------------------------------------*/
1751 /* getRegGpr - will try for GPR if not spil */
1752 /*-----------------------------------------------------------------*/
1754 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1758 debugLog ("%s\n", __FUNCTION__);
1760 /* try for gpr type */
1761 if ((reg = allocReg (REG_GPR)))
1764 if (!pic14_ptrRegReq)
1765 if ((reg = allocReg (REG_PTR)))
1768 /* we have to spil */
1769 if (!spilSomething (ic, ebp, sym))
1772 /* this looks like an infinite loop but
1773 in really selectSpil will abort */
1777 /*-----------------------------------------------------------------*/
1778 /* symHasReg - symbol has a given register */
1779 /*-----------------------------------------------------------------*/
1781 symHasReg (symbol * sym, regs * reg)
1785 debugLog ("%s\n", __FUNCTION__);
1786 for (i = 0; i < sym->nRegs; i++)
1787 if (sym->regs[i] == reg)
1793 /*-----------------------------------------------------------------*/
1794 /* deassignLRs - check the live to and if they have registers & are */
1795 /* not spilt then free up the registers */
1796 /*-----------------------------------------------------------------*/
1798 deassignLRs (iCode * ic, eBBlock * ebp)
1804 debugLog ("%s\n", __FUNCTION__);
1805 for (sym = hTabFirstItem (liveRanges, &k); sym;
1806 sym = hTabNextItem (liveRanges, &k))
1809 symbol *psym = NULL;
1810 /* if it does not end here */
1811 if (sym->liveTo > ic->seq)
1814 /* if it was spilt on stack then we can
1815 mark the stack spil location as free */
1820 sym->usl.spillLoc->isFree = 1;
1826 if (!bitVectBitValue (_G.regAssigned, sym->key))
1829 /* special case check if this is an IFX &
1830 the privious one was a pop and the
1831 previous one was not spilt then keep track
1833 if (ic->op == IFX && ic->prev &&
1834 ic->prev->op == IPOP &&
1835 !ic->prev->parmPush &&
1836 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1837 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1843 bitVectUnSetBit (_G.regAssigned, sym->key);
1845 /* if the result of this one needs registers
1846 and does not have it then assign it right
1848 if (IC_RESULT (ic) &&
1849 !(SKIP_IC2 (ic) || /* not a special icode */
1850 ic->op == JUMPTABLE ||
1855 POINTER_SET (ic)) &&
1856 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1857 result->liveTo > ic->seq && /* and will live beyond this */
1858 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1859 result->regType == sym->regType && /* same register types */
1860 result->nRegs && /* which needs registers */
1861 !result->isspilt && /* and does not already have them */
1863 !bitVectBitValue (_G.regAssigned, result->key) &&
1864 /* the number of free regs + number of regs in this LR
1865 can accomodate the what result Needs */
1866 ((nfreeRegsType (result->regType) +
1867 sym->nRegs) >= result->nRegs)
1871 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1873 result->regs[i] = sym->regs[i];
1875 result->regs[i] = getRegGpr (ic, ebp, result);
1877 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1881 /* free the remaining */
1882 for (; i < sym->nRegs; i++)
1886 if (!symHasReg (psym, sym->regs[i]))
1887 freeReg (sym->regs[i]);
1890 freeReg (sym->regs[i]);
1897 /*-----------------------------------------------------------------*/
1898 /* reassignLR - reassign this to registers */
1899 /*-----------------------------------------------------------------*/
1901 reassignLR (operand * op)
1903 symbol *sym = OP_SYMBOL (op);
1906 debugLog ("%s\n", __FUNCTION__);
1907 /* not spilt any more */
1908 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1909 bitVectUnSetBit (_G.spiltSet, sym->key);
1911 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1915 for (i = 0; i < sym->nRegs; i++)
1916 sym->regs[i]->isFree = 0;
1919 /*-----------------------------------------------------------------*/
1920 /* willCauseSpill - determines if allocating will cause a spill */
1921 /*-----------------------------------------------------------------*/
1923 willCauseSpill (int nr, int rt)
1925 debugLog ("%s\n", __FUNCTION__);
1926 /* first check if there are any avlb registers
1927 of te type required */
1930 /* special case for pointer type
1931 if pointer type not avlb then
1932 check for type gpr */
1933 if (nFreeRegs (rt) >= nr)
1935 if (nFreeRegs (REG_GPR) >= nr)
1940 if (pic14_ptrRegReq)
1942 if (nFreeRegs (rt) >= nr)
1947 if (nFreeRegs (REG_PTR) +
1948 nFreeRegs (REG_GPR) >= nr)
1953 debugLog (" ... yep it will (cause a spill)\n");
1954 /* it will cause a spil */
1958 /*-----------------------------------------------------------------*/
1959 /* positionRegs - the allocator can allocate same registers to res- */
1960 /* ult and operand, if this happens make sure they are in the same */
1961 /* position as the operand otherwise chaos results */
1962 /*-----------------------------------------------------------------*/
1964 positionRegs (symbol * result, symbol * opsym, int lineno)
1966 int count = min (result->nRegs, opsym->nRegs);
1967 int i, j = 0, shared = 0;
1969 debugLog ("%s\n", __FUNCTION__);
1970 /* if the result has been spilt then cannot share */
1975 /* first make sure that they actually share */
1976 for (i = 0; i < count; i++)
1978 for (j = 0; j < count; j++)
1980 if (result->regs[i] == opsym->regs[j] && i != j)
1990 regs *tmp = result->regs[i];
1991 result->regs[i] = result->regs[j];
1992 result->regs[j] = tmp;
1997 /*-----------------------------------------------------------------*/
1998 /* serialRegAssign - serially allocate registers to the variables */
1999 /*-----------------------------------------------------------------*/
2001 serialRegAssign (eBBlock ** ebbs, int count)
2005 debugLog ("%s\n", __FUNCTION__);
2006 /* for all blocks */
2007 for (i = 0; i < count; i++)
2012 if (ebbs[i]->noPath &&
2013 (ebbs[i]->entryLabel != entryLabel &&
2014 ebbs[i]->entryLabel != returnLabel))
2017 /* of all instructions do */
2018 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2021 debugLog (" op: %s\n", decodeOp (ic->op));
2023 /* if this is an ipop that means some live
2024 range will have to be assigned again */
2026 reassignLR (IC_LEFT (ic));
2028 /* if result is present && is a true symbol */
2029 if (IC_RESULT (ic) && ic->op != IFX &&
2030 IS_TRUE_SYMOP (IC_RESULT (ic)))
2031 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2033 /* take away registers from live
2034 ranges that end at this instruction */
2035 deassignLRs (ic, ebbs[i]);
2037 /* some don't need registers */
2038 if (SKIP_IC2 (ic) ||
2039 ic->op == JUMPTABLE ||
2043 (IC_RESULT (ic) && POINTER_SET (ic)))
2046 /* now we need to allocate registers
2047 only for the result */
2050 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2056 /* if it does not need or is spilt
2057 or is already assigned to registers
2058 or will not live beyond this instructions */
2061 bitVectBitValue (_G.regAssigned, sym->key) ||
2062 sym->liveTo <= ic->seq)
2065 /* if some liverange has been spilt at the block level
2066 and this one live beyond this block then spil this
2068 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2073 /* if trying to allocate this will cause
2074 a spill and there is nothing to spill
2075 or this one is rematerializable then
2077 willCS = willCauseSpill (sym->nRegs, sym->regType);
2078 spillable = computeSpillable (ic);
2080 (willCS && bitVectIsZero (spillable)))
2088 /* if it has a spillocation & is used less than
2089 all other live ranges then spill this */
2091 if (sym->usl.spillLoc) {
2092 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2093 allLRs, ebbs[i], ic));
2094 if (leastUsed && leastUsed->used > sym->used) {
2099 /* if none of the liveRanges have a spillLocation then better
2100 to spill this one than anything else already assigned to registers */
2101 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2102 /* if this is local to this block then we might find a block spil */
2103 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2111 if (ic->op == RECEIVE)
2112 debugLog ("When I get clever, I'll optimize the receive logic\n");
2114 /* if we need ptr regs for the right side
2116 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2117 <= (unsigned) PTRSIZE)
2122 /* else we assign registers to it */
2123 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2125 debugLog (" %d - \n", __LINE__);
2127 bitVectDebugOn(_G.regAssigned, debugF);
2129 for (j = 0; j < sym->nRegs; j++)
2131 if (sym->regType == REG_PTR)
2132 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2134 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2136 /* if the allocation falied which means
2137 this was spilt then break */
2141 debugLog (" %d - \n", __LINE__);
2143 /* if it shares registers with operands make sure
2144 that they are in the same position */
2145 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2146 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2147 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2148 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2149 /* do the same for the right operand */
2150 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2151 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2152 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2153 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2155 debugLog (" %d - \n", __LINE__);
2158 debugLog (" %d - \n", __LINE__);
2168 /*-----------------------------------------------------------------*/
2169 /* rUmaskForOp :- returns register mask for an operand */
2170 /*-----------------------------------------------------------------*/
2172 rUmaskForOp (operand * op)
2178 debugLog ("%s\n", __FUNCTION__);
2179 /* only temporaries are assigned registers */
2183 sym = OP_SYMBOL (op);
2185 /* if spilt or no registers assigned to it
2187 if (sym->isspilt || !sym->nRegs)
2190 rumask = newBitVect (pic14_nRegs);
2192 for (j = 0; j < sym->nRegs; j++)
2194 rumask = bitVectSetBit (rumask,
2195 sym->regs[j]->rIdx);
2201 /*-----------------------------------------------------------------*/
2202 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2203 /*-----------------------------------------------------------------*/
2205 regsUsedIniCode (iCode * ic)
2207 bitVect *rmask = newBitVect (pic14_nRegs);
2209 debugLog ("%s\n", __FUNCTION__);
2210 /* do the special cases first */
2213 rmask = bitVectUnion (rmask,
2214 rUmaskForOp (IC_COND (ic)));
2218 /* for the jumptable */
2219 if (ic->op == JUMPTABLE)
2221 rmask = bitVectUnion (rmask,
2222 rUmaskForOp (IC_JTCOND (ic)));
2227 /* of all other cases */
2229 rmask = bitVectUnion (rmask,
2230 rUmaskForOp (IC_LEFT (ic)));
2234 rmask = bitVectUnion (rmask,
2235 rUmaskForOp (IC_RIGHT (ic)));
2238 rmask = bitVectUnion (rmask,
2239 rUmaskForOp (IC_RESULT (ic)));
2245 /*-----------------------------------------------------------------*/
2246 /* createRegMask - for each instruction will determine the regsUsed */
2247 /*-----------------------------------------------------------------*/
2249 createRegMask (eBBlock ** ebbs, int count)
2253 debugLog ("%s\n", __FUNCTION__);
2254 /* for all blocks */
2255 for (i = 0; i < count; i++)
2259 if (ebbs[i]->noPath &&
2260 (ebbs[i]->entryLabel != entryLabel &&
2261 ebbs[i]->entryLabel != returnLabel))
2264 /* for all instructions */
2265 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2270 if (SKIP_IC2 (ic) || !ic->rlive)
2273 /* first mark the registers used in this
2275 ic->rUsed = regsUsedIniCode (ic);
2276 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2278 /* now create the register mask for those
2279 registers that are in use : this is a
2280 super set of ic->rUsed */
2281 ic->rMask = newBitVect (pic14_nRegs + 1);
2283 /* for all live Ranges alive at this point */
2284 for (j = 1; j < ic->rlive->size; j++)
2289 /* if not alive then continue */
2290 if (!bitVectBitValue (ic->rlive, j))
2293 /* find the live range we are interested in */
2294 if (!(sym = hTabItemWithKey (liveRanges, j)))
2296 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2297 "createRegMask cannot find live range");
2301 /* if no register assigned to it */
2302 if (!sym->nRegs || sym->isspilt)
2305 /* for all the registers allocated to it */
2306 for (k = 0; k < sym->nRegs; k++)
2309 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2315 /*-----------------------------------------------------------------*/
2316 /* rematStr - returns the rematerialized string for a remat var */
2317 /*-----------------------------------------------------------------*/
2319 rematStr (symbol * sym)
2322 iCode *ic = sym->rematiCode;
2323 symbol *psym = NULL;
2325 debugLog ("%s\n", __FUNCTION__);
2327 //printf ("%s\n", s);
2329 /* if plus or minus print the right hand side */
2331 if (ic->op == '+' || ic->op == '-') {
2333 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2335 sprintf (s, "(%s %c 0x%04x)",
2336 OP_SYMBOL (IC_LEFT (ric))->rname,
2338 (int) operandLitValue (IC_RIGHT (ic)));
2341 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2343 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2344 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2349 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2350 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2352 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2357 /*-----------------------------------------------------------------*/
2358 /* rematStr - returns the rematerialized string for a remat var */
2359 /*-----------------------------------------------------------------*/
2361 rematStr (symbol * sym)
2364 iCode *ic = sym->rematiCode;
2366 debugLog ("%s\n", __FUNCTION__);
2371 /* if plus or minus print the right hand side */
2373 if (ic->op == '+' || ic->op == '-') {
2374 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2377 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2381 if (ic->op == '+' || ic->op == '-')
2383 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2384 sprintf (s, "(%s %c 0x%04x)",
2385 OP_SYMBOL (IC_LEFT (ric))->rname,
2387 (int) operandLitValue (IC_RIGHT (ic)));
2390 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2392 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2396 /* we reached the end */
2397 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2401 printf ("%s\n", buffer);
2406 /*-----------------------------------------------------------------*/
2407 /* regTypeNum - computes the type & number of registers required */
2408 /*-----------------------------------------------------------------*/
2416 debugLog ("%s\n", __FUNCTION__);
2417 /* for each live range do */
2418 for (sym = hTabFirstItem (liveRanges, &k); sym;
2419 sym = hTabNextItem (liveRanges, &k)) {
2421 debugLog (" %d - %s\n", __LINE__, sym->rname);
2423 /* if used zero times then no registers needed */
2424 if ((sym->liveTo - sym->liveFrom) == 0)
2428 /* if the live range is a temporary */
2431 debugLog (" %d - itemp register\n", __LINE__);
2433 /* if the type is marked as a conditional */
2434 if (sym->regType == REG_CND)
2437 /* if used in return only then we don't
2440 if (IS_AGGREGATE (sym->type) || sym->isptr)
2441 sym->type = aggrToPtr (sym->type, FALSE);
2442 debugLog (" %d - no reg needed - accumulator used\n", __LINE__);
2448 //if (IS_AGGREGATE (sym->type) || sym->isptr)
2449 // sym->type = aggrToPtr (sym->type, FALSE);
2450 debugLog (" %d - used as a return\n", __LINE__);
2455 /* if the symbol has only one definition &
2456 that definition is a get_pointer and the
2457 pointer we are getting is rematerializable and
2460 if (bitVectnBitsOn (sym->defs) == 1 &&
2461 (ic = hTabItemWithKey (iCodehTab,
2462 bitVectFirstBit (sym->defs))) &&
2465 !IS_BITVAR (sym->etype)) {
2468 debugLog (" %d - \n", __LINE__);
2470 /* if remat in data space */
2471 if (OP_SYMBOL (IC_LEFT (ic))->remat &&
2472 DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) {
2474 /* create a psuedo symbol & force a spil */
2475 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2476 symbol *psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2477 psym->type = sym->type;
2478 psym->etype = sym->etype;
2479 strcpy (psym->rname, psym->name);
2481 sym->usl.spillLoc = psym;
2485 /* if in data space or idata space then try to
2486 allocate pointer register */
2490 /* if not then we require registers */
2491 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2492 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2493 getSize (sym->type));
2496 if(IS_PTR_CONST (sym->type)) {
2497 debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2501 if (sym->nRegs > 4) {
2502 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2503 printTypeChain (sym->type, stderr);
2504 fprintf (stderr, "\n");
2507 /* determine the type of register required */
2508 if (sym->nRegs == 1 &&
2509 IS_PTR (sym->type) &&
2511 sym->regType = REG_PTR;
2513 sym->regType = REG_GPR;
2516 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2520 /* for the first run we don't provide */
2521 /* registers for true symbols we will */
2522 /* see how things go */
2527 DEFSETFUNC (markRegFree)
2529 ((regs *)item)->isFree = 1;
2534 DEFSETFUNC (deallocReg)
2536 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2537 ((regs *)item)->isFree = 1;
2538 ((regs *)item)->wasUsed = 0;
2542 /*-----------------------------------------------------------------*/
2543 /* freeAllRegs - mark all registers as free */
2544 /*-----------------------------------------------------------------*/
2546 pic14_freeAllRegs ()
2550 debugLog ("%s\n", __FUNCTION__);
2552 applyToSet(dynAllocRegs,markRegFree);
2553 applyToSet(dynStackRegs,markRegFree);
2556 for (i = 0; i < pic14_nRegs; i++)
2557 regspic14[i].isFree = 1;
2561 /*-----------------------------------------------------------------*/
2562 /*-----------------------------------------------------------------*/
2564 pic14_deallocateAllRegs ()
2568 debugLog ("%s\n", __FUNCTION__);
2570 applyToSet(dynAllocRegs,deallocReg);
2573 for (i = 0; i < pic14_nRegs; i++) {
2574 if(regspic14[i].pc_type == PO_GPR_TEMP) {
2575 regspic14[i].isFree = 1;
2576 regspic14[i].wasUsed = 0;
2583 /*-----------------------------------------------------------------*/
2584 /* deallocStackSpil - this will set the stack pointer back */
2585 /*-----------------------------------------------------------------*/
2587 DEFSETFUNC (deallocStackSpil)
2591 debugLog ("%s\n", __FUNCTION__);
2596 /*-----------------------------------------------------------------*/
2597 /* farSpacePackable - returns the packable icode for far variables */
2598 /*-----------------------------------------------------------------*/
2600 farSpacePackable (iCode * ic)
2604 debugLog ("%s\n", __FUNCTION__);
2605 /* go thru till we find a definition for the
2606 symbol on the right */
2607 for (dic = ic->prev; dic; dic = dic->prev)
2610 /* if the definition is a call then no */
2611 if ((dic->op == CALL || dic->op == PCALL) &&
2612 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2617 /* if shift by unknown amount then not */
2618 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2619 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2622 /* if pointer get and size > 1 */
2623 if (POINTER_GET (dic) &&
2624 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2627 if (POINTER_SET (dic) &&
2628 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2631 /* if any three is a true symbol in far space */
2632 if (IC_RESULT (dic) &&
2633 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2634 isOperandInFarSpace (IC_RESULT (dic)))
2637 if (IC_RIGHT (dic) &&
2638 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2639 isOperandInFarSpace (IC_RIGHT (dic)) &&
2640 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2643 if (IC_LEFT (dic) &&
2644 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2645 isOperandInFarSpace (IC_LEFT (dic)) &&
2646 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2649 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2651 if ((dic->op == LEFT_OP ||
2652 dic->op == RIGHT_OP ||
2654 IS_OP_LITERAL (IC_RIGHT (dic)))
2664 /*-----------------------------------------------------------------*/
2665 /* packRegsForAssign - register reduction for assignment */
2666 /*-----------------------------------------------------------------*/
2668 packRegsForAssign (iCode * ic, eBBlock * ebp)
2673 debugLog ("%s\n", __FUNCTION__);
2675 debugAopGet (" result:", IC_RESULT (ic));
2676 debugAopGet (" left:", IC_LEFT (ic));
2677 debugAopGet (" right:", IC_RIGHT (ic));
2679 /* if this is at an absolute address, then get the address. */
2680 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2681 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2682 debugLog (" %d - found config word declaration\n", __LINE__);
2683 if(IS_VALOP(IC_RIGHT(ic))) {
2684 debugLog (" setting config word to %x\n",
2685 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2686 assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2687 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2690 /* remove the assignment from the iCode chain. */
2692 remiCodeFromeBBlock (ebp, ic);
2693 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2694 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2701 if (!IS_ITEMP (IC_RESULT (ic))) {
2702 allocDirReg(IC_RESULT (ic));
2703 debugLog (" %d - result is not temp\n", __LINE__);
2706 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2707 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2708 allocDirReg(IC_LEFT (ic));
2712 if (!IS_ITEMP (IC_RIGHT (ic))) {
2713 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2714 allocDirReg(IC_RIGHT (ic));
2718 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2719 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2721 debugLog (" %d - not packing - right side fails \n", __LINE__);
2725 /* if the true symbol is defined in far space or on stack
2726 then we should not since this will increase register pressure */
2727 if (isOperandInFarSpace (IC_RESULT (ic)))
2729 if ((dic = farSpacePackable (ic)))
2735 /* find the definition of iTempNN scanning backwards if we find a
2736 a use of the true symbol before we find the definition then
2738 for (dic = ic->prev; dic; dic = dic->prev)
2741 /* if there is a function call and this is
2742 a parameter & not my parameter then don't pack it */
2743 if ((dic->op == CALL || dic->op == PCALL) &&
2744 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2745 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2747 debugLog (" %d - \n", __LINE__);
2755 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2756 IS_OP_VOLATILE (IC_RESULT (dic)))
2758 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2763 if (IS_SYMOP (IC_RESULT (dic)) &&
2764 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2766 /* A previous result was assigned to the same register - we'll our definition */
2767 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2768 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2769 if (POINTER_SET (dic))
2775 if (IS_SYMOP (IC_RIGHT (dic)) &&
2776 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2777 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2779 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
2784 if (IS_SYMOP (IC_LEFT (dic)) &&
2785 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2786 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2788 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
2793 if (POINTER_SET (dic) &&
2794 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2796 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
2804 return 0; /* did not find */
2806 /* if the result is on stack or iaccess then it must be
2807 the same atleast one of the operands */
2808 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2809 OP_SYMBOL (IC_RESULT (ic))->iaccess)
2812 /* the operation has only one symbol
2813 operator then we can pack */
2814 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2815 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2818 if (!((IC_LEFT (dic) &&
2819 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2821 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2825 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2826 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
2827 /* found the definition */
2828 /* replace the result with the result of */
2829 /* this assignment and remove this assignment */
2830 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2831 IC_RESULT (dic) = IC_RESULT (ic);
2833 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2835 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2837 /* delete from liverange table also
2838 delete from all the points inbetween and the new
2840 for (sic = dic; sic != ic; sic = sic->next)
2842 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2843 if (IS_ITEMP (IC_RESULT (dic)))
2844 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2847 remiCodeFromeBBlock (ebp, ic);
2848 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2849 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2850 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2856 /*-----------------------------------------------------------------*/
2857 /* findAssignToSym : scanning backwards looks for first assig found */
2858 /*-----------------------------------------------------------------*/
2860 findAssignToSym (operand * op, iCode * ic)
2864 debugLog ("%s\n", __FUNCTION__);
2865 for (dic = ic->prev; dic; dic = dic->prev)
2868 /* if definition by assignment */
2869 if (dic->op == '=' &&
2870 !POINTER_SET (dic) &&
2871 IC_RESULT (dic)->key == op->key
2872 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2876 /* we are interested only if defined in far space */
2877 /* or in stack space in case of + & - */
2879 /* if assigned to a non-symbol then return
2881 if (!IS_SYMOP (IC_RIGHT (dic)))
2884 /* if the symbol is in far space then
2886 if (isOperandInFarSpace (IC_RIGHT (dic)))
2889 /* for + & - operations make sure that
2890 if it is on the stack it is the same
2891 as one of the three operands */
2892 if ((ic->op == '+' || ic->op == '-') &&
2893 OP_SYMBOL (IC_RIGHT (dic))->onStack)
2896 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2897 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2898 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2906 /* if we find an usage then we cannot delete it */
2907 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2910 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2913 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2917 /* now make sure that the right side of dic
2918 is not defined between ic & dic */
2921 iCode *sic = dic->next;
2923 for (; sic != ic; sic = sic->next)
2924 if (IC_RESULT (sic) &&
2925 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2934 /*-----------------------------------------------------------------*/
2935 /* packRegsForSupport :- reduce some registers for support calls */
2936 /*-----------------------------------------------------------------*/
2938 packRegsForSupport (iCode * ic, eBBlock * ebp)
2942 debugLog ("%s\n", __FUNCTION__);
2943 /* for the left & right operand :- look to see if the
2944 left was assigned a true symbol in far space in that
2945 case replace them */
2946 if (IS_ITEMP (IC_LEFT (ic)) &&
2947 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2949 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
2955 debugAopGet ("removing left:", IC_LEFT (ic));
2957 /* found it we need to remove it from the
2959 for (sic = dic; sic != ic; sic = sic->next)
2960 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
2962 IC_LEFT (ic)->operand.symOperand =
2963 IC_RIGHT (dic)->operand.symOperand;
2964 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2965 remiCodeFromeBBlock (ebp, dic);
2966 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2967 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2971 /* do the same for the right operand */
2974 IS_ITEMP (IC_RIGHT (ic)) &&
2975 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2977 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2983 /* if this is a subtraction & the result
2984 is a true symbol in far space then don't pack */
2985 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
2987 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
2988 if (IN_FARSPACE (SPEC_OCLS (etype)))
2992 debugAopGet ("removing right:", IC_RIGHT (ic));
2994 /* found it we need to remove it from the
2996 for (sic = dic; sic != ic; sic = sic->next)
2997 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
2999 IC_RIGHT (ic)->operand.symOperand =
3000 IC_RIGHT (dic)->operand.symOperand;
3001 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3003 remiCodeFromeBBlock (ebp, dic);
3004 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3005 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3012 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3015 /*-----------------------------------------------------------------*/
3016 /* packRegsForOneuse : - will reduce some registers for single Use */
3017 /*-----------------------------------------------------------------*/
3019 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3024 debugLog ("%s\n", __FUNCTION__);
3025 /* if returning a literal then do nothing */
3029 /* only upto 2 bytes since we cannot predict
3030 the usage of b, & acc */
3031 if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
3036 /* this routine will mark the a symbol as used in one
3037 instruction use only && if the definition is local
3038 (ie. within the basic block) && has only one definition &&
3039 that definition is either a return value from a
3040 function or does not contain any variables in
3042 uses = bitVectCopy (OP_USES (op));
3043 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3044 if (!bitVectIsZero (uses)) /* has other uses */
3047 /* if it has only one defintion */
3048 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3049 return NULL; /* has more than one definition */
3051 /* get that definition */
3053 hTabItemWithKey (iCodehTab,
3054 bitVectFirstBit (OP_DEFS (op)))))
3057 /* found the definition now check if it is local */
3058 if (dic->seq < ebp->fSeq ||
3059 dic->seq > ebp->lSeq)
3060 return NULL; /* non-local */
3062 /* now check if it is the return from
3064 if (dic->op == CALL || dic->op == PCALL)
3066 if (ic->op != SEND && ic->op != RETURN &&
3067 !POINTER_SET(ic) && !POINTER_GET(ic))
3069 OP_SYMBOL (op)->ruonly = 1;
3076 /* otherwise check that the definition does
3077 not contain any symbols in far space */
3078 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3079 isOperandInFarSpace (IC_RIGHT (dic)) ||
3080 IS_OP_RUONLY (IC_LEFT (ic)) ||
3081 IS_OP_RUONLY (IC_RIGHT (ic)))
3086 /* if pointer set then make sure the pointer
3088 if (POINTER_SET (dic) &&
3089 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3092 if (POINTER_GET (dic) &&
3093 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3098 /* also make sure the intervenening instructions
3099 don't have any thing in far space */
3100 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3103 /* if there is an intervening function call then no */
3104 if (dic->op == CALL || dic->op == PCALL)
3106 /* if pointer set then make sure the pointer
3108 if (POINTER_SET (dic) &&
3109 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3112 if (POINTER_GET (dic) &&
3113 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3116 /* if address of & the result is remat then okay */
3117 if (dic->op == ADDRESS_OF &&
3118 OP_SYMBOL (IC_RESULT (dic))->remat)
3121 /* if operand has size of three or more & this
3122 operation is a '*','/' or '%' then 'b' may
3124 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3125 getSize (operandType (op)) >= 3)
3128 /* if left or right or result is in far space */
3129 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3130 isOperandInFarSpace (IC_RIGHT (dic)) ||
3131 isOperandInFarSpace (IC_RESULT (dic)) ||
3132 IS_OP_RUONLY (IC_LEFT (dic)) ||
3133 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3134 IS_OP_RUONLY (IC_RESULT (dic)))
3140 OP_SYMBOL (op)->ruonly = 1;
3145 /*-----------------------------------------------------------------*/
3146 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3147 /*-----------------------------------------------------------------*/
3149 isBitwiseOptimizable (iCode * ic)
3151 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3152 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3154 debugLog ("%s\n", __FUNCTION__);
3155 /* bitwise operations are considered optimizable
3156 under the following conditions (Jean-Louis VERN)
3168 if (IS_LITERAL (rtype) ||
3169 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3175 /*-----------------------------------------------------------------*/
3176 /* packRegsForAccUse - pack registers for acc use */
3177 /*-----------------------------------------------------------------*/
3179 packRegsForAccUse (iCode * ic)
3183 debugLog ("%s\n", __FUNCTION__);
3185 /* if this is an aggregate, e.g. a one byte char array */
3186 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3189 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3191 /* if + or - then it has to be one byte result */
3192 if ((ic->op == '+' || ic->op == '-')
3193 && getSize (operandType (IC_RESULT (ic))) > 1)
3196 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3197 /* if shift operation make sure right side is not a literal */
3198 if (ic->op == RIGHT_OP &&
3199 (isOperandLiteral (IC_RIGHT (ic)) ||
3200 getSize (operandType (IC_RESULT (ic))) > 1))
3203 if (ic->op == LEFT_OP &&
3204 (isOperandLiteral (IC_RIGHT (ic)) ||
3205 getSize (operandType (IC_RESULT (ic))) > 1))
3208 if (IS_BITWISE_OP (ic) &&
3209 getSize (operandType (IC_RESULT (ic))) > 1)
3213 /* has only one definition */
3214 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3217 /* has only one use */
3218 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3221 /* and the usage immediately follows this iCode */
3222 if (!(uic = hTabItemWithKey (iCodehTab,
3223 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3226 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3227 if (ic->next != uic)
3230 /* if it is a conditional branch then we definitely can */
3234 if (uic->op == JUMPTABLE)
3237 /* if the usage is not is an assignment
3238 or an arithmetic / bitwise / shift operation then not */
3239 if (POINTER_SET (uic) &&
3240 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3243 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3244 if (uic->op != '=' &&
3245 !IS_ARITHMETIC_OP (uic) &&
3246 !IS_BITWISE_OP (uic) &&
3247 uic->op != LEFT_OP &&
3248 uic->op != RIGHT_OP)
3251 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3252 /* if used in ^ operation then make sure right is not a
3254 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3257 /* if shift operation make sure right side is not a literal */
3258 if (uic->op == RIGHT_OP &&
3259 (isOperandLiteral (IC_RIGHT (uic)) ||
3260 getSize (operandType (IC_RESULT (uic))) > 1))
3263 if (uic->op == LEFT_OP &&
3264 (isOperandLiteral (IC_RIGHT (uic)) ||
3265 getSize (operandType (IC_RESULT (uic))) > 1))
3268 /* make sure that the result of this icode is not on the
3269 stack, since acc is used to compute stack offset */
3270 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3271 OP_SYMBOL (IC_RESULT (uic))->onStack)
3274 /* if either one of them in far space then we cannot */
3275 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3276 isOperandInFarSpace (IC_LEFT (uic))) ||
3277 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3278 isOperandInFarSpace (IC_RIGHT (uic))))
3281 /* if the usage has only one operand then we can */
3282 if (IC_LEFT (uic) == NULL ||
3283 IC_RIGHT (uic) == NULL)
3286 /* make sure this is on the left side if not
3287 a '+' since '+' is commutative */
3288 if (ic->op != '+' &&
3289 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3292 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3293 /* if one of them is a literal then we can */
3294 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3295 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3296 (getSize (operandType (IC_RESULT (uic))) <= 1))
3298 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3302 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3303 /* if the other one is not on stack then we can */
3304 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3305 (IS_ITEMP (IC_RIGHT (uic)) ||
3306 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3307 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3310 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3311 (IS_ITEMP (IC_LEFT (uic)) ||
3312 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3313 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3319 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3320 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3325 /*-----------------------------------------------------------------*/
3326 /* packForPush - hueristics to reduce iCode for pushing */
3327 /*-----------------------------------------------------------------*/
3329 packForReceive (iCode * ic, eBBlock * ebp)
3333 debugLog ("%s\n", __FUNCTION__);
3334 debugAopGet (" result:", IC_RESULT (ic));
3335 debugAopGet (" left:", IC_LEFT (ic));
3336 debugAopGet (" right:", IC_RIGHT (ic));
3341 for (dic = ic->next; dic; dic = dic->next)
3346 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3347 debugLog (" used on left\n");
3348 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3349 debugLog (" used on right\n");
3350 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3351 debugLog (" used on result\n");
3353 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3354 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3359 debugLog (" hey we can remove this unnecessary assign\n");
3361 /*-----------------------------------------------------------------*/
3362 /* packForPush - hueristics to reduce iCode for pushing */
3363 /*-----------------------------------------------------------------*/
3365 packForPush (iCode * ic, eBBlock * ebp)
3369 debugLog ("%s\n", __FUNCTION__);
3370 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3373 /* must have only definition & one usage */
3374 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3375 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3378 /* find the definition */
3379 if (!(dic = hTabItemWithKey (iCodehTab,
3380 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3383 if (dic->op != '=' || POINTER_SET (dic))
3386 /* we now we know that it has one & only one def & use
3387 and the that the definition is an assignment */
3388 IC_LEFT (ic) = IC_RIGHT (dic);
3390 remiCodeFromeBBlock (ebp, dic);
3391 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3392 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3395 void printSymType(char * str, sym_link *sl)
3397 debugLog (" %s Symbol type: ",str);
3398 printTypeChain( sl, debugF);
3403 /*-----------------------------------------------------------------*/
3404 /* some debug code to print the symbol S_TYPE. Note that
3405 * the function checkSClass in src/SDCCsymt.c dinks with
3406 * the S_TYPE in ways the PIC port doesn't fully like...*/
3407 /*-----------------------------------------------------------------*/
3408 void isData(sym_link *sl)
3418 for ( ; sl; sl=sl->next) {
3420 switch (SPEC_SCLS(sl)) {
3422 case S_DATA: fprintf (of, "data "); break;
3423 case S_XDATA: fprintf (of, "xdata "); break;
3424 case S_SFR: fprintf (of, "sfr "); break;
3425 case S_SBIT: fprintf (of, "sbit "); break;
3426 case S_CODE: fprintf (of, "code "); break;
3427 case S_IDATA: fprintf (of, "idata "); break;
3428 case S_PDATA: fprintf (of, "pdata "); break;
3429 case S_LITERAL: fprintf (of, "literal "); break;
3430 case S_STACK: fprintf (of, "stack "); break;
3431 case S_XSTACK: fprintf (of, "xstack "); break;
3432 case S_BIT: fprintf (of, "bit "); break;
3433 case S_EEPROM: fprintf (of, "eeprom "); break;
3442 /*-----------------------------------------------------------------*/
3443 /* packRegisters - does some transformations to reduce register */
3445 /*-----------------------------------------------------------------*/
3447 packRegisters (eBBlock * ebp)
3452 debugLog ("%s\n", __FUNCTION__);
3458 /* look for assignments of the form */
3459 /* iTempNN = TRueSym (someoperation) SomeOperand */
3461 /* TrueSym := iTempNN:1 */
3462 for (ic = ebp->sch; ic; ic = ic->next)
3465 /* find assignment of the form TrueSym := iTempNN:1 */
3466 if (ic->op == '=' && !POINTER_SET (ic))
3467 change += packRegsForAssign (ic, ebp);
3471 if (POINTER_SET (ic))
3472 debugLog ("pointer is set\n");
3473 debugAopGet (" result:", IC_RESULT (ic));
3474 debugAopGet (" left:", IC_LEFT (ic));
3475 debugAopGet (" right:", IC_RIGHT (ic));
3484 for (ic = ebp->sch; ic; ic = ic->next) {
3486 if(IS_SYMOP ( IC_LEFT(ic))) {
3487 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3489 debugAopGet (" left:", IC_LEFT (ic));
3490 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3491 debugLog (" is a pointer\n");
3493 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3494 debugLog (" is volatile\n");
3498 printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
3501 if(IS_SYMOP ( IC_RIGHT(ic))) {
3502 debugAopGet (" right:", IC_RIGHT (ic));
3503 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3506 if(IS_SYMOP ( IC_RESULT(ic))) {
3507 debugAopGet (" result:", IC_RESULT (ic));
3508 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3511 if (POINTER_SET (ic))
3512 debugLog (" %d - Pointer set\n", __LINE__);
3515 /* if this is an itemp & result of a address of a true sym
3516 then mark this as rematerialisable */
3517 if (ic->op == ADDRESS_OF &&
3518 IS_ITEMP (IC_RESULT (ic)) &&
3519 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3520 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3521 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3524 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3526 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3527 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3528 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3532 /* if straight assignment then carry remat flag if
3533 this is the only definition */
3534 if (ic->op == '=' &&
3535 !POINTER_SET (ic) &&
3536 IS_SYMOP (IC_RIGHT (ic)) &&
3537 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3538 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3540 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3542 OP_SYMBOL (IC_RESULT (ic))->remat =
3543 OP_SYMBOL (IC_RIGHT (ic))->remat;
3544 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3545 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3548 /* if this is a +/- operation with a rematerizable
3549 then mark this as rematerializable as well */
3550 if ((ic->op == '+' || ic->op == '-') &&
3551 (IS_SYMOP (IC_LEFT (ic)) &&
3552 IS_ITEMP (IC_RESULT (ic)) &&
3553 OP_SYMBOL (IC_LEFT (ic))->remat &&
3554 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3555 IS_OP_LITERAL (IC_RIGHT (ic))))
3557 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3559 operandLitValue (IC_RIGHT (ic));
3560 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3561 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3562 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3565 /* mark the pointer usages */
3566 if (POINTER_SET (ic))
3568 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3569 debugLog (" marking as a pointer (set) =>");
3570 debugAopGet (" result:", IC_RESULT (ic));
3572 if (POINTER_GET (ic))
3574 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3575 debugLog (" marking as a pointer (get) =>");
3576 debugAopGet (" left:", IC_LEFT (ic));
3581 /* if we are using a symbol on the stack
3582 then we should say pic14_ptrRegReq */
3583 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3584 pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3585 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3586 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3587 pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3588 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3591 if (IS_SYMOP (IC_LEFT (ic)))
3592 pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3593 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3594 if (IS_SYMOP (IC_RIGHT (ic)))
3595 pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3596 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3597 if (IS_SYMOP (IC_RESULT (ic)))
3598 pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3599 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3602 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
3606 /* if the condition of an if instruction
3607 is defined in the previous instruction then
3608 mark the itemp as a conditional */
3609 if ((IS_CONDITIONAL (ic) ||
3610 ((ic->op == BITWISEAND ||
3613 isBitwiseOptimizable (ic))) &&
3614 ic->next && ic->next->op == IFX &&
3615 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3616 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3619 debugLog (" %d\n", __LINE__);
3620 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3624 /* reduce for support function calls */
3625 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3626 packRegsForSupport (ic, ebp);
3628 /* if a parameter is passed, it's in W, so we may not
3629 need to place a copy in a register */
3630 if (ic->op == RECEIVE)
3631 packForReceive (ic, ebp);
3633 /* some cases the redundant moves can
3634 can be eliminated for return statements */
3635 if ((ic->op == RETURN || ic->op == SEND) &&
3636 !isOperandInFarSpace (IC_LEFT (ic)) &&
3638 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3640 /* if pointer set & left has a size more than
3641 one and right is not in far space */
3642 if (POINTER_SET (ic) &&
3643 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3644 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3645 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3646 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3648 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3650 /* if pointer get */
3651 if (POINTER_GET (ic) &&
3652 !isOperandInFarSpace (IC_RESULT (ic)) &&
3653 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3654 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3655 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3657 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3660 /* if this is cast for intergral promotion then
3661 check if only use of the definition of the
3662 operand being casted/ if yes then replace
3663 the result of that arithmetic operation with
3664 this result and get rid of the cast */
3665 if (ic->op == CAST) {
3667 sym_link *fromType = operandType (IC_RIGHT (ic));
3668 sym_link *toType = operandType (IC_LEFT (ic));
3670 debugLog (" %d - casting\n", __LINE__);
3672 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3673 getSize (fromType) != getSize (toType)) {
3676 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3679 if (IS_ARITHMETIC_OP (dic)) {
3681 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3682 IC_RESULT (dic) = IC_RESULT (ic);
3683 remiCodeFromeBBlock (ebp, ic);
3684 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3685 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3686 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3690 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3694 /* if the type from and type to are the same
3695 then if this is the only use then packit */
3696 if (compareType (operandType (IC_RIGHT (ic)),
3697 operandType (IC_LEFT (ic))) == 1) {
3699 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3702 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3703 IC_RESULT (dic) = IC_RESULT (ic);
3704 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3705 remiCodeFromeBBlock (ebp, ic);
3706 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3707 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3715 iTempNN := (some variable in farspace) V1
3720 if (ic->op == IPUSH)
3722 packForPush (ic, ebp);
3726 /* pack registers for accumulator use, when the
3727 result of an arithmetic or bit wise operation
3728 has only one use, that use is immediately following
3729 the defintion and the using iCode has only one
3730 operand or has two operands but one is literal &
3731 the result of that operation is not on stack then
3732 we can leave the result of this operation in acc:b
3734 if ((IS_ARITHMETIC_OP (ic)
3736 || IS_BITWISE_OP (ic)
3738 || ic->op == LEFT_OP || ic->op == RIGHT_OP
3741 IS_ITEMP (IC_RESULT (ic)) &&
3742 getSize (operandType (IC_RESULT (ic))) <= 2)
3744 packRegsForAccUse (ic);
3750 dumpEbbsToDebug (eBBlock ** ebbs, int count)
3754 if (!debug || !debugF)
3757 for (i = 0; i < count; i++)
3759 fprintf (debugF, "\n----------------------------------------------------------------\n");
3760 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
3761 ebbs[i]->entryLabel->name,
3764 ebbs[i]->isLastInLoop);
3765 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
3770 fprintf (debugF, "visited %d : hasFcall = %d\n",
3774 fprintf (debugF, "\ndefines bitVector :");
3775 bitVectDebugOn (ebbs[i]->defSet, debugF);
3776 fprintf (debugF, "\nlocal defines bitVector :");
3777 bitVectDebugOn (ebbs[i]->ldefs, debugF);
3778 fprintf (debugF, "\npointers Set bitvector :");
3779 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
3780 fprintf (debugF, "\nin pointers Set bitvector :");
3781 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
3782 fprintf (debugF, "\ninDefs Set bitvector :");
3783 bitVectDebugOn (ebbs[i]->inDefs, debugF);
3784 fprintf (debugF, "\noutDefs Set bitvector :");
3785 bitVectDebugOn (ebbs[i]->outDefs, debugF);
3786 fprintf (debugF, "\nusesDefs Set bitvector :");
3787 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
3788 fprintf (debugF, "\n----------------------------------------------------------------\n");
3789 printiCChain (ebbs[i]->sch, debugF);
3792 /*-----------------------------------------------------------------*/
3793 /* assignRegisters - assigns registers to each live range as need */
3794 /*-----------------------------------------------------------------*/
3796 pic14_assignRegisters (eBBlock ** ebbs, int count)
3801 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
3802 debugLog ("\nebbs before optimizing:\n");
3803 dumpEbbsToDebug (ebbs, count);
3805 setToNull ((void *) &_G.funcrUsed);
3806 pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3809 /* change assignments this will remove some
3810 live ranges reducing some register pressure */
3811 for (i = 0; i < count; i++)
3812 packRegisters (ebbs[i]);
3819 debugLog("dir registers allocated so far:\n");
3820 reg = hTabFirstItem(dynDirectRegNames, &hkey);
3823 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
3824 reg = hTabNextItem(dynDirectRegNames, &hkey);
3829 if (options.dump_pack)
3830 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3832 /* first determine for each live range the number of
3833 registers & the type of registers required for each */
3836 /* and serially allocate registers */
3837 serialRegAssign (ebbs, count);
3839 /* if stack was extended then tell the user */
3842 /* werror(W_TOOMANY_SPILS,"stack", */
3843 /* _G.stackExtend,currFunc->name,""); */
3849 /* werror(W_TOOMANY_SPILS,"data space", */
3850 /* _G.dataExtend,currFunc->name,""); */
3854 /* after that create the register mask
3855 for each of the instruction */
3856 createRegMask (ebbs, count);
3858 /* redo that offsets for stacked automatic variables */
3859 redoStackOffsets ();
3861 if (options.dump_rassgn)
3862 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3864 /* now get back the chain */
3865 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3867 debugLog ("ebbs after optimizing:\n");
3868 dumpEbbsToDebug (ebbs, count);
3873 /* free up any _G.stackSpil locations allocated */
3874 applyToSet (_G.stackSpil, deallocStackSpil);
3876 setToNull ((void **) &_G.stackSpil);
3877 setToNull ((void **) &_G.spiltSet);
3878 /* mark all registers as free */
3879 //pic14_freeAllRegs ();
3881 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");