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++;
1023 static void bitEQUs(FILE *of, set *bregs)
1025 regs *breg,*bytereg;
1028 //fprintf(stderr," %s\n",__FUNCTION__);
1029 for (breg = setFirstItem(bregs) ; breg ;
1030 breg = setNextItem(bregs)) {
1032 //fprintf(stderr,"bit reg: %s\n",breg->name);
1034 bytereg = breg->reg_alias;
1036 fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
1039 breg->rIdx & 0x0007);
1042 fprintf(stderr, "bit field is not assigned to a register\n");
1043 fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
1054 static void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
1059 for (reg = setFirstItem(fregs) ; reg ;
1060 reg = setNextItem(fregs)) {
1062 if(!reg->isEmitted && reg->wasUsed) {
1064 if (reg->type != REG_SFR) {
1065 fprintf (of, "%s\tEQU\t0x%03x\n",
1071 fprintf (of, "%s\tEQU\t0x%03x\n",
1079 void pic16_writeUsedRegs(FILE *of)
1081 packBits(pic16_dynDirectBitRegs);
1084 pic16_assignFixedRegisters(pic16_dynAllocRegs);
1085 pic16_assignFixedRegisters(pic16_dynStackRegs);
1086 pic16_assignFixedRegisters(pic16_dynDirectRegs);
1088 pic16_assignRelocatableRegisters(pic16_dynInternalRegs,0);
1089 pic16_assignRelocatableRegisters(pic16_dynAllocRegs,0);
1090 pic16_assignRelocatableRegisters(pic16_dynStackRegs,0);
1091 pic16_assignRelocatableRegisters(pic16_dynDirectRegs,0);
1095 pic16_dump_cblock(of);
1098 bitEQUs(of,pic16_dynDirectBitRegs);
1099 aliasEQUs(of,pic16_dynAllocRegs,0);
1100 aliasEQUs(of,pic16_dynDirectRegs,0);
1101 aliasEQUs(of,pic16_dynStackRegs,0);
1102 aliasEQUs(of,pic16_dynProcessorRegs,1);
1108 /*-----------------------------------------------------------------*/
1109 /* allDefsOutOfRange - all definitions are out of a range */
1110 /*-----------------------------------------------------------------*/
1112 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
1116 debugLog ("%s\n", __FUNCTION__);
1120 for (i = 0; i < defs->size; i++)
1124 if (bitVectBitValue (defs, i) &&
1125 (ic = hTabItemWithKey (iCodehTab, i)) &&
1126 (ic->seq >= fseq && ic->seq <= toseq))
1136 /*-----------------------------------------------------------------*/
1137 /* computeSpillable - given a point find the spillable live ranges */
1138 /*-----------------------------------------------------------------*/
1140 computeSpillable (iCode * ic)
1144 debugLog ("%s\n", __FUNCTION__);
1145 /* spillable live ranges are those that are live at this
1146 point . the following categories need to be subtracted
1148 a) - those that are already spilt
1149 b) - if being used by this one
1150 c) - defined by this one */
1152 spillable = bitVectCopy (ic->rlive);
1154 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1156 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1157 bitVectUnSetBit (spillable, ic->defKey);
1158 spillable = bitVectIntersect (spillable, _G.regAssigned);
1163 /*-----------------------------------------------------------------*/
1164 /* noSpilLoc - return true if a variable has no spil location */
1165 /*-----------------------------------------------------------------*/
1167 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1169 debugLog ("%s\n", __FUNCTION__);
1170 return (sym->usl.spillLoc ? 0 : 1);
1173 /*-----------------------------------------------------------------*/
1174 /* hasSpilLoc - will return 1 if the symbol has spil location */
1175 /*-----------------------------------------------------------------*/
1177 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1179 debugLog ("%s\n", __FUNCTION__);
1180 return (sym->usl.spillLoc ? 1 : 0);
1183 /*-----------------------------------------------------------------*/
1184 /* directSpilLoc - will return 1 if the splilocation is in direct */
1185 /*-----------------------------------------------------------------*/
1187 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1189 debugLog ("%s\n", __FUNCTION__);
1190 if (sym->usl.spillLoc &&
1191 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1197 /*-----------------------------------------------------------------*/
1198 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1199 /* but is not used as a pointer */
1200 /*-----------------------------------------------------------------*/
1202 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1204 debugLog ("%s\n", __FUNCTION__);
1205 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1208 /*-----------------------------------------------------------------*/
1209 /* rematable - will return 1 if the remat flag is set */
1210 /*-----------------------------------------------------------------*/
1212 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1214 debugLog ("%s\n", __FUNCTION__);
1218 /*-----------------------------------------------------------------*/
1219 /* notUsedInRemaining - not used or defined in remain of the block */
1220 /*-----------------------------------------------------------------*/
1222 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1224 debugLog ("%s\n", __FUNCTION__);
1225 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1226 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1229 /*-----------------------------------------------------------------*/
1230 /* allLRs - return true for all */
1231 /*-----------------------------------------------------------------*/
1233 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1235 debugLog ("%s\n", __FUNCTION__);
1239 /*-----------------------------------------------------------------*/
1240 /* liveRangesWith - applies function to a given set of live range */
1241 /*-----------------------------------------------------------------*/
1243 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1244 eBBlock * ebp, iCode * ic)
1249 debugLog ("%s\n", __FUNCTION__);
1250 if (!lrs || !lrs->size)
1253 for (i = 1; i < lrs->size; i++)
1256 if (!bitVectBitValue (lrs, i))
1259 /* if we don't find it in the live range
1260 hash table we are in serious trouble */
1261 if (!(sym = hTabItemWithKey (liveRanges, i)))
1263 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1264 "liveRangesWith could not find liveRange");
1268 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1269 addSetHead (&rset, sym);
1276 /*-----------------------------------------------------------------*/
1277 /* leastUsedLR - given a set determines which is the least used */
1278 /*-----------------------------------------------------------------*/
1280 leastUsedLR (set * sset)
1282 symbol *sym = NULL, *lsym = NULL;
1284 debugLog ("%s\n", __FUNCTION__);
1285 sym = lsym = setFirstItem (sset);
1290 for (; lsym; lsym = setNextItem (sset))
1293 /* if usage is the same then prefer
1294 the spill the smaller of the two */
1295 if (lsym->used == sym->used)
1296 if (getSize (lsym->type) < getSize (sym->type))
1300 if (lsym->used < sym->used)
1305 setToNull ((void **) &sset);
1310 /*-----------------------------------------------------------------*/
1311 /* noOverLap - will iterate through the list looking for over lap */
1312 /*-----------------------------------------------------------------*/
1314 noOverLap (set * itmpStack, symbol * fsym)
1317 debugLog ("%s\n", __FUNCTION__);
1320 for (sym = setFirstItem (itmpStack); sym;
1321 sym = setNextItem (itmpStack))
1323 if (sym->liveTo > fsym->liveFrom)
1331 /*-----------------------------------------------------------------*/
1332 /* isFree - will return 1 if the a free spil location is found */
1333 /*-----------------------------------------------------------------*/
1338 V_ARG (symbol **, sloc);
1339 V_ARG (symbol *, fsym);
1341 debugLog ("%s\n", __FUNCTION__);
1342 /* if already found */
1346 /* if it is free && and the itmp assigned to
1347 this does not have any overlapping live ranges
1348 with the one currently being assigned and
1349 the size can be accomodated */
1351 noOverLap (sym->usl.itmpStack, fsym) &&
1352 getSize (sym->type) >= getSize (fsym->type))
1361 /*-----------------------------------------------------------------*/
1362 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1363 /*-----------------------------------------------------------------*/
1365 spillLRWithPtrReg (symbol * forSym)
1371 debugLog ("%s\n", __FUNCTION__);
1372 if (!_G.regAssigned ||
1373 bitVectIsZero (_G.regAssigned))
1376 r0 = pic16_regWithIdx (R0_IDX);
1377 r1 = pic16_regWithIdx (R1_IDX);
1379 /* for all live ranges */
1380 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1381 lrsym = hTabNextItem (liveRanges, &k))
1385 /* if no registers assigned to it or
1387 /* if it does not overlap with this then
1388 not need to spill it */
1390 if (lrsym->isspilt || !lrsym->nRegs ||
1391 (lrsym->liveTo < forSym->liveFrom))
1394 /* go thru the registers : if it is either
1395 r0 or r1 then spil it */
1396 for (j = 0; j < lrsym->nRegs; j++)
1397 if (lrsym->regs[j] == r0 ||
1398 lrsym->regs[j] == r1)
1407 /*-----------------------------------------------------------------*/
1408 /* createStackSpil - create a location on the stack to spil */
1409 /*-----------------------------------------------------------------*/
1411 createStackSpil (symbol * sym)
1413 symbol *sloc = NULL;
1414 int useXstack, model, noOverlay;
1416 char slocBuffer[30];
1417 debugLog ("%s\n", __FUNCTION__);
1419 /* first go try and find a free one that is already
1420 existing on the stack */
1421 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1423 /* found a free one : just update & return */
1424 sym->usl.spillLoc = sloc;
1427 addSetHead (&sloc->usl.itmpStack, sym);
1431 /* could not then have to create one , this is the hard part
1432 we need to allocate this on the stack : this is really a
1433 hack!! but cannot think of anything better at this time */
1435 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1437 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1438 __FILE__, __LINE__);
1442 sloc = newiTemp (slocBuffer);
1444 /* set the type to the spilling symbol */
1445 sloc->type = copyLinkChain (sym->type);
1446 sloc->etype = getSpec (sloc->type);
1447 SPEC_SCLS (sloc->etype) = S_DATA;
1448 SPEC_EXTR (sloc->etype) = 0;
1449 SPEC_STAT (sloc->etype) = 0;
1451 /* we don't allow it to be allocated`
1452 onto the external stack since : so we
1453 temporarily turn it off ; we also
1454 turn off memory model to prevent
1455 the spil from going to the external storage
1456 and turn off overlaying
1459 useXstack = options.useXstack;
1460 model = options.model;
1461 noOverlay = options.noOverlay;
1462 options.noOverlay = 1;
1463 options.model = options.useXstack = 0;
1467 options.useXstack = useXstack;
1468 options.model = model;
1469 options.noOverlay = noOverlay;
1470 sloc->isref = 1; /* to prevent compiler warning */
1472 /* if it is on the stack then update the stack */
1473 if (IN_STACK (sloc->etype))
1475 currFunc->stack += getSize (sloc->type);
1476 _G.stackExtend += getSize (sloc->type);
1479 _G.dataExtend += getSize (sloc->type);
1481 /* add it to the _G.stackSpil set */
1482 addSetHead (&_G.stackSpil, sloc);
1483 sym->usl.spillLoc = sloc;
1486 /* add it to the set of itempStack set
1487 of the spill location */
1488 addSetHead (&sloc->usl.itmpStack, sym);
1492 /*-----------------------------------------------------------------*/
1493 /* isSpiltOnStack - returns true if the spil location is on stack */
1494 /*-----------------------------------------------------------------*/
1496 isSpiltOnStack (symbol * sym)
1500 debugLog ("%s\n", __FUNCTION__);
1507 /* if (sym->_G.stackSpil) */
1510 if (!sym->usl.spillLoc)
1513 etype = getSpec (sym->usl.spillLoc->type);
1514 if (IN_STACK (etype))
1520 /*-----------------------------------------------------------------*/
1521 /* spillThis - spils a specific operand */
1522 /*-----------------------------------------------------------------*/
1524 spillThis (symbol * sym)
1527 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1529 /* if this is rematerializable or has a spillLocation
1530 we are okay, else we need to create a spillLocation
1532 if (!(sym->remat || sym->usl.spillLoc))
1533 createStackSpil (sym);
1536 /* mark it has spilt & put it in the spilt set */
1538 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1540 bitVectUnSetBit (_G.regAssigned, sym->key);
1542 for (i = 0; i < sym->nRegs; i++)
1546 freeReg (sym->regs[i]);
1547 sym->regs[i] = NULL;
1550 /* if spilt on stack then free up r0 & r1
1551 if they could have been assigned to some
1553 if (!pic16_ptrRegReq && isSpiltOnStack (sym))
1556 spillLRWithPtrReg (sym);
1559 if (sym->usl.spillLoc && !sym->remat)
1560 sym->usl.spillLoc->allocreq = 1;
1564 /*-----------------------------------------------------------------*/
1565 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1566 /*-----------------------------------------------------------------*/
1568 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1570 bitVect *lrcs = NULL;
1574 debugLog ("%s\n", __FUNCTION__);
1575 /* get the spillable live ranges */
1576 lrcs = computeSpillable (ic);
1578 /* get all live ranges that are rematerizable */
1579 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1582 /* return the least used of these */
1583 return leastUsedLR (selectS);
1586 /* get live ranges with spillLocations in direct space */
1587 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1589 sym = leastUsedLR (selectS);
1590 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1591 sym->usl.spillLoc->rname :
1592 sym->usl.spillLoc->name));
1594 /* mark it as allocation required */
1595 sym->usl.spillLoc->allocreq = 1;
1599 /* if the symbol is local to the block then */
1600 if (forSym->liveTo < ebp->lSeq)
1603 /* check if there are any live ranges allocated
1604 to registers that are not used in this block */
1605 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1607 sym = leastUsedLR (selectS);
1608 /* if this is not rematerializable */
1617 /* check if there are any live ranges that not
1618 used in the remainder of the block */
1619 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1621 sym = leastUsedLR (selectS);
1624 sym->remainSpil = 1;
1631 /* find live ranges with spillocation && not used as pointers */
1632 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1635 sym = leastUsedLR (selectS);
1636 /* mark this as allocation required */
1637 sym->usl.spillLoc->allocreq = 1;
1641 /* find live ranges with spillocation */
1642 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1645 sym = leastUsedLR (selectS);
1646 sym->usl.spillLoc->allocreq = 1;
1650 /* couldn't find then we need to create a spil
1651 location on the stack , for which one? the least
1653 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1656 /* return a created spil location */
1657 sym = createStackSpil (leastUsedLR (selectS));
1658 sym->usl.spillLoc->allocreq = 1;
1662 /* this is an extreme situation we will spill
1663 this one : happens very rarely but it does happen */
1669 /*-----------------------------------------------------------------*/
1670 /* spilSomething - spil some variable & mark registers as free */
1671 /*-----------------------------------------------------------------*/
1673 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1678 debugLog ("%s\n", __FUNCTION__);
1679 /* get something we can spil */
1680 ssym = selectSpil (ic, ebp, forSym);
1682 /* mark it as spilt */
1684 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1686 /* mark it as not register assigned &
1687 take it away from the set */
1688 bitVectUnSetBit (_G.regAssigned, ssym->key);
1690 /* mark the registers as free */
1691 for (i = 0; i < ssym->nRegs; i++)
1693 freeReg (ssym->regs[i]);
1695 /* if spilt on stack then free up r0 & r1
1696 if they could have been assigned to as gprs */
1697 if (!pic16_ptrRegReq && isSpiltOnStack (ssym))
1700 spillLRWithPtrReg (ssym);
1703 /* if this was a block level spil then insert push & pop
1704 at the start & end of block respectively */
1705 if (ssym->blockSpil)
1707 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1708 /* add push to the start of the block */
1709 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1710 ebp->sch->next : ebp->sch));
1711 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1712 /* add pop to the end of the block */
1713 addiCodeToeBBlock (ebp, nic, NULL);
1716 /* if spilt because not used in the remainder of the
1717 block then add a push before this instruction and
1718 a pop at the end of the block */
1719 if (ssym->remainSpil)
1722 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1723 /* add push just before this instruction */
1724 addiCodeToeBBlock (ebp, nic, ic);
1726 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1727 /* add pop to the end of the block */
1728 addiCodeToeBBlock (ebp, nic, NULL);
1737 /*-----------------------------------------------------------------*/
1738 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1739 /*-----------------------------------------------------------------*/
1741 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1745 debugLog ("%s\n", __FUNCTION__);
1747 /* try for a ptr type */
1748 if ((reg = allocReg (REG_PTR)))
1751 /* try for gpr type */
1752 if ((reg = allocReg (REG_GPR)))
1755 /* we have to spil */
1756 if (!spilSomething (ic, ebp, sym))
1759 /* this looks like an infinite loop but
1760 in really selectSpil will abort */
1764 /*-----------------------------------------------------------------*/
1765 /* getRegGpr - will try for GPR if not spil */
1766 /*-----------------------------------------------------------------*/
1768 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1772 debugLog ("%s\n", __FUNCTION__);
1774 /* try for gpr type */
1775 if ((reg = allocReg (REG_GPR)))
1778 if (!pic16_ptrRegReq)
1779 if ((reg = allocReg (REG_PTR)))
1782 /* we have to spil */
1783 if (!spilSomething (ic, ebp, sym))
1786 /* this looks like an infinite loop but
1787 in really selectSpil will abort */
1791 /*-----------------------------------------------------------------*/
1792 /* symHasReg - symbol has a given register */
1793 /*-----------------------------------------------------------------*/
1795 symHasReg (symbol * sym, regs * reg)
1799 debugLog ("%s\n", __FUNCTION__);
1800 for (i = 0; i < sym->nRegs; i++)
1801 if (sym->regs[i] == reg)
1807 /*-----------------------------------------------------------------*/
1808 /* deassignLRs - check the live to and if they have registers & are */
1809 /* not spilt then free up the registers */
1810 /*-----------------------------------------------------------------*/
1812 deassignLRs (iCode * ic, eBBlock * ebp)
1818 debugLog ("%s\n", __FUNCTION__);
1819 for (sym = hTabFirstItem (liveRanges, &k); sym;
1820 sym = hTabNextItem (liveRanges, &k))
1823 symbol *psym = NULL;
1824 /* if it does not end here */
1825 if (sym->liveTo > ic->seq)
1828 /* if it was spilt on stack then we can
1829 mark the stack spil location as free */
1834 sym->usl.spillLoc->isFree = 1;
1840 if (!bitVectBitValue (_G.regAssigned, sym->key))
1843 /* special case check if this is an IFX &
1844 the privious one was a pop and the
1845 previous one was not spilt then keep track
1847 if (ic->op == IFX && ic->prev &&
1848 ic->prev->op == IPOP &&
1849 !ic->prev->parmPush &&
1850 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1851 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1857 bitVectUnSetBit (_G.regAssigned, sym->key);
1859 /* if the result of this one needs registers
1860 and does not have it then assign it right
1862 if (IC_RESULT (ic) &&
1863 !(SKIP_IC2 (ic) || /* not a special icode */
1864 ic->op == JUMPTABLE ||
1869 POINTER_SET (ic)) &&
1870 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1871 result->liveTo > ic->seq && /* and will live beyond this */
1872 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1873 result->regType == sym->regType && /* same register types */
1874 result->nRegs && /* which needs registers */
1875 !result->isspilt && /* and does not already have them */
1877 !bitVectBitValue (_G.regAssigned, result->key) &&
1878 /* the number of free regs + number of regs in this LR
1879 can accomodate the what result Needs */
1880 ((nfreeRegsType (result->regType) +
1881 sym->nRegs) >= result->nRegs)
1885 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1887 result->regs[i] = sym->regs[i];
1889 result->regs[i] = getRegGpr (ic, ebp, result);
1891 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1895 /* free the remaining */
1896 for (; i < sym->nRegs; i++)
1900 if (!symHasReg (psym, sym->regs[i]))
1901 freeReg (sym->regs[i]);
1904 freeReg (sym->regs[i]);
1911 /*-----------------------------------------------------------------*/
1912 /* reassignLR - reassign this to registers */
1913 /*-----------------------------------------------------------------*/
1915 reassignLR (operand * op)
1917 symbol *sym = OP_SYMBOL (op);
1920 debugLog ("%s\n", __FUNCTION__);
1921 /* not spilt any more */
1922 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1923 bitVectUnSetBit (_G.spiltSet, sym->key);
1925 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1929 for (i = 0; i < sym->nRegs; i++)
1930 sym->regs[i]->isFree = 0;
1933 /*-----------------------------------------------------------------*/
1934 /* willCauseSpill - determines if allocating will cause a spill */
1935 /*-----------------------------------------------------------------*/
1937 willCauseSpill (int nr, int rt)
1939 debugLog ("%s\n", __FUNCTION__);
1940 /* first check if there are any avlb registers
1941 of te type required */
1944 /* special case for pointer type
1945 if pointer type not avlb then
1946 check for type gpr */
1947 if (nFreeRegs (rt) >= nr)
1949 if (nFreeRegs (REG_GPR) >= nr)
1954 if (pic16_ptrRegReq)
1956 if (nFreeRegs (rt) >= nr)
1961 if (nFreeRegs (REG_PTR) +
1962 nFreeRegs (REG_GPR) >= nr)
1967 debugLog (" ... yep it will (cause a spill)\n");
1968 /* it will cause a spil */
1972 /*-----------------------------------------------------------------*/
1973 /* positionRegs - the allocator can allocate same registers to res- */
1974 /* ult and operand, if this happens make sure they are in the same */
1975 /* position as the operand otherwise chaos results */
1976 /*-----------------------------------------------------------------*/
1978 positionRegs (symbol * result, symbol * opsym, int lineno)
1980 int count = min (result->nRegs, opsym->nRegs);
1981 int i, j = 0, shared = 0;
1983 debugLog ("%s\n", __FUNCTION__);
1984 /* if the result has been spilt then cannot share */
1989 /* first make sure that they actually share */
1990 for (i = 0; i < count; i++)
1992 for (j = 0; j < count; j++)
1994 if (result->regs[i] == opsym->regs[j] && i != j)
2004 regs *tmp = result->regs[i];
2005 result->regs[i] = result->regs[j];
2006 result->regs[j] = tmp;
2011 /*-----------------------------------------------------------------*/
2012 /* serialRegAssign - serially allocate registers to the variables */
2013 /*-----------------------------------------------------------------*/
2015 serialRegAssign (eBBlock ** ebbs, int count)
2019 debugLog ("%s\n", __FUNCTION__);
2020 /* for all blocks */
2021 for (i = 0; i < count; i++)
2026 if (ebbs[i]->noPath &&
2027 (ebbs[i]->entryLabel != entryLabel &&
2028 ebbs[i]->entryLabel != returnLabel))
2031 /* of all instructions do */
2032 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2035 debugLog (" op: %s\n", decodeOp (ic->op));
2037 /* if this is an ipop that means some live
2038 range will have to be assigned again */
2040 reassignLR (IC_LEFT (ic));
2042 /* if result is present && is a true symbol */
2043 if (IC_RESULT (ic) && ic->op != IFX &&
2044 IS_TRUE_SYMOP (IC_RESULT (ic)))
2045 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2047 /* take away registers from live
2048 ranges that end at this instruction */
2049 deassignLRs (ic, ebbs[i]);
2051 /* some don't need registers */
2052 if (SKIP_IC2 (ic) ||
2053 ic->op == JUMPTABLE ||
2057 (IC_RESULT (ic) && POINTER_SET (ic)))
2060 /* now we need to allocate registers
2061 only for the result */
2064 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2070 /* if it does not need or is spilt
2071 or is already assigned to registers
2072 or will not live beyond this instructions */
2075 bitVectBitValue (_G.regAssigned, sym->key) ||
2076 sym->liveTo <= ic->seq)
2079 /* if some liverange has been spilt at the block level
2080 and this one live beyond this block then spil this
2082 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2087 /* if trying to allocate this will cause
2088 a spill and there is nothing to spill
2089 or this one is rematerializable then
2091 willCS = willCauseSpill (sym->nRegs, sym->regType);
2092 spillable = computeSpillable (ic);
2094 (willCS && bitVectIsZero (spillable)))
2102 /* if it has a spillocation & is used less than
2103 all other live ranges then spill this */
2105 if (sym->usl.spillLoc) {
2106 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2107 allLRs, ebbs[i], ic));
2108 if (leastUsed && leastUsed->used > sym->used) {
2113 /* if none of the liveRanges have a spillLocation then better
2114 to spill this one than anything else already assigned to registers */
2115 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2116 /* if this is local to this block then we might find a block spil */
2117 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2125 if (ic->op == RECEIVE)
2126 debugLog ("When I get clever, I'll optimize the receive logic\n");
2128 /* if we need ptr regs for the right side
2130 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2131 <= (unsigned) PTRSIZE)
2136 /* else we assign registers to it */
2137 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2139 debugLog (" %d - \n", __LINE__);
2141 bitVectDebugOn(_G.regAssigned, debugF);
2143 for (j = 0; j < sym->nRegs; j++)
2145 if (sym->regType == REG_PTR)
2146 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2148 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2150 /* if the allocation falied which means
2151 this was spilt then break */
2155 debugLog (" %d - \n", __LINE__);
2157 /* if it shares registers with operands make sure
2158 that they are in the same position */
2159 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2160 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2161 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2162 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2163 /* do the same for the right operand */
2164 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2165 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2166 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2167 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2169 debugLog (" %d - \n", __LINE__);
2172 debugLog (" %d - \n", __LINE__);
2182 /*-----------------------------------------------------------------*/
2183 /* rUmaskForOp :- returns register mask for an operand */
2184 /*-----------------------------------------------------------------*/
2186 rUmaskForOp (operand * op)
2192 debugLog ("%s\n", __FUNCTION__);
2193 /* only temporaries are assigned registers */
2197 sym = OP_SYMBOL (op);
2199 /* if spilt or no registers assigned to it
2201 if (sym->isspilt || !sym->nRegs)
2204 rumask = newBitVect (pic16_nRegs);
2206 for (j = 0; j < sym->nRegs; j++)
2208 rumask = bitVectSetBit (rumask,
2209 sym->regs[j]->rIdx);
2215 /*-----------------------------------------------------------------*/
2216 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2217 /*-----------------------------------------------------------------*/
2219 regsUsedIniCode (iCode * ic)
2221 bitVect *rmask = newBitVect (pic16_nRegs);
2223 debugLog ("%s\n", __FUNCTION__);
2224 /* do the special cases first */
2227 rmask = bitVectUnion (rmask,
2228 rUmaskForOp (IC_COND (ic)));
2232 /* for the jumptable */
2233 if (ic->op == JUMPTABLE)
2235 rmask = bitVectUnion (rmask,
2236 rUmaskForOp (IC_JTCOND (ic)));
2241 /* of all other cases */
2243 rmask = bitVectUnion (rmask,
2244 rUmaskForOp (IC_LEFT (ic)));
2248 rmask = bitVectUnion (rmask,
2249 rUmaskForOp (IC_RIGHT (ic)));
2252 rmask = bitVectUnion (rmask,
2253 rUmaskForOp (IC_RESULT (ic)));
2259 /*-----------------------------------------------------------------*/
2260 /* createRegMask - for each instruction will determine the regsUsed */
2261 /*-----------------------------------------------------------------*/
2263 createRegMask (eBBlock ** ebbs, int count)
2267 debugLog ("%s\n", __FUNCTION__);
2268 /* for all blocks */
2269 for (i = 0; i < count; i++)
2273 if (ebbs[i]->noPath &&
2274 (ebbs[i]->entryLabel != entryLabel &&
2275 ebbs[i]->entryLabel != returnLabel))
2278 /* for all instructions */
2279 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2284 if (SKIP_IC2 (ic) || !ic->rlive)
2287 /* first mark the registers used in this
2289 ic->rUsed = regsUsedIniCode (ic);
2290 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2292 /* now create the register mask for those
2293 registers that are in use : this is a
2294 super set of ic->rUsed */
2295 ic->rMask = newBitVect (pic16_nRegs + 1);
2297 /* for all live Ranges alive at this point */
2298 for (j = 1; j < ic->rlive->size; j++)
2303 /* if not alive then continue */
2304 if (!bitVectBitValue (ic->rlive, j))
2307 /* find the live range we are interested in */
2308 if (!(sym = hTabItemWithKey (liveRanges, j)))
2310 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2311 "createRegMask cannot find live range");
2315 /* if no register assigned to it */
2316 if (!sym->nRegs || sym->isspilt)
2319 /* for all the registers allocated to it */
2320 for (k = 0; k < sym->nRegs; k++)
2323 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2329 /*-----------------------------------------------------------------*/
2330 /* rematStr - returns the rematerialized string for a remat var */
2331 /*-----------------------------------------------------------------*/
2333 rematStr (symbol * sym)
2336 iCode *ic = sym->rematiCode;
2337 symbol *psym = NULL;
2339 debugLog ("%s\n", __FUNCTION__);
2341 //printf ("%s\n", s);
2343 /* if plus or minus print the right hand side */
2345 if (ic->op == '+' || ic->op == '-') {
2347 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2349 sprintf (s, "(%s %c 0x%04x)",
2350 OP_SYMBOL (IC_LEFT (ric))->rname,
2352 (int) operandLitValue (IC_RIGHT (ic)));
2355 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2357 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2358 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2363 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2364 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2366 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2371 /*-----------------------------------------------------------------*/
2372 /* rematStr - returns the rematerialized string for a remat var */
2373 /*-----------------------------------------------------------------*/
2375 rematStr (symbol * sym)
2378 iCode *ic = sym->rematiCode;
2380 debugLog ("%s\n", __FUNCTION__);
2385 /* if plus or minus print the right hand side */
2387 if (ic->op == '+' || ic->op == '-') {
2388 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2391 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2395 if (ic->op == '+' || ic->op == '-')
2397 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2398 sprintf (s, "(%s %c 0x%04x)",
2399 OP_SYMBOL (IC_LEFT (ric))->rname,
2401 (int) operandLitValue (IC_RIGHT (ic)));
2404 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2406 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2410 /* we reached the end */
2411 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2415 printf ("%s\n", buffer);
2420 /*-----------------------------------------------------------------*/
2421 /* regTypeNum - computes the type & number of registers required */
2422 /*-----------------------------------------------------------------*/
2430 debugLog ("%s\n", __FUNCTION__);
2431 /* for each live range do */
2432 for (sym = hTabFirstItem (liveRanges, &k); sym;
2433 sym = hTabNextItem (liveRanges, &k)) {
2435 debugLog (" %d - %s\n", __LINE__, sym->rname);
2437 /* if used zero times then no registers needed */
2438 if ((sym->liveTo - sym->liveFrom) == 0)
2442 /* if the live range is a temporary */
2445 debugLog (" %d - itemp register\n", __LINE__);
2447 /* if the type is marked as a conditional */
2448 if (sym->regType == REG_CND)
2451 /* if used in return only then we don't
2453 if (sym->ruonly || sym->accuse) {
2454 if (IS_AGGREGATE (sym->type) || sym->isptr)
2455 sym->type = aggrToPtr (sym->type, FALSE);
2456 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
2461 /* if the symbol has only one definition &
2462 that definition is a get_pointer and the
2463 pointer we are getting is rematerializable and
2466 if (bitVectnBitsOn (sym->defs) == 1 &&
2467 (ic = hTabItemWithKey (iCodehTab,
2468 bitVectFirstBit (sym->defs))) &&
2471 !IS_BITVAR (sym->etype)) {
2474 debugLog (" %d - \n", __LINE__);
2476 /* if remat in data space */
2477 if (OP_SYMBOL (IC_LEFT (ic))->remat &&
2478 DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) {
2480 /* create a psuedo symbol & force a spil */
2481 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2482 symbol *psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2483 psym->type = sym->type;
2484 psym->etype = sym->etype;
2485 strcpy (psym->rname, psym->name);
2487 sym->usl.spillLoc = psym;
2491 /* if in data space or idata space then try to
2492 allocate pointer register */
2496 /* if not then we require registers */
2497 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2498 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2499 getSize (sym->type));
2502 if(IS_PTR_CONST (sym->type)) {
2503 debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2507 if (sym->nRegs > 4) {
2508 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2509 printTypeChain (sym->type, stderr);
2510 fprintf (stderr, "\n");
2513 /* determine the type of register required */
2514 if (sym->nRegs == 1 &&
2515 IS_PTR (sym->type) &&
2517 sym->regType = REG_PTR;
2519 sym->regType = REG_GPR;
2522 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2526 /* for the first run we don't provide */
2527 /* registers for true symbols we will */
2528 /* see how things go */
2533 static DEFSETFUNC (markRegFree)
2535 ((regs *)item)->isFree = 1;
2540 DEFSETFUNC (pic16_deallocReg)
2542 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2543 ((regs *)item)->isFree = 1;
2544 ((regs *)item)->wasUsed = 0;
2548 /*-----------------------------------------------------------------*/
2549 /* freeAllRegs - mark all registers as free */
2550 /*-----------------------------------------------------------------*/
2552 pic16_freeAllRegs ()
2556 debugLog ("%s\n", __FUNCTION__);
2558 applyToSet(pic16_dynAllocRegs,markRegFree);
2559 applyToSet(pic16_dynStackRegs,markRegFree);
2562 for (i = 0; i < pic16_nRegs; i++)
2563 regspic16[i].isFree = 1;
2567 /*-----------------------------------------------------------------*/
2568 /*-----------------------------------------------------------------*/
2570 pic16_deallocateAllRegs ()
2574 debugLog ("%s\n", __FUNCTION__);
2576 applyToSet(pic16_dynAllocRegs,pic16_deallocReg);
2579 for (i = 0; i < pic16_nRegs; i++) {
2580 if(regspic16[i].pc_type == PO_GPR_TEMP) {
2581 regspic16[i].isFree = 1;
2582 regspic16[i].wasUsed = 0;
2589 /*-----------------------------------------------------------------*/
2590 /* deallocStackSpil - this will set the stack pointer back */
2591 /*-----------------------------------------------------------------*/
2593 DEFSETFUNC (deallocStackSpil)
2597 debugLog ("%s\n", __FUNCTION__);
2602 /*-----------------------------------------------------------------*/
2603 /* farSpacePackable - returns the packable icode for far variables */
2604 /*-----------------------------------------------------------------*/
2606 farSpacePackable (iCode * ic)
2610 debugLog ("%s\n", __FUNCTION__);
2611 /* go thru till we find a definition for the
2612 symbol on the right */
2613 for (dic = ic->prev; dic; dic = dic->prev)
2616 /* if the definition is a call then no */
2617 if ((dic->op == CALL || dic->op == PCALL) &&
2618 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2623 /* if shift by unknown amount then not */
2624 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2625 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2628 /* if pointer get and size > 1 */
2629 if (POINTER_GET (dic) &&
2630 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2633 if (POINTER_SET (dic) &&
2634 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2637 /* if any three is a true symbol in far space */
2638 if (IC_RESULT (dic) &&
2639 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2640 isOperandInFarSpace (IC_RESULT (dic)))
2643 if (IC_RIGHT (dic) &&
2644 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2645 isOperandInFarSpace (IC_RIGHT (dic)) &&
2646 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2649 if (IC_LEFT (dic) &&
2650 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2651 isOperandInFarSpace (IC_LEFT (dic)) &&
2652 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2655 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2657 if ((dic->op == LEFT_OP ||
2658 dic->op == RIGHT_OP ||
2660 IS_OP_LITERAL (IC_RIGHT (dic)))
2670 /*-----------------------------------------------------------------*/
2671 /* packRegsForAssign - register reduction for assignment */
2672 /*-----------------------------------------------------------------*/
2674 packRegsForAssign (iCode * ic, eBBlock * ebp)
2679 debugLog ("%s\n", __FUNCTION__);
2681 debugAopGet (" result:", IC_RESULT (ic));
2682 debugAopGet (" left:", IC_LEFT (ic));
2683 debugAopGet (" right:", IC_RIGHT (ic));
2685 /* if this is at an absolute address, then get the address. */
2686 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2687 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2688 debugLog (" %d - found config word declaration\n", __LINE__);
2689 if(IS_VALOP(IC_RIGHT(ic))) {
2690 debugLog (" setting config word to %x\n",
2691 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2692 pic16_assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2693 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2696 /* remove the assignment from the iCode chain. */
2698 remiCodeFromeBBlock (ebp, ic);
2699 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2700 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2707 if (!IS_ITEMP (IC_RESULT (ic))) {
2708 pic16_allocDirReg(IC_RESULT (ic));
2709 debugLog (" %d - result is not temp\n", __LINE__);
2712 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2713 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2714 pic16_allocDirReg(IC_LEFT (ic));
2718 if (!IS_ITEMP (IC_RIGHT (ic))) {
2719 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2720 pic16_allocDirReg(IC_RIGHT (ic));
2724 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2725 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2727 debugLog (" %d - not packing - right side fails \n", __LINE__);
2731 /* if the true symbol is defined in far space or on stack
2732 then we should not since this will increase register pressure */
2733 if (isOperandInFarSpace (IC_RESULT (ic)))
2735 if ((dic = farSpacePackable (ic)))
2741 /* find the definition of iTempNN scanning backwards if we find a
2742 a use of the true symbol before we find the definition then
2744 for (dic = ic->prev; dic; dic = dic->prev)
2747 /* if there is a function call and this is
2748 a parameter & not my parameter then don't pack it */
2749 if ((dic->op == CALL || dic->op == PCALL) &&
2750 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2751 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2753 debugLog (" %d - \n", __LINE__);
2761 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2762 IS_OP_VOLATILE (IC_RESULT (dic)))
2764 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2769 if (IS_SYMOP (IC_RESULT (dic)) &&
2770 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2772 /* A previous result was assigned to the same register - we'll our definition */
2773 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2774 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2775 if (POINTER_SET (dic))
2781 if (IS_SYMOP (IC_RIGHT (dic)) &&
2782 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2783 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2785 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
2790 if (IS_SYMOP (IC_LEFT (dic)) &&
2791 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2792 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2794 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
2799 if (POINTER_SET (dic) &&
2800 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2802 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
2810 return 0; /* did not find */
2812 /* if the result is on stack or iaccess then it must be
2813 the same atleast one of the operands */
2814 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2815 OP_SYMBOL (IC_RESULT (ic))->iaccess)
2818 /* the operation has only one symbol
2819 operator then we can pack */
2820 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2821 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2824 if (!((IC_LEFT (dic) &&
2825 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2827 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2831 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2832 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
2833 /* found the definition */
2834 /* replace the result with the result of */
2835 /* this assignment and remove this assignment */
2836 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2837 IC_RESULT (dic) = IC_RESULT (ic);
2839 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2841 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2843 /* delete from liverange table also
2844 delete from all the points inbetween and the new
2846 for (sic = dic; sic != ic; sic = sic->next)
2848 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2849 if (IS_ITEMP (IC_RESULT (dic)))
2850 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2853 remiCodeFromeBBlock (ebp, ic);
2854 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2855 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2856 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2862 /*-----------------------------------------------------------------*/
2863 /* findAssignToSym : scanning backwards looks for first assig found */
2864 /*-----------------------------------------------------------------*/
2866 findAssignToSym (operand * op, iCode * ic)
2870 debugLog ("%s\n", __FUNCTION__);
2871 for (dic = ic->prev; dic; dic = dic->prev)
2874 /* if definition by assignment */
2875 if (dic->op == '=' &&
2876 !POINTER_SET (dic) &&
2877 IC_RESULT (dic)->key == op->key
2878 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2882 /* we are interested only if defined in far space */
2883 /* or in stack space in case of + & - */
2885 /* if assigned to a non-symbol then return
2887 if (!IS_SYMOP (IC_RIGHT (dic)))
2890 /* if the symbol is in far space then
2892 if (isOperandInFarSpace (IC_RIGHT (dic)))
2895 /* for + & - operations make sure that
2896 if it is on the stack it is the same
2897 as one of the three operands */
2898 if ((ic->op == '+' || ic->op == '-') &&
2899 OP_SYMBOL (IC_RIGHT (dic))->onStack)
2902 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2903 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2904 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2912 /* if we find an usage then we cannot delete it */
2913 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2916 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2919 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2923 /* now make sure that the right side of dic
2924 is not defined between ic & dic */
2927 iCode *sic = dic->next;
2929 for (; sic != ic; sic = sic->next)
2930 if (IC_RESULT (sic) &&
2931 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2940 /*-----------------------------------------------------------------*/
2941 /* packRegsForSupport :- reduce some registers for support calls */
2942 /*-----------------------------------------------------------------*/
2944 packRegsForSupport (iCode * ic, eBBlock * ebp)
2948 debugLog ("%s\n", __FUNCTION__);
2949 /* for the left & right operand :- look to see if the
2950 left was assigned a true symbol in far space in that
2951 case replace them */
2952 if (IS_ITEMP (IC_LEFT (ic)) &&
2953 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2955 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
2961 debugAopGet ("removing left:", IC_LEFT (ic));
2963 /* found it we need to remove it from the
2965 for (sic = dic; sic != ic; sic = sic->next)
2966 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
2968 IC_LEFT (ic)->operand.symOperand =
2969 IC_RIGHT (dic)->operand.symOperand;
2970 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2971 remiCodeFromeBBlock (ebp, dic);
2972 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2973 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2977 /* do the same for the right operand */
2980 IS_ITEMP (IC_RIGHT (ic)) &&
2981 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2983 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2989 /* if this is a subtraction & the result
2990 is a true symbol in far space then don't pack */
2991 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
2993 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
2994 if (IN_FARSPACE (SPEC_OCLS (etype)))
2998 debugAopGet ("removing right:", IC_RIGHT (ic));
3000 /* found it we need to remove it from the
3002 for (sic = dic; sic != ic; sic = sic->next)
3003 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3005 IC_RIGHT (ic)->operand.symOperand =
3006 IC_RIGHT (dic)->operand.symOperand;
3007 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3009 remiCodeFromeBBlock (ebp, dic);
3010 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3011 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3018 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3021 /*-----------------------------------------------------------------*/
3022 /* packRegsForOneuse : - will reduce some registers for single Use */
3023 /*-----------------------------------------------------------------*/
3025 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3030 debugLog ("%s\n", __FUNCTION__);
3031 /* if returning a literal then do nothing */
3035 /* only upto 2 bytes since we cannot predict
3036 the usage of b, & acc */
3037 if (getSize (operandType (op)) > (pic16_fReturnSizePic - 2) &&
3042 /* this routine will mark the a symbol as used in one
3043 instruction use only && if the definition is local
3044 (ie. within the basic block) && has only one definition &&
3045 that definition is either a return value from a
3046 function or does not contain any variables in
3048 uses = bitVectCopy (OP_USES (op));
3049 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3050 if (!bitVectIsZero (uses)) /* has other uses */
3053 /* if it has only one defintion */
3054 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3055 return NULL; /* has more than one definition */
3057 /* get that definition */
3059 hTabItemWithKey (iCodehTab,
3060 bitVectFirstBit (OP_DEFS (op)))))
3063 /* found the definition now check if it is local */
3064 if (dic->seq < ebp->fSeq ||
3065 dic->seq > ebp->lSeq)
3066 return NULL; /* non-local */
3068 /* now check if it is the return from
3070 if (dic->op == CALL || dic->op == PCALL)
3072 if (ic->op != SEND && ic->op != RETURN &&
3073 !POINTER_SET(ic) && !POINTER_GET(ic))
3075 OP_SYMBOL (op)->ruonly = 1;
3082 /* otherwise check that the definition does
3083 not contain any symbols in far space */
3084 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3085 isOperandInFarSpace (IC_RIGHT (dic)) ||
3086 IS_OP_RUONLY (IC_LEFT (ic)) ||
3087 IS_OP_RUONLY (IC_RIGHT (ic)))
3092 /* if pointer set then make sure the pointer
3094 if (POINTER_SET (dic) &&
3095 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3098 if (POINTER_GET (dic) &&
3099 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3104 /* also make sure the intervenening instructions
3105 don't have any thing in far space */
3106 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3109 /* if there is an intervening function call then no */
3110 if (dic->op == CALL || dic->op == PCALL)
3112 /* if pointer set then make sure the pointer
3114 if (POINTER_SET (dic) &&
3115 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3118 if (POINTER_GET (dic) &&
3119 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3122 /* if address of & the result is remat then okay */
3123 if (dic->op == ADDRESS_OF &&
3124 OP_SYMBOL (IC_RESULT (dic))->remat)
3127 /* if operand has size of three or more & this
3128 operation is a '*','/' or '%' then 'b' may
3130 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3131 getSize (operandType (op)) >= 3)
3134 /* if left or right or result is in far space */
3135 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3136 isOperandInFarSpace (IC_RIGHT (dic)) ||
3137 isOperandInFarSpace (IC_RESULT (dic)) ||
3138 IS_OP_RUONLY (IC_LEFT (dic)) ||
3139 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3140 IS_OP_RUONLY (IC_RESULT (dic)))
3146 OP_SYMBOL (op)->ruonly = 1;
3151 /*-----------------------------------------------------------------*/
3152 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3153 /*-----------------------------------------------------------------*/
3155 isBitwiseOptimizable (iCode * ic)
3157 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3158 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3160 debugLog ("%s\n", __FUNCTION__);
3161 /* bitwise operations are considered optimizable
3162 under the following conditions (Jean-Louis VERN)
3174 if (IS_LITERAL (rtype) ||
3175 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3181 /*-----------------------------------------------------------------*/
3182 /* packRegsForAccUse - pack registers for acc use */
3183 /*-----------------------------------------------------------------*/
3185 packRegsForAccUse (iCode * ic)
3189 debugLog ("%s\n", __FUNCTION__);
3191 /* if this is an aggregate, e.g. a one byte char array */
3192 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3195 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3197 /* if + or - then it has to be one byte result */
3198 if ((ic->op == '+' || ic->op == '-')
3199 && getSize (operandType (IC_RESULT (ic))) > 1)
3202 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3203 /* if shift operation make sure right side is not a literal */
3204 if (ic->op == RIGHT_OP &&
3205 (isOperandLiteral (IC_RIGHT (ic)) ||
3206 getSize (operandType (IC_RESULT (ic))) > 1))
3209 if (ic->op == LEFT_OP &&
3210 (isOperandLiteral (IC_RIGHT (ic)) ||
3211 getSize (operandType (IC_RESULT (ic))) > 1))
3214 if (IS_BITWISE_OP (ic) &&
3215 getSize (operandType (IC_RESULT (ic))) > 1)
3219 /* has only one definition */
3220 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3223 /* has only one use */
3224 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3227 /* and the usage immediately follows this iCode */
3228 if (!(uic = hTabItemWithKey (iCodehTab,
3229 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3232 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3233 if (ic->next != uic)
3236 /* if it is a conditional branch then we definitely can */
3240 if (uic->op == JUMPTABLE)
3243 /* if the usage is not is an assignment
3244 or an arithmetic / bitwise / shift operation then not */
3245 if (POINTER_SET (uic) &&
3246 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3249 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3250 if (uic->op != '=' &&
3251 !IS_ARITHMETIC_OP (uic) &&
3252 !IS_BITWISE_OP (uic) &&
3253 uic->op != LEFT_OP &&
3254 uic->op != RIGHT_OP)
3257 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3258 /* if used in ^ operation then make sure right is not a
3260 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3263 /* if shift operation make sure right side is not a literal */
3264 if (uic->op == RIGHT_OP &&
3265 (isOperandLiteral (IC_RIGHT (uic)) ||
3266 getSize (operandType (IC_RESULT (uic))) > 1))
3269 if (uic->op == LEFT_OP &&
3270 (isOperandLiteral (IC_RIGHT (uic)) ||
3271 getSize (operandType (IC_RESULT (uic))) > 1))
3274 /* make sure that the result of this icode is not on the
3275 stack, since acc is used to compute stack offset */
3276 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3277 OP_SYMBOL (IC_RESULT (uic))->onStack)
3280 /* if either one of them in far space then we cannot */
3281 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3282 isOperandInFarSpace (IC_LEFT (uic))) ||
3283 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3284 isOperandInFarSpace (IC_RIGHT (uic))))
3287 /* if the usage has only one operand then we can */
3288 if (IC_LEFT (uic) == NULL ||
3289 IC_RIGHT (uic) == NULL)
3292 /* make sure this is on the left side if not
3293 a '+' since '+' is commutative */
3294 if (ic->op != '+' &&
3295 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3298 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3299 /* if one of them is a literal then we can */
3300 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3301 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3302 (getSize (operandType (IC_RESULT (uic))) <= 1))
3304 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3308 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3309 /* if the other one is not on stack then we can */
3310 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3311 (IS_ITEMP (IC_RIGHT (uic)) ||
3312 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3313 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3316 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3317 (IS_ITEMP (IC_LEFT (uic)) ||
3318 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3319 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3325 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3326 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3331 /*-----------------------------------------------------------------*/
3332 /* packForPush - hueristics to reduce iCode for pushing */
3333 /*-----------------------------------------------------------------*/
3335 packForReceive (iCode * ic, eBBlock * ebp)
3339 debugLog ("%s\n", __FUNCTION__);
3340 debugAopGet (" result:", IC_RESULT (ic));
3341 debugAopGet (" left:", IC_LEFT (ic));
3342 debugAopGet (" right:", IC_RIGHT (ic));
3347 for (dic = ic->next; dic; dic = dic->next)
3352 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3353 debugLog (" used on left\n");
3354 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3355 debugLog (" used on right\n");
3356 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3357 debugLog (" used on result\n");
3359 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3360 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3365 debugLog (" hey we can remove this unnecessary assign\n");
3367 /*-----------------------------------------------------------------*/
3368 /* packForPush - hueristics to reduce iCode for pushing */
3369 /*-----------------------------------------------------------------*/
3371 packForPush (iCode * ic, eBBlock * ebp)
3375 debugLog ("%s\n", __FUNCTION__);
3376 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3379 /* must have only definition & one usage */
3380 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3381 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3384 /* find the definition */
3385 if (!(dic = hTabItemWithKey (iCodehTab,
3386 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3389 if (dic->op != '=' || POINTER_SET (dic))
3392 /* we now we know that it has one & only one def & use
3393 and the that the definition is an assignment */
3394 IC_LEFT (ic) = IC_RIGHT (dic);
3396 remiCodeFromeBBlock (ebp, dic);
3397 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3398 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3401 static void printSymType(char * str, sym_link *sl)
3403 debugLog (" %s Symbol type: ",str);
3404 printTypeChain( sl, debugF);
3409 /*-----------------------------------------------------------------*/
3410 /* some debug code to print the symbol S_TYPE. Note that
3411 * the function checkSClass in src/SDCCsymt.c dinks with
3412 * the S_TYPE in ways the PIC port doesn't fully like...*/
3413 /*-----------------------------------------------------------------*/
3414 static void isData(sym_link *sl)
3424 for ( ; sl; sl=sl->next) {
3426 switch (SPEC_SCLS(sl)) {
3428 case S_DATA: fprintf (of, "data "); break;
3429 case S_XDATA: fprintf (of, "xdata "); break;
3430 case S_SFR: fprintf (of, "sfr "); break;
3431 case S_SBIT: fprintf (of, "sbit "); break;
3432 case S_CODE: fprintf (of, "code "); break;
3433 case S_IDATA: fprintf (of, "idata "); break;
3434 case S_PDATA: fprintf (of, "pdata "); break;
3435 case S_LITERAL: fprintf (of, "literal "); break;
3436 case S_STACK: fprintf (of, "stack "); break;
3437 case S_XSTACK: fprintf (of, "xstack "); break;
3438 case S_BIT: fprintf (of, "bit "); break;
3439 case S_EEPROM: fprintf (of, "eeprom "); break;
3448 /*-----------------------------------------------------------------*/
3449 /* packRegisters - does some transformations to reduce register */
3451 /*-----------------------------------------------------------------*/
3453 packRegisters (eBBlock * ebp)
3458 debugLog ("%s\n", __FUNCTION__);
3464 /* look for assignments of the form */
3465 /* iTempNN = TRueSym (someoperation) SomeOperand */
3467 /* TrueSym := iTempNN:1 */
3468 for (ic = ebp->sch; ic; ic = ic->next)
3471 /* find assignment of the form TrueSym := iTempNN:1 */
3472 if (ic->op == '=' && !POINTER_SET (ic))
3473 change += packRegsForAssign (ic, ebp);
3477 if (POINTER_SET (ic))
3478 debugLog ("pointer is set\n");
3479 debugAopGet (" result:", IC_RESULT (ic));
3480 debugAopGet (" left:", IC_LEFT (ic));
3481 debugAopGet (" right:", IC_RIGHT (ic));
3490 for (ic = ebp->sch; ic; ic = ic->next) {
3492 if(IS_SYMOP ( IC_LEFT(ic))) {
3493 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3495 debugAopGet (" left:", IC_LEFT (ic));
3496 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3497 debugLog (" is a pointer\n");
3499 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3500 debugLog (" is volatile\n");
3504 printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
3507 if(IS_SYMOP ( IC_RIGHT(ic))) {
3508 debugAopGet (" right:", IC_RIGHT (ic));
3509 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3512 if(IS_SYMOP ( IC_RESULT(ic))) {
3513 debugAopGet (" result:", IC_RESULT (ic));
3514 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3517 if (POINTER_SET (ic))
3518 debugLog (" %d - Pointer set\n", __LINE__);
3521 /* if this is an itemp & result of a address of a true sym
3522 then mark this as rematerialisable */
3523 if (ic->op == ADDRESS_OF &&
3524 IS_ITEMP (IC_RESULT (ic)) &&
3525 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3526 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3527 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3530 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3532 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3533 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3534 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3538 /* if straight assignment then carry remat flag if
3539 this is the only definition */
3540 if (ic->op == '=' &&
3541 !POINTER_SET (ic) &&
3542 IS_SYMOP (IC_RIGHT (ic)) &&
3543 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3544 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3546 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3548 OP_SYMBOL (IC_RESULT (ic))->remat =
3549 OP_SYMBOL (IC_RIGHT (ic))->remat;
3550 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3551 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3554 /* if this is a +/- operation with a rematerizable
3555 then mark this as rematerializable as well */
3556 if ((ic->op == '+' || ic->op == '-') &&
3557 (IS_SYMOP (IC_LEFT (ic)) &&
3558 IS_ITEMP (IC_RESULT (ic)) &&
3559 OP_SYMBOL (IC_LEFT (ic))->remat &&
3560 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3561 IS_OP_LITERAL (IC_RIGHT (ic))))
3563 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3565 operandLitValue (IC_RIGHT (ic));
3566 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3567 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3568 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3571 /* mark the pointer usages */
3572 if (POINTER_SET (ic))
3574 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3575 debugLog (" marking as a pointer (set) =>");
3576 debugAopGet (" result:", IC_RESULT (ic));
3578 if (POINTER_GET (ic))
3580 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3581 debugLog (" marking as a pointer (get) =>");
3582 debugAopGet (" left:", IC_LEFT (ic));
3587 /* if we are using a symbol on the stack
3588 then we should say pic16_ptrRegReq */
3589 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3590 pic16_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3591 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3592 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3593 pic16_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3594 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3597 if (IS_SYMOP (IC_LEFT (ic)))
3598 pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3599 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3600 if (IS_SYMOP (IC_RIGHT (ic)))
3601 pic16_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3602 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3603 if (IS_SYMOP (IC_RESULT (ic)))
3604 pic16_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3605 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3608 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic16_ptrRegReq);
3612 /* if the condition of an if instruction
3613 is defined in the previous instruction then
3614 mark the itemp as a conditional */
3615 if ((IS_CONDITIONAL (ic) ||
3616 ((ic->op == BITWISEAND ||
3619 isBitwiseOptimizable (ic))) &&
3620 ic->next && ic->next->op == IFX &&
3621 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3622 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3625 debugLog (" %d\n", __LINE__);
3626 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3630 /* reduce for support function calls */
3631 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3632 packRegsForSupport (ic, ebp);
3634 /* if a parameter is passed, it's in W, so we may not
3635 need to place a copy in a register */
3636 if (ic->op == RECEIVE)
3637 packForReceive (ic, ebp);
3639 /* some cases the redundant moves can
3640 can be eliminated for return statements */
3641 if ((ic->op == RETURN || ic->op == SEND) &&
3642 !isOperandInFarSpace (IC_LEFT (ic)) &&
3644 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3646 /* if pointer set & left has a size more than
3647 one and right is not in far space */
3648 if (POINTER_SET (ic) &&
3649 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3650 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3651 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3652 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3654 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3656 /* if pointer get */
3657 if (POINTER_GET (ic) &&
3658 !isOperandInFarSpace (IC_RESULT (ic)) &&
3659 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3660 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3661 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3663 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3666 /* if this is cast for intergral promotion then
3667 check if only use of the definition of the
3668 operand being casted/ if yes then replace
3669 the result of that arithmetic operation with
3670 this result and get rid of the cast */
3671 if (ic->op == CAST) {
3673 sym_link *fromType = operandType (IC_RIGHT (ic));
3674 sym_link *toType = operandType (IC_LEFT (ic));
3676 debugLog (" %d - casting\n", __LINE__);
3678 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3679 getSize (fromType) != getSize (toType)) {
3682 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3685 if (IS_ARITHMETIC_OP (dic)) {
3687 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3688 IC_RESULT (dic) = IC_RESULT (ic);
3689 remiCodeFromeBBlock (ebp, ic);
3690 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3691 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3692 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3696 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3700 /* if the type from and type to are the same
3701 then if this is the only use then packit */
3702 if (compareType (operandType (IC_RIGHT (ic)),
3703 operandType (IC_LEFT (ic))) == 1) {
3705 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3708 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3709 IC_RESULT (dic) = IC_RESULT (ic);
3710 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3711 remiCodeFromeBBlock (ebp, ic);
3712 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3713 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3721 iTempNN := (some variable in farspace) V1
3726 if (ic->op == IPUSH)
3728 packForPush (ic, ebp);
3732 /* pack registers for accumulator use, when the
3733 result of an arithmetic or bit wise operation
3734 has only one use, that use is immediately following
3735 the defintion and the using iCode has only one
3736 operand or has two operands but one is literal &
3737 the result of that operation is not on stack then
3738 we can leave the result of this operation in acc:b
3740 if ((IS_ARITHMETIC_OP (ic)
3742 || IS_BITWISE_OP (ic)
3744 || ic->op == LEFT_OP || ic->op == RIGHT_OP
3747 IS_ITEMP (IC_RESULT (ic)) &&
3748 getSize (operandType (IC_RESULT (ic))) <= 2)
3750 packRegsForAccUse (ic);
3756 dumpEbbsToDebug (eBBlock ** ebbs, int count)
3760 if (!debug || !debugF)
3763 for (i = 0; i < count; i++)
3765 fprintf (debugF, "\n----------------------------------------------------------------\n");
3766 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
3767 ebbs[i]->entryLabel->name,
3770 ebbs[i]->isLastInLoop);
3771 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
3776 fprintf (debugF, "visited %d : hasFcall = %d\n",
3780 fprintf (debugF, "\ndefines bitVector :");
3781 bitVectDebugOn (ebbs[i]->defSet, debugF);
3782 fprintf (debugF, "\nlocal defines bitVector :");
3783 bitVectDebugOn (ebbs[i]->ldefs, debugF);
3784 fprintf (debugF, "\npointers Set bitvector :");
3785 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
3786 fprintf (debugF, "\nin pointers Set bitvector :");
3787 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
3788 fprintf (debugF, "\ninDefs Set bitvector :");
3789 bitVectDebugOn (ebbs[i]->inDefs, debugF);
3790 fprintf (debugF, "\noutDefs Set bitvector :");
3791 bitVectDebugOn (ebbs[i]->outDefs, debugF);
3792 fprintf (debugF, "\nusesDefs Set bitvector :");
3793 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
3794 fprintf (debugF, "\n----------------------------------------------------------------\n");
3795 printiCChain (ebbs[i]->sch, debugF);
3798 /*-----------------------------------------------------------------*/
3799 /* pic16_assignRegisters - assigns registers to each live range as need */
3800 /*-----------------------------------------------------------------*/
3802 pic16_assignRegisters (eBBlock ** ebbs, int count)
3807 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
3808 debugLog ("\nebbs before optimizing:\n");
3809 dumpEbbsToDebug (ebbs, count);
3811 setToNull ((void *) &_G.funcrUsed);
3812 pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3815 /* change assignments this will remove some
3816 live ranges reducing some register pressure */
3817 for (i = 0; i < count; i++)
3818 packRegisters (ebbs[i]);
3825 debugLog("dir registers allocated so far:\n");
3826 reg = hTabFirstItem(dynDirectRegNames, &hkey);
3829 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
3830 reg = hTabNextItem(dynDirectRegNames, &hkey);
3835 if (options.dump_pack)
3836 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3838 /* first determine for each live range the number of
3839 registers & the type of registers required for each */
3842 /* and serially allocate registers */
3843 serialRegAssign (ebbs, count);
3845 /* if stack was extended then tell the user */
3848 /* werror(W_TOOMANY_SPILS,"stack", */
3849 /* _G.stackExtend,currFunc->name,""); */
3855 /* werror(W_TOOMANY_SPILS,"data space", */
3856 /* _G.dataExtend,currFunc->name,""); */
3860 /* after that create the register mask
3861 for each of the instruction */
3862 createRegMask (ebbs, count);
3864 /* redo that offsets for stacked automatic variables */
3865 redoStackOffsets ();
3867 if (options.dump_rassgn)
3868 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3870 /* now get back the chain */
3871 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3873 debugLog ("ebbs after optimizing:\n");
3874 dumpEbbsToDebug (ebbs, count);
3879 /* free up any _G.stackSpil locations allocated */
3880 applyToSet (_G.stackSpil, deallocStackSpil);
3882 setToNull ((void **) &_G.stackSpil);
3883 setToNull ((void **) &_G.spiltSet);
3884 /* mark all registers as free */
3885 //pic16_freeAllRegs ();
3887 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");