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 /* this should go in SDCCicode.h, but it doesn't. */
39 #define IS_REF(op) (IS_SYMOP(op) && op->operand.symOperand->isref == 1)
41 /*-----------------------------------------------------------------*/
42 /* At this point we start getting processor specific although */
43 /* some routines are non-processor specific & can be reused when */
44 /* targetting other processors. The decision for this will have */
45 /* to be made on a routine by routine basis */
46 /* routines used to pack registers are most definitely not reusable */
47 /* since the pack the registers depending strictly on the MCU */
48 /*-----------------------------------------------------------------*/
50 extern void genpic14Code (iCode *);
51 extern void assignConfigWordValue(int address, int value);
61 bitVect *funcrUsed; /* registers used in a function */
67 /* Shared with gen.c */
68 int pic14_ptrRegReq; /* one byte pointer register required */
71 set *dynAllocRegs=NULL;
72 set *dynStackRegs=NULL;
73 set *dynProcessorRegs=NULL;
74 set *dynDirectRegs=NULL;
75 set *dynDirectBitRegs=NULL;
76 set *dynInternalRegs=NULL;
78 static hTab *dynDirectRegNames= NULL;
79 // static hTab *regHash = NULL; /* a hash table containing ALL registers */
81 static int dynrIdx=0x20;
82 static int rDirectIdx=0;
84 int pic14_nRegs = 128; // = sizeof (regspic14) / sizeof (regs);
86 int Gstack_base_addr=0; /* The starting address of registers that
87 * are used to pass and return parameters */
92 static void spillThis (symbol *);
94 static FILE *debugF = NULL;
95 /*-----------------------------------------------------------------*/
96 /* debugLog - open a file for debugging information */
97 /*-----------------------------------------------------------------*/
98 //static void debugLog(char *inst,char *fmt, ...)
100 debugLog (char *fmt,...)
102 static int append = 0; // First time through, open the file without append.
105 //char *bufferP=buffer;
108 if (!debug || !dstFileName)
114 /* create the file name */
115 strcpy (buffer, dstFileName);
116 strcat (buffer, ".d");
118 if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
120 werror (E_FILE_OPEN_ERR, buffer);
123 append = 1; // Next time debubLog is called, we'll append the debug info
129 vsprintf (buffer, fmt, ap);
131 fprintf (debugF, "%s", buffer);
133 while (isspace(*bufferP)) bufferP++;
135 if (bufferP && *bufferP)
136 lineCurr = (lineCurr ?
137 connectLine(lineCurr,newLineNode(lb)) :
138 (lineHead = newLineNode(lb)));
139 lineCurr->isInline = _G.inLine;
140 lineCurr->isDebug = _G.debugLine;
150 fputc ('\n', debugF);
152 /*-----------------------------------------------------------------*/
153 /* debugLogClose - closes the debug log file (if opened) */
154 /*-----------------------------------------------------------------*/
164 #define AOP(op) op->aop
167 debugAopGet (char *str, operand * op)
172 printOperand (op, debugF);
180 decodeOp (unsigned int op)
183 if (op < 128 && op > ' ')
185 buffer[0] = (op & 0xff);
199 return "STRING_LITERAL";
235 return "LEFT_ASSIGN";
237 return "RIGHT_ASSIGN";
352 case GET_VALUE_AT_ADDRESS:
353 return "GET_VALUE_AT_ADDRESS";
371 return "ENDFUNCTION";
395 sprintf (buffer, "unkown op %d %c", op, op & 0xff);
398 /*-----------------------------------------------------------------*/
399 /*-----------------------------------------------------------------*/
401 debugLogRegType (short type)
414 sprintf (buffer, "unknown reg type %d", type);
418 /*-----------------------------------------------------------------*/
419 /*-----------------------------------------------------------------*/
420 static int regname2key(char const *name)
429 key += (*name++) + 1;
433 return ( (key + (key >> 4) + (key>>8)) & 0x3f);
437 /*-----------------------------------------------------------------*/
438 /* newReg - allocate and init memory for a new register */
439 /*-----------------------------------------------------------------*/
440 static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias)
445 dReg = Safe_calloc(1,sizeof(regs));
447 dReg->pc_type = pc_type;
450 dReg->name = Safe_strdup(name);
452 sprintf(buffer,"r0x%02X", dReg->rIdx);
455 dReg->name = Safe_strdup(buffer);
457 //fprintf(stderr,"newReg: %s, rIdx = 0x%02x\n",dReg->name,rIdx);
470 dReg->reg_alias = NULL;
471 dReg->reglives.usedpFlows = newSet();
472 dReg->reglives.assignedpFlows = newSet();
474 hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
479 /*-----------------------------------------------------------------*/
480 /* regWithIdx - Search through a set of registers that matches idx */
481 /*-----------------------------------------------------------------*/
483 regWithIdx (set *dRegs, int idx, int fixed)
487 for (dReg = setFirstItem(dRegs) ; dReg ;
488 dReg = setNextItem(dRegs)) {
490 if(idx == dReg->rIdx && (fixed == (int)dReg->isFixed)) {
498 /*-----------------------------------------------------------------*/
499 /* regFindFree - Search for a free register in a set of registers */
500 /*-----------------------------------------------------------------*/
502 regFindFree (set *dRegs)
506 for (dReg = setFirstItem(dRegs) ; dReg ;
507 dReg = setNextItem(dRegs)) {
515 /*-----------------------------------------------------------------*/
516 /* initStack - allocate registers for a psuedo stack */
517 /*-----------------------------------------------------------------*/
518 void initStack(int base_address, int size)
523 Gstack_base_addr = base_address;
524 //fprintf(stderr,"initStack");
526 for(i = 0; i<size; i++)
527 addSet(&dynStackRegs,newReg(REG_STK, PO_GPR_TEMP,base_address++,NULL,1,0));
530 /*-----------------------------------------------------------------*
531 *-----------------------------------------------------------------*/
533 allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
536 //fprintf(stderr,"allocProcessorRegister %s addr =0x%x\n",name,rIdx);
537 return addSet(&dynProcessorRegs,newReg(REG_SFR, po_type, rIdx, name,1,alias));
540 /*-----------------------------------------------------------------*
541 *-----------------------------------------------------------------*/
544 allocInternalRegister(int rIdx, char * name, short po_type, int alias)
546 regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias);
548 //fprintf(stderr,"allocInternalRegister %s addr =0x%x\n",name,rIdx);
551 return addSet(&dynInternalRegs,reg);
556 /*-----------------------------------------------------------------*/
557 /* allocReg - allocates register of given type */
558 /*-----------------------------------------------------------------*/
560 allocReg (short type)
563 debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
564 //fprintf(stderr,"allocReg\n");
567 return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
572 /*-----------------------------------------------------------------*/
573 /* dirregWithName - search for register by name */
574 /*-----------------------------------------------------------------*/
576 dirregWithName (char *name)
584 /* hash the name to get a key */
586 hkey = regname2key(name);
588 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
592 if(STRCASECMP(reg->name, name) == 0) {
596 reg = hTabNextItemWK (dynDirectRegNames);
600 return NULL; // name wasn't found in the hash table
603 int IS_CONFIG_ADDRESS(int address)
606 return address == 0x2007;
609 /*-----------------------------------------------------------------*/
610 /* allocDirReg - allocates register of given type */
611 /*-----------------------------------------------------------------*/
613 allocDirReg (operand *op )
620 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
624 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
626 /* If the symbol is at a fixed address, then remove the leading underscore
627 * from the name. This is hack to allow the .asm include file named registers
628 * to match the .c declared register names */
630 //if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && (*name == '_'))
633 debugLog ("%s symbol name %s\n", __FUNCTION__,name);
635 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
636 debugLog(" %d const char\n",__LINE__);
637 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
640 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
641 if (IS_CODE ( OP_SYM_ETYPE(op)) )
642 debugLog(" %d code space\n",__LINE__);
644 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
645 debugLog(" %d integral\n",__LINE__);
646 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
647 debugLog(" %d literal\n",__LINE__);
648 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
649 debugLog(" %d specifier\n",__LINE__);
650 debugAopGet(NULL, op);
653 if (IS_CODE ( OP_SYM_ETYPE(op)) )
656 /* First, search the hash table to see if there is a register with this name */
657 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && !(IS_BITVAR (OP_SYM_ETYPE(op))) ) {
658 reg = regWithIdx (dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1);
661 fprintf(stderr,"ralloc %s is at fixed address but not a processor reg, addr=0x%x\n",
662 name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
664 fprintf(stderr,"ralloc %s at fixed address has already been declared, addr=0x%x\n",
665 name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
668 //fprintf(stderr,"ralloc:%d %s \n", __LINE__,name);
670 reg = dirregWithName(name);
676 /* if this is at an absolute address, then get the address. */
677 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
678 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
679 //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
682 /* Register wasn't found in hash, so let's create
683 * a new one and put it in the hash table AND in the
684 * dynDirectRegNames set */
685 if(!IS_CONFIG_ADDRESS(address)) {
686 //fprintf(stderr,"allocating new reg %s\n",name);
688 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0 );
689 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
691 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
693 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
695 //fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
699 if (IS_BITVAR (OP_SYM_ETYPE(op))) {
700 addSet(&dynDirectBitRegs, reg);
703 addSet(&dynDirectRegs, reg);
706 debugLog (" -- %s is declared at address 0x2007\n",name);
711 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
713 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
714 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
720 /*-----------------------------------------------------------------*/
721 /* allocDirReg - allocates register of given type */
722 /*-----------------------------------------------------------------*/
724 allocRegByName (char *name, int size)
730 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
734 /* First, search the hash table to see if there is a register with this name */
735 reg = dirregWithName(name);
739 /* Register wasn't found in hash, so let's create
740 * a new one and put it in the hash table AND in the
741 * dynDirectRegNames set */
742 //fprintf (stderr,"%s symbol name %s\n", __FUNCTION__,name);
743 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0 );
745 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
747 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
748 addSet(&dynDirectRegs, reg);
754 /*-----------------------------------------------------------------*/
755 /* RegWithIdx - returns pointer to register with index number */
756 /*-----------------------------------------------------------------*/
758 typeRegWithIdx (int idx, int type, int fixed)
763 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
768 if( (dReg = regWithIdx ( dynAllocRegs, idx, fixed)) != NULL) {
770 debugLog ("Found a Dynamic Register!\n");
773 if( (dReg = regWithIdx ( dynDirectRegs, idx, fixed)) != NULL ) {
774 debugLog ("Found a Direct Register!\n");
780 if( (dReg = regWithIdx ( dynStackRegs, idx, fixed)) != NULL ) {
781 debugLog ("Found a Stack Register!\n");
786 if( (dReg = regWithIdx ( dynProcessorRegs, idx, fixed)) != NULL ) {
787 debugLog ("Found a Processor Register!\n");
801 /*-----------------------------------------------------------------*/
802 /* pic14_regWithIdx - returns pointer to register with index number*/
803 /*-----------------------------------------------------------------*/
805 pic14_regWithIdx (int idx)
809 if( (dReg = typeRegWithIdx(idx,REG_GPR,0)) != NULL)
812 if( (dReg = typeRegWithIdx(idx,REG_SFR,0)) != NULL)
815 if( (dReg = typeRegWithIdx(idx,REG_STK,0)) != NULL)
821 /*-----------------------------------------------------------------*/
822 /* pic14_regWithIdx - returns pointer to register with index number */
823 /*-----------------------------------------------------------------*/
825 pic14_allocWithIdx (int idx)
830 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
832 if( (dReg = regWithIdx ( dynAllocRegs, idx,0)) != NULL) {
834 debugLog ("Found a Dynamic Register!\n");
835 } else if( (dReg = regWithIdx ( dynStackRegs, idx,0)) != NULL ) {
836 debugLog ("Found a Stack Register!\n");
837 } else if( (dReg = regWithIdx ( dynProcessorRegs, idx,0)) != NULL ) {
838 debugLog ("Found a Processor Register!\n");
839 } else if( (dReg = regWithIdx ( dynInternalRegs, idx,0)) != NULL ) {
840 debugLog ("Found an Internal Register!\n");
841 } else if( (dReg = regWithIdx ( dynInternalRegs, idx,1)) != NULL ) {
842 debugLog ("Found an Internal Register!\n");
845 debugLog ("Dynamic Register not found\n");
848 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
849 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
850 "regWithIdx not found");
860 /*-----------------------------------------------------------------*/
861 /*-----------------------------------------------------------------*/
863 pic14_findFreeReg(short type)
870 if((dReg = regFindFree(dynAllocRegs)) != NULL)
872 return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
876 if((dReg = regFindFree(dynStackRegs)) != NULL)
888 /*-----------------------------------------------------------------*/
889 /* freeReg - frees a register */
890 /*-----------------------------------------------------------------*/
894 debugLog ("%s\n", __FUNCTION__);
899 /*-----------------------------------------------------------------*/
900 /* nFreeRegs - returns number of free registers */
901 /*-----------------------------------------------------------------*/
905 /* dynamically allocate as many as we need and worry about
906 * fitting them into a PIC later */
913 debugLog ("%s\n", __FUNCTION__);
914 for (i = 0; i < pic14_nRegs; i++)
915 if (regspic14[i].isFree && regspic14[i].type == type)
921 /*-----------------------------------------------------------------*/
922 /* nfreeRegsType - free registers with type */
923 /*-----------------------------------------------------------------*/
925 nfreeRegsType (int type)
928 debugLog ("%s\n", __FUNCTION__);
931 if ((nfr = nFreeRegs (type)) == 0)
932 return nFreeRegs (REG_GPR);
935 return nFreeRegs (type);
938 void writeSetUsedRegs(FILE *of, set *dRegs)
943 for (dReg = setFirstItem(dRegs) ; dReg ;
944 dReg = setNextItem(dRegs)) {
947 fprintf (of, "\t%s\n",dReg->name);
951 extern void assignFixedRegisters(set *regset);
952 extern void assignRelocatableRegisters(set *regset,int used);
953 extern void dump_map(void);
954 extern void dump_sfr(FILE *of);
956 void packBits(set *bregs)
961 regs *relocbitfield=NULL;
967 for (regset = bregs ; regset ;
968 regset = regset->next) {
971 breg->isBitField = 1;
972 //fprintf(stderr,"bit reg: %s\n",breg->name);
975 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
977 bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1);
978 breg->rIdx = breg->address & 7;
982 //sprintf (buffer, "fbitfield%02x", breg->address);
983 sprintf (buffer, "0x%02x", breg->address);
984 //fprintf(stderr,"new bit field\n");
985 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0);
986 bitfield->isBitField = 1;
987 bitfield->isFixed = 1;
988 bitfield->address = breg->address;
989 //addSet(&dynDirectRegs,bitfield);
990 addSet(&dynInternalRegs,bitfield);
991 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
993 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
996 breg->reg_alias = bitfield;
1000 if(!relocbitfield || bit_no >7) {
1003 sprintf (buffer, "bitfield%d", byte_no);
1004 //fprintf(stderr,"new relocatable bit field\n");
1005 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0);
1006 relocbitfield->isBitField = 1;
1007 //addSet(&dynDirectRegs,relocbitfield);
1008 addSet(&dynInternalRegs,relocbitfield);
1009 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1013 breg->reg_alias = relocbitfield;
1014 breg->address = rDirectIdx; /* byte_no; */
1015 breg->rIdx = bit_no++;
1023 void bitEQUs(FILE *of, set *bregs)
1025 regs *breg,*bytereg;
1028 //fprintf(stderr," %s\n",__FUNCTION__);
1029 for (breg = setFirstItem(bregs) ; breg ;
1030 breg = setNextItem(bregs)) {
1032 //fprintf(stderr,"bit reg: %s\n",breg->name);
1034 bytereg = breg->reg_alias;
1036 fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
1039 breg->rIdx & 0x0007);
1042 //fprintf(stderr, "bit field is not assigned to a register\n");
1043 fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
1053 void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
1058 for (reg = setFirstItem(fregs) ; reg ;
1059 reg = setNextItem(fregs)) {
1061 //if(!reg->isEmitted && reg->wasUsed) {
1064 fprintf (of, "%s\tEQU\t0x%03x\n",
1068 fprintf (of, "%s\tEQU\t0x%03x\n",
1076 void writeUsedRegs(FILE *of)
1078 packBits(dynDirectBitRegs);
1080 assignFixedRegisters(dynInternalRegs);
1081 assignFixedRegisters(dynAllocRegs);
1082 assignFixedRegisters(dynStackRegs);
1083 assignFixedRegisters(dynDirectRegs);
1085 assignRelocatableRegisters(dynInternalRegs,0);
1086 assignRelocatableRegisters(dynAllocRegs,0);
1087 assignRelocatableRegisters(dynStackRegs,0);
1090 assignRelocatableRegisters(dynDirectRegs,0);
1091 printf("assignRelocatableRegisters(dynDirectRegs,0);\n");
1096 bitEQUs(of,dynDirectBitRegs);
1098 aliasEQUs(of,dynAllocRegs,0);
1099 aliasEQUs(of,dynDirectRegs,0);
1100 aliasEQUs(of,dynStackRegs,0);
1101 aliasEQUs(of,dynProcessorRegs,1);
1106 /*-----------------------------------------------------------------*/
1107 /* allDefsOutOfRange - all definitions are out of a range */
1108 /*-----------------------------------------------------------------*/
1110 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
1114 debugLog ("%s\n", __FUNCTION__);
1118 for (i = 0; i < defs->size; i++)
1122 if (bitVectBitValue (defs, i) &&
1123 (ic = hTabItemWithKey (iCodehTab, i)) &&
1124 (ic->seq >= fseq && ic->seq <= toseq))
1134 /*-----------------------------------------------------------------*/
1135 /* computeSpillable - given a point find the spillable live ranges */
1136 /*-----------------------------------------------------------------*/
1138 computeSpillable (iCode * ic)
1142 debugLog ("%s\n", __FUNCTION__);
1143 /* spillable live ranges are those that are live at this
1144 point . the following categories need to be subtracted
1146 a) - those that are already spilt
1147 b) - if being used by this one
1148 c) - defined by this one */
1150 spillable = bitVectCopy (ic->rlive);
1152 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1154 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1155 bitVectUnSetBit (spillable, ic->defKey);
1156 spillable = bitVectIntersect (spillable, _G.regAssigned);
1161 /*-----------------------------------------------------------------*/
1162 /* noSpilLoc - return true if a variable has no spil location */
1163 /*-----------------------------------------------------------------*/
1165 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1167 debugLog ("%s\n", __FUNCTION__);
1168 return (sym->usl.spillLoc ? 0 : 1);
1171 /*-----------------------------------------------------------------*/
1172 /* hasSpilLoc - will return 1 if the symbol has spil location */
1173 /*-----------------------------------------------------------------*/
1175 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1177 debugLog ("%s\n", __FUNCTION__);
1178 return (sym->usl.spillLoc ? 1 : 0);
1181 /*-----------------------------------------------------------------*/
1182 /* directSpilLoc - will return 1 if the splilocation is in direct */
1183 /*-----------------------------------------------------------------*/
1185 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1187 debugLog ("%s\n", __FUNCTION__);
1188 if (sym->usl.spillLoc &&
1189 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1195 /*-----------------------------------------------------------------*/
1196 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1197 /* but is not used as a pointer */
1198 /*-----------------------------------------------------------------*/
1200 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1202 debugLog ("%s\n", __FUNCTION__);
1203 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1206 /*-----------------------------------------------------------------*/
1207 /* rematable - will return 1 if the remat flag is set */
1208 /*-----------------------------------------------------------------*/
1210 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1212 debugLog ("%s\n", __FUNCTION__);
1216 /*-----------------------------------------------------------------*/
1217 /* notUsedInRemaining - not used or defined in remain of the block */
1218 /*-----------------------------------------------------------------*/
1220 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1222 debugLog ("%s\n", __FUNCTION__);
1223 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1224 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1227 /*-----------------------------------------------------------------*/
1228 /* allLRs - return true for all */
1229 /*-----------------------------------------------------------------*/
1231 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1233 debugLog ("%s\n", __FUNCTION__);
1237 /*-----------------------------------------------------------------*/
1238 /* liveRangesWith - applies function to a given set of live range */
1239 /*-----------------------------------------------------------------*/
1241 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1242 eBBlock * ebp, iCode * ic)
1247 debugLog ("%s\n", __FUNCTION__);
1248 if (!lrs || !lrs->size)
1251 for (i = 1; i < lrs->size; i++)
1254 if (!bitVectBitValue (lrs, i))
1257 /* if we don't find it in the live range
1258 hash table we are in serious trouble */
1259 if (!(sym = hTabItemWithKey (liveRanges, i)))
1261 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1262 "liveRangesWith could not find liveRange");
1266 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1267 addSetHead (&rset, sym);
1274 /*-----------------------------------------------------------------*/
1275 /* leastUsedLR - given a set determines which is the least used */
1276 /*-----------------------------------------------------------------*/
1278 leastUsedLR (set * sset)
1280 symbol *sym = NULL, *lsym = NULL;
1282 debugLog ("%s\n", __FUNCTION__);
1283 sym = lsym = setFirstItem (sset);
1288 for (; lsym; lsym = setNextItem (sset))
1291 /* if usage is the same then prefer
1292 the spill the smaller of the two */
1293 if (lsym->used == sym->used)
1294 if (getSize (lsym->type) < getSize (sym->type))
1298 if (lsym->used < sym->used)
1303 setToNull ((void **) &sset);
1308 /*-----------------------------------------------------------------*/
1309 /* noOverLap - will iterate through the list looking for over lap */
1310 /*-----------------------------------------------------------------*/
1312 noOverLap (set * itmpStack, symbol * fsym)
1315 debugLog ("%s\n", __FUNCTION__);
1318 for (sym = setFirstItem (itmpStack); sym;
1319 sym = setNextItem (itmpStack))
1321 if (sym->liveTo > fsym->liveFrom)
1329 /*-----------------------------------------------------------------*/
1330 /* isFree - will return 1 if the a free spil location is found */
1331 /*-----------------------------------------------------------------*/
1336 V_ARG (symbol **, sloc);
1337 V_ARG (symbol *, fsym);
1339 debugLog ("%s\n", __FUNCTION__);
1340 /* if already found */
1344 /* if it is free && and the itmp assigned to
1345 this does not have any overlapping live ranges
1346 with the one currently being assigned and
1347 the size can be accomodated */
1349 noOverLap (sym->usl.itmpStack, fsym) &&
1350 getSize (sym->type) >= getSize (fsym->type))
1359 /*-----------------------------------------------------------------*/
1360 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1361 /*-----------------------------------------------------------------*/
1363 spillLRWithPtrReg (symbol * forSym)
1369 debugLog ("%s\n", __FUNCTION__);
1370 if (!_G.regAssigned ||
1371 bitVectIsZero (_G.regAssigned))
1374 r0 = pic14_regWithIdx (R0_IDX);
1375 r1 = pic14_regWithIdx (R1_IDX);
1377 /* for all live ranges */
1378 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1379 lrsym = hTabNextItem (liveRanges, &k))
1383 /* if no registers assigned to it or
1385 /* if it does not overlap with this then
1386 not need to spill it */
1388 if (lrsym->isspilt || !lrsym->nRegs ||
1389 (lrsym->liveTo < forSym->liveFrom))
1392 /* go thru the registers : if it is either
1393 r0 or r1 then spil it */
1394 for (j = 0; j < lrsym->nRegs; j++)
1395 if (lrsym->regs[j] == r0 ||
1396 lrsym->regs[j] == r1)
1405 /*-----------------------------------------------------------------*/
1406 /* createStackSpil - create a location on the stack to spil */
1407 /*-----------------------------------------------------------------*/
1409 createStackSpil (symbol * sym)
1411 symbol *sloc = NULL;
1412 int useXstack, model, noOverlay;
1414 char slocBuffer[30];
1415 debugLog ("%s\n", __FUNCTION__);
1417 /* first go try and find a free one that is already
1418 existing on the stack */
1419 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1421 /* found a free one : just update & return */
1422 sym->usl.spillLoc = sloc;
1425 addSetHead (&sloc->usl.itmpStack, sym);
1429 /* could not then have to create one , this is the hard part
1430 we need to allocate this on the stack : this is really a
1431 hack!! but cannot think of anything better at this time */
1433 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1435 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1436 __FILE__, __LINE__);
1440 sloc = newiTemp (slocBuffer);
1442 /* set the type to the spilling symbol */
1443 sloc->type = copyLinkChain (sym->type);
1444 sloc->etype = getSpec (sloc->type);
1445 SPEC_SCLS (sloc->etype) = S_DATA;
1446 SPEC_EXTR (sloc->etype) = 0;
1447 SPEC_STAT (sloc->etype) = 0;
1449 /* we don't allow it to be allocated`
1450 onto the external stack since : so we
1451 temporarily turn it off ; we also
1452 turn off memory model to prevent
1453 the spil from going to the external storage
1454 and turn off overlaying
1457 useXstack = options.useXstack;
1458 model = options.model;
1459 noOverlay = options.noOverlay;
1460 options.noOverlay = 1;
1461 options.model = options.useXstack = 0;
1465 options.useXstack = useXstack;
1466 options.model = model;
1467 options.noOverlay = noOverlay;
1468 sloc->isref = 1; /* to prevent compiler warning */
1470 /* if it is on the stack then update the stack */
1471 if (IN_STACK (sloc->etype))
1473 currFunc->stack += getSize (sloc->type);
1474 _G.stackExtend += getSize (sloc->type);
1477 _G.dataExtend += getSize (sloc->type);
1479 /* add it to the _G.stackSpil set */
1480 addSetHead (&_G.stackSpil, sloc);
1481 sym->usl.spillLoc = sloc;
1484 /* add it to the set of itempStack set
1485 of the spill location */
1486 addSetHead (&sloc->usl.itmpStack, sym);
1490 /*-----------------------------------------------------------------*/
1491 /* isSpiltOnStack - returns true if the spil location is on stack */
1492 /*-----------------------------------------------------------------*/
1494 isSpiltOnStack (symbol * sym)
1498 debugLog ("%s\n", __FUNCTION__);
1505 /* if (sym->_G.stackSpil) */
1508 if (!sym->usl.spillLoc)
1511 etype = getSpec (sym->usl.spillLoc->type);
1512 if (IN_STACK (etype))
1518 /*-----------------------------------------------------------------*/
1519 /* spillThis - spils a specific operand */
1520 /*-----------------------------------------------------------------*/
1522 spillThis (symbol * sym)
1525 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1527 /* if this is rematerializable or has a spillLocation
1528 we are okay, else we need to create a spillLocation
1530 if (!(sym->remat || sym->usl.spillLoc))
1531 createStackSpil (sym);
1534 /* mark it has spilt & put it in the spilt set */
1536 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1538 bitVectUnSetBit (_G.regAssigned, sym->key);
1540 for (i = 0; i < sym->nRegs; i++)
1544 freeReg (sym->regs[i]);
1545 sym->regs[i] = NULL;
1548 /* if spilt on stack then free up r0 & r1
1549 if they could have been assigned to some
1551 if (!pic14_ptrRegReq && isSpiltOnStack (sym))
1554 spillLRWithPtrReg (sym);
1557 if (sym->usl.spillLoc && !sym->remat)
1558 sym->usl.spillLoc->allocreq = 1;
1562 /*-----------------------------------------------------------------*/
1563 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1564 /*-----------------------------------------------------------------*/
1566 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1568 bitVect *lrcs = NULL;
1572 debugLog ("%s\n", __FUNCTION__);
1573 /* get the spillable live ranges */
1574 lrcs = computeSpillable (ic);
1576 /* get all live ranges that are rematerizable */
1577 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1580 /* return the least used of these */
1581 return leastUsedLR (selectS);
1584 /* get live ranges with spillLocations in direct space */
1585 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1587 sym = leastUsedLR (selectS);
1588 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1589 sym->usl.spillLoc->rname :
1590 sym->usl.spillLoc->name));
1592 /* mark it as allocation required */
1593 sym->usl.spillLoc->allocreq = 1;
1597 /* if the symbol is local to the block then */
1598 if (forSym->liveTo < ebp->lSeq)
1601 /* check if there are any live ranges allocated
1602 to registers that are not used in this block */
1603 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1605 sym = leastUsedLR (selectS);
1606 /* if this is not rematerializable */
1615 /* check if there are any live ranges that not
1616 used in the remainder of the block */
1617 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1619 sym = leastUsedLR (selectS);
1622 sym->remainSpil = 1;
1629 /* find live ranges with spillocation && not used as pointers */
1630 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1633 sym = leastUsedLR (selectS);
1634 /* mark this as allocation required */
1635 sym->usl.spillLoc->allocreq = 1;
1639 /* find live ranges with spillocation */
1640 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1643 sym = leastUsedLR (selectS);
1644 sym->usl.spillLoc->allocreq = 1;
1648 /* couldn't find then we need to create a spil
1649 location on the stack , for which one? the least
1651 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1654 /* return a created spil location */
1655 sym = createStackSpil (leastUsedLR (selectS));
1656 sym->usl.spillLoc->allocreq = 1;
1660 /* this is an extreme situation we will spill
1661 this one : happens very rarely but it does happen */
1667 /*-----------------------------------------------------------------*/
1668 /* spilSomething - spil some variable & mark registers as free */
1669 /*-----------------------------------------------------------------*/
1671 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1676 debugLog ("%s\n", __FUNCTION__);
1677 /* get something we can spil */
1678 ssym = selectSpil (ic, ebp, forSym);
1680 /* mark it as spilt */
1682 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1684 /* mark it as not register assigned &
1685 take it away from the set */
1686 bitVectUnSetBit (_G.regAssigned, ssym->key);
1688 /* mark the registers as free */
1689 for (i = 0; i < ssym->nRegs; i++)
1691 freeReg (ssym->regs[i]);
1693 /* if spilt on stack then free up r0 & r1
1694 if they could have been assigned to as gprs */
1695 if (!pic14_ptrRegReq && isSpiltOnStack (ssym))
1698 spillLRWithPtrReg (ssym);
1701 /* if this was a block level spil then insert push & pop
1702 at the start & end of block respectively */
1703 if (ssym->blockSpil)
1705 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1706 /* add push to the start of the block */
1707 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1708 ebp->sch->next : ebp->sch));
1709 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1710 /* add pop to the end of the block */
1711 addiCodeToeBBlock (ebp, nic, NULL);
1714 /* if spilt because not used in the remainder of the
1715 block then add a push before this instruction and
1716 a pop at the end of the block */
1717 if (ssym->remainSpil)
1720 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1721 /* add push just before this instruction */
1722 addiCodeToeBBlock (ebp, nic, ic);
1724 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1725 /* add pop to the end of the block */
1726 addiCodeToeBBlock (ebp, nic, NULL);
1735 /*-----------------------------------------------------------------*/
1736 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1737 /*-----------------------------------------------------------------*/
1739 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1743 debugLog ("%s\n", __FUNCTION__);
1745 /* try for a ptr type */
1746 if ((reg = allocReg (REG_PTR)))
1749 /* try for gpr type */
1750 if ((reg = allocReg (REG_GPR)))
1753 /* we have to spil */
1754 if (!spilSomething (ic, ebp, sym))
1757 /* this looks like an infinite loop but
1758 in really selectSpil will abort */
1762 /*-----------------------------------------------------------------*/
1763 /* getRegGpr - will try for GPR if not spil */
1764 /*-----------------------------------------------------------------*/
1766 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1770 debugLog ("%s\n", __FUNCTION__);
1772 /* try for gpr type */
1773 if ((reg = allocReg (REG_GPR)))
1776 if (!pic14_ptrRegReq)
1777 if ((reg = allocReg (REG_PTR)))
1780 /* we have to spil */
1781 if (!spilSomething (ic, ebp, sym))
1784 /* this looks like an infinite loop but
1785 in really selectSpil will abort */
1789 /*-----------------------------------------------------------------*/
1790 /* symHasReg - symbol has a given register */
1791 /*-----------------------------------------------------------------*/
1793 symHasReg (symbol * sym, regs * reg)
1797 debugLog ("%s\n", __FUNCTION__);
1798 for (i = 0; i < sym->nRegs; i++)
1799 if (sym->regs[i] == reg)
1805 /*-----------------------------------------------------------------*/
1806 /* deassignLRs - check the live to and if they have registers & are */
1807 /* not spilt then free up the registers */
1808 /*-----------------------------------------------------------------*/
1810 deassignLRs (iCode * ic, eBBlock * ebp)
1816 debugLog ("%s\n", __FUNCTION__);
1817 for (sym = hTabFirstItem (liveRanges, &k); sym;
1818 sym = hTabNextItem (liveRanges, &k))
1821 symbol *psym = NULL;
1822 /* if it does not end here */
1823 if (sym->liveTo > ic->seq)
1826 /* if it was spilt on stack then we can
1827 mark the stack spil location as free */
1832 sym->usl.spillLoc->isFree = 1;
1838 if (!bitVectBitValue (_G.regAssigned, sym->key))
1841 /* special case check if this is an IFX &
1842 the privious one was a pop and the
1843 previous one was not spilt then keep track
1845 if (ic->op == IFX && ic->prev &&
1846 ic->prev->op == IPOP &&
1847 !ic->prev->parmPush &&
1848 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1849 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1855 bitVectUnSetBit (_G.regAssigned, sym->key);
1857 /* if the result of this one needs registers
1858 and does not have it then assign it right
1860 if (IC_RESULT (ic) &&
1861 !(SKIP_IC2 (ic) || /* not a special icode */
1862 ic->op == JUMPTABLE ||
1867 POINTER_SET (ic)) &&
1868 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1869 result->liveTo > ic->seq && /* and will live beyond this */
1870 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1871 result->regType == sym->regType && /* same register types */
1872 result->nRegs && /* which needs registers */
1873 !result->isspilt && /* and does not already have them */
1875 !bitVectBitValue (_G.regAssigned, result->key) &&
1876 /* the number of free regs + number of regs in this LR
1877 can accomodate the what result Needs */
1878 ((nfreeRegsType (result->regType) +
1879 sym->nRegs) >= result->nRegs)
1883 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1885 result->regs[i] = sym->regs[i];
1887 result->regs[i] = getRegGpr (ic, ebp, result);
1889 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1893 /* free the remaining */
1894 for (; i < sym->nRegs; i++)
1898 if (!symHasReg (psym, sym->regs[i]))
1899 freeReg (sym->regs[i]);
1902 freeReg (sym->regs[i]);
1909 /*-----------------------------------------------------------------*/
1910 /* reassignLR - reassign this to registers */
1911 /*-----------------------------------------------------------------*/
1913 reassignLR (operand * op)
1915 symbol *sym = OP_SYMBOL (op);
1918 debugLog ("%s\n", __FUNCTION__);
1919 /* not spilt any more */
1920 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1921 bitVectUnSetBit (_G.spiltSet, sym->key);
1923 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1927 for (i = 0; i < sym->nRegs; i++)
1928 sym->regs[i]->isFree = 0;
1931 /*-----------------------------------------------------------------*/
1932 /* willCauseSpill - determines if allocating will cause a spill */
1933 /*-----------------------------------------------------------------*/
1935 willCauseSpill (int nr, int rt)
1937 debugLog ("%s\n", __FUNCTION__);
1938 /* first check if there are any avlb registers
1939 of te type required */
1942 /* special case for pointer type
1943 if pointer type not avlb then
1944 check for type gpr */
1945 if (nFreeRegs (rt) >= nr)
1947 if (nFreeRegs (REG_GPR) >= nr)
1952 if (pic14_ptrRegReq)
1954 if (nFreeRegs (rt) >= nr)
1959 if (nFreeRegs (REG_PTR) +
1960 nFreeRegs (REG_GPR) >= nr)
1965 debugLog (" ... yep it will (cause a spill)\n");
1966 /* it will cause a spil */
1970 /*-----------------------------------------------------------------*/
1971 /* positionRegs - the allocator can allocate same registers to res- */
1972 /* ult and operand, if this happens make sure they are in the same */
1973 /* position as the operand otherwise chaos results */
1974 /*-----------------------------------------------------------------*/
1976 positionRegs (symbol * result, symbol * opsym, int lineno)
1978 int count = min (result->nRegs, opsym->nRegs);
1979 int i, j = 0, shared = 0;
1981 debugLog ("%s\n", __FUNCTION__);
1982 /* if the result has been spilt then cannot share */
1987 /* first make sure that they actually share */
1988 for (i = 0; i < count; i++)
1990 for (j = 0; j < count; j++)
1992 if (result->regs[i] == opsym->regs[j] && i != j)
2002 regs *tmp = result->regs[i];
2003 result->regs[i] = result->regs[j];
2004 result->regs[j] = tmp;
2009 /*-----------------------------------------------------------------*/
2010 /* serialRegAssign - serially allocate registers to the variables */
2011 /*-----------------------------------------------------------------*/
2013 serialRegAssign (eBBlock ** ebbs, int count)
2017 debugLog ("%s\n", __FUNCTION__);
2018 /* for all blocks */
2019 for (i = 0; i < count; i++)
2024 if (ebbs[i]->noPath &&
2025 (ebbs[i]->entryLabel != entryLabel &&
2026 ebbs[i]->entryLabel != returnLabel))
2029 /* of all instructions do */
2030 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2033 debugLog (" op: %s\n", decodeOp (ic->op));
2035 /* if this is an ipop that means some live
2036 range will have to be assigned again */
2038 reassignLR (IC_LEFT (ic));
2040 /* if result is present && is a true symbol */
2041 if (IC_RESULT (ic) && ic->op != IFX &&
2042 IS_TRUE_SYMOP (IC_RESULT (ic)))
2043 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2045 /* take away registers from live
2046 ranges that end at this instruction */
2047 deassignLRs (ic, ebbs[i]);
2049 /* some don't need registers */
2050 if (SKIP_IC2 (ic) ||
2051 ic->op == JUMPTABLE ||
2055 (IC_RESULT (ic) && POINTER_SET (ic)))
2058 /* now we need to allocate registers
2059 only for the result */
2062 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2068 /* if it does not need or is spilt
2069 or is already assigned to registers
2070 or will not live beyond this instructions */
2073 bitVectBitValue (_G.regAssigned, sym->key) ||
2074 sym->liveTo <= ic->seq)
2077 /* if some liverange has been spilt at the block level
2078 and this one live beyond this block then spil this
2080 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2085 /* if trying to allocate this will cause
2086 a spill and there is nothing to spill
2087 or this one is rematerializable then
2089 willCS = willCauseSpill (sym->nRegs, sym->regType);
2090 spillable = computeSpillable (ic);
2092 (willCS && bitVectIsZero (spillable)))
2100 /* if it has a spillocation & is used less than
2101 all other live ranges then spill this */
2103 if (sym->usl.spillLoc) {
2104 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2105 allLRs, ebbs[i], ic));
2106 if (leastUsed && leastUsed->used > sym->used) {
2111 /* if none of the liveRanges have a spillLocation then better
2112 to spill this one than anything else already assigned to registers */
2113 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2114 /* if this is local to this block then we might find a block spil */
2115 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2123 if (ic->op == RECEIVE)
2124 debugLog ("When I get clever, I'll optimize the receive logic\n");
2126 /* if we need ptr regs for the right side
2128 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2129 <= (unsigned) PTRSIZE)
2134 /* else we assign registers to it */
2135 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2137 debugLog (" %d - \n", __LINE__);
2139 bitVectDebugOn(_G.regAssigned, debugF);
2140 for (j = 0; j < sym->nRegs; j++)
2142 if (sym->regType == REG_PTR)
2143 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2145 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2147 /* if the allocation failed which means
2148 this was spilt then break */
2152 debugLog (" %d - \n", __LINE__);
2154 /* if it shares registers with operands make sure
2155 that they are in the same position */
2156 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2157 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2158 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2159 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2160 /* do the same for the right operand */
2161 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2162 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2163 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2164 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2166 debugLog (" %d - \n", __LINE__);
2169 debugLog (" %d - \n", __LINE__);
2179 /*-----------------------------------------------------------------*/
2180 /* rUmaskForOp :- returns register mask for an operand */
2181 /*-----------------------------------------------------------------*/
2183 rUmaskForOp (operand * op)
2189 debugLog ("%s\n", __FUNCTION__);
2190 /* only temporaries are assigned registers */
2194 sym = OP_SYMBOL (op);
2196 /* if spilt or no registers assigned to it
2198 if (sym->isspilt || !sym->nRegs)
2201 rumask = newBitVect (pic14_nRegs);
2203 for (j = 0; j < sym->nRegs; j++)
2205 rumask = bitVectSetBit (rumask,
2206 sym->regs[j]->rIdx);
2212 /*-----------------------------------------------------------------*/
2213 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2214 /*-----------------------------------------------------------------*/
2216 regsUsedIniCode (iCode * ic)
2218 bitVect *rmask = newBitVect (pic14_nRegs);
2220 debugLog ("%s\n", __FUNCTION__);
2221 /* do the special cases first */
2224 rmask = bitVectUnion (rmask,
2225 rUmaskForOp (IC_COND (ic)));
2229 /* for the jumptable */
2230 if (ic->op == JUMPTABLE)
2232 rmask = bitVectUnion (rmask,
2233 rUmaskForOp (IC_JTCOND (ic)));
2238 /* of all other cases */
2240 rmask = bitVectUnion (rmask,
2241 rUmaskForOp (IC_LEFT (ic)));
2245 rmask = bitVectUnion (rmask,
2246 rUmaskForOp (IC_RIGHT (ic)));
2249 rmask = bitVectUnion (rmask,
2250 rUmaskForOp (IC_RESULT (ic)));
2256 /*-----------------------------------------------------------------*/
2257 /* createRegMask - for each instruction will determine the regsUsed */
2258 /*-----------------------------------------------------------------*/
2260 createRegMask (eBBlock ** ebbs, int count)
2264 debugLog ("%s\n", __FUNCTION__);
2265 /* for all blocks */
2266 for (i = 0; i < count; i++)
2270 if (ebbs[i]->noPath &&
2271 (ebbs[i]->entryLabel != entryLabel &&
2272 ebbs[i]->entryLabel != returnLabel))
2275 /* for all instructions */
2276 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2281 if (SKIP_IC2 (ic) || !ic->rlive)
2284 /* first mark the registers used in this
2286 ic->rUsed = regsUsedIniCode (ic);
2287 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2289 /* now create the register mask for those
2290 registers that are in use : this is a
2291 super set of ic->rUsed */
2292 ic->rMask = newBitVect (pic14_nRegs + 1);
2294 /* for all live Ranges alive at this point */
2295 for (j = 1; j < ic->rlive->size; j++)
2300 /* if not alive then continue */
2301 if (!bitVectBitValue (ic->rlive, j))
2304 /* find the live range we are interested in */
2305 if (!(sym = hTabItemWithKey (liveRanges, j)))
2307 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2308 "createRegMask cannot find live range");
2312 /* if no register assigned to it */
2313 if (!sym->nRegs || sym->isspilt)
2316 /* for all the registers allocated to it */
2317 for (k = 0; k < sym->nRegs; k++)
2320 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2326 /*-----------------------------------------------------------------*/
2327 /* rematStr - returns the rematerialized string for a remat var */
2328 /*-----------------------------------------------------------------*/
2330 rematStr (symbol * sym)
2333 iCode *ic = sym->rematiCode;
2334 symbol *psym = NULL;
2336 debugLog ("%s\n", __FUNCTION__);
2338 //printf ("%s\n", s);
2340 /* if plus or minus print the right hand side */
2342 if (ic->op == '+' || ic->op == '-') {
2344 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2346 sprintf (s, "(%s %c 0x%04x)",
2347 OP_SYMBOL (IC_LEFT (ric))->rname,
2349 (int) operandLitValue (IC_RIGHT (ic)));
2352 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2354 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2355 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2360 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2361 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2363 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2368 /*-----------------------------------------------------------------*/
2369 /* rematStr - returns the rematerialized string for a remat var */
2370 /*-----------------------------------------------------------------*/
2372 rematStr (symbol * sym)
2375 iCode *ic = sym->rematiCode;
2377 debugLog ("%s\n", __FUNCTION__);
2382 /* if plus or minus print the right hand side */
2384 if (ic->op == '+' || ic->op == '-') {
2385 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2388 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2392 if (ic->op == '+' || ic->op == '-')
2394 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2395 sprintf (s, "(%s %c 0x%04x)",
2396 OP_SYMBOL (IC_LEFT (ric))->rname,
2398 (int) operandLitValue (IC_RIGHT (ic)));
2401 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2403 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2407 /* we reached the end */
2408 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2412 printf ("%s\n", buffer);
2417 /*-----------------------------------------------------------------*/
2418 /* regTypeNum - computes the type & number of registers required */
2419 /*-----------------------------------------------------------------*/
2427 debugLog ("%s\n", __FUNCTION__);
2428 /* for each live range do */
2429 for (sym = hTabFirstItem (liveRanges, &k); sym;
2430 sym = hTabNextItem (liveRanges, &k)) {
2432 debugLog (" %d - %s\n", __LINE__, sym->rname);
2434 /* if used zero times then no registers needed */
2435 if ((sym->liveTo - sym->liveFrom) == 0)
2439 /* if the live range is a temporary */
2442 debugLog (" %d - itemp register\n", __LINE__);
2444 /* if the type is marked as a conditional */
2445 if (sym->regType == REG_CND)
2448 /* if used in return only then we don't
2451 if (IS_AGGREGATE (sym->type) || sym->isptr)
2452 sym->type = aggrToPtr (sym->type, FALSE);
2453 debugLog (" %d - no reg needed - accumulator used\n", __LINE__);
2459 //if (IS_AGGREGATE (sym->type) || sym->isptr)
2460 // sym->type = aggrToPtr (sym->type, FALSE);
2461 debugLog (" %d - used as a return\n", __LINE__);
2466 /* if the symbol has only one definition &
2467 that definition is a get_pointer and the
2468 pointer we are getting is rematerializable and
2471 if (bitVectnBitsOn (sym->defs) == 1 &&
2472 (ic = hTabItemWithKey (iCodehTab,
2473 bitVectFirstBit (sym->defs))) &&
2476 !IS_BITVAR (sym->etype)) {
2479 debugLog (" %d - \n", __LINE__);
2481 /* if remat in data space */
2482 if (OP_SYMBOL (IC_LEFT (ic))->remat &&
2483 DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) {
2485 /* create a psuedo symbol & force a spil */
2486 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2487 symbol *psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2488 psym->type = sym->type;
2489 psym->etype = sym->etype;
2490 strcpy (psym->rname, psym->name);
2492 sym->usl.spillLoc = psym;
2496 /* if in data space or idata space then try to
2497 allocate pointer register */
2501 /* if not then we require registers */
2502 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2503 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2504 getSize (sym->type));
2508 if(IS_PTR_CONST (sym->type)) {
2510 if(IS_CODEPTR (sym->type)) {
2512 debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2516 if (sym->nRegs > 4) {
2517 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2518 printTypeChain (sym->type, stderr);
2519 fprintf (stderr, "\n");
2522 /* determine the type of register required */
2523 if (sym->nRegs == 1 &&
2524 IS_PTR (sym->type) &&
2526 sym->regType = REG_PTR;
2528 sym->regType = REG_GPR;
2531 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2535 /* for the first run we don't provide */
2536 /* registers for true symbols we will */
2537 /* see how things go */
2542 DEFSETFUNC (markRegFree)
2544 ((regs *)item)->isFree = 1;
2549 DEFSETFUNC (deallocReg)
2551 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2552 ((regs *)item)->isFree = 1;
2553 ((regs *)item)->wasUsed = 0;
2557 /*-----------------------------------------------------------------*/
2558 /* freeAllRegs - mark all registers as free */
2559 /*-----------------------------------------------------------------*/
2561 pic14_freeAllRegs ()
2565 debugLog ("%s\n", __FUNCTION__);
2567 applyToSet(dynAllocRegs,markRegFree);
2568 applyToSet(dynStackRegs,markRegFree);
2571 for (i = 0; i < pic14_nRegs; i++)
2572 regspic14[i].isFree = 1;
2576 /*-----------------------------------------------------------------*/
2577 /*-----------------------------------------------------------------*/
2579 pic14_deallocateAllRegs ()
2583 debugLog ("%s\n", __FUNCTION__);
2585 applyToSet(dynAllocRegs,deallocReg);
2588 for (i = 0; i < pic14_nRegs; i++) {
2589 if(regspic14[i].pc_type == PO_GPR_TEMP) {
2590 regspic14[i].isFree = 1;
2591 regspic14[i].wasUsed = 0;
2598 /*-----------------------------------------------------------------*/
2599 /* deallocStackSpil - this will set the stack pointer back */
2600 /*-----------------------------------------------------------------*/
2602 DEFSETFUNC (deallocStackSpil)
2606 debugLog ("%s\n", __FUNCTION__);
2611 /*-----------------------------------------------------------------*/
2612 /* farSpacePackable - returns the packable icode for far variables */
2613 /*-----------------------------------------------------------------*/
2615 farSpacePackable (iCode * ic)
2619 debugLog ("%s\n", __FUNCTION__);
2620 /* go thru till we find a definition for the
2621 symbol on the right */
2622 for (dic = ic->prev; dic; dic = dic->prev)
2625 /* if the definition is a call then no */
2626 if ((dic->op == CALL || dic->op == PCALL) &&
2627 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2632 /* if shift by unknown amount then not */
2633 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2634 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2637 /* if pointer get and size > 1 */
2638 if (POINTER_GET (dic) &&
2639 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2642 if (POINTER_SET (dic) &&
2643 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2646 /* if any three is a true symbol in far space */
2647 if (IC_RESULT (dic) &&
2648 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2649 isOperandInFarSpace (IC_RESULT (dic)))
2652 if (IC_RIGHT (dic) &&
2653 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2654 isOperandInFarSpace (IC_RIGHT (dic)) &&
2655 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2658 if (IC_LEFT (dic) &&
2659 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2660 isOperandInFarSpace (IC_LEFT (dic)) &&
2661 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2664 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2666 if ((dic->op == LEFT_OP ||
2667 dic->op == RIGHT_OP ||
2669 IS_OP_LITERAL (IC_RIGHT (dic)))
2679 /*-----------------------------------------------------------------*/
2680 /* packRegsForAssign - register reduction for assignment */
2681 /*-----------------------------------------------------------------*/
2683 packRegsForAssign (iCode * ic, eBBlock * ebp)
2688 debugLog ("%s\n", __FUNCTION__);
2690 debugAopGet (" result:", IC_RESULT (ic));
2691 debugAopGet (" left:", IC_LEFT (ic));
2692 debugAopGet (" right:", IC_RIGHT (ic));
2694 /* if this is at an absolute address, then get the address. */
2695 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2696 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2697 debugLog (" %d - found config word declaration\n", __LINE__);
2698 if(IS_VALOP(IC_RIGHT(ic))) {
2699 debugLog (" setting config word to %x\n",
2700 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2701 assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2702 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2705 /* remove the assignment from the iCode chain. */
2707 remiCodeFromeBBlock (ebp, ic);
2708 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2709 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2716 if (!IS_ITEMP (IC_RESULT (ic))) {
2717 allocDirReg(IC_RESULT (ic));
2718 debugLog (" %d - result is not temp\n", __LINE__);
2721 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2722 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2723 allocDirReg(IC_LEFT (ic));
2727 if (!IS_ITEMP (IC_RIGHT (ic))) {
2728 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2730 /* only pack if this is not a function pointer */
2731 if (!IS_REF (IC_RIGHT (ic)))
2732 allocDirReg(IC_RIGHT (ic));
2736 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2737 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2739 debugLog (" %d - not packing - right side fails \n", __LINE__);
2743 /* if the true symbol is defined in far space or on stack
2744 then we should not since this will increase register pressure */
2745 if (isOperandInFarSpace (IC_RESULT (ic)))
2747 if ((dic = farSpacePackable (ic)))
2753 /* find the definition of iTempNN scanning backwards if we find a
2754 a use of the true symbol before we find the definition then
2756 for (dic = ic->prev; dic; dic = dic->prev)
2759 /* if there is a function call and this is
2760 a parameter & not my parameter then don't pack it */
2761 if ((dic->op == CALL || dic->op == PCALL) &&
2762 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2763 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2765 debugLog (" %d - \n", __LINE__);
2773 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2774 IS_OP_VOLATILE (IC_RESULT (dic)))
2776 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2781 if (IS_SYMOP (IC_RESULT (dic)) &&
2782 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2784 /* A previous result was assigned to the same register - we'll our definition */
2785 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2786 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2787 if (POINTER_SET (dic))
2793 if (IS_SYMOP (IC_RIGHT (dic)) &&
2794 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2795 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2797 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
2802 if (IS_SYMOP (IC_LEFT (dic)) &&
2803 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2804 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2806 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
2811 if (POINTER_SET (dic) &&
2812 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2814 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
2822 return 0; /* did not find */
2824 /* if the result is on stack or iaccess then it must be
2825 the same atleast one of the operands */
2826 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2827 OP_SYMBOL (IC_RESULT (ic))->iaccess)
2830 /* the operation has only one symbol
2831 operator then we can pack */
2832 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2833 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2836 if (!((IC_LEFT (dic) &&
2837 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2839 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2843 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2844 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
2845 /* found the definition */
2846 /* replace the result with the result of */
2847 /* this assignment and remove this assignment */
2848 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2849 IC_RESULT (dic) = IC_RESULT (ic);
2851 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2853 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2855 /* delete from liverange table also
2856 delete from all the points inbetween and the new
2858 for (sic = dic; sic != ic; sic = sic->next)
2860 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2861 if (IS_ITEMP (IC_RESULT (dic)))
2862 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2865 remiCodeFromeBBlock (ebp, ic);
2866 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2867 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2868 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2874 /*-----------------------------------------------------------------*/
2875 /* findAssignToSym : scanning backwards looks for first assig found */
2876 /*-----------------------------------------------------------------*/
2878 findAssignToSym (operand * op, iCode * ic)
2882 debugLog ("%s\n", __FUNCTION__);
2883 for (dic = ic->prev; dic; dic = dic->prev)
2886 /* if definition by assignment */
2887 if (dic->op == '=' &&
2888 !POINTER_SET (dic) &&
2889 IC_RESULT (dic)->key == op->key
2890 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2894 /* we are interested only if defined in far space */
2895 /* or in stack space in case of + & - */
2897 /* if assigned to a non-symbol then return
2899 if (!IS_SYMOP (IC_RIGHT (dic)))
2902 /* if the symbol is in far space then
2904 if (isOperandInFarSpace (IC_RIGHT (dic)))
2907 /* for + & - operations make sure that
2908 if it is on the stack it is the same
2909 as one of the three operands */
2910 if ((ic->op == '+' || ic->op == '-') &&
2911 OP_SYMBOL (IC_RIGHT (dic))->onStack)
2914 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2915 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2916 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2924 /* if we find an usage then we cannot delete it */
2925 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2928 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2931 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2935 /* now make sure that the right side of dic
2936 is not defined between ic & dic */
2939 iCode *sic = dic->next;
2941 for (; sic != ic; sic = sic->next)
2942 if (IC_RESULT (sic) &&
2943 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2952 /*-----------------------------------------------------------------*/
2953 /* packRegsForSupport :- reduce some registers for support calls */
2954 /*-----------------------------------------------------------------*/
2956 packRegsForSupport (iCode * ic, eBBlock * ebp)
2960 debugLog ("%s\n", __FUNCTION__);
2961 /* for the left & right operand :- look to see if the
2962 left was assigned a true symbol in far space in that
2963 case replace them */
2964 if (IS_ITEMP (IC_LEFT (ic)) &&
2965 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2967 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
2973 debugAopGet ("removing left:", IC_LEFT (ic));
2975 /* found it we need to remove it from the
2977 for (sic = dic; sic != ic; sic = sic->next)
2978 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
2980 IC_LEFT (ic)->operand.symOperand =
2981 IC_RIGHT (dic)->operand.symOperand;
2982 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2983 remiCodeFromeBBlock (ebp, dic);
2984 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2985 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2989 /* do the same for the right operand */
2992 IS_ITEMP (IC_RIGHT (ic)) &&
2993 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2995 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3001 /* if this is a subtraction & the result
3002 is a true symbol in far space then don't pack */
3003 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3005 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3006 if (IN_FARSPACE (SPEC_OCLS (etype)))
3010 debugAopGet ("removing right:", IC_RIGHT (ic));
3012 /* found it we need to remove it from the
3014 for (sic = dic; sic != ic; sic = sic->next)
3015 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3017 IC_RIGHT (ic)->operand.symOperand =
3018 IC_RIGHT (dic)->operand.symOperand;
3019 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3021 remiCodeFromeBBlock (ebp, dic);
3022 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3023 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3030 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3033 /*-----------------------------------------------------------------*/
3034 /* packRegsForOneuse : - will reduce some registers for single Use */
3035 /*-----------------------------------------------------------------*/
3037 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3042 debugLog ("%s\n", __FUNCTION__);
3043 /* if returning a literal then do nothing */
3047 /* only upto 2 bytes since we cannot predict
3048 the usage of b, & acc */
3049 if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
3054 /* this routine will mark the a symbol as used in one
3055 instruction use only && if the definition is local
3056 (ie. within the basic block) && has only one definition &&
3057 that definition is either a return value from a
3058 function or does not contain any variables in
3060 uses = bitVectCopy (OP_USES (op));
3061 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3062 if (!bitVectIsZero (uses)) /* has other uses */
3065 /* if it has only one defintion */
3066 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3067 return NULL; /* has more than one definition */
3069 /* get that definition */
3071 hTabItemWithKey (iCodehTab,
3072 bitVectFirstBit (OP_DEFS (op)))))
3075 /* found the definition now check if it is local */
3076 if (dic->seq < ebp->fSeq ||
3077 dic->seq > ebp->lSeq)
3078 return NULL; /* non-local */
3080 /* now check if it is the return from
3082 if (dic->op == CALL || dic->op == PCALL)
3084 if (ic->op != SEND && ic->op != RETURN &&
3085 !POINTER_SET(ic) && !POINTER_GET(ic))
3087 OP_SYMBOL (op)->ruonly = 1;
3094 /* otherwise check that the definition does
3095 not contain any symbols in far space */
3096 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3097 isOperandInFarSpace (IC_RIGHT (dic)) ||
3098 IS_OP_RUONLY (IC_LEFT (ic)) ||
3099 IS_OP_RUONLY (IC_RIGHT (ic)))
3104 /* if pointer set then make sure the pointer
3106 if (POINTER_SET (dic) &&
3107 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3110 if (POINTER_GET (dic) &&
3111 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3116 /* also make sure the intervenening instructions
3117 don't have any thing in far space */
3118 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3121 /* if there is an intervening function call then no */
3122 if (dic->op == CALL || dic->op == PCALL)
3124 /* if pointer set then make sure the pointer
3126 if (POINTER_SET (dic) &&
3127 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3130 if (POINTER_GET (dic) &&
3131 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3134 /* if address of & the result is remat then okay */
3135 if (dic->op == ADDRESS_OF &&
3136 OP_SYMBOL (IC_RESULT (dic))->remat)
3139 /* if operand has size of three or more & this
3140 operation is a '*','/' or '%' then 'b' may
3142 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3143 getSize (operandType (op)) >= 3)
3146 /* if left or right or result is in far space */
3147 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3148 isOperandInFarSpace (IC_RIGHT (dic)) ||
3149 isOperandInFarSpace (IC_RESULT (dic)) ||
3150 IS_OP_RUONLY (IC_LEFT (dic)) ||
3151 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3152 IS_OP_RUONLY (IC_RESULT (dic)))
3158 OP_SYMBOL (op)->ruonly = 1;
3163 /*-----------------------------------------------------------------*/
3164 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3165 /*-----------------------------------------------------------------*/
3167 isBitwiseOptimizable (iCode * ic)
3169 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3170 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3172 debugLog ("%s\n", __FUNCTION__);
3173 /* bitwise operations are considered optimizable
3174 under the following conditions (Jean-Louis VERN)
3186 if (IS_LITERAL (rtype) ||
3187 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3193 /*-----------------------------------------------------------------*/
3194 /* packRegsForAccUse - pack registers for acc use */
3195 /*-----------------------------------------------------------------*/
3197 packRegsForAccUse (iCode * ic)
3201 debugLog ("%s\n", __FUNCTION__);
3203 /* if this is an aggregate, e.g. a one byte char array */
3204 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3207 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3209 /* if + or - then it has to be one byte result */
3210 if ((ic->op == '+' || ic->op == '-')
3211 && getSize (operandType (IC_RESULT (ic))) > 1)
3214 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3215 /* if shift operation make sure right side is not a literal */
3216 if (ic->op == RIGHT_OP &&
3217 (isOperandLiteral (IC_RIGHT (ic)) ||
3218 getSize (operandType (IC_RESULT (ic))) > 1))
3221 if (ic->op == LEFT_OP &&
3222 (isOperandLiteral (IC_RIGHT (ic)) ||
3223 getSize (operandType (IC_RESULT (ic))) > 1))
3226 if (IS_BITWISE_OP (ic) &&
3227 getSize (operandType (IC_RESULT (ic))) > 1)
3231 /* has only one definition */
3232 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3235 /* has only one use */
3236 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3239 /* and the usage immediately follows this iCode */
3240 if (!(uic = hTabItemWithKey (iCodehTab,
3241 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3244 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3245 if (ic->next != uic)
3248 /* if it is a conditional branch then we definitely can */
3252 if (uic->op == JUMPTABLE)
3255 /* if the usage is not is an assignment
3256 or an arithmetic / bitwise / shift operation then not */
3257 if (POINTER_SET (uic) &&
3258 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3261 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3262 if (uic->op != '=' &&
3263 !IS_ARITHMETIC_OP (uic) &&
3264 !IS_BITWISE_OP (uic) &&
3265 uic->op != LEFT_OP &&
3266 uic->op != RIGHT_OP)
3269 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3270 /* if used in ^ operation then make sure right is not a
3272 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3275 /* if shift operation make sure right side is not a literal */
3276 if (uic->op == RIGHT_OP &&
3277 (isOperandLiteral (IC_RIGHT (uic)) ||
3278 getSize (operandType (IC_RESULT (uic))) > 1))
3281 if (uic->op == LEFT_OP &&
3282 (isOperandLiteral (IC_RIGHT (uic)) ||
3283 getSize (operandType (IC_RESULT (uic))) > 1))
3286 /* make sure that the result of this icode is not on the
3287 stack, since acc is used to compute stack offset */
3288 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3289 OP_SYMBOL (IC_RESULT (uic))->onStack)
3292 /* if either one of them in far space then we cannot */
3293 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3294 isOperandInFarSpace (IC_LEFT (uic))) ||
3295 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3296 isOperandInFarSpace (IC_RIGHT (uic))))
3299 /* if the usage has only one operand then we can */
3300 if (IC_LEFT (uic) == NULL ||
3301 IC_RIGHT (uic) == NULL)
3304 /* make sure this is on the left side if not
3305 a '+' since '+' is commutative */
3306 if (ic->op != '+' &&
3307 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3310 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3311 /* if one of them is a literal then we can */
3312 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3313 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3314 (getSize (operandType (IC_RESULT (uic))) <= 1))
3316 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3320 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3321 /* if the other one is not on stack then we can */
3322 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3323 (IS_ITEMP (IC_RIGHT (uic)) ||
3324 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3325 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3328 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3329 (IS_ITEMP (IC_LEFT (uic)) ||
3330 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3331 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3337 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3338 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3343 /*-----------------------------------------------------------------*/
3344 /* packForPush - hueristics to reduce iCode for pushing */
3345 /*-----------------------------------------------------------------*/
3347 packForReceive (iCode * ic, eBBlock * ebp)
3351 debugLog ("%s\n", __FUNCTION__);
3352 debugAopGet (" result:", IC_RESULT (ic));
3353 debugAopGet (" left:", IC_LEFT (ic));
3354 debugAopGet (" right:", IC_RIGHT (ic));
3359 for (dic = ic->next; dic; dic = dic->next)
3364 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3365 debugLog (" used on left\n");
3366 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3367 debugLog (" used on right\n");
3368 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3369 debugLog (" used on result\n");
3371 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3372 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3377 debugLog (" hey we can remove this unnecessary assign\n");
3379 /*-----------------------------------------------------------------*/
3380 /* packForPush - hueristics to reduce iCode for pushing */
3381 /*-----------------------------------------------------------------*/
3383 packForPush (iCode * ic, eBBlock * ebp)
3387 debugLog ("%s\n", __FUNCTION__);
3388 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3391 /* must have only definition & one usage */
3392 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3393 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3396 /* find the definition */
3397 if (!(dic = hTabItemWithKey (iCodehTab,
3398 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3401 if (dic->op != '=' || POINTER_SET (dic))
3404 /* we now we know that it has one & only one def & use
3405 and the that the definition is an assignment */
3406 IC_LEFT (ic) = IC_RIGHT (dic);
3408 remiCodeFromeBBlock (ebp, dic);
3409 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3410 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3413 void printSymType(char * str, sym_link *sl)
3415 debugLog (" %s Symbol type: ",str);
3416 printTypeChain( sl, debugF);
3421 /*-----------------------------------------------------------------*/
3422 /* some debug code to print the symbol S_TYPE. Note that
3423 * the function checkSClass in src/SDCCsymt.c dinks with
3424 * the S_TYPE in ways the PIC port doesn't fully like...*/
3425 /*-----------------------------------------------------------------*/
3426 void isData(sym_link *sl)
3436 for ( ; sl; sl=sl->next) {
3438 switch (SPEC_SCLS(sl)) {
3440 case S_DATA: fprintf (of, "data "); break;
3441 case S_XDATA: fprintf (of, "xdata "); break;
3442 case S_SFR: fprintf (of, "sfr "); break;
3443 case S_SBIT: fprintf (of, "sbit "); break;
3444 case S_CODE: fprintf (of, "code "); break;
3445 case S_IDATA: fprintf (of, "idata "); break;
3446 case S_PDATA: fprintf (of, "pdata "); break;
3447 case S_LITERAL: fprintf (of, "literal "); break;
3448 case S_STACK: fprintf (of, "stack "); break;
3449 case S_XSTACK: fprintf (of, "xstack "); break;
3450 case S_BIT: fprintf (of, "bit "); break;
3451 case S_EEPROM: fprintf (of, "eeprom "); break;
3460 /*-----------------------------------------------------------------*/
3461 /* packRegisters - does some transformations to reduce register */
3463 /*-----------------------------------------------------------------*/
3465 packRegisters (eBBlock * ebp)
3470 debugLog ("%s\n", __FUNCTION__);
3476 /* look for assignments of the form */
3477 /* iTempNN = TRueSym (someoperation) SomeOperand */
3479 /* TrueSym := iTempNN:1 */
3480 for (ic = ebp->sch; ic; ic = ic->next)
3483 /* find assignment of the form TrueSym := iTempNN:1 */
3484 if (ic->op == '=' && !POINTER_SET (ic))
3485 change += packRegsForAssign (ic, ebp);
3489 if (POINTER_SET (ic))
3490 debugLog ("pointer is set\n");
3491 debugAopGet (" result:", IC_RESULT (ic));
3492 debugAopGet (" left:", IC_LEFT (ic));
3493 debugAopGet (" right:", IC_RIGHT (ic));
3502 for (ic = ebp->sch; ic; ic = ic->next) {
3504 if(IS_SYMOP ( IC_LEFT(ic))) {
3505 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3507 debugAopGet (" left:", IC_LEFT (ic));
3509 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3511 if(IS_CODEPTR(OP_SYMBOL(IC_LEFT(ic))->type))
3513 debugLog (" is a pointer\n");
3515 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3516 debugLog (" is volatile\n");
3520 printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
3523 if(IS_SYMOP ( IC_RIGHT(ic))) {
3524 debugAopGet (" right:", IC_RIGHT (ic));
3525 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3528 if(IS_SYMOP ( IC_RESULT(ic))) {
3529 debugAopGet (" result:", IC_RESULT (ic));
3530 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3533 if (POINTER_SET (ic))
3534 debugLog (" %d - Pointer set\n", __LINE__);
3537 /* if this is an itemp & result of a address of a true sym
3538 then mark this as rematerialisable */
3539 if (ic->op == ADDRESS_OF &&
3540 IS_ITEMP (IC_RESULT (ic)) &&
3541 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3542 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3543 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3546 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3548 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3549 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3550 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3554 /* if straight assignment then carry remat flag if
3555 this is the only definition */
3556 if (ic->op == '=' &&
3557 !POINTER_SET (ic) &&
3558 IS_SYMOP (IC_RIGHT (ic)) &&
3559 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3560 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3562 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3564 OP_SYMBOL (IC_RESULT (ic))->remat =
3565 OP_SYMBOL (IC_RIGHT (ic))->remat;
3566 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3567 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3570 /* if this is a +/- operation with a rematerizable
3571 then mark this as rematerializable as well */
3572 if ((ic->op == '+' || ic->op == '-') &&
3573 (IS_SYMOP (IC_LEFT (ic)) &&
3574 IS_ITEMP (IC_RESULT (ic)) &&
3575 OP_SYMBOL (IC_LEFT (ic))->remat &&
3576 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3577 IS_OP_LITERAL (IC_RIGHT (ic))))
3579 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3581 operandLitValue (IC_RIGHT (ic));
3582 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3583 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3584 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3587 /* mark the pointer usages */
3588 if (POINTER_SET (ic))
3590 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3591 debugLog (" marking as a pointer (set) =>");
3592 debugAopGet (" result:", IC_RESULT (ic));
3594 if (POINTER_GET (ic))
3596 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3597 debugLog (" marking as a pointer (get) =>");
3598 debugAopGet (" left:", IC_LEFT (ic));
3603 /* if we are using a symbol on the stack
3604 then we should say pic14_ptrRegReq */
3605 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3606 pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3607 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3608 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3609 pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3610 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3613 if (IS_SYMOP (IC_LEFT (ic)))
3614 pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3615 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3616 if (IS_SYMOP (IC_RIGHT (ic)))
3617 pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3618 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3619 if (IS_SYMOP (IC_RESULT (ic)))
3620 pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3621 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3624 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
3628 /* if the condition of an if instruction
3629 is defined in the previous instruction then
3630 mark the itemp as a conditional */
3631 if ((IS_CONDITIONAL (ic) ||
3632 ((ic->op == BITWISEAND ||
3635 isBitwiseOptimizable (ic))) &&
3636 ic->next && ic->next->op == IFX &&
3637 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3638 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3641 debugLog (" %d\n", __LINE__);
3642 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3646 /* reduce for support function calls */
3647 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3648 packRegsForSupport (ic, ebp);
3650 /* if a parameter is passed, it's in W, so we may not
3651 need to place a copy in a register */
3652 if (ic->op == RECEIVE)
3653 packForReceive (ic, ebp);
3655 /* some cases the redundant moves can
3656 can be eliminated for return statements */
3657 if ((ic->op == RETURN || ic->op == SEND) &&
3658 !isOperandInFarSpace (IC_LEFT (ic)) &&
3660 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3662 /* if pointer set & left has a size more than
3663 one and right is not in far space */
3664 if (POINTER_SET (ic) &&
3665 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3666 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3667 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3668 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3670 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3672 /* if pointer get */
3673 if (POINTER_GET (ic) &&
3674 !isOperandInFarSpace (IC_RESULT (ic)) &&
3675 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3676 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3677 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3679 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3682 /* if this is cast for intergral promotion then
3683 check if only use of the definition of the
3684 operand being casted/ if yes then replace
3685 the result of that arithmetic operation with
3686 this result and get rid of the cast */
3687 if (ic->op == CAST) {
3689 sym_link *fromType = operandType (IC_RIGHT (ic));
3690 sym_link *toType = operandType (IC_LEFT (ic));
3692 debugLog (" %d - casting\n", __LINE__);
3694 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3695 getSize (fromType) != getSize (toType)) {
3698 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3701 if (IS_ARITHMETIC_OP (dic)) {
3703 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3704 IC_RESULT (dic) = IC_RESULT (ic);
3705 remiCodeFromeBBlock (ebp, ic);
3706 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3707 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3708 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3712 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3716 /* if the type from and type to are the same
3717 then if this is the only use then packit */
3718 if (compareType (operandType (IC_RIGHT (ic)),
3719 operandType (IC_LEFT (ic))) == 1) {
3721 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3724 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3725 IC_RESULT (dic) = IC_RESULT (ic);
3726 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3727 remiCodeFromeBBlock (ebp, ic);
3728 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3729 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3737 iTempNN := (some variable in farspace) V1
3742 if (ic->op == IPUSH)
3744 packForPush (ic, ebp);
3748 /* pack registers for accumulator use, when the
3749 result of an arithmetic or bit wise operation
3750 has only one use, that use is immediately following
3751 the defintion and the using iCode has only one
3752 operand or has two operands but one is literal &
3753 the result of that operation is not on stack then
3754 we can leave the result of this operation in acc:b
3756 if ((IS_ARITHMETIC_OP (ic)
3758 || IS_BITWISE_OP (ic)
3760 || ic->op == LEFT_OP || ic->op == RIGHT_OP
3763 IS_ITEMP (IC_RESULT (ic)) &&
3764 getSize (operandType (IC_RESULT (ic))) <= 2)
3766 packRegsForAccUse (ic);
3772 dumpEbbsToDebug (eBBlock ** ebbs, int count)
3776 if (!debug || !debugF)
3779 for (i = 0; i < count; i++)
3781 fprintf (debugF, "\n----------------------------------------------------------------\n");
3782 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
3783 ebbs[i]->entryLabel->name,
3786 ebbs[i]->isLastInLoop);
3787 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
3792 fprintf (debugF, "visited %d : hasFcall = %d\n",
3796 fprintf (debugF, "\ndefines bitVector :");
3797 bitVectDebugOn (ebbs[i]->defSet, debugF);
3798 fprintf (debugF, "\nlocal defines bitVector :");
3799 bitVectDebugOn (ebbs[i]->ldefs, debugF);
3800 fprintf (debugF, "\npointers Set bitvector :");
3801 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
3802 fprintf (debugF, "\nin pointers Set bitvector :");
3803 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
3804 fprintf (debugF, "\ninDefs Set bitvector :");
3805 bitVectDebugOn (ebbs[i]->inDefs, debugF);
3806 fprintf (debugF, "\noutDefs Set bitvector :");
3807 bitVectDebugOn (ebbs[i]->outDefs, debugF);
3808 fprintf (debugF, "\nusesDefs Set bitvector :");
3809 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
3810 fprintf (debugF, "\n----------------------------------------------------------------\n");
3811 printiCChain (ebbs[i]->sch, debugF);
3814 /*-----------------------------------------------------------------*/
3815 /* assignRegisters - assigns registers to each live range as need */
3816 /*-----------------------------------------------------------------*/
3818 pic14_assignRegisters (eBBlock ** ebbs, int count)
3823 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
3824 debugLog ("\nebbs before optimizing:\n");
3825 dumpEbbsToDebug (ebbs, count);
3827 setToNull ((void *) &_G.funcrUsed);
3828 pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3831 /* change assignments this will remove some
3832 live ranges reducing some register pressure */
3833 for (i = 0; i < count; i++)
3834 packRegisters (ebbs[i]);
3841 debugLog("dir registers allocated so far:\n");
3842 reg = hTabFirstItem(dynDirectRegNames, &hkey);
3845 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
3846 reg = hTabNextItem(dynDirectRegNames, &hkey);
3851 if (options.dump_pack)
3852 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3854 /* first determine for each live range the number of
3855 registers & the type of registers required for each */
3858 /* and serially allocate registers */
3859 serialRegAssign (ebbs, count);
3861 /* if stack was extended then tell the user */
3864 /* werror(W_TOOMANY_SPILS,"stack", */
3865 /* _G.stackExtend,currFunc->name,""); */
3871 /* werror(W_TOOMANY_SPILS,"data space", */
3872 /* _G.dataExtend,currFunc->name,""); */
3876 /* after that create the register mask
3877 for each of the instruction */
3878 createRegMask (ebbs, count);
3880 /* redo that offsets for stacked automatic variables */
3881 redoStackOffsets ();
3883 if (options.dump_rassgn)
3884 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3886 /* now get back the chain */
3887 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3889 debugLog ("ebbs after optimizing:\n");
3890 dumpEbbsToDebug (ebbs, count);
3895 /* free up any _G.stackSpil locations allocated */
3896 applyToSet (_G.stackSpil, deallocStackSpil);
3898 setToNull ((void **) &_G.stackSpil);
3899 setToNull ((void **) &_G.spiltSet);
3900 /* mark all registers as free */
3901 //pic14_freeAllRegs ();
3903 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");