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 == 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");
843 debugLog ("Dynamic Register not found\n");
846 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
847 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
848 "regWithIdx not found");
858 /*-----------------------------------------------------------------*/
859 /*-----------------------------------------------------------------*/
861 pic14_findFreeReg(short type)
868 if((dReg = regFindFree(dynAllocRegs)) != NULL)
870 return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
874 if((dReg = regFindFree(dynStackRegs)) != NULL)
886 /*-----------------------------------------------------------------*/
887 /* freeReg - frees a register */
888 /*-----------------------------------------------------------------*/
892 debugLog ("%s\n", __FUNCTION__);
897 /*-----------------------------------------------------------------*/
898 /* nFreeRegs - returns number of free registers */
899 /*-----------------------------------------------------------------*/
903 /* dynamically allocate as many as we need and worry about
904 * fitting them into a PIC later */
911 debugLog ("%s\n", __FUNCTION__);
912 for (i = 0; i < pic14_nRegs; i++)
913 if (regspic14[i].isFree && regspic14[i].type == type)
919 /*-----------------------------------------------------------------*/
920 /* nfreeRegsType - free registers with type */
921 /*-----------------------------------------------------------------*/
923 nfreeRegsType (int type)
926 debugLog ("%s\n", __FUNCTION__);
929 if ((nfr = nFreeRegs (type)) == 0)
930 return nFreeRegs (REG_GPR);
933 return nFreeRegs (type);
936 void writeSetUsedRegs(FILE *of, set *dRegs)
941 for (dReg = setFirstItem(dRegs) ; dReg ;
942 dReg = setNextItem(dRegs)) {
945 fprintf (of, "\t%s\n",dReg->name);
949 extern void assignFixedRegisters(set *regset);
950 extern void assignRelocatableRegisters(set *regset,int used);
951 extern void dump_map(void);
952 extern void dump_sfr(FILE *of);
954 void packBits(set *bregs)
959 regs *relocbitfield=NULL;
965 for (regset = bregs ; regset ;
966 regset = regset->next) {
969 breg->isBitField = 1;
970 //fprintf(stderr,"bit reg: %s\n",breg->name);
973 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
975 bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1);
976 breg->rIdx = breg->address & 7;
980 sprintf (buffer, "fbitfield%02x", breg->address);
981 //fprintf(stderr,"new bit field\n");
982 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0);
983 bitfield->isBitField = 1;
984 bitfield->isFixed = 1;
985 bitfield->address = breg->address;
986 //addSet(&dynDirectRegs,bitfield);
987 addSet(&dynInternalRegs,bitfield);
988 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
990 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
993 breg->reg_alias = bitfield;
997 if(!relocbitfield || bit_no >7) {
1000 sprintf (buffer, "bitfield%d", byte_no);
1001 //fprintf(stderr,"new relocatable bit field\n");
1002 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0);
1003 relocbitfield->isBitField = 1;
1004 //addSet(&dynDirectRegs,relocbitfield);
1005 addSet(&dynInternalRegs,relocbitfield);
1006 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1010 breg->reg_alias = relocbitfield;
1011 breg->address = rDirectIdx; /* byte_no; */
1012 breg->rIdx = bit_no++;
1020 void bitEQUs(FILE *of, set *bregs)
1022 regs *breg,*bytereg;
1025 //fprintf(stderr," %s\n",__FUNCTION__);
1026 for (breg = setFirstItem(bregs) ; breg ;
1027 breg = setNextItem(bregs)) {
1029 //fprintf(stderr,"bit reg: %s\n",breg->name);
1031 bytereg = breg->reg_alias;
1033 fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
1036 breg->rIdx & 0x0007);
1039 //fprintf(stderr, "bit field is not assigned to a register\n");
1040 fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
1050 void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
1055 for (reg = setFirstItem(fregs) ; reg ;
1056 reg = setNextItem(fregs)) {
1058 //if(!reg->isEmitted && reg->wasUsed) {
1061 fprintf (of, "%s\tEQU\t0x%03x\n",
1065 fprintf (of, "%s\tEQU\t0x%03x\n",
1073 void writeUsedRegs(FILE *of)
1075 packBits(dynDirectBitRegs);
1077 assignFixedRegisters(dynAllocRegs);
1078 assignFixedRegisters(dynStackRegs);
1079 assignFixedRegisters(dynDirectRegs);
1081 assignRelocatableRegisters(dynInternalRegs,0);
1082 assignRelocatableRegisters(dynAllocRegs,0);
1083 assignRelocatableRegisters(dynStackRegs,0);
1086 assignRelocatableRegisters(dynDirectRegs,0);
1087 printf("assignRelocatableRegisters(dynDirectRegs,0);\n");
1092 bitEQUs(of,dynDirectBitRegs);
1094 aliasEQUs(of,dynAllocRegs,0);
1095 aliasEQUs(of,dynDirectRegs,0);
1096 aliasEQUs(of,dynStackRegs,0);
1097 aliasEQUs(of,dynProcessorRegs,1);
1102 /*-----------------------------------------------------------------*/
1103 /* allDefsOutOfRange - all definitions are out of a range */
1104 /*-----------------------------------------------------------------*/
1106 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
1110 debugLog ("%s\n", __FUNCTION__);
1114 for (i = 0; i < defs->size; i++)
1118 if (bitVectBitValue (defs, i) &&
1119 (ic = hTabItemWithKey (iCodehTab, i)) &&
1120 (ic->seq >= fseq && ic->seq <= toseq))
1130 /*-----------------------------------------------------------------*/
1131 /* computeSpillable - given a point find the spillable live ranges */
1132 /*-----------------------------------------------------------------*/
1134 computeSpillable (iCode * ic)
1138 debugLog ("%s\n", __FUNCTION__);
1139 /* spillable live ranges are those that are live at this
1140 point . the following categories need to be subtracted
1142 a) - those that are already spilt
1143 b) - if being used by this one
1144 c) - defined by this one */
1146 spillable = bitVectCopy (ic->rlive);
1148 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1150 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1151 bitVectUnSetBit (spillable, ic->defKey);
1152 spillable = bitVectIntersect (spillable, _G.regAssigned);
1157 /*-----------------------------------------------------------------*/
1158 /* noSpilLoc - return true if a variable has no spil location */
1159 /*-----------------------------------------------------------------*/
1161 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1163 debugLog ("%s\n", __FUNCTION__);
1164 return (sym->usl.spillLoc ? 0 : 1);
1167 /*-----------------------------------------------------------------*/
1168 /* hasSpilLoc - will return 1 if the symbol has spil location */
1169 /*-----------------------------------------------------------------*/
1171 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1173 debugLog ("%s\n", __FUNCTION__);
1174 return (sym->usl.spillLoc ? 1 : 0);
1177 /*-----------------------------------------------------------------*/
1178 /* directSpilLoc - will return 1 if the splilocation is in direct */
1179 /*-----------------------------------------------------------------*/
1181 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1183 debugLog ("%s\n", __FUNCTION__);
1184 if (sym->usl.spillLoc &&
1185 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1191 /*-----------------------------------------------------------------*/
1192 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1193 /* but is not used as a pointer */
1194 /*-----------------------------------------------------------------*/
1196 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1198 debugLog ("%s\n", __FUNCTION__);
1199 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1202 /*-----------------------------------------------------------------*/
1203 /* rematable - will return 1 if the remat flag is set */
1204 /*-----------------------------------------------------------------*/
1206 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1208 debugLog ("%s\n", __FUNCTION__);
1212 /*-----------------------------------------------------------------*/
1213 /* notUsedInRemaining - not used or defined in remain of the block */
1214 /*-----------------------------------------------------------------*/
1216 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1218 debugLog ("%s\n", __FUNCTION__);
1219 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1220 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1223 /*-----------------------------------------------------------------*/
1224 /* allLRs - return true for all */
1225 /*-----------------------------------------------------------------*/
1227 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1229 debugLog ("%s\n", __FUNCTION__);
1233 /*-----------------------------------------------------------------*/
1234 /* liveRangesWith - applies function to a given set of live range */
1235 /*-----------------------------------------------------------------*/
1237 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1238 eBBlock * ebp, iCode * ic)
1243 debugLog ("%s\n", __FUNCTION__);
1244 if (!lrs || !lrs->size)
1247 for (i = 1; i < lrs->size; i++)
1250 if (!bitVectBitValue (lrs, i))
1253 /* if we don't find it in the live range
1254 hash table we are in serious trouble */
1255 if (!(sym = hTabItemWithKey (liveRanges, i)))
1257 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1258 "liveRangesWith could not find liveRange");
1262 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1263 addSetHead (&rset, sym);
1270 /*-----------------------------------------------------------------*/
1271 /* leastUsedLR - given a set determines which is the least used */
1272 /*-----------------------------------------------------------------*/
1274 leastUsedLR (set * sset)
1276 symbol *sym = NULL, *lsym = NULL;
1278 debugLog ("%s\n", __FUNCTION__);
1279 sym = lsym = setFirstItem (sset);
1284 for (; lsym; lsym = setNextItem (sset))
1287 /* if usage is the same then prefer
1288 the spill the smaller of the two */
1289 if (lsym->used == sym->used)
1290 if (getSize (lsym->type) < getSize (sym->type))
1294 if (lsym->used < sym->used)
1299 setToNull ((void **) &sset);
1304 /*-----------------------------------------------------------------*/
1305 /* noOverLap - will iterate through the list looking for over lap */
1306 /*-----------------------------------------------------------------*/
1308 noOverLap (set * itmpStack, symbol * fsym)
1311 debugLog ("%s\n", __FUNCTION__);
1314 for (sym = setFirstItem (itmpStack); sym;
1315 sym = setNextItem (itmpStack))
1317 if (sym->liveTo > fsym->liveFrom)
1325 /*-----------------------------------------------------------------*/
1326 /* isFree - will return 1 if the a free spil location is found */
1327 /*-----------------------------------------------------------------*/
1332 V_ARG (symbol **, sloc);
1333 V_ARG (symbol *, fsym);
1335 debugLog ("%s\n", __FUNCTION__);
1336 /* if already found */
1340 /* if it is free && and the itmp assigned to
1341 this does not have any overlapping live ranges
1342 with the one currently being assigned and
1343 the size can be accomodated */
1345 noOverLap (sym->usl.itmpStack, fsym) &&
1346 getSize (sym->type) >= getSize (fsym->type))
1355 /*-----------------------------------------------------------------*/
1356 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1357 /*-----------------------------------------------------------------*/
1359 spillLRWithPtrReg (symbol * forSym)
1365 debugLog ("%s\n", __FUNCTION__);
1366 if (!_G.regAssigned ||
1367 bitVectIsZero (_G.regAssigned))
1370 r0 = pic14_regWithIdx (R0_IDX);
1371 r1 = pic14_regWithIdx (R1_IDX);
1373 /* for all live ranges */
1374 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1375 lrsym = hTabNextItem (liveRanges, &k))
1379 /* if no registers assigned to it or
1381 /* if it does not overlap with this then
1382 not need to spill it */
1384 if (lrsym->isspilt || !lrsym->nRegs ||
1385 (lrsym->liveTo < forSym->liveFrom))
1388 /* go thru the registers : if it is either
1389 r0 or r1 then spil it */
1390 for (j = 0; j < lrsym->nRegs; j++)
1391 if (lrsym->regs[j] == r0 ||
1392 lrsym->regs[j] == r1)
1401 /*-----------------------------------------------------------------*/
1402 /* createStackSpil - create a location on the stack to spil */
1403 /*-----------------------------------------------------------------*/
1405 createStackSpil (symbol * sym)
1407 symbol *sloc = NULL;
1408 int useXstack, model, noOverlay;
1410 char slocBuffer[30];
1411 debugLog ("%s\n", __FUNCTION__);
1413 /* first go try and find a free one that is already
1414 existing on the stack */
1415 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1417 /* found a free one : just update & return */
1418 sym->usl.spillLoc = sloc;
1421 addSetHead (&sloc->usl.itmpStack, sym);
1425 /* could not then have to create one , this is the hard part
1426 we need to allocate this on the stack : this is really a
1427 hack!! but cannot think of anything better at this time */
1429 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1431 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1432 __FILE__, __LINE__);
1436 sloc = newiTemp (slocBuffer);
1438 /* set the type to the spilling symbol */
1439 sloc->type = copyLinkChain (sym->type);
1440 sloc->etype = getSpec (sloc->type);
1441 SPEC_SCLS (sloc->etype) = S_DATA;
1442 SPEC_EXTR (sloc->etype) = 0;
1443 SPEC_STAT (sloc->etype) = 0;
1445 /* we don't allow it to be allocated`
1446 onto the external stack since : so we
1447 temporarily turn it off ; we also
1448 turn off memory model to prevent
1449 the spil from going to the external storage
1450 and turn off overlaying
1453 useXstack = options.useXstack;
1454 model = options.model;
1455 noOverlay = options.noOverlay;
1456 options.noOverlay = 1;
1457 options.model = options.useXstack = 0;
1461 options.useXstack = useXstack;
1462 options.model = model;
1463 options.noOverlay = noOverlay;
1464 sloc->isref = 1; /* to prevent compiler warning */
1466 /* if it is on the stack then update the stack */
1467 if (IN_STACK (sloc->etype))
1469 currFunc->stack += getSize (sloc->type);
1470 _G.stackExtend += getSize (sloc->type);
1473 _G.dataExtend += getSize (sloc->type);
1475 /* add it to the _G.stackSpil set */
1476 addSetHead (&_G.stackSpil, sloc);
1477 sym->usl.spillLoc = sloc;
1480 /* add it to the set of itempStack set
1481 of the spill location */
1482 addSetHead (&sloc->usl.itmpStack, sym);
1486 /*-----------------------------------------------------------------*/
1487 /* isSpiltOnStack - returns true if the spil location is on stack */
1488 /*-----------------------------------------------------------------*/
1490 isSpiltOnStack (symbol * sym)
1494 debugLog ("%s\n", __FUNCTION__);
1501 /* if (sym->_G.stackSpil) */
1504 if (!sym->usl.spillLoc)
1507 etype = getSpec (sym->usl.spillLoc->type);
1508 if (IN_STACK (etype))
1514 /*-----------------------------------------------------------------*/
1515 /* spillThis - spils a specific operand */
1516 /*-----------------------------------------------------------------*/
1518 spillThis (symbol * sym)
1521 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1523 /* if this is rematerializable or has a spillLocation
1524 we are okay, else we need to create a spillLocation
1526 if (!(sym->remat || sym->usl.spillLoc))
1527 createStackSpil (sym);
1530 /* mark it has spilt & put it in the spilt set */
1532 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1534 bitVectUnSetBit (_G.regAssigned, sym->key);
1536 for (i = 0; i < sym->nRegs; i++)
1540 freeReg (sym->regs[i]);
1541 sym->regs[i] = NULL;
1544 /* if spilt on stack then free up r0 & r1
1545 if they could have been assigned to some
1547 if (!pic14_ptrRegReq && isSpiltOnStack (sym))
1550 spillLRWithPtrReg (sym);
1553 if (sym->usl.spillLoc && !sym->remat)
1554 sym->usl.spillLoc->allocreq = 1;
1558 /*-----------------------------------------------------------------*/
1559 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1560 /*-----------------------------------------------------------------*/
1562 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1564 bitVect *lrcs = NULL;
1568 debugLog ("%s\n", __FUNCTION__);
1569 /* get the spillable live ranges */
1570 lrcs = computeSpillable (ic);
1572 /* get all live ranges that are rematerizable */
1573 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1576 /* return the least used of these */
1577 return leastUsedLR (selectS);
1580 /* get live ranges with spillLocations in direct space */
1581 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1583 sym = leastUsedLR (selectS);
1584 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1585 sym->usl.spillLoc->rname :
1586 sym->usl.spillLoc->name));
1588 /* mark it as allocation required */
1589 sym->usl.spillLoc->allocreq = 1;
1593 /* if the symbol is local to the block then */
1594 if (forSym->liveTo < ebp->lSeq)
1597 /* check if there are any live ranges allocated
1598 to registers that are not used in this block */
1599 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1601 sym = leastUsedLR (selectS);
1602 /* if this is not rematerializable */
1611 /* check if there are any live ranges that not
1612 used in the remainder of the block */
1613 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1615 sym = leastUsedLR (selectS);
1618 sym->remainSpil = 1;
1625 /* find live ranges with spillocation && not used as pointers */
1626 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1629 sym = leastUsedLR (selectS);
1630 /* mark this as allocation required */
1631 sym->usl.spillLoc->allocreq = 1;
1635 /* find live ranges with spillocation */
1636 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1639 sym = leastUsedLR (selectS);
1640 sym->usl.spillLoc->allocreq = 1;
1644 /* couldn't find then we need to create a spil
1645 location on the stack , for which one? the least
1647 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1650 /* return a created spil location */
1651 sym = createStackSpil (leastUsedLR (selectS));
1652 sym->usl.spillLoc->allocreq = 1;
1656 /* this is an extreme situation we will spill
1657 this one : happens very rarely but it does happen */
1663 /*-----------------------------------------------------------------*/
1664 /* spilSomething - spil some variable & mark registers as free */
1665 /*-----------------------------------------------------------------*/
1667 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1672 debugLog ("%s\n", __FUNCTION__);
1673 /* get something we can spil */
1674 ssym = selectSpil (ic, ebp, forSym);
1676 /* mark it as spilt */
1678 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1680 /* mark it as not register assigned &
1681 take it away from the set */
1682 bitVectUnSetBit (_G.regAssigned, ssym->key);
1684 /* mark the registers as free */
1685 for (i = 0; i < ssym->nRegs; i++)
1687 freeReg (ssym->regs[i]);
1689 /* if spilt on stack then free up r0 & r1
1690 if they could have been assigned to as gprs */
1691 if (!pic14_ptrRegReq && isSpiltOnStack (ssym))
1694 spillLRWithPtrReg (ssym);
1697 /* if this was a block level spil then insert push & pop
1698 at the start & end of block respectively */
1699 if (ssym->blockSpil)
1701 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1702 /* add push to the start of the block */
1703 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1704 ebp->sch->next : ebp->sch));
1705 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1706 /* add pop to the end of the block */
1707 addiCodeToeBBlock (ebp, nic, NULL);
1710 /* if spilt because not used in the remainder of the
1711 block then add a push before this instruction and
1712 a pop at the end of the block */
1713 if (ssym->remainSpil)
1716 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1717 /* add push just before this instruction */
1718 addiCodeToeBBlock (ebp, nic, ic);
1720 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1721 /* add pop to the end of the block */
1722 addiCodeToeBBlock (ebp, nic, NULL);
1731 /*-----------------------------------------------------------------*/
1732 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1733 /*-----------------------------------------------------------------*/
1735 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1739 debugLog ("%s\n", __FUNCTION__);
1741 /* try for a ptr type */
1742 if ((reg = allocReg (REG_PTR)))
1745 /* try for gpr type */
1746 if ((reg = allocReg (REG_GPR)))
1749 /* we have to spil */
1750 if (!spilSomething (ic, ebp, sym))
1753 /* this looks like an infinite loop but
1754 in really selectSpil will abort */
1758 /*-----------------------------------------------------------------*/
1759 /* getRegGpr - will try for GPR if not spil */
1760 /*-----------------------------------------------------------------*/
1762 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1766 debugLog ("%s\n", __FUNCTION__);
1768 /* try for gpr type */
1769 if ((reg = allocReg (REG_GPR)))
1772 if (!pic14_ptrRegReq)
1773 if ((reg = allocReg (REG_PTR)))
1776 /* we have to spil */
1777 if (!spilSomething (ic, ebp, sym))
1780 /* this looks like an infinite loop but
1781 in really selectSpil will abort */
1785 /*-----------------------------------------------------------------*/
1786 /* symHasReg - symbol has a given register */
1787 /*-----------------------------------------------------------------*/
1789 symHasReg (symbol * sym, regs * reg)
1793 debugLog ("%s\n", __FUNCTION__);
1794 for (i = 0; i < sym->nRegs; i++)
1795 if (sym->regs[i] == reg)
1801 /*-----------------------------------------------------------------*/
1802 /* deassignLRs - check the live to and if they have registers & are */
1803 /* not spilt then free up the registers */
1804 /*-----------------------------------------------------------------*/
1806 deassignLRs (iCode * ic, eBBlock * ebp)
1812 debugLog ("%s\n", __FUNCTION__);
1813 for (sym = hTabFirstItem (liveRanges, &k); sym;
1814 sym = hTabNextItem (liveRanges, &k))
1817 symbol *psym = NULL;
1818 /* if it does not end here */
1819 if (sym->liveTo > ic->seq)
1822 /* if it was spilt on stack then we can
1823 mark the stack spil location as free */
1828 sym->usl.spillLoc->isFree = 1;
1834 if (!bitVectBitValue (_G.regAssigned, sym->key))
1837 /* special case check if this is an IFX &
1838 the privious one was a pop and the
1839 previous one was not spilt then keep track
1841 if (ic->op == IFX && ic->prev &&
1842 ic->prev->op == IPOP &&
1843 !ic->prev->parmPush &&
1844 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1845 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1851 bitVectUnSetBit (_G.regAssigned, sym->key);
1853 /* if the result of this one needs registers
1854 and does not have it then assign it right
1856 if (IC_RESULT (ic) &&
1857 !(SKIP_IC2 (ic) || /* not a special icode */
1858 ic->op == JUMPTABLE ||
1863 POINTER_SET (ic)) &&
1864 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1865 result->liveTo > ic->seq && /* and will live beyond this */
1866 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1867 result->regType == sym->regType && /* same register types */
1868 result->nRegs && /* which needs registers */
1869 !result->isspilt && /* and does not already have them */
1871 !bitVectBitValue (_G.regAssigned, result->key) &&
1872 /* the number of free regs + number of regs in this LR
1873 can accomodate the what result Needs */
1874 ((nfreeRegsType (result->regType) +
1875 sym->nRegs) >= result->nRegs)
1879 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1881 result->regs[i] = sym->regs[i];
1883 result->regs[i] = getRegGpr (ic, ebp, result);
1885 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1889 /* free the remaining */
1890 for (; i < sym->nRegs; i++)
1894 if (!symHasReg (psym, sym->regs[i]))
1895 freeReg (sym->regs[i]);
1898 freeReg (sym->regs[i]);
1905 /*-----------------------------------------------------------------*/
1906 /* reassignLR - reassign this to registers */
1907 /*-----------------------------------------------------------------*/
1909 reassignLR (operand * op)
1911 symbol *sym = OP_SYMBOL (op);
1914 debugLog ("%s\n", __FUNCTION__);
1915 /* not spilt any more */
1916 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1917 bitVectUnSetBit (_G.spiltSet, sym->key);
1919 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1923 for (i = 0; i < sym->nRegs; i++)
1924 sym->regs[i]->isFree = 0;
1927 /*-----------------------------------------------------------------*/
1928 /* willCauseSpill - determines if allocating will cause a spill */
1929 /*-----------------------------------------------------------------*/
1931 willCauseSpill (int nr, int rt)
1933 debugLog ("%s\n", __FUNCTION__);
1934 /* first check if there are any avlb registers
1935 of te type required */
1938 /* special case for pointer type
1939 if pointer type not avlb then
1940 check for type gpr */
1941 if (nFreeRegs (rt) >= nr)
1943 if (nFreeRegs (REG_GPR) >= nr)
1948 if (pic14_ptrRegReq)
1950 if (nFreeRegs (rt) >= nr)
1955 if (nFreeRegs (REG_PTR) +
1956 nFreeRegs (REG_GPR) >= nr)
1961 debugLog (" ... yep it will (cause a spill)\n");
1962 /* it will cause a spil */
1966 /*-----------------------------------------------------------------*/
1967 /* positionRegs - the allocator can allocate same registers to res- */
1968 /* ult and operand, if this happens make sure they are in the same */
1969 /* position as the operand otherwise chaos results */
1970 /*-----------------------------------------------------------------*/
1972 positionRegs (symbol * result, symbol * opsym, int lineno)
1974 int count = min (result->nRegs, opsym->nRegs);
1975 int i, j = 0, shared = 0;
1977 debugLog ("%s\n", __FUNCTION__);
1978 /* if the result has been spilt then cannot share */
1983 /* first make sure that they actually share */
1984 for (i = 0; i < count; i++)
1986 for (j = 0; j < count; j++)
1988 if (result->regs[i] == opsym->regs[j] && i != j)
1998 regs *tmp = result->regs[i];
1999 result->regs[i] = result->regs[j];
2000 result->regs[j] = tmp;
2005 /*-----------------------------------------------------------------*/
2006 /* serialRegAssign - serially allocate registers to the variables */
2007 /*-----------------------------------------------------------------*/
2009 serialRegAssign (eBBlock ** ebbs, int count)
2013 debugLog ("%s\n", __FUNCTION__);
2014 /* for all blocks */
2015 for (i = 0; i < count; i++)
2020 if (ebbs[i]->noPath &&
2021 (ebbs[i]->entryLabel != entryLabel &&
2022 ebbs[i]->entryLabel != returnLabel))
2025 /* of all instructions do */
2026 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2029 debugLog (" op: %s\n", decodeOp (ic->op));
2031 /* if this is an ipop that means some live
2032 range will have to be assigned again */
2034 reassignLR (IC_LEFT (ic));
2036 /* if result is present && is a true symbol */
2037 if (IC_RESULT (ic) && ic->op != IFX &&
2038 IS_TRUE_SYMOP (IC_RESULT (ic)))
2039 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2041 /* take away registers from live
2042 ranges that end at this instruction */
2043 deassignLRs (ic, ebbs[i]);
2045 /* some don't need registers */
2046 if (SKIP_IC2 (ic) ||
2047 ic->op == JUMPTABLE ||
2051 (IC_RESULT (ic) && POINTER_SET (ic)))
2054 /* now we need to allocate registers
2055 only for the result */
2058 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2064 /* if it does not need or is spilt
2065 or is already assigned to registers
2066 or will not live beyond this instructions */
2069 bitVectBitValue (_G.regAssigned, sym->key) ||
2070 sym->liveTo <= ic->seq)
2073 /* if some liverange has been spilt at the block level
2074 and this one live beyond this block then spil this
2076 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2081 /* if trying to allocate this will cause
2082 a spill and there is nothing to spill
2083 or this one is rematerializable then
2085 willCS = willCauseSpill (sym->nRegs, sym->regType);
2086 spillable = computeSpillable (ic);
2088 (willCS && bitVectIsZero (spillable)))
2096 /* if it has a spillocation & is used less than
2097 all other live ranges then spill this */
2099 if (sym->usl.spillLoc) {
2100 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2101 allLRs, ebbs[i], ic));
2102 if (leastUsed && leastUsed->used > sym->used) {
2107 /* if none of the liveRanges have a spillLocation then better
2108 to spill this one than anything else already assigned to registers */
2109 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2110 /* if this is local to this block then we might find a block spil */
2111 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2119 if (ic->op == RECEIVE)
2120 debugLog ("When I get clever, I'll optimize the receive logic\n");
2122 /* if we need ptr regs for the right side
2124 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2125 <= (unsigned) PTRSIZE)
2130 /* else we assign registers to it */
2131 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2133 debugLog (" %d - \n", __LINE__);
2135 bitVectDebugOn(_G.regAssigned, debugF);
2137 for (j = 0; j < sym->nRegs; j++)
2139 if (sym->regType == REG_PTR)
2140 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2142 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2144 /* if the allocation falied which means
2145 this was spilt then break */
2149 debugLog (" %d - \n", __LINE__);
2151 /* if it shares registers with operands make sure
2152 that they are in the same position */
2153 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2154 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2155 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2156 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2157 /* do the same for the right operand */
2158 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2159 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2160 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2161 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2163 debugLog (" %d - \n", __LINE__);
2166 debugLog (" %d - \n", __LINE__);
2176 /*-----------------------------------------------------------------*/
2177 /* rUmaskForOp :- returns register mask for an operand */
2178 /*-----------------------------------------------------------------*/
2180 rUmaskForOp (operand * op)
2186 debugLog ("%s\n", __FUNCTION__);
2187 /* only temporaries are assigned registers */
2191 sym = OP_SYMBOL (op);
2193 /* if spilt or no registers assigned to it
2195 if (sym->isspilt || !sym->nRegs)
2198 rumask = newBitVect (pic14_nRegs);
2200 for (j = 0; j < sym->nRegs; j++)
2202 rumask = bitVectSetBit (rumask,
2203 sym->regs[j]->rIdx);
2209 /*-----------------------------------------------------------------*/
2210 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2211 /*-----------------------------------------------------------------*/
2213 regsUsedIniCode (iCode * ic)
2215 bitVect *rmask = newBitVect (pic14_nRegs);
2217 debugLog ("%s\n", __FUNCTION__);
2218 /* do the special cases first */
2221 rmask = bitVectUnion (rmask,
2222 rUmaskForOp (IC_COND (ic)));
2226 /* for the jumptable */
2227 if (ic->op == JUMPTABLE)
2229 rmask = bitVectUnion (rmask,
2230 rUmaskForOp (IC_JTCOND (ic)));
2235 /* of all other cases */
2237 rmask = bitVectUnion (rmask,
2238 rUmaskForOp (IC_LEFT (ic)));
2242 rmask = bitVectUnion (rmask,
2243 rUmaskForOp (IC_RIGHT (ic)));
2246 rmask = bitVectUnion (rmask,
2247 rUmaskForOp (IC_RESULT (ic)));
2253 /*-----------------------------------------------------------------*/
2254 /* createRegMask - for each instruction will determine the regsUsed */
2255 /*-----------------------------------------------------------------*/
2257 createRegMask (eBBlock ** ebbs, int count)
2261 debugLog ("%s\n", __FUNCTION__);
2262 /* for all blocks */
2263 for (i = 0; i < count; i++)
2267 if (ebbs[i]->noPath &&
2268 (ebbs[i]->entryLabel != entryLabel &&
2269 ebbs[i]->entryLabel != returnLabel))
2272 /* for all instructions */
2273 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2278 if (SKIP_IC2 (ic) || !ic->rlive)
2281 /* first mark the registers used in this
2283 ic->rUsed = regsUsedIniCode (ic);
2284 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2286 /* now create the register mask for those
2287 registers that are in use : this is a
2288 super set of ic->rUsed */
2289 ic->rMask = newBitVect (pic14_nRegs + 1);
2291 /* for all live Ranges alive at this point */
2292 for (j = 1; j < ic->rlive->size; j++)
2297 /* if not alive then continue */
2298 if (!bitVectBitValue (ic->rlive, j))
2301 /* find the live range we are interested in */
2302 if (!(sym = hTabItemWithKey (liveRanges, j)))
2304 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2305 "createRegMask cannot find live range");
2309 /* if no register assigned to it */
2310 if (!sym->nRegs || sym->isspilt)
2313 /* for all the registers allocated to it */
2314 for (k = 0; k < sym->nRegs; k++)
2317 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2323 /*-----------------------------------------------------------------*/
2324 /* rematStr - returns the rematerialized string for a remat var */
2325 /*-----------------------------------------------------------------*/
2327 rematStr (symbol * sym)
2330 iCode *ic = sym->rematiCode;
2331 symbol *psym = NULL;
2333 debugLog ("%s\n", __FUNCTION__);
2335 //printf ("%s\n", s);
2337 /* if plus or minus print the right hand side */
2339 if (ic->op == '+' || ic->op == '-') {
2341 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2343 sprintf (s, "(%s %c 0x%04x)",
2344 OP_SYMBOL (IC_LEFT (ric))->rname,
2346 (int) operandLitValue (IC_RIGHT (ic)));
2349 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2351 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2352 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2357 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2358 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2360 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2365 /*-----------------------------------------------------------------*/
2366 /* rematStr - returns the rematerialized string for a remat var */
2367 /*-----------------------------------------------------------------*/
2369 rematStr (symbol * sym)
2372 iCode *ic = sym->rematiCode;
2374 debugLog ("%s\n", __FUNCTION__);
2379 /* if plus or minus print the right hand side */
2381 if (ic->op == '+' || ic->op == '-') {
2382 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2385 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2389 if (ic->op == '+' || ic->op == '-')
2391 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2392 sprintf (s, "(%s %c 0x%04x)",
2393 OP_SYMBOL (IC_LEFT (ric))->rname,
2395 (int) operandLitValue (IC_RIGHT (ic)));
2398 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2400 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2404 /* we reached the end */
2405 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2409 printf ("%s\n", buffer);
2414 /*-----------------------------------------------------------------*/
2415 /* regTypeNum - computes the type & number of registers required */
2416 /*-----------------------------------------------------------------*/
2424 debugLog ("%s\n", __FUNCTION__);
2425 /* for each live range do */
2426 for (sym = hTabFirstItem (liveRanges, &k); sym;
2427 sym = hTabNextItem (liveRanges, &k)) {
2429 debugLog (" %d - %s\n", __LINE__, sym->rname);
2431 /* if used zero times then no registers needed */
2432 if ((sym->liveTo - sym->liveFrom) == 0)
2436 /* if the live range is a temporary */
2439 debugLog (" %d - itemp register\n", __LINE__);
2441 /* if the type is marked as a conditional */
2442 if (sym->regType == REG_CND)
2445 /* if used in return only then we don't
2448 if (IS_AGGREGATE (sym->type) || sym->isptr)
2449 sym->type = aggrToPtr (sym->type, FALSE);
2450 debugLog (" %d - no reg needed - accumulator used\n", __LINE__);
2456 //if (IS_AGGREGATE (sym->type) || sym->isptr)
2457 // sym->type = aggrToPtr (sym->type, FALSE);
2458 debugLog (" %d - used as a return\n", __LINE__);
2463 /* if the symbol has only one definition &
2464 that definition is a get_pointer and the
2465 pointer we are getting is rematerializable and
2468 if (bitVectnBitsOn (sym->defs) == 1 &&
2469 (ic = hTabItemWithKey (iCodehTab,
2470 bitVectFirstBit (sym->defs))) &&
2473 !IS_BITVAR (sym->etype)) {
2476 debugLog (" %d - \n", __LINE__);
2478 /* if remat in data space */
2479 if (OP_SYMBOL (IC_LEFT (ic))->remat &&
2480 DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) {
2482 /* create a psuedo symbol & force a spil */
2483 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2484 symbol *psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2485 psym->type = sym->type;
2486 psym->etype = sym->etype;
2487 strcpy (psym->rname, psym->name);
2489 sym->usl.spillLoc = psym;
2493 /* if in data space or idata space then try to
2494 allocate pointer register */
2498 /* if not then we require registers */
2499 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2500 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2501 getSize (sym->type));
2504 if(IS_PTR_CONST (sym->type)) {
2505 debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2509 if (sym->nRegs > 4) {
2510 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2511 printTypeChain (sym->type, stderr);
2512 fprintf (stderr, "\n");
2515 /* determine the type of register required */
2516 if (sym->nRegs == 1 &&
2517 IS_PTR (sym->type) &&
2519 sym->regType = REG_PTR;
2521 sym->regType = REG_GPR;
2524 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2528 /* for the first run we don't provide */
2529 /* registers for true symbols we will */
2530 /* see how things go */
2535 DEFSETFUNC (markRegFree)
2537 ((regs *)item)->isFree = 1;
2542 DEFSETFUNC (deallocReg)
2544 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2545 ((regs *)item)->isFree = 1;
2546 ((regs *)item)->wasUsed = 0;
2550 /*-----------------------------------------------------------------*/
2551 /* freeAllRegs - mark all registers as free */
2552 /*-----------------------------------------------------------------*/
2554 pic14_freeAllRegs ()
2558 debugLog ("%s\n", __FUNCTION__);
2560 applyToSet(dynAllocRegs,markRegFree);
2561 applyToSet(dynStackRegs,markRegFree);
2564 for (i = 0; i < pic14_nRegs; i++)
2565 regspic14[i].isFree = 1;
2569 /*-----------------------------------------------------------------*/
2570 /*-----------------------------------------------------------------*/
2572 pic14_deallocateAllRegs ()
2576 debugLog ("%s\n", __FUNCTION__);
2578 applyToSet(dynAllocRegs,deallocReg);
2581 for (i = 0; i < pic14_nRegs; i++) {
2582 if(regspic14[i].pc_type == PO_GPR_TEMP) {
2583 regspic14[i].isFree = 1;
2584 regspic14[i].wasUsed = 0;
2591 /*-----------------------------------------------------------------*/
2592 /* deallocStackSpil - this will set the stack pointer back */
2593 /*-----------------------------------------------------------------*/
2595 DEFSETFUNC (deallocStackSpil)
2599 debugLog ("%s\n", __FUNCTION__);
2604 /*-----------------------------------------------------------------*/
2605 /* farSpacePackable - returns the packable icode for far variables */
2606 /*-----------------------------------------------------------------*/
2608 farSpacePackable (iCode * ic)
2612 debugLog ("%s\n", __FUNCTION__);
2613 /* go thru till we find a definition for the
2614 symbol on the right */
2615 for (dic = ic->prev; dic; dic = dic->prev)
2618 /* if the definition is a call then no */
2619 if ((dic->op == CALL || dic->op == PCALL) &&
2620 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2625 /* if shift by unknown amount then not */
2626 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2627 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2630 /* if pointer get and size > 1 */
2631 if (POINTER_GET (dic) &&
2632 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2635 if (POINTER_SET (dic) &&
2636 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2639 /* if any three is a true symbol in far space */
2640 if (IC_RESULT (dic) &&
2641 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2642 isOperandInFarSpace (IC_RESULT (dic)))
2645 if (IC_RIGHT (dic) &&
2646 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2647 isOperandInFarSpace (IC_RIGHT (dic)) &&
2648 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2651 if (IC_LEFT (dic) &&
2652 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2653 isOperandInFarSpace (IC_LEFT (dic)) &&
2654 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2657 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2659 if ((dic->op == LEFT_OP ||
2660 dic->op == RIGHT_OP ||
2662 IS_OP_LITERAL (IC_RIGHT (dic)))
2672 /*-----------------------------------------------------------------*/
2673 /* packRegsForAssign - register reduction for assignment */
2674 /*-----------------------------------------------------------------*/
2676 packRegsForAssign (iCode * ic, eBBlock * ebp)
2681 debugLog ("%s\n", __FUNCTION__);
2683 debugAopGet (" result:", IC_RESULT (ic));
2684 debugAopGet (" left:", IC_LEFT (ic));
2685 debugAopGet (" right:", IC_RIGHT (ic));
2687 /* if this is at an absolute address, then get the address. */
2688 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2689 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2690 debugLog (" %d - found config word declaration\n", __LINE__);
2691 if(IS_VALOP(IC_RIGHT(ic))) {
2692 debugLog (" setting config word to %x\n",
2693 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2694 assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2695 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2698 /* remove the assignment from the iCode chain. */
2700 remiCodeFromeBBlock (ebp, ic);
2701 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2702 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2709 if (!IS_ITEMP (IC_RESULT (ic))) {
2710 allocDirReg(IC_RESULT (ic));
2711 debugLog (" %d - result is not temp\n", __LINE__);
2714 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2715 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2716 allocDirReg(IC_LEFT (ic));
2720 if (!IS_ITEMP (IC_RIGHT (ic))) {
2721 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2723 /* only pack if this is not a function pointer */
2724 if (!IS_REF (IC_RIGHT (ic)))
2725 allocDirReg(IC_RIGHT (ic));
2729 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2730 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2732 debugLog (" %d - not packing - right side fails \n", __LINE__);
2736 /* if the true symbol is defined in far space or on stack
2737 then we should not since this will increase register pressure */
2738 if (isOperandInFarSpace (IC_RESULT (ic)))
2740 if ((dic = farSpacePackable (ic)))
2746 /* find the definition of iTempNN scanning backwards if we find a
2747 a use of the true symbol before we find the definition then
2749 for (dic = ic->prev; dic; dic = dic->prev)
2752 /* if there is a function call and this is
2753 a parameter & not my parameter then don't pack it */
2754 if ((dic->op == CALL || dic->op == PCALL) &&
2755 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2756 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2758 debugLog (" %d - \n", __LINE__);
2766 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2767 IS_OP_VOLATILE (IC_RESULT (dic)))
2769 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2774 if (IS_SYMOP (IC_RESULT (dic)) &&
2775 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2777 /* A previous result was assigned to the same register - we'll our definition */
2778 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2779 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2780 if (POINTER_SET (dic))
2786 if (IS_SYMOP (IC_RIGHT (dic)) &&
2787 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2788 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2790 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
2795 if (IS_SYMOP (IC_LEFT (dic)) &&
2796 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2797 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2799 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
2804 if (POINTER_SET (dic) &&
2805 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2807 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
2815 return 0; /* did not find */
2817 /* if the result is on stack or iaccess then it must be
2818 the same atleast one of the operands */
2819 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2820 OP_SYMBOL (IC_RESULT (ic))->iaccess)
2823 /* the operation has only one symbol
2824 operator then we can pack */
2825 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2826 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2829 if (!((IC_LEFT (dic) &&
2830 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2832 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2836 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2837 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
2838 /* found the definition */
2839 /* replace the result with the result of */
2840 /* this assignment and remove this assignment */
2841 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2842 IC_RESULT (dic) = IC_RESULT (ic);
2844 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2846 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2848 /* delete from liverange table also
2849 delete from all the points inbetween and the new
2851 for (sic = dic; sic != ic; sic = sic->next)
2853 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2854 if (IS_ITEMP (IC_RESULT (dic)))
2855 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2858 remiCodeFromeBBlock (ebp, ic);
2859 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2860 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2861 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2867 /*-----------------------------------------------------------------*/
2868 /* findAssignToSym : scanning backwards looks for first assig found */
2869 /*-----------------------------------------------------------------*/
2871 findAssignToSym (operand * op, iCode * ic)
2875 debugLog ("%s\n", __FUNCTION__);
2876 for (dic = ic->prev; dic; dic = dic->prev)
2879 /* if definition by assignment */
2880 if (dic->op == '=' &&
2881 !POINTER_SET (dic) &&
2882 IC_RESULT (dic)->key == op->key
2883 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2887 /* we are interested only if defined in far space */
2888 /* or in stack space in case of + & - */
2890 /* if assigned to a non-symbol then return
2892 if (!IS_SYMOP (IC_RIGHT (dic)))
2895 /* if the symbol is in far space then
2897 if (isOperandInFarSpace (IC_RIGHT (dic)))
2900 /* for + & - operations make sure that
2901 if it is on the stack it is the same
2902 as one of the three operands */
2903 if ((ic->op == '+' || ic->op == '-') &&
2904 OP_SYMBOL (IC_RIGHT (dic))->onStack)
2907 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2908 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2909 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2917 /* if we find an usage then we cannot delete it */
2918 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2921 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2924 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2928 /* now make sure that the right side of dic
2929 is not defined between ic & dic */
2932 iCode *sic = dic->next;
2934 for (; sic != ic; sic = sic->next)
2935 if (IC_RESULT (sic) &&
2936 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2945 /*-----------------------------------------------------------------*/
2946 /* packRegsForSupport :- reduce some registers for support calls */
2947 /*-----------------------------------------------------------------*/
2949 packRegsForSupport (iCode * ic, eBBlock * ebp)
2953 debugLog ("%s\n", __FUNCTION__);
2954 /* for the left & right operand :- look to see if the
2955 left was assigned a true symbol in far space in that
2956 case replace them */
2957 if (IS_ITEMP (IC_LEFT (ic)) &&
2958 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2960 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
2966 debugAopGet ("removing left:", IC_LEFT (ic));
2968 /* found it we need to remove it from the
2970 for (sic = dic; sic != ic; sic = sic->next)
2971 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
2973 IC_LEFT (ic)->operand.symOperand =
2974 IC_RIGHT (dic)->operand.symOperand;
2975 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2976 remiCodeFromeBBlock (ebp, dic);
2977 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2978 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2982 /* do the same for the right operand */
2985 IS_ITEMP (IC_RIGHT (ic)) &&
2986 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2988 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2994 /* if this is a subtraction & the result
2995 is a true symbol in far space then don't pack */
2996 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
2998 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
2999 if (IN_FARSPACE (SPEC_OCLS (etype)))
3003 debugAopGet ("removing right:", IC_RIGHT (ic));
3005 /* found it we need to remove it from the
3007 for (sic = dic; sic != ic; sic = sic->next)
3008 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3010 IC_RIGHT (ic)->operand.symOperand =
3011 IC_RIGHT (dic)->operand.symOperand;
3012 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3014 remiCodeFromeBBlock (ebp, dic);
3015 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3016 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3023 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3026 /*-----------------------------------------------------------------*/
3027 /* packRegsForOneuse : - will reduce some registers for single Use */
3028 /*-----------------------------------------------------------------*/
3030 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3035 debugLog ("%s\n", __FUNCTION__);
3036 /* if returning a literal then do nothing */
3040 /* only upto 2 bytes since we cannot predict
3041 the usage of b, & acc */
3042 if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
3047 /* this routine will mark the a symbol as used in one
3048 instruction use only && if the definition is local
3049 (ie. within the basic block) && has only one definition &&
3050 that definition is either a return value from a
3051 function or does not contain any variables in
3053 uses = bitVectCopy (OP_USES (op));
3054 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3055 if (!bitVectIsZero (uses)) /* has other uses */
3058 /* if it has only one defintion */
3059 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3060 return NULL; /* has more than one definition */
3062 /* get that definition */
3064 hTabItemWithKey (iCodehTab,
3065 bitVectFirstBit (OP_DEFS (op)))))
3068 /* found the definition now check if it is local */
3069 if (dic->seq < ebp->fSeq ||
3070 dic->seq > ebp->lSeq)
3071 return NULL; /* non-local */
3073 /* now check if it is the return from
3075 if (dic->op == CALL || dic->op == PCALL)
3077 if (ic->op != SEND && ic->op != RETURN &&
3078 !POINTER_SET(ic) && !POINTER_GET(ic))
3080 OP_SYMBOL (op)->ruonly = 1;
3087 /* otherwise check that the definition does
3088 not contain any symbols in far space */
3089 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3090 isOperandInFarSpace (IC_RIGHT (dic)) ||
3091 IS_OP_RUONLY (IC_LEFT (ic)) ||
3092 IS_OP_RUONLY (IC_RIGHT (ic)))
3097 /* if pointer set then make sure the pointer
3099 if (POINTER_SET (dic) &&
3100 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3103 if (POINTER_GET (dic) &&
3104 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3109 /* also make sure the intervenening instructions
3110 don't have any thing in far space */
3111 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3114 /* if there is an intervening function call then no */
3115 if (dic->op == CALL || dic->op == PCALL)
3117 /* if pointer set then make sure the pointer
3119 if (POINTER_SET (dic) &&
3120 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3123 if (POINTER_GET (dic) &&
3124 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3127 /* if address of & the result is remat then okay */
3128 if (dic->op == ADDRESS_OF &&
3129 OP_SYMBOL (IC_RESULT (dic))->remat)
3132 /* if operand has size of three or more & this
3133 operation is a '*','/' or '%' then 'b' may
3135 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3136 getSize (operandType (op)) >= 3)
3139 /* if left or right or result is in far space */
3140 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3141 isOperandInFarSpace (IC_RIGHT (dic)) ||
3142 isOperandInFarSpace (IC_RESULT (dic)) ||
3143 IS_OP_RUONLY (IC_LEFT (dic)) ||
3144 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3145 IS_OP_RUONLY (IC_RESULT (dic)))
3151 OP_SYMBOL (op)->ruonly = 1;
3156 /*-----------------------------------------------------------------*/
3157 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3158 /*-----------------------------------------------------------------*/
3160 isBitwiseOptimizable (iCode * ic)
3162 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3163 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3165 debugLog ("%s\n", __FUNCTION__);
3166 /* bitwise operations are considered optimizable
3167 under the following conditions (Jean-Louis VERN)
3179 if (IS_LITERAL (rtype) ||
3180 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3186 /*-----------------------------------------------------------------*/
3187 /* packRegsForAccUse - pack registers for acc use */
3188 /*-----------------------------------------------------------------*/
3190 packRegsForAccUse (iCode * ic)
3194 debugLog ("%s\n", __FUNCTION__);
3196 /* if this is an aggregate, e.g. a one byte char array */
3197 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3200 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3202 /* if + or - then it has to be one byte result */
3203 if ((ic->op == '+' || ic->op == '-')
3204 && getSize (operandType (IC_RESULT (ic))) > 1)
3207 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3208 /* if shift operation make sure right side is not a literal */
3209 if (ic->op == RIGHT_OP &&
3210 (isOperandLiteral (IC_RIGHT (ic)) ||
3211 getSize (operandType (IC_RESULT (ic))) > 1))
3214 if (ic->op == LEFT_OP &&
3215 (isOperandLiteral (IC_RIGHT (ic)) ||
3216 getSize (operandType (IC_RESULT (ic))) > 1))
3219 if (IS_BITWISE_OP (ic) &&
3220 getSize (operandType (IC_RESULT (ic))) > 1)
3224 /* has only one definition */
3225 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3228 /* has only one use */
3229 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3232 /* and the usage immediately follows this iCode */
3233 if (!(uic = hTabItemWithKey (iCodehTab,
3234 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3237 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3238 if (ic->next != uic)
3241 /* if it is a conditional branch then we definitely can */
3245 if (uic->op == JUMPTABLE)
3248 /* if the usage is not is an assignment
3249 or an arithmetic / bitwise / shift operation then not */
3250 if (POINTER_SET (uic) &&
3251 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3254 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3255 if (uic->op != '=' &&
3256 !IS_ARITHMETIC_OP (uic) &&
3257 !IS_BITWISE_OP (uic) &&
3258 uic->op != LEFT_OP &&
3259 uic->op != RIGHT_OP)
3262 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3263 /* if used in ^ operation then make sure right is not a
3265 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3268 /* if shift operation make sure right side is not a literal */
3269 if (uic->op == RIGHT_OP &&
3270 (isOperandLiteral (IC_RIGHT (uic)) ||
3271 getSize (operandType (IC_RESULT (uic))) > 1))
3274 if (uic->op == LEFT_OP &&
3275 (isOperandLiteral (IC_RIGHT (uic)) ||
3276 getSize (operandType (IC_RESULT (uic))) > 1))
3279 /* make sure that the result of this icode is not on the
3280 stack, since acc is used to compute stack offset */
3281 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3282 OP_SYMBOL (IC_RESULT (uic))->onStack)
3285 /* if either one of them in far space then we cannot */
3286 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3287 isOperandInFarSpace (IC_LEFT (uic))) ||
3288 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3289 isOperandInFarSpace (IC_RIGHT (uic))))
3292 /* if the usage has only one operand then we can */
3293 if (IC_LEFT (uic) == NULL ||
3294 IC_RIGHT (uic) == NULL)
3297 /* make sure this is on the left side if not
3298 a '+' since '+' is commutative */
3299 if (ic->op != '+' &&
3300 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3303 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3304 /* if one of them is a literal then we can */
3305 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3306 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3307 (getSize (operandType (IC_RESULT (uic))) <= 1))
3309 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3313 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3314 /* if the other one is not on stack then we can */
3315 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3316 (IS_ITEMP (IC_RIGHT (uic)) ||
3317 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3318 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3321 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3322 (IS_ITEMP (IC_LEFT (uic)) ||
3323 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3324 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3330 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3331 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3336 /*-----------------------------------------------------------------*/
3337 /* packForPush - hueristics to reduce iCode for pushing */
3338 /*-----------------------------------------------------------------*/
3340 packForReceive (iCode * ic, eBBlock * ebp)
3344 debugLog ("%s\n", __FUNCTION__);
3345 debugAopGet (" result:", IC_RESULT (ic));
3346 debugAopGet (" left:", IC_LEFT (ic));
3347 debugAopGet (" right:", IC_RIGHT (ic));
3352 for (dic = ic->next; dic; dic = dic->next)
3357 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3358 debugLog (" used on left\n");
3359 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3360 debugLog (" used on right\n");
3361 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3362 debugLog (" used on result\n");
3364 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3365 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3370 debugLog (" hey we can remove this unnecessary assign\n");
3372 /*-----------------------------------------------------------------*/
3373 /* packForPush - hueristics to reduce iCode for pushing */
3374 /*-----------------------------------------------------------------*/
3376 packForPush (iCode * ic, eBBlock * ebp)
3380 debugLog ("%s\n", __FUNCTION__);
3381 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3384 /* must have only definition & one usage */
3385 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3386 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3389 /* find the definition */
3390 if (!(dic = hTabItemWithKey (iCodehTab,
3391 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3394 if (dic->op != '=' || POINTER_SET (dic))
3397 /* we now we know that it has one & only one def & use
3398 and the that the definition is an assignment */
3399 IC_LEFT (ic) = IC_RIGHT (dic);
3401 remiCodeFromeBBlock (ebp, dic);
3402 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3403 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3406 void printSymType(char * str, sym_link *sl)
3408 debugLog (" %s Symbol type: ",str);
3409 printTypeChain( sl, debugF);
3414 /*-----------------------------------------------------------------*/
3415 /* some debug code to print the symbol S_TYPE. Note that
3416 * the function checkSClass in src/SDCCsymt.c dinks with
3417 * the S_TYPE in ways the PIC port doesn't fully like...*/
3418 /*-----------------------------------------------------------------*/
3419 void isData(sym_link *sl)
3429 for ( ; sl; sl=sl->next) {
3431 switch (SPEC_SCLS(sl)) {
3433 case S_DATA: fprintf (of, "data "); break;
3434 case S_XDATA: fprintf (of, "xdata "); break;
3435 case S_SFR: fprintf (of, "sfr "); break;
3436 case S_SBIT: fprintf (of, "sbit "); break;
3437 case S_CODE: fprintf (of, "code "); break;
3438 case S_IDATA: fprintf (of, "idata "); break;
3439 case S_PDATA: fprintf (of, "pdata "); break;
3440 case S_LITERAL: fprintf (of, "literal "); break;
3441 case S_STACK: fprintf (of, "stack "); break;
3442 case S_XSTACK: fprintf (of, "xstack "); break;
3443 case S_BIT: fprintf (of, "bit "); break;
3444 case S_EEPROM: fprintf (of, "eeprom "); break;
3453 /*-----------------------------------------------------------------*/
3454 /* packRegisters - does some transformations to reduce register */
3456 /*-----------------------------------------------------------------*/
3458 packRegisters (eBBlock * ebp)
3463 debugLog ("%s\n", __FUNCTION__);
3469 /* look for assignments of the form */
3470 /* iTempNN = TRueSym (someoperation) SomeOperand */
3472 /* TrueSym := iTempNN:1 */
3473 for (ic = ebp->sch; ic; ic = ic->next)
3476 /* find assignment of the form TrueSym := iTempNN:1 */
3477 if (ic->op == '=' && !POINTER_SET (ic))
3478 change += packRegsForAssign (ic, ebp);
3482 if (POINTER_SET (ic))
3483 debugLog ("pointer is set\n");
3484 debugAopGet (" result:", IC_RESULT (ic));
3485 debugAopGet (" left:", IC_LEFT (ic));
3486 debugAopGet (" right:", IC_RIGHT (ic));
3495 for (ic = ebp->sch; ic; ic = ic->next) {
3497 if(IS_SYMOP ( IC_LEFT(ic))) {
3498 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3500 debugAopGet (" left:", IC_LEFT (ic));
3501 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3502 debugLog (" is a pointer\n");
3504 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3505 debugLog (" is volatile\n");
3509 printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
3512 if(IS_SYMOP ( IC_RIGHT(ic))) {
3513 debugAopGet (" right:", IC_RIGHT (ic));
3514 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3517 if(IS_SYMOP ( IC_RESULT(ic))) {
3518 debugAopGet (" result:", IC_RESULT (ic));
3519 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3522 if (POINTER_SET (ic))
3523 debugLog (" %d - Pointer set\n", __LINE__);
3526 /* if this is an itemp & result of a address of a true sym
3527 then mark this as rematerialisable */
3528 if (ic->op == ADDRESS_OF &&
3529 IS_ITEMP (IC_RESULT (ic)) &&
3530 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3531 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3532 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3535 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3537 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3538 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3539 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3543 /* if straight assignment then carry remat flag if
3544 this is the only definition */
3545 if (ic->op == '=' &&
3546 !POINTER_SET (ic) &&
3547 IS_SYMOP (IC_RIGHT (ic)) &&
3548 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3549 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3551 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3553 OP_SYMBOL (IC_RESULT (ic))->remat =
3554 OP_SYMBOL (IC_RIGHT (ic))->remat;
3555 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3556 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3559 /* if this is a +/- operation with a rematerizable
3560 then mark this as rematerializable as well */
3561 if ((ic->op == '+' || ic->op == '-') &&
3562 (IS_SYMOP (IC_LEFT (ic)) &&
3563 IS_ITEMP (IC_RESULT (ic)) &&
3564 OP_SYMBOL (IC_LEFT (ic))->remat &&
3565 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3566 IS_OP_LITERAL (IC_RIGHT (ic))))
3568 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3570 operandLitValue (IC_RIGHT (ic));
3571 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3572 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3573 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3576 /* mark the pointer usages */
3577 if (POINTER_SET (ic))
3579 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3580 debugLog (" marking as a pointer (set) =>");
3581 debugAopGet (" result:", IC_RESULT (ic));
3583 if (POINTER_GET (ic))
3585 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3586 debugLog (" marking as a pointer (get) =>");
3587 debugAopGet (" left:", IC_LEFT (ic));
3592 /* if we are using a symbol on the stack
3593 then we should say pic14_ptrRegReq */
3594 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3595 pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3596 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3597 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3598 pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3599 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3602 if (IS_SYMOP (IC_LEFT (ic)))
3603 pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3604 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3605 if (IS_SYMOP (IC_RIGHT (ic)))
3606 pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3607 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3608 if (IS_SYMOP (IC_RESULT (ic)))
3609 pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3610 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3613 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
3617 /* if the condition of an if instruction
3618 is defined in the previous instruction then
3619 mark the itemp as a conditional */
3620 if ((IS_CONDITIONAL (ic) ||
3621 ((ic->op == BITWISEAND ||
3624 isBitwiseOptimizable (ic))) &&
3625 ic->next && ic->next->op == IFX &&
3626 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3627 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3630 debugLog (" %d\n", __LINE__);
3631 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3635 /* reduce for support function calls */
3636 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3637 packRegsForSupport (ic, ebp);
3639 /* if a parameter is passed, it's in W, so we may not
3640 need to place a copy in a register */
3641 if (ic->op == RECEIVE)
3642 packForReceive (ic, ebp);
3644 /* some cases the redundant moves can
3645 can be eliminated for return statements */
3646 if ((ic->op == RETURN || ic->op == SEND) &&
3647 !isOperandInFarSpace (IC_LEFT (ic)) &&
3649 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3651 /* if pointer set & left has a size more than
3652 one and right is not in far space */
3653 if (POINTER_SET (ic) &&
3654 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3655 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3656 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3657 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3659 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3661 /* if pointer get */
3662 if (POINTER_GET (ic) &&
3663 !isOperandInFarSpace (IC_RESULT (ic)) &&
3664 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3665 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3666 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3668 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3671 /* if this is cast for intergral promotion then
3672 check if only use of the definition of the
3673 operand being casted/ if yes then replace
3674 the result of that arithmetic operation with
3675 this result and get rid of the cast */
3676 if (ic->op == CAST) {
3678 sym_link *fromType = operandType (IC_RIGHT (ic));
3679 sym_link *toType = operandType (IC_LEFT (ic));
3681 debugLog (" %d - casting\n", __LINE__);
3683 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3684 getSize (fromType) != getSize (toType)) {
3687 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3690 if (IS_ARITHMETIC_OP (dic)) {
3692 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3693 IC_RESULT (dic) = IC_RESULT (ic);
3694 remiCodeFromeBBlock (ebp, ic);
3695 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3696 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3697 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3701 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3705 /* if the type from and type to are the same
3706 then if this is the only use then packit */
3707 if (compareType (operandType (IC_RIGHT (ic)),
3708 operandType (IC_LEFT (ic))) == 1) {
3710 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3713 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3714 IC_RESULT (dic) = IC_RESULT (ic);
3715 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3716 remiCodeFromeBBlock (ebp, ic);
3717 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3718 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3726 iTempNN := (some variable in farspace) V1
3731 if (ic->op == IPUSH)
3733 packForPush (ic, ebp);
3737 /* pack registers for accumulator use, when the
3738 result of an arithmetic or bit wise operation
3739 has only one use, that use is immediately following
3740 the defintion and the using iCode has only one
3741 operand or has two operands but one is literal &
3742 the result of that operation is not on stack then
3743 we can leave the result of this operation in acc:b
3745 if ((IS_ARITHMETIC_OP (ic)
3747 || IS_BITWISE_OP (ic)
3749 || ic->op == LEFT_OP || ic->op == RIGHT_OP
3752 IS_ITEMP (IC_RESULT (ic)) &&
3753 getSize (operandType (IC_RESULT (ic))) <= 2)
3755 packRegsForAccUse (ic);
3761 dumpEbbsToDebug (eBBlock ** ebbs, int count)
3765 if (!debug || !debugF)
3768 for (i = 0; i < count; i++)
3770 fprintf (debugF, "\n----------------------------------------------------------------\n");
3771 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
3772 ebbs[i]->entryLabel->name,
3775 ebbs[i]->isLastInLoop);
3776 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
3781 fprintf (debugF, "visited %d : hasFcall = %d\n",
3785 fprintf (debugF, "\ndefines bitVector :");
3786 bitVectDebugOn (ebbs[i]->defSet, debugF);
3787 fprintf (debugF, "\nlocal defines bitVector :");
3788 bitVectDebugOn (ebbs[i]->ldefs, debugF);
3789 fprintf (debugF, "\npointers Set bitvector :");
3790 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
3791 fprintf (debugF, "\nin pointers Set bitvector :");
3792 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
3793 fprintf (debugF, "\ninDefs Set bitvector :");
3794 bitVectDebugOn (ebbs[i]->inDefs, debugF);
3795 fprintf (debugF, "\noutDefs Set bitvector :");
3796 bitVectDebugOn (ebbs[i]->outDefs, debugF);
3797 fprintf (debugF, "\nusesDefs Set bitvector :");
3798 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
3799 fprintf (debugF, "\n----------------------------------------------------------------\n");
3800 printiCChain (ebbs[i]->sch, debugF);
3803 /*-----------------------------------------------------------------*/
3804 /* assignRegisters - assigns registers to each live range as need */
3805 /*-----------------------------------------------------------------*/
3807 pic14_assignRegisters (eBBlock ** ebbs, int count)
3812 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
3813 debugLog ("\nebbs before optimizing:\n");
3814 dumpEbbsToDebug (ebbs, count);
3816 setToNull ((void *) &_G.funcrUsed);
3817 pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3820 /* change assignments this will remove some
3821 live ranges reducing some register pressure */
3822 for (i = 0; i < count; i++)
3823 packRegisters (ebbs[i]);
3830 debugLog("dir registers allocated so far:\n");
3831 reg = hTabFirstItem(dynDirectRegNames, &hkey);
3834 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
3835 reg = hTabNextItem(dynDirectRegNames, &hkey);
3840 if (options.dump_pack)
3841 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3843 /* first determine for each live range the number of
3844 registers & the type of registers required for each */
3847 /* and serially allocate registers */
3848 serialRegAssign (ebbs, count);
3850 /* if stack was extended then tell the user */
3853 /* werror(W_TOOMANY_SPILS,"stack", */
3854 /* _G.stackExtend,currFunc->name,""); */
3860 /* werror(W_TOOMANY_SPILS,"data space", */
3861 /* _G.dataExtend,currFunc->name,""); */
3865 /* after that create the register mask
3866 for each of the instruction */
3867 createRegMask (ebbs, count);
3869 /* redo that offsets for stacked automatic variables */
3870 redoStackOffsets ();
3872 if (options.dump_rassgn)
3873 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3875 /* now get back the chain */
3876 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3878 debugLog ("ebbs after optimizing:\n");
3879 dumpEbbsToDebug (ebbs, count);
3884 /* free up any _G.stackSpil locations allocated */
3885 applyToSet (_G.stackSpil, deallocStackSpil);
3887 setToNull ((void **) &_G.stackSpil);
3888 setToNull ((void **) &_G.spiltSet);
3889 /* mark all registers as free */
3890 //pic14_freeAllRegs ();
3892 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");