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 sprintf (buffer, "0x%02x", breg->address);
982 //fprintf(stderr,"new bit field\n");
983 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0);
984 bitfield->isBitField = 1;
985 bitfield->isFixed = 1;
986 bitfield->address = breg->address;
987 //addSet(&dynDirectRegs,bitfield);
988 addSet(&dynInternalRegs,bitfield);
989 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
991 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
994 breg->reg_alias = bitfield;
998 if(!relocbitfield || bit_no >7) {
1001 sprintf (buffer, "bitfield%d", byte_no);
1002 //fprintf(stderr,"new relocatable bit field\n");
1003 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0);
1004 relocbitfield->isBitField = 1;
1005 //addSet(&dynDirectRegs,relocbitfield);
1006 addSet(&dynInternalRegs,relocbitfield);
1007 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1011 breg->reg_alias = relocbitfield;
1012 breg->address = rDirectIdx; /* byte_no; */
1013 breg->rIdx = bit_no++;
1021 void bitEQUs(FILE *of, set *bregs)
1023 regs *breg,*bytereg;
1026 //fprintf(stderr," %s\n",__FUNCTION__);
1027 for (breg = setFirstItem(bregs) ; breg ;
1028 breg = setNextItem(bregs)) {
1030 //fprintf(stderr,"bit reg: %s\n",breg->name);
1032 bytereg = breg->reg_alias;
1034 fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
1037 breg->rIdx & 0x0007);
1040 //fprintf(stderr, "bit field is not assigned to a register\n");
1041 fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
1051 void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
1056 for (reg = setFirstItem(fregs) ; reg ;
1057 reg = setNextItem(fregs)) {
1059 //if(!reg->isEmitted && reg->wasUsed) {
1062 fprintf (of, "%s\tEQU\t0x%03x\n",
1066 fprintf (of, "%s\tEQU\t0x%03x\n",
1074 void writeUsedRegs(FILE *of)
1076 packBits(dynDirectBitRegs);
1078 assignFixedRegisters(dynAllocRegs);
1079 assignFixedRegisters(dynStackRegs);
1080 assignFixedRegisters(dynDirectRegs);
1082 assignRelocatableRegisters(dynInternalRegs,0);
1083 assignRelocatableRegisters(dynAllocRegs,0);
1084 assignRelocatableRegisters(dynStackRegs,0);
1087 assignRelocatableRegisters(dynDirectRegs,0);
1088 printf("assignRelocatableRegisters(dynDirectRegs,0);\n");
1093 bitEQUs(of,dynDirectBitRegs);
1095 aliasEQUs(of,dynAllocRegs,0);
1096 aliasEQUs(of,dynDirectRegs,0);
1097 aliasEQUs(of,dynStackRegs,0);
1098 aliasEQUs(of,dynProcessorRegs,1);
1103 /*-----------------------------------------------------------------*/
1104 /* allDefsOutOfRange - all definitions are out of a range */
1105 /*-----------------------------------------------------------------*/
1107 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
1111 debugLog ("%s\n", __FUNCTION__);
1115 for (i = 0; i < defs->size; i++)
1119 if (bitVectBitValue (defs, i) &&
1120 (ic = hTabItemWithKey (iCodehTab, i)) &&
1121 (ic->seq >= fseq && ic->seq <= toseq))
1131 /*-----------------------------------------------------------------*/
1132 /* computeSpillable - given a point find the spillable live ranges */
1133 /*-----------------------------------------------------------------*/
1135 computeSpillable (iCode * ic)
1139 debugLog ("%s\n", __FUNCTION__);
1140 /* spillable live ranges are those that are live at this
1141 point . the following categories need to be subtracted
1143 a) - those that are already spilt
1144 b) - if being used by this one
1145 c) - defined by this one */
1147 spillable = bitVectCopy (ic->rlive);
1149 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1151 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1152 bitVectUnSetBit (spillable, ic->defKey);
1153 spillable = bitVectIntersect (spillable, _G.regAssigned);
1158 /*-----------------------------------------------------------------*/
1159 /* noSpilLoc - return true if a variable has no spil location */
1160 /*-----------------------------------------------------------------*/
1162 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1164 debugLog ("%s\n", __FUNCTION__);
1165 return (sym->usl.spillLoc ? 0 : 1);
1168 /*-----------------------------------------------------------------*/
1169 /* hasSpilLoc - will return 1 if the symbol has spil location */
1170 /*-----------------------------------------------------------------*/
1172 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1174 debugLog ("%s\n", __FUNCTION__);
1175 return (sym->usl.spillLoc ? 1 : 0);
1178 /*-----------------------------------------------------------------*/
1179 /* directSpilLoc - will return 1 if the splilocation is in direct */
1180 /*-----------------------------------------------------------------*/
1182 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1184 debugLog ("%s\n", __FUNCTION__);
1185 if (sym->usl.spillLoc &&
1186 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1192 /*-----------------------------------------------------------------*/
1193 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1194 /* but is not used as a pointer */
1195 /*-----------------------------------------------------------------*/
1197 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1199 debugLog ("%s\n", __FUNCTION__);
1200 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1203 /*-----------------------------------------------------------------*/
1204 /* rematable - will return 1 if the remat flag is set */
1205 /*-----------------------------------------------------------------*/
1207 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1209 debugLog ("%s\n", __FUNCTION__);
1213 /*-----------------------------------------------------------------*/
1214 /* notUsedInRemaining - not used or defined in remain of the block */
1215 /*-----------------------------------------------------------------*/
1217 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1219 debugLog ("%s\n", __FUNCTION__);
1220 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1221 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1224 /*-----------------------------------------------------------------*/
1225 /* allLRs - return true for all */
1226 /*-----------------------------------------------------------------*/
1228 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1230 debugLog ("%s\n", __FUNCTION__);
1234 /*-----------------------------------------------------------------*/
1235 /* liveRangesWith - applies function to a given set of live range */
1236 /*-----------------------------------------------------------------*/
1238 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1239 eBBlock * ebp, iCode * ic)
1244 debugLog ("%s\n", __FUNCTION__);
1245 if (!lrs || !lrs->size)
1248 for (i = 1; i < lrs->size; i++)
1251 if (!bitVectBitValue (lrs, i))
1254 /* if we don't find it in the live range
1255 hash table we are in serious trouble */
1256 if (!(sym = hTabItemWithKey (liveRanges, i)))
1258 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1259 "liveRangesWith could not find liveRange");
1263 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1264 addSetHead (&rset, sym);
1271 /*-----------------------------------------------------------------*/
1272 /* leastUsedLR - given a set determines which is the least used */
1273 /*-----------------------------------------------------------------*/
1275 leastUsedLR (set * sset)
1277 symbol *sym = NULL, *lsym = NULL;
1279 debugLog ("%s\n", __FUNCTION__);
1280 sym = lsym = setFirstItem (sset);
1285 for (; lsym; lsym = setNextItem (sset))
1288 /* if usage is the same then prefer
1289 the spill the smaller of the two */
1290 if (lsym->used == sym->used)
1291 if (getSize (lsym->type) < getSize (sym->type))
1295 if (lsym->used < sym->used)
1300 setToNull ((void **) &sset);
1305 /*-----------------------------------------------------------------*/
1306 /* noOverLap - will iterate through the list looking for over lap */
1307 /*-----------------------------------------------------------------*/
1309 noOverLap (set * itmpStack, symbol * fsym)
1312 debugLog ("%s\n", __FUNCTION__);
1315 for (sym = setFirstItem (itmpStack); sym;
1316 sym = setNextItem (itmpStack))
1318 if (sym->liveTo > fsym->liveFrom)
1326 /*-----------------------------------------------------------------*/
1327 /* isFree - will return 1 if the a free spil location is found */
1328 /*-----------------------------------------------------------------*/
1333 V_ARG (symbol **, sloc);
1334 V_ARG (symbol *, fsym);
1336 debugLog ("%s\n", __FUNCTION__);
1337 /* if already found */
1341 /* if it is free && and the itmp assigned to
1342 this does not have any overlapping live ranges
1343 with the one currently being assigned and
1344 the size can be accomodated */
1346 noOverLap (sym->usl.itmpStack, fsym) &&
1347 getSize (sym->type) >= getSize (fsym->type))
1356 /*-----------------------------------------------------------------*/
1357 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1358 /*-----------------------------------------------------------------*/
1360 spillLRWithPtrReg (symbol * forSym)
1366 debugLog ("%s\n", __FUNCTION__);
1367 if (!_G.regAssigned ||
1368 bitVectIsZero (_G.regAssigned))
1371 r0 = pic14_regWithIdx (R0_IDX);
1372 r1 = pic14_regWithIdx (R1_IDX);
1374 /* for all live ranges */
1375 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1376 lrsym = hTabNextItem (liveRanges, &k))
1380 /* if no registers assigned to it or
1382 /* if it does not overlap with this then
1383 not need to spill it */
1385 if (lrsym->isspilt || !lrsym->nRegs ||
1386 (lrsym->liveTo < forSym->liveFrom))
1389 /* go thru the registers : if it is either
1390 r0 or r1 then spil it */
1391 for (j = 0; j < lrsym->nRegs; j++)
1392 if (lrsym->regs[j] == r0 ||
1393 lrsym->regs[j] == r1)
1402 /*-----------------------------------------------------------------*/
1403 /* createStackSpil - create a location on the stack to spil */
1404 /*-----------------------------------------------------------------*/
1406 createStackSpil (symbol * sym)
1408 symbol *sloc = NULL;
1409 int useXstack, model, noOverlay;
1411 char slocBuffer[30];
1412 debugLog ("%s\n", __FUNCTION__);
1414 /* first go try and find a free one that is already
1415 existing on the stack */
1416 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1418 /* found a free one : just update & return */
1419 sym->usl.spillLoc = sloc;
1422 addSetHead (&sloc->usl.itmpStack, sym);
1426 /* could not then have to create one , this is the hard part
1427 we need to allocate this on the stack : this is really a
1428 hack!! but cannot think of anything better at this time */
1430 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1432 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1433 __FILE__, __LINE__);
1437 sloc = newiTemp (slocBuffer);
1439 /* set the type to the spilling symbol */
1440 sloc->type = copyLinkChain (sym->type);
1441 sloc->etype = getSpec (sloc->type);
1442 SPEC_SCLS (sloc->etype) = S_DATA;
1443 SPEC_EXTR (sloc->etype) = 0;
1444 SPEC_STAT (sloc->etype) = 0;
1446 /* we don't allow it to be allocated`
1447 onto the external stack since : so we
1448 temporarily turn it off ; we also
1449 turn off memory model to prevent
1450 the spil from going to the external storage
1451 and turn off overlaying
1454 useXstack = options.useXstack;
1455 model = options.model;
1456 noOverlay = options.noOverlay;
1457 options.noOverlay = 1;
1458 options.model = options.useXstack = 0;
1462 options.useXstack = useXstack;
1463 options.model = model;
1464 options.noOverlay = noOverlay;
1465 sloc->isref = 1; /* to prevent compiler warning */
1467 /* if it is on the stack then update the stack */
1468 if (IN_STACK (sloc->etype))
1470 currFunc->stack += getSize (sloc->type);
1471 _G.stackExtend += getSize (sloc->type);
1474 _G.dataExtend += getSize (sloc->type);
1476 /* add it to the _G.stackSpil set */
1477 addSetHead (&_G.stackSpil, sloc);
1478 sym->usl.spillLoc = sloc;
1481 /* add it to the set of itempStack set
1482 of the spill location */
1483 addSetHead (&sloc->usl.itmpStack, sym);
1487 /*-----------------------------------------------------------------*/
1488 /* isSpiltOnStack - returns true if the spil location is on stack */
1489 /*-----------------------------------------------------------------*/
1491 isSpiltOnStack (symbol * sym)
1495 debugLog ("%s\n", __FUNCTION__);
1502 /* if (sym->_G.stackSpil) */
1505 if (!sym->usl.spillLoc)
1508 etype = getSpec (sym->usl.spillLoc->type);
1509 if (IN_STACK (etype))
1515 /*-----------------------------------------------------------------*/
1516 /* spillThis - spils a specific operand */
1517 /*-----------------------------------------------------------------*/
1519 spillThis (symbol * sym)
1522 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1524 /* if this is rematerializable or has a spillLocation
1525 we are okay, else we need to create a spillLocation
1527 if (!(sym->remat || sym->usl.spillLoc))
1528 createStackSpil (sym);
1531 /* mark it has spilt & put it in the spilt set */
1533 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1535 bitVectUnSetBit (_G.regAssigned, sym->key);
1537 for (i = 0; i < sym->nRegs; i++)
1541 freeReg (sym->regs[i]);
1542 sym->regs[i] = NULL;
1545 /* if spilt on stack then free up r0 & r1
1546 if they could have been assigned to some
1548 if (!pic14_ptrRegReq && isSpiltOnStack (sym))
1551 spillLRWithPtrReg (sym);
1554 if (sym->usl.spillLoc && !sym->remat)
1555 sym->usl.spillLoc->allocreq = 1;
1559 /*-----------------------------------------------------------------*/
1560 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1561 /*-----------------------------------------------------------------*/
1563 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1565 bitVect *lrcs = NULL;
1569 debugLog ("%s\n", __FUNCTION__);
1570 /* get the spillable live ranges */
1571 lrcs = computeSpillable (ic);
1573 /* get all live ranges that are rematerizable */
1574 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1577 /* return the least used of these */
1578 return leastUsedLR (selectS);
1581 /* get live ranges with spillLocations in direct space */
1582 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1584 sym = leastUsedLR (selectS);
1585 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1586 sym->usl.spillLoc->rname :
1587 sym->usl.spillLoc->name));
1589 /* mark it as allocation required */
1590 sym->usl.spillLoc->allocreq = 1;
1594 /* if the symbol is local to the block then */
1595 if (forSym->liveTo < ebp->lSeq)
1598 /* check if there are any live ranges allocated
1599 to registers that are not used in this block */
1600 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1602 sym = leastUsedLR (selectS);
1603 /* if this is not rematerializable */
1612 /* check if there are any live ranges that not
1613 used in the remainder of the block */
1614 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1616 sym = leastUsedLR (selectS);
1619 sym->remainSpil = 1;
1626 /* find live ranges with spillocation && not used as pointers */
1627 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1630 sym = leastUsedLR (selectS);
1631 /* mark this as allocation required */
1632 sym->usl.spillLoc->allocreq = 1;
1636 /* find live ranges with spillocation */
1637 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1640 sym = leastUsedLR (selectS);
1641 sym->usl.spillLoc->allocreq = 1;
1645 /* couldn't find then we need to create a spil
1646 location on the stack , for which one? the least
1648 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1651 /* return a created spil location */
1652 sym = createStackSpil (leastUsedLR (selectS));
1653 sym->usl.spillLoc->allocreq = 1;
1657 /* this is an extreme situation we will spill
1658 this one : happens very rarely but it does happen */
1664 /*-----------------------------------------------------------------*/
1665 /* spilSomething - spil some variable & mark registers as free */
1666 /*-----------------------------------------------------------------*/
1668 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1673 debugLog ("%s\n", __FUNCTION__);
1674 /* get something we can spil */
1675 ssym = selectSpil (ic, ebp, forSym);
1677 /* mark it as spilt */
1679 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1681 /* mark it as not register assigned &
1682 take it away from the set */
1683 bitVectUnSetBit (_G.regAssigned, ssym->key);
1685 /* mark the registers as free */
1686 for (i = 0; i < ssym->nRegs; i++)
1688 freeReg (ssym->regs[i]);
1690 /* if spilt on stack then free up r0 & r1
1691 if they could have been assigned to as gprs */
1692 if (!pic14_ptrRegReq && isSpiltOnStack (ssym))
1695 spillLRWithPtrReg (ssym);
1698 /* if this was a block level spil then insert push & pop
1699 at the start & end of block respectively */
1700 if (ssym->blockSpil)
1702 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1703 /* add push to the start of the block */
1704 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1705 ebp->sch->next : ebp->sch));
1706 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1707 /* add pop to the end of the block */
1708 addiCodeToeBBlock (ebp, nic, NULL);
1711 /* if spilt because not used in the remainder of the
1712 block then add a push before this instruction and
1713 a pop at the end of the block */
1714 if (ssym->remainSpil)
1717 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1718 /* add push just before this instruction */
1719 addiCodeToeBBlock (ebp, nic, ic);
1721 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1722 /* add pop to the end of the block */
1723 addiCodeToeBBlock (ebp, nic, NULL);
1732 /*-----------------------------------------------------------------*/
1733 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1734 /*-----------------------------------------------------------------*/
1736 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1740 debugLog ("%s\n", __FUNCTION__);
1742 /* try for a ptr type */
1743 if ((reg = allocReg (REG_PTR)))
1746 /* try for gpr type */
1747 if ((reg = allocReg (REG_GPR)))
1750 /* we have to spil */
1751 if (!spilSomething (ic, ebp, sym))
1754 /* this looks like an infinite loop but
1755 in really selectSpil will abort */
1759 /*-----------------------------------------------------------------*/
1760 /* getRegGpr - will try for GPR if not spil */
1761 /*-----------------------------------------------------------------*/
1763 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1767 debugLog ("%s\n", __FUNCTION__);
1769 /* try for gpr type */
1770 if ((reg = allocReg (REG_GPR)))
1773 if (!pic14_ptrRegReq)
1774 if ((reg = allocReg (REG_PTR)))
1777 /* we have to spil */
1778 if (!spilSomething (ic, ebp, sym))
1781 /* this looks like an infinite loop but
1782 in really selectSpil will abort */
1786 /*-----------------------------------------------------------------*/
1787 /* symHasReg - symbol has a given register */
1788 /*-----------------------------------------------------------------*/
1790 symHasReg (symbol * sym, regs * reg)
1794 debugLog ("%s\n", __FUNCTION__);
1795 for (i = 0; i < sym->nRegs; i++)
1796 if (sym->regs[i] == reg)
1802 /*-----------------------------------------------------------------*/
1803 /* deassignLRs - check the live to and if they have registers & are */
1804 /* not spilt then free up the registers */
1805 /*-----------------------------------------------------------------*/
1807 deassignLRs (iCode * ic, eBBlock * ebp)
1813 debugLog ("%s\n", __FUNCTION__);
1814 for (sym = hTabFirstItem (liveRanges, &k); sym;
1815 sym = hTabNextItem (liveRanges, &k))
1818 symbol *psym = NULL;
1819 /* if it does not end here */
1820 if (sym->liveTo > ic->seq)
1823 /* if it was spilt on stack then we can
1824 mark the stack spil location as free */
1829 sym->usl.spillLoc->isFree = 1;
1835 if (!bitVectBitValue (_G.regAssigned, sym->key))
1838 /* special case check if this is an IFX &
1839 the privious one was a pop and the
1840 previous one was not spilt then keep track
1842 if (ic->op == IFX && ic->prev &&
1843 ic->prev->op == IPOP &&
1844 !ic->prev->parmPush &&
1845 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1846 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1852 bitVectUnSetBit (_G.regAssigned, sym->key);
1854 /* if the result of this one needs registers
1855 and does not have it then assign it right
1857 if (IC_RESULT (ic) &&
1858 !(SKIP_IC2 (ic) || /* not a special icode */
1859 ic->op == JUMPTABLE ||
1864 POINTER_SET (ic)) &&
1865 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1866 result->liveTo > ic->seq && /* and will live beyond this */
1867 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1868 result->regType == sym->regType && /* same register types */
1869 result->nRegs && /* which needs registers */
1870 !result->isspilt && /* and does not already have them */
1872 !bitVectBitValue (_G.regAssigned, result->key) &&
1873 /* the number of free regs + number of regs in this LR
1874 can accomodate the what result Needs */
1875 ((nfreeRegsType (result->regType) +
1876 sym->nRegs) >= result->nRegs)
1880 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1882 result->regs[i] = sym->regs[i];
1884 result->regs[i] = getRegGpr (ic, ebp, result);
1886 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1890 /* free the remaining */
1891 for (; i < sym->nRegs; i++)
1895 if (!symHasReg (psym, sym->regs[i]))
1896 freeReg (sym->regs[i]);
1899 freeReg (sym->regs[i]);
1906 /*-----------------------------------------------------------------*/
1907 /* reassignLR - reassign this to registers */
1908 /*-----------------------------------------------------------------*/
1910 reassignLR (operand * op)
1912 symbol *sym = OP_SYMBOL (op);
1915 debugLog ("%s\n", __FUNCTION__);
1916 /* not spilt any more */
1917 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1918 bitVectUnSetBit (_G.spiltSet, sym->key);
1920 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1924 for (i = 0; i < sym->nRegs; i++)
1925 sym->regs[i]->isFree = 0;
1928 /*-----------------------------------------------------------------*/
1929 /* willCauseSpill - determines if allocating will cause a spill */
1930 /*-----------------------------------------------------------------*/
1932 willCauseSpill (int nr, int rt)
1934 debugLog ("%s\n", __FUNCTION__);
1935 /* first check if there are any avlb registers
1936 of te type required */
1939 /* special case for pointer type
1940 if pointer type not avlb then
1941 check for type gpr */
1942 if (nFreeRegs (rt) >= nr)
1944 if (nFreeRegs (REG_GPR) >= nr)
1949 if (pic14_ptrRegReq)
1951 if (nFreeRegs (rt) >= nr)
1956 if (nFreeRegs (REG_PTR) +
1957 nFreeRegs (REG_GPR) >= nr)
1962 debugLog (" ... yep it will (cause a spill)\n");
1963 /* it will cause a spil */
1967 /*-----------------------------------------------------------------*/
1968 /* positionRegs - the allocator can allocate same registers to res- */
1969 /* ult and operand, if this happens make sure they are in the same */
1970 /* position as the operand otherwise chaos results */
1971 /*-----------------------------------------------------------------*/
1973 positionRegs (symbol * result, symbol * opsym, int lineno)
1975 int count = min (result->nRegs, opsym->nRegs);
1976 int i, j = 0, shared = 0;
1978 debugLog ("%s\n", __FUNCTION__);
1979 /* if the result has been spilt then cannot share */
1984 /* first make sure that they actually share */
1985 for (i = 0; i < count; i++)
1987 for (j = 0; j < count; j++)
1989 if (result->regs[i] == opsym->regs[j] && i != j)
1999 regs *tmp = result->regs[i];
2000 result->regs[i] = result->regs[j];
2001 result->regs[j] = tmp;
2006 /*-----------------------------------------------------------------*/
2007 /* serialRegAssign - serially allocate registers to the variables */
2008 /*-----------------------------------------------------------------*/
2010 serialRegAssign (eBBlock ** ebbs, int count)
2014 debugLog ("%s\n", __FUNCTION__);
2015 /* for all blocks */
2016 for (i = 0; i < count; i++)
2021 if (ebbs[i]->noPath &&
2022 (ebbs[i]->entryLabel != entryLabel &&
2023 ebbs[i]->entryLabel != returnLabel))
2026 /* of all instructions do */
2027 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2030 debugLog (" op: %s\n", decodeOp (ic->op));
2032 /* if this is an ipop that means some live
2033 range will have to be assigned again */
2035 reassignLR (IC_LEFT (ic));
2037 /* if result is present && is a true symbol */
2038 if (IC_RESULT (ic) && ic->op != IFX &&
2039 IS_TRUE_SYMOP (IC_RESULT (ic)))
2040 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2042 /* take away registers from live
2043 ranges that end at this instruction */
2044 deassignLRs (ic, ebbs[i]);
2046 /* some don't need registers */
2047 if (SKIP_IC2 (ic) ||
2048 ic->op == JUMPTABLE ||
2052 (IC_RESULT (ic) && POINTER_SET (ic)))
2055 /* now we need to allocate registers
2056 only for the result */
2059 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2065 /* if it does not need or is spilt
2066 or is already assigned to registers
2067 or will not live beyond this instructions */
2070 bitVectBitValue (_G.regAssigned, sym->key) ||
2071 sym->liveTo <= ic->seq)
2074 /* if some liverange has been spilt at the block level
2075 and this one live beyond this block then spil this
2077 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2082 /* if trying to allocate this will cause
2083 a spill and there is nothing to spill
2084 or this one is rematerializable then
2086 willCS = willCauseSpill (sym->nRegs, sym->regType);
2087 spillable = computeSpillable (ic);
2089 (willCS && bitVectIsZero (spillable)))
2097 /* if it has a spillocation & is used less than
2098 all other live ranges then spill this */
2100 if (sym->usl.spillLoc) {
2101 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2102 allLRs, ebbs[i], ic));
2103 if (leastUsed && leastUsed->used > sym->used) {
2108 /* if none of the liveRanges have a spillLocation then better
2109 to spill this one than anything else already assigned to registers */
2110 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2111 /* if this is local to this block then we might find a block spil */
2112 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2120 if (ic->op == RECEIVE)
2121 debugLog ("When I get clever, I'll optimize the receive logic\n");
2123 /* if we need ptr regs for the right side
2125 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2126 <= (unsigned) PTRSIZE)
2131 /* else we assign registers to it */
2132 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2134 debugLog (" %d - \n", __LINE__);
2136 bitVectDebugOn(_G.regAssigned, debugF);
2138 for (j = 0; j < sym->nRegs; j++)
2140 if (sym->regType == REG_PTR)
2141 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2143 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2145 /* if the allocation falied which means
2146 this was spilt then break */
2150 debugLog (" %d - \n", __LINE__);
2152 /* if it shares registers with operands make sure
2153 that they are in the same position */
2154 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2155 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2156 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2157 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2158 /* do the same for the right operand */
2159 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2160 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2161 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2162 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2164 debugLog (" %d - \n", __LINE__);
2167 debugLog (" %d - \n", __LINE__);
2177 /*-----------------------------------------------------------------*/
2178 /* rUmaskForOp :- returns register mask for an operand */
2179 /*-----------------------------------------------------------------*/
2181 rUmaskForOp (operand * op)
2187 debugLog ("%s\n", __FUNCTION__);
2188 /* only temporaries are assigned registers */
2192 sym = OP_SYMBOL (op);
2194 /* if spilt or no registers assigned to it
2196 if (sym->isspilt || !sym->nRegs)
2199 rumask = newBitVect (pic14_nRegs);
2201 for (j = 0; j < sym->nRegs; j++)
2203 rumask = bitVectSetBit (rumask,
2204 sym->regs[j]->rIdx);
2210 /*-----------------------------------------------------------------*/
2211 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2212 /*-----------------------------------------------------------------*/
2214 regsUsedIniCode (iCode * ic)
2216 bitVect *rmask = newBitVect (pic14_nRegs);
2218 debugLog ("%s\n", __FUNCTION__);
2219 /* do the special cases first */
2222 rmask = bitVectUnion (rmask,
2223 rUmaskForOp (IC_COND (ic)));
2227 /* for the jumptable */
2228 if (ic->op == JUMPTABLE)
2230 rmask = bitVectUnion (rmask,
2231 rUmaskForOp (IC_JTCOND (ic)));
2236 /* of all other cases */
2238 rmask = bitVectUnion (rmask,
2239 rUmaskForOp (IC_LEFT (ic)));
2243 rmask = bitVectUnion (rmask,
2244 rUmaskForOp (IC_RIGHT (ic)));
2247 rmask = bitVectUnion (rmask,
2248 rUmaskForOp (IC_RESULT (ic)));
2254 /*-----------------------------------------------------------------*/
2255 /* createRegMask - for each instruction will determine the regsUsed */
2256 /*-----------------------------------------------------------------*/
2258 createRegMask (eBBlock ** ebbs, int count)
2262 debugLog ("%s\n", __FUNCTION__);
2263 /* for all blocks */
2264 for (i = 0; i < count; i++)
2268 if (ebbs[i]->noPath &&
2269 (ebbs[i]->entryLabel != entryLabel &&
2270 ebbs[i]->entryLabel != returnLabel))
2273 /* for all instructions */
2274 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2279 if (SKIP_IC2 (ic) || !ic->rlive)
2282 /* first mark the registers used in this
2284 ic->rUsed = regsUsedIniCode (ic);
2285 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2287 /* now create the register mask for those
2288 registers that are in use : this is a
2289 super set of ic->rUsed */
2290 ic->rMask = newBitVect (pic14_nRegs + 1);
2292 /* for all live Ranges alive at this point */
2293 for (j = 1; j < ic->rlive->size; j++)
2298 /* if not alive then continue */
2299 if (!bitVectBitValue (ic->rlive, j))
2302 /* find the live range we are interested in */
2303 if (!(sym = hTabItemWithKey (liveRanges, j)))
2305 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2306 "createRegMask cannot find live range");
2310 /* if no register assigned to it */
2311 if (!sym->nRegs || sym->isspilt)
2314 /* for all the registers allocated to it */
2315 for (k = 0; k < sym->nRegs; k++)
2318 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2324 /*-----------------------------------------------------------------*/
2325 /* rematStr - returns the rematerialized string for a remat var */
2326 /*-----------------------------------------------------------------*/
2328 rematStr (symbol * sym)
2331 iCode *ic = sym->rematiCode;
2332 symbol *psym = NULL;
2334 debugLog ("%s\n", __FUNCTION__);
2336 //printf ("%s\n", s);
2338 /* if plus or minus print the right hand side */
2340 if (ic->op == '+' || ic->op == '-') {
2342 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2344 sprintf (s, "(%s %c 0x%04x)",
2345 OP_SYMBOL (IC_LEFT (ric))->rname,
2347 (int) operandLitValue (IC_RIGHT (ic)));
2350 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2352 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2353 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2358 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2359 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2361 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2366 /*-----------------------------------------------------------------*/
2367 /* rematStr - returns the rematerialized string for a remat var */
2368 /*-----------------------------------------------------------------*/
2370 rematStr (symbol * sym)
2373 iCode *ic = sym->rematiCode;
2375 debugLog ("%s\n", __FUNCTION__);
2380 /* if plus or minus print the right hand side */
2382 if (ic->op == '+' || ic->op == '-') {
2383 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2386 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2390 if (ic->op == '+' || ic->op == '-')
2392 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2393 sprintf (s, "(%s %c 0x%04x)",
2394 OP_SYMBOL (IC_LEFT (ric))->rname,
2396 (int) operandLitValue (IC_RIGHT (ic)));
2399 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2401 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2405 /* we reached the end */
2406 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2410 printf ("%s\n", buffer);
2415 /*-----------------------------------------------------------------*/
2416 /* regTypeNum - computes the type & number of registers required */
2417 /*-----------------------------------------------------------------*/
2425 debugLog ("%s\n", __FUNCTION__);
2426 /* for each live range do */
2427 for (sym = hTabFirstItem (liveRanges, &k); sym;
2428 sym = hTabNextItem (liveRanges, &k)) {
2430 debugLog (" %d - %s\n", __LINE__, sym->rname);
2432 /* if used zero times then no registers needed */
2433 if ((sym->liveTo - sym->liveFrom) == 0)
2437 /* if the live range is a temporary */
2440 debugLog (" %d - itemp register\n", __LINE__);
2442 /* if the type is marked as a conditional */
2443 if (sym->regType == REG_CND)
2446 /* if used in return only then we don't
2449 if (IS_AGGREGATE (sym->type) || sym->isptr)
2450 sym->type = aggrToPtr (sym->type, FALSE);
2451 debugLog (" %d - no reg needed - accumulator used\n", __LINE__);
2457 //if (IS_AGGREGATE (sym->type) || sym->isptr)
2458 // sym->type = aggrToPtr (sym->type, FALSE);
2459 debugLog (" %d - used as a return\n", __LINE__);
2464 /* if the symbol has only one definition &
2465 that definition is a get_pointer and the
2466 pointer we are getting is rematerializable and
2469 if (bitVectnBitsOn (sym->defs) == 1 &&
2470 (ic = hTabItemWithKey (iCodehTab,
2471 bitVectFirstBit (sym->defs))) &&
2474 !IS_BITVAR (sym->etype)) {
2477 debugLog (" %d - \n", __LINE__);
2479 /* if remat in data space */
2480 if (OP_SYMBOL (IC_LEFT (ic))->remat &&
2481 DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) {
2483 /* create a psuedo symbol & force a spil */
2484 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2485 symbol *psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2486 psym->type = sym->type;
2487 psym->etype = sym->etype;
2488 strcpy (psym->rname, psym->name);
2490 sym->usl.spillLoc = psym;
2494 /* if in data space or idata space then try to
2495 allocate pointer register */
2499 /* if not then we require registers */
2500 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2501 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2502 getSize (sym->type));
2505 if(IS_PTR_CONST (sym->type)) {
2506 debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2510 if (sym->nRegs > 4) {
2511 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2512 printTypeChain (sym->type, stderr);
2513 fprintf (stderr, "\n");
2516 /* determine the type of register required */
2517 if (sym->nRegs == 1 &&
2518 IS_PTR (sym->type) &&
2520 sym->regType = REG_PTR;
2522 sym->regType = REG_GPR;
2525 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2529 /* for the first run we don't provide */
2530 /* registers for true symbols we will */
2531 /* see how things go */
2536 DEFSETFUNC (markRegFree)
2538 ((regs *)item)->isFree = 1;
2543 DEFSETFUNC (deallocReg)
2545 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2546 ((regs *)item)->isFree = 1;
2547 ((regs *)item)->wasUsed = 0;
2551 /*-----------------------------------------------------------------*/
2552 /* freeAllRegs - mark all registers as free */
2553 /*-----------------------------------------------------------------*/
2555 pic14_freeAllRegs ()
2559 debugLog ("%s\n", __FUNCTION__);
2561 applyToSet(dynAllocRegs,markRegFree);
2562 applyToSet(dynStackRegs,markRegFree);
2565 for (i = 0; i < pic14_nRegs; i++)
2566 regspic14[i].isFree = 1;
2570 /*-----------------------------------------------------------------*/
2571 /*-----------------------------------------------------------------*/
2573 pic14_deallocateAllRegs ()
2577 debugLog ("%s\n", __FUNCTION__);
2579 applyToSet(dynAllocRegs,deallocReg);
2582 for (i = 0; i < pic14_nRegs; i++) {
2583 if(regspic14[i].pc_type == PO_GPR_TEMP) {
2584 regspic14[i].isFree = 1;
2585 regspic14[i].wasUsed = 0;
2592 /*-----------------------------------------------------------------*/
2593 /* deallocStackSpil - this will set the stack pointer back */
2594 /*-----------------------------------------------------------------*/
2596 DEFSETFUNC (deallocStackSpil)
2600 debugLog ("%s\n", __FUNCTION__);
2605 /*-----------------------------------------------------------------*/
2606 /* farSpacePackable - returns the packable icode for far variables */
2607 /*-----------------------------------------------------------------*/
2609 farSpacePackable (iCode * ic)
2613 debugLog ("%s\n", __FUNCTION__);
2614 /* go thru till we find a definition for the
2615 symbol on the right */
2616 for (dic = ic->prev; dic; dic = dic->prev)
2619 /* if the definition is a call then no */
2620 if ((dic->op == CALL || dic->op == PCALL) &&
2621 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2626 /* if shift by unknown amount then not */
2627 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2628 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2631 /* if pointer get and size > 1 */
2632 if (POINTER_GET (dic) &&
2633 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2636 if (POINTER_SET (dic) &&
2637 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2640 /* if any three is a true symbol in far space */
2641 if (IC_RESULT (dic) &&
2642 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2643 isOperandInFarSpace (IC_RESULT (dic)))
2646 if (IC_RIGHT (dic) &&
2647 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2648 isOperandInFarSpace (IC_RIGHT (dic)) &&
2649 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2652 if (IC_LEFT (dic) &&
2653 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2654 isOperandInFarSpace (IC_LEFT (dic)) &&
2655 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2658 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2660 if ((dic->op == LEFT_OP ||
2661 dic->op == RIGHT_OP ||
2663 IS_OP_LITERAL (IC_RIGHT (dic)))
2673 /*-----------------------------------------------------------------*/
2674 /* packRegsForAssign - register reduction for assignment */
2675 /*-----------------------------------------------------------------*/
2677 packRegsForAssign (iCode * ic, eBBlock * ebp)
2682 debugLog ("%s\n", __FUNCTION__);
2684 debugAopGet (" result:", IC_RESULT (ic));
2685 debugAopGet (" left:", IC_LEFT (ic));
2686 debugAopGet (" right:", IC_RIGHT (ic));
2688 /* if this is at an absolute address, then get the address. */
2689 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2690 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2691 debugLog (" %d - found config word declaration\n", __LINE__);
2692 if(IS_VALOP(IC_RIGHT(ic))) {
2693 debugLog (" setting config word to %x\n",
2694 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2695 assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2696 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2699 /* remove the assignment from the iCode chain. */
2701 remiCodeFromeBBlock (ebp, ic);
2702 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2703 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2710 if (!IS_ITEMP (IC_RESULT (ic))) {
2711 allocDirReg(IC_RESULT (ic));
2712 debugLog (" %d - result is not temp\n", __LINE__);
2715 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2716 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2717 allocDirReg(IC_LEFT (ic));
2721 if (!IS_ITEMP (IC_RIGHT (ic))) {
2722 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2724 /* only pack if this is not a function pointer */
2725 if (!IS_REF (IC_RIGHT (ic)))
2726 allocDirReg(IC_RIGHT (ic));
2730 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2731 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2733 debugLog (" %d - not packing - right side fails \n", __LINE__);
2737 /* if the true symbol is defined in far space or on stack
2738 then we should not since this will increase register pressure */
2739 if (isOperandInFarSpace (IC_RESULT (ic)))
2741 if ((dic = farSpacePackable (ic)))
2747 /* find the definition of iTempNN scanning backwards if we find a
2748 a use of the true symbol before we find the definition then
2750 for (dic = ic->prev; dic; dic = dic->prev)
2753 /* if there is a function call and this is
2754 a parameter & not my parameter then don't pack it */
2755 if ((dic->op == CALL || dic->op == PCALL) &&
2756 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2757 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2759 debugLog (" %d - \n", __LINE__);
2767 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2768 IS_OP_VOLATILE (IC_RESULT (dic)))
2770 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2775 if (IS_SYMOP (IC_RESULT (dic)) &&
2776 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2778 /* A previous result was assigned to the same register - we'll our definition */
2779 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2780 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2781 if (POINTER_SET (dic))
2787 if (IS_SYMOP (IC_RIGHT (dic)) &&
2788 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2789 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2791 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
2796 if (IS_SYMOP (IC_LEFT (dic)) &&
2797 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2798 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2800 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
2805 if (POINTER_SET (dic) &&
2806 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2808 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
2816 return 0; /* did not find */
2818 /* if the result is on stack or iaccess then it must be
2819 the same atleast one of the operands */
2820 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2821 OP_SYMBOL (IC_RESULT (ic))->iaccess)
2824 /* the operation has only one symbol
2825 operator then we can pack */
2826 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2827 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2830 if (!((IC_LEFT (dic) &&
2831 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2833 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2837 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2838 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
2839 /* found the definition */
2840 /* replace the result with the result of */
2841 /* this assignment and remove this assignment */
2842 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2843 IC_RESULT (dic) = IC_RESULT (ic);
2845 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2847 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2849 /* delete from liverange table also
2850 delete from all the points inbetween and the new
2852 for (sic = dic; sic != ic; sic = sic->next)
2854 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2855 if (IS_ITEMP (IC_RESULT (dic)))
2856 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2859 remiCodeFromeBBlock (ebp, ic);
2860 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2861 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2862 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2868 /*-----------------------------------------------------------------*/
2869 /* findAssignToSym : scanning backwards looks for first assig found */
2870 /*-----------------------------------------------------------------*/
2872 findAssignToSym (operand * op, iCode * ic)
2876 debugLog ("%s\n", __FUNCTION__);
2877 for (dic = ic->prev; dic; dic = dic->prev)
2880 /* if definition by assignment */
2881 if (dic->op == '=' &&
2882 !POINTER_SET (dic) &&
2883 IC_RESULT (dic)->key == op->key
2884 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2888 /* we are interested only if defined in far space */
2889 /* or in stack space in case of + & - */
2891 /* if assigned to a non-symbol then return
2893 if (!IS_SYMOP (IC_RIGHT (dic)))
2896 /* if the symbol is in far space then
2898 if (isOperandInFarSpace (IC_RIGHT (dic)))
2901 /* for + & - operations make sure that
2902 if it is on the stack it is the same
2903 as one of the three operands */
2904 if ((ic->op == '+' || ic->op == '-') &&
2905 OP_SYMBOL (IC_RIGHT (dic))->onStack)
2908 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2909 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2910 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2918 /* if we find an usage then we cannot delete it */
2919 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2922 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2925 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2929 /* now make sure that the right side of dic
2930 is not defined between ic & dic */
2933 iCode *sic = dic->next;
2935 for (; sic != ic; sic = sic->next)
2936 if (IC_RESULT (sic) &&
2937 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2946 /*-----------------------------------------------------------------*/
2947 /* packRegsForSupport :- reduce some registers for support calls */
2948 /*-----------------------------------------------------------------*/
2950 packRegsForSupport (iCode * ic, eBBlock * ebp)
2954 debugLog ("%s\n", __FUNCTION__);
2955 /* for the left & right operand :- look to see if the
2956 left was assigned a true symbol in far space in that
2957 case replace them */
2958 if (IS_ITEMP (IC_LEFT (ic)) &&
2959 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2961 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
2967 debugAopGet ("removing left:", IC_LEFT (ic));
2969 /* found it we need to remove it from the
2971 for (sic = dic; sic != ic; sic = sic->next)
2972 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
2974 IC_LEFT (ic)->operand.symOperand =
2975 IC_RIGHT (dic)->operand.symOperand;
2976 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2977 remiCodeFromeBBlock (ebp, dic);
2978 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2979 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2983 /* do the same for the right operand */
2986 IS_ITEMP (IC_RIGHT (ic)) &&
2987 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2989 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2995 /* if this is a subtraction & the result
2996 is a true symbol in far space then don't pack */
2997 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
2999 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3000 if (IN_FARSPACE (SPEC_OCLS (etype)))
3004 debugAopGet ("removing right:", IC_RIGHT (ic));
3006 /* found it we need to remove it from the
3008 for (sic = dic; sic != ic; sic = sic->next)
3009 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3011 IC_RIGHT (ic)->operand.symOperand =
3012 IC_RIGHT (dic)->operand.symOperand;
3013 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3015 remiCodeFromeBBlock (ebp, dic);
3016 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3017 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3024 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3027 /*-----------------------------------------------------------------*/
3028 /* packRegsForOneuse : - will reduce some registers for single Use */
3029 /*-----------------------------------------------------------------*/
3031 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3036 debugLog ("%s\n", __FUNCTION__);
3037 /* if returning a literal then do nothing */
3041 /* only upto 2 bytes since we cannot predict
3042 the usage of b, & acc */
3043 if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
3048 /* this routine will mark the a symbol as used in one
3049 instruction use only && if the definition is local
3050 (ie. within the basic block) && has only one definition &&
3051 that definition is either a return value from a
3052 function or does not contain any variables in
3054 uses = bitVectCopy (OP_USES (op));
3055 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3056 if (!bitVectIsZero (uses)) /* has other uses */
3059 /* if it has only one defintion */
3060 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3061 return NULL; /* has more than one definition */
3063 /* get that definition */
3065 hTabItemWithKey (iCodehTab,
3066 bitVectFirstBit (OP_DEFS (op)))))
3069 /* found the definition now check if it is local */
3070 if (dic->seq < ebp->fSeq ||
3071 dic->seq > ebp->lSeq)
3072 return NULL; /* non-local */
3074 /* now check if it is the return from
3076 if (dic->op == CALL || dic->op == PCALL)
3078 if (ic->op != SEND && ic->op != RETURN &&
3079 !POINTER_SET(ic) && !POINTER_GET(ic))
3081 OP_SYMBOL (op)->ruonly = 1;
3088 /* otherwise check that the definition does
3089 not contain any symbols in far space */
3090 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3091 isOperandInFarSpace (IC_RIGHT (dic)) ||
3092 IS_OP_RUONLY (IC_LEFT (ic)) ||
3093 IS_OP_RUONLY (IC_RIGHT (ic)))
3098 /* if pointer set then make sure the pointer
3100 if (POINTER_SET (dic) &&
3101 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3104 if (POINTER_GET (dic) &&
3105 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3110 /* also make sure the intervenening instructions
3111 don't have any thing in far space */
3112 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3115 /* if there is an intervening function call then no */
3116 if (dic->op == CALL || dic->op == PCALL)
3118 /* if pointer set then make sure the pointer
3120 if (POINTER_SET (dic) &&
3121 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3124 if (POINTER_GET (dic) &&
3125 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3128 /* if address of & the result is remat then okay */
3129 if (dic->op == ADDRESS_OF &&
3130 OP_SYMBOL (IC_RESULT (dic))->remat)
3133 /* if operand has size of three or more & this
3134 operation is a '*','/' or '%' then 'b' may
3136 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3137 getSize (operandType (op)) >= 3)
3140 /* if left or right or result is in far space */
3141 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3142 isOperandInFarSpace (IC_RIGHT (dic)) ||
3143 isOperandInFarSpace (IC_RESULT (dic)) ||
3144 IS_OP_RUONLY (IC_LEFT (dic)) ||
3145 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3146 IS_OP_RUONLY (IC_RESULT (dic)))
3152 OP_SYMBOL (op)->ruonly = 1;
3157 /*-----------------------------------------------------------------*/
3158 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3159 /*-----------------------------------------------------------------*/
3161 isBitwiseOptimizable (iCode * ic)
3163 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3164 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3166 debugLog ("%s\n", __FUNCTION__);
3167 /* bitwise operations are considered optimizable
3168 under the following conditions (Jean-Louis VERN)
3180 if (IS_LITERAL (rtype) ||
3181 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3187 /*-----------------------------------------------------------------*/
3188 /* packRegsForAccUse - pack registers for acc use */
3189 /*-----------------------------------------------------------------*/
3191 packRegsForAccUse (iCode * ic)
3195 debugLog ("%s\n", __FUNCTION__);
3197 /* if this is an aggregate, e.g. a one byte char array */
3198 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3201 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3203 /* if + or - then it has to be one byte result */
3204 if ((ic->op == '+' || ic->op == '-')
3205 && getSize (operandType (IC_RESULT (ic))) > 1)
3208 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3209 /* if shift operation make sure right side is not a literal */
3210 if (ic->op == RIGHT_OP &&
3211 (isOperandLiteral (IC_RIGHT (ic)) ||
3212 getSize (operandType (IC_RESULT (ic))) > 1))
3215 if (ic->op == LEFT_OP &&
3216 (isOperandLiteral (IC_RIGHT (ic)) ||
3217 getSize (operandType (IC_RESULT (ic))) > 1))
3220 if (IS_BITWISE_OP (ic) &&
3221 getSize (operandType (IC_RESULT (ic))) > 1)
3225 /* has only one definition */
3226 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3229 /* has only one use */
3230 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3233 /* and the usage immediately follows this iCode */
3234 if (!(uic = hTabItemWithKey (iCodehTab,
3235 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3238 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3239 if (ic->next != uic)
3242 /* if it is a conditional branch then we definitely can */
3246 if (uic->op == JUMPTABLE)
3249 /* if the usage is not is an assignment
3250 or an arithmetic / bitwise / shift operation then not */
3251 if (POINTER_SET (uic) &&
3252 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3255 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3256 if (uic->op != '=' &&
3257 !IS_ARITHMETIC_OP (uic) &&
3258 !IS_BITWISE_OP (uic) &&
3259 uic->op != LEFT_OP &&
3260 uic->op != RIGHT_OP)
3263 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3264 /* if used in ^ operation then make sure right is not a
3266 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3269 /* if shift operation make sure right side is not a literal */
3270 if (uic->op == RIGHT_OP &&
3271 (isOperandLiteral (IC_RIGHT (uic)) ||
3272 getSize (operandType (IC_RESULT (uic))) > 1))
3275 if (uic->op == LEFT_OP &&
3276 (isOperandLiteral (IC_RIGHT (uic)) ||
3277 getSize (operandType (IC_RESULT (uic))) > 1))
3280 /* make sure that the result of this icode is not on the
3281 stack, since acc is used to compute stack offset */
3282 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3283 OP_SYMBOL (IC_RESULT (uic))->onStack)
3286 /* if either one of them in far space then we cannot */
3287 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3288 isOperandInFarSpace (IC_LEFT (uic))) ||
3289 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3290 isOperandInFarSpace (IC_RIGHT (uic))))
3293 /* if the usage has only one operand then we can */
3294 if (IC_LEFT (uic) == NULL ||
3295 IC_RIGHT (uic) == NULL)
3298 /* make sure this is on the left side if not
3299 a '+' since '+' is commutative */
3300 if (ic->op != '+' &&
3301 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3304 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3305 /* if one of them is a literal then we can */
3306 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3307 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3308 (getSize (operandType (IC_RESULT (uic))) <= 1))
3310 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3314 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3315 /* if the other one is not on stack then we can */
3316 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3317 (IS_ITEMP (IC_RIGHT (uic)) ||
3318 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3319 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3322 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3323 (IS_ITEMP (IC_LEFT (uic)) ||
3324 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3325 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3331 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3332 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3337 /*-----------------------------------------------------------------*/
3338 /* packForPush - hueristics to reduce iCode for pushing */
3339 /*-----------------------------------------------------------------*/
3341 packForReceive (iCode * ic, eBBlock * ebp)
3345 debugLog ("%s\n", __FUNCTION__);
3346 debugAopGet (" result:", IC_RESULT (ic));
3347 debugAopGet (" left:", IC_LEFT (ic));
3348 debugAopGet (" right:", IC_RIGHT (ic));
3353 for (dic = ic->next; dic; dic = dic->next)
3358 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3359 debugLog (" used on left\n");
3360 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3361 debugLog (" used on right\n");
3362 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3363 debugLog (" used on result\n");
3365 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3366 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3371 debugLog (" hey we can remove this unnecessary assign\n");
3373 /*-----------------------------------------------------------------*/
3374 /* packForPush - hueristics to reduce iCode for pushing */
3375 /*-----------------------------------------------------------------*/
3377 packForPush (iCode * ic, eBBlock * ebp)
3381 debugLog ("%s\n", __FUNCTION__);
3382 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3385 /* must have only definition & one usage */
3386 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3387 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3390 /* find the definition */
3391 if (!(dic = hTabItemWithKey (iCodehTab,
3392 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3395 if (dic->op != '=' || POINTER_SET (dic))
3398 /* we now we know that it has one & only one def & use
3399 and the that the definition is an assignment */
3400 IC_LEFT (ic) = IC_RIGHT (dic);
3402 remiCodeFromeBBlock (ebp, dic);
3403 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3404 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3407 void printSymType(char * str, sym_link *sl)
3409 debugLog (" %s Symbol type: ",str);
3410 printTypeChain( sl, debugF);
3415 /*-----------------------------------------------------------------*/
3416 /* some debug code to print the symbol S_TYPE. Note that
3417 * the function checkSClass in src/SDCCsymt.c dinks with
3418 * the S_TYPE in ways the PIC port doesn't fully like...*/
3419 /*-----------------------------------------------------------------*/
3420 void isData(sym_link *sl)
3430 for ( ; sl; sl=sl->next) {
3432 switch (SPEC_SCLS(sl)) {
3434 case S_DATA: fprintf (of, "data "); break;
3435 case S_XDATA: fprintf (of, "xdata "); break;
3436 case S_SFR: fprintf (of, "sfr "); break;
3437 case S_SBIT: fprintf (of, "sbit "); break;
3438 case S_CODE: fprintf (of, "code "); break;
3439 case S_IDATA: fprintf (of, "idata "); break;
3440 case S_PDATA: fprintf (of, "pdata "); break;
3441 case S_LITERAL: fprintf (of, "literal "); break;
3442 case S_STACK: fprintf (of, "stack "); break;
3443 case S_XSTACK: fprintf (of, "xstack "); break;
3444 case S_BIT: fprintf (of, "bit "); break;
3445 case S_EEPROM: fprintf (of, "eeprom "); break;
3454 /*-----------------------------------------------------------------*/
3455 /* packRegisters - does some transformations to reduce register */
3457 /*-----------------------------------------------------------------*/
3459 packRegisters (eBBlock * ebp)
3464 debugLog ("%s\n", __FUNCTION__);
3470 /* look for assignments of the form */
3471 /* iTempNN = TRueSym (someoperation) SomeOperand */
3473 /* TrueSym := iTempNN:1 */
3474 for (ic = ebp->sch; ic; ic = ic->next)
3477 /* find assignment of the form TrueSym := iTempNN:1 */
3478 if (ic->op == '=' && !POINTER_SET (ic))
3479 change += packRegsForAssign (ic, ebp);
3483 if (POINTER_SET (ic))
3484 debugLog ("pointer is set\n");
3485 debugAopGet (" result:", IC_RESULT (ic));
3486 debugAopGet (" left:", IC_LEFT (ic));
3487 debugAopGet (" right:", IC_RIGHT (ic));
3496 for (ic = ebp->sch; ic; ic = ic->next) {
3498 if(IS_SYMOP ( IC_LEFT(ic))) {
3499 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3501 debugAopGet (" left:", IC_LEFT (ic));
3502 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3503 debugLog (" is a pointer\n");
3505 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3506 debugLog (" is volatile\n");
3510 printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
3513 if(IS_SYMOP ( IC_RIGHT(ic))) {
3514 debugAopGet (" right:", IC_RIGHT (ic));
3515 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3518 if(IS_SYMOP ( IC_RESULT(ic))) {
3519 debugAopGet (" result:", IC_RESULT (ic));
3520 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3523 if (POINTER_SET (ic))
3524 debugLog (" %d - Pointer set\n", __LINE__);
3527 /* if this is an itemp & result of a address of a true sym
3528 then mark this as rematerialisable */
3529 if (ic->op == ADDRESS_OF &&
3530 IS_ITEMP (IC_RESULT (ic)) &&
3531 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3532 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3533 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3536 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3538 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3539 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3540 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3544 /* if straight assignment then carry remat flag if
3545 this is the only definition */
3546 if (ic->op == '=' &&
3547 !POINTER_SET (ic) &&
3548 IS_SYMOP (IC_RIGHT (ic)) &&
3549 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3550 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3552 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3554 OP_SYMBOL (IC_RESULT (ic))->remat =
3555 OP_SYMBOL (IC_RIGHT (ic))->remat;
3556 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3557 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3560 /* if this is a +/- operation with a rematerizable
3561 then mark this as rematerializable as well */
3562 if ((ic->op == '+' || ic->op == '-') &&
3563 (IS_SYMOP (IC_LEFT (ic)) &&
3564 IS_ITEMP (IC_RESULT (ic)) &&
3565 OP_SYMBOL (IC_LEFT (ic))->remat &&
3566 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3567 IS_OP_LITERAL (IC_RIGHT (ic))))
3569 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3571 operandLitValue (IC_RIGHT (ic));
3572 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3573 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3574 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3577 /* mark the pointer usages */
3578 if (POINTER_SET (ic))
3580 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3581 debugLog (" marking as a pointer (set) =>");
3582 debugAopGet (" result:", IC_RESULT (ic));
3584 if (POINTER_GET (ic))
3586 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3587 debugLog (" marking as a pointer (get) =>");
3588 debugAopGet (" left:", IC_LEFT (ic));
3593 /* if we are using a symbol on the stack
3594 then we should say pic14_ptrRegReq */
3595 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3596 pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3597 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3598 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3599 pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3600 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3603 if (IS_SYMOP (IC_LEFT (ic)))
3604 pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3605 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3606 if (IS_SYMOP (IC_RIGHT (ic)))
3607 pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3608 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3609 if (IS_SYMOP (IC_RESULT (ic)))
3610 pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3611 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3614 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
3618 /* if the condition of an if instruction
3619 is defined in the previous instruction then
3620 mark the itemp as a conditional */
3621 if ((IS_CONDITIONAL (ic) ||
3622 ((ic->op == BITWISEAND ||
3625 isBitwiseOptimizable (ic))) &&
3626 ic->next && ic->next->op == IFX &&
3627 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3628 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3631 debugLog (" %d\n", __LINE__);
3632 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3636 /* reduce for support function calls */
3637 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3638 packRegsForSupport (ic, ebp);
3640 /* if a parameter is passed, it's in W, so we may not
3641 need to place a copy in a register */
3642 if (ic->op == RECEIVE)
3643 packForReceive (ic, ebp);
3645 /* some cases the redundant moves can
3646 can be eliminated for return statements */
3647 if ((ic->op == RETURN || ic->op == SEND) &&
3648 !isOperandInFarSpace (IC_LEFT (ic)) &&
3650 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3652 /* if pointer set & left has a size more than
3653 one and right is not in far space */
3654 if (POINTER_SET (ic) &&
3655 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3656 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3657 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3658 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3660 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3662 /* if pointer get */
3663 if (POINTER_GET (ic) &&
3664 !isOperandInFarSpace (IC_RESULT (ic)) &&
3665 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3666 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3667 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3669 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3672 /* if this is cast for intergral promotion then
3673 check if only use of the definition of the
3674 operand being casted/ if yes then replace
3675 the result of that arithmetic operation with
3676 this result and get rid of the cast */
3677 if (ic->op == CAST) {
3679 sym_link *fromType = operandType (IC_RIGHT (ic));
3680 sym_link *toType = operandType (IC_LEFT (ic));
3682 debugLog (" %d - casting\n", __LINE__);
3684 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3685 getSize (fromType) != getSize (toType)) {
3688 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3691 if (IS_ARITHMETIC_OP (dic)) {
3693 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3694 IC_RESULT (dic) = IC_RESULT (ic);
3695 remiCodeFromeBBlock (ebp, ic);
3696 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3697 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3698 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3702 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3706 /* if the type from and type to are the same
3707 then if this is the only use then packit */
3708 if (compareType (operandType (IC_RIGHT (ic)),
3709 operandType (IC_LEFT (ic))) == 1) {
3711 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3714 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3715 IC_RESULT (dic) = IC_RESULT (ic);
3716 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3717 remiCodeFromeBBlock (ebp, ic);
3718 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3719 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3727 iTempNN := (some variable in farspace) V1
3732 if (ic->op == IPUSH)
3734 packForPush (ic, ebp);
3738 /* pack registers for accumulator use, when the
3739 result of an arithmetic or bit wise operation
3740 has only one use, that use is immediately following
3741 the defintion and the using iCode has only one
3742 operand or has two operands but one is literal &
3743 the result of that operation is not on stack then
3744 we can leave the result of this operation in acc:b
3746 if ((IS_ARITHMETIC_OP (ic)
3748 || IS_BITWISE_OP (ic)
3750 || ic->op == LEFT_OP || ic->op == RIGHT_OP
3753 IS_ITEMP (IC_RESULT (ic)) &&
3754 getSize (operandType (IC_RESULT (ic))) <= 2)
3756 packRegsForAccUse (ic);
3762 dumpEbbsToDebug (eBBlock ** ebbs, int count)
3766 if (!debug || !debugF)
3769 for (i = 0; i < count; i++)
3771 fprintf (debugF, "\n----------------------------------------------------------------\n");
3772 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
3773 ebbs[i]->entryLabel->name,
3776 ebbs[i]->isLastInLoop);
3777 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
3782 fprintf (debugF, "visited %d : hasFcall = %d\n",
3786 fprintf (debugF, "\ndefines bitVector :");
3787 bitVectDebugOn (ebbs[i]->defSet, debugF);
3788 fprintf (debugF, "\nlocal defines bitVector :");
3789 bitVectDebugOn (ebbs[i]->ldefs, debugF);
3790 fprintf (debugF, "\npointers Set bitvector :");
3791 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
3792 fprintf (debugF, "\nin pointers Set bitvector :");
3793 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
3794 fprintf (debugF, "\ninDefs Set bitvector :");
3795 bitVectDebugOn (ebbs[i]->inDefs, debugF);
3796 fprintf (debugF, "\noutDefs Set bitvector :");
3797 bitVectDebugOn (ebbs[i]->outDefs, debugF);
3798 fprintf (debugF, "\nusesDefs Set bitvector :");
3799 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
3800 fprintf (debugF, "\n----------------------------------------------------------------\n");
3801 printiCChain (ebbs[i]->sch, debugF);
3804 /*-----------------------------------------------------------------*/
3805 /* assignRegisters - assigns registers to each live range as need */
3806 /*-----------------------------------------------------------------*/
3808 pic14_assignRegisters (eBBlock ** ebbs, int count)
3813 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
3814 debugLog ("\nebbs before optimizing:\n");
3815 dumpEbbsToDebug (ebbs, count);
3817 setToNull ((void *) &_G.funcrUsed);
3818 pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3821 /* change assignments this will remove some
3822 live ranges reducing some register pressure */
3823 for (i = 0; i < count; i++)
3824 packRegisters (ebbs[i]);
3831 debugLog("dir registers allocated so far:\n");
3832 reg = hTabFirstItem(dynDirectRegNames, &hkey);
3835 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
3836 reg = hTabNextItem(dynDirectRegNames, &hkey);
3841 if (options.dump_pack)
3842 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3844 /* first determine for each live range the number of
3845 registers & the type of registers required for each */
3848 /* and serially allocate registers */
3849 serialRegAssign (ebbs, count);
3851 /* if stack was extended then tell the user */
3854 /* werror(W_TOOMANY_SPILS,"stack", */
3855 /* _G.stackExtend,currFunc->name,""); */
3861 /* werror(W_TOOMANY_SPILS,"data space", */
3862 /* _G.dataExtend,currFunc->name,""); */
3866 /* after that create the register mask
3867 for each of the instruction */
3868 createRegMask (ebbs, count);
3870 /* redo that offsets for stacked automatic variables */
3871 redoStackOffsets ();
3873 if (options.dump_rassgn)
3874 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3876 /* now get back the chain */
3877 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3879 debugLog ("ebbs after optimizing:\n");
3880 dumpEbbsToDebug (ebbs, count);
3885 /* free up any _G.stackSpil locations allocated */
3886 applyToSet (_G.stackSpil, deallocStackSpil);
3888 setToNull ((void **) &_G.stackSpil);
3889 setToNull ((void **) &_G.spiltSet);
3890 /* mark all registers as free */
3891 //pic14_freeAllRegs ();
3893 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");