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);
950 extern void pic16_assignFixedRegisters(set *regset);
951 extern void pic16_assignRelocatableRegisters(set *regset,int used);
952 extern void pic16_dump_map(void);
953 extern void pic16_dump_cblock(FILE *of);
956 static void packBits(set *bregs)
961 regs *relocbitfield=NULL;
967 for (regset = bregs ; regset ;
968 regset = regset->next) {
971 breg->isBitField = 1;
972 //fprintf(stderr,"bit reg: %s\n",breg->name);
975 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
977 bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1);
978 breg->rIdx = breg->address & 7;
982 sprintf (buffer, "fbitfield%02x", breg->address);
983 //fprintf(stderr,"new bit field\n");
984 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0);
985 bitfield->isBitField = 1;
986 bitfield->isFixed = 1;
987 bitfield->address = breg->address;
988 addSet(&pic16_dynDirectRegs,bitfield);
989 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
991 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
994 breg->reg_alias = bitfield;
998 if(!relocbitfield || bit_no >7) {
1001 sprintf (buffer, "bitfield%d", byte_no);
1002 //fprintf(stderr,"new relocatable bit field\n");
1003 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0);
1004 relocbitfield->isBitField = 1;
1005 addSet(&pic16_dynDirectRegs,relocbitfield);
1006 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1010 breg->reg_alias = relocbitfield;
1011 breg->address = rDirectIdx; /* byte_no; */
1012 breg->rIdx = bit_no++;
1020 static void bitEQUs(FILE *of, set *bregs)
1022 regs *breg,*bytereg;
1025 //fprintf(stderr," %s\n",__FUNCTION__);
1026 for (breg = setFirstItem(bregs) ; breg ;
1027 breg = setNextItem(bregs)) {
1029 //fprintf(stderr,"bit reg: %s\n",breg->name);
1031 bytereg = breg->reg_alias;
1033 fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
1036 breg->rIdx & 0x0007);
1039 fprintf(stderr, "bit field is not assigned to a register\n");
1040 fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
1051 static void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
1056 for (reg = setFirstItem(fregs) ; reg ;
1057 reg = setNextItem(fregs)) {
1059 if(!reg->isEmitted && reg->wasUsed) {
1061 if (reg->type != REG_SFR) {
1062 fprintf (of, "%s\tEQU\t0x%03x\n",
1068 fprintf (of, "%s\tEQU\t0x%03x\n",
1076 void pic16_writeUsedRegs(FILE *of)
1078 packBits(pic16_dynDirectBitRegs);
1081 pic16_assignFixedRegisters(pic16_dynAllocRegs);
1082 pic16_assignFixedRegisters(pic16_dynStackRegs);
1083 pic16_assignFixedRegisters(pic16_dynDirectRegs);
1085 pic16_assignRelocatableRegisters(pic16_dynInternalRegs,0);
1086 pic16_assignRelocatableRegisters(pic16_dynAllocRegs,0);
1087 pic16_assignRelocatableRegisters(pic16_dynStackRegs,0);
1088 pic16_assignRelocatableRegisters(pic16_dynDirectRegs,0);
1092 pic16_dump_cblock(of);
1093 bitEQUs(of,pic16_dynDirectBitRegs);
1094 aliasEQUs(of,pic16_dynAllocRegs,0);
1095 aliasEQUs(of,pic16_dynDirectRegs,0);
1096 aliasEQUs(of,pic16_dynStackRegs,0);
1097 aliasEQUs(of,pic16_dynProcessorRegs,1);
1102 /*-----------------------------------------------------------------*/
1103 /* allDefsOutOfRange - all definitions are out of a range */
1104 /*-----------------------------------------------------------------*/
1106 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
1110 debugLog ("%s\n", __FUNCTION__);
1114 for (i = 0; i < defs->size; i++)
1118 if (bitVectBitValue (defs, i) &&
1119 (ic = hTabItemWithKey (iCodehTab, i)) &&
1120 (ic->seq >= fseq && ic->seq <= toseq))
1130 /*-----------------------------------------------------------------*/
1131 /* computeSpillable - given a point find the spillable live ranges */
1132 /*-----------------------------------------------------------------*/
1134 computeSpillable (iCode * ic)
1138 debugLog ("%s\n", __FUNCTION__);
1139 /* spillable live ranges are those that are live at this
1140 point . the following categories need to be subtracted
1142 a) - those that are already spilt
1143 b) - if being used by this one
1144 c) - defined by this one */
1146 spillable = bitVectCopy (ic->rlive);
1148 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1150 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1151 bitVectUnSetBit (spillable, ic->defKey);
1152 spillable = bitVectIntersect (spillable, _G.regAssigned);
1157 /*-----------------------------------------------------------------*/
1158 /* noSpilLoc - return true if a variable has no spil location */
1159 /*-----------------------------------------------------------------*/
1161 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1163 debugLog ("%s\n", __FUNCTION__);
1164 return (sym->usl.spillLoc ? 0 : 1);
1167 /*-----------------------------------------------------------------*/
1168 /* hasSpilLoc - will return 1 if the symbol has spil location */
1169 /*-----------------------------------------------------------------*/
1171 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1173 debugLog ("%s\n", __FUNCTION__);
1174 return (sym->usl.spillLoc ? 1 : 0);
1177 /*-----------------------------------------------------------------*/
1178 /* directSpilLoc - will return 1 if the splilocation is in direct */
1179 /*-----------------------------------------------------------------*/
1181 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1183 debugLog ("%s\n", __FUNCTION__);
1184 if (sym->usl.spillLoc &&
1185 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1191 /*-----------------------------------------------------------------*/
1192 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1193 /* but is not used as a pointer */
1194 /*-----------------------------------------------------------------*/
1196 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1198 debugLog ("%s\n", __FUNCTION__);
1199 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1202 /*-----------------------------------------------------------------*/
1203 /* rematable - will return 1 if the remat flag is set */
1204 /*-----------------------------------------------------------------*/
1206 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1208 debugLog ("%s\n", __FUNCTION__);
1212 /*-----------------------------------------------------------------*/
1213 /* notUsedInRemaining - not used or defined in remain of the block */
1214 /*-----------------------------------------------------------------*/
1216 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1218 debugLog ("%s\n", __FUNCTION__);
1219 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1220 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1223 /*-----------------------------------------------------------------*/
1224 /* allLRs - return true for all */
1225 /*-----------------------------------------------------------------*/
1227 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1229 debugLog ("%s\n", __FUNCTION__);
1233 /*-----------------------------------------------------------------*/
1234 /* liveRangesWith - applies function to a given set of live range */
1235 /*-----------------------------------------------------------------*/
1237 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1238 eBBlock * ebp, iCode * ic)
1243 debugLog ("%s\n", __FUNCTION__);
1244 if (!lrs || !lrs->size)
1247 for (i = 1; i < lrs->size; i++)
1250 if (!bitVectBitValue (lrs, i))
1253 /* if we don't find it in the live range
1254 hash table we are in serious trouble */
1255 if (!(sym = hTabItemWithKey (liveRanges, i)))
1257 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1258 "liveRangesWith could not find liveRange");
1262 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1263 addSetHead (&rset, sym);
1270 /*-----------------------------------------------------------------*/
1271 /* leastUsedLR - given a set determines which is the least used */
1272 /*-----------------------------------------------------------------*/
1274 leastUsedLR (set * sset)
1276 symbol *sym = NULL, *lsym = NULL;
1278 debugLog ("%s\n", __FUNCTION__);
1279 sym = lsym = setFirstItem (sset);
1284 for (; lsym; lsym = setNextItem (sset))
1287 /* if usage is the same then prefer
1288 the spill the smaller of the two */
1289 if (lsym->used == sym->used)
1290 if (getSize (lsym->type) < getSize (sym->type))
1294 if (lsym->used < sym->used)
1299 setToNull ((void **) &sset);
1304 /*-----------------------------------------------------------------*/
1305 /* noOverLap - will iterate through the list looking for over lap */
1306 /*-----------------------------------------------------------------*/
1308 noOverLap (set * itmpStack, symbol * fsym)
1311 debugLog ("%s\n", __FUNCTION__);
1314 for (sym = setFirstItem (itmpStack); sym;
1315 sym = setNextItem (itmpStack))
1317 if (sym->liveTo > fsym->liveFrom)
1325 /*-----------------------------------------------------------------*/
1326 /* isFree - will return 1 if the a free spil location is found */
1327 /*-----------------------------------------------------------------*/
1332 V_ARG (symbol **, sloc);
1333 V_ARG (symbol *, fsym);
1335 debugLog ("%s\n", __FUNCTION__);
1336 /* if already found */
1340 /* if it is free && and the itmp assigned to
1341 this does not have any overlapping live ranges
1342 with the one currently being assigned and
1343 the size can be accomodated */
1345 noOverLap (sym->usl.itmpStack, fsym) &&
1346 getSize (sym->type) >= getSize (fsym->type))
1355 /*-----------------------------------------------------------------*/
1356 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1357 /*-----------------------------------------------------------------*/
1359 spillLRWithPtrReg (symbol * forSym)
1365 debugLog ("%s\n", __FUNCTION__);
1366 if (!_G.regAssigned ||
1367 bitVectIsZero (_G.regAssigned))
1370 r0 = pic16_regWithIdx (R0_IDX);
1371 r1 = pic16_regWithIdx (R1_IDX);
1373 /* for all live ranges */
1374 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1375 lrsym = hTabNextItem (liveRanges, &k))
1379 /* if no registers assigned to it or
1381 /* if it does not overlap with this then
1382 not need to spill it */
1384 if (lrsym->isspilt || !lrsym->nRegs ||
1385 (lrsym->liveTo < forSym->liveFrom))
1388 /* go thru the registers : if it is either
1389 r0 or r1 then spil it */
1390 for (j = 0; j < lrsym->nRegs; j++)
1391 if (lrsym->regs[j] == r0 ||
1392 lrsym->regs[j] == r1)
1401 /*-----------------------------------------------------------------*/
1402 /* createStackSpil - create a location on the stack to spil */
1403 /*-----------------------------------------------------------------*/
1405 createStackSpil (symbol * sym)
1407 symbol *sloc = NULL;
1408 int useXstack, model, noOverlay;
1410 char slocBuffer[30];
1411 debugLog ("%s\n", __FUNCTION__);
1413 /* first go try and find a free one that is already
1414 existing on the stack */
1415 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1417 /* found a free one : just update & return */
1418 sym->usl.spillLoc = sloc;
1421 addSetHead (&sloc->usl.itmpStack, sym);
1425 /* could not then have to create one , this is the hard part
1426 we need to allocate this on the stack : this is really a
1427 hack!! but cannot think of anything better at this time */
1429 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1431 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1432 __FILE__, __LINE__);
1436 sloc = newiTemp (slocBuffer);
1438 /* set the type to the spilling symbol */
1439 sloc->type = copyLinkChain (sym->type);
1440 sloc->etype = getSpec (sloc->type);
1441 SPEC_SCLS (sloc->etype) = S_DATA;
1442 SPEC_EXTR (sloc->etype) = 0;
1443 SPEC_STAT (sloc->etype) = 0;
1445 /* we don't allow it to be allocated`
1446 onto the external stack since : so we
1447 temporarily turn it off ; we also
1448 turn off memory model to prevent
1449 the spil from going to the external storage
1450 and turn off overlaying
1453 useXstack = options.useXstack;
1454 model = options.model;
1455 noOverlay = options.noOverlay;
1456 options.noOverlay = 1;
1457 options.model = options.useXstack = 0;
1461 options.useXstack = useXstack;
1462 options.model = model;
1463 options.noOverlay = noOverlay;
1464 sloc->isref = 1; /* to prevent compiler warning */
1466 /* if it is on the stack then update the stack */
1467 if (IN_STACK (sloc->etype))
1469 currFunc->stack += getSize (sloc->type);
1470 _G.stackExtend += getSize (sloc->type);
1473 _G.dataExtend += getSize (sloc->type);
1475 /* add it to the _G.stackSpil set */
1476 addSetHead (&_G.stackSpil, sloc);
1477 sym->usl.spillLoc = sloc;
1480 /* add it to the set of itempStack set
1481 of the spill location */
1482 addSetHead (&sloc->usl.itmpStack, sym);
1486 /*-----------------------------------------------------------------*/
1487 /* isSpiltOnStack - returns true if the spil location is on stack */
1488 /*-----------------------------------------------------------------*/
1490 isSpiltOnStack (symbol * sym)
1494 debugLog ("%s\n", __FUNCTION__);
1501 /* if (sym->_G.stackSpil) */
1504 if (!sym->usl.spillLoc)
1507 etype = getSpec (sym->usl.spillLoc->type);
1508 if (IN_STACK (etype))
1514 /*-----------------------------------------------------------------*/
1515 /* spillThis - spils a specific operand */
1516 /*-----------------------------------------------------------------*/
1518 spillThis (symbol * sym)
1521 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1523 /* if this is rematerializable or has a spillLocation
1524 we are okay, else we need to create a spillLocation
1526 if (!(sym->remat || sym->usl.spillLoc))
1527 createStackSpil (sym);
1530 /* mark it has spilt & put it in the spilt set */
1532 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1534 bitVectUnSetBit (_G.regAssigned, sym->key);
1536 for (i = 0; i < sym->nRegs; i++)
1540 freeReg (sym->regs[i]);
1541 sym->regs[i] = NULL;
1544 /* if spilt on stack then free up r0 & r1
1545 if they could have been assigned to some
1547 if (!pic16_ptrRegReq && isSpiltOnStack (sym))
1550 spillLRWithPtrReg (sym);
1553 if (sym->usl.spillLoc && !sym->remat)
1554 sym->usl.spillLoc->allocreq = 1;
1558 /*-----------------------------------------------------------------*/
1559 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1560 /*-----------------------------------------------------------------*/
1562 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1564 bitVect *lrcs = NULL;
1568 debugLog ("%s\n", __FUNCTION__);
1569 /* get the spillable live ranges */
1570 lrcs = computeSpillable (ic);
1572 /* get all live ranges that are rematerizable */
1573 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1576 /* return the least used of these */
1577 return leastUsedLR (selectS);
1580 /* get live ranges with spillLocations in direct space */
1581 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1583 sym = leastUsedLR (selectS);
1584 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1585 sym->usl.spillLoc->rname :
1586 sym->usl.spillLoc->name));
1588 /* mark it as allocation required */
1589 sym->usl.spillLoc->allocreq = 1;
1593 /* if the symbol is local to the block then */
1594 if (forSym->liveTo < ebp->lSeq)
1597 /* check if there are any live ranges allocated
1598 to registers that are not used in this block */
1599 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1601 sym = leastUsedLR (selectS);
1602 /* if this is not rematerializable */
1611 /* check if there are any live ranges that not
1612 used in the remainder of the block */
1613 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1615 sym = leastUsedLR (selectS);
1618 sym->remainSpil = 1;
1625 /* find live ranges with spillocation && not used as pointers */
1626 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1629 sym = leastUsedLR (selectS);
1630 /* mark this as allocation required */
1631 sym->usl.spillLoc->allocreq = 1;
1635 /* find live ranges with spillocation */
1636 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1639 sym = leastUsedLR (selectS);
1640 sym->usl.spillLoc->allocreq = 1;
1644 /* couldn't find then we need to create a spil
1645 location on the stack , for which one? the least
1647 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1650 /* return a created spil location */
1651 sym = createStackSpil (leastUsedLR (selectS));
1652 sym->usl.spillLoc->allocreq = 1;
1656 /* this is an extreme situation we will spill
1657 this one : happens very rarely but it does happen */
1663 /*-----------------------------------------------------------------*/
1664 /* spilSomething - spil some variable & mark registers as free */
1665 /*-----------------------------------------------------------------*/
1667 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1672 debugLog ("%s\n", __FUNCTION__);
1673 /* get something we can spil */
1674 ssym = selectSpil (ic, ebp, forSym);
1676 /* mark it as spilt */
1678 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1680 /* mark it as not register assigned &
1681 take it away from the set */
1682 bitVectUnSetBit (_G.regAssigned, ssym->key);
1684 /* mark the registers as free */
1685 for (i = 0; i < ssym->nRegs; i++)
1687 freeReg (ssym->regs[i]);
1689 /* if spilt on stack then free up r0 & r1
1690 if they could have been assigned to as gprs */
1691 if (!pic16_ptrRegReq && isSpiltOnStack (ssym))
1694 spillLRWithPtrReg (ssym);
1697 /* if this was a block level spil then insert push & pop
1698 at the start & end of block respectively */
1699 if (ssym->blockSpil)
1701 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1702 /* add push to the start of the block */
1703 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1704 ebp->sch->next : ebp->sch));
1705 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1706 /* add pop to the end of the block */
1707 addiCodeToeBBlock (ebp, nic, NULL);
1710 /* if spilt because not used in the remainder of the
1711 block then add a push before this instruction and
1712 a pop at the end of the block */
1713 if (ssym->remainSpil)
1716 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1717 /* add push just before this instruction */
1718 addiCodeToeBBlock (ebp, nic, ic);
1720 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1721 /* add pop to the end of the block */
1722 addiCodeToeBBlock (ebp, nic, NULL);
1731 /*-----------------------------------------------------------------*/
1732 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1733 /*-----------------------------------------------------------------*/
1735 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1739 debugLog ("%s\n", __FUNCTION__);
1741 /* try for a ptr type */
1742 if ((reg = allocReg (REG_PTR)))
1745 /* try for gpr type */
1746 if ((reg = allocReg (REG_GPR)))
1749 /* we have to spil */
1750 if (!spilSomething (ic, ebp, sym))
1753 /* this looks like an infinite loop but
1754 in really selectSpil will abort */
1758 /*-----------------------------------------------------------------*/
1759 /* getRegGpr - will try for GPR if not spil */
1760 /*-----------------------------------------------------------------*/
1762 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1766 debugLog ("%s\n", __FUNCTION__);
1768 /* try for gpr type */
1769 if ((reg = allocReg (REG_GPR)))
1772 if (!pic16_ptrRegReq)
1773 if ((reg = allocReg (REG_PTR)))
1776 /* we have to spil */
1777 if (!spilSomething (ic, ebp, sym))
1780 /* this looks like an infinite loop but
1781 in really selectSpil will abort */
1785 /*-----------------------------------------------------------------*/
1786 /* symHasReg - symbol has a given register */
1787 /*-----------------------------------------------------------------*/
1789 symHasReg (symbol * sym, regs * reg)
1793 debugLog ("%s\n", __FUNCTION__);
1794 for (i = 0; i < sym->nRegs; i++)
1795 if (sym->regs[i] == reg)
1801 /*-----------------------------------------------------------------*/
1802 /* deassignLRs - check the live to and if they have registers & are */
1803 /* not spilt then free up the registers */
1804 /*-----------------------------------------------------------------*/
1806 deassignLRs (iCode * ic, eBBlock * ebp)
1812 debugLog ("%s\n", __FUNCTION__);
1813 for (sym = hTabFirstItem (liveRanges, &k); sym;
1814 sym = hTabNextItem (liveRanges, &k))
1817 symbol *psym = NULL;
1818 /* if it does not end here */
1819 if (sym->liveTo > ic->seq)
1822 /* if it was spilt on stack then we can
1823 mark the stack spil location as free */
1828 sym->usl.spillLoc->isFree = 1;
1834 if (!bitVectBitValue (_G.regAssigned, sym->key))
1837 /* special case check if this is an IFX &
1838 the privious one was a pop and the
1839 previous one was not spilt then keep track
1841 if (ic->op == IFX && ic->prev &&
1842 ic->prev->op == IPOP &&
1843 !ic->prev->parmPush &&
1844 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1845 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1851 bitVectUnSetBit (_G.regAssigned, sym->key);
1853 /* if the result of this one needs registers
1854 and does not have it then assign it right
1856 if (IC_RESULT (ic) &&
1857 !(SKIP_IC2 (ic) || /* not a special icode */
1858 ic->op == JUMPTABLE ||
1863 POINTER_SET (ic)) &&
1864 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1865 result->liveTo > ic->seq && /* and will live beyond this */
1866 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1867 result->regType == sym->regType && /* same register types */
1868 result->nRegs && /* which needs registers */
1869 !result->isspilt && /* and does not already have them */
1871 !bitVectBitValue (_G.regAssigned, result->key) &&
1872 /* the number of free regs + number of regs in this LR
1873 can accomodate the what result Needs */
1874 ((nfreeRegsType (result->regType) +
1875 sym->nRegs) >= result->nRegs)
1879 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1881 result->regs[i] = sym->regs[i];
1883 result->regs[i] = getRegGpr (ic, ebp, result);
1885 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1889 /* free the remaining */
1890 for (; i < sym->nRegs; i++)
1894 if (!symHasReg (psym, sym->regs[i]))
1895 freeReg (sym->regs[i]);
1898 freeReg (sym->regs[i]);
1905 /*-----------------------------------------------------------------*/
1906 /* reassignLR - reassign this to registers */
1907 /*-----------------------------------------------------------------*/
1909 reassignLR (operand * op)
1911 symbol *sym = OP_SYMBOL (op);
1914 debugLog ("%s\n", __FUNCTION__);
1915 /* not spilt any more */
1916 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1917 bitVectUnSetBit (_G.spiltSet, sym->key);
1919 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1923 for (i = 0; i < sym->nRegs; i++)
1924 sym->regs[i]->isFree = 0;
1927 /*-----------------------------------------------------------------*/
1928 /* willCauseSpill - determines if allocating will cause a spill */
1929 /*-----------------------------------------------------------------*/
1931 willCauseSpill (int nr, int rt)
1933 debugLog ("%s\n", __FUNCTION__);
1934 /* first check if there are any avlb registers
1935 of te type required */
1938 /* special case for pointer type
1939 if pointer type not avlb then
1940 check for type gpr */
1941 if (nFreeRegs (rt) >= nr)
1943 if (nFreeRegs (REG_GPR) >= nr)
1948 if (pic16_ptrRegReq)
1950 if (nFreeRegs (rt) >= nr)
1955 if (nFreeRegs (REG_PTR) +
1956 nFreeRegs (REG_GPR) >= nr)
1961 debugLog (" ... yep it will (cause a spill)\n");
1962 /* it will cause a spil */
1966 /*-----------------------------------------------------------------*/
1967 /* positionRegs - the allocator can allocate same registers to res- */
1968 /* ult and operand, if this happens make sure they are in the same */
1969 /* position as the operand otherwise chaos results */
1970 /*-----------------------------------------------------------------*/
1972 positionRegs (symbol * result, symbol * opsym, int lineno)
1974 int count = min (result->nRegs, opsym->nRegs);
1975 int i, j = 0, shared = 0;
1977 debugLog ("%s\n", __FUNCTION__);
1978 /* if the result has been spilt then cannot share */
1983 /* first make sure that they actually share */
1984 for (i = 0; i < count; i++)
1986 for (j = 0; j < count; j++)
1988 if (result->regs[i] == opsym->regs[j] && i != j)
1998 regs *tmp = result->regs[i];
1999 result->regs[i] = result->regs[j];
2000 result->regs[j] = tmp;
2005 /*-----------------------------------------------------------------*/
2006 /* serialRegAssign - serially allocate registers to the variables */
2007 /*-----------------------------------------------------------------*/
2009 serialRegAssign (eBBlock ** ebbs, int count)
2013 debugLog ("%s\n", __FUNCTION__);
2014 /* for all blocks */
2015 for (i = 0; i < count; i++)
2020 if (ebbs[i]->noPath &&
2021 (ebbs[i]->entryLabel != entryLabel &&
2022 ebbs[i]->entryLabel != returnLabel))
2025 /* of all instructions do */
2026 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2029 debugLog (" op: %s\n", decodeOp (ic->op));
2031 /* if this is an ipop that means some live
2032 range will have to be assigned again */
2034 reassignLR (IC_LEFT (ic));
2036 /* if result is present && is a true symbol */
2037 if (IC_RESULT (ic) && ic->op != IFX &&
2038 IS_TRUE_SYMOP (IC_RESULT (ic)))
2039 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2041 /* take away registers from live
2042 ranges that end at this instruction */
2043 deassignLRs (ic, ebbs[i]);
2045 /* some don't need registers */
2046 if (SKIP_IC2 (ic) ||
2047 ic->op == JUMPTABLE ||
2051 (IC_RESULT (ic) && POINTER_SET (ic)))
2054 /* now we need to allocate registers
2055 only for the result */
2058 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2064 /* if it does not need or is spilt
2065 or is already assigned to registers
2066 or will not live beyond this instructions */
2069 bitVectBitValue (_G.regAssigned, sym->key) ||
2070 sym->liveTo <= ic->seq)
2073 /* if some liverange has been spilt at the block level
2074 and this one live beyond this block then spil this
2076 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2081 /* if trying to allocate this will cause
2082 a spill and there is nothing to spill
2083 or this one is rematerializable then
2085 willCS = willCauseSpill (sym->nRegs, sym->regType);
2086 spillable = computeSpillable (ic);
2088 (willCS && bitVectIsZero (spillable)))
2096 /* if it has a spillocation & is used less than
2097 all other live ranges then spill this */
2099 if (sym->usl.spillLoc) {
2100 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2101 allLRs, ebbs[i], ic));
2102 if (leastUsed && leastUsed->used > sym->used) {
2107 /* if none of the liveRanges have a spillLocation then better
2108 to spill this one than anything else already assigned to registers */
2109 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2110 /* if this is local to this block then we might find a block spil */
2111 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2119 if (ic->op == RECEIVE)
2120 debugLog ("When I get clever, I'll optimize the receive logic\n");
2122 /* if we need ptr regs for the right side
2124 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2125 <= (unsigned) PTRSIZE)
2130 /* else we assign registers to it */
2131 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2133 debugLog (" %d - \n", __LINE__);
2135 bitVectDebugOn(_G.regAssigned, debugF);
2137 for (j = 0; j < sym->nRegs; j++)
2139 if (sym->regType == REG_PTR)
2140 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2142 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2144 /* if the allocation falied which means
2145 this was spilt then break */
2149 debugLog (" %d - \n", __LINE__);
2151 /* if it shares registers with operands make sure
2152 that they are in the same position */
2153 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2154 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2155 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2156 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2157 /* do the same for the right operand */
2158 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2159 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2160 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2161 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2163 debugLog (" %d - \n", __LINE__);
2166 debugLog (" %d - \n", __LINE__);
2176 /*-----------------------------------------------------------------*/
2177 /* rUmaskForOp :- returns register mask for an operand */
2178 /*-----------------------------------------------------------------*/
2180 rUmaskForOp (operand * op)
2186 debugLog ("%s\n", __FUNCTION__);
2187 /* only temporaries are assigned registers */
2191 sym = OP_SYMBOL (op);
2193 /* if spilt or no registers assigned to it
2195 if (sym->isspilt || !sym->nRegs)
2198 rumask = newBitVect (pic16_nRegs);
2200 for (j = 0; j < sym->nRegs; j++)
2202 rumask = bitVectSetBit (rumask,
2203 sym->regs[j]->rIdx);
2209 /*-----------------------------------------------------------------*/
2210 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2211 /*-----------------------------------------------------------------*/
2213 regsUsedIniCode (iCode * ic)
2215 bitVect *rmask = newBitVect (pic16_nRegs);
2217 debugLog ("%s\n", __FUNCTION__);
2218 /* do the special cases first */
2221 rmask = bitVectUnion (rmask,
2222 rUmaskForOp (IC_COND (ic)));
2226 /* for the jumptable */
2227 if (ic->op == JUMPTABLE)
2229 rmask = bitVectUnion (rmask,
2230 rUmaskForOp (IC_JTCOND (ic)));
2235 /* of all other cases */
2237 rmask = bitVectUnion (rmask,
2238 rUmaskForOp (IC_LEFT (ic)));
2242 rmask = bitVectUnion (rmask,
2243 rUmaskForOp (IC_RIGHT (ic)));
2246 rmask = bitVectUnion (rmask,
2247 rUmaskForOp (IC_RESULT (ic)));
2253 /*-----------------------------------------------------------------*/
2254 /* createRegMask - for each instruction will determine the regsUsed */
2255 /*-----------------------------------------------------------------*/
2257 createRegMask (eBBlock ** ebbs, int count)
2261 debugLog ("%s\n", __FUNCTION__);
2262 /* for all blocks */
2263 for (i = 0; i < count; i++)
2267 if (ebbs[i]->noPath &&
2268 (ebbs[i]->entryLabel != entryLabel &&
2269 ebbs[i]->entryLabel != returnLabel))
2272 /* for all instructions */
2273 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2278 if (SKIP_IC2 (ic) || !ic->rlive)
2281 /* first mark the registers used in this
2283 ic->rUsed = regsUsedIniCode (ic);
2284 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2286 /* now create the register mask for those
2287 registers that are in use : this is a
2288 super set of ic->rUsed */
2289 ic->rMask = newBitVect (pic16_nRegs + 1);
2291 /* for all live Ranges alive at this point */
2292 for (j = 1; j < ic->rlive->size; j++)
2297 /* if not alive then continue */
2298 if (!bitVectBitValue (ic->rlive, j))
2301 /* find the live range we are interested in */
2302 if (!(sym = hTabItemWithKey (liveRanges, j)))
2304 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2305 "createRegMask cannot find live range");
2309 /* if no register assigned to it */
2310 if (!sym->nRegs || sym->isspilt)
2313 /* for all the registers allocated to it */
2314 for (k = 0; k < sym->nRegs; k++)
2317 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2323 /*-----------------------------------------------------------------*/
2324 /* rematStr - returns the rematerialized string for a remat var */
2325 /*-----------------------------------------------------------------*/
2327 rematStr (symbol * sym)
2330 iCode *ic = sym->rematiCode;
2331 symbol *psym = NULL;
2333 debugLog ("%s\n", __FUNCTION__);
2335 //printf ("%s\n", s);
2337 /* if plus or minus print the right hand side */
2339 if (ic->op == '+' || ic->op == '-') {
2341 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2343 sprintf (s, "(%s %c 0x%04x)",
2344 OP_SYMBOL (IC_LEFT (ric))->rname,
2346 (int) operandLitValue (IC_RIGHT (ic)));
2349 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2351 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2352 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2357 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2358 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2360 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2365 /*-----------------------------------------------------------------*/
2366 /* rematStr - returns the rematerialized string for a remat var */
2367 /*-----------------------------------------------------------------*/
2369 rematStr (symbol * sym)
2372 iCode *ic = sym->rematiCode;
2374 debugLog ("%s\n", __FUNCTION__);
2379 /* if plus or minus print the right hand side */
2381 if (ic->op == '+' || ic->op == '-') {
2382 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2385 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2389 if (ic->op == '+' || ic->op == '-')
2391 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2392 sprintf (s, "(%s %c 0x%04x)",
2393 OP_SYMBOL (IC_LEFT (ric))->rname,
2395 (int) operandLitValue (IC_RIGHT (ic)));
2398 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2400 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2404 /* we reached the end */
2405 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2409 printf ("%s\n", buffer);
2414 /*-----------------------------------------------------------------*/
2415 /* regTypeNum - computes the type & number of registers required */
2416 /*-----------------------------------------------------------------*/
2424 debugLog ("%s\n", __FUNCTION__);
2425 /* for each live range do */
2426 for (sym = hTabFirstItem (liveRanges, &k); sym;
2427 sym = hTabNextItem (liveRanges, &k)) {
2429 debugLog (" %d - %s\n", __LINE__, sym->rname);
2431 /* if used zero times then no registers needed */
2432 if ((sym->liveTo - sym->liveFrom) == 0)
2436 /* if the live range is a temporary */
2439 debugLog (" %d - itemp register\n", __LINE__);
2441 /* if the type is marked as a conditional */
2442 if (sym->regType == REG_CND)
2445 /* if used in return only then we don't
2447 if (sym->ruonly || sym->accuse) {
2448 if (IS_AGGREGATE (sym->type) || sym->isptr)
2449 sym->type = aggrToPtr (sym->type, FALSE);
2450 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
2455 /* if the symbol has only one definition &
2456 that definition is a get_pointer and the
2457 pointer we are getting is rematerializable and
2460 if (bitVectnBitsOn (sym->defs) == 1 &&
2461 (ic = hTabItemWithKey (iCodehTab,
2462 bitVectFirstBit (sym->defs))) &&
2465 !IS_BITVAR (sym->etype)) {
2468 debugLog (" %d - \n", __LINE__);
2470 /* if remat in data space */
2471 if (OP_SYMBOL (IC_LEFT (ic))->remat &&
2472 DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) {
2474 /* create a psuedo symbol & force a spil */
2475 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2476 symbol *psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2477 psym->type = sym->type;
2478 psym->etype = sym->etype;
2479 strcpy (psym->rname, psym->name);
2481 sym->usl.spillLoc = psym;
2485 /* if in data space or idata space then try to
2486 allocate pointer register */
2490 /* if not then we require registers */
2491 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2492 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2493 getSize (sym->type));
2496 if(IS_PTR_CONST (sym->type)) {
2497 debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2501 if (sym->nRegs > 4) {
2502 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2503 printTypeChain (sym->type, stderr);
2504 fprintf (stderr, "\n");
2507 /* determine the type of register required */
2508 if (sym->nRegs == 1 &&
2509 IS_PTR (sym->type) &&
2511 sym->regType = REG_PTR;
2513 sym->regType = REG_GPR;
2516 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2520 /* for the first run we don't provide */
2521 /* registers for true symbols we will */
2522 /* see how things go */
2527 static DEFSETFUNC (markRegFree)
2529 ((regs *)item)->isFree = 1;
2534 DEFSETFUNC (pic16_deallocReg)
2536 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2537 ((regs *)item)->isFree = 1;
2538 ((regs *)item)->wasUsed = 0;
2542 /*-----------------------------------------------------------------*/
2543 /* freeAllRegs - mark all registers as free */
2544 /*-----------------------------------------------------------------*/
2546 pic16_freeAllRegs ()
2550 debugLog ("%s\n", __FUNCTION__);
2552 applyToSet(pic16_dynAllocRegs,markRegFree);
2553 applyToSet(pic16_dynStackRegs,markRegFree);
2556 for (i = 0; i < pic16_nRegs; i++)
2557 regspic16[i].isFree = 1;
2561 /*-----------------------------------------------------------------*/
2562 /*-----------------------------------------------------------------*/
2564 pic16_deallocateAllRegs ()
2568 debugLog ("%s\n", __FUNCTION__);
2570 applyToSet(pic16_dynAllocRegs,pic16_deallocReg);
2573 for (i = 0; i < pic16_nRegs; i++) {
2574 if(regspic16[i].pc_type == PO_GPR_TEMP) {
2575 regspic16[i].isFree = 1;
2576 regspic16[i].wasUsed = 0;
2583 /*-----------------------------------------------------------------*/
2584 /* deallocStackSpil - this will set the stack pointer back */
2585 /*-----------------------------------------------------------------*/
2587 DEFSETFUNC (deallocStackSpil)
2591 debugLog ("%s\n", __FUNCTION__);
2596 /*-----------------------------------------------------------------*/
2597 /* farSpacePackable - returns the packable icode for far variables */
2598 /*-----------------------------------------------------------------*/
2600 farSpacePackable (iCode * ic)
2604 debugLog ("%s\n", __FUNCTION__);
2605 /* go thru till we find a definition for the
2606 symbol on the right */
2607 for (dic = ic->prev; dic; dic = dic->prev)
2610 /* if the definition is a call then no */
2611 if ((dic->op == CALL || dic->op == PCALL) &&
2612 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2617 /* if shift by unknown amount then not */
2618 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2619 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2622 /* if pointer get and size > 1 */
2623 if (POINTER_GET (dic) &&
2624 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2627 if (POINTER_SET (dic) &&
2628 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2631 /* if any three is a true symbol in far space */
2632 if (IC_RESULT (dic) &&
2633 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2634 isOperandInFarSpace (IC_RESULT (dic)))
2637 if (IC_RIGHT (dic) &&
2638 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2639 isOperandInFarSpace (IC_RIGHT (dic)) &&
2640 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2643 if (IC_LEFT (dic) &&
2644 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2645 isOperandInFarSpace (IC_LEFT (dic)) &&
2646 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2649 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2651 if ((dic->op == LEFT_OP ||
2652 dic->op == RIGHT_OP ||
2654 IS_OP_LITERAL (IC_RIGHT (dic)))
2664 /*-----------------------------------------------------------------*/
2665 /* packRegsForAssign - register reduction for assignment */
2666 /*-----------------------------------------------------------------*/
2668 packRegsForAssign (iCode * ic, eBBlock * ebp)
2673 debugLog ("%s\n", __FUNCTION__);
2675 debugAopGet (" result:", IC_RESULT (ic));
2676 debugAopGet (" left:", IC_LEFT (ic));
2677 debugAopGet (" right:", IC_RIGHT (ic));
2679 /* if this is at an absolute address, then get the address. */
2680 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2681 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2682 debugLog (" %d - found config word declaration\n", __LINE__);
2683 if(IS_VALOP(IC_RIGHT(ic))) {
2684 debugLog (" setting config word to %x\n",
2685 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2686 pic16_assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2687 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2690 /* remove the assignment from the iCode chain. */
2692 remiCodeFromeBBlock (ebp, ic);
2693 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2694 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2701 if (!IS_ITEMP (IC_RESULT (ic))) {
2702 pic16_allocDirReg(IC_RESULT (ic));
2703 debugLog (" %d - result is not temp\n", __LINE__);
2706 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2707 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2708 pic16_allocDirReg(IC_LEFT (ic));
2712 if (!IS_ITEMP (IC_RIGHT (ic))) {
2713 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2714 pic16_allocDirReg(IC_RIGHT (ic));
2718 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2719 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2721 debugLog (" %d - not packing - right side fails \n", __LINE__);
2725 /* if the true symbol is defined in far space or on stack
2726 then we should not since this will increase register pressure */
2727 if (isOperandInFarSpace (IC_RESULT (ic)))
2729 if ((dic = farSpacePackable (ic)))
2735 /* find the definition of iTempNN scanning backwards if we find a
2736 a use of the true symbol before we find the definition then
2738 for (dic = ic->prev; dic; dic = dic->prev)
2741 /* if there is a function call and this is
2742 a parameter & not my parameter then don't pack it */
2743 if ((dic->op == CALL || dic->op == PCALL) &&
2744 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2745 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2747 debugLog (" %d - \n", __LINE__);
2755 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2756 IS_OP_VOLATILE (IC_RESULT (dic)))
2758 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2763 if (IS_SYMOP (IC_RESULT (dic)) &&
2764 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2766 /* A previous result was assigned to the same register - we'll our definition */
2767 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2768 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2769 if (POINTER_SET (dic))
2775 if (IS_SYMOP (IC_RIGHT (dic)) &&
2776 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2777 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2779 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
2784 if (IS_SYMOP (IC_LEFT (dic)) &&
2785 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2786 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2788 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
2793 if (POINTER_SET (dic) &&
2794 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2796 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
2804 return 0; /* did not find */
2806 /* if the result is on stack or iaccess then it must be
2807 the same atleast one of the operands */
2808 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2809 OP_SYMBOL (IC_RESULT (ic))->iaccess)
2812 /* the operation has only one symbol
2813 operator then we can pack */
2814 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2815 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2818 if (!((IC_LEFT (dic) &&
2819 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2821 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2825 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2826 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
2827 /* found the definition */
2828 /* replace the result with the result of */
2829 /* this assignment and remove this assignment */
2830 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2831 IC_RESULT (dic) = IC_RESULT (ic);
2833 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2835 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2837 /* delete from liverange table also
2838 delete from all the points inbetween and the new
2840 for (sic = dic; sic != ic; sic = sic->next)
2842 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2843 if (IS_ITEMP (IC_RESULT (dic)))
2844 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2847 remiCodeFromeBBlock (ebp, ic);
2848 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2849 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2850 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2856 /*-----------------------------------------------------------------*/
2857 /* findAssignToSym : scanning backwards looks for first assig found */
2858 /*-----------------------------------------------------------------*/
2860 findAssignToSym (operand * op, iCode * ic)
2864 debugLog ("%s\n", __FUNCTION__);
2865 for (dic = ic->prev; dic; dic = dic->prev)
2868 /* if definition by assignment */
2869 if (dic->op == '=' &&
2870 !POINTER_SET (dic) &&
2871 IC_RESULT (dic)->key == op->key
2872 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2876 /* we are interested only if defined in far space */
2877 /* or in stack space in case of + & - */
2879 /* if assigned to a non-symbol then return
2881 if (!IS_SYMOP (IC_RIGHT (dic)))
2884 /* if the symbol is in far space then
2886 if (isOperandInFarSpace (IC_RIGHT (dic)))
2889 /* for + & - operations make sure that
2890 if it is on the stack it is the same
2891 as one of the three operands */
2892 if ((ic->op == '+' || ic->op == '-') &&
2893 OP_SYMBOL (IC_RIGHT (dic))->onStack)
2896 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2897 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2898 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2906 /* if we find an usage then we cannot delete it */
2907 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2910 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2913 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2917 /* now make sure that the right side of dic
2918 is not defined between ic & dic */
2921 iCode *sic = dic->next;
2923 for (; sic != ic; sic = sic->next)
2924 if (IC_RESULT (sic) &&
2925 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2934 /*-----------------------------------------------------------------*/
2935 /* packRegsForSupport :- reduce some registers for support calls */
2936 /*-----------------------------------------------------------------*/
2938 packRegsForSupport (iCode * ic, eBBlock * ebp)
2942 debugLog ("%s\n", __FUNCTION__);
2943 /* for the left & right operand :- look to see if the
2944 left was assigned a true symbol in far space in that
2945 case replace them */
2946 if (IS_ITEMP (IC_LEFT (ic)) &&
2947 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2949 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
2955 debugAopGet ("removing left:", IC_LEFT (ic));
2957 /* found it we need to remove it from the
2959 for (sic = dic; sic != ic; sic = sic->next)
2960 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
2962 IC_LEFT (ic)->operand.symOperand =
2963 IC_RIGHT (dic)->operand.symOperand;
2964 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2965 remiCodeFromeBBlock (ebp, dic);
2966 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2967 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2971 /* do the same for the right operand */
2974 IS_ITEMP (IC_RIGHT (ic)) &&
2975 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2977 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2983 /* if this is a subtraction & the result
2984 is a true symbol in far space then don't pack */
2985 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
2987 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
2988 if (IN_FARSPACE (SPEC_OCLS (etype)))
2992 debugAopGet ("removing right:", IC_RIGHT (ic));
2994 /* found it we need to remove it from the
2996 for (sic = dic; sic != ic; sic = sic->next)
2997 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
2999 IC_RIGHT (ic)->operand.symOperand =
3000 IC_RIGHT (dic)->operand.symOperand;
3001 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3003 remiCodeFromeBBlock (ebp, dic);
3004 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3005 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3012 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3015 /*-----------------------------------------------------------------*/
3016 /* packRegsForOneuse : - will reduce some registers for single Use */
3017 /*-----------------------------------------------------------------*/
3019 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3024 debugLog ("%s\n", __FUNCTION__);
3025 /* if returning a literal then do nothing */
3029 /* only upto 2 bytes since we cannot predict
3030 the usage of b, & acc */
3031 if (getSize (operandType (op)) > (pic16_fReturnSizePic - 2) &&
3036 /* this routine will mark the a symbol as used in one
3037 instruction use only && if the definition is local
3038 (ie. within the basic block) && has only one definition &&
3039 that definition is either a return value from a
3040 function or does not contain any variables in
3042 uses = bitVectCopy (OP_USES (op));
3043 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3044 if (!bitVectIsZero (uses)) /* has other uses */
3047 /* if it has only one defintion */
3048 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3049 return NULL; /* has more than one definition */
3051 /* get that definition */
3053 hTabItemWithKey (iCodehTab,
3054 bitVectFirstBit (OP_DEFS (op)))))
3057 /* found the definition now check if it is local */
3058 if (dic->seq < ebp->fSeq ||
3059 dic->seq > ebp->lSeq)
3060 return NULL; /* non-local */
3062 /* now check if it is the return from
3064 if (dic->op == CALL || dic->op == PCALL)
3066 if (ic->op != SEND && ic->op != RETURN &&
3067 !POINTER_SET(ic) && !POINTER_GET(ic))
3069 OP_SYMBOL (op)->ruonly = 1;
3076 /* otherwise check that the definition does
3077 not contain any symbols in far space */
3078 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3079 isOperandInFarSpace (IC_RIGHT (dic)) ||
3080 IS_OP_RUONLY (IC_LEFT (ic)) ||
3081 IS_OP_RUONLY (IC_RIGHT (ic)))
3086 /* if pointer set then make sure the pointer
3088 if (POINTER_SET (dic) &&
3089 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3092 if (POINTER_GET (dic) &&
3093 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3098 /* also make sure the intervenening instructions
3099 don't have any thing in far space */
3100 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3103 /* if there is an intervening function call then no */
3104 if (dic->op == CALL || dic->op == PCALL)
3106 /* if pointer set then make sure the pointer
3108 if (POINTER_SET (dic) &&
3109 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3112 if (POINTER_GET (dic) &&
3113 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3116 /* if address of & the result is remat then okay */
3117 if (dic->op == ADDRESS_OF &&
3118 OP_SYMBOL (IC_RESULT (dic))->remat)
3121 /* if operand has size of three or more & this
3122 operation is a '*','/' or '%' then 'b' may
3124 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3125 getSize (operandType (op)) >= 3)
3128 /* if left or right or result is in far space */
3129 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3130 isOperandInFarSpace (IC_RIGHT (dic)) ||
3131 isOperandInFarSpace (IC_RESULT (dic)) ||
3132 IS_OP_RUONLY (IC_LEFT (dic)) ||
3133 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3134 IS_OP_RUONLY (IC_RESULT (dic)))
3140 OP_SYMBOL (op)->ruonly = 1;
3145 /*-----------------------------------------------------------------*/
3146 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3147 /*-----------------------------------------------------------------*/
3149 isBitwiseOptimizable (iCode * ic)
3151 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3152 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3154 debugLog ("%s\n", __FUNCTION__);
3155 /* bitwise operations are considered optimizable
3156 under the following conditions (Jean-Louis VERN)
3168 if (IS_LITERAL (rtype) ||
3169 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3175 /*-----------------------------------------------------------------*/
3176 /* packRegsForAccUse - pack registers for acc use */
3177 /*-----------------------------------------------------------------*/
3179 packRegsForAccUse (iCode * ic)
3183 debugLog ("%s\n", __FUNCTION__);
3185 /* if this is an aggregate, e.g. a one byte char array */
3186 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3189 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3191 /* if + or - then it has to be one byte result */
3192 if ((ic->op == '+' || ic->op == '-')
3193 && getSize (operandType (IC_RESULT (ic))) > 1)
3196 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3197 /* if shift operation make sure right side is not a literal */
3198 if (ic->op == RIGHT_OP &&
3199 (isOperandLiteral (IC_RIGHT (ic)) ||
3200 getSize (operandType (IC_RESULT (ic))) > 1))
3203 if (ic->op == LEFT_OP &&
3204 (isOperandLiteral (IC_RIGHT (ic)) ||
3205 getSize (operandType (IC_RESULT (ic))) > 1))
3208 if (IS_BITWISE_OP (ic) &&
3209 getSize (operandType (IC_RESULT (ic))) > 1)
3213 /* has only one definition */
3214 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3217 /* has only one use */
3218 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3221 /* and the usage immediately follows this iCode */
3222 if (!(uic = hTabItemWithKey (iCodehTab,
3223 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3226 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3227 if (ic->next != uic)
3230 /* if it is a conditional branch then we definitely can */
3234 if (uic->op == JUMPTABLE)
3237 /* if the usage is not is an assignment
3238 or an arithmetic / bitwise / shift operation then not */
3239 if (POINTER_SET (uic) &&
3240 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3243 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3244 if (uic->op != '=' &&
3245 !IS_ARITHMETIC_OP (uic) &&
3246 !IS_BITWISE_OP (uic) &&
3247 uic->op != LEFT_OP &&
3248 uic->op != RIGHT_OP)
3251 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3252 /* if used in ^ operation then make sure right is not a
3254 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3257 /* if shift operation make sure right side is not a literal */
3258 if (uic->op == RIGHT_OP &&
3259 (isOperandLiteral (IC_RIGHT (uic)) ||
3260 getSize (operandType (IC_RESULT (uic))) > 1))
3263 if (uic->op == LEFT_OP &&
3264 (isOperandLiteral (IC_RIGHT (uic)) ||
3265 getSize (operandType (IC_RESULT (uic))) > 1))
3268 /* make sure that the result of this icode is not on the
3269 stack, since acc is used to compute stack offset */
3270 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3271 OP_SYMBOL (IC_RESULT (uic))->onStack)
3274 /* if either one of them in far space then we cannot */
3275 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3276 isOperandInFarSpace (IC_LEFT (uic))) ||
3277 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3278 isOperandInFarSpace (IC_RIGHT (uic))))
3281 /* if the usage has only one operand then we can */
3282 if (IC_LEFT (uic) == NULL ||
3283 IC_RIGHT (uic) == NULL)
3286 /* make sure this is on the left side if not
3287 a '+' since '+' is commutative */
3288 if (ic->op != '+' &&
3289 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3292 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3293 /* if one of them is a literal then we can */
3294 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3295 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3296 (getSize (operandType (IC_RESULT (uic))) <= 1))
3298 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3302 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3303 /* if the other one is not on stack then we can */
3304 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3305 (IS_ITEMP (IC_RIGHT (uic)) ||
3306 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3307 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3310 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3311 (IS_ITEMP (IC_LEFT (uic)) ||
3312 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3313 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3319 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3320 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3325 /*-----------------------------------------------------------------*/
3326 /* packForPush - hueristics to reduce iCode for pushing */
3327 /*-----------------------------------------------------------------*/
3329 packForReceive (iCode * ic, eBBlock * ebp)
3333 debugLog ("%s\n", __FUNCTION__);
3334 debugAopGet (" result:", IC_RESULT (ic));
3335 debugAopGet (" left:", IC_LEFT (ic));
3336 debugAopGet (" right:", IC_RIGHT (ic));
3341 for (dic = ic->next; dic; dic = dic->next)
3346 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3347 debugLog (" used on left\n");
3348 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3349 debugLog (" used on right\n");
3350 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3351 debugLog (" used on result\n");
3353 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3354 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3359 debugLog (" hey we can remove this unnecessary assign\n");
3361 /*-----------------------------------------------------------------*/
3362 /* packForPush - hueristics to reduce iCode for pushing */
3363 /*-----------------------------------------------------------------*/
3365 packForPush (iCode * ic, eBBlock * ebp)
3369 debugLog ("%s\n", __FUNCTION__);
3370 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3373 /* must have only definition & one usage */
3374 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3375 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3378 /* find the definition */
3379 if (!(dic = hTabItemWithKey (iCodehTab,
3380 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3383 if (dic->op != '=' || POINTER_SET (dic))
3386 /* we now we know that it has one & only one def & use
3387 and the that the definition is an assignment */
3388 IC_LEFT (ic) = IC_RIGHT (dic);
3390 remiCodeFromeBBlock (ebp, dic);
3391 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3392 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3395 static void printSymType(char * str, sym_link *sl)
3397 debugLog (" %s Symbol type: ",str);
3398 printTypeChain( sl, debugF);
3403 /*-----------------------------------------------------------------*/
3404 /* some debug code to print the symbol S_TYPE. Note that
3405 * the function checkSClass in src/SDCCsymt.c dinks with
3406 * the S_TYPE in ways the PIC port doesn't fully like...*/
3407 /*-----------------------------------------------------------------*/
3408 static void isData(sym_link *sl)
3418 for ( ; sl; sl=sl->next) {
3420 switch (SPEC_SCLS(sl)) {
3422 case S_DATA: fprintf (of, "data "); break;
3423 case S_XDATA: fprintf (of, "xdata "); break;
3424 case S_SFR: fprintf (of, "sfr "); break;
3425 case S_SBIT: fprintf (of, "sbit "); break;
3426 case S_CODE: fprintf (of, "code "); break;
3427 case S_IDATA: fprintf (of, "idata "); break;
3428 case S_PDATA: fprintf (of, "pdata "); break;
3429 case S_LITERAL: fprintf (of, "literal "); break;
3430 case S_STACK: fprintf (of, "stack "); break;
3431 case S_XSTACK: fprintf (of, "xstack "); break;
3432 case S_BIT: fprintf (of, "bit "); break;
3433 case S_EEPROM: fprintf (of, "eeprom "); break;
3442 /*-----------------------------------------------------------------*/
3443 /* packRegisters - does some transformations to reduce register */
3445 /*-----------------------------------------------------------------*/
3447 packRegisters (eBBlock * ebp)
3452 debugLog ("%s\n", __FUNCTION__);
3458 /* look for assignments of the form */
3459 /* iTempNN = TRueSym (someoperation) SomeOperand */
3461 /* TrueSym := iTempNN:1 */
3462 for (ic = ebp->sch; ic; ic = ic->next)
3465 /* find assignment of the form TrueSym := iTempNN:1 */
3466 if (ic->op == '=' && !POINTER_SET (ic))
3467 change += packRegsForAssign (ic, ebp);
3471 if (POINTER_SET (ic))
3472 debugLog ("pointer is set\n");
3473 debugAopGet (" result:", IC_RESULT (ic));
3474 debugAopGet (" left:", IC_LEFT (ic));
3475 debugAopGet (" right:", IC_RIGHT (ic));
3484 for (ic = ebp->sch; ic; ic = ic->next) {
3486 if(IS_SYMOP ( IC_LEFT(ic))) {
3487 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3489 debugAopGet (" left:", IC_LEFT (ic));
3490 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3491 debugLog (" is a pointer\n");
3493 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3494 debugLog (" is volatile\n");
3498 printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
3501 if(IS_SYMOP ( IC_RIGHT(ic))) {
3502 debugAopGet (" right:", IC_RIGHT (ic));
3503 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3506 if(IS_SYMOP ( IC_RESULT(ic))) {
3507 debugAopGet (" result:", IC_RESULT (ic));
3508 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3511 if (POINTER_SET (ic))
3512 debugLog (" %d - Pointer set\n", __LINE__);
3515 /* if this is an itemp & result of a address of a true sym
3516 then mark this as rematerialisable */
3517 if (ic->op == ADDRESS_OF &&
3518 IS_ITEMP (IC_RESULT (ic)) &&
3519 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3520 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3521 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3524 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3526 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3527 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3528 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3532 /* if straight assignment then carry remat flag if
3533 this is the only definition */
3534 if (ic->op == '=' &&
3535 !POINTER_SET (ic) &&
3536 IS_SYMOP (IC_RIGHT (ic)) &&
3537 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3538 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3540 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3542 OP_SYMBOL (IC_RESULT (ic))->remat =
3543 OP_SYMBOL (IC_RIGHT (ic))->remat;
3544 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3545 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3548 /* if this is a +/- operation with a rematerizable
3549 then mark this as rematerializable as well */
3550 if ((ic->op == '+' || ic->op == '-') &&
3551 (IS_SYMOP (IC_LEFT (ic)) &&
3552 IS_ITEMP (IC_RESULT (ic)) &&
3553 OP_SYMBOL (IC_LEFT (ic))->remat &&
3554 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3555 IS_OP_LITERAL (IC_RIGHT (ic))))
3557 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3559 operandLitValue (IC_RIGHT (ic));
3560 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3561 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3562 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3565 /* mark the pointer usages */
3566 if (POINTER_SET (ic))
3568 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3569 debugLog (" marking as a pointer (set) =>");
3570 debugAopGet (" result:", IC_RESULT (ic));
3572 if (POINTER_GET (ic))
3574 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3575 debugLog (" marking as a pointer (get) =>");
3576 debugAopGet (" left:", IC_LEFT (ic));
3581 /* if we are using a symbol on the stack
3582 then we should say pic16_ptrRegReq */
3583 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3584 pic16_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3585 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3586 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3587 pic16_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3588 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3591 if (IS_SYMOP (IC_LEFT (ic)))
3592 pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3593 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3594 if (IS_SYMOP (IC_RIGHT (ic)))
3595 pic16_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3596 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3597 if (IS_SYMOP (IC_RESULT (ic)))
3598 pic16_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3599 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3602 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic16_ptrRegReq);
3606 /* if the condition of an if instruction
3607 is defined in the previous instruction then
3608 mark the itemp as a conditional */
3609 if ((IS_CONDITIONAL (ic) ||
3610 ((ic->op == BITWISEAND ||
3613 isBitwiseOptimizable (ic))) &&
3614 ic->next && ic->next->op == IFX &&
3615 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3616 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3619 debugLog (" %d\n", __LINE__);
3620 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3624 /* reduce for support function calls */
3625 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3626 packRegsForSupport (ic, ebp);
3628 /* if a parameter is passed, it's in W, so we may not
3629 need to place a copy in a register */
3630 if (ic->op == RECEIVE)
3631 packForReceive (ic, ebp);
3633 /* some cases the redundant moves can
3634 can be eliminated for return statements */
3635 if ((ic->op == RETURN || ic->op == SEND) &&
3636 !isOperandInFarSpace (IC_LEFT (ic)) &&
3638 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3640 /* if pointer set & left has a size more than
3641 one and right is not in far space */
3642 if (POINTER_SET (ic) &&
3643 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3644 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3645 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3646 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3648 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3650 /* if pointer get */
3651 if (POINTER_GET (ic) &&
3652 !isOperandInFarSpace (IC_RESULT (ic)) &&
3653 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3654 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3655 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3657 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3660 /* if this is cast for intergral promotion then
3661 check if only use of the definition of the
3662 operand being casted/ if yes then replace
3663 the result of that arithmetic operation with
3664 this result and get rid of the cast */
3665 if (ic->op == CAST) {
3667 sym_link *fromType = operandType (IC_RIGHT (ic));
3668 sym_link *toType = operandType (IC_LEFT (ic));
3670 debugLog (" %d - casting\n", __LINE__);
3672 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3673 getSize (fromType) != getSize (toType)) {
3676 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3679 if (IS_ARITHMETIC_OP (dic)) {
3681 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3682 IC_RESULT (dic) = IC_RESULT (ic);
3683 remiCodeFromeBBlock (ebp, ic);
3684 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3685 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3686 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3690 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3694 /* if the type from and type to are the same
3695 then if this is the only use then packit */
3696 if (compareType (operandType (IC_RIGHT (ic)),
3697 operandType (IC_LEFT (ic))) == 1) {
3699 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3702 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3703 IC_RESULT (dic) = IC_RESULT (ic);
3704 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3705 remiCodeFromeBBlock (ebp, ic);
3706 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3707 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3715 iTempNN := (some variable in farspace) V1
3720 if (ic->op == IPUSH)
3722 packForPush (ic, ebp);
3726 /* pack registers for accumulator use, when the
3727 result of an arithmetic or bit wise operation
3728 has only one use, that use is immediately following
3729 the defintion and the using iCode has only one
3730 operand or has two operands but one is literal &
3731 the result of that operation is not on stack then
3732 we can leave the result of this operation in acc:b
3734 if ((IS_ARITHMETIC_OP (ic)
3736 || IS_BITWISE_OP (ic)
3738 || ic->op == LEFT_OP || ic->op == RIGHT_OP
3741 IS_ITEMP (IC_RESULT (ic)) &&
3742 getSize (operandType (IC_RESULT (ic))) <= 2)
3744 packRegsForAccUse (ic);
3750 dumpEbbsToDebug (eBBlock ** ebbs, int count)
3754 if (!debug || !debugF)
3757 for (i = 0; i < count; i++)
3759 fprintf (debugF, "\n----------------------------------------------------------------\n");
3760 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
3761 ebbs[i]->entryLabel->name,
3764 ebbs[i]->isLastInLoop);
3765 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
3770 fprintf (debugF, "visited %d : hasFcall = %d\n",
3774 fprintf (debugF, "\ndefines bitVector :");
3775 bitVectDebugOn (ebbs[i]->defSet, debugF);
3776 fprintf (debugF, "\nlocal defines bitVector :");
3777 bitVectDebugOn (ebbs[i]->ldefs, debugF);
3778 fprintf (debugF, "\npointers Set bitvector :");
3779 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
3780 fprintf (debugF, "\nin pointers Set bitvector :");
3781 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
3782 fprintf (debugF, "\ninDefs Set bitvector :");
3783 bitVectDebugOn (ebbs[i]->inDefs, debugF);
3784 fprintf (debugF, "\noutDefs Set bitvector :");
3785 bitVectDebugOn (ebbs[i]->outDefs, debugF);
3786 fprintf (debugF, "\nusesDefs Set bitvector :");
3787 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
3788 fprintf (debugF, "\n----------------------------------------------------------------\n");
3789 printiCChain (ebbs[i]->sch, debugF);
3792 /*-----------------------------------------------------------------*/
3793 /* pic16_assignRegisters - assigns registers to each live range as need */
3794 /*-----------------------------------------------------------------*/
3796 pic16_assignRegisters (eBBlock ** ebbs, int count)
3801 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
3802 debugLog ("\nebbs before optimizing:\n");
3803 dumpEbbsToDebug (ebbs, count);
3805 setToNull ((void *) &_G.funcrUsed);
3806 pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3809 /* change assignments this will remove some
3810 live ranges reducing some register pressure */
3811 for (i = 0; i < count; i++)
3812 packRegisters (ebbs[i]);
3819 debugLog("dir registers allocated so far:\n");
3820 reg = hTabFirstItem(dynDirectRegNames, &hkey);
3823 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
3824 reg = hTabNextItem(dynDirectRegNames, &hkey);
3829 if (options.dump_pack)
3830 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3832 /* first determine for each live range the number of
3833 registers & the type of registers required for each */
3836 /* and serially allocate registers */
3837 serialRegAssign (ebbs, count);
3839 /* if stack was extended then tell the user */
3842 /* werror(W_TOOMANY_SPILS,"stack", */
3843 /* _G.stackExtend,currFunc->name,""); */
3849 /* werror(W_TOOMANY_SPILS,"data space", */
3850 /* _G.dataExtend,currFunc->name,""); */
3854 /* after that create the register mask
3855 for each of the instruction */
3856 createRegMask (ebbs, count);
3858 /* redo that offsets for stacked automatic variables */
3859 redoStackOffsets ();
3861 if (options.dump_rassgn)
3862 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3864 /* now get back the chain */
3865 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3867 debugLog ("ebbs after optimizing:\n");
3868 dumpEbbsToDebug (ebbs, count);
3873 /* free up any _G.stackSpil locations allocated */
3874 applyToSet (_G.stackSpil, deallocStackSpil);
3876 setToNull ((void **) &_G.stackSpil);
3877 setToNull ((void **) &_G.spiltSet);
3878 /* mark all registers as free */
3879 //pic16_freeAllRegs ();
3881 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");