1 /*------------------------------------------------------------------------
3 ralloc.c - source file for register allocation. PIC16 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));
2505 if(IS_PTR_CONST (sym->type)) {
2507 if(IS_CODEPTR (sym->type)) {
2509 debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2513 if (sym->nRegs > 4) {
2514 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2515 printTypeChain (sym->type, stderr);
2516 fprintf (stderr, "\n");
2519 /* determine the type of register required */
2520 if (sym->nRegs == 1 &&
2521 IS_PTR (sym->type) &&
2523 sym->regType = REG_PTR;
2525 sym->regType = REG_GPR;
2528 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2532 /* for the first run we don't provide */
2533 /* registers for true symbols we will */
2534 /* see how things go */
2539 static DEFSETFUNC (markRegFree)
2541 ((regs *)item)->isFree = 1;
2546 DEFSETFUNC (pic16_deallocReg)
2548 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2549 ((regs *)item)->isFree = 1;
2550 ((regs *)item)->wasUsed = 0;
2554 /*-----------------------------------------------------------------*/
2555 /* freeAllRegs - mark all registers as free */
2556 /*-----------------------------------------------------------------*/
2558 pic16_freeAllRegs ()
2562 debugLog ("%s\n", __FUNCTION__);
2564 applyToSet(pic16_dynAllocRegs,markRegFree);
2565 applyToSet(pic16_dynStackRegs,markRegFree);
2568 for (i = 0; i < pic16_nRegs; i++)
2569 regspic16[i].isFree = 1;
2573 /*-----------------------------------------------------------------*/
2574 /*-----------------------------------------------------------------*/
2576 pic16_deallocateAllRegs ()
2580 debugLog ("%s\n", __FUNCTION__);
2582 applyToSet(pic16_dynAllocRegs,pic16_deallocReg);
2585 for (i = 0; i < pic16_nRegs; i++) {
2586 if(regspic16[i].pc_type == PO_GPR_TEMP) {
2587 regspic16[i].isFree = 1;
2588 regspic16[i].wasUsed = 0;
2595 /*-----------------------------------------------------------------*/
2596 /* deallocStackSpil - this will set the stack pointer back */
2597 /*-----------------------------------------------------------------*/
2599 DEFSETFUNC (deallocStackSpil)
2603 debugLog ("%s\n", __FUNCTION__);
2608 /*-----------------------------------------------------------------*/
2609 /* farSpacePackable - returns the packable icode for far variables */
2610 /*-----------------------------------------------------------------*/
2612 farSpacePackable (iCode * ic)
2616 debugLog ("%s\n", __FUNCTION__);
2617 /* go thru till we find a definition for the
2618 symbol on the right */
2619 for (dic = ic->prev; dic; dic = dic->prev)
2622 /* if the definition is a call then no */
2623 if ((dic->op == CALL || dic->op == PCALL) &&
2624 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2629 /* if shift by unknown amount then not */
2630 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2631 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2634 /* if pointer get and size > 1 */
2635 if (POINTER_GET (dic) &&
2636 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2639 if (POINTER_SET (dic) &&
2640 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2643 /* if any three is a true symbol in far space */
2644 if (IC_RESULT (dic) &&
2645 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2646 isOperandInFarSpace (IC_RESULT (dic)))
2649 if (IC_RIGHT (dic) &&
2650 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2651 isOperandInFarSpace (IC_RIGHT (dic)) &&
2652 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2655 if (IC_LEFT (dic) &&
2656 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2657 isOperandInFarSpace (IC_LEFT (dic)) &&
2658 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2661 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2663 if ((dic->op == LEFT_OP ||
2664 dic->op == RIGHT_OP ||
2666 IS_OP_LITERAL (IC_RIGHT (dic)))
2676 /*-----------------------------------------------------------------*/
2677 /* packRegsForAssign - register reduction for assignment */
2678 /*-----------------------------------------------------------------*/
2680 packRegsForAssign (iCode * ic, eBBlock * ebp)
2685 debugLog ("%s\n", __FUNCTION__);
2687 debugAopGet (" result:", IC_RESULT (ic));
2688 debugAopGet (" left:", IC_LEFT (ic));
2689 debugAopGet (" right:", IC_RIGHT (ic));
2691 /* if this is at an absolute address, then get the address. */
2692 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2693 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2694 debugLog (" %d - found config word declaration\n", __LINE__);
2695 if(IS_VALOP(IC_RIGHT(ic))) {
2696 debugLog (" setting config word to %x\n",
2697 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2698 pic16_assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2699 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2702 /* remove the assignment from the iCode chain. */
2704 remiCodeFromeBBlock (ebp, ic);
2705 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2706 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2713 if (!IS_ITEMP (IC_RESULT (ic))) {
2714 pic16_allocDirReg(IC_RESULT (ic));
2715 debugLog (" %d - result is not temp\n", __LINE__);
2718 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2719 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2720 pic16_allocDirReg(IC_LEFT (ic));
2724 if (!IS_ITEMP (IC_RIGHT (ic))) {
2725 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2726 pic16_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)) > (pic16_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 static 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 static 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 /* pic16_packRegisters - does some transformations to reduce */
3456 /* register pressure */
3458 /*--------------------------------------------------------------------*/
3460 pic16_packRegisters (eBBlock * ebp)
3465 debugLog ("%s\n", __FUNCTION__);
3471 /* look for assignments of the form */
3472 /* iTempNN = TRueSym (someoperation) SomeOperand */
3474 /* TrueSym := iTempNN:1 */
3475 for (ic = ebp->sch; ic; ic = ic->next)
3478 /* find assignment of the form TrueSym := iTempNN:1 */
3479 /* see BUGLOG0001 for workaround with the CAST - VR */
3480 if ((ic->op == '=' || ic->op == CAST) && !POINTER_SET (ic))
3481 change += packRegsForAssign (ic, ebp);
3485 if (POINTER_SET (ic))
3486 debugLog ("pointer is set\n");
3487 debugAopGet (" result:", IC_RESULT (ic));
3488 debugAopGet (" left:", IC_LEFT (ic));
3489 debugAopGet (" right:", IC_RIGHT (ic));
3498 for (ic = ebp->sch; ic; ic = ic->next) {
3500 if(IS_SYMOP ( IC_LEFT(ic))) {
3501 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3503 debugAopGet (" left:", IC_LEFT (ic));
3505 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3507 if(IS_CODEPTR(OP_SYMBOL(IC_LEFT(ic))->type))
3509 debugLog (" is a pointer\n");
3511 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3512 debugLog (" is volatile\n");
3516 printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
3519 if(IS_SYMOP ( IC_RIGHT(ic))) {
3520 debugAopGet (" right:", IC_RIGHT (ic));
3521 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3524 if(IS_SYMOP ( IC_RESULT(ic))) {
3525 debugAopGet (" result:", IC_RESULT (ic));
3526 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3529 if (POINTER_SET (ic))
3530 debugLog (" %d - Pointer set\n", __LINE__);
3533 /* if this is an itemp & result of a address of a true sym
3534 then mark this as rematerialisable */
3535 if (ic->op == ADDRESS_OF &&
3536 IS_ITEMP (IC_RESULT (ic)) &&
3537 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3538 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3539 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3542 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3544 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3545 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3546 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3550 /* if straight assignment then carry remat flag if
3551 this is the only definition */
3552 if (ic->op == '=' &&
3553 !POINTER_SET (ic) &&
3554 IS_SYMOP (IC_RIGHT (ic)) &&
3555 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3556 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3558 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3560 OP_SYMBOL (IC_RESULT (ic))->remat =
3561 OP_SYMBOL (IC_RIGHT (ic))->remat;
3562 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3563 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3566 /* if this is a +/- operation with a rematerizable
3567 then mark this as rematerializable as well */
3568 if ((ic->op == '+' || ic->op == '-') &&
3569 (IS_SYMOP (IC_LEFT (ic)) &&
3570 IS_ITEMP (IC_RESULT (ic)) &&
3571 OP_SYMBOL (IC_LEFT (ic))->remat &&
3572 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3573 IS_OP_LITERAL (IC_RIGHT (ic))))
3575 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3577 operandLitValue (IC_RIGHT (ic));
3578 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3579 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3580 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3583 /* mark the pointer usages */
3584 if (POINTER_SET (ic))
3586 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3587 debugLog (" marking as a pointer (set) =>");
3588 debugAopGet (" result:", IC_RESULT (ic));
3590 if (POINTER_GET (ic))
3592 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3593 debugLog (" marking as a pointer (get) =>");
3594 debugAopGet (" left:", IC_LEFT (ic));
3599 /* if we are using a symbol on the stack
3600 then we should say pic16_ptrRegReq */
3601 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3602 pic16_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3603 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3604 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3605 pic16_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3606 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3609 if (IS_SYMOP (IC_LEFT (ic)))
3610 pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3611 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3612 if (IS_SYMOP (IC_RIGHT (ic)))
3613 pic16_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3614 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3615 if (IS_SYMOP (IC_RESULT (ic)))
3616 pic16_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3617 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3620 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic16_ptrRegReq);
3624 /* if the condition of an if instruction
3625 is defined in the previous instruction then
3626 mark the itemp as a conditional */
3627 if ((IS_CONDITIONAL (ic) ||
3628 ((ic->op == BITWISEAND ||
3631 isBitwiseOptimizable (ic))) &&
3632 ic->next && ic->next->op == IFX &&
3633 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3634 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3637 debugLog (" %d\n", __LINE__);
3638 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3642 /* reduce for support function calls */
3643 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3644 packRegsForSupport (ic, ebp);
3646 /* if a parameter is passed, it's in W, so we may not
3647 need to place a copy in a register */
3648 if (ic->op == RECEIVE)
3649 packForReceive (ic, ebp);
3651 /* some cases the redundant moves can
3652 can be eliminated for return statements */
3653 if ((ic->op == RETURN || ic->op == SEND) &&
3654 !isOperandInFarSpace (IC_LEFT (ic)) &&
3656 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3658 /* if pointer set & left has a size more than
3659 one and right is not in far space */
3660 if (POINTER_SET (ic) &&
3661 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3662 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3663 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3664 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3666 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3668 /* if pointer get */
3669 if (POINTER_GET (ic) &&
3670 !isOperandInFarSpace (IC_RESULT (ic)) &&
3671 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3672 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3673 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3675 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3678 /* if this is cast for intergral promotion then
3679 check if only use of the definition of the
3680 operand being casted/ if yes then replace
3681 the result of that arithmetic operation with
3682 this result and get rid of the cast */
3683 if (ic->op == CAST) {
3685 sym_link *fromType = operandType (IC_RIGHT (ic));
3686 sym_link *toType = operandType (IC_LEFT (ic));
3688 debugLog (" %d - casting\n", __LINE__);
3690 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3691 getSize (fromType) != getSize (toType)) {
3694 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3697 if (IS_ARITHMETIC_OP (dic)) {
3699 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3700 IC_RESULT (dic) = IC_RESULT (ic);
3701 remiCodeFromeBBlock (ebp, ic);
3702 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3703 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3704 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3708 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3712 /* if the type from and type to are the same
3713 then if this is the only use then packit */
3714 if (compareType (operandType (IC_RIGHT (ic)),
3715 operandType (IC_LEFT (ic))) == 1) {
3717 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3720 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3721 IC_RESULT (dic) = IC_RESULT (ic);
3722 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3723 remiCodeFromeBBlock (ebp, ic);
3724 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3725 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3733 iTempNN := (some variable in farspace) V1
3738 if (ic->op == IPUSH)
3740 packForPush (ic, ebp);
3744 /* pack registers for accumulator use, when the
3745 result of an arithmetic or bit wise operation
3746 has only one use, that use is immediately following
3747 the defintion and the using iCode has only one
3748 operand or has two operands but one is literal &
3749 the result of that operation is not on stack then
3750 we can leave the result of this operation in acc:b
3752 if ((IS_ARITHMETIC_OP (ic)
3754 || IS_BITWISE_OP (ic)
3756 || ic->op == LEFT_OP || ic->op == RIGHT_OP
3759 IS_ITEMP (IC_RESULT (ic)) &&
3760 getSize (operandType (IC_RESULT (ic))) <= 2)
3762 packRegsForAccUse (ic);
3768 dumpEbbsToDebug (eBBlock ** ebbs, int count)
3772 if (!debug || !debugF)
3775 for (i = 0; i < count; i++)
3777 fprintf (debugF, "\n----------------------------------------------------------------\n");
3778 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
3779 ebbs[i]->entryLabel->name,
3782 ebbs[i]->isLastInLoop);
3783 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
3788 fprintf (debugF, "visited %d : hasFcall = %d\n",
3792 fprintf (debugF, "\ndefines bitVector :");
3793 bitVectDebugOn (ebbs[i]->defSet, debugF);
3794 fprintf (debugF, "\nlocal defines bitVector :");
3795 bitVectDebugOn (ebbs[i]->ldefs, debugF);
3796 fprintf (debugF, "\npointers Set bitvector :");
3797 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
3798 fprintf (debugF, "\nin pointers Set bitvector :");
3799 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
3800 fprintf (debugF, "\ninDefs Set bitvector :");
3801 bitVectDebugOn (ebbs[i]->inDefs, debugF);
3802 fprintf (debugF, "\noutDefs Set bitvector :");
3803 bitVectDebugOn (ebbs[i]->outDefs, debugF);
3804 fprintf (debugF, "\nusesDefs Set bitvector :");
3805 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
3806 fprintf (debugF, "\n----------------------------------------------------------------\n");
3807 printiCChain (ebbs[i]->sch, debugF);
3810 /*-----------------------------------------------------------------*/
3811 /* pic16_assignRegisters - assigns registers to each live range as need */
3812 /*-----------------------------------------------------------------*/
3814 pic16_assignRegisters (eBBlock ** ebbs, int count)
3819 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
3820 debugLog ("\nebbs before optimizing:\n");
3821 dumpEbbsToDebug (ebbs, count);
3823 setToNull ((void *) &_G.funcrUsed);
3824 pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3827 /* change assignments this will remove some
3828 live ranges reducing some register pressure */
3829 for (i = 0; i < count; i++)
3830 pic16_packRegisters (ebbs[i]);
3837 debugLog("dir registers allocated so far:\n");
3838 reg = hTabFirstItem(dynDirectRegNames, &hkey);
3841 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
3842 reg = hTabNextItem(dynDirectRegNames, &hkey);
3847 /* liveranges probably changed by register packing
3848 so we compute them again */
3849 recomputeLiveRanges (ebbs, count);
3851 if (options.dump_pack)
3852 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3854 /* first determine for each live range the number of
3855 registers & the type of registers required for each */
3858 /* and serially allocate registers */
3859 serialRegAssign (ebbs, count);
3861 /* if stack was extended then tell the user */
3864 /* werror(W_TOOMANY_SPILS,"stack", */
3865 /* _G.stackExtend,currFunc->name,""); */
3871 /* werror(W_TOOMANY_SPILS,"data space", */
3872 /* _G.dataExtend,currFunc->name,""); */
3876 /* after that create the register mask
3877 for each of the instruction */
3878 createRegMask (ebbs, count);
3880 /* redo that offsets for stacked automatic variables */
3881 redoStackOffsets ();
3883 if (options.dump_rassgn)
3884 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3886 /* now get back the chain */
3887 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3889 debugLog ("ebbs after optimizing:\n");
3890 dumpEbbsToDebug (ebbs, count);
3895 /* free up any _G.stackSpil locations allocated */
3896 applyToSet (_G.stackSpil, deallocStackSpil);
3898 setToNull ((void *) &_G.stackSpil);
3899 setToNull ((void *) &_G.spiltSet);
3900 /* mark all registers as free */
3901 //pic16_freeAllRegs ();
3903 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");