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 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
591 if(STRCASECMP(reg->name, name) == 0) {
595 reg = hTabNextItemWK (dynDirectRegNames);
599 return NULL; // name wasn't found in the hash table
602 static int IS_CONFIG_ADDRESS(int address)
605 return address >= 0x300000 && address <= 0x300000d;
608 /*-----------------------------------------------------------------*/
609 /* pic16_allocDirReg - allocates register of given type */
610 /*-----------------------------------------------------------------*/
612 pic16_allocDirReg (operand *op )
619 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
623 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
625 /* If the symbol is at a fixed address, then remove the leading underscore
626 * from the name. This is hack to allow the .asm include file named registers
627 * to match the .c declared register names */
629 //if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && (*name == '_'))
632 debugLog ("%s symbol name %s\n", __FUNCTION__,name);
634 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
635 debugLog(" %d const char\n",__LINE__);
636 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
639 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
640 if (IS_CODE ( OP_SYM_ETYPE(op)) )
641 debugLog(" %d code space\n",__LINE__);
643 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
644 debugLog(" %d integral\n",__LINE__);
645 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
646 debugLog(" %d literal\n",__LINE__);
647 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
648 debugLog(" %d specifier\n",__LINE__);
649 debugAopGet(NULL, op);
652 if (IS_CODE ( OP_SYM_ETYPE(op)) )
655 /* First, search the hash table to see if there is a register with this name */
656 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && !(IS_BITVAR (OP_SYM_ETYPE(op))) ) {
657 reg = regWithIdx (pic16_dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1);
660 fprintf(stderr,"ralloc %s is at fixed address but not a processor reg, addr=0x%x\n",
661 name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
663 fprintf(stderr,"ralloc %s at fixed address has already been declared, addr=0x%x\n",
664 name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
667 //fprintf(stderr,"ralloc:%d %s \n", __LINE__,name);
669 reg = pic16_dirregWithName(name);
675 /* if this is at an absolute address, then get the address. */
676 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
677 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
678 //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
681 /* Register wasn't found in hash, so let's create
682 * a new one and put it in the hash table AND in the
683 * dynDirectRegNames set */
684 if(!IS_CONFIG_ADDRESS(address)) {
685 //fprintf(stderr,"allocating new reg %s\n",name);
687 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0 );
688 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
690 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
692 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
694 //fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
698 if (IS_BITVAR (OP_SYM_ETYPE(op))) {
699 addSet(&pic16_dynDirectBitRegs, reg);
702 addSet(&pic16_dynDirectRegs, reg);
705 debugLog (" -- %s is declared at address 0x30000x\n",name);
710 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
712 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
713 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
719 /*-----------------------------------------------------------------*/
720 /* pic16_allocRegByName - allocates register of given type */
721 /*-----------------------------------------------------------------*/
723 pic16_allocRegByName (char *name, int size)
729 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
733 /* First, search the hash table to see if there is a register with this name */
734 reg = pic16_dirregWithName(name);
738 /* Register wasn't found in hash, so let's create
739 * a new one and put it in the hash table AND in the
740 * dynDirectRegNames set */
741 //fprintf (stderr,"%s symbol name %s\n", __FUNCTION__,name);
742 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0 );
744 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
746 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
747 addSet(&pic16_dynDirectRegs, reg);
753 /*-----------------------------------------------------------------*/
754 /* RegWithIdx - returns pointer to register with index number */
755 /*-----------------------------------------------------------------*/
757 typeRegWithIdx (int idx, int type, int fixed)
762 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
767 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx, fixed)) != NULL) {
769 debugLog ("Found a Dynamic Register!\n");
772 if( (dReg = regWithIdx ( pic16_dynDirectRegs, idx, fixed)) != NULL ) {
773 debugLog ("Found a Direct Register!\n");
779 if( (dReg = regWithIdx ( pic16_dynStackRegs, idx, fixed)) != NULL ) {
780 debugLog ("Found a Stack Register!\n");
785 if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx, fixed)) != NULL ) {
786 debugLog ("Found a Processor Register!\n");
800 /*-----------------------------------------------------------------*/
801 /* pic16_regWithIdx - returns pointer to register with index number*/
802 /*-----------------------------------------------------------------*/
804 pic16_regWithIdx (int idx)
808 if( (dReg = typeRegWithIdx(idx,REG_GPR,0)) != NULL)
811 if( (dReg = typeRegWithIdx(idx,REG_SFR,0)) != NULL)
814 if( (dReg = typeRegWithIdx(idx,REG_STK,0)) != NULL)
820 /*-----------------------------------------------------------------*/
821 /* pic16_regWithIdx - returns pointer to register with index number */
822 /*-----------------------------------------------------------------*/
824 pic16_allocWithIdx (int idx)
829 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
831 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx,0)) != NULL) {
833 debugLog ("Found a Dynamic Register!\n");
834 } else if( (dReg = regWithIdx ( pic16_dynStackRegs, idx,0)) != NULL ) {
835 debugLog ("Found a Stack Register!\n");
836 } else if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx,0)) != NULL ) {
837 debugLog ("Found a Processor Register!\n");
838 } else if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx,0)) != NULL ) {
839 debugLog ("Found an Internal Register!\n");
842 debugLog ("Dynamic Register not found\n");
845 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
846 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
847 "regWithIdx not found");
857 /*-----------------------------------------------------------------*/
858 /*-----------------------------------------------------------------*/
860 pic16_findFreeReg(short type)
867 if((dReg = regFindFree(pic16_dynAllocRegs)) != NULL)
869 return addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
873 if((dReg = regFindFree(pic16_dynStackRegs)) != NULL)
885 /*-----------------------------------------------------------------*/
886 /* freeReg - frees a register */
887 /*-----------------------------------------------------------------*/
891 debugLog ("%s\n", __FUNCTION__);
896 /*-----------------------------------------------------------------*/
897 /* nFreeRegs - returns number of free registers */
898 /*-----------------------------------------------------------------*/
902 /* dynamically allocate as many as we need and worry about
903 * fitting them into a PIC later */
910 debugLog ("%s\n", __FUNCTION__);
911 for (i = 0; i < pic16_nRegs; i++)
912 if (regspic16[i].isFree && regspic16[i].type == type)
918 /*-----------------------------------------------------------------*/
919 /* nfreeRegsType - free registers with type */
920 /*-----------------------------------------------------------------*/
922 nfreeRegsType (int type)
925 debugLog ("%s\n", __FUNCTION__);
928 if ((nfr = nFreeRegs (type)) == 0)
929 return nFreeRegs (REG_GPR);
932 return nFreeRegs (type);
935 static void writeSetUsedRegs(FILE *of, set *dRegs)
940 for (dReg = setFirstItem(dRegs) ; dReg ;
941 dReg = setNextItem(dRegs)) {
944 fprintf (of, "\t%s\n",dReg->name);
948 extern void pic16_assignFixedRegisters(set *regset);
949 extern void pic16_assignRelocatableRegisters(set *regset,int used);
950 extern void pic16_dump_map(void);
951 extern void pic16_dump_cblock(FILE *of);
954 static void packBits(set *bregs)
959 regs *relocbitfield=NULL;
965 for (regset = bregs ; regset ;
966 regset = regset->next) {
969 breg->isBitField = 1;
970 //fprintf(stderr,"bit reg: %s\n",breg->name);
973 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
975 bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1);
976 breg->rIdx = breg->address & 7;
980 sprintf (buffer, "fbitfield%02x", breg->address);
981 //fprintf(stderr,"new bit field\n");
982 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0);
983 bitfield->isBitField = 1;
984 bitfield->isFixed = 1;
985 bitfield->address = breg->address;
986 addSet(&pic16_dynDirectRegs,bitfield);
987 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
989 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
992 breg->reg_alias = bitfield;
996 if(!relocbitfield || bit_no >7) {
999 sprintf (buffer, "bitfield%d", byte_no);
1000 //fprintf(stderr,"new relocatable bit field\n");
1001 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0);
1002 relocbitfield->isBitField = 1;
1003 addSet(&pic16_dynDirectRegs,relocbitfield);
1004 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1008 breg->reg_alias = relocbitfield;
1009 breg->address = rDirectIdx; /* byte_no; */
1010 breg->rIdx = bit_no++;
1018 static void bitEQUs(FILE *of, set *bregs)
1020 regs *breg,*bytereg;
1023 //fprintf(stderr," %s\n",__FUNCTION__);
1024 for (breg = setFirstItem(bregs) ; breg ;
1025 breg = setNextItem(bregs)) {
1027 //fprintf(stderr,"bit reg: %s\n",breg->name);
1029 bytereg = breg->reg_alias;
1031 fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
1034 breg->rIdx & 0x0007);
1037 fprintf(stderr, "bit field is not assigned to a register\n");
1038 fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
1049 static void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
1054 for (reg = setFirstItem(fregs) ; reg ;
1055 reg = setNextItem(fregs)) {
1057 if(!reg->isEmitted && reg->wasUsed) {
1059 if (reg->type != REG_SFR) {
1060 fprintf (of, "%s\tEQU\t0x%03x\n",
1066 fprintf (of, "%s\tEQU\t0x%03x\n",
1074 void pic16_writeUsedRegs(FILE *of)
1076 packBits(pic16_dynDirectBitRegs);
1079 pic16_assignFixedRegisters(pic16_dynAllocRegs);
1080 pic16_assignFixedRegisters(pic16_dynStackRegs);
1081 pic16_assignFixedRegisters(pic16_dynDirectRegs);
1083 pic16_assignRelocatableRegisters(pic16_dynInternalRegs,0);
1084 pic16_assignRelocatableRegisters(pic16_dynAllocRegs,0);
1085 pic16_assignRelocatableRegisters(pic16_dynStackRegs,0);
1086 pic16_assignRelocatableRegisters(pic16_dynDirectRegs,0);
1090 pic16_dump_cblock(of);
1091 bitEQUs(of,pic16_dynDirectBitRegs);
1092 aliasEQUs(of,pic16_dynAllocRegs,0);
1093 aliasEQUs(of,pic16_dynDirectRegs,0);
1094 aliasEQUs(of,pic16_dynStackRegs,0);
1095 aliasEQUs(of,pic16_dynProcessorRegs,1);
1100 /*-----------------------------------------------------------------*/
1101 /* allDefsOutOfRange - all definitions are out of a range */
1102 /*-----------------------------------------------------------------*/
1104 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
1108 debugLog ("%s\n", __FUNCTION__);
1112 for (i = 0; i < defs->size; i++)
1116 if (bitVectBitValue (defs, i) &&
1117 (ic = hTabItemWithKey (iCodehTab, i)) &&
1118 (ic->seq >= fseq && ic->seq <= toseq))
1128 /*-----------------------------------------------------------------*/
1129 /* computeSpillable - given a point find the spillable live ranges */
1130 /*-----------------------------------------------------------------*/
1132 computeSpillable (iCode * ic)
1136 debugLog ("%s\n", __FUNCTION__);
1137 /* spillable live ranges are those that are live at this
1138 point . the following categories need to be subtracted
1140 a) - those that are already spilt
1141 b) - if being used by this one
1142 c) - defined by this one */
1144 spillable = bitVectCopy (ic->rlive);
1146 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1148 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1149 bitVectUnSetBit (spillable, ic->defKey);
1150 spillable = bitVectIntersect (spillable, _G.regAssigned);
1155 /*-----------------------------------------------------------------*/
1156 /* noSpilLoc - return true if a variable has no spil location */
1157 /*-----------------------------------------------------------------*/
1159 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1161 debugLog ("%s\n", __FUNCTION__);
1162 return (sym->usl.spillLoc ? 0 : 1);
1165 /*-----------------------------------------------------------------*/
1166 /* hasSpilLoc - will return 1 if the symbol has spil location */
1167 /*-----------------------------------------------------------------*/
1169 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1171 debugLog ("%s\n", __FUNCTION__);
1172 return (sym->usl.spillLoc ? 1 : 0);
1175 /*-----------------------------------------------------------------*/
1176 /* directSpilLoc - will return 1 if the splilocation is in direct */
1177 /*-----------------------------------------------------------------*/
1179 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1181 debugLog ("%s\n", __FUNCTION__);
1182 if (sym->usl.spillLoc &&
1183 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1189 /*-----------------------------------------------------------------*/
1190 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1191 /* but is not used as a pointer */
1192 /*-----------------------------------------------------------------*/
1194 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1196 debugLog ("%s\n", __FUNCTION__);
1197 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1200 /*-----------------------------------------------------------------*/
1201 /* rematable - will return 1 if the remat flag is set */
1202 /*-----------------------------------------------------------------*/
1204 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1206 debugLog ("%s\n", __FUNCTION__);
1210 /*-----------------------------------------------------------------*/
1211 /* notUsedInRemaining - not used or defined in remain of the block */
1212 /*-----------------------------------------------------------------*/
1214 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1216 debugLog ("%s\n", __FUNCTION__);
1217 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1218 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1221 /*-----------------------------------------------------------------*/
1222 /* allLRs - return true for all */
1223 /*-----------------------------------------------------------------*/
1225 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1227 debugLog ("%s\n", __FUNCTION__);
1231 /*-----------------------------------------------------------------*/
1232 /* liveRangesWith - applies function to a given set of live range */
1233 /*-----------------------------------------------------------------*/
1235 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1236 eBBlock * ebp, iCode * ic)
1241 debugLog ("%s\n", __FUNCTION__);
1242 if (!lrs || !lrs->size)
1245 for (i = 1; i < lrs->size; i++)
1248 if (!bitVectBitValue (lrs, i))
1251 /* if we don't find it in the live range
1252 hash table we are in serious trouble */
1253 if (!(sym = hTabItemWithKey (liveRanges, i)))
1255 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1256 "liveRangesWith could not find liveRange");
1260 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1261 addSetHead (&rset, sym);
1268 /*-----------------------------------------------------------------*/
1269 /* leastUsedLR - given a set determines which is the least used */
1270 /*-----------------------------------------------------------------*/
1272 leastUsedLR (set * sset)
1274 symbol *sym = NULL, *lsym = NULL;
1276 debugLog ("%s\n", __FUNCTION__);
1277 sym = lsym = setFirstItem (sset);
1282 for (; lsym; lsym = setNextItem (sset))
1285 /* if usage is the same then prefer
1286 the spill the smaller of the two */
1287 if (lsym->used == sym->used)
1288 if (getSize (lsym->type) < getSize (sym->type))
1292 if (lsym->used < sym->used)
1297 setToNull ((void **) &sset);
1302 /*-----------------------------------------------------------------*/
1303 /* noOverLap - will iterate through the list looking for over lap */
1304 /*-----------------------------------------------------------------*/
1306 noOverLap (set * itmpStack, symbol * fsym)
1309 debugLog ("%s\n", __FUNCTION__);
1312 for (sym = setFirstItem (itmpStack); sym;
1313 sym = setNextItem (itmpStack))
1315 if (sym->liveTo > fsym->liveFrom)
1323 /*-----------------------------------------------------------------*/
1324 /* isFree - will return 1 if the a free spil location is found */
1325 /*-----------------------------------------------------------------*/
1330 V_ARG (symbol **, sloc);
1331 V_ARG (symbol *, fsym);
1333 debugLog ("%s\n", __FUNCTION__);
1334 /* if already found */
1338 /* if it is free && and the itmp assigned to
1339 this does not have any overlapping live ranges
1340 with the one currently being assigned and
1341 the size can be accomodated */
1343 noOverLap (sym->usl.itmpStack, fsym) &&
1344 getSize (sym->type) >= getSize (fsym->type))
1353 /*-----------------------------------------------------------------*/
1354 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1355 /*-----------------------------------------------------------------*/
1357 spillLRWithPtrReg (symbol * forSym)
1363 debugLog ("%s\n", __FUNCTION__);
1364 if (!_G.regAssigned ||
1365 bitVectIsZero (_G.regAssigned))
1368 r0 = pic16_regWithIdx (R0_IDX);
1369 r1 = pic16_regWithIdx (R1_IDX);
1371 /* for all live ranges */
1372 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1373 lrsym = hTabNextItem (liveRanges, &k))
1377 /* if no registers assigned to it or
1379 /* if it does not overlap with this then
1380 not need to spill it */
1382 if (lrsym->isspilt || !lrsym->nRegs ||
1383 (lrsym->liveTo < forSym->liveFrom))
1386 /* go thru the registers : if it is either
1387 r0 or r1 then spil it */
1388 for (j = 0; j < lrsym->nRegs; j++)
1389 if (lrsym->regs[j] == r0 ||
1390 lrsym->regs[j] == r1)
1399 /*-----------------------------------------------------------------*/
1400 /* createStackSpil - create a location on the stack to spil */
1401 /*-----------------------------------------------------------------*/
1403 createStackSpil (symbol * sym)
1405 symbol *sloc = NULL;
1406 int useXstack, model, noOverlay;
1408 char slocBuffer[30];
1409 debugLog ("%s\n", __FUNCTION__);
1411 /* first go try and find a free one that is already
1412 existing on the stack */
1413 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1415 /* found a free one : just update & return */
1416 sym->usl.spillLoc = sloc;
1419 addSetHead (&sloc->usl.itmpStack, sym);
1423 /* could not then have to create one , this is the hard part
1424 we need to allocate this on the stack : this is really a
1425 hack!! but cannot think of anything better at this time */
1427 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1429 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1430 __FILE__, __LINE__);
1434 sloc = newiTemp (slocBuffer);
1436 /* set the type to the spilling symbol */
1437 sloc->type = copyLinkChain (sym->type);
1438 sloc->etype = getSpec (sloc->type);
1439 SPEC_SCLS (sloc->etype) = S_DATA;
1440 SPEC_EXTR (sloc->etype) = 0;
1441 SPEC_STAT (sloc->etype) = 0;
1443 /* we don't allow it to be allocated`
1444 onto the external stack since : so we
1445 temporarily turn it off ; we also
1446 turn off memory model to prevent
1447 the spil from going to the external storage
1448 and turn off overlaying
1451 useXstack = options.useXstack;
1452 model = options.model;
1453 noOverlay = options.noOverlay;
1454 options.noOverlay = 1;
1455 options.model = options.useXstack = 0;
1459 options.useXstack = useXstack;
1460 options.model = model;
1461 options.noOverlay = noOverlay;
1462 sloc->isref = 1; /* to prevent compiler warning */
1464 /* if it is on the stack then update the stack */
1465 if (IN_STACK (sloc->etype))
1467 currFunc->stack += getSize (sloc->type);
1468 _G.stackExtend += getSize (sloc->type);
1471 _G.dataExtend += getSize (sloc->type);
1473 /* add it to the _G.stackSpil set */
1474 addSetHead (&_G.stackSpil, sloc);
1475 sym->usl.spillLoc = sloc;
1478 /* add it to the set of itempStack set
1479 of the spill location */
1480 addSetHead (&sloc->usl.itmpStack, sym);
1484 /*-----------------------------------------------------------------*/
1485 /* isSpiltOnStack - returns true if the spil location is on stack */
1486 /*-----------------------------------------------------------------*/
1488 isSpiltOnStack (symbol * sym)
1492 debugLog ("%s\n", __FUNCTION__);
1499 /* if (sym->_G.stackSpil) */
1502 if (!sym->usl.spillLoc)
1505 etype = getSpec (sym->usl.spillLoc->type);
1506 if (IN_STACK (etype))
1512 /*-----------------------------------------------------------------*/
1513 /* spillThis - spils a specific operand */
1514 /*-----------------------------------------------------------------*/
1516 spillThis (symbol * sym)
1519 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1521 /* if this is rematerializable or has a spillLocation
1522 we are okay, else we need to create a spillLocation
1524 if (!(sym->remat || sym->usl.spillLoc))
1525 createStackSpil (sym);
1528 /* mark it has spilt & put it in the spilt set */
1530 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1532 bitVectUnSetBit (_G.regAssigned, sym->key);
1534 for (i = 0; i < sym->nRegs; i++)
1538 freeReg (sym->regs[i]);
1539 sym->regs[i] = NULL;
1542 /* if spilt on stack then free up r0 & r1
1543 if they could have been assigned to some
1545 if (!pic16_ptrRegReq && isSpiltOnStack (sym))
1548 spillLRWithPtrReg (sym);
1551 if (sym->usl.spillLoc && !sym->remat)
1552 sym->usl.spillLoc->allocreq = 1;
1556 /*-----------------------------------------------------------------*/
1557 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1558 /*-----------------------------------------------------------------*/
1560 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1562 bitVect *lrcs = NULL;
1566 debugLog ("%s\n", __FUNCTION__);
1567 /* get the spillable live ranges */
1568 lrcs = computeSpillable (ic);
1570 /* get all live ranges that are rematerizable */
1571 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1574 /* return the least used of these */
1575 return leastUsedLR (selectS);
1578 /* get live ranges with spillLocations in direct space */
1579 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1581 sym = leastUsedLR (selectS);
1582 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1583 sym->usl.spillLoc->rname :
1584 sym->usl.spillLoc->name));
1586 /* mark it as allocation required */
1587 sym->usl.spillLoc->allocreq = 1;
1591 /* if the symbol is local to the block then */
1592 if (forSym->liveTo < ebp->lSeq)
1595 /* check if there are any live ranges allocated
1596 to registers that are not used in this block */
1597 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1599 sym = leastUsedLR (selectS);
1600 /* if this is not rematerializable */
1609 /* check if there are any live ranges that not
1610 used in the remainder of the block */
1611 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1613 sym = leastUsedLR (selectS);
1616 sym->remainSpil = 1;
1623 /* find live ranges with spillocation && not used as pointers */
1624 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1627 sym = leastUsedLR (selectS);
1628 /* mark this as allocation required */
1629 sym->usl.spillLoc->allocreq = 1;
1633 /* find live ranges with spillocation */
1634 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1637 sym = leastUsedLR (selectS);
1638 sym->usl.spillLoc->allocreq = 1;
1642 /* couldn't find then we need to create a spil
1643 location on the stack , for which one? the least
1645 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1648 /* return a created spil location */
1649 sym = createStackSpil (leastUsedLR (selectS));
1650 sym->usl.spillLoc->allocreq = 1;
1654 /* this is an extreme situation we will spill
1655 this one : happens very rarely but it does happen */
1661 /*-----------------------------------------------------------------*/
1662 /* spilSomething - spil some variable & mark registers as free */
1663 /*-----------------------------------------------------------------*/
1665 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1670 debugLog ("%s\n", __FUNCTION__);
1671 /* get something we can spil */
1672 ssym = selectSpil (ic, ebp, forSym);
1674 /* mark it as spilt */
1676 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1678 /* mark it as not register assigned &
1679 take it away from the set */
1680 bitVectUnSetBit (_G.regAssigned, ssym->key);
1682 /* mark the registers as free */
1683 for (i = 0; i < ssym->nRegs; i++)
1685 freeReg (ssym->regs[i]);
1687 /* if spilt on stack then free up r0 & r1
1688 if they could have been assigned to as gprs */
1689 if (!pic16_ptrRegReq && isSpiltOnStack (ssym))
1692 spillLRWithPtrReg (ssym);
1695 /* if this was a block level spil then insert push & pop
1696 at the start & end of block respectively */
1697 if (ssym->blockSpil)
1699 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1700 /* add push to the start of the block */
1701 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1702 ebp->sch->next : ebp->sch));
1703 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1704 /* add pop to the end of the block */
1705 addiCodeToeBBlock (ebp, nic, NULL);
1708 /* if spilt because not used in the remainder of the
1709 block then add a push before this instruction and
1710 a pop at the end of the block */
1711 if (ssym->remainSpil)
1714 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1715 /* add push just before this instruction */
1716 addiCodeToeBBlock (ebp, nic, ic);
1718 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1719 /* add pop to the end of the block */
1720 addiCodeToeBBlock (ebp, nic, NULL);
1729 /*-----------------------------------------------------------------*/
1730 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1731 /*-----------------------------------------------------------------*/
1733 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1737 debugLog ("%s\n", __FUNCTION__);
1739 /* try for a ptr type */
1740 if ((reg = allocReg (REG_PTR)))
1743 /* try for gpr type */
1744 if ((reg = allocReg (REG_GPR)))
1747 /* we have to spil */
1748 if (!spilSomething (ic, ebp, sym))
1751 /* this looks like an infinite loop but
1752 in really selectSpil will abort */
1756 /*-----------------------------------------------------------------*/
1757 /* getRegGpr - will try for GPR if not spil */
1758 /*-----------------------------------------------------------------*/
1760 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1764 debugLog ("%s\n", __FUNCTION__);
1766 /* try for gpr type */
1767 if ((reg = allocReg (REG_GPR)))
1770 if (!pic16_ptrRegReq)
1771 if ((reg = allocReg (REG_PTR)))
1774 /* we have to spil */
1775 if (!spilSomething (ic, ebp, sym))
1778 /* this looks like an infinite loop but
1779 in really selectSpil will abort */
1783 /*-----------------------------------------------------------------*/
1784 /* symHasReg - symbol has a given register */
1785 /*-----------------------------------------------------------------*/
1787 symHasReg (symbol * sym, regs * reg)
1791 debugLog ("%s\n", __FUNCTION__);
1792 for (i = 0; i < sym->nRegs; i++)
1793 if (sym->regs[i] == reg)
1799 /*-----------------------------------------------------------------*/
1800 /* deassignLRs - check the live to and if they have registers & are */
1801 /* not spilt then free up the registers */
1802 /*-----------------------------------------------------------------*/
1804 deassignLRs (iCode * ic, eBBlock * ebp)
1810 debugLog ("%s\n", __FUNCTION__);
1811 for (sym = hTabFirstItem (liveRanges, &k); sym;
1812 sym = hTabNextItem (liveRanges, &k))
1815 symbol *psym = NULL;
1816 /* if it does not end here */
1817 if (sym->liveTo > ic->seq)
1820 /* if it was spilt on stack then we can
1821 mark the stack spil location as free */
1826 sym->usl.spillLoc->isFree = 1;
1832 if (!bitVectBitValue (_G.regAssigned, sym->key))
1835 /* special case check if this is an IFX &
1836 the privious one was a pop and the
1837 previous one was not spilt then keep track
1839 if (ic->op == IFX && ic->prev &&
1840 ic->prev->op == IPOP &&
1841 !ic->prev->parmPush &&
1842 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1843 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1849 bitVectUnSetBit (_G.regAssigned, sym->key);
1851 /* if the result of this one needs registers
1852 and does not have it then assign it right
1854 if (IC_RESULT (ic) &&
1855 !(SKIP_IC2 (ic) || /* not a special icode */
1856 ic->op == JUMPTABLE ||
1861 POINTER_SET (ic)) &&
1862 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1863 result->liveTo > ic->seq && /* and will live beyond this */
1864 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1865 result->regType == sym->regType && /* same register types */
1866 result->nRegs && /* which needs registers */
1867 !result->isspilt && /* and does not already have them */
1869 !bitVectBitValue (_G.regAssigned, result->key) &&
1870 /* the number of free regs + number of regs in this LR
1871 can accomodate the what result Needs */
1872 ((nfreeRegsType (result->regType) +
1873 sym->nRegs) >= result->nRegs)
1877 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1879 result->regs[i] = sym->regs[i];
1881 result->regs[i] = getRegGpr (ic, ebp, result);
1883 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1887 /* free the remaining */
1888 for (; i < sym->nRegs; i++)
1892 if (!symHasReg (psym, sym->regs[i]))
1893 freeReg (sym->regs[i]);
1896 freeReg (sym->regs[i]);
1903 /*-----------------------------------------------------------------*/
1904 /* reassignLR - reassign this to registers */
1905 /*-----------------------------------------------------------------*/
1907 reassignLR (operand * op)
1909 symbol *sym = OP_SYMBOL (op);
1912 debugLog ("%s\n", __FUNCTION__);
1913 /* not spilt any more */
1914 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1915 bitVectUnSetBit (_G.spiltSet, sym->key);
1917 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1921 for (i = 0; i < sym->nRegs; i++)
1922 sym->regs[i]->isFree = 0;
1925 /*-----------------------------------------------------------------*/
1926 /* willCauseSpill - determines if allocating will cause a spill */
1927 /*-----------------------------------------------------------------*/
1929 willCauseSpill (int nr, int rt)
1931 debugLog ("%s\n", __FUNCTION__);
1932 /* first check if there are any avlb registers
1933 of te type required */
1936 /* special case for pointer type
1937 if pointer type not avlb then
1938 check for type gpr */
1939 if (nFreeRegs (rt) >= nr)
1941 if (nFreeRegs (REG_GPR) >= nr)
1946 if (pic16_ptrRegReq)
1948 if (nFreeRegs (rt) >= nr)
1953 if (nFreeRegs (REG_PTR) +
1954 nFreeRegs (REG_GPR) >= nr)
1959 debugLog (" ... yep it will (cause a spill)\n");
1960 /* it will cause a spil */
1964 /*-----------------------------------------------------------------*/
1965 /* positionRegs - the allocator can allocate same registers to res- */
1966 /* ult and operand, if this happens make sure they are in the same */
1967 /* position as the operand otherwise chaos results */
1968 /*-----------------------------------------------------------------*/
1970 positionRegs (symbol * result, symbol * opsym, int lineno)
1972 int count = min (result->nRegs, opsym->nRegs);
1973 int i, j = 0, shared = 0;
1975 debugLog ("%s\n", __FUNCTION__);
1976 /* if the result has been spilt then cannot share */
1981 /* first make sure that they actually share */
1982 for (i = 0; i < count; i++)
1984 for (j = 0; j < count; j++)
1986 if (result->regs[i] == opsym->regs[j] && i != j)
1996 regs *tmp = result->regs[i];
1997 result->regs[i] = result->regs[j];
1998 result->regs[j] = tmp;
2003 /*-----------------------------------------------------------------*/
2004 /* serialRegAssign - serially allocate registers to the variables */
2005 /*-----------------------------------------------------------------*/
2007 serialRegAssign (eBBlock ** ebbs, int count)
2011 debugLog ("%s\n", __FUNCTION__);
2012 /* for all blocks */
2013 for (i = 0; i < count; i++)
2018 if (ebbs[i]->noPath &&
2019 (ebbs[i]->entryLabel != entryLabel &&
2020 ebbs[i]->entryLabel != returnLabel))
2023 /* of all instructions do */
2024 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2027 debugLog (" op: %s\n", decodeOp (ic->op));
2029 /* if this is an ipop that means some live
2030 range will have to be assigned again */
2032 reassignLR (IC_LEFT (ic));
2034 /* if result is present && is a true symbol */
2035 if (IC_RESULT (ic) && ic->op != IFX &&
2036 IS_TRUE_SYMOP (IC_RESULT (ic)))
2037 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2039 /* take away registers from live
2040 ranges that end at this instruction */
2041 deassignLRs (ic, ebbs[i]);
2043 /* some don't need registers */
2044 if (SKIP_IC2 (ic) ||
2045 ic->op == JUMPTABLE ||
2049 (IC_RESULT (ic) && POINTER_SET (ic)))
2052 /* now we need to allocate registers
2053 only for the result */
2056 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2062 /* if it does not need or is spilt
2063 or is already assigned to registers
2064 or will not live beyond this instructions */
2067 bitVectBitValue (_G.regAssigned, sym->key) ||
2068 sym->liveTo <= ic->seq)
2071 /* if some liverange has been spilt at the block level
2072 and this one live beyond this block then spil this
2074 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2079 /* if trying to allocate this will cause
2080 a spill and there is nothing to spill
2081 or this one is rematerializable then
2083 willCS = willCauseSpill (sym->nRegs, sym->regType);
2084 spillable = computeSpillable (ic);
2086 (willCS && bitVectIsZero (spillable)))
2094 /* if it has a spillocation & is used less than
2095 all other live ranges then spill this */
2097 if (sym->usl.spillLoc) {
2098 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2099 allLRs, ebbs[i], ic));
2100 if (leastUsed && leastUsed->used > sym->used) {
2105 /* if none of the liveRanges have a spillLocation then better
2106 to spill this one than anything else already assigned to registers */
2107 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2108 /* if this is local to this block then we might find a block spil */
2109 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2117 if (ic->op == RECEIVE)
2118 debugLog ("When I get clever, I'll optimize the receive logic\n");
2120 /* if we need ptr regs for the right side
2122 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2123 <= (unsigned) PTRSIZE)
2128 /* else we assign registers to it */
2129 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2131 debugLog (" %d - \n", __LINE__);
2133 bitVectDebugOn(_G.regAssigned, debugF);
2135 for (j = 0; j < sym->nRegs; j++)
2137 if (sym->regType == REG_PTR)
2138 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2140 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2142 /* if the allocation falied which means
2143 this was spilt then break */
2147 debugLog (" %d - \n", __LINE__);
2149 /* if it shares registers with operands make sure
2150 that they are in the same position */
2151 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2152 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2153 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2154 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2155 /* do the same for the right operand */
2156 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2157 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2158 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2159 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2161 debugLog (" %d - \n", __LINE__);
2164 debugLog (" %d - \n", __LINE__);
2174 /*-----------------------------------------------------------------*/
2175 /* rUmaskForOp :- returns register mask for an operand */
2176 /*-----------------------------------------------------------------*/
2178 rUmaskForOp (operand * op)
2184 debugLog ("%s\n", __FUNCTION__);
2185 /* only temporaries are assigned registers */
2189 sym = OP_SYMBOL (op);
2191 /* if spilt or no registers assigned to it
2193 if (sym->isspilt || !sym->nRegs)
2196 rumask = newBitVect (pic16_nRegs);
2198 for (j = 0; j < sym->nRegs; j++)
2200 rumask = bitVectSetBit (rumask,
2201 sym->regs[j]->rIdx);
2207 /*-----------------------------------------------------------------*/
2208 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2209 /*-----------------------------------------------------------------*/
2211 regsUsedIniCode (iCode * ic)
2213 bitVect *rmask = newBitVect (pic16_nRegs);
2215 debugLog ("%s\n", __FUNCTION__);
2216 /* do the special cases first */
2219 rmask = bitVectUnion (rmask,
2220 rUmaskForOp (IC_COND (ic)));
2224 /* for the jumptable */
2225 if (ic->op == JUMPTABLE)
2227 rmask = bitVectUnion (rmask,
2228 rUmaskForOp (IC_JTCOND (ic)));
2233 /* of all other cases */
2235 rmask = bitVectUnion (rmask,
2236 rUmaskForOp (IC_LEFT (ic)));
2240 rmask = bitVectUnion (rmask,
2241 rUmaskForOp (IC_RIGHT (ic)));
2244 rmask = bitVectUnion (rmask,
2245 rUmaskForOp (IC_RESULT (ic)));
2251 /*-----------------------------------------------------------------*/
2252 /* createRegMask - for each instruction will determine the regsUsed */
2253 /*-----------------------------------------------------------------*/
2255 createRegMask (eBBlock ** ebbs, int count)
2259 debugLog ("%s\n", __FUNCTION__);
2260 /* for all blocks */
2261 for (i = 0; i < count; i++)
2265 if (ebbs[i]->noPath &&
2266 (ebbs[i]->entryLabel != entryLabel &&
2267 ebbs[i]->entryLabel != returnLabel))
2270 /* for all instructions */
2271 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2276 if (SKIP_IC2 (ic) || !ic->rlive)
2279 /* first mark the registers used in this
2281 ic->rUsed = regsUsedIniCode (ic);
2282 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2284 /* now create the register mask for those
2285 registers that are in use : this is a
2286 super set of ic->rUsed */
2287 ic->rMask = newBitVect (pic16_nRegs + 1);
2289 /* for all live Ranges alive at this point */
2290 for (j = 1; j < ic->rlive->size; j++)
2295 /* if not alive then continue */
2296 if (!bitVectBitValue (ic->rlive, j))
2299 /* find the live range we are interested in */
2300 if (!(sym = hTabItemWithKey (liveRanges, j)))
2302 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2303 "createRegMask cannot find live range");
2307 /* if no register assigned to it */
2308 if (!sym->nRegs || sym->isspilt)
2311 /* for all the registers allocated to it */
2312 for (k = 0; k < sym->nRegs; k++)
2315 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2321 /*-----------------------------------------------------------------*/
2322 /* rematStr - returns the rematerialized string for a remat var */
2323 /*-----------------------------------------------------------------*/
2325 rematStr (symbol * sym)
2328 iCode *ic = sym->rematiCode;
2329 symbol *psym = NULL;
2331 debugLog ("%s\n", __FUNCTION__);
2333 //printf ("%s\n", s);
2335 /* if plus or minus print the right hand side */
2337 if (ic->op == '+' || ic->op == '-') {
2339 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2341 sprintf (s, "(%s %c 0x%04x)",
2342 OP_SYMBOL (IC_LEFT (ric))->rname,
2344 (int) operandLitValue (IC_RIGHT (ic)));
2347 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2349 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2350 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2355 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2356 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2358 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2363 /*-----------------------------------------------------------------*/
2364 /* rematStr - returns the rematerialized string for a remat var */
2365 /*-----------------------------------------------------------------*/
2367 rematStr (symbol * sym)
2370 iCode *ic = sym->rematiCode;
2372 debugLog ("%s\n", __FUNCTION__);
2377 /* if plus or minus print the right hand side */
2379 if (ic->op == '+' || ic->op == '-') {
2380 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2383 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2387 if (ic->op == '+' || ic->op == '-')
2389 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2390 sprintf (s, "(%s %c 0x%04x)",
2391 OP_SYMBOL (IC_LEFT (ric))->rname,
2393 (int) operandLitValue (IC_RIGHT (ic)));
2396 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2398 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2402 /* we reached the end */
2403 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2407 printf ("%s\n", buffer);
2412 /*-----------------------------------------------------------------*/
2413 /* regTypeNum - computes the type & number of registers required */
2414 /*-----------------------------------------------------------------*/
2422 debugLog ("%s\n", __FUNCTION__);
2423 /* for each live range do */
2424 for (sym = hTabFirstItem (liveRanges, &k); sym;
2425 sym = hTabNextItem (liveRanges, &k)) {
2427 debugLog (" %d - %s\n", __LINE__, sym->rname);
2429 /* if used zero times then no registers needed */
2430 if ((sym->liveTo - sym->liveFrom) == 0)
2434 /* if the live range is a temporary */
2437 debugLog (" %d - itemp register\n", __LINE__);
2439 /* if the type is marked as a conditional */
2440 if (sym->regType == REG_CND)
2443 /* if used in return only then we don't
2445 if (sym->ruonly || sym->accuse) {
2446 if (IS_AGGREGATE (sym->type) || sym->isptr)
2447 sym->type = aggrToPtr (sym->type, FALSE);
2448 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
2453 /* if the symbol has only one definition &
2454 that definition is a get_pointer and the
2455 pointer we are getting is rematerializable and
2458 if (bitVectnBitsOn (sym->defs) == 1 &&
2459 (ic = hTabItemWithKey (iCodehTab,
2460 bitVectFirstBit (sym->defs))) &&
2463 !IS_BITVAR (sym->etype)) {
2466 debugLog (" %d - \n", __LINE__);
2468 /* if remat in data space */
2469 if (OP_SYMBOL (IC_LEFT (ic))->remat &&
2470 DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) {
2472 /* create a psuedo symbol & force a spil */
2473 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2474 symbol *psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2475 psym->type = sym->type;
2476 psym->etype = sym->etype;
2477 strcpy (psym->rname, psym->name);
2479 sym->usl.spillLoc = psym;
2483 /* if in data space or idata space then try to
2484 allocate pointer register */
2488 /* if not then we require registers */
2489 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2490 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2491 getSize (sym->type));
2494 if(IS_PTR_CONST (sym->type)) {
2495 debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2499 if (sym->nRegs > 4) {
2500 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2501 printTypeChain (sym->type, stderr);
2502 fprintf (stderr, "\n");
2505 /* determine the type of register required */
2506 if (sym->nRegs == 1 &&
2507 IS_PTR (sym->type) &&
2509 sym->regType = REG_PTR;
2511 sym->regType = REG_GPR;
2514 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2518 /* for the first run we don't provide */
2519 /* registers for true symbols we will */
2520 /* see how things go */
2525 static DEFSETFUNC (markRegFree)
2527 ((regs *)item)->isFree = 1;
2532 DEFSETFUNC (pic16_deallocReg)
2534 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2535 ((regs *)item)->isFree = 1;
2536 ((regs *)item)->wasUsed = 0;
2540 /*-----------------------------------------------------------------*/
2541 /* freeAllRegs - mark all registers as free */
2542 /*-----------------------------------------------------------------*/
2544 pic16_freeAllRegs ()
2548 debugLog ("%s\n", __FUNCTION__);
2550 applyToSet(pic16_dynAllocRegs,markRegFree);
2551 applyToSet(pic16_dynStackRegs,markRegFree);
2554 for (i = 0; i < pic16_nRegs; i++)
2555 regspic16[i].isFree = 1;
2559 /*-----------------------------------------------------------------*/
2560 /*-----------------------------------------------------------------*/
2562 pic16_deallocateAllRegs ()
2566 debugLog ("%s\n", __FUNCTION__);
2568 applyToSet(pic16_dynAllocRegs,pic16_deallocReg);
2571 for (i = 0; i < pic16_nRegs; i++) {
2572 if(regspic16[i].pc_type == PO_GPR_TEMP) {
2573 regspic16[i].isFree = 1;
2574 regspic16[i].wasUsed = 0;
2581 /*-----------------------------------------------------------------*/
2582 /* deallocStackSpil - this will set the stack pointer back */
2583 /*-----------------------------------------------------------------*/
2585 DEFSETFUNC (deallocStackSpil)
2589 debugLog ("%s\n", __FUNCTION__);
2594 /*-----------------------------------------------------------------*/
2595 /* farSpacePackable - returns the packable icode for far variables */
2596 /*-----------------------------------------------------------------*/
2598 farSpacePackable (iCode * ic)
2602 debugLog ("%s\n", __FUNCTION__);
2603 /* go thru till we find a definition for the
2604 symbol on the right */
2605 for (dic = ic->prev; dic; dic = dic->prev)
2608 /* if the definition is a call then no */
2609 if ((dic->op == CALL || dic->op == PCALL) &&
2610 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2615 /* if shift by unknown amount then not */
2616 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2617 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2620 /* if pointer get and size > 1 */
2621 if (POINTER_GET (dic) &&
2622 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2625 if (POINTER_SET (dic) &&
2626 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2629 /* if any three is a true symbol in far space */
2630 if (IC_RESULT (dic) &&
2631 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2632 isOperandInFarSpace (IC_RESULT (dic)))
2635 if (IC_RIGHT (dic) &&
2636 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2637 isOperandInFarSpace (IC_RIGHT (dic)) &&
2638 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2641 if (IC_LEFT (dic) &&
2642 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2643 isOperandInFarSpace (IC_LEFT (dic)) &&
2644 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2647 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2649 if ((dic->op == LEFT_OP ||
2650 dic->op == RIGHT_OP ||
2652 IS_OP_LITERAL (IC_RIGHT (dic)))
2662 /*-----------------------------------------------------------------*/
2663 /* packRegsForAssign - register reduction for assignment */
2664 /*-----------------------------------------------------------------*/
2666 packRegsForAssign (iCode * ic, eBBlock * ebp)
2671 debugLog ("%s\n", __FUNCTION__);
2673 debugAopGet (" result:", IC_RESULT (ic));
2674 debugAopGet (" left:", IC_LEFT (ic));
2675 debugAopGet (" right:", IC_RIGHT (ic));
2677 /* if this is at an absolute address, then get the address. */
2678 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2679 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2680 debugLog (" %d - found config word declaration\n", __LINE__);
2681 if(IS_VALOP(IC_RIGHT(ic))) {
2682 debugLog (" setting config word to %x\n",
2683 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2684 pic16_assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2685 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2688 /* remove the assignment from the iCode chain. */
2690 remiCodeFromeBBlock (ebp, ic);
2691 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2692 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2699 if (!IS_ITEMP (IC_RESULT (ic))) {
2700 pic16_allocDirReg(IC_RESULT (ic));
2701 debugLog (" %d - result is not temp\n", __LINE__);
2704 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2705 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2706 pic16_allocDirReg(IC_LEFT (ic));
2710 if (!IS_ITEMP (IC_RIGHT (ic))) {
2711 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2712 pic16_allocDirReg(IC_RIGHT (ic));
2716 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2717 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2719 debugLog (" %d - not packing - right side fails \n", __LINE__);
2723 /* if the true symbol is defined in far space or on stack
2724 then we should not since this will increase register pressure */
2725 if (isOperandInFarSpace (IC_RESULT (ic)))
2727 if ((dic = farSpacePackable (ic)))
2733 /* find the definition of iTempNN scanning backwards if we find a
2734 a use of the true symbol before we find the definition then
2736 for (dic = ic->prev; dic; dic = dic->prev)
2739 /* if there is a function call and this is
2740 a parameter & not my parameter then don't pack it */
2741 if ((dic->op == CALL || dic->op == PCALL) &&
2742 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2743 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2745 debugLog (" %d - \n", __LINE__);
2753 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2754 IS_OP_VOLATILE (IC_RESULT (dic)))
2756 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2761 if (IS_SYMOP (IC_RESULT (dic)) &&
2762 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2764 /* A previous result was assigned to the same register - we'll our definition */
2765 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2766 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2767 if (POINTER_SET (dic))
2773 if (IS_SYMOP (IC_RIGHT (dic)) &&
2774 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2775 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2777 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
2782 if (IS_SYMOP (IC_LEFT (dic)) &&
2783 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2784 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2786 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
2791 if (POINTER_SET (dic) &&
2792 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2794 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
2802 return 0; /* did not find */
2804 /* if the result is on stack or iaccess then it must be
2805 the same atleast one of the operands */
2806 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2807 OP_SYMBOL (IC_RESULT (ic))->iaccess)
2810 /* the operation has only one symbol
2811 operator then we can pack */
2812 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2813 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2816 if (!((IC_LEFT (dic) &&
2817 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2819 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2823 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2824 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
2825 /* found the definition */
2826 /* replace the result with the result of */
2827 /* this assignment and remove this assignment */
2828 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2829 IC_RESULT (dic) = IC_RESULT (ic);
2831 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2833 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2835 /* delete from liverange table also
2836 delete from all the points inbetween and the new
2838 for (sic = dic; sic != ic; sic = sic->next)
2840 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2841 if (IS_ITEMP (IC_RESULT (dic)))
2842 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2845 remiCodeFromeBBlock (ebp, ic);
2846 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2847 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2848 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2854 /*-----------------------------------------------------------------*/
2855 /* findAssignToSym : scanning backwards looks for first assig found */
2856 /*-----------------------------------------------------------------*/
2858 findAssignToSym (operand * op, iCode * ic)
2862 debugLog ("%s\n", __FUNCTION__);
2863 for (dic = ic->prev; dic; dic = dic->prev)
2866 /* if definition by assignment */
2867 if (dic->op == '=' &&
2868 !POINTER_SET (dic) &&
2869 IC_RESULT (dic)->key == op->key
2870 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2874 /* we are interested only if defined in far space */
2875 /* or in stack space in case of + & - */
2877 /* if assigned to a non-symbol then return
2879 if (!IS_SYMOP (IC_RIGHT (dic)))
2882 /* if the symbol is in far space then
2884 if (isOperandInFarSpace (IC_RIGHT (dic)))
2887 /* for + & - operations make sure that
2888 if it is on the stack it is the same
2889 as one of the three operands */
2890 if ((ic->op == '+' || ic->op == '-') &&
2891 OP_SYMBOL (IC_RIGHT (dic))->onStack)
2894 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2895 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2896 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2904 /* if we find an usage then we cannot delete it */
2905 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2908 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2911 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2915 /* now make sure that the right side of dic
2916 is not defined between ic & dic */
2919 iCode *sic = dic->next;
2921 for (; sic != ic; sic = sic->next)
2922 if (IC_RESULT (sic) &&
2923 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2932 /*-----------------------------------------------------------------*/
2933 /* packRegsForSupport :- reduce some registers for support calls */
2934 /*-----------------------------------------------------------------*/
2936 packRegsForSupport (iCode * ic, eBBlock * ebp)
2940 debugLog ("%s\n", __FUNCTION__);
2941 /* for the left & right operand :- look to see if the
2942 left was assigned a true symbol in far space in that
2943 case replace them */
2944 if (IS_ITEMP (IC_LEFT (ic)) &&
2945 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2947 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
2953 debugAopGet ("removing left:", IC_LEFT (ic));
2955 /* found it we need to remove it from the
2957 for (sic = dic; sic != ic; sic = sic->next)
2958 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
2960 IC_LEFT (ic)->operand.symOperand =
2961 IC_RIGHT (dic)->operand.symOperand;
2962 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2963 remiCodeFromeBBlock (ebp, dic);
2964 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2965 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2969 /* do the same for the right operand */
2972 IS_ITEMP (IC_RIGHT (ic)) &&
2973 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2975 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2981 /* if this is a subtraction & the result
2982 is a true symbol in far space then don't pack */
2983 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
2985 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
2986 if (IN_FARSPACE (SPEC_OCLS (etype)))
2990 debugAopGet ("removing right:", IC_RIGHT (ic));
2992 /* found it we need to remove it from the
2994 for (sic = dic; sic != ic; sic = sic->next)
2995 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
2997 IC_RIGHT (ic)->operand.symOperand =
2998 IC_RIGHT (dic)->operand.symOperand;
2999 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3001 remiCodeFromeBBlock (ebp, dic);
3002 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3003 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3010 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3013 /*-----------------------------------------------------------------*/
3014 /* packRegsForOneuse : - will reduce some registers for single Use */
3015 /*-----------------------------------------------------------------*/
3017 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3022 debugLog ("%s\n", __FUNCTION__);
3023 /* if returning a literal then do nothing */
3027 /* only upto 2 bytes since we cannot predict
3028 the usage of b, & acc */
3029 if (getSize (operandType (op)) > (pic16_fReturnSizePic - 2) &&
3034 /* this routine will mark the a symbol as used in one
3035 instruction use only && if the definition is local
3036 (ie. within the basic block) && has only one definition &&
3037 that definition is either a return value from a
3038 function or does not contain any variables in
3040 uses = bitVectCopy (OP_USES (op));
3041 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3042 if (!bitVectIsZero (uses)) /* has other uses */
3045 /* if it has only one defintion */
3046 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3047 return NULL; /* has more than one definition */
3049 /* get that definition */
3051 hTabItemWithKey (iCodehTab,
3052 bitVectFirstBit (OP_DEFS (op)))))
3055 /* found the definition now check if it is local */
3056 if (dic->seq < ebp->fSeq ||
3057 dic->seq > ebp->lSeq)
3058 return NULL; /* non-local */
3060 /* now check if it is the return from
3062 if (dic->op == CALL || dic->op == PCALL)
3064 if (ic->op != SEND && ic->op != RETURN &&
3065 !POINTER_SET(ic) && !POINTER_GET(ic))
3067 OP_SYMBOL (op)->ruonly = 1;
3074 /* otherwise check that the definition does
3075 not contain any symbols in far space */
3076 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3077 isOperandInFarSpace (IC_RIGHT (dic)) ||
3078 IS_OP_RUONLY (IC_LEFT (ic)) ||
3079 IS_OP_RUONLY (IC_RIGHT (ic)))
3084 /* if pointer set then make sure the pointer
3086 if (POINTER_SET (dic) &&
3087 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3090 if (POINTER_GET (dic) &&
3091 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3096 /* also make sure the intervenening instructions
3097 don't have any thing in far space */
3098 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3101 /* if there is an intervening function call then no */
3102 if (dic->op == CALL || dic->op == PCALL)
3104 /* if pointer set then make sure the pointer
3106 if (POINTER_SET (dic) &&
3107 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3110 if (POINTER_GET (dic) &&
3111 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3114 /* if address of & the result is remat then okay */
3115 if (dic->op == ADDRESS_OF &&
3116 OP_SYMBOL (IC_RESULT (dic))->remat)
3119 /* if operand has size of three or more & this
3120 operation is a '*','/' or '%' then 'b' may
3122 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3123 getSize (operandType (op)) >= 3)
3126 /* if left or right or result is in far space */
3127 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3128 isOperandInFarSpace (IC_RIGHT (dic)) ||
3129 isOperandInFarSpace (IC_RESULT (dic)) ||
3130 IS_OP_RUONLY (IC_LEFT (dic)) ||
3131 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3132 IS_OP_RUONLY (IC_RESULT (dic)))
3138 OP_SYMBOL (op)->ruonly = 1;
3143 /*-----------------------------------------------------------------*/
3144 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3145 /*-----------------------------------------------------------------*/
3147 isBitwiseOptimizable (iCode * ic)
3149 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3150 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3152 debugLog ("%s\n", __FUNCTION__);
3153 /* bitwise operations are considered optimizable
3154 under the following conditions (Jean-Louis VERN)
3166 if (IS_LITERAL (rtype) ||
3167 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3173 /*-----------------------------------------------------------------*/
3174 /* packRegsForAccUse - pack registers for acc use */
3175 /*-----------------------------------------------------------------*/
3177 packRegsForAccUse (iCode * ic)
3181 debugLog ("%s\n", __FUNCTION__);
3183 /* if this is an aggregate, e.g. a one byte char array */
3184 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3187 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3189 /* if + or - then it has to be one byte result */
3190 if ((ic->op == '+' || ic->op == '-')
3191 && getSize (operandType (IC_RESULT (ic))) > 1)
3194 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3195 /* if shift operation make sure right side is not a literal */
3196 if (ic->op == RIGHT_OP &&
3197 (isOperandLiteral (IC_RIGHT (ic)) ||
3198 getSize (operandType (IC_RESULT (ic))) > 1))
3201 if (ic->op == LEFT_OP &&
3202 (isOperandLiteral (IC_RIGHT (ic)) ||
3203 getSize (operandType (IC_RESULT (ic))) > 1))
3206 if (IS_BITWISE_OP (ic) &&
3207 getSize (operandType (IC_RESULT (ic))) > 1)
3211 /* has only one definition */
3212 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3215 /* has only one use */
3216 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3219 /* and the usage immediately follows this iCode */
3220 if (!(uic = hTabItemWithKey (iCodehTab,
3221 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3224 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3225 if (ic->next != uic)
3228 /* if it is a conditional branch then we definitely can */
3232 if (uic->op == JUMPTABLE)
3235 /* if the usage is not is an assignment
3236 or an arithmetic / bitwise / shift operation then not */
3237 if (POINTER_SET (uic) &&
3238 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3241 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3242 if (uic->op != '=' &&
3243 !IS_ARITHMETIC_OP (uic) &&
3244 !IS_BITWISE_OP (uic) &&
3245 uic->op != LEFT_OP &&
3246 uic->op != RIGHT_OP)
3249 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3250 /* if used in ^ operation then make sure right is not a
3252 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3255 /* if shift operation make sure right side is not a literal */
3256 if (uic->op == RIGHT_OP &&
3257 (isOperandLiteral (IC_RIGHT (uic)) ||
3258 getSize (operandType (IC_RESULT (uic))) > 1))
3261 if (uic->op == LEFT_OP &&
3262 (isOperandLiteral (IC_RIGHT (uic)) ||
3263 getSize (operandType (IC_RESULT (uic))) > 1))
3266 /* make sure that the result of this icode is not on the
3267 stack, since acc is used to compute stack offset */
3268 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3269 OP_SYMBOL (IC_RESULT (uic))->onStack)
3272 /* if either one of them in far space then we cannot */
3273 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3274 isOperandInFarSpace (IC_LEFT (uic))) ||
3275 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3276 isOperandInFarSpace (IC_RIGHT (uic))))
3279 /* if the usage has only one operand then we can */
3280 if (IC_LEFT (uic) == NULL ||
3281 IC_RIGHT (uic) == NULL)
3284 /* make sure this is on the left side if not
3285 a '+' since '+' is commutative */
3286 if (ic->op != '+' &&
3287 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3290 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3291 /* if one of them is a literal then we can */
3292 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3293 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3294 (getSize (operandType (IC_RESULT (uic))) <= 1))
3296 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3300 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3301 /* if the other one is not on stack then we can */
3302 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3303 (IS_ITEMP (IC_RIGHT (uic)) ||
3304 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3305 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3308 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3309 (IS_ITEMP (IC_LEFT (uic)) ||
3310 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3311 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3317 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3318 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3323 /*-----------------------------------------------------------------*/
3324 /* packForPush - hueristics to reduce iCode for pushing */
3325 /*-----------------------------------------------------------------*/
3327 packForReceive (iCode * ic, eBBlock * ebp)
3331 debugLog ("%s\n", __FUNCTION__);
3332 debugAopGet (" result:", IC_RESULT (ic));
3333 debugAopGet (" left:", IC_LEFT (ic));
3334 debugAopGet (" right:", IC_RIGHT (ic));
3339 for (dic = ic->next; dic; dic = dic->next)
3344 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3345 debugLog (" used on left\n");
3346 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3347 debugLog (" used on right\n");
3348 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3349 debugLog (" used on result\n");
3351 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3352 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3357 debugLog (" hey we can remove this unnecessary assign\n");
3359 /*-----------------------------------------------------------------*/
3360 /* packForPush - hueristics to reduce iCode for pushing */
3361 /*-----------------------------------------------------------------*/
3363 packForPush (iCode * ic, eBBlock * ebp)
3367 debugLog ("%s\n", __FUNCTION__);
3368 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3371 /* must have only definition & one usage */
3372 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3373 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3376 /* find the definition */
3377 if (!(dic = hTabItemWithKey (iCodehTab,
3378 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3381 if (dic->op != '=' || POINTER_SET (dic))
3384 /* we now we know that it has one & only one def & use
3385 and the that the definition is an assignment */
3386 IC_LEFT (ic) = IC_RIGHT (dic);
3388 remiCodeFromeBBlock (ebp, dic);
3389 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3390 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3393 static void printSymType(char * str, sym_link *sl)
3395 debugLog (" %s Symbol type: ",str);
3396 printTypeChain( sl, debugF);
3401 /*-----------------------------------------------------------------*/
3402 /* some debug code to print the symbol S_TYPE. Note that
3403 * the function checkSClass in src/SDCCsymt.c dinks with
3404 * the S_TYPE in ways the PIC port doesn't fully like...*/
3405 /*-----------------------------------------------------------------*/
3406 static void isData(sym_link *sl)
3416 for ( ; sl; sl=sl->next) {
3418 switch (SPEC_SCLS(sl)) {
3420 case S_DATA: fprintf (of, "data "); break;
3421 case S_XDATA: fprintf (of, "xdata "); break;
3422 case S_SFR: fprintf (of, "sfr "); break;
3423 case S_SBIT: fprintf (of, "sbit "); break;
3424 case S_CODE: fprintf (of, "code "); break;
3425 case S_IDATA: fprintf (of, "idata "); break;
3426 case S_PDATA: fprintf (of, "pdata "); break;
3427 case S_LITERAL: fprintf (of, "literal "); break;
3428 case S_STACK: fprintf (of, "stack "); break;
3429 case S_XSTACK: fprintf (of, "xstack "); break;
3430 case S_BIT: fprintf (of, "bit "); break;
3431 case S_EEPROM: fprintf (of, "eeprom "); break;
3440 /*-----------------------------------------------------------------*/
3441 /* packRegisters - does some transformations to reduce register */
3443 /*-----------------------------------------------------------------*/
3445 packRegisters (eBBlock * ebp)
3450 debugLog ("%s\n", __FUNCTION__);
3456 /* look for assignments of the form */
3457 /* iTempNN = TRueSym (someoperation) SomeOperand */
3459 /* TrueSym := iTempNN:1 */
3460 for (ic = ebp->sch; ic; ic = ic->next)
3463 /* find assignment of the form TrueSym := iTempNN:1 */
3464 if (ic->op == '=' && !POINTER_SET (ic))
3465 change += packRegsForAssign (ic, ebp);
3469 if (POINTER_SET (ic))
3470 debugLog ("pointer is set\n");
3471 debugAopGet (" result:", IC_RESULT (ic));
3472 debugAopGet (" left:", IC_LEFT (ic));
3473 debugAopGet (" right:", IC_RIGHT (ic));
3482 for (ic = ebp->sch; ic; ic = ic->next) {
3484 if(IS_SYMOP ( IC_LEFT(ic))) {
3485 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3487 debugAopGet (" left:", IC_LEFT (ic));
3488 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3489 debugLog (" is a pointer\n");
3491 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3492 debugLog (" is volatile\n");
3496 printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
3499 if(IS_SYMOP ( IC_RIGHT(ic))) {
3500 debugAopGet (" right:", IC_RIGHT (ic));
3501 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3504 if(IS_SYMOP ( IC_RESULT(ic))) {
3505 debugAopGet (" result:", IC_RESULT (ic));
3506 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3509 if (POINTER_SET (ic))
3510 debugLog (" %d - Pointer set\n", __LINE__);
3513 /* if this is an itemp & result of a address of a true sym
3514 then mark this as rematerialisable */
3515 if (ic->op == ADDRESS_OF &&
3516 IS_ITEMP (IC_RESULT (ic)) &&
3517 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3518 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3519 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3522 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3524 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3525 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3526 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3530 /* if straight assignment then carry remat flag if
3531 this is the only definition */
3532 if (ic->op == '=' &&
3533 !POINTER_SET (ic) &&
3534 IS_SYMOP (IC_RIGHT (ic)) &&
3535 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3536 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3538 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3540 OP_SYMBOL (IC_RESULT (ic))->remat =
3541 OP_SYMBOL (IC_RIGHT (ic))->remat;
3542 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3543 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3546 /* if this is a +/- operation with a rematerizable
3547 then mark this as rematerializable as well */
3548 if ((ic->op == '+' || ic->op == '-') &&
3549 (IS_SYMOP (IC_LEFT (ic)) &&
3550 IS_ITEMP (IC_RESULT (ic)) &&
3551 OP_SYMBOL (IC_LEFT (ic))->remat &&
3552 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3553 IS_OP_LITERAL (IC_RIGHT (ic))))
3555 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3557 operandLitValue (IC_RIGHT (ic));
3558 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3559 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3560 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3563 /* mark the pointer usages */
3564 if (POINTER_SET (ic))
3566 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3567 debugLog (" marking as a pointer (set) =>");
3568 debugAopGet (" result:", IC_RESULT (ic));
3570 if (POINTER_GET (ic))
3572 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3573 debugLog (" marking as a pointer (get) =>");
3574 debugAopGet (" left:", IC_LEFT (ic));
3579 /* if we are using a symbol on the stack
3580 then we should say pic16_ptrRegReq */
3581 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3582 pic16_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3583 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3584 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3585 pic16_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3586 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3589 if (IS_SYMOP (IC_LEFT (ic)))
3590 pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3591 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3592 if (IS_SYMOP (IC_RIGHT (ic)))
3593 pic16_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3594 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3595 if (IS_SYMOP (IC_RESULT (ic)))
3596 pic16_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3597 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3600 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic16_ptrRegReq);
3604 /* if the condition of an if instruction
3605 is defined in the previous instruction then
3606 mark the itemp as a conditional */
3607 if ((IS_CONDITIONAL (ic) ||
3608 ((ic->op == BITWISEAND ||
3611 isBitwiseOptimizable (ic))) &&
3612 ic->next && ic->next->op == IFX &&
3613 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3614 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3617 debugLog (" %d\n", __LINE__);
3618 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3622 /* reduce for support function calls */
3623 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3624 packRegsForSupport (ic, ebp);
3626 /* if a parameter is passed, it's in W, so we may not
3627 need to place a copy in a register */
3628 if (ic->op == RECEIVE)
3629 packForReceive (ic, ebp);
3631 /* some cases the redundant moves can
3632 can be eliminated for return statements */
3633 if ((ic->op == RETURN || ic->op == SEND) &&
3634 !isOperandInFarSpace (IC_LEFT (ic)) &&
3636 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3638 /* if pointer set & left has a size more than
3639 one and right is not in far space */
3640 if (POINTER_SET (ic) &&
3641 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3642 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3643 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3644 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3646 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3648 /* if pointer get */
3649 if (POINTER_GET (ic) &&
3650 !isOperandInFarSpace (IC_RESULT (ic)) &&
3651 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3652 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3653 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3655 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3658 /* if this is cast for intergral promotion then
3659 check if only use of the definition of the
3660 operand being casted/ if yes then replace
3661 the result of that arithmetic operation with
3662 this result and get rid of the cast */
3663 if (ic->op == CAST) {
3665 sym_link *fromType = operandType (IC_RIGHT (ic));
3666 sym_link *toType = operandType (IC_LEFT (ic));
3668 debugLog (" %d - casting\n", __LINE__);
3670 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3671 getSize (fromType) != getSize (toType)) {
3674 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3677 if (IS_ARITHMETIC_OP (dic)) {
3679 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3680 IC_RESULT (dic) = IC_RESULT (ic);
3681 remiCodeFromeBBlock (ebp, ic);
3682 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3683 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3684 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3688 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3692 /* if the type from and type to are the same
3693 then if this is the only use then packit */
3694 if (compareType (operandType (IC_RIGHT (ic)),
3695 operandType (IC_LEFT (ic))) == 1) {
3697 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3700 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3701 IC_RESULT (dic) = IC_RESULT (ic);
3702 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3703 remiCodeFromeBBlock (ebp, ic);
3704 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3705 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3713 iTempNN := (some variable in farspace) V1
3718 if (ic->op == IPUSH)
3720 packForPush (ic, ebp);
3724 /* pack registers for accumulator use, when the
3725 result of an arithmetic or bit wise operation
3726 has only one use, that use is immediately following
3727 the defintion and the using iCode has only one
3728 operand or has two operands but one is literal &
3729 the result of that operation is not on stack then
3730 we can leave the result of this operation in acc:b
3732 if ((IS_ARITHMETIC_OP (ic)
3734 || IS_BITWISE_OP (ic)
3736 || ic->op == LEFT_OP || ic->op == RIGHT_OP
3739 IS_ITEMP (IC_RESULT (ic)) &&
3740 getSize (operandType (IC_RESULT (ic))) <= 2)
3742 packRegsForAccUse (ic);
3748 dumpEbbsToDebug (eBBlock ** ebbs, int count)
3752 if (!debug || !debugF)
3755 for (i = 0; i < count; i++)
3757 fprintf (debugF, "\n----------------------------------------------------------------\n");
3758 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
3759 ebbs[i]->entryLabel->name,
3762 ebbs[i]->isLastInLoop);
3763 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
3768 fprintf (debugF, "visited %d : hasFcall = %d\n",
3772 fprintf (debugF, "\ndefines bitVector :");
3773 bitVectDebugOn (ebbs[i]->defSet, debugF);
3774 fprintf (debugF, "\nlocal defines bitVector :");
3775 bitVectDebugOn (ebbs[i]->ldefs, debugF);
3776 fprintf (debugF, "\npointers Set bitvector :");
3777 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
3778 fprintf (debugF, "\nin pointers Set bitvector :");
3779 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
3780 fprintf (debugF, "\ninDefs Set bitvector :");
3781 bitVectDebugOn (ebbs[i]->inDefs, debugF);
3782 fprintf (debugF, "\noutDefs Set bitvector :");
3783 bitVectDebugOn (ebbs[i]->outDefs, debugF);
3784 fprintf (debugF, "\nusesDefs Set bitvector :");
3785 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
3786 fprintf (debugF, "\n----------------------------------------------------------------\n");
3787 printiCChain (ebbs[i]->sch, debugF);
3790 /*-----------------------------------------------------------------*/
3791 /* pic16_assignRegisters - assigns registers to each live range as need */
3792 /*-----------------------------------------------------------------*/
3794 pic16_assignRegisters (eBBlock ** ebbs, int count)
3799 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
3800 debugLog ("\nebbs before optimizing:\n");
3801 dumpEbbsToDebug (ebbs, count);
3803 setToNull ((void *) &_G.funcrUsed);
3804 pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3807 /* change assignments this will remove some
3808 live ranges reducing some register pressure */
3809 for (i = 0; i < count; i++)
3810 packRegisters (ebbs[i]);
3817 debugLog("dir registers allocated so far:\n");
3818 reg = hTabFirstItem(dynDirectRegNames, &hkey);
3821 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
3822 reg = hTabNextItem(dynDirectRegNames, &hkey);
3827 if (options.dump_pack)
3828 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3830 /* first determine for each live range the number of
3831 registers & the type of registers required for each */
3834 /* and serially allocate registers */
3835 serialRegAssign (ebbs, count);
3837 /* if stack was extended then tell the user */
3840 /* werror(W_TOOMANY_SPILS,"stack", */
3841 /* _G.stackExtend,currFunc->name,""); */
3847 /* werror(W_TOOMANY_SPILS,"data space", */
3848 /* _G.dataExtend,currFunc->name,""); */
3852 /* after that create the register mask
3853 for each of the instruction */
3854 createRegMask (ebbs, count);
3856 /* redo that offsets for stacked automatic variables */
3857 redoStackOffsets ();
3859 if (options.dump_rassgn)
3860 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3862 /* now get back the chain */
3863 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3865 debugLog ("ebbs after optimizing:\n");
3866 dumpEbbsToDebug (ebbs, count);
3871 /* free up any _G.stackSpil locations allocated */
3872 applyToSet (_G.stackSpil, deallocStackSpil);
3874 setToNull ((void **) &_G.stackSpil);
3875 setToNull ((void **) &_G.spiltSet);
3876 /* mark all registers as free */
3877 //pic16_freeAllRegs ();
3879 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");