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
2439 if (sym->ruonly || sym->accuse) {
2440 if (IS_AGGREGATE (sym->type) || sym->isptr)
2441 sym->type = aggrToPtr (sym->type, FALSE);
2442 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
2447 /* if the symbol has only one definition &
2448 that definition is a get_pointer and the
2449 pointer we are getting is rematerializable and
2452 if (bitVectnBitsOn (sym->defs) == 1 &&
2453 (ic = hTabItemWithKey (iCodehTab,
2454 bitVectFirstBit (sym->defs))) &&
2457 !IS_BITVAR (sym->etype)) {
2460 debugLog (" %d - \n", __LINE__);
2462 /* if remat in data space */
2463 if (OP_SYMBOL (IC_LEFT (ic))->remat &&
2464 DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) {
2466 /* create a psuedo symbol & force a spil */
2467 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2468 symbol *psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2469 psym->type = sym->type;
2470 psym->etype = sym->etype;
2471 strcpy (psym->rname, psym->name);
2473 sym->usl.spillLoc = psym;
2477 /* if in data space or idata space then try to
2478 allocate pointer register */
2482 /* if not then we require registers */
2483 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2484 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2485 getSize (sym->type));
2488 if(IS_PTR_CONST (sym->type)) {
2489 debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2493 if (sym->nRegs > 4) {
2494 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2495 printTypeChain (sym->type, stderr);
2496 fprintf (stderr, "\n");
2499 /* determine the type of register required */
2500 if (sym->nRegs == 1 &&
2501 IS_PTR (sym->type) &&
2503 sym->regType = REG_PTR;
2505 sym->regType = REG_GPR;
2508 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2512 /* for the first run we don't provide */
2513 /* registers for true symbols we will */
2514 /* see how things go */
2519 DEFSETFUNC (markRegFree)
2521 ((regs *)item)->isFree = 1;
2526 DEFSETFUNC (deallocReg)
2528 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2529 ((regs *)item)->isFree = 1;
2530 ((regs *)item)->wasUsed = 0;
2534 /*-----------------------------------------------------------------*/
2535 /* freeAllRegs - mark all registers as free */
2536 /*-----------------------------------------------------------------*/
2538 pic14_freeAllRegs ()
2542 debugLog ("%s\n", __FUNCTION__);
2544 applyToSet(dynAllocRegs,markRegFree);
2545 applyToSet(dynStackRegs,markRegFree);
2548 for (i = 0; i < pic14_nRegs; i++)
2549 regspic14[i].isFree = 1;
2553 /*-----------------------------------------------------------------*/
2554 /*-----------------------------------------------------------------*/
2556 pic14_deallocateAllRegs ()
2560 debugLog ("%s\n", __FUNCTION__);
2562 applyToSet(dynAllocRegs,deallocReg);
2565 for (i = 0; i < pic14_nRegs; i++) {
2566 if(regspic14[i].pc_type == PO_GPR_TEMP) {
2567 regspic14[i].isFree = 1;
2568 regspic14[i].wasUsed = 0;
2575 /*-----------------------------------------------------------------*/
2576 /* deallocStackSpil - this will set the stack pointer back */
2577 /*-----------------------------------------------------------------*/
2579 DEFSETFUNC (deallocStackSpil)
2583 debugLog ("%s\n", __FUNCTION__);
2588 /*-----------------------------------------------------------------*/
2589 /* farSpacePackable - returns the packable icode for far variables */
2590 /*-----------------------------------------------------------------*/
2592 farSpacePackable (iCode * ic)
2596 debugLog ("%s\n", __FUNCTION__);
2597 /* go thru till we find a definition for the
2598 symbol on the right */
2599 for (dic = ic->prev; dic; dic = dic->prev)
2602 /* if the definition is a call then no */
2603 if ((dic->op == CALL || dic->op == PCALL) &&
2604 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2609 /* if shift by unknown amount then not */
2610 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2611 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2614 /* if pointer get and size > 1 */
2615 if (POINTER_GET (dic) &&
2616 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2619 if (POINTER_SET (dic) &&
2620 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2623 /* if any three is a true symbol in far space */
2624 if (IC_RESULT (dic) &&
2625 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2626 isOperandInFarSpace (IC_RESULT (dic)))
2629 if (IC_RIGHT (dic) &&
2630 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2631 isOperandInFarSpace (IC_RIGHT (dic)) &&
2632 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2635 if (IC_LEFT (dic) &&
2636 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2637 isOperandInFarSpace (IC_LEFT (dic)) &&
2638 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2641 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2643 if ((dic->op == LEFT_OP ||
2644 dic->op == RIGHT_OP ||
2646 IS_OP_LITERAL (IC_RIGHT (dic)))
2656 /*-----------------------------------------------------------------*/
2657 /* packRegsForAssign - register reduction for assignment */
2658 /*-----------------------------------------------------------------*/
2660 packRegsForAssign (iCode * ic, eBBlock * ebp)
2665 debugLog ("%s\n", __FUNCTION__);
2667 debugAopGet (" result:", IC_RESULT (ic));
2668 debugAopGet (" left:", IC_LEFT (ic));
2669 debugAopGet (" right:", IC_RIGHT (ic));
2671 /* if this is at an absolute address, then get the address. */
2672 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2673 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2674 debugLog (" %d - found config word declaration\n", __LINE__);
2675 if(IS_VALOP(IC_RIGHT(ic))) {
2676 debugLog (" setting config word to %x\n",
2677 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2678 assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2679 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2682 /* remove the assignment from the iCode chain. */
2684 remiCodeFromeBBlock (ebp, ic);
2685 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2686 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2693 if (!IS_ITEMP (IC_RESULT (ic))) {
2694 allocDirReg(IC_RESULT (ic));
2695 debugLog (" %d - result is not temp\n", __LINE__);
2698 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2699 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2700 allocDirReg(IC_LEFT (ic));
2704 if (!IS_ITEMP (IC_RIGHT (ic))) {
2705 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2706 allocDirReg(IC_RIGHT (ic));
2710 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2711 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2713 debugLog (" %d - not packing - right side fails \n", __LINE__);
2717 /* if the true symbol is defined in far space or on stack
2718 then we should not since this will increase register pressure */
2719 if (isOperandInFarSpace (IC_RESULT (ic)))
2721 if ((dic = farSpacePackable (ic)))
2727 /* find the definition of iTempNN scanning backwards if we find a
2728 a use of the true symbol before we find the definition then
2730 for (dic = ic->prev; dic; dic = dic->prev)
2733 /* if there is a function call and this is
2734 a parameter & not my parameter then don't pack it */
2735 if ((dic->op == CALL || dic->op == PCALL) &&
2736 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2737 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2739 debugLog (" %d - \n", __LINE__);
2747 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2748 IS_OP_VOLATILE (IC_RESULT (dic)))
2750 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2755 if (IS_SYMOP (IC_RESULT (dic)) &&
2756 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2758 /* A previous result was assigned to the same register - we'll our definition */
2759 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2760 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2761 if (POINTER_SET (dic))
2767 if (IS_SYMOP (IC_RIGHT (dic)) &&
2768 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2769 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2771 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
2776 if (IS_SYMOP (IC_LEFT (dic)) &&
2777 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2778 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2780 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
2785 if (POINTER_SET (dic) &&
2786 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2788 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
2796 return 0; /* did not find */
2798 /* if the result is on stack or iaccess then it must be
2799 the same atleast one of the operands */
2800 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2801 OP_SYMBOL (IC_RESULT (ic))->iaccess)
2804 /* the operation has only one symbol
2805 operator then we can pack */
2806 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2807 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2810 if (!((IC_LEFT (dic) &&
2811 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2813 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2817 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2818 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
2819 /* found the definition */
2820 /* replace the result with the result of */
2821 /* this assignment and remove this assignment */
2822 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2823 IC_RESULT (dic) = IC_RESULT (ic);
2825 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2827 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2829 /* delete from liverange table also
2830 delete from all the points inbetween and the new
2832 for (sic = dic; sic != ic; sic = sic->next)
2834 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2835 if (IS_ITEMP (IC_RESULT (dic)))
2836 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2839 remiCodeFromeBBlock (ebp, ic);
2840 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2841 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2842 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2848 /*-----------------------------------------------------------------*/
2849 /* findAssignToSym : scanning backwards looks for first assig found */
2850 /*-----------------------------------------------------------------*/
2852 findAssignToSym (operand * op, iCode * ic)
2856 debugLog ("%s\n", __FUNCTION__);
2857 for (dic = ic->prev; dic; dic = dic->prev)
2860 /* if definition by assignment */
2861 if (dic->op == '=' &&
2862 !POINTER_SET (dic) &&
2863 IC_RESULT (dic)->key == op->key
2864 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2868 /* we are interested only if defined in far space */
2869 /* or in stack space in case of + & - */
2871 /* if assigned to a non-symbol then return
2873 if (!IS_SYMOP (IC_RIGHT (dic)))
2876 /* if the symbol is in far space then
2878 if (isOperandInFarSpace (IC_RIGHT (dic)))
2881 /* for + & - operations make sure that
2882 if it is on the stack it is the same
2883 as one of the three operands */
2884 if ((ic->op == '+' || ic->op == '-') &&
2885 OP_SYMBOL (IC_RIGHT (dic))->onStack)
2888 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2889 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2890 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2898 /* if we find an usage then we cannot delete it */
2899 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2902 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2905 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2909 /* now make sure that the right side of dic
2910 is not defined between ic & dic */
2913 iCode *sic = dic->next;
2915 for (; sic != ic; sic = sic->next)
2916 if (IC_RESULT (sic) &&
2917 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2926 /*-----------------------------------------------------------------*/
2927 /* packRegsForSupport :- reduce some registers for support calls */
2928 /*-----------------------------------------------------------------*/
2930 packRegsForSupport (iCode * ic, eBBlock * ebp)
2934 debugLog ("%s\n", __FUNCTION__);
2935 /* for the left & right operand :- look to see if the
2936 left was assigned a true symbol in far space in that
2937 case replace them */
2938 if (IS_ITEMP (IC_LEFT (ic)) &&
2939 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2941 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
2947 debugAopGet ("removing left:", IC_LEFT (ic));
2949 /* found it we need to remove it from the
2951 for (sic = dic; sic != ic; sic = sic->next)
2952 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
2954 IC_LEFT (ic)->operand.symOperand =
2955 IC_RIGHT (dic)->operand.symOperand;
2956 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2957 remiCodeFromeBBlock (ebp, dic);
2958 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2959 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2963 /* do the same for the right operand */
2966 IS_ITEMP (IC_RIGHT (ic)) &&
2967 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2969 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2975 /* if this is a subtraction & the result
2976 is a true symbol in far space then don't pack */
2977 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
2979 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
2980 if (IN_FARSPACE (SPEC_OCLS (etype)))
2984 debugAopGet ("removing right:", IC_RIGHT (ic));
2986 /* found it we need to remove it from the
2988 for (sic = dic; sic != ic; sic = sic->next)
2989 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
2991 IC_RIGHT (ic)->operand.symOperand =
2992 IC_RIGHT (dic)->operand.symOperand;
2993 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2995 remiCodeFromeBBlock (ebp, dic);
2996 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2997 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3004 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3007 /*-----------------------------------------------------------------*/
3008 /* packRegsForOneuse : - will reduce some registers for single Use */
3009 /*-----------------------------------------------------------------*/
3011 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3016 debugLog ("%s\n", __FUNCTION__);
3017 /* if returning a literal then do nothing */
3021 /* only upto 2 bytes since we cannot predict
3022 the usage of b, & acc */
3023 if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
3028 /* this routine will mark the a symbol as used in one
3029 instruction use only && if the definition is local
3030 (ie. within the basic block) && has only one definition &&
3031 that definition is either a return value from a
3032 function or does not contain any variables in
3034 uses = bitVectCopy (OP_USES (op));
3035 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3036 if (!bitVectIsZero (uses)) /* has other uses */
3039 /* if it has only one defintion */
3040 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3041 return NULL; /* has more than one definition */
3043 /* get that definition */
3045 hTabItemWithKey (iCodehTab,
3046 bitVectFirstBit (OP_DEFS (op)))))
3049 /* found the definition now check if it is local */
3050 if (dic->seq < ebp->fSeq ||
3051 dic->seq > ebp->lSeq)
3052 return NULL; /* non-local */
3054 /* now check if it is the return from
3056 if (dic->op == CALL || dic->op == PCALL)
3058 if (ic->op != SEND && ic->op != RETURN &&
3059 !POINTER_SET(ic) && !POINTER_GET(ic))
3061 OP_SYMBOL (op)->ruonly = 1;
3068 /* otherwise check that the definition does
3069 not contain any symbols in far space */
3070 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3071 isOperandInFarSpace (IC_RIGHT (dic)) ||
3072 IS_OP_RUONLY (IC_LEFT (ic)) ||
3073 IS_OP_RUONLY (IC_RIGHT (ic)))
3078 /* if pointer set then make sure the pointer
3080 if (POINTER_SET (dic) &&
3081 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3084 if (POINTER_GET (dic) &&
3085 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3090 /* also make sure the intervenening instructions
3091 don't have any thing in far space */
3092 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3095 /* if there is an intervening function call then no */
3096 if (dic->op == CALL || dic->op == PCALL)
3098 /* if pointer set then make sure the pointer
3100 if (POINTER_SET (dic) &&
3101 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3104 if (POINTER_GET (dic) &&
3105 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3108 /* if address of & the result is remat then okay */
3109 if (dic->op == ADDRESS_OF &&
3110 OP_SYMBOL (IC_RESULT (dic))->remat)
3113 /* if operand has size of three or more & this
3114 operation is a '*','/' or '%' then 'b' may
3116 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3117 getSize (operandType (op)) >= 3)
3120 /* if left or right or result is in far space */
3121 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3122 isOperandInFarSpace (IC_RIGHT (dic)) ||
3123 isOperandInFarSpace (IC_RESULT (dic)) ||
3124 IS_OP_RUONLY (IC_LEFT (dic)) ||
3125 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3126 IS_OP_RUONLY (IC_RESULT (dic)))
3132 OP_SYMBOL (op)->ruonly = 1;
3137 /*-----------------------------------------------------------------*/
3138 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3139 /*-----------------------------------------------------------------*/
3141 isBitwiseOptimizable (iCode * ic)
3143 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3144 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3146 debugLog ("%s\n", __FUNCTION__);
3147 /* bitwise operations are considered optimizable
3148 under the following conditions (Jean-Louis VERN)
3160 if (IS_LITERAL (rtype) ||
3161 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3167 /*-----------------------------------------------------------------*/
3168 /* packRegsForAccUse - pack registers for acc use */
3169 /*-----------------------------------------------------------------*/
3171 packRegsForAccUse (iCode * ic)
3175 debugLog ("%s\n", __FUNCTION__);
3177 /* if this is an aggregate, e.g. a one byte char array */
3178 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3181 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3183 /* if + or - then it has to be one byte result */
3184 if ((ic->op == '+' || ic->op == '-')
3185 && getSize (operandType (IC_RESULT (ic))) > 1)
3188 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3189 /* if shift operation make sure right side is not a literal */
3190 if (ic->op == RIGHT_OP &&
3191 (isOperandLiteral (IC_RIGHT (ic)) ||
3192 getSize (operandType (IC_RESULT (ic))) > 1))
3195 if (ic->op == LEFT_OP &&
3196 (isOperandLiteral (IC_RIGHT (ic)) ||
3197 getSize (operandType (IC_RESULT (ic))) > 1))
3200 if (IS_BITWISE_OP (ic) &&
3201 getSize (operandType (IC_RESULT (ic))) > 1)
3205 /* has only one definition */
3206 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3209 /* has only one use */
3210 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3213 /* and the usage immediately follows this iCode */
3214 if (!(uic = hTabItemWithKey (iCodehTab,
3215 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3218 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3219 if (ic->next != uic)
3222 /* if it is a conditional branch then we definitely can */
3226 if (uic->op == JUMPTABLE)
3229 /* if the usage is not is an assignment
3230 or an arithmetic / bitwise / shift operation then not */
3231 if (POINTER_SET (uic) &&
3232 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3235 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3236 if (uic->op != '=' &&
3237 !IS_ARITHMETIC_OP (uic) &&
3238 !IS_BITWISE_OP (uic) &&
3239 uic->op != LEFT_OP &&
3240 uic->op != RIGHT_OP)
3243 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3244 /* if used in ^ operation then make sure right is not a
3246 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3249 /* if shift operation make sure right side is not a literal */
3250 if (uic->op == RIGHT_OP &&
3251 (isOperandLiteral (IC_RIGHT (uic)) ||
3252 getSize (operandType (IC_RESULT (uic))) > 1))
3255 if (uic->op == LEFT_OP &&
3256 (isOperandLiteral (IC_RIGHT (uic)) ||
3257 getSize (operandType (IC_RESULT (uic))) > 1))
3260 /* make sure that the result of this icode is not on the
3261 stack, since acc is used to compute stack offset */
3262 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3263 OP_SYMBOL (IC_RESULT (uic))->onStack)
3266 /* if either one of them in far space then we cannot */
3267 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3268 isOperandInFarSpace (IC_LEFT (uic))) ||
3269 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3270 isOperandInFarSpace (IC_RIGHT (uic))))
3273 /* if the usage has only one operand then we can */
3274 if (IC_LEFT (uic) == NULL ||
3275 IC_RIGHT (uic) == NULL)
3278 /* make sure this is on the left side if not
3279 a '+' since '+' is commutative */
3280 if (ic->op != '+' &&
3281 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3284 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3285 /* if one of them is a literal then we can */
3286 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3287 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3288 (getSize (operandType (IC_RESULT (uic))) <= 1))
3290 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3294 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3295 /* if the other one is not on stack then we can */
3296 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3297 (IS_ITEMP (IC_RIGHT (uic)) ||
3298 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3299 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3302 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3303 (IS_ITEMP (IC_LEFT (uic)) ||
3304 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3305 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3311 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3312 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3317 /*-----------------------------------------------------------------*/
3318 /* packForPush - hueristics to reduce iCode for pushing */
3319 /*-----------------------------------------------------------------*/
3321 packForReceive (iCode * ic, eBBlock * ebp)
3325 debugLog ("%s\n", __FUNCTION__);
3326 debugAopGet (" result:", IC_RESULT (ic));
3327 debugAopGet (" left:", IC_LEFT (ic));
3328 debugAopGet (" right:", IC_RIGHT (ic));
3333 for (dic = ic->next; dic; dic = dic->next)
3338 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3339 debugLog (" used on left\n");
3340 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3341 debugLog (" used on right\n");
3342 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3343 debugLog (" used on result\n");
3345 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3346 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3351 debugLog (" hey we can remove this unnecessary assign\n");
3353 /*-----------------------------------------------------------------*/
3354 /* packForPush - hueristics to reduce iCode for pushing */
3355 /*-----------------------------------------------------------------*/
3357 packForPush (iCode * ic, eBBlock * ebp)
3361 debugLog ("%s\n", __FUNCTION__);
3362 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3365 /* must have only definition & one usage */
3366 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3367 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3370 /* find the definition */
3371 if (!(dic = hTabItemWithKey (iCodehTab,
3372 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3375 if (dic->op != '=' || POINTER_SET (dic))
3378 /* we now we know that it has one & only one def & use
3379 and the that the definition is an assignment */
3380 IC_LEFT (ic) = IC_RIGHT (dic);
3382 remiCodeFromeBBlock (ebp, dic);
3383 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3384 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3387 void printSymType(char * str, sym_link *sl)
3389 debugLog (" %s Symbol type: ",str);
3390 printTypeChain( sl, debugF);
3395 /*-----------------------------------------------------------------*/
3396 /* some debug code to print the symbol S_TYPE. Note that
3397 * the function checkSClass in src/SDCCsymt.c dinks with
3398 * the S_TYPE in ways the PIC port doesn't fully like...*/
3399 /*-----------------------------------------------------------------*/
3400 void isData(sym_link *sl)
3410 for ( ; sl; sl=sl->next) {
3412 switch (SPEC_SCLS(sl)) {
3414 case S_DATA: fprintf (of, "data "); break;
3415 case S_XDATA: fprintf (of, "xdata "); break;
3416 case S_SFR: fprintf (of, "sfr "); break;
3417 case S_SBIT: fprintf (of, "sbit "); break;
3418 case S_CODE: fprintf (of, "code "); break;
3419 case S_IDATA: fprintf (of, "idata "); break;
3420 case S_PDATA: fprintf (of, "pdata "); break;
3421 case S_LITERAL: fprintf (of, "literal "); break;
3422 case S_STACK: fprintf (of, "stack "); break;
3423 case S_XSTACK: fprintf (of, "xstack "); break;
3424 case S_BIT: fprintf (of, "bit "); break;
3425 case S_EEPROM: fprintf (of, "eeprom "); break;
3434 /*-----------------------------------------------------------------*/
3435 /* packRegisters - does some transformations to reduce register */
3437 /*-----------------------------------------------------------------*/
3439 packRegisters (eBBlock * ebp)
3444 debugLog ("%s\n", __FUNCTION__);
3450 /* look for assignments of the form */
3451 /* iTempNN = TRueSym (someoperation) SomeOperand */
3453 /* TrueSym := iTempNN:1 */
3454 for (ic = ebp->sch; ic; ic = ic->next)
3457 /* find assignment of the form TrueSym := iTempNN:1 */
3458 if (ic->op == '=' && !POINTER_SET (ic))
3459 change += packRegsForAssign (ic, ebp);
3463 if (POINTER_SET (ic))
3464 debugLog ("pointer is set\n");
3465 debugAopGet (" result:", IC_RESULT (ic));
3466 debugAopGet (" left:", IC_LEFT (ic));
3467 debugAopGet (" right:", IC_RIGHT (ic));
3476 for (ic = ebp->sch; ic; ic = ic->next) {
3478 if(IS_SYMOP ( IC_LEFT(ic))) {
3479 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3481 debugAopGet (" left:", IC_LEFT (ic));
3482 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3483 debugLog (" is a pointer\n");
3485 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3486 debugLog (" is volatile\n");
3490 printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
3493 if(IS_SYMOP ( IC_RIGHT(ic))) {
3494 debugAopGet (" right:", IC_RIGHT (ic));
3495 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3498 if(IS_SYMOP ( IC_RESULT(ic))) {
3499 debugAopGet (" result:", IC_RESULT (ic));
3500 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3503 if (POINTER_SET (ic))
3504 debugLog (" %d - Pointer set\n", __LINE__);
3507 /* if this is an itemp & result of a address of a true sym
3508 then mark this as rematerialisable */
3509 if (ic->op == ADDRESS_OF &&
3510 IS_ITEMP (IC_RESULT (ic)) &&
3511 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3512 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3513 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3516 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3518 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3519 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3520 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3524 /* if straight assignment then carry remat flag if
3525 this is the only definition */
3526 if (ic->op == '=' &&
3527 !POINTER_SET (ic) &&
3528 IS_SYMOP (IC_RIGHT (ic)) &&
3529 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3530 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3532 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3534 OP_SYMBOL (IC_RESULT (ic))->remat =
3535 OP_SYMBOL (IC_RIGHT (ic))->remat;
3536 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3537 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3540 /* if this is a +/- operation with a rematerizable
3541 then mark this as rematerializable as well */
3542 if ((ic->op == '+' || ic->op == '-') &&
3543 (IS_SYMOP (IC_LEFT (ic)) &&
3544 IS_ITEMP (IC_RESULT (ic)) &&
3545 OP_SYMBOL (IC_LEFT (ic))->remat &&
3546 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3547 IS_OP_LITERAL (IC_RIGHT (ic))))
3549 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3551 operandLitValue (IC_RIGHT (ic));
3552 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3553 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3554 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3557 /* mark the pointer usages */
3558 if (POINTER_SET (ic))
3560 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3561 debugLog (" marking as a pointer (set) =>");
3562 debugAopGet (" result:", IC_RESULT (ic));
3564 if (POINTER_GET (ic))
3566 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3567 debugLog (" marking as a pointer (get) =>");
3568 debugAopGet (" left:", IC_LEFT (ic));
3573 /* if we are using a symbol on the stack
3574 then we should say pic14_ptrRegReq */
3575 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3576 pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3577 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3578 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3579 pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3580 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3583 if (IS_SYMOP (IC_LEFT (ic)))
3584 pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3585 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3586 if (IS_SYMOP (IC_RIGHT (ic)))
3587 pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3588 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3589 if (IS_SYMOP (IC_RESULT (ic)))
3590 pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3591 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3594 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
3598 /* if the condition of an if instruction
3599 is defined in the previous instruction then
3600 mark the itemp as a conditional */
3601 if ((IS_CONDITIONAL (ic) ||
3602 ((ic->op == BITWISEAND ||
3605 isBitwiseOptimizable (ic))) &&
3606 ic->next && ic->next->op == IFX &&
3607 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3608 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3611 debugLog (" %d\n", __LINE__);
3612 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3616 /* reduce for support function calls */
3617 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3618 packRegsForSupport (ic, ebp);
3620 /* if a parameter is passed, it's in W, so we may not
3621 need to place a copy in a register */
3622 if (ic->op == RECEIVE)
3623 packForReceive (ic, ebp);
3625 /* some cases the redundant moves can
3626 can be eliminated for return statements */
3627 if ((ic->op == RETURN || ic->op == SEND) &&
3628 !isOperandInFarSpace (IC_LEFT (ic)) &&
3630 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3632 /* if pointer set & left has a size more than
3633 one and right is not in far space */
3634 if (POINTER_SET (ic) &&
3635 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3636 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3637 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3638 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3640 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3642 /* if pointer get */
3643 if (POINTER_GET (ic) &&
3644 !isOperandInFarSpace (IC_RESULT (ic)) &&
3645 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3646 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3647 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3649 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3652 /* if this is cast for intergral promotion then
3653 check if only use of the definition of the
3654 operand being casted/ if yes then replace
3655 the result of that arithmetic operation with
3656 this result and get rid of the cast */
3657 if (ic->op == CAST) {
3659 sym_link *fromType = operandType (IC_RIGHT (ic));
3660 sym_link *toType = operandType (IC_LEFT (ic));
3662 debugLog (" %d - casting\n", __LINE__);
3664 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3665 getSize (fromType) != getSize (toType)) {
3668 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3671 if (IS_ARITHMETIC_OP (dic)) {
3673 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3674 IC_RESULT (dic) = IC_RESULT (ic);
3675 remiCodeFromeBBlock (ebp, ic);
3676 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3677 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3678 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3682 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3686 /* if the type from and type to are the same
3687 then if this is the only use then packit */
3688 if (compareType (operandType (IC_RIGHT (ic)),
3689 operandType (IC_LEFT (ic))) == 1) {
3691 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3694 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3695 IC_RESULT (dic) = IC_RESULT (ic);
3696 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3697 remiCodeFromeBBlock (ebp, ic);
3698 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3699 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3707 iTempNN := (some variable in farspace) V1
3712 if (ic->op == IPUSH)
3714 packForPush (ic, ebp);
3718 /* pack registers for accumulator use, when the
3719 result of an arithmetic or bit wise operation
3720 has only one use, that use is immediately following
3721 the defintion and the using iCode has only one
3722 operand or has two operands but one is literal &
3723 the result of that operation is not on stack then
3724 we can leave the result of this operation in acc:b
3726 if ((IS_ARITHMETIC_OP (ic)
3728 || IS_BITWISE_OP (ic)
3730 || ic->op == LEFT_OP || ic->op == RIGHT_OP
3733 IS_ITEMP (IC_RESULT (ic)) &&
3734 getSize (operandType (IC_RESULT (ic))) <= 2)
3736 packRegsForAccUse (ic);
3742 dumpEbbsToDebug (eBBlock ** ebbs, int count)
3746 if (!debug || !debugF)
3749 for (i = 0; i < count; i++)
3751 fprintf (debugF, "\n----------------------------------------------------------------\n");
3752 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
3753 ebbs[i]->entryLabel->name,
3756 ebbs[i]->isLastInLoop);
3757 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
3762 fprintf (debugF, "visited %d : hasFcall = %d\n",
3766 fprintf (debugF, "\ndefines bitVector :");
3767 bitVectDebugOn (ebbs[i]->defSet, debugF);
3768 fprintf (debugF, "\nlocal defines bitVector :");
3769 bitVectDebugOn (ebbs[i]->ldefs, debugF);
3770 fprintf (debugF, "\npointers Set bitvector :");
3771 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
3772 fprintf (debugF, "\nin pointers Set bitvector :");
3773 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
3774 fprintf (debugF, "\ninDefs Set bitvector :");
3775 bitVectDebugOn (ebbs[i]->inDefs, debugF);
3776 fprintf (debugF, "\noutDefs Set bitvector :");
3777 bitVectDebugOn (ebbs[i]->outDefs, debugF);
3778 fprintf (debugF, "\nusesDefs Set bitvector :");
3779 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
3780 fprintf (debugF, "\n----------------------------------------------------------------\n");
3781 printiCChain (ebbs[i]->sch, debugF);
3784 /*-----------------------------------------------------------------*/
3785 /* assignRegisters - assigns registers to each live range as need */
3786 /*-----------------------------------------------------------------*/
3788 pic14_assignRegisters (eBBlock ** ebbs, int count)
3793 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
3794 debugLog ("\nebbs before optimizing:\n");
3795 dumpEbbsToDebug (ebbs, count);
3797 setToNull ((void *) &_G.funcrUsed);
3798 pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3801 /* change assignments this will remove some
3802 live ranges reducing some register pressure */
3803 for (i = 0; i < count; i++)
3804 packRegisters (ebbs[i]);
3811 debugLog("dir registers allocated so far:\n");
3812 reg = hTabFirstItem(dynDirectRegNames, &hkey);
3815 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
3816 reg = hTabNextItem(dynDirectRegNames, &hkey);
3821 if (options.dump_pack)
3822 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3824 /* first determine for each live range the number of
3825 registers & the type of registers required for each */
3828 /* and serially allocate registers */
3829 serialRegAssign (ebbs, count);
3831 /* if stack was extended then tell the user */
3834 /* werror(W_TOOMANY_SPILS,"stack", */
3835 /* _G.stackExtend,currFunc->name,""); */
3841 /* werror(W_TOOMANY_SPILS,"data space", */
3842 /* _G.dataExtend,currFunc->name,""); */
3846 /* after that create the register mask
3847 for each of the instruction */
3848 createRegMask (ebbs, count);
3850 /* redo that offsets for stacked automatic variables */
3851 redoStackOffsets ();
3853 if (options.dump_rassgn)
3854 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3856 /* now get back the chain */
3857 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3859 debugLog ("ebbs after optimizing:\n");
3860 dumpEbbsToDebug (ebbs, count);
3865 /* free up any _G.stackSpil locations allocated */
3866 applyToSet (_G.stackSpil, deallocStackSpil);
3868 setToNull ((void **) &_G.stackSpil);
3869 setToNull ((void **) &_G.spiltSet);
3870 /* mark all registers as free */
3871 //pic14_freeAllRegs ();
3873 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");