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)
7 Added Pic16 Port Martin Dubuc m.dubuc@rogers.com (2002)
9 This program is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 In other words, you are welcome to use, share and improve this program.
24 You are forbidden to forbid anyone else to use, share and improve
25 what you give them. Help stamp out software-hoarding!
26 -------------------------------------------------------------------------*/
33 #if defined(__BORLANDC__) || defined(_MSC_VER)
34 #define STRCASECMP stricmp
36 #define STRCASECMP strcasecmp
39 /*-----------------------------------------------------------------*/
40 /* At this point we start getting processor specific although */
41 /* some routines are non-processor specific & can be reused when */
42 /* targetting other processors. The decision for this will have */
43 /* to be made on a routine by routine basis */
44 /* routines used to pack registers are most definitely not reusable */
45 /* since the pack the registers depending strictly on the MCU */
46 /*-----------------------------------------------------------------*/
48 static regs *typeRegWithIdx (int idx, int type, int fixed);
49 extern void genpic16Code (iCode *);
50 extern void pic16_assignConfigWordValue(int address, int value);
60 bitVect *funcrUsed; /* registers used in a function */
66 /* Shared with gen.c */
67 int pic16_ptrRegReq; /* one byte pointer register required */
70 set *pic16_dynAllocRegs=NULL;
71 set *pic16_dynStackRegs=NULL;
72 set *pic16_dynProcessorRegs=NULL;
73 set *pic16_dynDirectRegs=NULL;
74 set *pic16_dynDirectBitRegs=NULL;
75 set *pic16_dynInternalRegs=NULL;
77 static hTab *dynDirectRegNames= NULL;
78 //static hTab *regHash = NULL; /* a hash table containing ALL registers */
80 static int dynrIdx=0x20;
81 static int rDirectIdx=0;
83 int pic16_nRegs = 128; // = sizeof (regspic16) / sizeof (regs);
85 int pic16_Gstack_base_addr=0; /* The starting address of registers that
86 * are used to pass and return parameters */
91 static void spillThis (symbol *);
93 static FILE *debugF = NULL;
94 /*-----------------------------------------------------------------*/
95 /* debugLog - open a file for debugging information */
96 /*-----------------------------------------------------------------*/
97 //static void debugLog(char *inst,char *fmt, ...)
99 debugLog (char *fmt,...)
101 static int append = 0; // First time through, open the file without append.
104 //char *bufferP=buffer;
107 if (!debug || !dstFileName)
113 /* create the file name */
114 strcpy (buffer, dstFileName);
115 strcat (buffer, ".d");
117 if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
119 werror (E_FILE_OPEN_ERR, buffer);
122 append = 1; // Next time debubLog is called, we'll append the debug info
128 vsprintf (buffer, fmt, ap);
130 fprintf (debugF, "%s", buffer);
132 while (isspace(*bufferP)) bufferP++;
134 if (bufferP && *bufferP)
135 lineCurr = (lineCurr ?
136 connectLine(lineCurr,newLineNode(lb)) :
137 (lineHead = newLineNode(lb)));
138 lineCurr->isInline = _G.inLine;
139 lineCurr->isDebug = _G.debugLine;
149 fputc ('\n', debugF);
151 /*-----------------------------------------------------------------*/
152 /* debugLogClose - closes the debug log file (if opened) */
153 /*-----------------------------------------------------------------*/
163 #define AOP(op) op->aop
166 debugAopGet (char *str, operand * op)
171 printOperand (op, debugF);
179 decodeOp (unsigned int op)
182 if (op < 128 && op > ' ')
184 buffer[0] = (op & 0xff);
198 return "STRING_LITERAL";
234 return "LEFT_ASSIGN";
236 return "RIGHT_ASSIGN";
351 case GET_VALUE_AT_ADDRESS:
352 return "GET_VALUE_AT_ADDRESS";
370 return "ENDFUNCTION";
394 sprintf (buffer, "unkown op %d %c", op, op & 0xff);
397 /*-----------------------------------------------------------------*/
398 /*-----------------------------------------------------------------*/
400 debugLogRegType (short type)
413 sprintf (buffer, "unknown reg type %d", type);
417 /*-----------------------------------------------------------------*/
418 /*-----------------------------------------------------------------*/
419 static int regname2key(char const *name)
428 key += (*name++) + 1;
432 return ( (key + (key >> 4) + (key>>8)) & 0x3f);
436 /*-----------------------------------------------------------------*/
437 /* newReg - allocate and init memory for a new register */
438 /*-----------------------------------------------------------------*/
439 static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias)
444 dReg = Safe_calloc(1,sizeof(regs));
446 dReg->pc_type = pc_type;
449 dReg->name = Safe_strdup(name);
451 sprintf(buffer,"r0x%02X", dReg->rIdx);
454 dReg->name = Safe_strdup(buffer);
456 //fprintf(stderr,"newReg: %s, rIdx = 0x%02x\n",dReg->name,rIdx);
469 dReg->reg_alias = NULL;
470 dReg->reglives.usedpFlows = newSet();
471 dReg->reglives.assignedpFlows = newSet();
473 hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
478 /*-----------------------------------------------------------------*/
479 /* regWithIdx - Search through a set of registers that matches idx */
480 /*-----------------------------------------------------------------*/
482 regWithIdx (set *dRegs, int idx, int fixed)
486 for (dReg = setFirstItem(dRegs) ; dReg ;
487 dReg = setNextItem(dRegs)) {
489 if(idx == dReg->rIdx && (fixed == dReg->isFixed)) {
497 /*-----------------------------------------------------------------*/
498 /* regFindFree - Search for a free register in a set of registers */
499 /*-----------------------------------------------------------------*/
501 regFindFree (set *dRegs)
505 for (dReg = setFirstItem(dRegs) ; dReg ;
506 dReg = setNextItem(dRegs)) {
514 /*-----------------------------------------------------------------*/
515 /* pic16_initStack - allocate registers for a pseudo stack */
516 /*-----------------------------------------------------------------*/
517 void pic16_initStack(int base_address, int size)
522 pic16_Gstack_base_addr = base_address;
523 //fprintf(stderr,"initStack");
525 for(i = 0; i<size; i++)
526 addSet(&pic16_dynStackRegs,newReg(REG_STK, PO_GPR_TEMP,base_address++,NULL,1,0));
529 /*-----------------------------------------------------------------*
530 *-----------------------------------------------------------------*/
532 pic16_allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
535 //fprintf(stderr,"pic16_allocProcessorRegister %s addr =0x%x\n",name,rIdx);
536 return addSet(&pic16_dynProcessorRegs,newReg(REG_SFR, po_type, rIdx, name,1,alias));
539 /*-----------------------------------------------------------------*
540 *-----------------------------------------------------------------*/
543 pic16_allocInternalRegister(int rIdx, char * name, short po_type, int alias)
545 regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias);
547 //fprintf(stderr,"pic16_allocInternalRegister %s addr =0x%x\n",name,rIdx);
550 return addSet(&pic16_dynInternalRegs,reg);
555 /*-----------------------------------------------------------------*/
556 /* allocReg - allocates register of given type */
557 /*-----------------------------------------------------------------*/
559 allocReg (short type)
562 debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
563 //fprintf(stderr,"allocReg\n");
566 return addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
571 /*-----------------------------------------------------------------*/
572 /* pic16_dirregWithName - search for register by name */
573 /*-----------------------------------------------------------------*/
575 pic16_dirregWithName (char *name)
583 /* hash the name to get a key */
585 hkey = regname2key(name);
587 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
589 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
593 if(STRCASECMP(reg->name, name) == 0) {
597 reg = hTabNextItemWK (dynDirectRegNames);
601 return NULL; // name wasn't found in the hash table
604 static int IS_CONFIG_ADDRESS(int address)
607 return address >= 0x300000 && address <= 0x300000d;
610 /*-----------------------------------------------------------------*/
611 /* pic16_allocDirReg - allocates register of given type */
612 /*-----------------------------------------------------------------*/
614 pic16_allocDirReg (operand *op )
621 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
625 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
627 /* If the symbol is at a fixed address, then remove the leading underscore
628 * from the name. This is hack to allow the .asm include file named registers
629 * to match the .c declared register names */
631 //if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && (*name == '_'))
634 debugLog ("%s symbol name %s\n", __FUNCTION__,name);
636 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
637 debugLog(" %d const char\n",__LINE__);
638 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
641 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
642 if (IS_CODE ( OP_SYM_ETYPE(op)) )
643 debugLog(" %d code space\n",__LINE__);
645 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
646 debugLog(" %d integral\n",__LINE__);
647 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
648 debugLog(" %d literal\n",__LINE__);
649 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
650 debugLog(" %d specifier\n",__LINE__);
651 debugAopGet(NULL, op);
654 if (IS_CODE ( OP_SYM_ETYPE(op)) )
657 /* First, search the hash table to see if there is a register with this name */
658 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && !(IS_BITVAR (OP_SYM_ETYPE(op))) ) {
659 reg = regWithIdx (pic16_dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1);
663 fprintf(stderr,"%s:%d: ralloc %s is at fixed address but not a processor reg, addr=0x%x\n",
664 __FUNCTION__, __LINE__, name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
666 fprintf(stderr,"%s:%d: ralloc %s at fixed address has already been declared, addr=0x%x\n",
667 __FUNCTION__, __LINE__, name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
670 // fprintf(stderr,"ralloc:%d %s \n", __LINE__,name);
672 reg = pic16_dirregWithName(name);
678 /* if this is at an absolute address, then get the address. */
679 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
680 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
681 //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
684 /* Register wasn't found in hash, so let's create
685 * a new one and put it in the hash table AND in the
686 * dynDirectRegNames set */
687 if(!IS_CONFIG_ADDRESS(address)) {
688 //fprintf(stderr,"allocating new reg %s\n",name);
690 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0 );
691 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
693 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
695 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
697 //fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
701 if (IS_BITVAR (OP_SYM_ETYPE(op))) {
702 addSet(&pic16_dynDirectBitRegs, reg);
705 addSet(&pic16_dynDirectRegs, reg);
708 debugLog (" -- %s is declared at address 0x30000x\n",name);
713 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
715 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
716 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
722 /*-----------------------------------------------------------------*/
723 /* pic16_allocRegByName - allocates register of given type */
724 /*-----------------------------------------------------------------*/
726 pic16_allocRegByName (char *name, int size)
732 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
736 /* First, search the hash table to see if there is a register with this name */
737 reg = pic16_dirregWithName(name);
741 /* Register wasn't found in hash, so let's create
742 * a new one and put it in the hash table AND in the
743 * dynDirectRegNames set */
744 //fprintf (stderr,"%s symbol name %s\n", __FUNCTION__,name);
745 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0 );
747 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
749 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
750 addSet(&pic16_dynDirectRegs, reg);
756 /*-----------------------------------------------------------------*/
757 /* RegWithIdx - returns pointer to register with index number */
758 /*-----------------------------------------------------------------*/
760 typeRegWithIdx (int idx, int type, int fixed)
765 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
770 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx, fixed)) != NULL) {
772 debugLog ("Found a Dynamic Register!\n");
775 if( (dReg = regWithIdx ( pic16_dynDirectRegs, idx, fixed)) != NULL ) {
776 debugLog ("Found a Direct Register!\n");
782 if( (dReg = regWithIdx ( pic16_dynStackRegs, idx, fixed)) != NULL ) {
783 debugLog ("Found a Stack Register!\n");
788 if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx, fixed)) != NULL ) {
789 debugLog ("Found a Processor Register!\n");
803 /*-----------------------------------------------------------------*/
804 /* pic16_regWithIdx - returns pointer to register with index number*/
805 /*-----------------------------------------------------------------*/
807 pic16_regWithIdx (int idx)
811 if( (dReg = typeRegWithIdx(idx,REG_GPR,0)) != NULL)
814 if( (dReg = typeRegWithIdx(idx,REG_SFR,0)) != NULL)
817 if( (dReg = typeRegWithIdx(idx,REG_STK,0)) != NULL)
823 /*-----------------------------------------------------------------*/
824 /* pic16_regWithIdx - returns pointer to register with index number */
825 /*-----------------------------------------------------------------*/
827 pic16_allocWithIdx (int idx)
832 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
834 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx,0)) != NULL) {
836 debugLog ("Found a Dynamic Register!\n");
837 } else if( (dReg = regWithIdx ( pic16_dynStackRegs, idx,0)) != NULL ) {
838 debugLog ("Found a Stack Register!\n");
839 } else if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx,0)) != NULL ) {
840 debugLog ("Found a Processor Register!\n");
841 } else if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx,0)) != NULL ) {
842 debugLog ("Found an Internal Register!\n");
845 debugLog ("Dynamic Register not found\n");
848 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
849 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
850 "regWithIdx not found");
860 /*-----------------------------------------------------------------*/
861 /*-----------------------------------------------------------------*/
863 pic16_findFreeReg(short type)
870 if((dReg = regFindFree(pic16_dynAllocRegs)) != NULL)
872 return addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
876 if((dReg = regFindFree(pic16_dynStackRegs)) != NULL)
888 /*-----------------------------------------------------------------*/
889 /* freeReg - frees a register */
890 /*-----------------------------------------------------------------*/
894 debugLog ("%s\n", __FUNCTION__);
899 /*-----------------------------------------------------------------*/
900 /* nFreeRegs - returns number of free registers */
901 /*-----------------------------------------------------------------*/
905 /* dynamically allocate as many as we need and worry about
906 * fitting them into a PIC later */
913 debugLog ("%s\n", __FUNCTION__);
914 for (i = 0; i < pic16_nRegs; i++)
915 if (regspic16[i].isFree && regspic16[i].type == type)
921 /*-----------------------------------------------------------------*/
922 /* nfreeRegsType - free registers with type */
923 /*-----------------------------------------------------------------*/
925 nfreeRegsType (int type)
928 debugLog ("%s\n", __FUNCTION__);
931 if ((nfr = nFreeRegs (type)) == 0)
932 return nFreeRegs (REG_GPR);
935 return nFreeRegs (type);
938 static void writeSetUsedRegs(FILE *of, set *dRegs)
943 for (dReg = setFirstItem(dRegs) ; dReg ;
944 dReg = setNextItem(dRegs)) {
947 fprintf (of, "\t%s\n",dReg->name);
953 extern void pic16_assignFixedRegisters(set *regset);
954 extern void pic16_assignRelocatableRegisters(set *regset,int used);
955 extern void pic16_dump_map(void);
956 extern void pic16_dump_cblock(FILE *of);
959 static void packBits(set *bregs)
964 regs *relocbitfield=NULL;
970 for (regset = bregs ; regset ;
971 regset = regset->next) {
974 breg->isBitField = 1;
975 //fprintf(stderr,"bit reg: %s\n",breg->name);
978 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
980 bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1);
981 breg->rIdx = breg->address & 7;
985 sprintf (buffer, "fbitfield%02x", breg->address);
986 //fprintf(stderr,"new bit field\n");
987 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0);
988 bitfield->isBitField = 1;
989 bitfield->isFixed = 1;
990 bitfield->address = breg->address;
991 addSet(&pic16_dynDirectRegs,bitfield);
992 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
994 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
997 breg->reg_alias = bitfield;
1001 if(!relocbitfield || bit_no >7) {
1004 sprintf (buffer, "bitfield%d", byte_no);
1005 //fprintf(stderr,"new relocatable bit field\n");
1006 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0);
1007 relocbitfield->isBitField = 1;
1008 addSet(&pic16_dynDirectRegs,relocbitfield);
1009 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1013 breg->reg_alias = relocbitfield;
1014 breg->address = rDirectIdx; /* byte_no; */
1015 breg->rIdx = bit_no++;
1024 static void bitEQUs(FILE *of, set *bregs)
1026 regs *breg,*bytereg;
1029 //fprintf(stderr," %s\n",__FUNCTION__);
1030 for (breg = setFirstItem(bregs) ; breg ;
1031 breg = setNextItem(bregs)) {
1033 //fprintf(stderr,"bit reg: %s\n",breg->name);
1035 bytereg = breg->reg_alias;
1037 fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
1040 breg->rIdx & 0x0007);
1043 fprintf(stderr, "bit field is not assigned to a register\n");
1044 fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
1055 static void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
1060 for (reg = setFirstItem(fregs) ; reg ;
1061 reg = setNextItem(fregs)) {
1063 if(!reg->isEmitted && reg->wasUsed) {
1065 if (reg->type != REG_SFR) {
1066 fprintf (of, "%s\tEQU\t0x%03x\n",
1072 fprintf (of, "%s\tEQU\t0x%03x\n",
1081 void pic16_writeUsedRegs(FILE *of)
1083 packBits(pic16_dynDirectBitRegs);
1086 pic16_assignFixedRegisters(pic16_dynAllocRegs);
1087 pic16_assignFixedRegisters(pic16_dynStackRegs);
1088 pic16_assignFixedRegisters(pic16_dynDirectRegs);
1090 pic16_assignRelocatableRegisters(pic16_dynInternalRegs,0);
1091 pic16_assignRelocatableRegisters(pic16_dynAllocRegs,0);
1092 pic16_assignRelocatableRegisters(pic16_dynStackRegs,0);
1093 pic16_assignRelocatableRegisters(pic16_dynDirectRegs,0);
1097 pic16_dump_cblock(of);
1100 bitEQUs(of,pic16_dynDirectBitRegs);
1101 aliasEQUs(of,pic16_dynAllocRegs,0);
1102 aliasEQUs(of,pic16_dynDirectRegs,0);
1103 aliasEQUs(of,pic16_dynStackRegs,0);
1104 aliasEQUs(of,pic16_dynProcessorRegs,1);
1110 /*-----------------------------------------------------------------*/
1111 /* allDefsOutOfRange - all definitions are out of a range */
1112 /*-----------------------------------------------------------------*/
1114 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
1118 debugLog ("%s\n", __FUNCTION__);
1122 for (i = 0; i < defs->size; i++)
1126 if (bitVectBitValue (defs, i) &&
1127 (ic = hTabItemWithKey (iCodehTab, i)) &&
1128 (ic->seq >= fseq && ic->seq <= toseq))
1138 /*-----------------------------------------------------------------*/
1139 /* computeSpillable - given a point find the spillable live ranges */
1140 /*-----------------------------------------------------------------*/
1142 computeSpillable (iCode * ic)
1146 debugLog ("%s\n", __FUNCTION__);
1147 /* spillable live ranges are those that are live at this
1148 point . the following categories need to be subtracted
1150 a) - those that are already spilt
1151 b) - if being used by this one
1152 c) - defined by this one */
1154 spillable = bitVectCopy (ic->rlive);
1156 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1158 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1159 bitVectUnSetBit (spillable, ic->defKey);
1160 spillable = bitVectIntersect (spillable, _G.regAssigned);
1165 /*-----------------------------------------------------------------*/
1166 /* noSpilLoc - return true if a variable has no spil location */
1167 /*-----------------------------------------------------------------*/
1169 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1171 debugLog ("%s\n", __FUNCTION__);
1172 return (sym->usl.spillLoc ? 0 : 1);
1175 /*-----------------------------------------------------------------*/
1176 /* hasSpilLoc - will return 1 if the symbol has spil location */
1177 /*-----------------------------------------------------------------*/
1179 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1181 debugLog ("%s\n", __FUNCTION__);
1182 return (sym->usl.spillLoc ? 1 : 0);
1185 /*-----------------------------------------------------------------*/
1186 /* directSpilLoc - will return 1 if the splilocation is in direct */
1187 /*-----------------------------------------------------------------*/
1189 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1191 debugLog ("%s\n", __FUNCTION__);
1192 if (sym->usl.spillLoc &&
1193 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1199 /*-----------------------------------------------------------------*/
1200 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1201 /* but is not used as a pointer */
1202 /*-----------------------------------------------------------------*/
1204 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1206 debugLog ("%s\n", __FUNCTION__);
1207 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1210 /*-----------------------------------------------------------------*/
1211 /* rematable - will return 1 if the remat flag is set */
1212 /*-----------------------------------------------------------------*/
1214 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1216 debugLog ("%s\n", __FUNCTION__);
1220 /*-----------------------------------------------------------------*/
1221 /* notUsedInRemaining - not used or defined in remain of the block */
1222 /*-----------------------------------------------------------------*/
1224 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1226 debugLog ("%s\n", __FUNCTION__);
1227 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1228 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1231 /*-----------------------------------------------------------------*/
1232 /* allLRs - return true for all */
1233 /*-----------------------------------------------------------------*/
1235 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1237 debugLog ("%s\n", __FUNCTION__);
1241 /*-----------------------------------------------------------------*/
1242 /* liveRangesWith - applies function to a given set of live range */
1243 /*-----------------------------------------------------------------*/
1245 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1246 eBBlock * ebp, iCode * ic)
1251 debugLog ("%s\n", __FUNCTION__);
1252 if (!lrs || !lrs->size)
1255 for (i = 1; i < lrs->size; i++)
1258 if (!bitVectBitValue (lrs, i))
1261 /* if we don't find it in the live range
1262 hash table we are in serious trouble */
1263 if (!(sym = hTabItemWithKey (liveRanges, i)))
1265 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1266 "liveRangesWith could not find liveRange");
1270 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1271 addSetHead (&rset, sym);
1278 /*-----------------------------------------------------------------*/
1279 /* leastUsedLR - given a set determines which is the least used */
1280 /*-----------------------------------------------------------------*/
1282 leastUsedLR (set * sset)
1284 symbol *sym = NULL, *lsym = NULL;
1286 debugLog ("%s\n", __FUNCTION__);
1287 sym = lsym = setFirstItem (sset);
1292 for (; lsym; lsym = setNextItem (sset))
1295 /* if usage is the same then prefer
1296 the spill the smaller of the two */
1297 if (lsym->used == sym->used)
1298 if (getSize (lsym->type) < getSize (sym->type))
1302 if (lsym->used < sym->used)
1307 setToNull ((void **) &sset);
1312 /*-----------------------------------------------------------------*/
1313 /* noOverLap - will iterate through the list looking for over lap */
1314 /*-----------------------------------------------------------------*/
1316 noOverLap (set * itmpStack, symbol * fsym)
1319 debugLog ("%s\n", __FUNCTION__);
1322 for (sym = setFirstItem (itmpStack); sym;
1323 sym = setNextItem (itmpStack))
1325 if (sym->liveTo > fsym->liveFrom)
1333 /*-----------------------------------------------------------------*/
1334 /* isFree - will return 1 if the a free spil location is found */
1335 /*-----------------------------------------------------------------*/
1340 V_ARG (symbol **, sloc);
1341 V_ARG (symbol *, fsym);
1343 debugLog ("%s\n", __FUNCTION__);
1344 /* if already found */
1348 /* if it is free && and the itmp assigned to
1349 this does not have any overlapping live ranges
1350 with the one currently being assigned and
1351 the size can be accomodated */
1353 noOverLap (sym->usl.itmpStack, fsym) &&
1354 getSize (sym->type) >= getSize (fsym->type))
1363 /*-----------------------------------------------------------------*/
1364 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1365 /*-----------------------------------------------------------------*/
1367 spillLRWithPtrReg (symbol * forSym)
1373 debugLog ("%s\n", __FUNCTION__);
1374 if (!_G.regAssigned ||
1375 bitVectIsZero (_G.regAssigned))
1378 r0 = pic16_regWithIdx (R0_IDX);
1379 r1 = pic16_regWithIdx (R1_IDX);
1381 /* for all live ranges */
1382 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1383 lrsym = hTabNextItem (liveRanges, &k))
1387 /* if no registers assigned to it or
1389 /* if it does not overlap with this then
1390 not need to spill it */
1392 if (lrsym->isspilt || !lrsym->nRegs ||
1393 (lrsym->liveTo < forSym->liveFrom))
1396 /* go thru the registers : if it is either
1397 r0 or r1 then spil it */
1398 for (j = 0; j < lrsym->nRegs; j++)
1399 if (lrsym->regs[j] == r0 ||
1400 lrsym->regs[j] == r1)
1409 /*-----------------------------------------------------------------*/
1410 /* createStackSpil - create a location on the stack to spil */
1411 /*-----------------------------------------------------------------*/
1413 createStackSpil (symbol * sym)
1415 symbol *sloc = NULL;
1416 int useXstack, model, noOverlay;
1418 char slocBuffer[30];
1419 debugLog ("%s\n", __FUNCTION__);
1421 /* first go try and find a free one that is already
1422 existing on the stack */
1423 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1425 /* found a free one : just update & return */
1426 sym->usl.spillLoc = sloc;
1429 addSetHead (&sloc->usl.itmpStack, sym);
1433 /* could not then have to create one , this is the hard part
1434 we need to allocate this on the stack : this is really a
1435 hack!! but cannot think of anything better at this time */
1437 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1439 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1440 __FILE__, __LINE__);
1444 sloc = newiTemp (slocBuffer);
1446 /* set the type to the spilling symbol */
1447 sloc->type = copyLinkChain (sym->type);
1448 sloc->etype = getSpec (sloc->type);
1449 SPEC_SCLS (sloc->etype) = S_DATA;
1450 SPEC_EXTR (sloc->etype) = 0;
1451 SPEC_STAT (sloc->etype) = 0;
1453 /* we don't allow it to be allocated`
1454 onto the external stack since : so we
1455 temporarily turn it off ; we also
1456 turn off memory model to prevent
1457 the spil from going to the external storage
1458 and turn off overlaying
1461 useXstack = options.useXstack;
1462 model = options.model;
1463 noOverlay = options.noOverlay;
1464 options.noOverlay = 1;
1465 options.model = options.useXstack = 0;
1469 options.useXstack = useXstack;
1470 options.model = model;
1471 options.noOverlay = noOverlay;
1472 sloc->isref = 1; /* to prevent compiler warning */
1474 /* if it is on the stack then update the stack */
1475 if (IN_STACK (sloc->etype))
1477 currFunc->stack += getSize (sloc->type);
1478 _G.stackExtend += getSize (sloc->type);
1481 _G.dataExtend += getSize (sloc->type);
1483 /* add it to the _G.stackSpil set */
1484 addSetHead (&_G.stackSpil, sloc);
1485 sym->usl.spillLoc = sloc;
1488 /* add it to the set of itempStack set
1489 of the spill location */
1490 addSetHead (&sloc->usl.itmpStack, sym);
1494 /*-----------------------------------------------------------------*/
1495 /* isSpiltOnStack - returns true if the spil location is on stack */
1496 /*-----------------------------------------------------------------*/
1498 isSpiltOnStack (symbol * sym)
1502 debugLog ("%s\n", __FUNCTION__);
1509 /* if (sym->_G.stackSpil) */
1512 if (!sym->usl.spillLoc)
1515 etype = getSpec (sym->usl.spillLoc->type);
1516 if (IN_STACK (etype))
1522 /*-----------------------------------------------------------------*/
1523 /* spillThis - spils a specific operand */
1524 /*-----------------------------------------------------------------*/
1526 spillThis (symbol * sym)
1529 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1531 /* if this is rematerializable or has a spillLocation
1532 we are okay, else we need to create a spillLocation
1534 if (!(sym->remat || sym->usl.spillLoc))
1535 createStackSpil (sym);
1538 /* mark it has spilt & put it in the spilt set */
1540 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1542 bitVectUnSetBit (_G.regAssigned, sym->key);
1544 for (i = 0; i < sym->nRegs; i++)
1548 freeReg (sym->regs[i]);
1549 sym->regs[i] = NULL;
1552 /* if spilt on stack then free up r0 & r1
1553 if they could have been assigned to some
1555 if (!pic16_ptrRegReq && isSpiltOnStack (sym))
1558 spillLRWithPtrReg (sym);
1561 if (sym->usl.spillLoc && !sym->remat)
1562 sym->usl.spillLoc->allocreq = 1;
1566 /*-----------------------------------------------------------------*/
1567 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1568 /*-----------------------------------------------------------------*/
1570 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1572 bitVect *lrcs = NULL;
1576 debugLog ("%s\n", __FUNCTION__);
1577 /* get the spillable live ranges */
1578 lrcs = computeSpillable (ic);
1580 /* get all live ranges that are rematerizable */
1581 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1584 /* return the least used of these */
1585 return leastUsedLR (selectS);
1588 /* get live ranges with spillLocations in direct space */
1589 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1591 sym = leastUsedLR (selectS);
1592 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1593 sym->usl.spillLoc->rname :
1594 sym->usl.spillLoc->name));
1596 /* mark it as allocation required */
1597 sym->usl.spillLoc->allocreq = 1;
1601 /* if the symbol is local to the block then */
1602 if (forSym->liveTo < ebp->lSeq)
1605 /* check if there are any live ranges allocated
1606 to registers that are not used in this block */
1607 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1609 sym = leastUsedLR (selectS);
1610 /* if this is not rematerializable */
1619 /* check if there are any live ranges that not
1620 used in the remainder of the block */
1621 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1623 sym = leastUsedLR (selectS);
1626 sym->remainSpil = 1;
1633 /* find live ranges with spillocation && not used as pointers */
1634 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1637 sym = leastUsedLR (selectS);
1638 /* mark this as allocation required */
1639 sym->usl.spillLoc->allocreq = 1;
1643 /* find live ranges with spillocation */
1644 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1647 sym = leastUsedLR (selectS);
1648 sym->usl.spillLoc->allocreq = 1;
1652 /* couldn't find then we need to create a spil
1653 location on the stack , for which one? the least
1655 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1658 /* return a created spil location */
1659 sym = createStackSpil (leastUsedLR (selectS));
1660 sym->usl.spillLoc->allocreq = 1;
1664 /* this is an extreme situation we will spill
1665 this one : happens very rarely but it does happen */
1671 /*-----------------------------------------------------------------*/
1672 /* spilSomething - spil some variable & mark registers as free */
1673 /*-----------------------------------------------------------------*/
1675 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1680 debugLog ("%s\n", __FUNCTION__);
1681 /* get something we can spil */
1682 ssym = selectSpil (ic, ebp, forSym);
1684 /* mark it as spilt */
1686 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1688 /* mark it as not register assigned &
1689 take it away from the set */
1690 bitVectUnSetBit (_G.regAssigned, ssym->key);
1692 /* mark the registers as free */
1693 for (i = 0; i < ssym->nRegs; i++)
1695 freeReg (ssym->regs[i]);
1697 /* if spilt on stack then free up r0 & r1
1698 if they could have been assigned to as gprs */
1699 if (!pic16_ptrRegReq && isSpiltOnStack (ssym))
1702 spillLRWithPtrReg (ssym);
1705 /* if this was a block level spil then insert push & pop
1706 at the start & end of block respectively */
1707 if (ssym->blockSpil)
1709 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1710 /* add push to the start of the block */
1711 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1712 ebp->sch->next : ebp->sch));
1713 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1714 /* add pop to the end of the block */
1715 addiCodeToeBBlock (ebp, nic, NULL);
1718 /* if spilt because not used in the remainder of the
1719 block then add a push before this instruction and
1720 a pop at the end of the block */
1721 if (ssym->remainSpil)
1724 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1725 /* add push just before this instruction */
1726 addiCodeToeBBlock (ebp, nic, ic);
1728 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1729 /* add pop to the end of the block */
1730 addiCodeToeBBlock (ebp, nic, NULL);
1739 /*-----------------------------------------------------------------*/
1740 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1741 /*-----------------------------------------------------------------*/
1743 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1747 debugLog ("%s\n", __FUNCTION__);
1749 /* try for a ptr type */
1750 if ((reg = allocReg (REG_PTR)))
1753 /* try for gpr type */
1754 if ((reg = allocReg (REG_GPR)))
1757 /* we have to spil */
1758 if (!spilSomething (ic, ebp, sym))
1761 /* this looks like an infinite loop but
1762 in really selectSpil will abort */
1766 /*-----------------------------------------------------------------*/
1767 /* getRegGpr - will try for GPR if not spil */
1768 /*-----------------------------------------------------------------*/
1770 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1774 debugLog ("%s\n", __FUNCTION__);
1776 /* try for gpr type */
1777 if ((reg = allocReg (REG_GPR)))
1780 if (!pic16_ptrRegReq)
1781 if ((reg = allocReg (REG_PTR)))
1784 /* we have to spil */
1785 if (!spilSomething (ic, ebp, sym))
1788 /* this looks like an infinite loop but
1789 in really selectSpil will abort */
1793 /*-----------------------------------------------------------------*/
1794 /* symHasReg - symbol has a given register */
1795 /*-----------------------------------------------------------------*/
1797 symHasReg (symbol * sym, regs * reg)
1801 debugLog ("%s\n", __FUNCTION__);
1802 for (i = 0; i < sym->nRegs; i++)
1803 if (sym->regs[i] == reg)
1809 /*-----------------------------------------------------------------*/
1810 /* deassignLRs - check the live to and if they have registers & are */
1811 /* not spilt then free up the registers */
1812 /*-----------------------------------------------------------------*/
1814 deassignLRs (iCode * ic, eBBlock * ebp)
1820 debugLog ("%s\n", __FUNCTION__);
1821 for (sym = hTabFirstItem (liveRanges, &k); sym;
1822 sym = hTabNextItem (liveRanges, &k))
1825 symbol *psym = NULL;
1826 /* if it does not end here */
1827 if (sym->liveTo > ic->seq)
1830 /* if it was spilt on stack then we can
1831 mark the stack spil location as free */
1836 sym->usl.spillLoc->isFree = 1;
1842 if (!bitVectBitValue (_G.regAssigned, sym->key))
1845 /* special case check if this is an IFX &
1846 the privious one was a pop and the
1847 previous one was not spilt then keep track
1849 if (ic->op == IFX && ic->prev &&
1850 ic->prev->op == IPOP &&
1851 !ic->prev->parmPush &&
1852 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1853 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1859 bitVectUnSetBit (_G.regAssigned, sym->key);
1861 /* if the result of this one needs registers
1862 and does not have it then assign it right
1864 if (IC_RESULT (ic) &&
1865 !(SKIP_IC2 (ic) || /* not a special icode */
1866 ic->op == JUMPTABLE ||
1871 POINTER_SET (ic)) &&
1872 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1873 result->liveTo > ic->seq && /* and will live beyond this */
1874 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1875 result->regType == sym->regType && /* same register types */
1876 result->nRegs && /* which needs registers */
1877 !result->isspilt && /* and does not already have them */
1879 !bitVectBitValue (_G.regAssigned, result->key) &&
1880 /* the number of free regs + number of regs in this LR
1881 can accomodate the what result Needs */
1882 ((nfreeRegsType (result->regType) +
1883 sym->nRegs) >= result->nRegs)
1887 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1889 result->regs[i] = sym->regs[i];
1891 result->regs[i] = getRegGpr (ic, ebp, result);
1893 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1897 /* free the remaining */
1898 for (; i < sym->nRegs; i++)
1902 if (!symHasReg (psym, sym->regs[i]))
1903 freeReg (sym->regs[i]);
1906 freeReg (sym->regs[i]);
1913 /*-----------------------------------------------------------------*/
1914 /* reassignLR - reassign this to registers */
1915 /*-----------------------------------------------------------------*/
1917 reassignLR (operand * op)
1919 symbol *sym = OP_SYMBOL (op);
1922 debugLog ("%s\n", __FUNCTION__);
1923 /* not spilt any more */
1924 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1925 bitVectUnSetBit (_G.spiltSet, sym->key);
1927 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1931 for (i = 0; i < sym->nRegs; i++)
1932 sym->regs[i]->isFree = 0;
1935 /*-----------------------------------------------------------------*/
1936 /* willCauseSpill - determines if allocating will cause a spill */
1937 /*-----------------------------------------------------------------*/
1939 willCauseSpill (int nr, int rt)
1941 debugLog ("%s\n", __FUNCTION__);
1942 /* first check if there are any avlb registers
1943 of te type required */
1946 /* special case for pointer type
1947 if pointer type not avlb then
1948 check for type gpr */
1949 if (nFreeRegs (rt) >= nr)
1951 if (nFreeRegs (REG_GPR) >= nr)
1956 if (pic16_ptrRegReq)
1958 if (nFreeRegs (rt) >= nr)
1963 if (nFreeRegs (REG_PTR) +
1964 nFreeRegs (REG_GPR) >= nr)
1969 debugLog (" ... yep it will (cause a spill)\n");
1970 /* it will cause a spil */
1974 /*-----------------------------------------------------------------*/
1975 /* positionRegs - the allocator can allocate same registers to res- */
1976 /* ult and operand, if this happens make sure they are in the same */
1977 /* position as the operand otherwise chaos results */
1978 /*-----------------------------------------------------------------*/
1980 positionRegs (symbol * result, symbol * opsym, int lineno)
1982 int count = min (result->nRegs, opsym->nRegs);
1983 int i, j = 0, shared = 0;
1985 debugLog ("%s\n", __FUNCTION__);
1986 /* if the result has been spilt then cannot share */
1991 /* first make sure that they actually share */
1992 for (i = 0; i < count; i++)
1994 for (j = 0; j < count; j++)
1996 if (result->regs[i] == opsym->regs[j] && i != j)
2006 regs *tmp = result->regs[i];
2007 result->regs[i] = result->regs[j];
2008 result->regs[j] = tmp;
2013 /*-----------------------------------------------------------------*/
2014 /* serialRegAssign - serially allocate registers to the variables */
2015 /*-----------------------------------------------------------------*/
2017 serialRegAssign (eBBlock ** ebbs, int count)
2021 debugLog ("%s\n", __FUNCTION__);
2022 /* for all blocks */
2023 for (i = 0; i < count; i++)
2028 if (ebbs[i]->noPath &&
2029 (ebbs[i]->entryLabel != entryLabel &&
2030 ebbs[i]->entryLabel != returnLabel))
2033 /* of all instructions do */
2034 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2037 debugLog (" op: %s\n", decodeOp (ic->op));
2039 /* if this is an ipop that means some live
2040 range will have to be assigned again */
2042 reassignLR (IC_LEFT (ic));
2044 /* if result is present && is a true symbol */
2045 if (IC_RESULT (ic) && ic->op != IFX &&
2046 IS_TRUE_SYMOP (IC_RESULT (ic)))
2047 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2049 /* take away registers from live
2050 ranges that end at this instruction */
2051 deassignLRs (ic, ebbs[i]);
2053 /* some don't need registers */
2054 if (SKIP_IC2 (ic) ||
2055 ic->op == JUMPTABLE ||
2059 (IC_RESULT (ic) && POINTER_SET (ic)))
2062 /* now we need to allocate registers
2063 only for the result */
2066 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2072 /* if it does not need or is spilt
2073 or is already assigned to registers
2074 or will not live beyond this instructions */
2077 bitVectBitValue (_G.regAssigned, sym->key) ||
2078 sym->liveTo <= ic->seq)
2081 /* if some liverange has been spilt at the block level
2082 and this one live beyond this block then spil this
2084 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2089 /* if trying to allocate this will cause
2090 a spill and there is nothing to spill
2091 or this one is rematerializable then
2093 willCS = willCauseSpill (sym->nRegs, sym->regType);
2094 spillable = computeSpillable (ic);
2096 (willCS && bitVectIsZero (spillable)))
2104 /* if it has a spillocation & is used less than
2105 all other live ranges then spill this */
2107 if (sym->usl.spillLoc) {
2108 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2109 allLRs, ebbs[i], ic));
2110 if (leastUsed && leastUsed->used > sym->used) {
2115 /* if none of the liveRanges have a spillLocation then better
2116 to spill this one than anything else already assigned to registers */
2117 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2118 /* if this is local to this block then we might find a block spil */
2119 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2127 if (ic->op == RECEIVE)
2128 debugLog ("When I get clever, I'll optimize the receive logic\n");
2130 /* if we need ptr regs for the right side
2132 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2133 <= (unsigned) PTRSIZE)
2138 /* else we assign registers to it */
2139 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2141 debugLog (" %d - \n", __LINE__);
2143 bitVectDebugOn(_G.regAssigned, debugF);
2145 for (j = 0; j < sym->nRegs; j++)
2147 if (sym->regType == REG_PTR)
2148 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2150 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2152 /* if the allocation falied which means
2153 this was spilt then break */
2157 debugLog (" %d - \n", __LINE__);
2159 /* if it shares registers with operands make sure
2160 that they are in the same position */
2161 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2162 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2163 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2164 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2165 /* do the same for the right operand */
2166 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2167 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2168 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2169 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2171 debugLog (" %d - \n", __LINE__);
2174 debugLog (" %d - \n", __LINE__);
2184 /*-----------------------------------------------------------------*/
2185 /* rUmaskForOp :- returns register mask for an operand */
2186 /*-----------------------------------------------------------------*/
2188 rUmaskForOp (operand * op)
2194 debugLog ("%s\n", __FUNCTION__);
2195 /* only temporaries are assigned registers */
2199 sym = OP_SYMBOL (op);
2201 /* if spilt or no registers assigned to it
2203 if (sym->isspilt || !sym->nRegs)
2206 rumask = newBitVect (pic16_nRegs);
2208 for (j = 0; j < sym->nRegs; j++)
2210 rumask = bitVectSetBit (rumask,
2211 sym->regs[j]->rIdx);
2217 /*-----------------------------------------------------------------*/
2218 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2219 /*-----------------------------------------------------------------*/
2221 regsUsedIniCode (iCode * ic)
2223 bitVect *rmask = newBitVect (pic16_nRegs);
2225 debugLog ("%s\n", __FUNCTION__);
2226 /* do the special cases first */
2229 rmask = bitVectUnion (rmask,
2230 rUmaskForOp (IC_COND (ic)));
2234 /* for the jumptable */
2235 if (ic->op == JUMPTABLE)
2237 rmask = bitVectUnion (rmask,
2238 rUmaskForOp (IC_JTCOND (ic)));
2243 /* of all other cases */
2245 rmask = bitVectUnion (rmask,
2246 rUmaskForOp (IC_LEFT (ic)));
2250 rmask = bitVectUnion (rmask,
2251 rUmaskForOp (IC_RIGHT (ic)));
2254 rmask = bitVectUnion (rmask,
2255 rUmaskForOp (IC_RESULT (ic)));
2261 /*-----------------------------------------------------------------*/
2262 /* createRegMask - for each instruction will determine the regsUsed */
2263 /*-----------------------------------------------------------------*/
2265 createRegMask (eBBlock ** ebbs, int count)
2269 debugLog ("%s\n", __FUNCTION__);
2270 /* for all blocks */
2271 for (i = 0; i < count; i++)
2275 if (ebbs[i]->noPath &&
2276 (ebbs[i]->entryLabel != entryLabel &&
2277 ebbs[i]->entryLabel != returnLabel))
2280 /* for all instructions */
2281 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2286 if (SKIP_IC2 (ic) || !ic->rlive)
2289 /* first mark the registers used in this
2291 ic->rUsed = regsUsedIniCode (ic);
2292 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2294 /* now create the register mask for those
2295 registers that are in use : this is a
2296 super set of ic->rUsed */
2297 ic->rMask = newBitVect (pic16_nRegs + 1);
2299 /* for all live Ranges alive at this point */
2300 for (j = 1; j < ic->rlive->size; j++)
2305 /* if not alive then continue */
2306 if (!bitVectBitValue (ic->rlive, j))
2309 /* find the live range we are interested in */
2310 if (!(sym = hTabItemWithKey (liveRanges, j)))
2312 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2313 "createRegMask cannot find live range");
2317 /* if no register assigned to it */
2318 if (!sym->nRegs || sym->isspilt)
2321 /* for all the registers allocated to it */
2322 for (k = 0; k < sym->nRegs; k++)
2325 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2331 /*-----------------------------------------------------------------*/
2332 /* rematStr - returns the rematerialized string for a remat var */
2333 /*-----------------------------------------------------------------*/
2335 rematStr (symbol * sym)
2338 iCode *ic = sym->rematiCode;
2339 symbol *psym = NULL;
2341 debugLog ("%s\n", __FUNCTION__);
2343 //printf ("%s\n", s);
2345 /* if plus or minus print the right hand side */
2347 if (ic->op == '+' || ic->op == '-') {
2349 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2351 sprintf (s, "(%s %c 0x%04x)",
2352 OP_SYMBOL (IC_LEFT (ric))->rname,
2354 (int) operandLitValue (IC_RIGHT (ic)));
2357 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2359 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2360 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2365 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2366 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2368 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2373 /*-----------------------------------------------------------------*/
2374 /* rematStr - returns the rematerialized string for a remat var */
2375 /*-----------------------------------------------------------------*/
2377 rematStr (symbol * sym)
2380 iCode *ic = sym->rematiCode;
2382 debugLog ("%s\n", __FUNCTION__);
2387 /* if plus or minus print the right hand side */
2389 if (ic->op == '+' || ic->op == '-') {
2390 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2393 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2397 if (ic->op == '+' || ic->op == '-')
2399 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2400 sprintf (s, "(%s %c 0x%04x)",
2401 OP_SYMBOL (IC_LEFT (ric))->rname,
2403 (int) operandLitValue (IC_RIGHT (ic)));
2406 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2408 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2412 /* we reached the end */
2413 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2417 printf ("%s\n", buffer);
2422 /*-----------------------------------------------------------------*/
2423 /* regTypeNum - computes the type & number of registers required */
2424 /*-----------------------------------------------------------------*/
2432 debugLog ("%s\n", __FUNCTION__);
2433 /* for each live range do */
2434 for (sym = hTabFirstItem (liveRanges, &k); sym;
2435 sym = hTabNextItem (liveRanges, &k)) {
2437 debugLog (" %d - %s\n", __LINE__, sym->rname);
2439 /* if used zero times then no registers needed */
2440 if ((sym->liveTo - sym->liveFrom) == 0)
2444 /* if the live range is a temporary */
2447 debugLog (" %d - itemp register\n", __LINE__);
2449 /* if the type is marked as a conditional */
2450 if (sym->regType == REG_CND)
2453 /* if used in return only then we don't
2455 if (sym->ruonly || sym->accuse) {
2456 if (IS_AGGREGATE (sym->type) || sym->isptr)
2457 sym->type = aggrToPtr (sym->type, FALSE);
2458 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
2463 /* if the symbol has only one definition &
2464 that definition is a get_pointer and the
2465 pointer we are getting is rematerializable and
2468 if (bitVectnBitsOn (sym->defs) == 1 &&
2469 (ic = hTabItemWithKey (iCodehTab,
2470 bitVectFirstBit (sym->defs))) &&
2473 !IS_BITVAR (sym->etype)) {
2476 debugLog (" %d - \n", __LINE__);
2478 /* if remat in data space */
2479 if (OP_SYMBOL (IC_LEFT (ic))->remat &&
2480 DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) {
2482 /* create a psuedo symbol & force a spil */
2483 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2484 symbol *psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2485 psym->type = sym->type;
2486 psym->etype = sym->etype;
2487 strcpy (psym->rname, psym->name);
2489 sym->usl.spillLoc = psym;
2493 /* if in data space or idata space then try to
2494 allocate pointer register */
2498 /* if not then we require registers */
2499 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2500 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2501 getSize (sym->type));
2504 if(IS_PTR_CONST (sym->type)) {
2505 debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2509 if (sym->nRegs > 4) {
2510 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2511 printTypeChain (sym->type, stderr);
2512 fprintf (stderr, "\n");
2515 /* determine the type of register required */
2516 if (sym->nRegs == 1 &&
2517 IS_PTR (sym->type) &&
2519 sym->regType = REG_PTR;
2521 sym->regType = REG_GPR;
2524 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2528 /* for the first run we don't provide */
2529 /* registers for true symbols we will */
2530 /* see how things go */
2535 static DEFSETFUNC (markRegFree)
2537 ((regs *)item)->isFree = 1;
2542 DEFSETFUNC (pic16_deallocReg)
2544 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2545 ((regs *)item)->isFree = 1;
2546 ((regs *)item)->wasUsed = 0;
2550 /*-----------------------------------------------------------------*/
2551 /* freeAllRegs - mark all registers as free */
2552 /*-----------------------------------------------------------------*/
2554 pic16_freeAllRegs ()
2558 debugLog ("%s\n", __FUNCTION__);
2560 applyToSet(pic16_dynAllocRegs,markRegFree);
2561 applyToSet(pic16_dynStackRegs,markRegFree);
2564 for (i = 0; i < pic16_nRegs; i++)
2565 regspic16[i].isFree = 1;
2569 /*-----------------------------------------------------------------*/
2570 /*-----------------------------------------------------------------*/
2572 pic16_deallocateAllRegs ()
2576 debugLog ("%s\n", __FUNCTION__);
2578 applyToSet(pic16_dynAllocRegs,pic16_deallocReg);
2581 for (i = 0; i < pic16_nRegs; i++) {
2582 if(regspic16[i].pc_type == PO_GPR_TEMP) {
2583 regspic16[i].isFree = 1;
2584 regspic16[i].wasUsed = 0;
2591 /*-----------------------------------------------------------------*/
2592 /* deallocStackSpil - this will set the stack pointer back */
2593 /*-----------------------------------------------------------------*/
2595 DEFSETFUNC (deallocStackSpil)
2599 debugLog ("%s\n", __FUNCTION__);
2604 /*-----------------------------------------------------------------*/
2605 /* farSpacePackable - returns the packable icode for far variables */
2606 /*-----------------------------------------------------------------*/
2608 farSpacePackable (iCode * ic)
2612 debugLog ("%s\n", __FUNCTION__);
2613 /* go thru till we find a definition for the
2614 symbol on the right */
2615 for (dic = ic->prev; dic; dic = dic->prev)
2618 /* if the definition is a call then no */
2619 if ((dic->op == CALL || dic->op == PCALL) &&
2620 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2625 /* if shift by unknown amount then not */
2626 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2627 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2630 /* if pointer get and size > 1 */
2631 if (POINTER_GET (dic) &&
2632 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2635 if (POINTER_SET (dic) &&
2636 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2639 /* if any three is a true symbol in far space */
2640 if (IC_RESULT (dic) &&
2641 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2642 isOperandInFarSpace (IC_RESULT (dic)))
2645 if (IC_RIGHT (dic) &&
2646 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2647 isOperandInFarSpace (IC_RIGHT (dic)) &&
2648 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2651 if (IC_LEFT (dic) &&
2652 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2653 isOperandInFarSpace (IC_LEFT (dic)) &&
2654 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2657 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2659 if ((dic->op == LEFT_OP ||
2660 dic->op == RIGHT_OP ||
2662 IS_OP_LITERAL (IC_RIGHT (dic)))
2672 /*-----------------------------------------------------------------*/
2673 /* packRegsForAssign - register reduction for assignment */
2674 /*-----------------------------------------------------------------*/
2676 packRegsForAssign (iCode * ic, eBBlock * ebp)
2681 debugLog ("%s\n", __FUNCTION__);
2683 debugAopGet (" result:", IC_RESULT (ic));
2684 debugAopGet (" left:", IC_LEFT (ic));
2685 debugAopGet (" right:", IC_RIGHT (ic));
2687 /* if this is at an absolute address, then get the address. */
2688 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2689 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2690 debugLog (" %d - found config word declaration\n", __LINE__);
2691 if(IS_VALOP(IC_RIGHT(ic))) {
2692 debugLog (" setting config word to %x\n",
2693 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2694 pic16_assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2695 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2698 /* remove the assignment from the iCode chain. */
2700 remiCodeFromeBBlock (ebp, ic);
2701 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2702 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2709 if (!IS_ITEMP (IC_RESULT (ic))) {
2710 pic16_allocDirReg(IC_RESULT (ic));
2711 debugLog (" %d - result is not temp\n", __LINE__);
2714 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2715 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2716 pic16_allocDirReg(IC_LEFT (ic));
2720 if (!IS_ITEMP (IC_RIGHT (ic))) {
2721 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2722 pic16_allocDirReg(IC_RIGHT (ic));
2726 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2727 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2729 debugLog (" %d - not packing - right side fails \n", __LINE__);
2733 /* if the true symbol is defined in far space or on stack
2734 then we should not since this will increase register pressure */
2735 if (isOperandInFarSpace (IC_RESULT (ic)))
2737 if ((dic = farSpacePackable (ic)))
2743 /* find the definition of iTempNN scanning backwards if we find a
2744 a use of the true symbol before we find the definition then
2746 for (dic = ic->prev; dic; dic = dic->prev)
2749 /* if there is a function call and this is
2750 a parameter & not my parameter then don't pack it */
2751 if ((dic->op == CALL || dic->op == PCALL) &&
2752 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2753 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2755 debugLog (" %d - \n", __LINE__);
2763 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2764 IS_OP_VOLATILE (IC_RESULT (dic)))
2766 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2771 if (IS_SYMOP (IC_RESULT (dic)) &&
2772 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2774 /* A previous result was assigned to the same register - we'll our definition */
2775 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2776 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2777 if (POINTER_SET (dic))
2783 if (IS_SYMOP (IC_RIGHT (dic)) &&
2784 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2785 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2787 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
2792 if (IS_SYMOP (IC_LEFT (dic)) &&
2793 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2794 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2796 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
2801 if (POINTER_SET (dic) &&
2802 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2804 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
2812 return 0; /* did not find */
2814 /* if the result is on stack or iaccess then it must be
2815 the same atleast one of the operands */
2816 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2817 OP_SYMBOL (IC_RESULT (ic))->iaccess)
2820 /* the operation has only one symbol
2821 operator then we can pack */
2822 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2823 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2826 if (!((IC_LEFT (dic) &&
2827 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2829 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2833 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2834 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
2835 /* found the definition */
2836 /* replace the result with the result of */
2837 /* this assignment and remove this assignment */
2838 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2839 IC_RESULT (dic) = IC_RESULT (ic);
2841 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2843 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2845 /* delete from liverange table also
2846 delete from all the points inbetween and the new
2848 for (sic = dic; sic != ic; sic = sic->next)
2850 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2851 if (IS_ITEMP (IC_RESULT (dic)))
2852 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2855 remiCodeFromeBBlock (ebp, ic);
2856 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2857 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2858 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2864 /*-----------------------------------------------------------------*/
2865 /* findAssignToSym : scanning backwards looks for first assig found */
2866 /*-----------------------------------------------------------------*/
2868 findAssignToSym (operand * op, iCode * ic)
2872 debugLog ("%s\n", __FUNCTION__);
2873 for (dic = ic->prev; dic; dic = dic->prev)
2876 /* if definition by assignment */
2877 if (dic->op == '=' &&
2878 !POINTER_SET (dic) &&
2879 IC_RESULT (dic)->key == op->key
2880 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2884 /* we are interested only if defined in far space */
2885 /* or in stack space in case of + & - */
2887 /* if assigned to a non-symbol then return
2889 if (!IS_SYMOP (IC_RIGHT (dic)))
2892 /* if the symbol is in far space then
2894 if (isOperandInFarSpace (IC_RIGHT (dic)))
2897 /* for + & - operations make sure that
2898 if it is on the stack it is the same
2899 as one of the three operands */
2900 if ((ic->op == '+' || ic->op == '-') &&
2901 OP_SYMBOL (IC_RIGHT (dic))->onStack)
2904 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2905 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2906 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2914 /* if we find an usage then we cannot delete it */
2915 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2918 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2921 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2925 /* now make sure that the right side of dic
2926 is not defined between ic & dic */
2929 iCode *sic = dic->next;
2931 for (; sic != ic; sic = sic->next)
2932 if (IC_RESULT (sic) &&
2933 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2942 /*-----------------------------------------------------------------*/
2943 /* packRegsForSupport :- reduce some registers for support calls */
2944 /*-----------------------------------------------------------------*/
2946 packRegsForSupport (iCode * ic, eBBlock * ebp)
2950 debugLog ("%s\n", __FUNCTION__);
2951 /* for the left & right operand :- look to see if the
2952 left was assigned a true symbol in far space in that
2953 case replace them */
2954 if (IS_ITEMP (IC_LEFT (ic)) &&
2955 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2957 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
2963 debugAopGet ("removing left:", IC_LEFT (ic));
2965 /* found it we need to remove it from the
2967 for (sic = dic; sic != ic; sic = sic->next)
2968 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
2970 IC_LEFT (ic)->operand.symOperand =
2971 IC_RIGHT (dic)->operand.symOperand;
2972 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2973 remiCodeFromeBBlock (ebp, dic);
2974 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2975 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2979 /* do the same for the right operand */
2982 IS_ITEMP (IC_RIGHT (ic)) &&
2983 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2985 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2991 /* if this is a subtraction & the result
2992 is a true symbol in far space then don't pack */
2993 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
2995 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
2996 if (IN_FARSPACE (SPEC_OCLS (etype)))
3000 debugAopGet ("removing right:", IC_RIGHT (ic));
3002 /* found it we need to remove it from the
3004 for (sic = dic; sic != ic; sic = sic->next)
3005 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3007 IC_RIGHT (ic)->operand.symOperand =
3008 IC_RIGHT (dic)->operand.symOperand;
3009 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3011 remiCodeFromeBBlock (ebp, dic);
3012 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3013 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3020 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3023 /*-----------------------------------------------------------------*/
3024 /* packRegsForOneuse : - will reduce some registers for single Use */
3025 /*-----------------------------------------------------------------*/
3027 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3032 debugLog ("%s\n", __FUNCTION__);
3033 /* if returning a literal then do nothing */
3037 /* only upto 2 bytes since we cannot predict
3038 the usage of b, & acc */
3039 if (getSize (operandType (op)) > (pic16_fReturnSizePic - 2) &&
3044 /* this routine will mark the a symbol as used in one
3045 instruction use only && if the definition is local
3046 (ie. within the basic block) && has only one definition &&
3047 that definition is either a return value from a
3048 function or does not contain any variables in
3050 uses = bitVectCopy (OP_USES (op));
3051 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3052 if (!bitVectIsZero (uses)) /* has other uses */
3055 /* if it has only one defintion */
3056 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3057 return NULL; /* has more than one definition */
3059 /* get that definition */
3061 hTabItemWithKey (iCodehTab,
3062 bitVectFirstBit (OP_DEFS (op)))))
3065 /* found the definition now check if it is local */
3066 if (dic->seq < ebp->fSeq ||
3067 dic->seq > ebp->lSeq)
3068 return NULL; /* non-local */
3070 /* now check if it is the return from
3072 if (dic->op == CALL || dic->op == PCALL)
3074 if (ic->op != SEND && ic->op != RETURN &&
3075 !POINTER_SET(ic) && !POINTER_GET(ic))
3077 OP_SYMBOL (op)->ruonly = 1;
3084 /* otherwise check that the definition does
3085 not contain any symbols in far space */
3086 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3087 isOperandInFarSpace (IC_RIGHT (dic)) ||
3088 IS_OP_RUONLY (IC_LEFT (ic)) ||
3089 IS_OP_RUONLY (IC_RIGHT (ic)))
3094 /* if pointer set then make sure the pointer
3096 if (POINTER_SET (dic) &&
3097 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3100 if (POINTER_GET (dic) &&
3101 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3106 /* also make sure the intervenening instructions
3107 don't have any thing in far space */
3108 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3111 /* if there is an intervening function call then no */
3112 if (dic->op == CALL || dic->op == PCALL)
3114 /* if pointer set then make sure the pointer
3116 if (POINTER_SET (dic) &&
3117 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3120 if (POINTER_GET (dic) &&
3121 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3124 /* if address of & the result is remat then okay */
3125 if (dic->op == ADDRESS_OF &&
3126 OP_SYMBOL (IC_RESULT (dic))->remat)
3129 /* if operand has size of three or more & this
3130 operation is a '*','/' or '%' then 'b' may
3132 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3133 getSize (operandType (op)) >= 3)
3136 /* if left or right or result is in far space */
3137 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3138 isOperandInFarSpace (IC_RIGHT (dic)) ||
3139 isOperandInFarSpace (IC_RESULT (dic)) ||
3140 IS_OP_RUONLY (IC_LEFT (dic)) ||
3141 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3142 IS_OP_RUONLY (IC_RESULT (dic)))
3148 OP_SYMBOL (op)->ruonly = 1;
3153 /*-----------------------------------------------------------------*/
3154 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3155 /*-----------------------------------------------------------------*/
3157 isBitwiseOptimizable (iCode * ic)
3159 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3160 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3162 debugLog ("%s\n", __FUNCTION__);
3163 /* bitwise operations are considered optimizable
3164 under the following conditions (Jean-Louis VERN)
3176 if (IS_LITERAL (rtype) ||
3177 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3183 /*-----------------------------------------------------------------*/
3184 /* packRegsForAccUse - pack registers for acc use */
3185 /*-----------------------------------------------------------------*/
3187 packRegsForAccUse (iCode * ic)
3191 debugLog ("%s\n", __FUNCTION__);
3193 /* if this is an aggregate, e.g. a one byte char array */
3194 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3197 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3199 /* if + or - then it has to be one byte result */
3200 if ((ic->op == '+' || ic->op == '-')
3201 && getSize (operandType (IC_RESULT (ic))) > 1)
3204 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3205 /* if shift operation make sure right side is not a literal */
3206 if (ic->op == RIGHT_OP &&
3207 (isOperandLiteral (IC_RIGHT (ic)) ||
3208 getSize (operandType (IC_RESULT (ic))) > 1))
3211 if (ic->op == LEFT_OP &&
3212 (isOperandLiteral (IC_RIGHT (ic)) ||
3213 getSize (operandType (IC_RESULT (ic))) > 1))
3216 if (IS_BITWISE_OP (ic) &&
3217 getSize (operandType (IC_RESULT (ic))) > 1)
3221 /* has only one definition */
3222 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3225 /* has only one use */
3226 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3229 /* and the usage immediately follows this iCode */
3230 if (!(uic = hTabItemWithKey (iCodehTab,
3231 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3234 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3235 if (ic->next != uic)
3238 /* if it is a conditional branch then we definitely can */
3242 if (uic->op == JUMPTABLE)
3245 /* if the usage is not is an assignment
3246 or an arithmetic / bitwise / shift operation then not */
3247 if (POINTER_SET (uic) &&
3248 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3251 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3252 if (uic->op != '=' &&
3253 !IS_ARITHMETIC_OP (uic) &&
3254 !IS_BITWISE_OP (uic) &&
3255 uic->op != LEFT_OP &&
3256 uic->op != RIGHT_OP)
3259 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3260 /* if used in ^ operation then make sure right is not a
3262 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3265 /* if shift operation make sure right side is not a literal */
3266 if (uic->op == RIGHT_OP &&
3267 (isOperandLiteral (IC_RIGHT (uic)) ||
3268 getSize (operandType (IC_RESULT (uic))) > 1))
3271 if (uic->op == LEFT_OP &&
3272 (isOperandLiteral (IC_RIGHT (uic)) ||
3273 getSize (operandType (IC_RESULT (uic))) > 1))
3276 /* make sure that the result of this icode is not on the
3277 stack, since acc is used to compute stack offset */
3278 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3279 OP_SYMBOL (IC_RESULT (uic))->onStack)
3282 /* if either one of them in far space then we cannot */
3283 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3284 isOperandInFarSpace (IC_LEFT (uic))) ||
3285 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3286 isOperandInFarSpace (IC_RIGHT (uic))))
3289 /* if the usage has only one operand then we can */
3290 if (IC_LEFT (uic) == NULL ||
3291 IC_RIGHT (uic) == NULL)
3294 /* make sure this is on the left side if not
3295 a '+' since '+' is commutative */
3296 if (ic->op != '+' &&
3297 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3300 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3301 /* if one of them is a literal then we can */
3302 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3303 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3304 (getSize (operandType (IC_RESULT (uic))) <= 1))
3306 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3310 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3311 /* if the other one is not on stack then we can */
3312 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3313 (IS_ITEMP (IC_RIGHT (uic)) ||
3314 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3315 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3318 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3319 (IS_ITEMP (IC_LEFT (uic)) ||
3320 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3321 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3327 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3328 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3333 /*-----------------------------------------------------------------*/
3334 /* packForPush - hueristics to reduce iCode for pushing */
3335 /*-----------------------------------------------------------------*/
3337 packForReceive (iCode * ic, eBBlock * ebp)
3341 debugLog ("%s\n", __FUNCTION__);
3342 debugAopGet (" result:", IC_RESULT (ic));
3343 debugAopGet (" left:", IC_LEFT (ic));
3344 debugAopGet (" right:", IC_RIGHT (ic));
3349 for (dic = ic->next; dic; dic = dic->next)
3354 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3355 debugLog (" used on left\n");
3356 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3357 debugLog (" used on right\n");
3358 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3359 debugLog (" used on result\n");
3361 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3362 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3367 debugLog (" hey we can remove this unnecessary assign\n");
3369 /*-----------------------------------------------------------------*/
3370 /* packForPush - hueristics to reduce iCode for pushing */
3371 /*-----------------------------------------------------------------*/
3373 packForPush (iCode * ic, eBBlock * ebp)
3377 debugLog ("%s\n", __FUNCTION__);
3378 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3381 /* must have only definition & one usage */
3382 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3383 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3386 /* find the definition */
3387 if (!(dic = hTabItemWithKey (iCodehTab,
3388 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3391 if (dic->op != '=' || POINTER_SET (dic))
3394 /* we now we know that it has one & only one def & use
3395 and the that the definition is an assignment */
3396 IC_LEFT (ic) = IC_RIGHT (dic);
3398 remiCodeFromeBBlock (ebp, dic);
3399 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3400 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3403 static void printSymType(char * str, sym_link *sl)
3405 debugLog (" %s Symbol type: ",str);
3406 printTypeChain( sl, debugF);
3411 /*-----------------------------------------------------------------*/
3412 /* some debug code to print the symbol S_TYPE. Note that
3413 * the function checkSClass in src/SDCCsymt.c dinks with
3414 * the S_TYPE in ways the PIC port doesn't fully like...*/
3415 /*-----------------------------------------------------------------*/
3416 static void isData(sym_link *sl)
3426 for ( ; sl; sl=sl->next) {
3428 switch (SPEC_SCLS(sl)) {
3430 case S_DATA: fprintf (of, "data "); break;
3431 case S_XDATA: fprintf (of, "xdata "); break;
3432 case S_SFR: fprintf (of, "sfr "); break;
3433 case S_SBIT: fprintf (of, "sbit "); break;
3434 case S_CODE: fprintf (of, "code "); break;
3435 case S_IDATA: fprintf (of, "idata "); break;
3436 case S_PDATA: fprintf (of, "pdata "); break;
3437 case S_LITERAL: fprintf (of, "literal "); break;
3438 case S_STACK: fprintf (of, "stack "); break;
3439 case S_XSTACK: fprintf (of, "xstack "); break;
3440 case S_BIT: fprintf (of, "bit "); break;
3441 case S_EEPROM: fprintf (of, "eeprom "); break;
3450 /*-----------------------------------------------------------------*/
3451 /* packRegisters - does some transformations to reduce register */
3453 /*-----------------------------------------------------------------*/
3455 packRegisters (eBBlock * ebp)
3460 debugLog ("%s\n", __FUNCTION__);
3466 /* look for assignments of the form */
3467 /* iTempNN = TRueSym (someoperation) SomeOperand */
3469 /* TrueSym := iTempNN:1 */
3470 for (ic = ebp->sch; ic; ic = ic->next)
3473 /* find assignment of the form TrueSym := iTempNN:1 */
3474 if (ic->op == '=' && !POINTER_SET (ic))
3475 change += packRegsForAssign (ic, ebp);
3479 if (POINTER_SET (ic))
3480 debugLog ("pointer is set\n");
3481 debugAopGet (" result:", IC_RESULT (ic));
3482 debugAopGet (" left:", IC_LEFT (ic));
3483 debugAopGet (" right:", IC_RIGHT (ic));
3492 for (ic = ebp->sch; ic; ic = ic->next) {
3494 if(IS_SYMOP ( IC_LEFT(ic))) {
3495 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3497 debugAopGet (" left:", IC_LEFT (ic));
3498 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3499 debugLog (" is a pointer\n");
3501 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3502 debugLog (" is volatile\n");
3506 printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
3509 if(IS_SYMOP ( IC_RIGHT(ic))) {
3510 debugAopGet (" right:", IC_RIGHT (ic));
3511 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3514 if(IS_SYMOP ( IC_RESULT(ic))) {
3515 debugAopGet (" result:", IC_RESULT (ic));
3516 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3519 if (POINTER_SET (ic))
3520 debugLog (" %d - Pointer set\n", __LINE__);
3523 /* if this is an itemp & result of a address of a true sym
3524 then mark this as rematerialisable */
3525 if (ic->op == ADDRESS_OF &&
3526 IS_ITEMP (IC_RESULT (ic)) &&
3527 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3528 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3529 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3532 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3534 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3535 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3536 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3540 /* if straight assignment then carry remat flag if
3541 this is the only definition */
3542 if (ic->op == '=' &&
3543 !POINTER_SET (ic) &&
3544 IS_SYMOP (IC_RIGHT (ic)) &&
3545 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3546 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3548 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3550 OP_SYMBOL (IC_RESULT (ic))->remat =
3551 OP_SYMBOL (IC_RIGHT (ic))->remat;
3552 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3553 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3556 /* if this is a +/- operation with a rematerizable
3557 then mark this as rematerializable as well */
3558 if ((ic->op == '+' || ic->op == '-') &&
3559 (IS_SYMOP (IC_LEFT (ic)) &&
3560 IS_ITEMP (IC_RESULT (ic)) &&
3561 OP_SYMBOL (IC_LEFT (ic))->remat &&
3562 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3563 IS_OP_LITERAL (IC_RIGHT (ic))))
3565 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3567 operandLitValue (IC_RIGHT (ic));
3568 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3569 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3570 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3573 /* mark the pointer usages */
3574 if (POINTER_SET (ic))
3576 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3577 debugLog (" marking as a pointer (set) =>");
3578 debugAopGet (" result:", IC_RESULT (ic));
3580 if (POINTER_GET (ic))
3582 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3583 debugLog (" marking as a pointer (get) =>");
3584 debugAopGet (" left:", IC_LEFT (ic));
3589 /* if we are using a symbol on the stack
3590 then we should say pic16_ptrRegReq */
3591 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3592 pic16_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3593 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3594 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3595 pic16_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3596 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3599 if (IS_SYMOP (IC_LEFT (ic)))
3600 pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3601 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3602 if (IS_SYMOP (IC_RIGHT (ic)))
3603 pic16_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3604 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3605 if (IS_SYMOP (IC_RESULT (ic)))
3606 pic16_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3607 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3610 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic16_ptrRegReq);
3614 /* if the condition of an if instruction
3615 is defined in the previous instruction then
3616 mark the itemp as a conditional */
3617 if ((IS_CONDITIONAL (ic) ||
3618 ((ic->op == BITWISEAND ||
3621 isBitwiseOptimizable (ic))) &&
3622 ic->next && ic->next->op == IFX &&
3623 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3624 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3627 debugLog (" %d\n", __LINE__);
3628 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3632 /* reduce for support function calls */
3633 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3634 packRegsForSupport (ic, ebp);
3636 /* if a parameter is passed, it's in W, so we may not
3637 need to place a copy in a register */
3638 if (ic->op == RECEIVE)
3639 packForReceive (ic, ebp);
3641 /* some cases the redundant moves can
3642 can be eliminated for return statements */
3643 if ((ic->op == RETURN || ic->op == SEND) &&
3644 !isOperandInFarSpace (IC_LEFT (ic)) &&
3646 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3648 /* if pointer set & left has a size more than
3649 one and right is not in far space */
3650 if (POINTER_SET (ic) &&
3651 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3652 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3653 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3654 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3656 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3658 /* if pointer get */
3659 if (POINTER_GET (ic) &&
3660 !isOperandInFarSpace (IC_RESULT (ic)) &&
3661 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3662 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3663 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3665 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3668 /* if this is cast for intergral promotion then
3669 check if only use of the definition of the
3670 operand being casted/ if yes then replace
3671 the result of that arithmetic operation with
3672 this result and get rid of the cast */
3673 if (ic->op == CAST) {
3675 sym_link *fromType = operandType (IC_RIGHT (ic));
3676 sym_link *toType = operandType (IC_LEFT (ic));
3678 debugLog (" %d - casting\n", __LINE__);
3680 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3681 getSize (fromType) != getSize (toType)) {
3684 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3687 if (IS_ARITHMETIC_OP (dic)) {
3689 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3690 IC_RESULT (dic) = IC_RESULT (ic);
3691 remiCodeFromeBBlock (ebp, ic);
3692 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3693 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3694 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3698 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3702 /* if the type from and type to are the same
3703 then if this is the only use then packit */
3704 if (compareType (operandType (IC_RIGHT (ic)),
3705 operandType (IC_LEFT (ic))) == 1) {
3707 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3710 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3711 IC_RESULT (dic) = IC_RESULT (ic);
3712 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3713 remiCodeFromeBBlock (ebp, ic);
3714 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3715 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3723 iTempNN := (some variable in farspace) V1
3728 if (ic->op == IPUSH)
3730 packForPush (ic, ebp);
3734 /* pack registers for accumulator use, when the
3735 result of an arithmetic or bit wise operation
3736 has only one use, that use is immediately following
3737 the defintion and the using iCode has only one
3738 operand or has two operands but one is literal &
3739 the result of that operation is not on stack then
3740 we can leave the result of this operation in acc:b
3742 if ((IS_ARITHMETIC_OP (ic)
3744 || IS_BITWISE_OP (ic)
3746 || ic->op == LEFT_OP || ic->op == RIGHT_OP
3749 IS_ITEMP (IC_RESULT (ic)) &&
3750 getSize (operandType (IC_RESULT (ic))) <= 2)
3752 packRegsForAccUse (ic);
3758 dumpEbbsToDebug (eBBlock ** ebbs, int count)
3762 if (!debug || !debugF)
3765 for (i = 0; i < count; i++)
3767 fprintf (debugF, "\n----------------------------------------------------------------\n");
3768 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
3769 ebbs[i]->entryLabel->name,
3772 ebbs[i]->isLastInLoop);
3773 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
3778 fprintf (debugF, "visited %d : hasFcall = %d\n",
3782 fprintf (debugF, "\ndefines bitVector :");
3783 bitVectDebugOn (ebbs[i]->defSet, debugF);
3784 fprintf (debugF, "\nlocal defines bitVector :");
3785 bitVectDebugOn (ebbs[i]->ldefs, debugF);
3786 fprintf (debugF, "\npointers Set bitvector :");
3787 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
3788 fprintf (debugF, "\nin pointers Set bitvector :");
3789 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
3790 fprintf (debugF, "\ninDefs Set bitvector :");
3791 bitVectDebugOn (ebbs[i]->inDefs, debugF);
3792 fprintf (debugF, "\noutDefs Set bitvector :");
3793 bitVectDebugOn (ebbs[i]->outDefs, debugF);
3794 fprintf (debugF, "\nusesDefs Set bitvector :");
3795 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
3796 fprintf (debugF, "\n----------------------------------------------------------------\n");
3797 printiCChain (ebbs[i]->sch, debugF);
3800 /*-----------------------------------------------------------------*/
3801 /* pic16_assignRegisters - assigns registers to each live range as need */
3802 /*-----------------------------------------------------------------*/
3804 pic16_assignRegisters (eBBlock ** ebbs, int count)
3809 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
3810 debugLog ("\nebbs before optimizing:\n");
3811 dumpEbbsToDebug (ebbs, count);
3813 setToNull ((void *) &_G.funcrUsed);
3814 pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3817 /* change assignments this will remove some
3818 live ranges reducing some register pressure */
3819 for (i = 0; i < count; i++)
3820 packRegisters (ebbs[i]);
3827 debugLog("dir registers allocated so far:\n");
3828 reg = hTabFirstItem(dynDirectRegNames, &hkey);
3831 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
3832 reg = hTabNextItem(dynDirectRegNames, &hkey);
3837 if (options.dump_pack)
3838 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3840 /* first determine for each live range the number of
3841 registers & the type of registers required for each */
3844 /* and serially allocate registers */
3845 serialRegAssign (ebbs, count);
3847 /* if stack was extended then tell the user */
3850 /* werror(W_TOOMANY_SPILS,"stack", */
3851 /* _G.stackExtend,currFunc->name,""); */
3857 /* werror(W_TOOMANY_SPILS,"data space", */
3858 /* _G.dataExtend,currFunc->name,""); */
3862 /* after that create the register mask
3863 for each of the instruction */
3864 createRegMask (ebbs, count);
3866 /* redo that offsets for stacked automatic variables */
3867 redoStackOffsets ();
3869 if (options.dump_rassgn)
3870 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3872 /* now get back the chain */
3873 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3875 debugLog ("ebbs after optimizing:\n");
3876 dumpEbbsToDebug (ebbs, count);
3881 /* free up any _G.stackSpil locations allocated */
3882 applyToSet (_G.stackSpil, deallocStackSpil);
3884 setToNull ((void **) &_G.stackSpil);
3885 setToNull ((void **) &_G.spiltSet);
3886 /* mark all registers as free */
3887 //pic16_freeAllRegs ();
3889 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");