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 printf("assignFixedRegisters(dynAllocRegs);\n");
1079 assignFixedRegisters(dynStackRegs);
1080 printf("assignFixedRegisters(dynStackRegs);\n");
1081 assignFixedRegisters(dynDirectRegs);
1082 printf("assignFixedRegisters(dynDirectRegs);\n");
1084 assignRelocatableRegisters(dynInternalRegs,0);
1085 printf("assignRelocatableRegisters(dynInternalRegs,0);\n");
1086 assignRelocatableRegisters(dynAllocRegs,0);
1087 printf("assignRelocatableRegisters(dynAllocRegs,0);\n");
1088 assignRelocatableRegisters(dynStackRegs,0);
1089 printf("assignRelocatableRegisters(dynStackRegs,0);\n");
1091 assignRelocatableRegisters(dynDirectRegs,0);
1092 printf("assignRelocatableRegisters(dynDirectRegs,0);\n");
1097 bitEQUs(of,dynDirectBitRegs);
1099 aliasEQUs(of,dynAllocRegs,0);
1100 aliasEQUs(of,dynDirectRegs,0);
1101 aliasEQUs(of,dynStackRegs,0);
1102 aliasEQUs(of,dynProcessorRegs,1);
1107 /*-----------------------------------------------------------------*/
1108 /* allDefsOutOfRange - all definitions are out of a range */
1109 /*-----------------------------------------------------------------*/
1111 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
1115 debugLog ("%s\n", __FUNCTION__);
1119 for (i = 0; i < defs->size; i++)
1123 if (bitVectBitValue (defs, i) &&
1124 (ic = hTabItemWithKey (iCodehTab, i)) &&
1125 (ic->seq >= fseq && ic->seq <= toseq))
1135 /*-----------------------------------------------------------------*/
1136 /* computeSpillable - given a point find the spillable live ranges */
1137 /*-----------------------------------------------------------------*/
1139 computeSpillable (iCode * ic)
1143 debugLog ("%s\n", __FUNCTION__);
1144 /* spillable live ranges are those that are live at this
1145 point . the following categories need to be subtracted
1147 a) - those that are already spilt
1148 b) - if being used by this one
1149 c) - defined by this one */
1151 spillable = bitVectCopy (ic->rlive);
1153 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1155 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1156 bitVectUnSetBit (spillable, ic->defKey);
1157 spillable = bitVectIntersect (spillable, _G.regAssigned);
1162 /*-----------------------------------------------------------------*/
1163 /* noSpilLoc - return true if a variable has no spil location */
1164 /*-----------------------------------------------------------------*/
1166 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1168 debugLog ("%s\n", __FUNCTION__);
1169 return (sym->usl.spillLoc ? 0 : 1);
1172 /*-----------------------------------------------------------------*/
1173 /* hasSpilLoc - will return 1 if the symbol has spil location */
1174 /*-----------------------------------------------------------------*/
1176 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1178 debugLog ("%s\n", __FUNCTION__);
1179 return (sym->usl.spillLoc ? 1 : 0);
1182 /*-----------------------------------------------------------------*/
1183 /* directSpilLoc - will return 1 if the splilocation is in direct */
1184 /*-----------------------------------------------------------------*/
1186 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1188 debugLog ("%s\n", __FUNCTION__);
1189 if (sym->usl.spillLoc &&
1190 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1196 /*-----------------------------------------------------------------*/
1197 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1198 /* but is not used as a pointer */
1199 /*-----------------------------------------------------------------*/
1201 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1203 debugLog ("%s\n", __FUNCTION__);
1204 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1207 /*-----------------------------------------------------------------*/
1208 /* rematable - will return 1 if the remat flag is set */
1209 /*-----------------------------------------------------------------*/
1211 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1213 debugLog ("%s\n", __FUNCTION__);
1217 /*-----------------------------------------------------------------*/
1218 /* notUsedInRemaining - not used or defined in remain of the block */
1219 /*-----------------------------------------------------------------*/
1221 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1223 debugLog ("%s\n", __FUNCTION__);
1224 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1225 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1228 /*-----------------------------------------------------------------*/
1229 /* allLRs - return true for all */
1230 /*-----------------------------------------------------------------*/
1232 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1234 debugLog ("%s\n", __FUNCTION__);
1238 /*-----------------------------------------------------------------*/
1239 /* liveRangesWith - applies function to a given set of live range */
1240 /*-----------------------------------------------------------------*/
1242 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1243 eBBlock * ebp, iCode * ic)
1248 debugLog ("%s\n", __FUNCTION__);
1249 if (!lrs || !lrs->size)
1252 for (i = 1; i < lrs->size; i++)
1255 if (!bitVectBitValue (lrs, i))
1258 /* if we don't find it in the live range
1259 hash table we are in serious trouble */
1260 if (!(sym = hTabItemWithKey (liveRanges, i)))
1262 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1263 "liveRangesWith could not find liveRange");
1267 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1268 addSetHead (&rset, sym);
1275 /*-----------------------------------------------------------------*/
1276 /* leastUsedLR - given a set determines which is the least used */
1277 /*-----------------------------------------------------------------*/
1279 leastUsedLR (set * sset)
1281 symbol *sym = NULL, *lsym = NULL;
1283 debugLog ("%s\n", __FUNCTION__);
1284 sym = lsym = setFirstItem (sset);
1289 for (; lsym; lsym = setNextItem (sset))
1292 /* if usage is the same then prefer
1293 the spill the smaller of the two */
1294 if (lsym->used == sym->used)
1295 if (getSize (lsym->type) < getSize (sym->type))
1299 if (lsym->used < sym->used)
1304 setToNull ((void **) &sset);
1309 /*-----------------------------------------------------------------*/
1310 /* noOverLap - will iterate through the list looking for over lap */
1311 /*-----------------------------------------------------------------*/
1313 noOverLap (set * itmpStack, symbol * fsym)
1316 debugLog ("%s\n", __FUNCTION__);
1319 for (sym = setFirstItem (itmpStack); sym;
1320 sym = setNextItem (itmpStack))
1322 if (sym->liveTo > fsym->liveFrom)
1330 /*-----------------------------------------------------------------*/
1331 /* isFree - will return 1 if the a free spil location is found */
1332 /*-----------------------------------------------------------------*/
1337 V_ARG (symbol **, sloc);
1338 V_ARG (symbol *, fsym);
1340 debugLog ("%s\n", __FUNCTION__);
1341 /* if already found */
1345 /* if it is free && and the itmp assigned to
1346 this does not have any overlapping live ranges
1347 with the one currently being assigned and
1348 the size can be accomodated */
1350 noOverLap (sym->usl.itmpStack, fsym) &&
1351 getSize (sym->type) >= getSize (fsym->type))
1360 /*-----------------------------------------------------------------*/
1361 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1362 /*-----------------------------------------------------------------*/
1364 spillLRWithPtrReg (symbol * forSym)
1370 debugLog ("%s\n", __FUNCTION__);
1371 if (!_G.regAssigned ||
1372 bitVectIsZero (_G.regAssigned))
1375 r0 = pic14_regWithIdx (R0_IDX);
1376 r1 = pic14_regWithIdx (R1_IDX);
1378 /* for all live ranges */
1379 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1380 lrsym = hTabNextItem (liveRanges, &k))
1384 /* if no registers assigned to it or
1386 /* if it does not overlap with this then
1387 not need to spill it */
1389 if (lrsym->isspilt || !lrsym->nRegs ||
1390 (lrsym->liveTo < forSym->liveFrom))
1393 /* go thru the registers : if it is either
1394 r0 or r1 then spil it */
1395 for (j = 0; j < lrsym->nRegs; j++)
1396 if (lrsym->regs[j] == r0 ||
1397 lrsym->regs[j] == r1)
1406 /*-----------------------------------------------------------------*/
1407 /* createStackSpil - create a location on the stack to spil */
1408 /*-----------------------------------------------------------------*/
1410 createStackSpil (symbol * sym)
1412 symbol *sloc = NULL;
1413 int useXstack, model, noOverlay;
1415 char slocBuffer[30];
1416 debugLog ("%s\n", __FUNCTION__);
1418 /* first go try and find a free one that is already
1419 existing on the stack */
1420 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1422 /* found a free one : just update & return */
1423 sym->usl.spillLoc = sloc;
1426 addSetHead (&sloc->usl.itmpStack, sym);
1430 /* could not then have to create one , this is the hard part
1431 we need to allocate this on the stack : this is really a
1432 hack!! but cannot think of anything better at this time */
1434 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1436 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1437 __FILE__, __LINE__);
1441 sloc = newiTemp (slocBuffer);
1443 /* set the type to the spilling symbol */
1444 sloc->type = copyLinkChain (sym->type);
1445 sloc->etype = getSpec (sloc->type);
1446 SPEC_SCLS (sloc->etype) = S_DATA;
1447 SPEC_EXTR (sloc->etype) = 0;
1448 SPEC_STAT (sloc->etype) = 0;
1450 /* we don't allow it to be allocated`
1451 onto the external stack since : so we
1452 temporarily turn it off ; we also
1453 turn off memory model to prevent
1454 the spil from going to the external storage
1455 and turn off overlaying
1458 useXstack = options.useXstack;
1459 model = options.model;
1460 noOverlay = options.noOverlay;
1461 options.noOverlay = 1;
1462 options.model = options.useXstack = 0;
1466 options.useXstack = useXstack;
1467 options.model = model;
1468 options.noOverlay = noOverlay;
1469 sloc->isref = 1; /* to prevent compiler warning */
1471 /* if it is on the stack then update the stack */
1472 if (IN_STACK (sloc->etype))
1474 currFunc->stack += getSize (sloc->type);
1475 _G.stackExtend += getSize (sloc->type);
1478 _G.dataExtend += getSize (sloc->type);
1480 /* add it to the _G.stackSpil set */
1481 addSetHead (&_G.stackSpil, sloc);
1482 sym->usl.spillLoc = sloc;
1485 /* add it to the set of itempStack set
1486 of the spill location */
1487 addSetHead (&sloc->usl.itmpStack, sym);
1491 /*-----------------------------------------------------------------*/
1492 /* isSpiltOnStack - returns true if the spil location is on stack */
1493 /*-----------------------------------------------------------------*/
1495 isSpiltOnStack (symbol * sym)
1499 debugLog ("%s\n", __FUNCTION__);
1506 /* if (sym->_G.stackSpil) */
1509 if (!sym->usl.spillLoc)
1512 etype = getSpec (sym->usl.spillLoc->type);
1513 if (IN_STACK (etype))
1519 /*-----------------------------------------------------------------*/
1520 /* spillThis - spils a specific operand */
1521 /*-----------------------------------------------------------------*/
1523 spillThis (symbol * sym)
1526 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1528 /* if this is rematerializable or has a spillLocation
1529 we are okay, else we need to create a spillLocation
1531 if (!(sym->remat || sym->usl.spillLoc))
1532 createStackSpil (sym);
1535 /* mark it has spilt & put it in the spilt set */
1537 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1539 bitVectUnSetBit (_G.regAssigned, sym->key);
1541 for (i = 0; i < sym->nRegs; i++)
1545 freeReg (sym->regs[i]);
1546 sym->regs[i] = NULL;
1549 /* if spilt on stack then free up r0 & r1
1550 if they could have been assigned to some
1552 if (!pic14_ptrRegReq && isSpiltOnStack (sym))
1555 spillLRWithPtrReg (sym);
1558 if (sym->usl.spillLoc && !sym->remat)
1559 sym->usl.spillLoc->allocreq = 1;
1563 /*-----------------------------------------------------------------*/
1564 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1565 /*-----------------------------------------------------------------*/
1567 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1569 bitVect *lrcs = NULL;
1573 debugLog ("%s\n", __FUNCTION__);
1574 /* get the spillable live ranges */
1575 lrcs = computeSpillable (ic);
1577 /* get all live ranges that are rematerizable */
1578 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1581 /* return the least used of these */
1582 return leastUsedLR (selectS);
1585 /* get live ranges with spillLocations in direct space */
1586 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1588 sym = leastUsedLR (selectS);
1589 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1590 sym->usl.spillLoc->rname :
1591 sym->usl.spillLoc->name));
1593 /* mark it as allocation required */
1594 sym->usl.spillLoc->allocreq = 1;
1598 /* if the symbol is local to the block then */
1599 if (forSym->liveTo < ebp->lSeq)
1602 /* check if there are any live ranges allocated
1603 to registers that are not used in this block */
1604 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1606 sym = leastUsedLR (selectS);
1607 /* if this is not rematerializable */
1616 /* check if there are any live ranges that not
1617 used in the remainder of the block */
1618 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1620 sym = leastUsedLR (selectS);
1623 sym->remainSpil = 1;
1630 /* find live ranges with spillocation && not used as pointers */
1631 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1634 sym = leastUsedLR (selectS);
1635 /* mark this as allocation required */
1636 sym->usl.spillLoc->allocreq = 1;
1640 /* find live ranges with spillocation */
1641 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1644 sym = leastUsedLR (selectS);
1645 sym->usl.spillLoc->allocreq = 1;
1649 /* couldn't find then we need to create a spil
1650 location on the stack , for which one? the least
1652 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1655 /* return a created spil location */
1656 sym = createStackSpil (leastUsedLR (selectS));
1657 sym->usl.spillLoc->allocreq = 1;
1661 /* this is an extreme situation we will spill
1662 this one : happens very rarely but it does happen */
1668 /*-----------------------------------------------------------------*/
1669 /* spilSomething - spil some variable & mark registers as free */
1670 /*-----------------------------------------------------------------*/
1672 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1677 debugLog ("%s\n", __FUNCTION__);
1678 /* get something we can spil */
1679 ssym = selectSpil (ic, ebp, forSym);
1681 /* mark it as spilt */
1683 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1685 /* mark it as not register assigned &
1686 take it away from the set */
1687 bitVectUnSetBit (_G.regAssigned, ssym->key);
1689 /* mark the registers as free */
1690 for (i = 0; i < ssym->nRegs; i++)
1692 freeReg (ssym->regs[i]);
1694 /* if spilt on stack then free up r0 & r1
1695 if they could have been assigned to as gprs */
1696 if (!pic14_ptrRegReq && isSpiltOnStack (ssym))
1699 spillLRWithPtrReg (ssym);
1702 /* if this was a block level spil then insert push & pop
1703 at the start & end of block respectively */
1704 if (ssym->blockSpil)
1706 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1707 /* add push to the start of the block */
1708 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1709 ebp->sch->next : ebp->sch));
1710 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1711 /* add pop to the end of the block */
1712 addiCodeToeBBlock (ebp, nic, NULL);
1715 /* if spilt because not used in the remainder of the
1716 block then add a push before this instruction and
1717 a pop at the end of the block */
1718 if (ssym->remainSpil)
1721 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1722 /* add push just before this instruction */
1723 addiCodeToeBBlock (ebp, nic, ic);
1725 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1726 /* add pop to the end of the block */
1727 addiCodeToeBBlock (ebp, nic, NULL);
1736 /*-----------------------------------------------------------------*/
1737 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1738 /*-----------------------------------------------------------------*/
1740 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1744 debugLog ("%s\n", __FUNCTION__);
1746 /* try for a ptr type */
1747 if ((reg = allocReg (REG_PTR)))
1750 /* try for gpr type */
1751 if ((reg = allocReg (REG_GPR)))
1754 /* we have to spil */
1755 if (!spilSomething (ic, ebp, sym))
1758 /* this looks like an infinite loop but
1759 in really selectSpil will abort */
1763 /*-----------------------------------------------------------------*/
1764 /* getRegGpr - will try for GPR if not spil */
1765 /*-----------------------------------------------------------------*/
1767 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1771 debugLog ("%s\n", __FUNCTION__);
1773 /* try for gpr type */
1774 if ((reg = allocReg (REG_GPR)))
1777 if (!pic14_ptrRegReq)
1778 if ((reg = allocReg (REG_PTR)))
1781 /* we have to spil */
1782 if (!spilSomething (ic, ebp, sym))
1785 /* this looks like an infinite loop but
1786 in really selectSpil will abort */
1790 /*-----------------------------------------------------------------*/
1791 /* symHasReg - symbol has a given register */
1792 /*-----------------------------------------------------------------*/
1794 symHasReg (symbol * sym, regs * reg)
1798 debugLog ("%s\n", __FUNCTION__);
1799 for (i = 0; i < sym->nRegs; i++)
1800 if (sym->regs[i] == reg)
1806 /*-----------------------------------------------------------------*/
1807 /* deassignLRs - check the live to and if they have registers & are */
1808 /* not spilt then free up the registers */
1809 /*-----------------------------------------------------------------*/
1811 deassignLRs (iCode * ic, eBBlock * ebp)
1817 debugLog ("%s\n", __FUNCTION__);
1818 for (sym = hTabFirstItem (liveRanges, &k); sym;
1819 sym = hTabNextItem (liveRanges, &k))
1822 symbol *psym = NULL;
1823 /* if it does not end here */
1824 if (sym->liveTo > ic->seq)
1827 /* if it was spilt on stack then we can
1828 mark the stack spil location as free */
1833 sym->usl.spillLoc->isFree = 1;
1839 if (!bitVectBitValue (_G.regAssigned, sym->key))
1842 /* special case check if this is an IFX &
1843 the privious one was a pop and the
1844 previous one was not spilt then keep track
1846 if (ic->op == IFX && ic->prev &&
1847 ic->prev->op == IPOP &&
1848 !ic->prev->parmPush &&
1849 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1850 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1856 bitVectUnSetBit (_G.regAssigned, sym->key);
1858 /* if the result of this one needs registers
1859 and does not have it then assign it right
1861 if (IC_RESULT (ic) &&
1862 !(SKIP_IC2 (ic) || /* not a special icode */
1863 ic->op == JUMPTABLE ||
1868 POINTER_SET (ic)) &&
1869 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1870 result->liveTo > ic->seq && /* and will live beyond this */
1871 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1872 result->regType == sym->regType && /* same register types */
1873 result->nRegs && /* which needs registers */
1874 !result->isspilt && /* and does not already have them */
1876 !bitVectBitValue (_G.regAssigned, result->key) &&
1877 /* the number of free regs + number of regs in this LR
1878 can accomodate the what result Needs */
1879 ((nfreeRegsType (result->regType) +
1880 sym->nRegs) >= result->nRegs)
1884 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1886 result->regs[i] = sym->regs[i];
1888 result->regs[i] = getRegGpr (ic, ebp, result);
1890 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1894 /* free the remaining */
1895 for (; i < sym->nRegs; i++)
1899 if (!symHasReg (psym, sym->regs[i]))
1900 freeReg (sym->regs[i]);
1903 freeReg (sym->regs[i]);
1910 /*-----------------------------------------------------------------*/
1911 /* reassignLR - reassign this to registers */
1912 /*-----------------------------------------------------------------*/
1914 reassignLR (operand * op)
1916 symbol *sym = OP_SYMBOL (op);
1919 debugLog ("%s\n", __FUNCTION__);
1920 /* not spilt any more */
1921 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1922 bitVectUnSetBit (_G.spiltSet, sym->key);
1924 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1928 for (i = 0; i < sym->nRegs; i++)
1929 sym->regs[i]->isFree = 0;
1932 /*-----------------------------------------------------------------*/
1933 /* willCauseSpill - determines if allocating will cause a spill */
1934 /*-----------------------------------------------------------------*/
1936 willCauseSpill (int nr, int rt)
1938 debugLog ("%s\n", __FUNCTION__);
1939 /* first check if there are any avlb registers
1940 of te type required */
1943 /* special case for pointer type
1944 if pointer type not avlb then
1945 check for type gpr */
1946 if (nFreeRegs (rt) >= nr)
1948 if (nFreeRegs (REG_GPR) >= nr)
1953 if (pic14_ptrRegReq)
1955 if (nFreeRegs (rt) >= nr)
1960 if (nFreeRegs (REG_PTR) +
1961 nFreeRegs (REG_GPR) >= nr)
1966 debugLog (" ... yep it will (cause a spill)\n");
1967 /* it will cause a spil */
1971 /*-----------------------------------------------------------------*/
1972 /* positionRegs - the allocator can allocate same registers to res- */
1973 /* ult and operand, if this happens make sure they are in the same */
1974 /* position as the operand otherwise chaos results */
1975 /*-----------------------------------------------------------------*/
1977 positionRegs (symbol * result, symbol * opsym, int lineno)
1979 int count = min (result->nRegs, opsym->nRegs);
1980 int i, j = 0, shared = 0;
1982 debugLog ("%s\n", __FUNCTION__);
1983 /* if the result has been spilt then cannot share */
1988 /* first make sure that they actually share */
1989 for (i = 0; i < count; i++)
1991 for (j = 0; j < count; j++)
1993 if (result->regs[i] == opsym->regs[j] && i != j)
2003 regs *tmp = result->regs[i];
2004 result->regs[i] = result->regs[j];
2005 result->regs[j] = tmp;
2010 /*-----------------------------------------------------------------*/
2011 /* serialRegAssign - serially allocate registers to the variables */
2012 /*-----------------------------------------------------------------*/
2014 serialRegAssign (eBBlock ** ebbs, int count)
2018 debugLog ("%s\n", __FUNCTION__);
2019 /* for all blocks */
2020 for (i = 0; i < count; i++)
2025 if (ebbs[i]->noPath &&
2026 (ebbs[i]->entryLabel != entryLabel &&
2027 ebbs[i]->entryLabel != returnLabel))
2030 /* of all instructions do */
2031 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2034 debugLog (" op: %s\n", decodeOp (ic->op));
2036 /* if this is an ipop that means some live
2037 range will have to be assigned again */
2039 reassignLR (IC_LEFT (ic));
2041 /* if result is present && is a true symbol */
2042 if (IC_RESULT (ic) && ic->op != IFX &&
2043 IS_TRUE_SYMOP (IC_RESULT (ic)))
2044 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2046 /* take away registers from live
2047 ranges that end at this instruction */
2048 deassignLRs (ic, ebbs[i]);
2050 /* some don't need registers */
2051 if (SKIP_IC2 (ic) ||
2052 ic->op == JUMPTABLE ||
2056 (IC_RESULT (ic) && POINTER_SET (ic)))
2059 /* now we need to allocate registers
2060 only for the result */
2063 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2069 /* if it does not need or is spilt
2070 or is already assigned to registers
2071 or will not live beyond this instructions */
2074 bitVectBitValue (_G.regAssigned, sym->key) ||
2075 sym->liveTo <= ic->seq)
2078 /* if some liverange has been spilt at the block level
2079 and this one live beyond this block then spil this
2081 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2086 /* if trying to allocate this will cause
2087 a spill and there is nothing to spill
2088 or this one is rematerializable then
2090 willCS = willCauseSpill (sym->nRegs, sym->regType);
2091 spillable = computeSpillable (ic);
2093 (willCS && bitVectIsZero (spillable)))
2101 /* if it has a spillocation & is used less than
2102 all other live ranges then spill this */
2104 if (sym->usl.spillLoc) {
2105 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2106 allLRs, ebbs[i], ic));
2107 if (leastUsed && leastUsed->used > sym->used) {
2112 /* if none of the liveRanges have a spillLocation then better
2113 to spill this one than anything else already assigned to registers */
2114 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2115 /* if this is local to this block then we might find a block spil */
2116 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2124 if (ic->op == RECEIVE)
2125 debugLog ("When I get clever, I'll optimize the receive logic\n");
2127 /* if we need ptr regs for the right side
2129 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2130 <= (unsigned) PTRSIZE)
2135 /* else we assign registers to it */
2136 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2138 debugLog (" %d - \n", __LINE__);
2140 bitVectDebugOn(_G.regAssigned, debugF);
2142 for (j = 0; j < sym->nRegs; j++)
2144 if (sym->regType == REG_PTR)
2145 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2147 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2149 /* if the allocation falied which means
2150 this was spilt then break */
2154 debugLog (" %d - \n", __LINE__);
2156 /* if it shares registers with operands make sure
2157 that they are in the same position */
2158 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2159 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2160 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2161 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2162 /* do the same for the right operand */
2163 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2164 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2165 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2166 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2168 debugLog (" %d - \n", __LINE__);
2171 debugLog (" %d - \n", __LINE__);
2181 /*-----------------------------------------------------------------*/
2182 /* rUmaskForOp :- returns register mask for an operand */
2183 /*-----------------------------------------------------------------*/
2185 rUmaskForOp (operand * op)
2191 debugLog ("%s\n", __FUNCTION__);
2192 /* only temporaries are assigned registers */
2196 sym = OP_SYMBOL (op);
2198 /* if spilt or no registers assigned to it
2200 if (sym->isspilt || !sym->nRegs)
2203 rumask = newBitVect (pic14_nRegs);
2205 for (j = 0; j < sym->nRegs; j++)
2207 rumask = bitVectSetBit (rumask,
2208 sym->regs[j]->rIdx);
2214 /*-----------------------------------------------------------------*/
2215 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2216 /*-----------------------------------------------------------------*/
2218 regsUsedIniCode (iCode * ic)
2220 bitVect *rmask = newBitVect (pic14_nRegs);
2222 debugLog ("%s\n", __FUNCTION__);
2223 /* do the special cases first */
2226 rmask = bitVectUnion (rmask,
2227 rUmaskForOp (IC_COND (ic)));
2231 /* for the jumptable */
2232 if (ic->op == JUMPTABLE)
2234 rmask = bitVectUnion (rmask,
2235 rUmaskForOp (IC_JTCOND (ic)));
2240 /* of all other cases */
2242 rmask = bitVectUnion (rmask,
2243 rUmaskForOp (IC_LEFT (ic)));
2247 rmask = bitVectUnion (rmask,
2248 rUmaskForOp (IC_RIGHT (ic)));
2251 rmask = bitVectUnion (rmask,
2252 rUmaskForOp (IC_RESULT (ic)));
2258 /*-----------------------------------------------------------------*/
2259 /* createRegMask - for each instruction will determine the regsUsed */
2260 /*-----------------------------------------------------------------*/
2262 createRegMask (eBBlock ** ebbs, int count)
2266 debugLog ("%s\n", __FUNCTION__);
2267 /* for all blocks */
2268 for (i = 0; i < count; i++)
2272 if (ebbs[i]->noPath &&
2273 (ebbs[i]->entryLabel != entryLabel &&
2274 ebbs[i]->entryLabel != returnLabel))
2277 /* for all instructions */
2278 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2283 if (SKIP_IC2 (ic) || !ic->rlive)
2286 /* first mark the registers used in this
2288 ic->rUsed = regsUsedIniCode (ic);
2289 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2291 /* now create the register mask for those
2292 registers that are in use : this is a
2293 super set of ic->rUsed */
2294 ic->rMask = newBitVect (pic14_nRegs + 1);
2296 /* for all live Ranges alive at this point */
2297 for (j = 1; j < ic->rlive->size; j++)
2302 /* if not alive then continue */
2303 if (!bitVectBitValue (ic->rlive, j))
2306 /* find the live range we are interested in */
2307 if (!(sym = hTabItemWithKey (liveRanges, j)))
2309 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2310 "createRegMask cannot find live range");
2314 /* if no register assigned to it */
2315 if (!sym->nRegs || sym->isspilt)
2318 /* for all the registers allocated to it */
2319 for (k = 0; k < sym->nRegs; k++)
2322 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2328 /*-----------------------------------------------------------------*/
2329 /* rematStr - returns the rematerialized string for a remat var */
2330 /*-----------------------------------------------------------------*/
2332 rematStr (symbol * sym)
2335 iCode *ic = sym->rematiCode;
2336 symbol *psym = NULL;
2338 debugLog ("%s\n", __FUNCTION__);
2340 //printf ("%s\n", s);
2342 /* if plus or minus print the right hand side */
2344 if (ic->op == '+' || ic->op == '-') {
2346 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2348 sprintf (s, "(%s %c 0x%04x)",
2349 OP_SYMBOL (IC_LEFT (ric))->rname,
2351 (int) operandLitValue (IC_RIGHT (ic)));
2354 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2356 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2357 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2362 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2363 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2365 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2370 /*-----------------------------------------------------------------*/
2371 /* rematStr - returns the rematerialized string for a remat var */
2372 /*-----------------------------------------------------------------*/
2374 rematStr (symbol * sym)
2377 iCode *ic = sym->rematiCode;
2379 debugLog ("%s\n", __FUNCTION__);
2384 /* if plus or minus print the right hand side */
2386 if (ic->op == '+' || ic->op == '-') {
2387 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2390 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2394 if (ic->op == '+' || ic->op == '-')
2396 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2397 sprintf (s, "(%s %c 0x%04x)",
2398 OP_SYMBOL (IC_LEFT (ric))->rname,
2400 (int) operandLitValue (IC_RIGHT (ic)));
2403 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2405 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2409 /* we reached the end */
2410 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2414 printf ("%s\n", buffer);
2419 /*-----------------------------------------------------------------*/
2420 /* regTypeNum - computes the type & number of registers required */
2421 /*-----------------------------------------------------------------*/
2429 debugLog ("%s\n", __FUNCTION__);
2430 /* for each live range do */
2431 for (sym = hTabFirstItem (liveRanges, &k); sym;
2432 sym = hTabNextItem (liveRanges, &k)) {
2434 debugLog (" %d - %s\n", __LINE__, sym->rname);
2436 /* if used zero times then no registers needed */
2437 if ((sym->liveTo - sym->liveFrom) == 0)
2441 /* if the live range is a temporary */
2444 debugLog (" %d - itemp register\n", __LINE__);
2446 /* if the type is marked as a conditional */
2447 if (sym->regType == REG_CND)
2450 /* if used in return only then we don't
2453 if (IS_AGGREGATE (sym->type) || sym->isptr)
2454 sym->type = aggrToPtr (sym->type, FALSE);
2455 debugLog (" %d - no reg needed - accumulator used\n", __LINE__);
2461 //if (IS_AGGREGATE (sym->type) || sym->isptr)
2462 // sym->type = aggrToPtr (sym->type, FALSE);
2463 debugLog (" %d - used as a return\n", __LINE__);
2468 /* if the symbol has only one definition &
2469 that definition is a get_pointer and the
2470 pointer we are getting is rematerializable and
2473 if (bitVectnBitsOn (sym->defs) == 1 &&
2474 (ic = hTabItemWithKey (iCodehTab,
2475 bitVectFirstBit (sym->defs))) &&
2478 !IS_BITVAR (sym->etype)) {
2481 debugLog (" %d - \n", __LINE__);
2483 /* if remat in data space */
2484 if (OP_SYMBOL (IC_LEFT (ic))->remat &&
2485 DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) {
2487 /* create a psuedo symbol & force a spil */
2488 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2489 symbol *psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2490 psym->type = sym->type;
2491 psym->etype = sym->etype;
2492 strcpy (psym->rname, psym->name);
2494 sym->usl.spillLoc = psym;
2498 /* if in data space or idata space then try to
2499 allocate pointer register */
2503 /* if not then we require registers */
2504 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2505 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2506 getSize (sym->type));
2509 if(IS_PTR_CONST (sym->type)) {
2510 debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2514 if (sym->nRegs > 4) {
2515 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2516 printTypeChain (sym->type, stderr);
2517 fprintf (stderr, "\n");
2520 /* determine the type of register required */
2521 if (sym->nRegs == 1 &&
2522 IS_PTR (sym->type) &&
2524 sym->regType = REG_PTR;
2526 sym->regType = REG_GPR;
2529 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2533 /* for the first run we don't provide */
2534 /* registers for true symbols we will */
2535 /* see how things go */
2540 DEFSETFUNC (markRegFree)
2542 ((regs *)item)->isFree = 1;
2547 DEFSETFUNC (deallocReg)
2549 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2550 ((regs *)item)->isFree = 1;
2551 ((regs *)item)->wasUsed = 0;
2555 /*-----------------------------------------------------------------*/
2556 /* freeAllRegs - mark all registers as free */
2557 /*-----------------------------------------------------------------*/
2559 pic14_freeAllRegs ()
2563 debugLog ("%s\n", __FUNCTION__);
2565 applyToSet(dynAllocRegs,markRegFree);
2566 applyToSet(dynStackRegs,markRegFree);
2569 for (i = 0; i < pic14_nRegs; i++)
2570 regspic14[i].isFree = 1;
2574 /*-----------------------------------------------------------------*/
2575 /*-----------------------------------------------------------------*/
2577 pic14_deallocateAllRegs ()
2581 debugLog ("%s\n", __FUNCTION__);
2583 applyToSet(dynAllocRegs,deallocReg);
2586 for (i = 0; i < pic14_nRegs; i++) {
2587 if(regspic14[i].pc_type == PO_GPR_TEMP) {
2588 regspic14[i].isFree = 1;
2589 regspic14[i].wasUsed = 0;
2596 /*-----------------------------------------------------------------*/
2597 /* deallocStackSpil - this will set the stack pointer back */
2598 /*-----------------------------------------------------------------*/
2600 DEFSETFUNC (deallocStackSpil)
2604 debugLog ("%s\n", __FUNCTION__);
2609 /*-----------------------------------------------------------------*/
2610 /* farSpacePackable - returns the packable icode for far variables */
2611 /*-----------------------------------------------------------------*/
2613 farSpacePackable (iCode * ic)
2617 debugLog ("%s\n", __FUNCTION__);
2618 /* go thru till we find a definition for the
2619 symbol on the right */
2620 for (dic = ic->prev; dic; dic = dic->prev)
2623 /* if the definition is a call then no */
2624 if ((dic->op == CALL || dic->op == PCALL) &&
2625 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2630 /* if shift by unknown amount then not */
2631 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2632 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2635 /* if pointer get and size > 1 */
2636 if (POINTER_GET (dic) &&
2637 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2640 if (POINTER_SET (dic) &&
2641 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2644 /* if any three is a true symbol in far space */
2645 if (IC_RESULT (dic) &&
2646 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2647 isOperandInFarSpace (IC_RESULT (dic)))
2650 if (IC_RIGHT (dic) &&
2651 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2652 isOperandInFarSpace (IC_RIGHT (dic)) &&
2653 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2656 if (IC_LEFT (dic) &&
2657 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2658 isOperandInFarSpace (IC_LEFT (dic)) &&
2659 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2662 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2664 if ((dic->op == LEFT_OP ||
2665 dic->op == RIGHT_OP ||
2667 IS_OP_LITERAL (IC_RIGHT (dic)))
2677 /*-----------------------------------------------------------------*/
2678 /* packRegsForAssign - register reduction for assignment */
2679 /*-----------------------------------------------------------------*/
2681 packRegsForAssign (iCode * ic, eBBlock * ebp)
2686 debugLog ("%s\n", __FUNCTION__);
2688 debugAopGet (" result:", IC_RESULT (ic));
2689 debugAopGet (" left:", IC_LEFT (ic));
2690 debugAopGet (" right:", IC_RIGHT (ic));
2692 /* if this is at an absolute address, then get the address. */
2693 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2694 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2695 debugLog (" %d - found config word declaration\n", __LINE__);
2696 if(IS_VALOP(IC_RIGHT(ic))) {
2697 debugLog (" setting config word to %x\n",
2698 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2699 assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2700 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2703 /* remove the assignment from the iCode chain. */
2705 remiCodeFromeBBlock (ebp, ic);
2706 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2707 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2714 if (!IS_ITEMP (IC_RESULT (ic))) {
2715 allocDirReg(IC_RESULT (ic));
2716 debugLog (" %d - result is not temp\n", __LINE__);
2719 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2720 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2721 allocDirReg(IC_LEFT (ic));
2725 if (!IS_ITEMP (IC_RIGHT (ic))) {
2726 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2728 /* only pack if this is not a function pointer */
2729 if (!IS_REF (IC_RIGHT (ic)))
2730 allocDirReg(IC_RIGHT (ic));
2734 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2735 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2737 debugLog (" %d - not packing - right side fails \n", __LINE__);
2741 /* if the true symbol is defined in far space or on stack
2742 then we should not since this will increase register pressure */
2743 if (isOperandInFarSpace (IC_RESULT (ic)))
2745 if ((dic = farSpacePackable (ic)))
2751 /* find the definition of iTempNN scanning backwards if we find a
2752 a use of the true symbol before we find the definition then
2754 for (dic = ic->prev; dic; dic = dic->prev)
2757 /* if there is a function call and this is
2758 a parameter & not my parameter then don't pack it */
2759 if ((dic->op == CALL || dic->op == PCALL) &&
2760 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2761 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2763 debugLog (" %d - \n", __LINE__);
2771 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2772 IS_OP_VOLATILE (IC_RESULT (dic)))
2774 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2779 if (IS_SYMOP (IC_RESULT (dic)) &&
2780 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2782 /* A previous result was assigned to the same register - we'll our definition */
2783 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2784 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2785 if (POINTER_SET (dic))
2791 if (IS_SYMOP (IC_RIGHT (dic)) &&
2792 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2793 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2795 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
2800 if (IS_SYMOP (IC_LEFT (dic)) &&
2801 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2802 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2804 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
2809 if (POINTER_SET (dic) &&
2810 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2812 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
2820 return 0; /* did not find */
2822 /* if the result is on stack or iaccess then it must be
2823 the same atleast one of the operands */
2824 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2825 OP_SYMBOL (IC_RESULT (ic))->iaccess)
2828 /* the operation has only one symbol
2829 operator then we can pack */
2830 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2831 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2834 if (!((IC_LEFT (dic) &&
2835 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2837 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2841 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2842 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
2843 /* found the definition */
2844 /* replace the result with the result of */
2845 /* this assignment and remove this assignment */
2846 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2847 IC_RESULT (dic) = IC_RESULT (ic);
2849 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2851 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2853 /* delete from liverange table also
2854 delete from all the points inbetween and the new
2856 for (sic = dic; sic != ic; sic = sic->next)
2858 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2859 if (IS_ITEMP (IC_RESULT (dic)))
2860 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2863 remiCodeFromeBBlock (ebp, ic);
2864 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2865 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2866 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2872 /*-----------------------------------------------------------------*/
2873 /* findAssignToSym : scanning backwards looks for first assig found */
2874 /*-----------------------------------------------------------------*/
2876 findAssignToSym (operand * op, iCode * ic)
2880 debugLog ("%s\n", __FUNCTION__);
2881 for (dic = ic->prev; dic; dic = dic->prev)
2884 /* if definition by assignment */
2885 if (dic->op == '=' &&
2886 !POINTER_SET (dic) &&
2887 IC_RESULT (dic)->key == op->key
2888 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2892 /* we are interested only if defined in far space */
2893 /* or in stack space in case of + & - */
2895 /* if assigned to a non-symbol then return
2897 if (!IS_SYMOP (IC_RIGHT (dic)))
2900 /* if the symbol is in far space then
2902 if (isOperandInFarSpace (IC_RIGHT (dic)))
2905 /* for + & - operations make sure that
2906 if it is on the stack it is the same
2907 as one of the three operands */
2908 if ((ic->op == '+' || ic->op == '-') &&
2909 OP_SYMBOL (IC_RIGHT (dic))->onStack)
2912 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2913 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2914 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2922 /* if we find an usage then we cannot delete it */
2923 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2926 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2929 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2933 /* now make sure that the right side of dic
2934 is not defined between ic & dic */
2937 iCode *sic = dic->next;
2939 for (; sic != ic; sic = sic->next)
2940 if (IC_RESULT (sic) &&
2941 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2950 /*-----------------------------------------------------------------*/
2951 /* packRegsForSupport :- reduce some registers for support calls */
2952 /*-----------------------------------------------------------------*/
2954 packRegsForSupport (iCode * ic, eBBlock * ebp)
2958 debugLog ("%s\n", __FUNCTION__);
2959 /* for the left & right operand :- look to see if the
2960 left was assigned a true symbol in far space in that
2961 case replace them */
2962 if (IS_ITEMP (IC_LEFT (ic)) &&
2963 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2965 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
2971 debugAopGet ("removing left:", IC_LEFT (ic));
2973 /* found it we need to remove it from the
2975 for (sic = dic; sic != ic; sic = sic->next)
2976 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
2978 IC_LEFT (ic)->operand.symOperand =
2979 IC_RIGHT (dic)->operand.symOperand;
2980 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2981 remiCodeFromeBBlock (ebp, dic);
2982 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2983 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2987 /* do the same for the right operand */
2990 IS_ITEMP (IC_RIGHT (ic)) &&
2991 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2993 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2999 /* if this is a subtraction & the result
3000 is a true symbol in far space then don't pack */
3001 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3003 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3004 if (IN_FARSPACE (SPEC_OCLS (etype)))
3008 debugAopGet ("removing right:", IC_RIGHT (ic));
3010 /* found it we need to remove it from the
3012 for (sic = dic; sic != ic; sic = sic->next)
3013 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3015 IC_RIGHT (ic)->operand.symOperand =
3016 IC_RIGHT (dic)->operand.symOperand;
3017 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3019 remiCodeFromeBBlock (ebp, dic);
3020 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3021 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3028 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3031 /*-----------------------------------------------------------------*/
3032 /* packRegsForOneuse : - will reduce some registers for single Use */
3033 /*-----------------------------------------------------------------*/
3035 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3040 debugLog ("%s\n", __FUNCTION__);
3041 /* if returning a literal then do nothing */
3045 /* only upto 2 bytes since we cannot predict
3046 the usage of b, & acc */
3047 if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
3052 /* this routine will mark the a symbol as used in one
3053 instruction use only && if the definition is local
3054 (ie. within the basic block) && has only one definition &&
3055 that definition is either a return value from a
3056 function or does not contain any variables in
3058 uses = bitVectCopy (OP_USES (op));
3059 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3060 if (!bitVectIsZero (uses)) /* has other uses */
3063 /* if it has only one defintion */
3064 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3065 return NULL; /* has more than one definition */
3067 /* get that definition */
3069 hTabItemWithKey (iCodehTab,
3070 bitVectFirstBit (OP_DEFS (op)))))
3073 /* found the definition now check if it is local */
3074 if (dic->seq < ebp->fSeq ||
3075 dic->seq > ebp->lSeq)
3076 return NULL; /* non-local */
3078 /* now check if it is the return from
3080 if (dic->op == CALL || dic->op == PCALL)
3082 if (ic->op != SEND && ic->op != RETURN &&
3083 !POINTER_SET(ic) && !POINTER_GET(ic))
3085 OP_SYMBOL (op)->ruonly = 1;
3092 /* otherwise check that the definition does
3093 not contain any symbols in far space */
3094 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3095 isOperandInFarSpace (IC_RIGHT (dic)) ||
3096 IS_OP_RUONLY (IC_LEFT (ic)) ||
3097 IS_OP_RUONLY (IC_RIGHT (ic)))
3102 /* if pointer set then make sure the pointer
3104 if (POINTER_SET (dic) &&
3105 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3108 if (POINTER_GET (dic) &&
3109 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3114 /* also make sure the intervenening instructions
3115 don't have any thing in far space */
3116 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3119 /* if there is an intervening function call then no */
3120 if (dic->op == CALL || dic->op == PCALL)
3122 /* if pointer set then make sure the pointer
3124 if (POINTER_SET (dic) &&
3125 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3128 if (POINTER_GET (dic) &&
3129 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3132 /* if address of & the result is remat then okay */
3133 if (dic->op == ADDRESS_OF &&
3134 OP_SYMBOL (IC_RESULT (dic))->remat)
3137 /* if operand has size of three or more & this
3138 operation is a '*','/' or '%' then 'b' may
3140 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3141 getSize (operandType (op)) >= 3)
3144 /* if left or right or result is in far space */
3145 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3146 isOperandInFarSpace (IC_RIGHT (dic)) ||
3147 isOperandInFarSpace (IC_RESULT (dic)) ||
3148 IS_OP_RUONLY (IC_LEFT (dic)) ||
3149 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3150 IS_OP_RUONLY (IC_RESULT (dic)))
3156 OP_SYMBOL (op)->ruonly = 1;
3161 /*-----------------------------------------------------------------*/
3162 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3163 /*-----------------------------------------------------------------*/
3165 isBitwiseOptimizable (iCode * ic)
3167 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3168 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3170 debugLog ("%s\n", __FUNCTION__);
3171 /* bitwise operations are considered optimizable
3172 under the following conditions (Jean-Louis VERN)
3184 if (IS_LITERAL (rtype) ||
3185 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3191 /*-----------------------------------------------------------------*/
3192 /* packRegsForAccUse - pack registers for acc use */
3193 /*-----------------------------------------------------------------*/
3195 packRegsForAccUse (iCode * ic)
3199 debugLog ("%s\n", __FUNCTION__);
3201 /* if this is an aggregate, e.g. a one byte char array */
3202 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3205 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3207 /* if + or - then it has to be one byte result */
3208 if ((ic->op == '+' || ic->op == '-')
3209 && getSize (operandType (IC_RESULT (ic))) > 1)
3212 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3213 /* if shift operation make sure right side is not a literal */
3214 if (ic->op == RIGHT_OP &&
3215 (isOperandLiteral (IC_RIGHT (ic)) ||
3216 getSize (operandType (IC_RESULT (ic))) > 1))
3219 if (ic->op == LEFT_OP &&
3220 (isOperandLiteral (IC_RIGHT (ic)) ||
3221 getSize (operandType (IC_RESULT (ic))) > 1))
3224 if (IS_BITWISE_OP (ic) &&
3225 getSize (operandType (IC_RESULT (ic))) > 1)
3229 /* has only one definition */
3230 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3233 /* has only one use */
3234 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3237 /* and the usage immediately follows this iCode */
3238 if (!(uic = hTabItemWithKey (iCodehTab,
3239 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3242 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3243 if (ic->next != uic)
3246 /* if it is a conditional branch then we definitely can */
3250 if (uic->op == JUMPTABLE)
3253 /* if the usage is not is an assignment
3254 or an arithmetic / bitwise / shift operation then not */
3255 if (POINTER_SET (uic) &&
3256 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3259 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3260 if (uic->op != '=' &&
3261 !IS_ARITHMETIC_OP (uic) &&
3262 !IS_BITWISE_OP (uic) &&
3263 uic->op != LEFT_OP &&
3264 uic->op != RIGHT_OP)
3267 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3268 /* if used in ^ operation then make sure right is not a
3270 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3273 /* if shift operation make sure right side is not a literal */
3274 if (uic->op == RIGHT_OP &&
3275 (isOperandLiteral (IC_RIGHT (uic)) ||
3276 getSize (operandType (IC_RESULT (uic))) > 1))
3279 if (uic->op == LEFT_OP &&
3280 (isOperandLiteral (IC_RIGHT (uic)) ||
3281 getSize (operandType (IC_RESULT (uic))) > 1))
3284 /* make sure that the result of this icode is not on the
3285 stack, since acc is used to compute stack offset */
3286 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3287 OP_SYMBOL (IC_RESULT (uic))->onStack)
3290 /* if either one of them in far space then we cannot */
3291 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3292 isOperandInFarSpace (IC_LEFT (uic))) ||
3293 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3294 isOperandInFarSpace (IC_RIGHT (uic))))
3297 /* if the usage has only one operand then we can */
3298 if (IC_LEFT (uic) == NULL ||
3299 IC_RIGHT (uic) == NULL)
3302 /* make sure this is on the left side if not
3303 a '+' since '+' is commutative */
3304 if (ic->op != '+' &&
3305 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3308 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3309 /* if one of them is a literal then we can */
3310 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3311 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3312 (getSize (operandType (IC_RESULT (uic))) <= 1))
3314 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3318 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3319 /* if the other one is not on stack then we can */
3320 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3321 (IS_ITEMP (IC_RIGHT (uic)) ||
3322 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3323 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3326 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3327 (IS_ITEMP (IC_LEFT (uic)) ||
3328 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3329 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3335 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3336 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3341 /*-----------------------------------------------------------------*/
3342 /* packForPush - hueristics to reduce iCode for pushing */
3343 /*-----------------------------------------------------------------*/
3345 packForReceive (iCode * ic, eBBlock * ebp)
3349 debugLog ("%s\n", __FUNCTION__);
3350 debugAopGet (" result:", IC_RESULT (ic));
3351 debugAopGet (" left:", IC_LEFT (ic));
3352 debugAopGet (" right:", IC_RIGHT (ic));
3357 for (dic = ic->next; dic; dic = dic->next)
3362 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3363 debugLog (" used on left\n");
3364 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3365 debugLog (" used on right\n");
3366 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3367 debugLog (" used on result\n");
3369 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3370 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3375 debugLog (" hey we can remove this unnecessary assign\n");
3377 /*-----------------------------------------------------------------*/
3378 /* packForPush - hueristics to reduce iCode for pushing */
3379 /*-----------------------------------------------------------------*/
3381 packForPush (iCode * ic, eBBlock * ebp)
3385 debugLog ("%s\n", __FUNCTION__);
3386 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3389 /* must have only definition & one usage */
3390 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3391 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3394 /* find the definition */
3395 if (!(dic = hTabItemWithKey (iCodehTab,
3396 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3399 if (dic->op != '=' || POINTER_SET (dic))
3402 /* we now we know that it has one & only one def & use
3403 and the that the definition is an assignment */
3404 IC_LEFT (ic) = IC_RIGHT (dic);
3406 remiCodeFromeBBlock (ebp, dic);
3407 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3408 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3411 void printSymType(char * str, sym_link *sl)
3413 debugLog (" %s Symbol type: ",str);
3414 printTypeChain( sl, debugF);
3419 /*-----------------------------------------------------------------*/
3420 /* some debug code to print the symbol S_TYPE. Note that
3421 * the function checkSClass in src/SDCCsymt.c dinks with
3422 * the S_TYPE in ways the PIC port doesn't fully like...*/
3423 /*-----------------------------------------------------------------*/
3424 void isData(sym_link *sl)
3434 for ( ; sl; sl=sl->next) {
3436 switch (SPEC_SCLS(sl)) {
3438 case S_DATA: fprintf (of, "data "); break;
3439 case S_XDATA: fprintf (of, "xdata "); break;
3440 case S_SFR: fprintf (of, "sfr "); break;
3441 case S_SBIT: fprintf (of, "sbit "); break;
3442 case S_CODE: fprintf (of, "code "); break;
3443 case S_IDATA: fprintf (of, "idata "); break;
3444 case S_PDATA: fprintf (of, "pdata "); break;
3445 case S_LITERAL: fprintf (of, "literal "); break;
3446 case S_STACK: fprintf (of, "stack "); break;
3447 case S_XSTACK: fprintf (of, "xstack "); break;
3448 case S_BIT: fprintf (of, "bit "); break;
3449 case S_EEPROM: fprintf (of, "eeprom "); break;
3458 /*-----------------------------------------------------------------*/
3459 /* packRegisters - does some transformations to reduce register */
3461 /*-----------------------------------------------------------------*/
3463 packRegisters (eBBlock * ebp)
3468 debugLog ("%s\n", __FUNCTION__);
3474 /* look for assignments of the form */
3475 /* iTempNN = TRueSym (someoperation) SomeOperand */
3477 /* TrueSym := iTempNN:1 */
3478 for (ic = ebp->sch; ic; ic = ic->next)
3481 /* find assignment of the form TrueSym := iTempNN:1 */
3482 if (ic->op == '=' && !POINTER_SET (ic))
3483 change += packRegsForAssign (ic, ebp);
3487 if (POINTER_SET (ic))
3488 debugLog ("pointer is set\n");
3489 debugAopGet (" result:", IC_RESULT (ic));
3490 debugAopGet (" left:", IC_LEFT (ic));
3491 debugAopGet (" right:", IC_RIGHT (ic));
3500 for (ic = ebp->sch; ic; ic = ic->next) {
3502 if(IS_SYMOP ( IC_LEFT(ic))) {
3503 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3505 debugAopGet (" left:", IC_LEFT (ic));
3506 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3507 debugLog (" is a pointer\n");
3509 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3510 debugLog (" is volatile\n");
3514 printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
3517 if(IS_SYMOP ( IC_RIGHT(ic))) {
3518 debugAopGet (" right:", IC_RIGHT (ic));
3519 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3522 if(IS_SYMOP ( IC_RESULT(ic))) {
3523 debugAopGet (" result:", IC_RESULT (ic));
3524 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3527 if (POINTER_SET (ic))
3528 debugLog (" %d - Pointer set\n", __LINE__);
3531 /* if this is an itemp & result of a address of a true sym
3532 then mark this as rematerialisable */
3533 if (ic->op == ADDRESS_OF &&
3534 IS_ITEMP (IC_RESULT (ic)) &&
3535 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3536 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3537 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3540 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3542 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3543 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3544 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3548 /* if straight assignment then carry remat flag if
3549 this is the only definition */
3550 if (ic->op == '=' &&
3551 !POINTER_SET (ic) &&
3552 IS_SYMOP (IC_RIGHT (ic)) &&
3553 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3554 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3556 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3558 OP_SYMBOL (IC_RESULT (ic))->remat =
3559 OP_SYMBOL (IC_RIGHT (ic))->remat;
3560 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3561 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3564 /* if this is a +/- operation with a rematerizable
3565 then mark this as rematerializable as well */
3566 if ((ic->op == '+' || ic->op == '-') &&
3567 (IS_SYMOP (IC_LEFT (ic)) &&
3568 IS_ITEMP (IC_RESULT (ic)) &&
3569 OP_SYMBOL (IC_LEFT (ic))->remat &&
3570 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3571 IS_OP_LITERAL (IC_RIGHT (ic))))
3573 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3575 operandLitValue (IC_RIGHT (ic));
3576 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3577 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3578 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3581 /* mark the pointer usages */
3582 if (POINTER_SET (ic))
3584 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3585 debugLog (" marking as a pointer (set) =>");
3586 debugAopGet (" result:", IC_RESULT (ic));
3588 if (POINTER_GET (ic))
3590 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3591 debugLog (" marking as a pointer (get) =>");
3592 debugAopGet (" left:", IC_LEFT (ic));
3597 /* if we are using a symbol on the stack
3598 then we should say pic14_ptrRegReq */
3599 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3600 pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3601 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3602 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3603 pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3604 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3607 if (IS_SYMOP (IC_LEFT (ic)))
3608 pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3609 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3610 if (IS_SYMOP (IC_RIGHT (ic)))
3611 pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3612 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3613 if (IS_SYMOP (IC_RESULT (ic)))
3614 pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3615 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3618 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
3622 /* if the condition of an if instruction
3623 is defined in the previous instruction then
3624 mark the itemp as a conditional */
3625 if ((IS_CONDITIONAL (ic) ||
3626 ((ic->op == BITWISEAND ||
3629 isBitwiseOptimizable (ic))) &&
3630 ic->next && ic->next->op == IFX &&
3631 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3632 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3635 debugLog (" %d\n", __LINE__);
3636 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3640 /* reduce for support function calls */
3641 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3642 packRegsForSupport (ic, ebp);
3644 /* if a parameter is passed, it's in W, so we may not
3645 need to place a copy in a register */
3646 if (ic->op == RECEIVE)
3647 packForReceive (ic, ebp);
3649 /* some cases the redundant moves can
3650 can be eliminated for return statements */
3651 if ((ic->op == RETURN || ic->op == SEND) &&
3652 !isOperandInFarSpace (IC_LEFT (ic)) &&
3654 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3656 /* if pointer set & left has a size more than
3657 one and right is not in far space */
3658 if (POINTER_SET (ic) &&
3659 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3660 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3661 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3662 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3664 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3666 /* if pointer get */
3667 if (POINTER_GET (ic) &&
3668 !isOperandInFarSpace (IC_RESULT (ic)) &&
3669 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3670 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3671 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3673 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3676 /* if this is cast for intergral promotion then
3677 check if only use of the definition of the
3678 operand being casted/ if yes then replace
3679 the result of that arithmetic operation with
3680 this result and get rid of the cast */
3681 if (ic->op == CAST) {
3683 sym_link *fromType = operandType (IC_RIGHT (ic));
3684 sym_link *toType = operandType (IC_LEFT (ic));
3686 debugLog (" %d - casting\n", __LINE__);
3688 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3689 getSize (fromType) != getSize (toType)) {
3692 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3695 if (IS_ARITHMETIC_OP (dic)) {
3697 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3698 IC_RESULT (dic) = IC_RESULT (ic);
3699 remiCodeFromeBBlock (ebp, ic);
3700 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3701 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3702 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3706 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3710 /* if the type from and type to are the same
3711 then if this is the only use then packit */
3712 if (compareType (operandType (IC_RIGHT (ic)),
3713 operandType (IC_LEFT (ic))) == 1) {
3715 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3718 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3719 IC_RESULT (dic) = IC_RESULT (ic);
3720 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3721 remiCodeFromeBBlock (ebp, ic);
3722 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3723 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3731 iTempNN := (some variable in farspace) V1
3736 if (ic->op == IPUSH)
3738 packForPush (ic, ebp);
3742 /* pack registers for accumulator use, when the
3743 result of an arithmetic or bit wise operation
3744 has only one use, that use is immediately following
3745 the defintion and the using iCode has only one
3746 operand or has two operands but one is literal &
3747 the result of that operation is not on stack then
3748 we can leave the result of this operation in acc:b
3750 if ((IS_ARITHMETIC_OP (ic)
3752 || IS_BITWISE_OP (ic)
3754 || ic->op == LEFT_OP || ic->op == RIGHT_OP
3757 IS_ITEMP (IC_RESULT (ic)) &&
3758 getSize (operandType (IC_RESULT (ic))) <= 2)
3760 packRegsForAccUse (ic);
3766 dumpEbbsToDebug (eBBlock ** ebbs, int count)
3770 if (!debug || !debugF)
3773 for (i = 0; i < count; i++)
3775 fprintf (debugF, "\n----------------------------------------------------------------\n");
3776 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
3777 ebbs[i]->entryLabel->name,
3780 ebbs[i]->isLastInLoop);
3781 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
3786 fprintf (debugF, "visited %d : hasFcall = %d\n",
3790 fprintf (debugF, "\ndefines bitVector :");
3791 bitVectDebugOn (ebbs[i]->defSet, debugF);
3792 fprintf (debugF, "\nlocal defines bitVector :");
3793 bitVectDebugOn (ebbs[i]->ldefs, debugF);
3794 fprintf (debugF, "\npointers Set bitvector :");
3795 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
3796 fprintf (debugF, "\nin pointers Set bitvector :");
3797 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
3798 fprintf (debugF, "\ninDefs Set bitvector :");
3799 bitVectDebugOn (ebbs[i]->inDefs, debugF);
3800 fprintf (debugF, "\noutDefs Set bitvector :");
3801 bitVectDebugOn (ebbs[i]->outDefs, debugF);
3802 fprintf (debugF, "\nusesDefs Set bitvector :");
3803 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
3804 fprintf (debugF, "\n----------------------------------------------------------------\n");
3805 printiCChain (ebbs[i]->sch, debugF);
3808 /*-----------------------------------------------------------------*/
3809 /* assignRegisters - assigns registers to each live range as need */
3810 /*-----------------------------------------------------------------*/
3812 pic14_assignRegisters (eBBlock ** ebbs, int count)
3817 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
3818 debugLog ("\nebbs before optimizing:\n");
3819 dumpEbbsToDebug (ebbs, count);
3821 setToNull ((void *) &_G.funcrUsed);
3822 pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3825 /* change assignments this will remove some
3826 live ranges reducing some register pressure */
3827 for (i = 0; i < count; i++)
3828 packRegisters (ebbs[i]);
3835 debugLog("dir registers allocated so far:\n");
3836 reg = hTabFirstItem(dynDirectRegNames, &hkey);
3839 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
3840 reg = hTabNextItem(dynDirectRegNames, &hkey);
3845 if (options.dump_pack)
3846 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3848 /* first determine for each live range the number of
3849 registers & the type of registers required for each */
3852 /* and serially allocate registers */
3853 serialRegAssign (ebbs, count);
3855 /* if stack was extended then tell the user */
3858 /* werror(W_TOOMANY_SPILS,"stack", */
3859 /* _G.stackExtend,currFunc->name,""); */
3865 /* werror(W_TOOMANY_SPILS,"data space", */
3866 /* _G.dataExtend,currFunc->name,""); */
3870 /* after that create the register mask
3871 for each of the instruction */
3872 createRegMask (ebbs, count);
3874 /* redo that offsets for stacked automatic variables */
3875 redoStackOffsets ();
3877 if (options.dump_rassgn)
3878 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3880 /* now get back the chain */
3881 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3883 debugLog ("ebbs after optimizing:\n");
3884 dumpEbbsToDebug (ebbs, count);
3889 /* free up any _G.stackSpil locations allocated */
3890 applyToSet (_G.stackSpil, deallocStackSpil);
3892 setToNull ((void **) &_G.stackSpil);
3893 setToNull ((void **) &_G.spiltSet);
3894 /* mark all registers as free */
3895 //pic14_freeAllRegs ();
3897 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");