1 /*------------------------------------------------------------------------
3 ralloc.c - source file for register allocation. PIC16 specific
5 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 Added Pic Port T.scott Dattalo scott@dattalo.com (2000)
7 Added Pic16 Port Martin Dubuc m.dubuc@rogers.com (2002)
9 This program is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 In other words, you are welcome to use, share and improve this program.
24 You are forbidden to forbid anyone else to use, share and improve
25 what you give them. Help stamp out software-hoarding!
26 -------------------------------------------------------------------------*/
33 #if defined(__BORLANDC__) || defined(_MSC_VER)
34 #define STRCASECMP stricmp
36 #define STRCASECMP strcasecmp
39 /*-----------------------------------------------------------------*/
40 /* At this point we start getting processor specific although */
41 /* some routines are non-processor specific & can be reused when */
42 /* targetting other processors. The decision for this will have */
43 /* to be made on a routine by routine basis */
44 /* routines used to pack registers are most definitely not reusable */
45 /* since the pack the registers depending strictly on the MCU */
46 /*-----------------------------------------------------------------*/
48 static regs *typeRegWithIdx (int idx, int type, int fixed);
49 extern void genpic16Code (iCode *);
50 extern void pic16_assignConfigWordValue(int address, int value);
60 bitVect *funcrUsed; /* registers used in a function */
66 /* Shared with gen.c */
67 int pic16_ptrRegReq; /* one byte pointer register required */
70 set *pic16_dynAllocRegs=NULL;
71 set *pic16_dynStackRegs=NULL;
72 set *pic16_dynProcessorRegs=NULL;
73 set *pic16_dynDirectRegs=NULL;
74 set *pic16_dynDirectBitRegs=NULL;
75 set *pic16_dynInternalRegs=NULL;
77 static hTab *dynDirectRegNames= NULL;
78 //static hTab *regHash = NULL; /* a hash table containing ALL registers */
80 static int dynrIdx=0x20;
81 static int rDirectIdx=0;
83 int pic16_nRegs = 128; // = sizeof (regspic16) / sizeof (regs);
85 int pic16_Gstack_base_addr=0; /* The starting address of registers that
86 * are used to pass and return parameters */
91 static void spillThis (symbol *);
93 static FILE *debugF = NULL;
94 /*-----------------------------------------------------------------*/
95 /* debugLog - open a file for debugging information */
96 /*-----------------------------------------------------------------*/
97 //static void debugLog(char *inst,char *fmt, ...)
99 debugLog (char *fmt,...)
101 static int append = 0; // First time through, open the file without append.
104 //char *bufferP=buffer;
107 if (!debug || !dstFileName)
113 /* create the file name */
114 strcpy (buffer, dstFileName);
115 strcat (buffer, ".d");
117 if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
119 werror (E_FILE_OPEN_ERR, buffer);
122 append = 1; // Next time debubLog is called, we'll append the debug info
128 vsprintf (buffer, fmt, ap);
130 fprintf (debugF, "%s", buffer);
132 while (isspace(*bufferP)) bufferP++;
134 if (bufferP && *bufferP)
135 lineCurr = (lineCurr ?
136 connectLine(lineCurr,newLineNode(lb)) :
137 (lineHead = newLineNode(lb)));
138 lineCurr->isInline = _G.inLine;
139 lineCurr->isDebug = _G.debugLine;
149 fputc ('\n', debugF);
151 /*-----------------------------------------------------------------*/
152 /* debugLogClose - closes the debug log file (if opened) */
153 /*-----------------------------------------------------------------*/
163 #define AOP(op) op->aop
166 debugAopGet (char *str, operand * op)
171 printOperand (op, debugF);
179 decodeOp (unsigned int op)
182 if (op < 128 && op > ' ')
184 buffer[0] = (op & 0xff);
198 return "STRING_LITERAL";
234 return "LEFT_ASSIGN";
236 return "RIGHT_ASSIGN";
351 case GET_VALUE_AT_ADDRESS:
352 return "GET_VALUE_AT_ADDRESS";
370 return "ENDFUNCTION";
394 sprintf (buffer, "unkown op %d %c", op, op & 0xff);
397 /*-----------------------------------------------------------------*/
398 /*-----------------------------------------------------------------*/
400 debugLogRegType (short type)
413 sprintf (buffer, "unknown reg type %d", type);
417 /*-----------------------------------------------------------------*/
418 /*-----------------------------------------------------------------*/
419 static int regname2key(char const *name)
428 key += (*name++) + 1;
432 return ( (key + (key >> 4) + (key>>8)) & 0x3f);
436 /*-----------------------------------------------------------------*/
437 /* newReg - allocate and init memory for a new register */
438 /*-----------------------------------------------------------------*/
439 static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias)
444 dReg = Safe_calloc(1,sizeof(regs));
446 dReg->pc_type = pc_type;
449 dReg->name = Safe_strdup(name);
451 sprintf(buffer,"r0x%02X", dReg->rIdx);
454 dReg->name = Safe_strdup(buffer);
456 //fprintf(stderr,"newReg: %s, rIdx = 0x%02x\n",dReg->name,rIdx);
459 if(type == REG_SFR) {
461 dReg->address = rIdx;
471 dReg->reg_alias = NULL;
472 dReg->reglives.usedpFlows = newSet();
473 dReg->reglives.assignedpFlows = newSet();
475 hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
480 /*-----------------------------------------------------------------*/
481 /* regWithIdx - Search through a set of registers that matches idx */
482 /*-----------------------------------------------------------------*/
484 regWithIdx (set *dRegs, int idx, int fixed)
488 for (dReg = setFirstItem(dRegs) ; dReg ;
489 dReg = setNextItem(dRegs)) {
491 if(idx == dReg->rIdx && (fixed == dReg->isFixed)) {
499 /*-----------------------------------------------------------------*/
500 /* regFindFree - Search for a free register in a set of registers */
501 /*-----------------------------------------------------------------*/
503 regFindFree (set *dRegs)
507 for (dReg = setFirstItem(dRegs) ; dReg ;
508 dReg = setNextItem(dRegs)) {
516 /*-----------------------------------------------------------------*/
517 /* pic16_initStack - allocate registers for a pseudo stack */
518 /*-----------------------------------------------------------------*/
519 void pic16_initStack(int base_address, int size)
524 pic16_Gstack_base_addr = base_address;
525 //fprintf(stderr,"initStack");
527 for(i = 0; i<size; i++)
528 addSet(&pic16_dynStackRegs,newReg(REG_STK, PO_GPR_TEMP,base_address++,NULL,1,0));
531 /*-----------------------------------------------------------------*
532 *-----------------------------------------------------------------*/
534 pic16_allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
536 regs * reg = newReg(REG_SFR, po_type, rIdx, name, 1, alias);
538 if(reg)reg->wasUsed = 0;
540 //fprintf(stderr,"pic16_allocProcessorRegister %s addr =0x%x\n",name,rIdx);
541 return addSet(&pic16_dynProcessorRegs, reg);
544 /*-----------------------------------------------------------------*
545 *-----------------------------------------------------------------*/
548 pic16_allocInternalRegister(int rIdx, char * name, short po_type, int alias)
550 regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias);
552 //fprintf(stderr,"pic16_allocInternalRegister %s addr =0x%x\n",name,rIdx);
555 return addSet(&pic16_dynInternalRegs,reg);
560 /*-----------------------------------------------------------------*/
561 /* allocReg - allocates register of given type */
562 /*-----------------------------------------------------------------*/
564 allocReg (short type)
567 debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
568 //fprintf(stderr,"allocReg\n");
571 return addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
576 /*-----------------------------------------------------------------*/
577 /* pic16_dirregWithName - search for register by name */
578 /*-----------------------------------------------------------------*/
580 pic16_dirregWithName (char *name)
588 /* hash the name to get a key */
590 hkey = regname2key(name);
592 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
594 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
598 if(STRCASECMP(reg->name, name) == 0) {
602 reg = hTabNextItemWK (dynDirectRegNames);
606 return NULL; // name wasn't found in the hash table
609 static int IS_CONFIG_ADDRESS(int address)
612 return address >= 0x300000 && address <= 0x300000d;
615 /*-----------------------------------------------------------------*/
616 /* pic16_allocDirReg - allocates register of given type */
617 /*-----------------------------------------------------------------*/
619 pic16_allocDirReg (operand *op )
626 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
630 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
632 /* If the symbol is at a fixed address, then remove the leading underscore
633 * from the name. This is hack to allow the .asm include file named registers
634 * to match the .c declared register names */
636 //if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && (*name == '_'))
639 debugLog ("%s symbol name %s\n", __FUNCTION__,name);
641 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
642 debugLog(" %d const char\n",__LINE__);
643 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
646 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
647 if (IS_CODE ( OP_SYM_ETYPE(op)) )
648 debugLog(" %d code space\n",__LINE__);
650 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
651 debugLog(" %d integral\n",__LINE__);
652 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
653 debugLog(" %d literal\n",__LINE__);
654 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
655 debugLog(" %d specifier\n",__LINE__);
656 debugAopGet(NULL, op);
659 if (IS_CODE ( OP_SYM_ETYPE(op)) )
662 /* First, search the hash table to see if there is a register with this name */
663 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && !(IS_BITVAR (OP_SYM_ETYPE(op))) ) {
664 reg = regWithIdx (pic16_dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1);
668 fprintf(stderr,"%s:%d: ralloc %s is at fixed address but not a processor reg, addr=0x%x\n",
669 __FUNCTION__, __LINE__, name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
671 fprintf(stderr,"%s:%d: ralloc %s at fixed address has already been declared, addr=0x%x\n",
672 __FUNCTION__, __LINE__, name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
675 // fprintf(stderr,"ralloc:%d %s \n", __LINE__,name);
677 reg = pic16_dirregWithName(name);
683 /* if this is at an absolute address, then get the address. */
684 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
685 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
686 //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
689 /* Register wasn't found in hash, so let's create
690 * a new one and put it in the hash table AND in the
691 * dynDirectRegNames set */
692 if(!IS_CONFIG_ADDRESS(address)) {
693 //fprintf(stderr,"allocating new reg %s\n",name);
695 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0 );
696 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
698 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
700 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
702 //fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
706 if (IS_BITVAR (OP_SYM_ETYPE(op))) {
707 addSet(&pic16_dynDirectBitRegs, reg);
710 addSet(&pic16_dynDirectRegs, reg);
713 debugLog (" -- %s is declared at address 0x30000x\n",name);
718 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
720 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
721 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
727 /*-----------------------------------------------------------------*/
728 /* pic16_allocRegByName - allocates register of given type */
729 /*-----------------------------------------------------------------*/
731 pic16_allocRegByName (char *name, int size)
737 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
741 /* First, search the hash table to see if there is a register with this name */
742 reg = pic16_dirregWithName(name);
746 /* Register wasn't found in hash, so let's create
747 * a new one and put it in the hash table AND in the
748 * dynDirectRegNames set */
749 //fprintf (stderr,"%s symbol name %s\n", __FUNCTION__,name);
750 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0 );
752 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
754 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
755 addSet(&pic16_dynDirectRegs, reg);
761 /*-----------------------------------------------------------------*/
762 /* RegWithIdx - returns pointer to register with index number */
763 /*-----------------------------------------------------------------*/
765 typeRegWithIdx (int idx, int type, int fixed)
770 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
775 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx, fixed)) != NULL) {
777 debugLog ("Found a Dynamic Register!\n");
780 if( (dReg = regWithIdx ( pic16_dynDirectRegs, idx, fixed)) != NULL ) {
781 debugLog ("Found a Direct Register!\n");
787 if( (dReg = regWithIdx ( pic16_dynStackRegs, idx, fixed)) != NULL ) {
788 debugLog ("Found a Stack Register!\n");
793 if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx, fixed)) != NULL ) {
794 debugLog ("Found a Processor Register!\n");
808 /*-----------------------------------------------------------------*/
809 /* pic16_regWithIdx - returns pointer to register with index number*/
810 /*-----------------------------------------------------------------*/
812 pic16_regWithIdx (int idx)
816 if( (dReg = typeRegWithIdx(idx,REG_GPR,0)) != NULL)
819 if( (dReg = typeRegWithIdx(idx,REG_SFR,0)) != NULL)
822 if( (dReg = typeRegWithIdx(idx,REG_STK,0)) != NULL)
828 /*-----------------------------------------------------------------*/
829 /* pic16_regWithIdx - returns pointer to register with index number */
830 /*-----------------------------------------------------------------*/
832 pic16_allocWithIdx (int idx)
837 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
839 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx,0)) != NULL) {
841 debugLog ("Found a Dynamic Register!\n");
842 } else if( (dReg = regWithIdx ( pic16_dynStackRegs, idx,0)) != NULL ) {
843 debugLog ("Found a Stack Register!\n");
844 } else if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx,0)) != NULL ) {
845 debugLog ("Found a Processor Register!\n");
846 } else if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx,0)) != NULL ) {
847 debugLog ("Found an Internal Register!\n");
850 debugLog ("Dynamic Register not found\n");
853 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
854 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
855 "regWithIdx not found");
865 /*-----------------------------------------------------------------*/
866 /*-----------------------------------------------------------------*/
868 pic16_findFreeReg(short type)
875 if((dReg = regFindFree(pic16_dynAllocRegs)) != NULL)
877 return addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
881 if((dReg = regFindFree(pic16_dynStackRegs)) != NULL)
893 /*-----------------------------------------------------------------*/
894 /* freeReg - frees a register */
895 /*-----------------------------------------------------------------*/
899 debugLog ("%s\n", __FUNCTION__);
904 /*-----------------------------------------------------------------*/
905 /* nFreeRegs - returns number of free registers */
906 /*-----------------------------------------------------------------*/
910 /* dynamically allocate as many as we need and worry about
911 * fitting them into a PIC later */
918 debugLog ("%s\n", __FUNCTION__);
919 for (i = 0; i < pic16_nRegs; i++)
920 if (regspic16[i].isFree && regspic16[i].type == type)
926 /*-----------------------------------------------------------------*/
927 /* nfreeRegsType - free registers with type */
928 /*-----------------------------------------------------------------*/
930 nfreeRegsType (int type)
933 debugLog ("%s\n", __FUNCTION__);
936 if ((nfr = nFreeRegs (type)) == 0)
937 return nFreeRegs (REG_GPR);
940 return nFreeRegs (type);
943 static void writeSetUsedRegs(FILE *of, set *dRegs)
948 for (dReg = setFirstItem(dRegs) ; dReg ;
949 dReg = setNextItem(dRegs)) {
952 fprintf (of, "\t%s\n",dReg->name);
958 extern void pic16_assignFixedRegisters(set *regset);
959 extern void pic16_assignRelocatableRegisters(set *regset,int used);
960 extern void pic16_dump_map(void);
961 extern void pic16_dump_cblock(FILE *of);
964 static void packBits(set *bregs)
969 regs *relocbitfield=NULL;
975 for (regset = bregs ; regset ;
976 regset = regset->next) {
979 breg->isBitField = 1;
980 //fprintf(stderr,"bit reg: %s\n",breg->name);
983 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
985 bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1);
986 breg->rIdx = breg->address & 7;
990 sprintf (buffer, "fbitfield%02x", breg->address);
991 //fprintf(stderr,"new bit field\n");
992 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0);
993 bitfield->isBitField = 1;
994 bitfield->isFixed = 1;
995 bitfield->address = breg->address;
996 addSet(&pic16_dynDirectRegs,bitfield);
997 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
999 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
1002 breg->reg_alias = bitfield;
1006 if(!relocbitfield || bit_no >7) {
1009 sprintf (buffer, "bitfield%d", byte_no);
1010 //fprintf(stderr,"new relocatable bit field\n");
1011 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0);
1012 relocbitfield->isBitField = 1;
1013 addSet(&pic16_dynDirectRegs,relocbitfield);
1014 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1018 breg->reg_alias = relocbitfield;
1019 breg->address = rDirectIdx; /* byte_no; */
1020 breg->rIdx = bit_no++;
1029 static void bitEQUs(FILE *of, set *bregs)
1031 regs *breg,*bytereg;
1034 //fprintf(stderr," %s\n",__FUNCTION__);
1035 for (breg = setFirstItem(bregs) ; breg ;
1036 breg = setNextItem(bregs)) {
1038 //fprintf(stderr,"bit reg: %s\n",breg->name);
1040 bytereg = breg->reg_alias;
1042 fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
1045 breg->rIdx & 0x0007);
1048 fprintf(stderr, "bit field is not assigned to a register\n");
1049 fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
1060 static void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
1065 for (reg = setFirstItem(fregs) ; reg ;
1066 reg = setNextItem(fregs)) {
1068 if(!reg->isEmitted && reg->wasUsed) {
1070 if (reg->type != REG_SFR) {
1071 fprintf (of, "%s\tEQU\t0x%03x\n",
1077 fprintf (of, "%s\tEQU\t0x%03x\n",
1086 void pic16_writeUsedRegs(FILE *of)
1088 packBits(pic16_dynDirectBitRegs);
1091 pic16_assignFixedRegisters(pic16_dynAllocRegs);
1092 pic16_assignFixedRegisters(pic16_dynStackRegs);
1093 pic16_assignFixedRegisters(pic16_dynDirectRegs);
1094 pic16_assignFixedRegisters(pic16_dynProcessorRegs);
1096 pic16_assignRelocatableRegisters(pic16_dynInternalRegs,0);
1097 pic16_assignRelocatableRegisters(pic16_dynAllocRegs,0);
1098 pic16_assignRelocatableRegisters(pic16_dynStackRegs,0);
1099 pic16_assignRelocatableRegisters(pic16_dynDirectRegs,0);
1103 pic16_dump_cblock(of);
1106 bitEQUs(of,pic16_dynDirectBitRegs);
1107 aliasEQUs(of,pic16_dynAllocRegs,0);
1108 aliasEQUs(of,pic16_dynDirectRegs,0);
1109 aliasEQUs(of,pic16_dynStackRegs,0);
1110 aliasEQUs(of,pic16_dynProcessorRegs,1);
1116 /*-----------------------------------------------------------------*/
1117 /* allDefsOutOfRange - all definitions are out of a range */
1118 /*-----------------------------------------------------------------*/
1120 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
1124 debugLog ("%s\n", __FUNCTION__);
1128 for (i = 0; i < defs->size; i++)
1132 if (bitVectBitValue (defs, i) &&
1133 (ic = hTabItemWithKey (iCodehTab, i)) &&
1134 (ic->seq >= fseq && ic->seq <= toseq))
1144 /*-----------------------------------------------------------------*/
1145 /* computeSpillable - given a point find the spillable live ranges */
1146 /*-----------------------------------------------------------------*/
1148 computeSpillable (iCode * ic)
1152 debugLog ("%s\n", __FUNCTION__);
1153 /* spillable live ranges are those that are live at this
1154 point . the following categories need to be subtracted
1156 a) - those that are already spilt
1157 b) - if being used by this one
1158 c) - defined by this one */
1160 spillable = bitVectCopy (ic->rlive);
1162 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1164 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1165 bitVectUnSetBit (spillable, ic->defKey);
1166 spillable = bitVectIntersect (spillable, _G.regAssigned);
1171 /*-----------------------------------------------------------------*/
1172 /* noSpilLoc - return true if a variable has no spil location */
1173 /*-----------------------------------------------------------------*/
1175 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1177 debugLog ("%s\n", __FUNCTION__);
1178 return (sym->usl.spillLoc ? 0 : 1);
1181 /*-----------------------------------------------------------------*/
1182 /* hasSpilLoc - will return 1 if the symbol has spil location */
1183 /*-----------------------------------------------------------------*/
1185 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1187 debugLog ("%s\n", __FUNCTION__);
1188 return (sym->usl.spillLoc ? 1 : 0);
1191 /*-----------------------------------------------------------------*/
1192 /* directSpilLoc - will return 1 if the splilocation is in direct */
1193 /*-----------------------------------------------------------------*/
1195 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1197 debugLog ("%s\n", __FUNCTION__);
1198 if (sym->usl.spillLoc &&
1199 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1205 /*-----------------------------------------------------------------*/
1206 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1207 /* but is not used as a pointer */
1208 /*-----------------------------------------------------------------*/
1210 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1212 debugLog ("%s\n", __FUNCTION__);
1213 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1216 /*-----------------------------------------------------------------*/
1217 /* rematable - will return 1 if the remat flag is set */
1218 /*-----------------------------------------------------------------*/
1220 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1222 debugLog ("%s\n", __FUNCTION__);
1226 /*-----------------------------------------------------------------*/
1227 /* notUsedInRemaining - not used or defined in remain of the block */
1228 /*-----------------------------------------------------------------*/
1230 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1232 debugLog ("%s\n", __FUNCTION__);
1233 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1234 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1237 /*-----------------------------------------------------------------*/
1238 /* allLRs - return true for all */
1239 /*-----------------------------------------------------------------*/
1241 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1243 debugLog ("%s\n", __FUNCTION__);
1247 /*-----------------------------------------------------------------*/
1248 /* liveRangesWith - applies function to a given set of live range */
1249 /*-----------------------------------------------------------------*/
1251 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1252 eBBlock * ebp, iCode * ic)
1257 debugLog ("%s\n", __FUNCTION__);
1258 if (!lrs || !lrs->size)
1261 for (i = 1; i < lrs->size; i++)
1264 if (!bitVectBitValue (lrs, i))
1267 /* if we don't find it in the live range
1268 hash table we are in serious trouble */
1269 if (!(sym = hTabItemWithKey (liveRanges, i)))
1271 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1272 "liveRangesWith could not find liveRange");
1276 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1277 addSetHead (&rset, sym);
1284 /*-----------------------------------------------------------------*/
1285 /* leastUsedLR - given a set determines which is the least used */
1286 /*-----------------------------------------------------------------*/
1288 leastUsedLR (set * sset)
1290 symbol *sym = NULL, *lsym = NULL;
1292 debugLog ("%s\n", __FUNCTION__);
1293 sym = lsym = setFirstItem (sset);
1298 for (; lsym; lsym = setNextItem (sset))
1301 /* if usage is the same then prefer
1302 the spill the smaller of the two */
1303 if (lsym->used == sym->used)
1304 if (getSize (lsym->type) < getSize (sym->type))
1308 if (lsym->used < sym->used)
1313 setToNull ((void *) &sset);
1318 /*-----------------------------------------------------------------*/
1319 /* noOverLap - will iterate through the list looking for over lap */
1320 /*-----------------------------------------------------------------*/
1322 noOverLap (set * itmpStack, symbol * fsym)
1325 debugLog ("%s\n", __FUNCTION__);
1328 for (sym = setFirstItem (itmpStack); sym;
1329 sym = setNextItem (itmpStack))
1331 if (sym->liveTo > fsym->liveFrom)
1339 /*-----------------------------------------------------------------*/
1340 /* isFree - will return 1 if the a free spil location is found */
1341 /*-----------------------------------------------------------------*/
1346 V_ARG (symbol **, sloc);
1347 V_ARG (symbol *, fsym);
1349 debugLog ("%s\n", __FUNCTION__);
1350 /* if already found */
1354 /* if it is free && and the itmp assigned to
1355 this does not have any overlapping live ranges
1356 with the one currently being assigned and
1357 the size can be accomodated */
1359 noOverLap (sym->usl.itmpStack, fsym) &&
1360 getSize (sym->type) >= getSize (fsym->type))
1369 /*-----------------------------------------------------------------*/
1370 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1371 /*-----------------------------------------------------------------*/
1373 spillLRWithPtrReg (symbol * forSym)
1379 debugLog ("%s\n", __FUNCTION__);
1380 if (!_G.regAssigned ||
1381 bitVectIsZero (_G.regAssigned))
1384 r0 = pic16_regWithIdx (R0_IDX);
1385 r1 = pic16_regWithIdx (R1_IDX);
1387 /* for all live ranges */
1388 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1389 lrsym = hTabNextItem (liveRanges, &k))
1393 /* if no registers assigned to it or
1395 /* if it does not overlap with this then
1396 not need to spill it */
1398 if (lrsym->isspilt || !lrsym->nRegs ||
1399 (lrsym->liveTo < forSym->liveFrom))
1402 /* go thru the registers : if it is either
1403 r0 or r1 then spil it */
1404 for (j = 0; j < lrsym->nRegs; j++)
1405 if (lrsym->regs[j] == r0 ||
1406 lrsym->regs[j] == r1)
1415 /*-----------------------------------------------------------------*/
1416 /* createStackSpil - create a location on the stack to spil */
1417 /*-----------------------------------------------------------------*/
1419 createStackSpil (symbol * sym)
1421 symbol *sloc = NULL;
1422 int useXstack, model, noOverlay;
1424 char slocBuffer[30];
1425 debugLog ("%s\n", __FUNCTION__);
1427 /* first go try and find a free one that is already
1428 existing on the stack */
1429 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1431 /* found a free one : just update & return */
1432 sym->usl.spillLoc = sloc;
1435 addSetHead (&sloc->usl.itmpStack, sym);
1439 /* could not then have to create one , this is the hard part
1440 we need to allocate this on the stack : this is really a
1441 hack!! but cannot think of anything better at this time */
1443 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1445 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1446 __FILE__, __LINE__);
1450 sloc = newiTemp (slocBuffer);
1452 /* set the type to the spilling symbol */
1453 sloc->type = copyLinkChain (sym->type);
1454 sloc->etype = getSpec (sloc->type);
1455 SPEC_SCLS (sloc->etype) = S_DATA;
1456 SPEC_EXTR (sloc->etype) = 0;
1457 SPEC_STAT (sloc->etype) = 0;
1459 /* we don't allow it to be allocated`
1460 onto the external stack since : so we
1461 temporarily turn it off ; we also
1462 turn off memory model to prevent
1463 the spil from going to the external storage
1464 and turn off overlaying
1467 useXstack = options.useXstack;
1468 model = options.model;
1469 noOverlay = options.noOverlay;
1470 options.noOverlay = 1;
1471 options.model = options.useXstack = 0;
1475 options.useXstack = useXstack;
1476 options.model = model;
1477 options.noOverlay = noOverlay;
1478 sloc->isref = 1; /* to prevent compiler warning */
1480 /* if it is on the stack then update the stack */
1481 if (IN_STACK (sloc->etype))
1483 currFunc->stack += getSize (sloc->type);
1484 _G.stackExtend += getSize (sloc->type);
1487 _G.dataExtend += getSize (sloc->type);
1489 /* add it to the _G.stackSpil set */
1490 addSetHead (&_G.stackSpil, sloc);
1491 sym->usl.spillLoc = sloc;
1494 /* add it to the set of itempStack set
1495 of the spill location */
1496 addSetHead (&sloc->usl.itmpStack, sym);
1500 /*-----------------------------------------------------------------*/
1501 /* isSpiltOnStack - returns true if the spil location is on stack */
1502 /*-----------------------------------------------------------------*/
1504 isSpiltOnStack (symbol * sym)
1508 debugLog ("%s\n", __FUNCTION__);
1515 /* if (sym->_G.stackSpil) */
1518 if (!sym->usl.spillLoc)
1521 etype = getSpec (sym->usl.spillLoc->type);
1522 if (IN_STACK (etype))
1528 /*-----------------------------------------------------------------*/
1529 /* spillThis - spils a specific operand */
1530 /*-----------------------------------------------------------------*/
1532 spillThis (symbol * sym)
1535 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1537 /* if this is rematerializable or has a spillLocation
1538 we are okay, else we need to create a spillLocation
1540 if (!(sym->remat || sym->usl.spillLoc))
1541 createStackSpil (sym);
1544 /* mark it has spilt & put it in the spilt set */
1546 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1548 bitVectUnSetBit (_G.regAssigned, sym->key);
1550 for (i = 0; i < sym->nRegs; i++)
1554 freeReg (sym->regs[i]);
1555 sym->regs[i] = NULL;
1558 /* if spilt on stack then free up r0 & r1
1559 if they could have been assigned to some
1561 if (!pic16_ptrRegReq && isSpiltOnStack (sym))
1564 spillLRWithPtrReg (sym);
1567 if (sym->usl.spillLoc && !sym->remat)
1568 sym->usl.spillLoc->allocreq = 1;
1572 /*-----------------------------------------------------------------*/
1573 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1574 /*-----------------------------------------------------------------*/
1576 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1578 bitVect *lrcs = NULL;
1582 debugLog ("%s\n", __FUNCTION__);
1583 /* get the spillable live ranges */
1584 lrcs = computeSpillable (ic);
1586 /* get all live ranges that are rematerizable */
1587 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1590 /* return the least used of these */
1591 return leastUsedLR (selectS);
1594 /* get live ranges with spillLocations in direct space */
1595 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1597 sym = leastUsedLR (selectS);
1598 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1599 sym->usl.spillLoc->rname :
1600 sym->usl.spillLoc->name));
1602 /* mark it as allocation required */
1603 sym->usl.spillLoc->allocreq = 1;
1607 /* if the symbol is local to the block then */
1608 if (forSym->liveTo < ebp->lSeq)
1611 /* check if there are any live ranges allocated
1612 to registers that are not used in this block */
1613 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1615 sym = leastUsedLR (selectS);
1616 /* if this is not rematerializable */
1625 /* check if there are any live ranges that not
1626 used in the remainder of the block */
1627 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1629 sym = leastUsedLR (selectS);
1632 sym->remainSpil = 1;
1639 /* find live ranges with spillocation && not used as pointers */
1640 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1643 sym = leastUsedLR (selectS);
1644 /* mark this as allocation required */
1645 sym->usl.spillLoc->allocreq = 1;
1649 /* find live ranges with spillocation */
1650 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1653 sym = leastUsedLR (selectS);
1654 sym->usl.spillLoc->allocreq = 1;
1658 /* couldn't find then we need to create a spil
1659 location on the stack , for which one? the least
1661 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1664 /* return a created spil location */
1665 sym = createStackSpil (leastUsedLR (selectS));
1666 sym->usl.spillLoc->allocreq = 1;
1670 /* this is an extreme situation we will spill
1671 this one : happens very rarely but it does happen */
1677 /*-----------------------------------------------------------------*/
1678 /* spilSomething - spil some variable & mark registers as free */
1679 /*-----------------------------------------------------------------*/
1681 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1686 debugLog ("%s\n", __FUNCTION__);
1687 /* get something we can spil */
1688 ssym = selectSpil (ic, ebp, forSym);
1690 /* mark it as spilt */
1692 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1694 /* mark it as not register assigned &
1695 take it away from the set */
1696 bitVectUnSetBit (_G.regAssigned, ssym->key);
1698 /* mark the registers as free */
1699 for (i = 0; i < ssym->nRegs; i++)
1701 freeReg (ssym->regs[i]);
1703 /* if spilt on stack then free up r0 & r1
1704 if they could have been assigned to as gprs */
1705 if (!pic16_ptrRegReq && isSpiltOnStack (ssym))
1708 spillLRWithPtrReg (ssym);
1711 /* if this was a block level spil then insert push & pop
1712 at the start & end of block respectively */
1713 if (ssym->blockSpil)
1715 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1716 /* add push to the start of the block */
1717 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1718 ebp->sch->next : ebp->sch));
1719 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1720 /* add pop to the end of the block */
1721 addiCodeToeBBlock (ebp, nic, NULL);
1724 /* if spilt because not used in the remainder of the
1725 block then add a push before this instruction and
1726 a pop at the end of the block */
1727 if (ssym->remainSpil)
1730 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1731 /* add push just before this instruction */
1732 addiCodeToeBBlock (ebp, nic, ic);
1734 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1735 /* add pop to the end of the block */
1736 addiCodeToeBBlock (ebp, nic, NULL);
1745 /*-----------------------------------------------------------------*/
1746 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1747 /*-----------------------------------------------------------------*/
1749 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1753 debugLog ("%s\n", __FUNCTION__);
1755 /* try for a ptr type */
1756 if ((reg = allocReg (REG_PTR)))
1759 /* try for gpr type */
1760 if ((reg = allocReg (REG_GPR)))
1763 /* we have to spil */
1764 if (!spilSomething (ic, ebp, sym))
1767 /* this looks like an infinite loop but
1768 in really selectSpil will abort */
1772 /*-----------------------------------------------------------------*/
1773 /* getRegGpr - will try for GPR if not spil */
1774 /*-----------------------------------------------------------------*/
1776 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1780 debugLog ("%s\n", __FUNCTION__);
1782 /* try for gpr type */
1783 if ((reg = allocReg (REG_GPR)))
1786 if (!pic16_ptrRegReq)
1787 if ((reg = allocReg (REG_PTR)))
1790 /* we have to spil */
1791 if (!spilSomething (ic, ebp, sym))
1794 /* this looks like an infinite loop but
1795 in really selectSpil will abort */
1799 /*-----------------------------------------------------------------*/
1800 /* symHasReg - symbol has a given register */
1801 /*-----------------------------------------------------------------*/
1803 symHasReg (symbol * sym, regs * reg)
1807 debugLog ("%s\n", __FUNCTION__);
1808 for (i = 0; i < sym->nRegs; i++)
1809 if (sym->regs[i] == reg)
1815 /*-----------------------------------------------------------------*/
1816 /* deassignLRs - check the live to and if they have registers & are */
1817 /* not spilt then free up the registers */
1818 /*-----------------------------------------------------------------*/
1820 deassignLRs (iCode * ic, eBBlock * ebp)
1826 debugLog ("%s\n", __FUNCTION__);
1827 for (sym = hTabFirstItem (liveRanges, &k); sym;
1828 sym = hTabNextItem (liveRanges, &k))
1831 symbol *psym = NULL;
1832 /* if it does not end here */
1833 if (sym->liveTo > ic->seq)
1836 /* if it was spilt on stack then we can
1837 mark the stack spil location as free */
1842 sym->usl.spillLoc->isFree = 1;
1848 if (!bitVectBitValue (_G.regAssigned, sym->key))
1851 /* special case check if this is an IFX &
1852 the privious one was a pop and the
1853 previous one was not spilt then keep track
1855 if (ic->op == IFX && ic->prev &&
1856 ic->prev->op == IPOP &&
1857 !ic->prev->parmPush &&
1858 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1859 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1865 bitVectUnSetBit (_G.regAssigned, sym->key);
1867 /* if the result of this one needs registers
1868 and does not have it then assign it right
1870 if (IC_RESULT (ic) &&
1871 !(SKIP_IC2 (ic) || /* not a special icode */
1872 ic->op == JUMPTABLE ||
1877 POINTER_SET (ic)) &&
1878 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1879 result->liveTo > ic->seq && /* and will live beyond this */
1880 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1881 result->regType == sym->regType && /* same register types */
1882 result->nRegs && /* which needs registers */
1883 !result->isspilt && /* and does not already have them */
1885 !bitVectBitValue (_G.regAssigned, result->key) &&
1886 /* the number of free regs + number of regs in this LR
1887 can accomodate the what result Needs */
1888 ((nfreeRegsType (result->regType) +
1889 sym->nRegs) >= result->nRegs)
1893 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1895 result->regs[i] = sym->regs[i];
1897 result->regs[i] = getRegGpr (ic, ebp, result);
1899 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1903 /* free the remaining */
1904 for (; i < sym->nRegs; i++)
1908 if (!symHasReg (psym, sym->regs[i]))
1909 freeReg (sym->regs[i]);
1912 freeReg (sym->regs[i]);
1919 /*-----------------------------------------------------------------*/
1920 /* reassignLR - reassign this to registers */
1921 /*-----------------------------------------------------------------*/
1923 reassignLR (operand * op)
1925 symbol *sym = OP_SYMBOL (op);
1928 debugLog ("%s\n", __FUNCTION__);
1929 /* not spilt any more */
1930 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1931 bitVectUnSetBit (_G.spiltSet, sym->key);
1933 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1937 for (i = 0; i < sym->nRegs; i++)
1938 sym->regs[i]->isFree = 0;
1941 /*-----------------------------------------------------------------*/
1942 /* willCauseSpill - determines if allocating will cause a spill */
1943 /*-----------------------------------------------------------------*/
1945 willCauseSpill (int nr, int rt)
1947 debugLog ("%s\n", __FUNCTION__);
1948 /* first check if there are any avlb registers
1949 of te type required */
1952 /* special case for pointer type
1953 if pointer type not avlb then
1954 check for type gpr */
1955 if (nFreeRegs (rt) >= nr)
1957 if (nFreeRegs (REG_GPR) >= nr)
1962 if (pic16_ptrRegReq)
1964 if (nFreeRegs (rt) >= nr)
1969 if (nFreeRegs (REG_PTR) +
1970 nFreeRegs (REG_GPR) >= nr)
1975 debugLog (" ... yep it will (cause a spill)\n");
1976 /* it will cause a spil */
1980 /*-----------------------------------------------------------------*/
1981 /* positionRegs - the allocator can allocate same registers to res- */
1982 /* ult and operand, if this happens make sure they are in the same */
1983 /* position as the operand otherwise chaos results */
1984 /*-----------------------------------------------------------------*/
1986 positionRegs (symbol * result, symbol * opsym, int lineno)
1988 int count = min (result->nRegs, opsym->nRegs);
1989 int i, j = 0, shared = 0;
1991 debugLog ("%s\n", __FUNCTION__);
1992 /* if the result has been spilt then cannot share */
1997 /* first make sure that they actually share */
1998 for (i = 0; i < count; i++)
2000 for (j = 0; j < count; j++)
2002 if (result->regs[i] == opsym->regs[j] && i != j)
2012 regs *tmp = result->regs[i];
2013 result->regs[i] = result->regs[j];
2014 result->regs[j] = tmp;
2019 /*-----------------------------------------------------------------*/
2020 /* serialRegAssign - serially allocate registers to the variables */
2021 /*-----------------------------------------------------------------*/
2023 serialRegAssign (eBBlock ** ebbs, int count)
2027 debugLog ("%s\n", __FUNCTION__);
2028 /* for all blocks */
2029 for (i = 0; i < count; i++)
2034 if (ebbs[i]->noPath &&
2035 (ebbs[i]->entryLabel != entryLabel &&
2036 ebbs[i]->entryLabel != returnLabel))
2039 /* of all instructions do */
2040 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2043 debugLog (" op: %s\n", decodeOp (ic->op));
2045 /* if this is an ipop that means some live
2046 range will have to be assigned again */
2048 reassignLR (IC_LEFT (ic));
2050 /* if result is present && is a true symbol */
2051 if (IC_RESULT (ic) && ic->op != IFX &&
2052 IS_TRUE_SYMOP (IC_RESULT (ic)))
2053 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2055 /* take away registers from live
2056 ranges that end at this instruction */
2057 deassignLRs (ic, ebbs[i]);
2059 /* some don't need registers */
2060 if (SKIP_IC2 (ic) ||
2061 ic->op == JUMPTABLE ||
2065 (IC_RESULT (ic) && POINTER_SET (ic)))
2068 /* now we need to allocate registers
2069 only for the result */
2072 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2078 /* if it does not need or is spilt
2079 or is already assigned to registers
2080 or will not live beyond this instructions */
2083 bitVectBitValue (_G.regAssigned, sym->key) ||
2084 sym->liveTo <= ic->seq)
2087 /* if some liverange has been spilt at the block level
2088 and this one live beyond this block then spil this
2090 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2095 /* if trying to allocate this will cause
2096 a spill and there is nothing to spill
2097 or this one is rematerializable then
2099 willCS = willCauseSpill (sym->nRegs, sym->regType);
2100 spillable = computeSpillable (ic);
2102 (willCS && bitVectIsZero (spillable)))
2110 /* if it has a spillocation & is used less than
2111 all other live ranges then spill this */
2113 if (sym->usl.spillLoc) {
2114 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2115 allLRs, ebbs[i], ic));
2116 if (leastUsed && leastUsed->used > sym->used) {
2121 /* if none of the liveRanges have a spillLocation then better
2122 to spill this one than anything else already assigned to registers */
2123 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2124 /* if this is local to this block then we might find a block spil */
2125 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2133 if (ic->op == RECEIVE)
2134 debugLog ("When I get clever, I'll optimize the receive logic\n");
2136 /* if we need ptr regs for the right side
2138 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2139 <= (unsigned) PTRSIZE)
2144 /* else we assign registers to it */
2145 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2147 debugLog (" %d - \n", __LINE__);
2149 bitVectDebugOn(_G.regAssigned, debugF);
2151 for (j = 0; j < sym->nRegs; j++)
2153 if (sym->regType == REG_PTR)
2154 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2156 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2158 /* if the allocation falied which means
2159 this was spilt then break */
2163 debugLog (" %d - \n", __LINE__);
2165 /* if it shares registers with operands make sure
2166 that they are in the same position */
2167 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2168 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2169 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2170 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2171 /* do the same for the right operand */
2172 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2173 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2174 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2175 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2177 debugLog (" %d - \n", __LINE__);
2180 debugLog (" %d - \n", __LINE__);
2190 /*-----------------------------------------------------------------*/
2191 /* rUmaskForOp :- returns register mask for an operand */
2192 /*-----------------------------------------------------------------*/
2194 rUmaskForOp (operand * op)
2200 debugLog ("%s\n", __FUNCTION__);
2201 /* only temporaries are assigned registers */
2205 sym = OP_SYMBOL (op);
2207 /* if spilt or no registers assigned to it
2209 if (sym->isspilt || !sym->nRegs)
2212 rumask = newBitVect (pic16_nRegs);
2214 for (j = 0; j < sym->nRegs; j++)
2216 rumask = bitVectSetBit (rumask,
2217 sym->regs[j]->rIdx);
2223 /*-----------------------------------------------------------------*/
2224 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2225 /*-----------------------------------------------------------------*/
2227 regsUsedIniCode (iCode * ic)
2229 bitVect *rmask = newBitVect (pic16_nRegs);
2231 debugLog ("%s\n", __FUNCTION__);
2232 /* do the special cases first */
2235 rmask = bitVectUnion (rmask,
2236 rUmaskForOp (IC_COND (ic)));
2240 /* for the jumptable */
2241 if (ic->op == JUMPTABLE)
2243 rmask = bitVectUnion (rmask,
2244 rUmaskForOp (IC_JTCOND (ic)));
2249 /* of all other cases */
2251 rmask = bitVectUnion (rmask,
2252 rUmaskForOp (IC_LEFT (ic)));
2256 rmask = bitVectUnion (rmask,
2257 rUmaskForOp (IC_RIGHT (ic)));
2260 rmask = bitVectUnion (rmask,
2261 rUmaskForOp (IC_RESULT (ic)));
2267 /*-----------------------------------------------------------------*/
2268 /* createRegMask - for each instruction will determine the regsUsed */
2269 /*-----------------------------------------------------------------*/
2271 createRegMask (eBBlock ** ebbs, int count)
2275 debugLog ("%s\n", __FUNCTION__);
2276 /* for all blocks */
2277 for (i = 0; i < count; i++)
2281 if (ebbs[i]->noPath &&
2282 (ebbs[i]->entryLabel != entryLabel &&
2283 ebbs[i]->entryLabel != returnLabel))
2286 /* for all instructions */
2287 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2292 if (SKIP_IC2 (ic) || !ic->rlive)
2295 /* first mark the registers used in this
2297 ic->rUsed = regsUsedIniCode (ic);
2298 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2300 /* now create the register mask for those
2301 registers that are in use : this is a
2302 super set of ic->rUsed */
2303 ic->rMask = newBitVect (pic16_nRegs + 1);
2305 /* for all live Ranges alive at this point */
2306 for (j = 1; j < ic->rlive->size; j++)
2311 /* if not alive then continue */
2312 if (!bitVectBitValue (ic->rlive, j))
2315 /* find the live range we are interested in */
2316 if (!(sym = hTabItemWithKey (liveRanges, j)))
2318 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2319 "createRegMask cannot find live range");
2323 /* if no register assigned to it */
2324 if (!sym->nRegs || sym->isspilt)
2327 /* for all the registers allocated to it */
2328 for (k = 0; k < sym->nRegs; k++)
2331 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2337 /*-----------------------------------------------------------------*/
2338 /* rematStr - returns the rematerialized string for a remat var */
2339 /*-----------------------------------------------------------------*/
2341 rematStr (symbol * sym)
2344 iCode *ic = sym->rematiCode;
2345 symbol *psym = NULL;
2347 debugLog ("%s\n", __FUNCTION__);
2349 //printf ("%s\n", s);
2351 /* if plus or minus print the right hand side */
2353 if (ic->op == '+' || ic->op == '-') {
2355 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2357 sprintf (s, "(%s %c 0x%04x)",
2358 OP_SYMBOL (IC_LEFT (ric))->rname,
2360 (int) operandLitValue (IC_RIGHT (ic)));
2363 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2365 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2366 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2371 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2372 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2374 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2379 /*-----------------------------------------------------------------*/
2380 /* rematStr - returns the rematerialized string for a remat var */
2381 /*-----------------------------------------------------------------*/
2383 rematStr (symbol * sym)
2386 iCode *ic = sym->rematiCode;
2388 debugLog ("%s\n", __FUNCTION__);
2393 /* if plus or minus print the right hand side */
2395 if (ic->op == '+' || ic->op == '-') {
2396 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2399 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2403 if (ic->op == '+' || ic->op == '-')
2405 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2406 sprintf (s, "(%s %c 0x%04x)",
2407 OP_SYMBOL (IC_LEFT (ric))->rname,
2409 (int) operandLitValue (IC_RIGHT (ic)));
2412 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2414 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2418 /* we reached the end */
2419 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2423 printf ("%s\n", buffer);
2428 /*-----------------------------------------------------------------*/
2429 /* regTypeNum - computes the type & number of registers required */
2430 /*-----------------------------------------------------------------*/
2438 debugLog ("%s\n", __FUNCTION__);
2439 /* for each live range do */
2440 for (sym = hTabFirstItem (liveRanges, &k); sym;
2441 sym = hTabNextItem (liveRanges, &k)) {
2443 debugLog (" %d - %s\n", __LINE__, sym->rname);
2445 /* if used zero times then no registers needed */
2446 if ((sym->liveTo - sym->liveFrom) == 0)
2450 /* if the live range is a temporary */
2453 debugLog (" %d - itemp register\n", __LINE__);
2455 /* if the type is marked as a conditional */
2456 if (sym->regType == REG_CND)
2459 /* if used in return only then we don't
2461 if (sym->ruonly || sym->accuse) {
2462 if (IS_AGGREGATE (sym->type) || sym->isptr)
2463 sym->type = aggrToPtr (sym->type, FALSE);
2464 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
2469 /* if the symbol has only one definition &
2470 that definition is a get_pointer and the
2471 pointer we are getting is rematerializable and
2474 if (bitVectnBitsOn (sym->defs) == 1 &&
2475 (ic = hTabItemWithKey (iCodehTab,
2476 bitVectFirstBit (sym->defs))) &&
2479 !IS_BITVAR (sym->etype)) {
2482 debugLog (" %d - \n", __LINE__);
2484 /* if remat in data space */
2485 if (OP_SYMBOL (IC_LEFT (ic))->remat &&
2486 DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) {
2488 /* create a psuedo symbol & force a spil */
2489 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2490 symbol *psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2491 psym->type = sym->type;
2492 psym->etype = sym->etype;
2493 strcpy (psym->rname, psym->name);
2495 sym->usl.spillLoc = psym;
2499 /* if in data space or idata space then try to
2500 allocate pointer register */
2504 /* if not then we require registers */
2505 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2506 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2507 getSize (sym->type));
2511 if(IS_PTR_CONST (sym->type)) {
2513 if(IS_CODEPTR (sym->type)) {
2515 debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2519 if (sym->nRegs > 4) {
2520 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2521 printTypeChain (sym->type, stderr);
2522 fprintf (stderr, "\n");
2525 /* determine the type of register required */
2526 if (sym->nRegs == 1 &&
2527 IS_PTR (sym->type) &&
2529 sym->regType = REG_PTR;
2531 sym->regType = REG_GPR;
2534 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2538 /* for the first run we don't provide */
2539 /* registers for true symbols we will */
2540 /* see how things go */
2545 static DEFSETFUNC (markRegFree)
2547 ((regs *)item)->isFree = 1;
2552 DEFSETFUNC (pic16_deallocReg)
2554 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2555 ((regs *)item)->isFree = 1;
2556 ((regs *)item)->wasUsed = 0;
2560 /*-----------------------------------------------------------------*/
2561 /* freeAllRegs - mark all registers as free */
2562 /*-----------------------------------------------------------------*/
2564 pic16_freeAllRegs ()
2568 debugLog ("%s\n", __FUNCTION__);
2570 applyToSet(pic16_dynAllocRegs,markRegFree);
2571 applyToSet(pic16_dynStackRegs,markRegFree);
2574 for (i = 0; i < pic16_nRegs; i++)
2575 regspic16[i].isFree = 1;
2579 /*-----------------------------------------------------------------*/
2580 /*-----------------------------------------------------------------*/
2582 pic16_deallocateAllRegs ()
2586 debugLog ("%s\n", __FUNCTION__);
2588 applyToSet(pic16_dynAllocRegs,pic16_deallocReg);
2591 for (i = 0; i < pic16_nRegs; i++) {
2592 if(regspic16[i].pc_type == PO_GPR_TEMP) {
2593 regspic16[i].isFree = 1;
2594 regspic16[i].wasUsed = 0;
2601 /*-----------------------------------------------------------------*/
2602 /* deallocStackSpil - this will set the stack pointer back */
2603 /*-----------------------------------------------------------------*/
2605 DEFSETFUNC (deallocStackSpil)
2609 debugLog ("%s\n", __FUNCTION__);
2614 /*-----------------------------------------------------------------*/
2615 /* farSpacePackable - returns the packable icode for far variables */
2616 /*-----------------------------------------------------------------*/
2618 farSpacePackable (iCode * ic)
2622 debugLog ("%s\n", __FUNCTION__);
2623 /* go thru till we find a definition for the
2624 symbol on the right */
2625 for (dic = ic->prev; dic; dic = dic->prev)
2628 /* if the definition is a call then no */
2629 if ((dic->op == CALL || dic->op == PCALL) &&
2630 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2635 /* if shift by unknown amount then not */
2636 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2637 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2640 /* if pointer get and size > 1 */
2641 if (POINTER_GET (dic) &&
2642 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2645 if (POINTER_SET (dic) &&
2646 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2649 /* if any three is a true symbol in far space */
2650 if (IC_RESULT (dic) &&
2651 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2652 isOperandInFarSpace (IC_RESULT (dic)))
2655 if (IC_RIGHT (dic) &&
2656 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2657 isOperandInFarSpace (IC_RIGHT (dic)) &&
2658 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2661 if (IC_LEFT (dic) &&
2662 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2663 isOperandInFarSpace (IC_LEFT (dic)) &&
2664 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2667 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2669 if ((dic->op == LEFT_OP ||
2670 dic->op == RIGHT_OP ||
2672 IS_OP_LITERAL (IC_RIGHT (dic)))
2682 /*-----------------------------------------------------------------*/
2683 /* packRegsForAssign - register reduction for assignment */
2684 /*-----------------------------------------------------------------*/
2686 packRegsForAssign (iCode * ic, eBBlock * ebp)
2691 debugLog ("%s\n", __FUNCTION__);
2693 debugAopGet (" result:", IC_RESULT (ic));
2694 debugAopGet (" left:", IC_LEFT (ic));
2695 debugAopGet (" right:", IC_RIGHT (ic));
2697 /* if this is at an absolute address, then get the address. */
2698 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2699 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2700 debugLog (" %d - found config word declaration\n", __LINE__);
2701 if(IS_VALOP(IC_RIGHT(ic))) {
2702 debugLog (" setting config word to %x\n",
2703 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2704 pic16_assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2705 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2708 /* remove the assignment from the iCode chain. */
2710 remiCodeFromeBBlock (ebp, ic);
2711 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2712 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2719 if (!IS_ITEMP (IC_RESULT (ic))) {
2720 pic16_allocDirReg(IC_RESULT (ic));
2721 debugLog (" %d - result is not temp\n", __LINE__);
2724 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2725 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2726 pic16_allocDirReg(IC_LEFT (ic));
2730 if (!IS_ITEMP (IC_RIGHT (ic))) {
2731 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2732 pic16_allocDirReg(IC_RIGHT (ic));
2736 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2737 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2739 debugLog (" %d - not packing - right side fails \n", __LINE__);
2743 /* if the true symbol is defined in far space or on stack
2744 then we should not since this will increase register pressure */
2745 if (isOperandInFarSpace (IC_RESULT (ic)))
2747 if ((dic = farSpacePackable (ic)))
2753 /* find the definition of iTempNN scanning backwards if we find a
2754 a use of the true symbol before we find the definition then
2756 for (dic = ic->prev; dic; dic = dic->prev)
2759 /* if there is a function call and this is
2760 a parameter & not my parameter then don't pack it */
2761 if ((dic->op == CALL || dic->op == PCALL) &&
2762 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2763 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2765 debugLog (" %d - \n", __LINE__);
2773 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2774 IS_OP_VOLATILE (IC_RESULT (dic)))
2776 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2781 if (IS_SYMOP (IC_RESULT (dic)) &&
2782 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2784 /* A previous result was assigned to the same register - we'll our definition */
2785 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2786 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2787 if (POINTER_SET (dic))
2793 if (IS_SYMOP (IC_RIGHT (dic)) &&
2794 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2795 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2797 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
2802 if (IS_SYMOP (IC_LEFT (dic)) &&
2803 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2804 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2806 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
2811 if (POINTER_SET (dic) &&
2812 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2814 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
2822 return 0; /* did not find */
2824 /* if the result is on stack or iaccess then it must be
2825 the same atleast one of the operands */
2826 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2827 OP_SYMBOL (IC_RESULT (ic))->iaccess)
2830 /* the operation has only one symbol
2831 operator then we can pack */
2832 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2833 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2836 if (!((IC_LEFT (dic) &&
2837 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2839 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2843 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2844 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
2845 /* found the definition */
2846 /* replace the result with the result of */
2847 /* this assignment and remove this assignment */
2848 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2849 IC_RESULT (dic) = IC_RESULT (ic);
2851 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2853 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2855 /* delete from liverange table also
2856 delete from all the points inbetween and the new
2858 for (sic = dic; sic != ic; sic = sic->next)
2860 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2861 if (IS_ITEMP (IC_RESULT (dic)))
2862 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2865 remiCodeFromeBBlock (ebp, ic);
2866 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2867 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2868 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2874 /*-----------------------------------------------------------------*/
2875 /* findAssignToSym : scanning backwards looks for first assig found */
2876 /*-----------------------------------------------------------------*/
2878 findAssignToSym (operand * op, iCode * ic)
2882 debugLog ("%s\n", __FUNCTION__);
2883 for (dic = ic->prev; dic; dic = dic->prev)
2886 /* if definition by assignment */
2887 if (dic->op == '=' &&
2888 !POINTER_SET (dic) &&
2889 IC_RESULT (dic)->key == op->key
2890 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2894 /* we are interested only if defined in far space */
2895 /* or in stack space in case of + & - */
2897 /* if assigned to a non-symbol then return
2899 if (!IS_SYMOP (IC_RIGHT (dic)))
2902 /* if the symbol is in far space then
2904 if (isOperandInFarSpace (IC_RIGHT (dic)))
2907 /* for + & - operations make sure that
2908 if it is on the stack it is the same
2909 as one of the three operands */
2910 if ((ic->op == '+' || ic->op == '-') &&
2911 OP_SYMBOL (IC_RIGHT (dic))->onStack)
2914 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2915 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2916 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2924 /* if we find an usage then we cannot delete it */
2925 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2928 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2931 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2935 /* now make sure that the right side of dic
2936 is not defined between ic & dic */
2939 iCode *sic = dic->next;
2941 for (; sic != ic; sic = sic->next)
2942 if (IC_RESULT (sic) &&
2943 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2952 /*-----------------------------------------------------------------*/
2953 /* packRegsForSupport :- reduce some registers for support calls */
2954 /*-----------------------------------------------------------------*/
2956 packRegsForSupport (iCode * ic, eBBlock * ebp)
2960 debugLog ("%s\n", __FUNCTION__);
2961 /* for the left & right operand :- look to see if the
2962 left was assigned a true symbol in far space in that
2963 case replace them */
2964 if (IS_ITEMP (IC_LEFT (ic)) &&
2965 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2967 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
2973 debugAopGet ("removing left:", IC_LEFT (ic));
2975 /* found it we need to remove it from the
2977 for (sic = dic; sic != ic; sic = sic->next)
2978 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
2980 IC_LEFT (ic)->operand.symOperand =
2981 IC_RIGHT (dic)->operand.symOperand;
2982 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2983 remiCodeFromeBBlock (ebp, dic);
2984 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2985 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2989 /* do the same for the right operand */
2992 IS_ITEMP (IC_RIGHT (ic)) &&
2993 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2995 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3001 /* if this is a subtraction & the result
3002 is a true symbol in far space then don't pack */
3003 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3005 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3006 if (IN_FARSPACE (SPEC_OCLS (etype)))
3010 debugAopGet ("removing right:", IC_RIGHT (ic));
3012 /* found it we need to remove it from the
3014 for (sic = dic; sic != ic; sic = sic->next)
3015 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3017 IC_RIGHT (ic)->operand.symOperand =
3018 IC_RIGHT (dic)->operand.symOperand;
3019 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3021 remiCodeFromeBBlock (ebp, dic);
3022 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3023 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3030 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3033 /*-----------------------------------------------------------------*/
3034 /* packRegsForOneuse : - will reduce some registers for single Use */
3035 /*-----------------------------------------------------------------*/
3037 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3042 debugLog ("%s\n", __FUNCTION__);
3043 /* if returning a literal then do nothing */
3047 /* only upto 2 bytes since we cannot predict
3048 the usage of b, & acc */
3049 if (getSize (operandType (op)) > (pic16_fReturnSizePic - 2) &&
3054 /* this routine will mark the a symbol as used in one
3055 instruction use only && if the definition is local
3056 (ie. within the basic block) && has only one definition &&
3057 that definition is either a return value from a
3058 function or does not contain any variables in
3060 uses = bitVectCopy (OP_USES (op));
3061 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3062 if (!bitVectIsZero (uses)) /* has other uses */
3065 /* if it has only one defintion */
3066 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3067 return NULL; /* has more than one definition */
3069 /* get that definition */
3071 hTabItemWithKey (iCodehTab,
3072 bitVectFirstBit (OP_DEFS (op)))))
3075 /* found the definition now check if it is local */
3076 if (dic->seq < ebp->fSeq ||
3077 dic->seq > ebp->lSeq)
3078 return NULL; /* non-local */
3080 /* now check if it is the return from
3082 if (dic->op == CALL || dic->op == PCALL)
3084 if (ic->op != SEND && ic->op != RETURN &&
3085 !POINTER_SET(ic) && !POINTER_GET(ic))
3087 OP_SYMBOL (op)->ruonly = 1;
3094 /* otherwise check that the definition does
3095 not contain any symbols in far space */
3096 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3097 isOperandInFarSpace (IC_RIGHT (dic)) ||
3098 IS_OP_RUONLY (IC_LEFT (ic)) ||
3099 IS_OP_RUONLY (IC_RIGHT (ic)))
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)))
3116 /* also make sure the intervenening instructions
3117 don't have any thing in far space */
3118 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3121 /* if there is an intervening function call then no */
3122 if (dic->op == CALL || dic->op == PCALL)
3124 /* if pointer set then make sure the pointer
3126 if (POINTER_SET (dic) &&
3127 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3130 if (POINTER_GET (dic) &&
3131 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3134 /* if address of & the result is remat then okay */
3135 if (dic->op == ADDRESS_OF &&
3136 OP_SYMBOL (IC_RESULT (dic))->remat)
3139 /* if operand has size of three or more & this
3140 operation is a '*','/' or '%' then 'b' may
3142 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3143 getSize (operandType (op)) >= 3)
3146 /* if left or right or result is in far space */
3147 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3148 isOperandInFarSpace (IC_RIGHT (dic)) ||
3149 isOperandInFarSpace (IC_RESULT (dic)) ||
3150 IS_OP_RUONLY (IC_LEFT (dic)) ||
3151 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3152 IS_OP_RUONLY (IC_RESULT (dic)))
3158 OP_SYMBOL (op)->ruonly = 1;
3163 /*-----------------------------------------------------------------*/
3164 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3165 /*-----------------------------------------------------------------*/
3167 isBitwiseOptimizable (iCode * ic)
3169 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3170 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3172 debugLog ("%s\n", __FUNCTION__);
3173 /* bitwise operations are considered optimizable
3174 under the following conditions (Jean-Louis VERN)
3186 if (IS_LITERAL (rtype) ||
3187 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3193 /*-----------------------------------------------------------------*/
3194 /* packRegsForAccUse - pack registers for acc use */
3195 /*-----------------------------------------------------------------*/
3197 packRegsForAccUse (iCode * ic)
3201 debugLog ("%s\n", __FUNCTION__);
3203 /* if this is an aggregate, e.g. a one byte char array */
3204 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3207 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3209 /* if + or - then it has to be one byte result */
3210 if ((ic->op == '+' || ic->op == '-')
3211 && getSize (operandType (IC_RESULT (ic))) > 1)
3214 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3215 /* if shift operation make sure right side is not a literal */
3216 if (ic->op == RIGHT_OP &&
3217 (isOperandLiteral (IC_RIGHT (ic)) ||
3218 getSize (operandType (IC_RESULT (ic))) > 1))
3221 if (ic->op == LEFT_OP &&
3222 (isOperandLiteral (IC_RIGHT (ic)) ||
3223 getSize (operandType (IC_RESULT (ic))) > 1))
3226 if (IS_BITWISE_OP (ic) &&
3227 getSize (operandType (IC_RESULT (ic))) > 1)
3231 /* has only one definition */
3232 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3235 /* has only one use */
3236 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3239 /* and the usage immediately follows this iCode */
3240 if (!(uic = hTabItemWithKey (iCodehTab,
3241 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3244 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3245 if (ic->next != uic)
3248 /* if it is a conditional branch then we definitely can */
3252 if (uic->op == JUMPTABLE)
3255 /* if the usage is not is an assignment
3256 or an arithmetic / bitwise / shift operation then not */
3257 if (POINTER_SET (uic) &&
3258 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3261 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3262 if (uic->op != '=' &&
3263 !IS_ARITHMETIC_OP (uic) &&
3264 !IS_BITWISE_OP (uic) &&
3265 uic->op != LEFT_OP &&
3266 uic->op != RIGHT_OP)
3269 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3270 /* if used in ^ operation then make sure right is not a
3272 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3275 /* if shift operation make sure right side is not a literal */
3276 if (uic->op == RIGHT_OP &&
3277 (isOperandLiteral (IC_RIGHT (uic)) ||
3278 getSize (operandType (IC_RESULT (uic))) > 1))
3281 if (uic->op == LEFT_OP &&
3282 (isOperandLiteral (IC_RIGHT (uic)) ||
3283 getSize (operandType (IC_RESULT (uic))) > 1))
3286 /* make sure that the result of this icode is not on the
3287 stack, since acc is used to compute stack offset */
3288 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3289 OP_SYMBOL (IC_RESULT (uic))->onStack)
3292 /* if either one of them in far space then we cannot */
3293 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3294 isOperandInFarSpace (IC_LEFT (uic))) ||
3295 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3296 isOperandInFarSpace (IC_RIGHT (uic))))
3299 /* if the usage has only one operand then we can */
3300 if (IC_LEFT (uic) == NULL ||
3301 IC_RIGHT (uic) == NULL)
3304 /* make sure this is on the left side if not
3305 a '+' since '+' is commutative */
3306 if (ic->op != '+' &&
3307 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3310 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3311 /* if one of them is a literal then we can */
3312 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3313 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3314 (getSize (operandType (IC_RESULT (uic))) <= 1))
3316 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3320 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3321 /* if the other one is not on stack then we can */
3322 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3323 (IS_ITEMP (IC_RIGHT (uic)) ||
3324 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3325 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3328 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3329 (IS_ITEMP (IC_LEFT (uic)) ||
3330 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3331 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3337 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3338 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3343 /*-----------------------------------------------------------------*/
3344 /* packForPush - hueristics to reduce iCode for pushing */
3345 /*-----------------------------------------------------------------*/
3347 packForReceive (iCode * ic, eBBlock * ebp)
3351 debugLog ("%s\n", __FUNCTION__);
3352 debugAopGet (" result:", IC_RESULT (ic));
3353 debugAopGet (" left:", IC_LEFT (ic));
3354 debugAopGet (" right:", IC_RIGHT (ic));
3359 for (dic = ic->next; dic; dic = dic->next)
3364 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3365 debugLog (" used on left\n");
3366 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3367 debugLog (" used on right\n");
3368 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3369 debugLog (" used on result\n");
3371 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3372 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3377 debugLog (" hey we can remove this unnecessary assign\n");
3379 /*-----------------------------------------------------------------*/
3380 /* packForPush - hueristics to reduce iCode for pushing */
3381 /*-----------------------------------------------------------------*/
3383 packForPush (iCode * ic, eBBlock * ebp)
3387 debugLog ("%s\n", __FUNCTION__);
3388 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3391 /* must have only definition & one usage */
3392 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3393 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3396 /* find the definition */
3397 if (!(dic = hTabItemWithKey (iCodehTab,
3398 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3401 if (dic->op != '=' || POINTER_SET (dic))
3404 /* we now we know that it has one & only one def & use
3405 and the that the definition is an assignment */
3406 IC_LEFT (ic) = IC_RIGHT (dic);
3408 remiCodeFromeBBlock (ebp, dic);
3409 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3410 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3413 static void printSymType(char * str, sym_link *sl)
3415 debugLog (" %s Symbol type: ",str);
3416 printTypeChain( sl, debugF);
3421 /*-----------------------------------------------------------------*/
3422 /* some debug code to print the symbol S_TYPE. Note that
3423 * the function checkSClass in src/SDCCsymt.c dinks with
3424 * the S_TYPE in ways the PIC port doesn't fully like...*/
3425 /*-----------------------------------------------------------------*/
3426 static void isData(sym_link *sl)
3436 for ( ; sl; sl=sl->next) {
3438 switch (SPEC_SCLS(sl)) {
3440 case S_DATA: fprintf (of, "data "); break;
3441 case S_XDATA: fprintf (of, "xdata "); break;
3442 case S_SFR: fprintf (of, "sfr "); break;
3443 case S_SBIT: fprintf (of, "sbit "); break;
3444 case S_CODE: fprintf (of, "code "); break;
3445 case S_IDATA: fprintf (of, "idata "); break;
3446 case S_PDATA: fprintf (of, "pdata "); break;
3447 case S_LITERAL: fprintf (of, "literal "); break;
3448 case S_STACK: fprintf (of, "stack "); break;
3449 case S_XSTACK: fprintf (of, "xstack "); break;
3450 case S_BIT: fprintf (of, "bit "); break;
3451 case S_EEPROM: fprintf (of, "eeprom "); break;
3460 /*--------------------------------------------------------------------*/
3461 /* pic16_packRegisters - does some transformations to reduce */
3462 /* register pressure */
3464 /*--------------------------------------------------------------------*/
3466 pic16_packRegisters (eBBlock * ebp)
3471 debugLog ("%s\n", __FUNCTION__);
3477 /* look for assignments of the form */
3478 /* iTempNN = TRueSym (someoperation) SomeOperand */
3480 /* TrueSym := iTempNN:1 */
3481 for (ic = ebp->sch; ic; ic = ic->next)
3484 /* find assignment of the form TrueSym := iTempNN:1 */
3485 /* see BUGLOG0001 for workaround with the CAST - VR */
3486 if ((ic->op == '=' || ic->op == CAST) && !POINTER_SET (ic))
3487 change += packRegsForAssign (ic, ebp);
3491 if (POINTER_SET (ic))
3492 debugLog ("pointer is set\n");
3493 debugAopGet (" result:", IC_RESULT (ic));
3494 debugAopGet (" left:", IC_LEFT (ic));
3495 debugAopGet (" right:", IC_RIGHT (ic));
3504 for (ic = ebp->sch; ic; ic = ic->next) {
3506 if(IS_SYMOP ( IC_LEFT(ic))) {
3507 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3509 debugAopGet (" left:", IC_LEFT (ic));
3511 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3513 if(IS_CODEPTR(OP_SYMBOL(IC_LEFT(ic))->type))
3515 debugLog (" is a pointer\n");
3517 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3518 debugLog (" is volatile\n");
3522 printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
3525 if(IS_SYMOP ( IC_RIGHT(ic))) {
3526 debugAopGet (" right:", IC_RIGHT (ic));
3527 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3530 if(IS_SYMOP ( IC_RESULT(ic))) {
3531 debugAopGet (" result:", IC_RESULT (ic));
3532 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3535 if (POINTER_SET (ic))
3536 debugLog (" %d - Pointer set\n", __LINE__);
3539 /* if this is an itemp & result of a address of a true sym
3540 then mark this as rematerialisable */
3541 if (ic->op == ADDRESS_OF &&
3542 IS_ITEMP (IC_RESULT (ic)) &&
3543 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3544 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3545 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3548 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3550 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3551 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3552 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3556 /* if straight assignment then carry remat flag if
3557 this is the only definition */
3558 if (ic->op == '=' &&
3559 !POINTER_SET (ic) &&
3560 IS_SYMOP (IC_RIGHT (ic)) &&
3561 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3562 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3564 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3566 OP_SYMBOL (IC_RESULT (ic))->remat =
3567 OP_SYMBOL (IC_RIGHT (ic))->remat;
3568 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3569 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3572 /* if this is a +/- operation with a rematerizable
3573 then mark this as rematerializable as well */
3574 if ((ic->op == '+' || ic->op == '-') &&
3575 (IS_SYMOP (IC_LEFT (ic)) &&
3576 IS_ITEMP (IC_RESULT (ic)) &&
3577 OP_SYMBOL (IC_LEFT (ic))->remat &&
3578 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3579 IS_OP_LITERAL (IC_RIGHT (ic))))
3581 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3583 operandLitValue (IC_RIGHT (ic));
3584 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3585 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3586 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3589 /* mark the pointer usages */
3590 if (POINTER_SET (ic))
3592 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3593 debugLog (" marking as a pointer (set) =>");
3594 debugAopGet (" result:", IC_RESULT (ic));
3596 if (POINTER_GET (ic))
3598 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3599 debugLog (" marking as a pointer (get) =>");
3600 debugAopGet (" left:", IC_LEFT (ic));
3605 /* if we are using a symbol on the stack
3606 then we should say pic16_ptrRegReq */
3607 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3608 pic16_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3609 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3610 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3611 pic16_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3612 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3615 if (IS_SYMOP (IC_LEFT (ic)))
3616 pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3617 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3618 if (IS_SYMOP (IC_RIGHT (ic)))
3619 pic16_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3620 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3621 if (IS_SYMOP (IC_RESULT (ic)))
3622 pic16_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3623 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3626 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic16_ptrRegReq);
3630 /* if the condition of an if instruction
3631 is defined in the previous instruction then
3632 mark the itemp as a conditional */
3633 if ((IS_CONDITIONAL (ic) ||
3634 ((ic->op == BITWISEAND ||
3637 isBitwiseOptimizable (ic))) &&
3638 ic->next && ic->next->op == IFX &&
3639 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3640 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3643 debugLog (" %d\n", __LINE__);
3644 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3648 /* reduce for support function calls */
3649 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3650 packRegsForSupport (ic, ebp);
3652 /* if a parameter is passed, it's in W, so we may not
3653 need to place a copy in a register */
3654 if (ic->op == RECEIVE)
3655 packForReceive (ic, ebp);
3657 /* some cases the redundant moves can
3658 can be eliminated for return statements */
3659 if ((ic->op == RETURN || ic->op == SEND) &&
3660 !isOperandInFarSpace (IC_LEFT (ic)) &&
3662 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3664 /* if pointer set & left has a size more than
3665 one and right is not in far space */
3666 if (POINTER_SET (ic) &&
3667 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3668 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3669 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3670 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3672 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3674 /* if pointer get */
3675 if (POINTER_GET (ic) &&
3676 !isOperandInFarSpace (IC_RESULT (ic)) &&
3677 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3678 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3679 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3681 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3684 /* if this is cast for intergral promotion then
3685 check if only use of the definition of the
3686 operand being casted/ if yes then replace
3687 the result of that arithmetic operation with
3688 this result and get rid of the cast */
3689 if (ic->op == CAST) {
3691 sym_link *fromType = operandType (IC_RIGHT (ic));
3692 sym_link *toType = operandType (IC_LEFT (ic));
3694 debugLog (" %d - casting\n", __LINE__);
3696 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3697 getSize (fromType) != getSize (toType)) {
3700 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3703 if (IS_ARITHMETIC_OP (dic)) {
3705 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3706 IC_RESULT (dic) = IC_RESULT (ic);
3707 remiCodeFromeBBlock (ebp, ic);
3708 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3709 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3710 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3714 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3718 /* if the type from and type to are the same
3719 then if this is the only use then packit */
3720 if (compareType (operandType (IC_RIGHT (ic)),
3721 operandType (IC_LEFT (ic))) == 1) {
3723 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3726 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3727 IC_RESULT (dic) = IC_RESULT (ic);
3728 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3729 remiCodeFromeBBlock (ebp, ic);
3730 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3731 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3739 iTempNN := (some variable in farspace) V1
3744 if (ic->op == IPUSH)
3746 packForPush (ic, ebp);
3750 /* pack registers for accumulator use, when the
3751 result of an arithmetic or bit wise operation
3752 has only one use, that use is immediately following
3753 the defintion and the using iCode has only one
3754 operand or has two operands but one is literal &
3755 the result of that operation is not on stack then
3756 we can leave the result of this operation in acc:b
3758 if ((IS_ARITHMETIC_OP (ic)
3760 || IS_BITWISE_OP (ic)
3762 || ic->op == LEFT_OP || ic->op == RIGHT_OP
3765 IS_ITEMP (IC_RESULT (ic)) &&
3766 getSize (operandType (IC_RESULT (ic))) <= 2)
3768 packRegsForAccUse (ic);
3774 dumpEbbsToDebug (eBBlock ** ebbs, int count)
3778 if (!debug || !debugF)
3781 for (i = 0; i < count; i++)
3783 fprintf (debugF, "\n----------------------------------------------------------------\n");
3784 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
3785 ebbs[i]->entryLabel->name,
3788 ebbs[i]->isLastInLoop);
3789 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
3794 fprintf (debugF, "visited %d : hasFcall = %d\n",
3798 fprintf (debugF, "\ndefines bitVector :");
3799 bitVectDebugOn (ebbs[i]->defSet, debugF);
3800 fprintf (debugF, "\nlocal defines bitVector :");
3801 bitVectDebugOn (ebbs[i]->ldefs, debugF);
3802 fprintf (debugF, "\npointers Set bitvector :");
3803 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
3804 fprintf (debugF, "\nin pointers Set bitvector :");
3805 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
3806 fprintf (debugF, "\ninDefs Set bitvector :");
3807 bitVectDebugOn (ebbs[i]->inDefs, debugF);
3808 fprintf (debugF, "\noutDefs Set bitvector :");
3809 bitVectDebugOn (ebbs[i]->outDefs, debugF);
3810 fprintf (debugF, "\nusesDefs Set bitvector :");
3811 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
3812 fprintf (debugF, "\n----------------------------------------------------------------\n");
3813 printiCChain (ebbs[i]->sch, debugF);
3816 /*-----------------------------------------------------------------*/
3817 /* pic16_assignRegisters - assigns registers to each live range as need */
3818 /*-----------------------------------------------------------------*/
3820 pic16_assignRegisters (eBBlock ** ebbs, int count)
3825 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
3826 debugLog ("\nebbs before optimizing:\n");
3827 dumpEbbsToDebug (ebbs, count);
3829 setToNull ((void *) &_G.funcrUsed);
3830 pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3833 /* change assignments this will remove some
3834 live ranges reducing some register pressure */
3835 for (i = 0; i < count; i++)
3836 pic16_packRegisters (ebbs[i]);
3843 debugLog("dir registers allocated so far:\n");
3844 reg = hTabFirstItem(dynDirectRegNames, &hkey);
3847 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
3848 reg = hTabNextItem(dynDirectRegNames, &hkey);
3853 /* liveranges probably changed by register packing
3854 so we compute them again */
3855 recomputeLiveRanges (ebbs, count);
3857 if (options.dump_pack)
3858 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3860 /* first determine for each live range the number of
3861 registers & the type of registers required for each */
3864 /* and serially allocate registers */
3865 serialRegAssign (ebbs, count);
3867 /* if stack was extended then tell the user */
3870 /* werror(W_TOOMANY_SPILS,"stack", */
3871 /* _G.stackExtend,currFunc->name,""); */
3877 /* werror(W_TOOMANY_SPILS,"data space", */
3878 /* _G.dataExtend,currFunc->name,""); */
3882 /* after that create the register mask
3883 for each of the instruction */
3884 createRegMask (ebbs, count);
3886 /* redo that offsets for stacked automatic variables */
3887 redoStackOffsets ();
3889 if (options.dump_rassgn)
3890 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3892 /* now get back the chain */
3893 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3895 debugLog ("ebbs after optimizing:\n");
3896 dumpEbbsToDebug (ebbs, count);
3901 /* free up any _G.stackSpil locations allocated */
3902 applyToSet (_G.stackSpil, deallocStackSpil);
3904 setToNull ((void *) &_G.stackSpil);
3905 setToNull ((void *) &_G.spiltSet);
3906 /* mark all registers as free */
3907 //pic16_freeAllRegs ();
3909 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");