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)
8 This program is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 In other words, you are welcome to use, share and improve this program.
23 You are forbidden to forbid anyone else to use, share and improve
24 what you give them. Help stamp out software-hoarding!
25 -------------------------------------------------------------------------*/
32 #if defined(__BORLANDC__) || defined(_MSC_VER)
33 #define STRCASECMP stricmp
35 #define STRCASECMP strcasecmp
38 /* this should go in SDCCicode.h, but it doesn't. */
39 #define IS_REF(op) (IS_SYMOP(op) && op->operand.symOperand->isref == 1)
41 /*-----------------------------------------------------------------*/
42 /* At this point we start getting processor specific although */
43 /* some routines are non-processor specific & can be reused when */
44 /* targetting other processors. The decision for this will have */
45 /* to be made on a routine by routine basis */
46 /* routines used to pack registers are most definitely not reusable */
47 /* since the pack the registers depending strictly on the MCU */
48 /*-----------------------------------------------------------------*/
50 extern void genpic14Code (iCode *);
51 extern void assignConfigWordValue(int address, int value);
61 bitVect *funcrUsed; /* registers used in a function */
67 /* Shared with gen.c */
68 int pic14_ptrRegReq; /* one byte pointer register required */
71 set *dynAllocRegs=NULL;
72 set *dynStackRegs=NULL;
73 set *dynProcessorRegs=NULL;
74 set *dynDirectRegs=NULL;
75 set *dynDirectBitRegs=NULL;
76 set *dynInternalRegs=NULL;
78 static hTab *dynDirectRegNames= NULL;
79 // static hTab *regHash = NULL; /* a hash table containing ALL registers */
81 static int dynrIdx=0x20;
82 static int rDirectIdx=0;
84 int pic14_nRegs = 128; // = sizeof (regspic14) / sizeof (regs);
86 int Gstack_base_addr=0; /* The starting address of registers that
87 * are used to pass and return parameters */
92 static void spillThis (symbol *);
94 static FILE *debugF = NULL;
95 /*-----------------------------------------------------------------*/
96 /* debugLog - open a file for debugging information */
97 /*-----------------------------------------------------------------*/
98 //static void debugLog(char *inst,char *fmt, ...)
100 debugLog (char *fmt,...)
102 static int append = 0; // First time through, open the file without append.
105 //char *bufferP=buffer;
108 if (!debug || !dstFileName)
114 /* create the file name */
115 strcpy (buffer, dstFileName);
116 strcat (buffer, ".d");
118 if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
120 werror (E_FILE_OPEN_ERR, buffer);
123 append = 1; // Next time debubLog is called, we'll append the debug info
129 vsprintf (buffer, fmt, ap);
131 fprintf (debugF, "%s", buffer);
133 while (isspace(*bufferP)) bufferP++;
135 if (bufferP && *bufferP)
136 lineCurr = (lineCurr ?
137 connectLine(lineCurr,newLineNode(lb)) :
138 (lineHead = newLineNode(lb)));
139 lineCurr->isInline = _G.inLine;
140 lineCurr->isDebug = _G.debugLine;
150 fputc ('\n', debugF);
152 /*-----------------------------------------------------------------*/
153 /* debugLogClose - closes the debug log file (if opened) */
154 /*-----------------------------------------------------------------*/
164 #define AOP(op) op->aop
167 debugAopGet (char *str, operand * op)
172 printOperand (op, debugF);
180 decodeOp (unsigned int op)
183 if (op < 128 && op > ' ')
185 buffer[0] = (op & 0xff);
199 return "STRING_LITERAL";
235 return "LEFT_ASSIGN";
237 return "RIGHT_ASSIGN";
352 case GET_VALUE_AT_ADDRESS:
353 return "GET_VALUE_AT_ADDRESS";
371 return "ENDFUNCTION";
395 sprintf (buffer, "unknown op %d %c", op, op & 0xff);
398 /*-----------------------------------------------------------------*/
399 /*-----------------------------------------------------------------*/
401 debugLogRegType (short type)
414 sprintf (buffer, "unknown reg type %d", type);
418 /*-----------------------------------------------------------------*/
419 /*-----------------------------------------------------------------*/
420 static int regname2key(char const *name)
429 key += (*name++) + 1;
433 return ( (key + (key >> 4) + (key>>8)) & 0x3f);
437 /*-----------------------------------------------------------------*/
438 /* newReg - allocate and init memory for a new register */
439 /*-----------------------------------------------------------------*/
440 static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias)
445 dReg = Safe_calloc(1,sizeof(regs));
447 dReg->pc_type = pc_type;
450 dReg->name = Safe_strdup(name);
452 sprintf(buffer,"r0x%02X", dReg->rIdx);
453 dReg->name = Safe_strdup(buffer);
455 //fprintf(stderr,"newReg: %s, rIdx = 0x%02x\n",dReg->name,rIdx);
470 dReg->reg_alias = NULL;
471 dReg->reglives.usedpFlows = newSet();
472 dReg->reglives.assignedpFlows = newSet();
474 hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
479 /*-----------------------------------------------------------------*/
480 /* regWithIdx - Search through a set of registers that matches idx */
481 /*-----------------------------------------------------------------*/
483 regWithIdx (set *dRegs, int idx, int fixed)
487 for (dReg = setFirstItem(dRegs) ; dReg ;
488 dReg = setNextItem(dRegs)) {
490 if(idx == dReg->rIdx && (fixed == (int)dReg->isFixed)) {
498 /*-----------------------------------------------------------------*/
499 /* regWithName - Search through a set of registers that matches name */
500 /*-----------------------------------------------------------------*/
502 regWithName (set *dRegs, const char *name)
506 for (dReg = setFirstItem(dRegs) ; dReg ;
507 dReg = setNextItem(dRegs)) {
509 if((strcmp(name,dReg->name)==0)) {
517 /*-----------------------------------------------------------------*/
518 /* regWithName - Search for a registers that matches name */
519 /*-----------------------------------------------------------------*/
521 regFindWithName (const char *name)
525 if( (dReg = regWithName ( dynDirectRegs, name)) != NULL ) {
526 debugLog ("Found a Direct Register!\n");
529 if( (dReg = regWithName ( dynDirectBitRegs, name)) != NULL) {
530 debugLog ("Found a Direct Bit Register!\n");
534 if (*name=='_') name++; // Step passed '_'
536 if( (dReg = regWithName ( dynAllocRegs, name)) != NULL) {
537 debugLog ("Found a Dynamic Register!\n");
540 if( (dReg = regWithName ( dynProcessorRegs, name)) != NULL) {
541 debugLog ("Found a Processor Register!\n");
544 if( (dReg = regWithName ( dynInternalRegs, name)) != NULL) {
545 debugLog ("Found an Internal Register!\n");
548 if( (dReg = regWithName ( dynStackRegs, name)) != NULL) {
549 debugLog ("Found an Stack Register!\n");
556 /*-----------------------------------------------------------------*/
557 /* regFindFree - Search for a free register in a set of registers */
558 /*-----------------------------------------------------------------*/
560 regFindFree (set *dRegs)
564 for (dReg = setFirstItem(dRegs) ; dReg ;
565 dReg = setNextItem(dRegs)) {
573 /*-----------------------------------------------------------------*/
574 /* initStack - allocate registers for a psuedo stack */
575 /*-----------------------------------------------------------------*/
576 void initStack(int base_address, int size)
581 Gstack_base_addr = base_address;
582 //fprintf(stderr,"initStack");
584 for(i = 0; i<size; i++) {
585 regs *r = newReg(REG_STK, PO_GPR_TEMP,base_address,NULL,1,0);
586 r->address = base_address; // Pseudo stack needs a fixed location that can be known by all modules
589 r->alias = 0x180; // Using shared memory for pseudo stack
590 addSet(&dynStackRegs,r);
595 /*-----------------------------------------------------------------*
596 *-----------------------------------------------------------------*/
598 allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
601 //fprintf(stderr,"allocProcessorRegister %s addr =0x%x\n",name,rIdx);
602 return addSet(&dynProcessorRegs,newReg(REG_SFR, po_type, rIdx, name,1,alias));
605 /*-----------------------------------------------------------------*
606 *-----------------------------------------------------------------*/
609 allocInternalRegister(int rIdx, char * name, short po_type, int alias)
611 regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias);
613 //fprintf(stderr,"allocInternalRegister %s addr =0x%x\n",name,rIdx);
616 return addSet(&dynInternalRegs,reg);
621 /*-----------------------------------------------------------------*/
622 /* allocReg - allocates register of given type */
623 /*-----------------------------------------------------------------*/
625 allocReg (short type)
628 debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
629 //fprintf(stderr,"allocReg\n");
632 return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
637 /*-----------------------------------------------------------------*/
638 /* dirregWithName - search for register by name */
639 /*-----------------------------------------------------------------*/
641 dirregWithName (char *name)
649 /* hash the name to get a key */
651 hkey = regname2key(name);
653 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
657 if(STRCASECMP(reg->name, name) == 0) {
661 reg = hTabNextItemWK (dynDirectRegNames);
665 return NULL; // name wasn't found in the hash table
668 int IS_CONFIG_ADDRESS(int address)
671 return address == 0x2007;
674 /*-----------------------------------------------------------------*/
675 /* allocNewDirReg - allocates a new register of given type */
676 /*-----------------------------------------------------------------*/
678 allocNewDirReg (sym_link *symlnk,const char *name)
683 /* if this is at an absolute address, then get the address. */
684 if (SPEC_ABSA (symlnk) ) {
685 address = SPEC_ADDR (symlnk);
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 debugLog (" -- %s is declared at address 0x2007\n",name);
698 if (IS_BITVAR (symlnk))
705 reg = newReg(REG_GPR, PO_DIR, idx, (char*)name,getSize (symlnk),0 );
706 debugLog (" -- added %s to hash, size = %d\n", (char*)name,reg->size);
708 if (SPEC_ABSA (symlnk) ) {
712 if (IS_BITVAR (symlnk)) {
713 addSet(&dynDirectBitRegs, reg);
716 addSet(&dynDirectRegs, reg);
718 if (!IS_STATIC (symlnk)) {
721 if (IS_EXTERN (symlnk)) {
727 if (address && reg) {
729 reg->address = address;
730 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
736 /*-----------------------------------------------------------------*/
737 /* allocDirReg - allocates register of given type */
738 /*-----------------------------------------------------------------*/
740 allocDirReg (operand *op )
747 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
751 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
753 /* If the symbol is at a fixed address, then remove the leading underscore
754 * from the name. This is hack to allow the .asm include file named registers
755 * to match the .c declared register names */
757 //if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && (*name == '_'))
760 debugLog ("%s symbol name %s\n", __FUNCTION__,name);
762 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
763 debugLog(" %d const char\n",__LINE__);
764 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
767 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
768 if (IS_CODE ( OP_SYM_ETYPE(op)) )
769 debugLog(" %d code space\n",__LINE__);
771 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
772 debugLog(" %d integral\n",__LINE__);
773 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
774 debugLog(" %d literal\n",__LINE__);
775 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
776 debugLog(" %d specifier\n",__LINE__);
777 debugAopGet(NULL, op);
780 if (IS_CODE ( OP_SYM_ETYPE(op)) )
783 /* First, search the hash table to see if there is a register with this name */
784 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && !(IS_BITVAR (OP_SYM_ETYPE(op))) ) {
785 reg = regWithIdx (dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1);
788 fprintf(stderr,"ralloc %s is at fixed address but not a processor reg, addr=0x%x\n",
789 name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
791 fprintf(stderr,"ralloc %s at fixed address has already been declared, addr=0x%x\n",
792 name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
795 //fprintf(stderr,"ralloc:%d %s \n", __LINE__,name);
797 reg = dirregWithName(name);
804 /* if this is at an absolute address, then get the address. */
805 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
806 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
807 //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
810 /* Register wasn't found in hash, so let's create
811 * a new one and put it in the hash table AND in the
812 * dynDirectRegNames set */
813 if(!IS_CONFIG_ADDRESS(address)) {
814 //fprintf(stderr,"allocating new reg %s\n",name);
816 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0 );
817 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
819 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
821 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
823 //fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
827 if (IS_BITVAR (OP_SYM_ETYPE(op))) {
828 addSet(&dynDirectBitRegs, reg);
831 addSet(&dynDirectRegs, reg);
833 if (!IS_STATIC (OP_SYM_ETYPE(op))) {
836 if (IS_EXTERN (OP_SYM_ETYPE(op))) {
842 debugLog (" -- %s is declared at address 0x2007\n",name);
847 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
849 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
850 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
855 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
857 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
858 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
861 allocNewDirReg (OP_SYM_ETYPE(op),name);
868 /*-----------------------------------------------------------------*/
869 /* allocRegByName - allocates register with given name */
870 /*-----------------------------------------------------------------*/
872 allocRegByName (char *name, int size)
878 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
882 /* First, search the hash table to see if there is a register with this name */
883 reg = dirregWithName(name);
889 /* Register wasn't found in hash, so let's create
890 * a new one and put it in the hash table AND in the
891 * dynDirectRegNames set */
892 //fprintf (stderr,"%s symbol name %s\n", __FUNCTION__,name);
893 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0 );
894 for (sym = setFirstItem(sfr->syms); sym; sym = setNextItem(sfr->syms)) {
895 if (strcmp(reg->name+1,sym->name)==0) {
896 unsigned a = SPEC_ADDR(sym->etype);
900 if (!IS_STATIC (sym->etype)) {
903 if (IS_EXTERN (sym->etype)) {
906 if (IS_BITVAR (sym->etype))
913 for (sym = setFirstItem(data->syms); sym; sym = setNextItem(data->syms)) {
914 if (strcmp(reg->name+1,sym->name)==0) {
915 unsigned a = SPEC_ADDR(sym->etype);
917 if (!IS_STATIC (sym->etype)) {
920 if (IS_EXTERN (sym->etype)) {
923 if (IS_BITVAR (sym->etype))
931 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
933 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
934 if (reg->isBitField) {
935 addSet(&dynDirectBitRegs, reg);
937 addSet(&dynDirectRegs, reg);
943 /*-----------------------------------------------------------------*/
944 /* RegWithIdx - returns pointer to register with index number */
945 /*-----------------------------------------------------------------*/
947 typeRegWithIdx (int idx, int type, int fixed)
952 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
957 if( (dReg = regWithIdx ( dynAllocRegs, idx, fixed)) != NULL) {
959 debugLog ("Found a Dynamic Register!\n");
962 if( (dReg = regWithIdx ( dynDirectRegs, idx, fixed)) != NULL ) {
963 debugLog ("Found a Direct Register!\n");
969 if( (dReg = regWithIdx ( dynStackRegs, idx, fixed)) != NULL ) {
970 debugLog ("Found a Stack Register!\n");
974 werror (E_STACK_OUT, "Register");
975 /* return an existing register just to avoid the SDCC crash */
976 return regWithIdx ( dynStackRegs, 0x7f, fixed);
980 if( (dReg = regWithIdx ( dynProcessorRegs, idx, fixed)) != NULL ) {
981 debugLog ("Found a Processor Register!\n");
995 /*-----------------------------------------------------------------*/
996 /* pic14_regWithIdx - returns pointer to register with index number*/
997 /*-----------------------------------------------------------------*/
999 pic14_regWithIdx (int idx)
1003 if( (dReg = typeRegWithIdx(idx,REG_GPR,0)) != NULL)
1006 if( (dReg = typeRegWithIdx(idx,REG_SFR,0)) != NULL)
1012 /*-----------------------------------------------------------------*/
1013 /* pic14_regWithIdx - returns pointer to register with index number */
1014 /*-----------------------------------------------------------------*/
1016 pic14_allocWithIdx (int idx)
1021 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
1023 if( (dReg = regWithIdx ( dynAllocRegs, idx,0)) != NULL) {
1025 debugLog ("Found a Dynamic Register!\n");
1026 } else if( (dReg = regWithIdx ( dynStackRegs, idx,0)) != NULL ) {
1027 debugLog ("Found a Stack Register!\n");
1028 } else if( (dReg = regWithIdx ( dynProcessorRegs, idx,0)) != NULL ) {
1029 debugLog ("Found a Processor Register!\n");
1030 } else if( (dReg = regWithIdx ( dynInternalRegs, idx,0)) != NULL ) {
1031 debugLog ("Found an Internal Register!\n");
1032 } else if( (dReg = regWithIdx ( dynInternalRegs, idx,1)) != NULL ) {
1033 debugLog ("Found an Internal Register!\n");
1036 debugLog ("Dynamic Register not found\n");
1039 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
1040 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1041 "regWithIdx not found");
1051 /*-----------------------------------------------------------------*/
1052 /*-----------------------------------------------------------------*/
1054 pic14_findFreeReg(short type)
1061 if((dReg = regFindFree(dynAllocRegs)) != NULL)
1063 return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
1067 if((dReg = regFindFree(dynStackRegs)) != NULL)
1079 /*-----------------------------------------------------------------*/
1080 /* freeReg - frees a register */
1081 /*-----------------------------------------------------------------*/
1083 freeReg (regs * reg)
1085 debugLog ("%s\n", __FUNCTION__);
1090 /*-----------------------------------------------------------------*/
1091 /* nFreeRegs - returns number of free registers */
1092 /*-----------------------------------------------------------------*/
1094 nFreeRegs (int type)
1096 /* dynamically allocate as many as we need and worry about
1097 * fitting them into a PIC later */
1104 debugLog ("%s\n", __FUNCTION__);
1105 for (i = 0; i < pic14_nRegs; i++)
1106 if (regspic14[i].isFree && regspic14[i].type == type)
1112 /*-----------------------------------------------------------------*/
1113 /* nfreeRegsType - free registers with type */
1114 /*-----------------------------------------------------------------*/
1116 nfreeRegsType (int type)
1119 debugLog ("%s\n", __FUNCTION__);
1120 if (type == REG_PTR)
1122 if ((nfr = nFreeRegs (type)) == 0)
1123 return nFreeRegs (REG_GPR);
1126 return nFreeRegs (type);
1129 void writeSetUsedRegs(FILE *of, set *dRegs)
1134 for (dReg = setFirstItem(dRegs) ; dReg ;
1135 dReg = setNextItem(dRegs)) {
1138 fprintf (of, "\t%s\n",dReg->name);
1142 extern void assignFixedRegisters(set *regset);
1143 extern void assignRelocatableRegisters(set *regset,int used);
1144 extern void dump_map(void);
1145 extern void dump_sfr(FILE *of);
1147 void packBits(set *bregs)
1151 regs *bitfield=NULL;
1152 regs *relocbitfield=NULL;
1158 for (regset = bregs ; regset ;
1159 regset = regset->next) {
1161 breg = regset->item;
1162 breg->isBitField = 1;
1163 //fprintf(stderr,"bit reg: %s\n",breg->name);
1166 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
1168 bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1);
1169 breg->rIdx = breg->address & 7;
1170 breg->address >>= 3;
1173 //sprintf (buffer, "fbitfield%02x", breg->address);
1174 sprintf (buffer, "0x%02x", breg->address);
1175 //fprintf(stderr,"new bit field\n");
1176 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0);
1177 bitfield->isBitField = 1;
1178 bitfield->isFixed = 1;
1179 bitfield->address = breg->address;
1180 //addSet(&dynDirectRegs,bitfield);
1181 addSet(&dynInternalRegs,bitfield);
1182 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
1184 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
1187 breg->reg_alias = bitfield;
1191 if(!relocbitfield || bit_no >7) {
1194 sprintf (buffer, "bitfield%d", byte_no);
1195 //fprintf(stderr,"new relocatable bit field\n");
1196 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0);
1197 relocbitfield->isBitField = 1;
1198 //addSet(&dynDirectRegs,relocbitfield);
1199 addSet(&dynInternalRegs,relocbitfield);
1200 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1204 breg->reg_alias = relocbitfield;
1205 breg->address = rDirectIdx; /* byte_no; */
1206 breg->rIdx = bit_no++;
1214 void bitEQUs(FILE *of, set *bregs)
1216 regs *breg,*bytereg;
1219 //fprintf(stderr," %s\n",__FUNCTION__);
1220 for (breg = setFirstItem(bregs) ; breg ;
1221 breg = setNextItem(bregs)) {
1223 //fprintf(stderr,"bit reg: %s\n",breg->name);
1225 bytereg = breg->reg_alias;
1227 fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
1230 breg->rIdx & 0x0007);
1233 //fprintf(stderr, "bit field is not assigned to a register\n");
1234 fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
1244 void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
1249 for (reg = setFirstItem(fregs) ; reg ;
1250 reg = setNextItem(fregs)) {
1252 //if(!reg->isEmitted && reg->wasUsed) {
1255 fprintf (of, "%s\tEQU\t0x%03x\n",
1259 fprintf (of, "%s\tEQU\t0x%03x\n",
1267 void writeUsedRegs(FILE *of)
1269 packBits(dynDirectBitRegs);
1271 assignFixedRegisters(dynInternalRegs);
1272 assignFixedRegisters(dynAllocRegs);
1273 assignFixedRegisters(dynStackRegs);
1274 assignFixedRegisters(dynDirectRegs);
1276 assignRelocatableRegisters(dynInternalRegs,0);
1277 assignRelocatableRegisters(dynAllocRegs,0);
1278 assignRelocatableRegisters(dynStackRegs,0);
1281 assignRelocatableRegisters(dynDirectRegs,0);
1282 printf("assignRelocatableRegisters(dynDirectRegs,0);\n");
1287 bitEQUs(of,dynDirectBitRegs);
1289 aliasEQUs(of,dynAllocRegs,0);
1290 aliasEQUs(of,dynDirectRegs,0);
1291 aliasEQUs(of,dynStackRegs,0);
1292 aliasEQUs(of,dynProcessorRegs,1);
1297 /*-----------------------------------------------------------------*/
1298 /* allDefsOutOfRange - all definitions are out of a range */
1299 /*-----------------------------------------------------------------*/
1301 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
1305 debugLog ("%s\n", __FUNCTION__);
1309 for (i = 0; i < defs->size; i++)
1313 if (bitVectBitValue (defs, i) &&
1314 (ic = hTabItemWithKey (iCodehTab, i)) &&
1315 (ic->seq >= fseq && ic->seq <= toseq))
1325 /*-----------------------------------------------------------------*/
1326 /* computeSpillable - given a point find the spillable live ranges */
1327 /*-----------------------------------------------------------------*/
1329 computeSpillable (iCode * ic)
1333 debugLog ("%s\n", __FUNCTION__);
1334 /* spillable live ranges are those that are live at this
1335 point . the following categories need to be subtracted
1337 a) - those that are already spilt
1338 b) - if being used by this one
1339 c) - defined by this one */
1341 spillable = bitVectCopy (ic->rlive);
1343 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1345 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1346 bitVectUnSetBit (spillable, ic->defKey);
1347 spillable = bitVectIntersect (spillable, _G.regAssigned);
1352 /*-----------------------------------------------------------------*/
1353 /* noSpilLoc - return true if a variable has no spil location */
1354 /*-----------------------------------------------------------------*/
1356 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1358 debugLog ("%s\n", __FUNCTION__);
1359 return (sym->usl.spillLoc ? 0 : 1);
1362 /*-----------------------------------------------------------------*/
1363 /* hasSpilLoc - will return 1 if the symbol has spil location */
1364 /*-----------------------------------------------------------------*/
1366 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1368 debugLog ("%s\n", __FUNCTION__);
1369 return (sym->usl.spillLoc ? 1 : 0);
1372 /*-----------------------------------------------------------------*/
1373 /* directSpilLoc - will return 1 if the splilocation is in direct */
1374 /*-----------------------------------------------------------------*/
1376 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1378 debugLog ("%s\n", __FUNCTION__);
1379 if (sym->usl.spillLoc &&
1380 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1386 /*-----------------------------------------------------------------*/
1387 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1388 /* but is not used as a pointer */
1389 /*-----------------------------------------------------------------*/
1391 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1393 debugLog ("%s\n", __FUNCTION__);
1394 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1397 /*-----------------------------------------------------------------*/
1398 /* rematable - will return 1 if the remat flag is set */
1399 /*-----------------------------------------------------------------*/
1401 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1403 debugLog ("%s\n", __FUNCTION__);
1407 /*-----------------------------------------------------------------*/
1408 /* notUsedInRemaining - not used or defined in remain of the block */
1409 /*-----------------------------------------------------------------*/
1411 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1413 debugLog ("%s\n", __FUNCTION__);
1414 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1415 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1418 /*-----------------------------------------------------------------*/
1419 /* allLRs - return true for all */
1420 /*-----------------------------------------------------------------*/
1422 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1424 debugLog ("%s\n", __FUNCTION__);
1428 /*-----------------------------------------------------------------*/
1429 /* liveRangesWith - applies function to a given set of live range */
1430 /*-----------------------------------------------------------------*/
1432 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1433 eBBlock * ebp, iCode * ic)
1438 debugLog ("%s\n", __FUNCTION__);
1439 if (!lrs || !lrs->size)
1442 for (i = 1; i < lrs->size; i++)
1445 if (!bitVectBitValue (lrs, i))
1448 /* if we don't find it in the live range
1449 hash table we are in serious trouble */
1450 if (!(sym = hTabItemWithKey (liveRanges, i)))
1452 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1453 "liveRangesWith could not find liveRange");
1457 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1458 addSetHead (&rset, sym);
1465 /*-----------------------------------------------------------------*/
1466 /* leastUsedLR - given a set determines which is the least used */
1467 /*-----------------------------------------------------------------*/
1469 leastUsedLR (set * sset)
1471 symbol *sym = NULL, *lsym = NULL;
1473 debugLog ("%s\n", __FUNCTION__);
1474 sym = lsym = setFirstItem (sset);
1479 for (; lsym; lsym = setNextItem (sset))
1482 /* if usage is the same then prefer
1483 the spill the smaller of the two */
1484 if (lsym->used == sym->used)
1485 if (getSize (lsym->type) < getSize (sym->type))
1489 if (lsym->used < sym->used)
1494 setToNull ((void *) &sset);
1499 /*-----------------------------------------------------------------*/
1500 /* noOverLap - will iterate through the list looking for over lap */
1501 /*-----------------------------------------------------------------*/
1503 noOverLap (set * itmpStack, symbol * fsym)
1506 debugLog ("%s\n", __FUNCTION__);
1509 for (sym = setFirstItem (itmpStack); sym;
1510 sym = setNextItem (itmpStack))
1512 if (sym->liveTo > fsym->liveFrom)
1520 /*-----------------------------------------------------------------*/
1521 /* isFree - will return 1 if the a free spil location is found */
1522 /*-----------------------------------------------------------------*/
1527 V_ARG (symbol **, sloc);
1528 V_ARG (symbol *, fsym);
1530 debugLog ("%s\n", __FUNCTION__);
1531 /* if already found */
1535 /* if it is free && and the itmp assigned to
1536 this does not have any overlapping live ranges
1537 with the one currently being assigned and
1538 the size can be accomodated */
1540 noOverLap (sym->usl.itmpStack, fsym) &&
1541 getSize (sym->type) >= getSize (fsym->type))
1550 /*-----------------------------------------------------------------*/
1551 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1552 /*-----------------------------------------------------------------*/
1554 spillLRWithPtrReg (symbol * forSym)
1560 debugLog ("%s\n", __FUNCTION__);
1561 if (!_G.regAssigned ||
1562 bitVectIsZero (_G.regAssigned))
1565 r0 = pic14_regWithIdx (R0_IDX);
1566 r1 = pic14_regWithIdx (R1_IDX);
1568 /* for all live ranges */
1569 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1570 lrsym = hTabNextItem (liveRanges, &k))
1574 /* if no registers assigned to it or
1576 /* if it does not overlap with this then
1577 not need to spill it */
1579 if (lrsym->isspilt || !lrsym->nRegs ||
1580 (lrsym->liveTo < forSym->liveFrom))
1583 /* go thru the registers : if it is either
1584 r0 or r1 then spil it */
1585 for (j = 0; j < lrsym->nRegs; j++)
1586 if (lrsym->regs[j] == r0 ||
1587 lrsym->regs[j] == r1)
1596 /*-----------------------------------------------------------------*/
1597 /* createStackSpil - create a location on the stack to spil */
1598 /*-----------------------------------------------------------------*/
1600 createStackSpil (symbol * sym)
1602 symbol *sloc = NULL;
1603 int useXstack, model, noOverlay;
1605 char slocBuffer[30];
1606 debugLog ("%s\n", __FUNCTION__);
1608 /* first go try and find a free one that is already
1609 existing on the stack */
1610 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1612 /* found a free one : just update & return */
1613 sym->usl.spillLoc = sloc;
1616 addSetHead (&sloc->usl.itmpStack, sym);
1620 /* could not then have to create one , this is the hard part
1621 we need to allocate this on the stack : this is really a
1622 hack!! but cannot think of anything better at this time */
1624 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1626 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1627 __FILE__, __LINE__);
1631 sloc = newiTemp (slocBuffer);
1633 /* set the type to the spilling symbol */
1634 sloc->type = copyLinkChain (sym->type);
1635 sloc->etype = getSpec (sloc->type);
1636 SPEC_SCLS (sloc->etype) = S_DATA;
1637 SPEC_EXTR (sloc->etype) = 0;
1638 SPEC_STAT (sloc->etype) = 0;
1640 /* we don't allow it to be allocated`
1641 onto the external stack since : so we
1642 temporarily turn it off ; we also
1643 turn off memory model to prevent
1644 the spil from going to the external storage
1645 and turn off overlaying
1648 useXstack = options.useXstack;
1649 model = options.model;
1650 noOverlay = options.noOverlay;
1651 options.noOverlay = 1;
1652 options.model = options.useXstack = 0;
1656 options.useXstack = useXstack;
1657 options.model = model;
1658 options.noOverlay = noOverlay;
1659 sloc->isref = 1; /* to prevent compiler warning */
1661 /* if it is on the stack then update the stack */
1662 if (IN_STACK (sloc->etype))
1664 currFunc->stack += getSize (sloc->type);
1665 _G.stackExtend += getSize (sloc->type);
1668 _G.dataExtend += getSize (sloc->type);
1670 /* add it to the _G.stackSpil set */
1671 addSetHead (&_G.stackSpil, sloc);
1672 sym->usl.spillLoc = sloc;
1675 /* add it to the set of itempStack set
1676 of the spill location */
1677 addSetHead (&sloc->usl.itmpStack, sym);
1681 /*-----------------------------------------------------------------*/
1682 /* isSpiltOnStack - returns true if the spil location is on stack */
1683 /*-----------------------------------------------------------------*/
1685 isSpiltOnStack (symbol * sym)
1689 debugLog ("%s\n", __FUNCTION__);
1696 /* if (sym->_G.stackSpil) */
1699 if (!sym->usl.spillLoc)
1702 etype = getSpec (sym->usl.spillLoc->type);
1703 if (IN_STACK (etype))
1709 /*-----------------------------------------------------------------*/
1710 /* spillThis - spils a specific operand */
1711 /*-----------------------------------------------------------------*/
1713 spillThis (symbol * sym)
1716 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1718 /* if this is rematerializable or has a spillLocation
1719 we are okay, else we need to create a spillLocation
1721 if (!(sym->remat || sym->usl.spillLoc))
1722 createStackSpil (sym);
1725 /* mark it has spilt & put it in the spilt set */
1727 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1729 bitVectUnSetBit (_G.regAssigned, sym->key);
1731 for (i = 0; i < sym->nRegs; i++)
1735 freeReg (sym->regs[i]);
1736 sym->regs[i] = NULL;
1739 /* if spilt on stack then free up r0 & r1
1740 if they could have been assigned to some
1742 if (!pic14_ptrRegReq && isSpiltOnStack (sym))
1745 spillLRWithPtrReg (sym);
1748 if (sym->usl.spillLoc && !sym->remat)
1749 sym->usl.spillLoc->allocreq = 1;
1753 /*-----------------------------------------------------------------*/
1754 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1755 /*-----------------------------------------------------------------*/
1757 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1759 bitVect *lrcs = NULL;
1763 debugLog ("%s\n", __FUNCTION__);
1764 /* get the spillable live ranges */
1765 lrcs = computeSpillable (ic);
1767 /* get all live ranges that are rematerizable */
1768 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1771 /* return the least used of these */
1772 return leastUsedLR (selectS);
1775 /* get live ranges with spillLocations in direct space */
1776 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1778 sym = leastUsedLR (selectS);
1779 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1780 sym->usl.spillLoc->rname :
1781 sym->usl.spillLoc->name));
1783 /* mark it as allocation required */
1784 sym->usl.spillLoc->allocreq = 1;
1788 /* if the symbol is local to the block then */
1789 if (forSym->liveTo < ebp->lSeq)
1792 /* check if there are any live ranges allocated
1793 to registers that are not used in this block */
1794 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1796 sym = leastUsedLR (selectS);
1797 /* if this is not rematerializable */
1806 /* check if there are any live ranges that not
1807 used in the remainder of the block */
1808 if (!_G.blockSpil &&
1809 !isiCodeInFunctionCall (ic) &&
1810 (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1812 sym = leastUsedLR (selectS);
1815 sym->remainSpil = 1;
1822 /* find live ranges with spillocation && not used as pointers */
1823 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1826 sym = leastUsedLR (selectS);
1827 /* mark this as allocation required */
1828 sym->usl.spillLoc->allocreq = 1;
1832 /* find live ranges with spillocation */
1833 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1836 sym = leastUsedLR (selectS);
1837 sym->usl.spillLoc->allocreq = 1;
1841 /* couldn't find then we need to create a spil
1842 location on the stack , for which one? the least
1844 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1847 /* return a created spil location */
1848 sym = createStackSpil (leastUsedLR (selectS));
1849 sym->usl.spillLoc->allocreq = 1;
1853 /* this is an extreme situation we will spill
1854 this one : happens very rarely but it does happen */
1860 /*-----------------------------------------------------------------*/
1861 /* spilSomething - spil some variable & mark registers as free */
1862 /*-----------------------------------------------------------------*/
1864 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1869 debugLog ("%s\n", __FUNCTION__);
1870 /* get something we can spil */
1871 ssym = selectSpil (ic, ebp, forSym);
1873 /* mark it as spilt */
1875 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1877 /* mark it as not register assigned &
1878 take it away from the set */
1879 bitVectUnSetBit (_G.regAssigned, ssym->key);
1881 /* mark the registers as free */
1882 for (i = 0; i < ssym->nRegs; i++)
1884 freeReg (ssym->regs[i]);
1886 /* if spilt on stack then free up r0 & r1
1887 if they could have been assigned to as gprs */
1888 if (!pic14_ptrRegReq && isSpiltOnStack (ssym))
1891 spillLRWithPtrReg (ssym);
1894 /* if this was a block level spil then insert push & pop
1895 at the start & end of block respectively */
1896 if (ssym->blockSpil)
1898 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1899 /* add push to the start of the block */
1900 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1901 ebp->sch->next : ebp->sch));
1902 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1903 /* add pop to the end of the block */
1904 addiCodeToeBBlock (ebp, nic, NULL);
1907 /* if spilt because not used in the remainder of the
1908 block then add a push before this instruction and
1909 a pop at the end of the block */
1910 if (ssym->remainSpil)
1913 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1914 /* add push just before this instruction */
1915 addiCodeToeBBlock (ebp, nic, ic);
1917 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1918 /* add pop to the end of the block */
1919 addiCodeToeBBlock (ebp, nic, NULL);
1928 /*-----------------------------------------------------------------*/
1929 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1930 /*-----------------------------------------------------------------*/
1932 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1937 debugLog ("%s\n", __FUNCTION__);
1939 /* try for a ptr type */
1940 if ((reg = allocReg (REG_PTR)))
1943 /* try for gpr type */
1944 if ((reg = allocReg (REG_GPR)))
1947 /* we have to spil */
1948 if (!spilSomething (ic, ebp, sym))
1951 /* make sure partially assigned registers aren't reused */
1952 for (j=0; j<=sym->nRegs; j++)
1954 sym->regs[j]->isFree = 0;
1956 /* this looks like an infinite loop but
1957 in really selectSpil will abort */
1961 /*-----------------------------------------------------------------*/
1962 /* getRegGpr - will try for GPR if not spil */
1963 /*-----------------------------------------------------------------*/
1965 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1970 debugLog ("%s\n", __FUNCTION__);
1972 /* try for gpr type */
1973 if ((reg = allocReg (REG_GPR)))
1976 if (!pic14_ptrRegReq)
1977 if ((reg = allocReg (REG_PTR)))
1980 /* we have to spil */
1981 if (!spilSomething (ic, ebp, sym))
1984 /* make sure partially assigned registers aren't reused */
1985 for (j=0; j<=sym->nRegs; j++)
1987 sym->regs[j]->isFree = 0;
1989 /* this looks like an infinite loop but
1990 in really selectSpil will abort */
1994 /*-----------------------------------------------------------------*/
1995 /* symHasReg - symbol has a given register */
1996 /*-----------------------------------------------------------------*/
1998 symHasReg (symbol * sym, regs * reg)
2002 debugLog ("%s\n", __FUNCTION__);
2003 for (i = 0; i < sym->nRegs; i++)
2004 if (sym->regs[i] == reg)
2010 /*-----------------------------------------------------------------*/
2011 /* deassignLRs - check the live to and if they have registers & are */
2012 /* not spilt then free up the registers */
2013 /*-----------------------------------------------------------------*/
2015 deassignLRs (iCode * ic, eBBlock * ebp)
2021 debugLog ("%s\n", __FUNCTION__);
2022 for (sym = hTabFirstItem (liveRanges, &k); sym;
2023 sym = hTabNextItem (liveRanges, &k))
2026 symbol *psym = NULL;
2027 /* if it does not end here */
2028 if (sym->liveTo > ic->seq)
2031 /* if it was spilt on stack then we can
2032 mark the stack spil location as free */
2037 sym->usl.spillLoc->isFree = 1;
2043 if (!bitVectBitValue (_G.regAssigned, sym->key))
2046 /* special case check if this is an IFX &
2047 the privious one was a pop and the
2048 previous one was not spilt then keep track
2050 if (ic->op == IFX && ic->prev &&
2051 ic->prev->op == IPOP &&
2052 !ic->prev->parmPush &&
2053 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
2054 psym = OP_SYMBOL (IC_LEFT (ic->prev));
2060 bitVectUnSetBit (_G.regAssigned, sym->key);
2062 /* if the result of this one needs registers
2063 and does not have it then assign it right
2065 if (IC_RESULT (ic) &&
2066 !(SKIP_IC2 (ic) || /* not a special icode */
2067 ic->op == JUMPTABLE ||
2072 POINTER_SET (ic)) &&
2073 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
2074 result->liveTo > ic->seq && /* and will live beyond this */
2075 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
2076 result->liveFrom == ic->seq && /* does not start before here */
2077 result->regType == sym->regType && /* same register types */
2078 result->regType == sym->regType && /* same register types */
2079 result->nRegs && /* which needs registers */
2080 !result->isspilt && /* and does not already have them */
2082 !bitVectBitValue (_G.regAssigned, result->key) &&
2083 /* the number of free regs + number of regs in this LR
2084 can accomodate the what result Needs */
2085 ((nfreeRegsType (result->regType) +
2086 sym->nRegs) >= result->nRegs)
2090 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
2092 result->regs[i] = sym->regs[i];
2094 result->regs[i] = getRegGpr (ic, ebp, result);
2096 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
2100 /* free the remaining */
2101 for (; i < sym->nRegs; i++)
2105 if (!symHasReg (psym, sym->regs[i]))
2106 freeReg (sym->regs[i]);
2109 freeReg (sym->regs[i]);
2116 /*-----------------------------------------------------------------*/
2117 /* reassignLR - reassign this to registers */
2118 /*-----------------------------------------------------------------*/
2120 reassignLR (operand * op)
2122 symbol *sym = OP_SYMBOL (op);
2125 debugLog ("%s\n", __FUNCTION__);
2126 /* not spilt any more */
2127 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
2128 bitVectUnSetBit (_G.spiltSet, sym->key);
2130 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2134 for (i = 0; i < sym->nRegs; i++)
2135 sym->regs[i]->isFree = 0;
2138 /*-----------------------------------------------------------------*/
2139 /* willCauseSpill - determines if allocating will cause a spill */
2140 /*-----------------------------------------------------------------*/
2142 willCauseSpill (int nr, int rt)
2144 debugLog ("%s\n", __FUNCTION__);
2145 /* first check if there are any avlb registers
2146 of te type required */
2149 /* special case for pointer type
2150 if pointer type not avlb then
2151 check for type gpr */
2152 if (nFreeRegs (rt) >= nr)
2154 if (nFreeRegs (REG_GPR) >= nr)
2159 if (pic14_ptrRegReq)
2161 if (nFreeRegs (rt) >= nr)
2166 if (nFreeRegs (REG_PTR) +
2167 nFreeRegs (REG_GPR) >= nr)
2172 debugLog (" ... yep it will (cause a spill)\n");
2173 /* it will cause a spil */
2177 /*-----------------------------------------------------------------*/
2178 /* positionRegs - the allocator can allocate same registers to res- */
2179 /* ult and operand, if this happens make sure they are in the same */
2180 /* position as the operand otherwise chaos results */
2181 /*-----------------------------------------------------------------*/
2183 positionRegs (symbol * result, symbol * opsym, int lineno)
2185 int count = min (result->nRegs, opsym->nRegs);
2186 int i, j = 0, shared = 0;
2188 debugLog ("%s\n", __FUNCTION__);
2189 /* if the result has been spilt then cannot share */
2194 /* first make sure that they actually share */
2195 for (i = 0; i < count; i++)
2197 for (j = 0; j < count; j++)
2199 if (result->regs[i] == opsym->regs[j] && i != j)
2209 regs *tmp = result->regs[i];
2210 result->regs[i] = result->regs[j];
2211 result->regs[j] = tmp;
2216 /*------------------------------------------------------------------*/
2217 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2218 /* it should either have registers or have beed spilled. Otherwise, */
2219 /* there was an uninitialized variable, so just spill this to get */
2220 /* the operand in a valid state. */
2221 /*------------------------------------------------------------------*/
2223 verifyRegsAssigned (operand *op, iCode * ic)
2228 if (!IS_ITEMP (op)) return;
2230 sym = OP_SYMBOL (op);
2231 if (sym->isspilt) return;
2232 if (!sym->nRegs) return;
2233 if (sym->regs[0]) return;
2235 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
2236 sym->prereqv ? sym->prereqv->name : sym->name);
2241 /*-----------------------------------------------------------------*/
2242 /* serialRegAssign - serially allocate registers to the variables */
2243 /*-----------------------------------------------------------------*/
2245 serialRegAssign (eBBlock ** ebbs, int count)
2249 debugLog ("%s\n", __FUNCTION__);
2250 /* for all blocks */
2251 for (i = 0; i < count; i++)
2256 if (ebbs[i]->noPath &&
2257 (ebbs[i]->entryLabel != entryLabel &&
2258 ebbs[i]->entryLabel != returnLabel))
2261 /* of all instructions do */
2262 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2265 debugLog (" op: %s\n", decodeOp (ic->op));
2267 /* if this is an ipop that means some live
2268 range will have to be assigned again */
2270 reassignLR (IC_LEFT (ic));
2272 /* if result is present && is a true symbol */
2273 if (IC_RESULT (ic) && ic->op != IFX &&
2274 IS_TRUE_SYMOP (IC_RESULT (ic)))
2275 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2277 /* take away registers from live
2278 ranges that end at this instruction */
2279 deassignLRs (ic, ebbs[i]);
2281 /* some don't need registers */
2282 if (SKIP_IC2 (ic) ||
2283 ic->op == JUMPTABLE ||
2287 (IC_RESULT (ic) && POINTER_SET (ic)))
2290 /* now we need to allocate registers
2291 only for the result */
2294 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2300 /* Make sure any spill location is definately allocated */
2301 if (sym->isspilt && !sym->remat && sym->usl.spillLoc &&
2302 !sym->usl.spillLoc->allocreq)
2304 sym->usl.spillLoc->allocreq++;
2307 /* if it does not need or is spilt
2308 or is already assigned to registers
2309 or will not live beyond this instructions */
2312 bitVectBitValue (_G.regAssigned, sym->key) ||
2313 sym->liveTo <= ic->seq)
2316 /* if some liverange has been spilt at the block level
2317 and this one live beyond this block then spil this
2319 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2324 /* if trying to allocate this will cause
2325 a spill and there is nothing to spill
2326 or this one is rematerializable then
2328 willCS = willCauseSpill (sym->nRegs, sym->regType);
2329 spillable = computeSpillable (ic);
2331 (willCS && bitVectIsZero (spillable)))
2339 /* If the live range preceeds the point of definition
2340 then ideally we must take into account registers that
2341 have been allocated after sym->liveFrom but freed
2342 before ic->seq. This is complicated, so spill this
2343 symbol instead and let fillGaps handle the allocation. */
2344 if (sym->liveFrom < ic->seq)
2350 /* if it has a spillocation & is used less than
2351 all other live ranges then spill this */
2353 if (sym->usl.spillLoc) {
2354 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2355 allLRs, ebbs[i], ic));
2356 if (leastUsed && leastUsed->used > sym->used) {
2361 /* if none of the liveRanges have a spillLocation then better
2362 to spill this one than anything else already assigned to registers */
2363 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2364 /* if this is local to this block then we might find a block spil */
2365 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2373 if (ic->op == RECEIVE)
2374 debugLog ("When I get clever, I'll optimize the receive logic\n");
2376 /* if we need ptr regs for the right side
2378 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2379 <= (unsigned) PTRSIZE)
2384 /* else we assign registers to it */
2385 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2387 debugLog (" %d - \n", __LINE__);
2389 bitVectDebugOn(_G.regAssigned, debugF);
2390 for (j = 0; j < sym->nRegs; j++)
2392 if (sym->regType == REG_PTR)
2393 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2395 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2397 /* if the allocation failed which means
2398 this was spilt then break */
2402 debugLog (" %d - \n", __LINE__);
2404 /* if it shares registers with operands make sure
2405 that they are in the same position */
2406 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2407 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2408 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2409 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2410 /* do the same for the right operand */
2411 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2412 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2413 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2414 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2416 debugLog (" %d - \n", __LINE__);
2419 debugLog (" %d - \n", __LINE__);
2428 /* Check for and fix any problems with uninitialized operands */
2429 for (i = 0; i < count; i++)
2433 if (ebbs[i]->noPath &&
2434 (ebbs[i]->entryLabel != entryLabel &&
2435 ebbs[i]->entryLabel != returnLabel))
2438 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2445 verifyRegsAssigned (IC_COND (ic), ic);
2449 if (ic->op == JUMPTABLE)
2451 verifyRegsAssigned (IC_JTCOND (ic), ic);
2455 verifyRegsAssigned (IC_RESULT (ic), ic);
2456 verifyRegsAssigned (IC_LEFT (ic), ic);
2457 verifyRegsAssigned (IC_RIGHT (ic), ic);
2463 /*-----------------------------------------------------------------*/
2464 /* rUmaskForOp :- returns register mask for an operand */
2465 /*-----------------------------------------------------------------*/
2467 rUmaskForOp (operand * op)
2473 debugLog ("%s\n", __FUNCTION__);
2474 /* only temporaries are assigned registers */
2478 sym = OP_SYMBOL (op);
2480 /* if spilt or no registers assigned to it
2482 if (sym->isspilt || !sym->nRegs)
2485 rumask = newBitVect (pic14_nRegs);
2487 for (j = 0; j < sym->nRegs; j++)
2489 rumask = bitVectSetBit (rumask,
2490 sym->regs[j]->rIdx);
2496 /*-----------------------------------------------------------------*/
2497 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2498 /*-----------------------------------------------------------------*/
2500 regsUsedIniCode (iCode * ic)
2502 bitVect *rmask = newBitVect (pic14_nRegs);
2504 debugLog ("%s\n", __FUNCTION__);
2505 /* do the special cases first */
2508 rmask = bitVectUnion (rmask,
2509 rUmaskForOp (IC_COND (ic)));
2513 /* for the jumptable */
2514 if (ic->op == JUMPTABLE)
2516 rmask = bitVectUnion (rmask,
2517 rUmaskForOp (IC_JTCOND (ic)));
2522 /* of all other cases */
2524 rmask = bitVectUnion (rmask,
2525 rUmaskForOp (IC_LEFT (ic)));
2529 rmask = bitVectUnion (rmask,
2530 rUmaskForOp (IC_RIGHT (ic)));
2533 rmask = bitVectUnion (rmask,
2534 rUmaskForOp (IC_RESULT (ic)));
2540 /*-----------------------------------------------------------------*/
2541 /* createRegMask - for each instruction will determine the regsUsed */
2542 /*-----------------------------------------------------------------*/
2544 createRegMask (eBBlock ** ebbs, int count)
2548 debugLog ("%s\n", __FUNCTION__);
2549 /* for all blocks */
2550 for (i = 0; i < count; i++)
2554 if (ebbs[i]->noPath &&
2555 (ebbs[i]->entryLabel != entryLabel &&
2556 ebbs[i]->entryLabel != returnLabel))
2559 /* for all instructions */
2560 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2565 if (SKIP_IC2 (ic) || !ic->rlive)
2568 /* first mark the registers used in this
2570 ic->rUsed = regsUsedIniCode (ic);
2571 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2573 /* now create the register mask for those
2574 registers that are in use : this is a
2575 super set of ic->rUsed */
2576 ic->rMask = newBitVect (pic14_nRegs + 1);
2578 /* for all live Ranges alive at this point */
2579 for (j = 1; j < ic->rlive->size; j++)
2584 /* if not alive then continue */
2585 if (!bitVectBitValue (ic->rlive, j))
2588 /* find the live range we are interested in */
2589 if (!(sym = hTabItemWithKey (liveRanges, j)))
2591 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2592 "createRegMask cannot find live range");
2596 /* if no register assigned to it */
2597 if (!sym->nRegs || sym->isspilt)
2600 /* for all the registers allocated to it */
2601 for (k = 0; k < sym->nRegs; k++)
2604 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2610 /*-----------------------------------------------------------------*/
2611 /* rematStr - returns the rematerialized string for a remat var */
2612 /*-----------------------------------------------------------------*/
2614 rematStr (symbol * sym)
2617 iCode *ic = sym->rematiCode;
2618 symbol *psym = NULL;
2620 debugLog ("%s\n", __FUNCTION__);
2622 //printf ("%s\n", s);
2624 /* if plus or minus print the right hand side */
2626 if (ic->op == '+' || ic->op == '-') {
2628 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2630 sprintf (s, "(%s %c 0x%04x)",
2631 OP_SYMBOL (IC_LEFT (ric))->rname,
2633 (int) operandLitValue (IC_RIGHT (ic)));
2636 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2638 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2639 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2644 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2645 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2647 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2652 /*-----------------------------------------------------------------*/
2653 /* rematStr - returns the rematerialized string for a remat var */
2654 /*-----------------------------------------------------------------*/
2656 rematStr (symbol * sym)
2659 iCode *ic = sym->rematiCode;
2661 debugLog ("%s\n", __FUNCTION__);
2666 /* if plus or minus print the right hand side */
2668 if (ic->op == '+' || ic->op == '-') {
2669 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2672 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2676 if (ic->op == '+' || ic->op == '-')
2678 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2679 sprintf (s, "(%s %c 0x%04x)",
2680 OP_SYMBOL (IC_LEFT (ric))->rname,
2682 (int) operandLitValue (IC_RIGHT (ic)));
2685 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2687 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2691 /* we reached the end */
2692 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2696 printf ("%s\n", buffer);
2701 /*-----------------------------------------------------------------*/
2702 /* regTypeNum - computes the type & number of registers required */
2703 /*-----------------------------------------------------------------*/
2711 debugLog ("%s\n", __FUNCTION__);
2712 /* for each live range do */
2713 for (sym = hTabFirstItem (liveRanges, &k); sym;
2714 sym = hTabNextItem (liveRanges, &k)) {
2716 debugLog (" %d - %s\n", __LINE__, sym->rname);
2718 /* if used zero times then no registers needed */
2719 if ((sym->liveTo - sym->liveFrom) == 0)
2723 /* if the live range is a temporary */
2726 debugLog (" %d - itemp register\n", __LINE__);
2728 /* if the type is marked as a conditional */
2729 if (sym->regType == REG_CND)
2732 /* if used in return only then we don't
2735 if (IS_AGGREGATE (sym->type) || sym->isptr)
2736 sym->type = aggrToPtr (sym->type, FALSE);
2737 debugLog (" %d - no reg needed - accumulator used\n", __LINE__);
2743 //if (IS_AGGREGATE (sym->type) || sym->isptr)
2744 // sym->type = aggrToPtr (sym->type, FALSE);
2745 debugLog (" %d - used as a return\n", __LINE__);
2750 /* if the symbol has only one definition &
2751 that definition is a get_pointer and the
2752 pointer we are getting is rematerializable and
2755 if (bitVectnBitsOn (sym->defs) == 1 &&
2756 (ic = hTabItemWithKey (iCodehTab,
2757 bitVectFirstBit (sym->defs))) &&
2759 !IS_BITVAR (sym->etype) &&
2760 (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
2762 if (ptrPseudoSymSafe (sym, ic)) {
2766 debugLog (" %d - \n", __LINE__);
2768 /* create a psuedo symbol & force a spil */
2769 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2770 psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2771 psym->type = sym->type;
2772 psym->etype = sym->etype;
2773 psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
2774 strcpy (psym->rname, psym->name);
2776 sym->usl.spillLoc = psym;
2780 /* if in data space or idata space then try to
2781 allocate pointer register */
2785 /* if not then we require registers */
2786 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2787 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2788 getSize (sym->type));
2791 if(IS_PTR_CONST (sym->type)) {
2792 debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2796 if (sym->nRegs > 4) {
2797 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2798 printTypeChain (sym->type, stderr);
2799 fprintf (stderr, "\n");
2802 /* determine the type of register required */
2803 if (sym->nRegs == 1 &&
2804 IS_PTR (sym->type) &&
2806 sym->regType = REG_PTR;
2808 sym->regType = REG_GPR;
2811 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2815 /* for the first run we don't provide */
2816 /* registers for true symbols we will */
2817 /* see how things go */
2822 DEFSETFUNC (markRegFree)
2824 ((regs *)item)->isFree = 1;
2829 DEFSETFUNC (deallocReg)
2831 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2832 ((regs *)item)->isFree = 1;
2833 ((regs *)item)->wasUsed = 0;
2837 /*-----------------------------------------------------------------*/
2838 /* freeAllRegs - mark all registers as free */
2839 /*-----------------------------------------------------------------*/
2841 pic14_freeAllRegs ()
2845 debugLog ("%s\n", __FUNCTION__);
2847 applyToSet(dynAllocRegs,markRegFree);
2848 applyToSet(dynStackRegs,markRegFree);
2851 for (i = 0; i < pic14_nRegs; i++)
2852 regspic14[i].isFree = 1;
2856 /*-----------------------------------------------------------------*/
2857 /*-----------------------------------------------------------------*/
2859 pic14_deallocateAllRegs ()
2863 debugLog ("%s\n", __FUNCTION__);
2865 applyToSet(dynAllocRegs,deallocReg);
2868 for (i = 0; i < pic14_nRegs; i++) {
2869 if(regspic14[i].pc_type == PO_GPR_TEMP) {
2870 regspic14[i].isFree = 1;
2871 regspic14[i].wasUsed = 0;
2878 /*-----------------------------------------------------------------*/
2879 /* deallocStackSpil - this will set the stack pointer back */
2880 /*-----------------------------------------------------------------*/
2882 DEFSETFUNC (deallocStackSpil)
2886 debugLog ("%s\n", __FUNCTION__);
2891 /*-----------------------------------------------------------------*/
2892 /* farSpacePackable - returns the packable icode for far variables */
2893 /*-----------------------------------------------------------------*/
2895 farSpacePackable (iCode * ic)
2899 debugLog ("%s\n", __FUNCTION__);
2900 /* go thru till we find a definition for the
2901 symbol on the right */
2902 for (dic = ic->prev; dic; dic = dic->prev)
2905 /* if the definition is a call then no */
2906 if ((dic->op == CALL || dic->op == PCALL) &&
2907 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2912 /* if shift by unknown amount then not */
2913 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2914 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2917 /* if pointer get and size > 1 */
2918 if (POINTER_GET (dic) &&
2919 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2922 if (POINTER_SET (dic) &&
2923 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2926 /* if any three is a true symbol in far space */
2927 if (IC_RESULT (dic) &&
2928 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2929 isOperandInFarSpace (IC_RESULT (dic)))
2932 if (IC_RIGHT (dic) &&
2933 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2934 isOperandInFarSpace (IC_RIGHT (dic)) &&
2935 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2938 if (IC_LEFT (dic) &&
2939 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2940 isOperandInFarSpace (IC_LEFT (dic)) &&
2941 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2944 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2946 if ((dic->op == LEFT_OP ||
2947 dic->op == RIGHT_OP ||
2949 IS_OP_LITERAL (IC_RIGHT (dic)))
2959 /*-----------------------------------------------------------------*/
2960 /* packRegsForAssign - register reduction for assignment */
2961 /*-----------------------------------------------------------------*/
2963 packRegsForAssign (iCode * ic, eBBlock * ebp)
2968 debugLog ("%s\n", __FUNCTION__);
2970 debugAopGet (" result:", IC_RESULT (ic));
2971 debugAopGet (" left:", IC_LEFT (ic));
2972 debugAopGet (" right:", IC_RIGHT (ic));
2974 /* if this is at an absolute address, then get the address. */
2975 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2976 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2977 debugLog (" %d - found config word declaration\n", __LINE__);
2978 if(IS_VALOP(IC_RIGHT(ic))) {
2979 debugLog (" setting config word to %x\n",
2980 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2981 assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2982 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2985 /* remove the assignment from the iCode chain. */
2987 remiCodeFromeBBlock (ebp, ic);
2988 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2989 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2996 if (!IS_ITEMP (IC_RESULT (ic))) {
2997 allocDirReg(IC_RESULT (ic));
2998 debugLog (" %d - result is not temp\n", __LINE__);
3001 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
3002 debugLog (" %d - left is not temp, allocating\n", __LINE__);
3003 allocDirReg(IC_LEFT (ic));
3007 if (!IS_ITEMP (IC_RIGHT (ic))) {
3008 debugLog (" %d - not packing - right is not temp\n", __LINE__);
3010 /* only pack if this is not a function pointer */
3011 if (!IS_REF (IC_RIGHT (ic)))
3012 allocDirReg(IC_RIGHT (ic));
3016 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
3017 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
3019 debugLog (" %d - not packing - right side fails \n", __LINE__);
3023 /* if the true symbol is defined in far space or on stack
3024 then we should not since this will increase register pressure */
3025 if (isOperandInFarSpace (IC_RESULT (ic)))
3027 if ((dic = farSpacePackable (ic)))
3033 /* find the definition of iTempNN scanning backwards if we find a
3034 a use of the true symbol before we find the definition then
3036 for (dic = ic->prev; dic; dic = dic->prev)
3039 /* if there is a function call and this is
3040 a parameter & not my parameter then don't pack it */
3041 if ((dic->op == CALL || dic->op == PCALL) &&
3042 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
3043 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
3045 debugLog (" %d - \n", __LINE__);
3053 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
3054 IS_OP_VOLATILE (IC_RESULT (dic)))
3056 debugLog (" %d - dic is VOLATILE \n", __LINE__);
3061 if (IS_SYMOP (IC_RESULT (dic)) &&
3062 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
3064 /* A previous result was assigned to the same register - we'll our definition */
3065 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
3066 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
3067 if (POINTER_SET (dic))
3073 if (IS_SYMOP (IC_RIGHT (dic)) &&
3074 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
3075 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
3077 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
3082 if (IS_SYMOP (IC_LEFT (dic)) &&
3083 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
3084 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
3086 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
3091 if (POINTER_SET (dic) &&
3092 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
3094 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
3102 return 0; /* did not find */
3104 /* if the result is on stack or iaccess then it must be
3105 the same at least one of the operands */
3106 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
3107 OP_SYMBOL (IC_RESULT (ic))->iaccess)
3110 /* the operation has only one symbol
3111 operator then we can pack */
3112 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
3113 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
3116 if (!((IC_LEFT (dic) &&
3117 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
3119 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
3123 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
3124 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
3125 /* found the definition */
3126 /* replace the result with the result of */
3127 /* this assignment and remove this assignment */
3128 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3129 IC_RESULT (dic) = IC_RESULT (ic);
3131 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
3133 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
3135 /* delete from liverange table also
3136 delete from all the points inbetween and the new
3138 for (sic = dic; sic != ic; sic = sic->next)
3140 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3141 if (IS_ITEMP (IC_RESULT (dic)))
3142 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3145 remiCodeFromeBBlock (ebp, ic);
3146 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3147 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3148 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3154 /*-----------------------------------------------------------------*/
3155 /* findAssignToSym : scanning backwards looks for first assig found */
3156 /*-----------------------------------------------------------------*/
3158 findAssignToSym (operand * op, iCode * ic)
3162 debugLog ("%s\n", __FUNCTION__);
3163 for (dic = ic->prev; dic; dic = dic->prev)
3166 /* if definition by assignment */
3167 if (dic->op == '=' &&
3168 !POINTER_SET (dic) &&
3169 IC_RESULT (dic)->key == op->key
3170 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3174 /* we are interested only if defined in far space */
3175 /* or in stack space in case of + & - */
3177 /* if assigned to a non-symbol then return
3179 if (!IS_SYMOP (IC_RIGHT (dic)))
3182 /* if the symbol is in far space then
3184 if (isOperandInFarSpace (IC_RIGHT (dic)))
3187 /* for + & - operations make sure that
3188 if it is on the stack it is the same
3189 as one of the three operands */
3190 if ((ic->op == '+' || ic->op == '-') &&
3191 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3194 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3195 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3196 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3204 /* if we find an usage then we cannot delete it */
3205 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3208 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3211 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3215 /* now make sure that the right side of dic
3216 is not defined between ic & dic */
3219 iCode *sic = dic->next;
3221 for (; sic != ic; sic = sic->next)
3222 if (IC_RESULT (sic) &&
3223 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3232 /*-----------------------------------------------------------------*/
3233 /* packRegsForSupport :- reduce some registers for support calls */
3234 /*-----------------------------------------------------------------*/
3236 packRegsForSupport (iCode * ic, eBBlock * ebp)
3240 debugLog ("%s\n", __FUNCTION__);
3241 /* for the left & right operand :- look to see if the
3242 left was assigned a true symbol in far space in that
3243 case replace them */
3244 if (IS_ITEMP (IC_LEFT (ic)) &&
3245 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3247 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3253 debugAopGet ("removing left:", IC_LEFT (ic));
3255 /* found it we need to remove it from the
3257 for (sic = dic; sic != ic; sic = sic->next)
3258 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3260 IC_LEFT (ic)->operand.symOperand =
3261 IC_RIGHT (dic)->operand.symOperand;
3262 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3263 remiCodeFromeBBlock (ebp, dic);
3264 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3265 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3269 /* do the same for the right operand */
3272 IS_ITEMP (IC_RIGHT (ic)) &&
3273 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3275 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3281 /* if this is a subtraction & the result
3282 is a true symbol in far space then don't pack */
3283 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3285 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3286 if (IN_FARSPACE (SPEC_OCLS (etype)))
3290 debugAopGet ("removing right:", IC_RIGHT (ic));
3292 /* found it we need to remove it from the
3294 for (sic = dic; sic != ic; sic = sic->next)
3295 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3297 IC_RIGHT (ic)->operand.symOperand =
3298 IC_RIGHT (dic)->operand.symOperand;
3299 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3301 remiCodeFromeBBlock (ebp, dic);
3302 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3303 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3310 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3313 /*-----------------------------------------------------------------*/
3314 /* packRegsForOneuse : - will reduce some registers for single Use */
3315 /*-----------------------------------------------------------------*/
3317 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3322 debugLog ("%s\n", __FUNCTION__);
3323 /* if returning a literal then do nothing */
3327 /* only upto 2 bytes since we cannot predict
3328 the usage of b, & acc */
3329 if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
3334 /* this routine will mark the a symbol as used in one
3335 instruction use only && if the definition is local
3336 (ie. within the basic block) && has only one definition &&
3337 that definition is either a return value from a
3338 function or does not contain any variables in
3340 uses = bitVectCopy (OP_USES (op));
3341 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3342 if (!bitVectIsZero (uses)) /* has other uses */
3345 /* if it has only one defintion */
3346 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3347 return NULL; /* has more than one definition */
3349 /* get that definition */
3351 hTabItemWithKey (iCodehTab,
3352 bitVectFirstBit (OP_DEFS (op)))))
3355 /* found the definition now check if it is local */
3356 if (dic->seq < ebp->fSeq ||
3357 dic->seq > ebp->lSeq)
3358 return NULL; /* non-local */
3360 /* now check if it is the return from
3362 if (dic->op == CALL || dic->op == PCALL)
3364 if (ic->op != SEND && ic->op != RETURN &&
3365 !POINTER_SET(ic) && !POINTER_GET(ic))
3367 OP_SYMBOL (op)->ruonly = 1;
3374 /* otherwise check that the definition does
3375 not contain any symbols in far space */
3376 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3377 isOperandInFarSpace (IC_RIGHT (dic)) ||
3378 IS_OP_RUONLY (IC_LEFT (ic)) ||
3379 IS_OP_RUONLY (IC_RIGHT (ic)))
3384 /* if pointer set then make sure the pointer
3386 if (POINTER_SET (dic) &&
3387 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3390 if (POINTER_GET (dic) &&
3391 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3396 /* also make sure the intervenening instructions
3397 don't have any thing in far space */
3398 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3401 /* if there is an intervening function call then no */
3402 if (dic->op == CALL || dic->op == PCALL)
3404 /* if pointer set then make sure the pointer
3406 if (POINTER_SET (dic) &&
3407 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3410 if (POINTER_GET (dic) &&
3411 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3414 /* if address of & the result is remat then okay */
3415 if (dic->op == ADDRESS_OF &&
3416 OP_SYMBOL (IC_RESULT (dic))->remat)
3419 /* if operand has size of three or more & this
3420 operation is a '*','/' or '%' then 'b' may
3422 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3423 getSize (operandType (op)) >= 3)
3426 /* if left or right or result is in far space */
3427 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3428 isOperandInFarSpace (IC_RIGHT (dic)) ||
3429 isOperandInFarSpace (IC_RESULT (dic)) ||
3430 IS_OP_RUONLY (IC_LEFT (dic)) ||
3431 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3432 IS_OP_RUONLY (IC_RESULT (dic)))
3438 OP_SYMBOL (op)->ruonly = 1;
3443 /*-----------------------------------------------------------------*/
3444 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3445 /*-----------------------------------------------------------------*/
3447 isBitwiseOptimizable (iCode * ic)
3449 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3450 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3452 debugLog ("%s\n", __FUNCTION__);
3453 /* bitwise operations are considered optimizable
3454 under the following conditions (Jean-Louis VERN)
3466 if (IS_LITERAL (rtype) ||
3467 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3473 /*-----------------------------------------------------------------*/
3474 /* packRegsForAccUse - pack registers for acc use */
3475 /*-----------------------------------------------------------------*/
3477 packRegsForAccUse (iCode * ic)
3481 debugLog ("%s\n", __FUNCTION__);
3483 /* if this is an aggregate, e.g. a one byte char array */
3484 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3487 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3489 /* if + or - then it has to be one byte result */
3490 if ((ic->op == '+' || ic->op == '-')
3491 && getSize (operandType (IC_RESULT (ic))) > 1)
3494 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3495 /* if shift operation make sure right side is not a literal */
3496 if (ic->op == RIGHT_OP &&
3497 (isOperandLiteral (IC_RIGHT (ic)) ||
3498 getSize (operandType (IC_RESULT (ic))) > 1))
3501 if (ic->op == LEFT_OP &&
3502 (isOperandLiteral (IC_RIGHT (ic)) ||
3503 getSize (operandType (IC_RESULT (ic))) > 1))
3506 if (IS_BITWISE_OP (ic) &&
3507 getSize (operandType (IC_RESULT (ic))) > 1)
3511 /* has only one definition */
3512 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3515 /* has only one use */
3516 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3519 /* and the usage immediately follows this iCode */
3520 if (!(uic = hTabItemWithKey (iCodehTab,
3521 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3524 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3525 if (ic->next != uic)
3528 /* if it is a conditional branch then we definitely can */
3532 if (uic->op == JUMPTABLE)
3535 /* if the usage is not is an assignment
3536 or an arithmetic / bitwise / shift operation then not */
3537 if (POINTER_SET (uic) &&
3538 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3541 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3542 if (uic->op != '=' &&
3543 !IS_ARITHMETIC_OP (uic) &&
3544 !IS_BITWISE_OP (uic) &&
3545 uic->op != LEFT_OP &&
3546 uic->op != RIGHT_OP)
3549 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3550 /* if used in ^ operation then make sure right is not a
3552 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3555 /* if shift operation make sure right side is not a literal */
3556 if (uic->op == RIGHT_OP &&
3557 (isOperandLiteral (IC_RIGHT (uic)) ||
3558 getSize (operandType (IC_RESULT (uic))) > 1))
3561 if (uic->op == LEFT_OP &&
3562 (isOperandLiteral (IC_RIGHT (uic)) ||
3563 getSize (operandType (IC_RESULT (uic))) > 1))
3566 /* make sure that the result of this icode is not on the
3567 stack, since acc is used to compute stack offset */
3568 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3569 OP_SYMBOL (IC_RESULT (uic))->onStack)
3572 /* if either one of them in far space then we cannot */
3573 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3574 isOperandInFarSpace (IC_LEFT (uic))) ||
3575 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3576 isOperandInFarSpace (IC_RIGHT (uic))))
3579 /* if the usage has only one operand then we can */
3580 if (IC_LEFT (uic) == NULL ||
3581 IC_RIGHT (uic) == NULL)
3584 /* make sure this is on the left side if not
3585 a '+' since '+' is commutative */
3586 if (ic->op != '+' &&
3587 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3590 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3591 /* if one of them is a literal then we can */
3592 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3593 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3594 (getSize (operandType (IC_RESULT (uic))) <= 1))
3596 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3600 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3601 /* if the other one is not on stack then we can */
3602 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3603 (IS_ITEMP (IC_RIGHT (uic)) ||
3604 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3605 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3608 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3609 (IS_ITEMP (IC_LEFT (uic)) ||
3610 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3611 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3617 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3618 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3623 /*-----------------------------------------------------------------*/
3624 /* packForPush - hueristics to reduce iCode for pushing */
3625 /*-----------------------------------------------------------------*/
3627 packForReceive (iCode * ic, eBBlock * ebp)
3631 debugLog ("%s\n", __FUNCTION__);
3632 debugAopGet (" result:", IC_RESULT (ic));
3633 debugAopGet (" left:", IC_LEFT (ic));
3634 debugAopGet (" right:", IC_RIGHT (ic));
3639 for (dic = ic->next; dic; dic = dic->next)
3644 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3645 debugLog (" used on left\n");
3646 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3647 debugLog (" used on right\n");
3648 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3649 debugLog (" used on result\n");
3651 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3652 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3657 debugLog (" hey we can remove this unnecessary assign\n");
3659 /*-----------------------------------------------------------------*/
3660 /* packForPush - hueristics to reduce iCode for pushing */
3661 /*-----------------------------------------------------------------*/
3663 packForPush (iCode * ic, eBBlock * ebp)
3667 debugLog ("%s\n", __FUNCTION__);
3668 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3671 /* must have only definition & one usage */
3672 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3673 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3676 /* find the definition */
3677 if (!(dic = hTabItemWithKey (iCodehTab,
3678 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3681 if (dic->op != '=' || POINTER_SET (dic))
3684 /* we now we know that it has one & only one def & use
3685 and the that the definition is an assignment */
3686 IC_LEFT (ic) = IC_RIGHT (dic);
3688 remiCodeFromeBBlock (ebp, dic);
3689 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3690 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3693 void printSymType(char * str, sym_link *sl)
3695 debugLog (" %s Symbol type: ",str);
3696 printTypeChain( sl, debugF);
3701 /*-----------------------------------------------------------------*/
3702 /* some debug code to print the symbol S_TYPE. Note that
3703 * the function checkSClass in src/SDCCsymt.c dinks with
3704 * the S_TYPE in ways the PIC port doesn't fully like...*/
3705 /*-----------------------------------------------------------------*/
3706 void isData(sym_link *sl)
3716 for ( ; sl; sl=sl->next) {
3718 switch (SPEC_SCLS(sl)) {
3720 case S_DATA: fprintf (of, "data "); break;
3721 case S_XDATA: fprintf (of, "xdata "); break;
3722 case S_SFR: fprintf (of, "sfr "); break;
3723 case S_SBIT: fprintf (of, "sbit "); break;
3724 case S_CODE: fprintf (of, "code "); break;
3725 case S_IDATA: fprintf (of, "idata "); break;
3726 case S_PDATA: fprintf (of, "pdata "); break;
3727 case S_LITERAL: fprintf (of, "literal "); break;
3728 case S_STACK: fprintf (of, "stack "); break;
3729 case S_XSTACK: fprintf (of, "xstack "); break;
3730 case S_BIT: fprintf (of, "bit "); break;
3731 case S_EEPROM: fprintf (of, "eeprom "); break;
3741 /*-----------------------------------------------------------------*/
3742 /* packRegisters - does some transformations to reduce register */
3744 /*-----------------------------------------------------------------*/
3746 packRegisters (eBBlock * ebp)
3751 debugLog ("%s\n", __FUNCTION__);
3757 /* look for assignments of the form */
3758 /* iTempNN = TRueSym (someoperation) SomeOperand */
3760 /* TrueSym := iTempNN:1 */
3761 for (ic = ebp->sch; ic; ic = ic->next)
3764 /* find assignment of the form TrueSym := iTempNN:1 */
3765 if (ic->op == '=' && !POINTER_SET (ic))
3766 change += packRegsForAssign (ic, ebp);
3770 if (POINTER_SET (ic))
3771 debugLog ("pointer is set\n");
3772 debugAopGet (" result:", IC_RESULT (ic));
3773 debugAopGet (" left:", IC_LEFT (ic));
3774 debugAopGet (" right:", IC_RIGHT (ic));
3783 for (ic = ebp->sch; ic; ic = ic->next) {
3785 if(IS_SYMOP ( IC_LEFT(ic))) {
3786 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3788 debugAopGet (" left:", IC_LEFT (ic));
3789 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3790 debugLog (" is a pointer\n");
3792 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3793 debugLog (" is volatile\n");
3797 printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
3800 if(IS_SYMOP ( IC_RIGHT(ic))) {
3801 debugAopGet (" right:", IC_RIGHT (ic));
3802 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3805 if(IS_SYMOP ( IC_RESULT(ic))) {
3806 debugAopGet (" result:", IC_RESULT (ic));
3807 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3810 if (POINTER_SET (ic))
3811 debugLog (" %d - Pointer set\n", __LINE__);
3814 /* Look for two subsequent iCodes with */
3816 /* _c = iTemp & op; */
3817 /* and replace them by */
3820 if ((ic->op == BITWISEAND || ic->op == '|' || ic->op == '^') &&
3822 ic->prev->op == '=' &&
3823 IS_ITEMP (IC_LEFT (ic)) &&
3824 IC_LEFT (ic) == IC_RESULT (ic->prev) &&
3825 isOperandEqual (IC_RESULT(ic), IC_RIGHT(ic->prev)))
3827 iCode* ic_prev = ic->prev;
3828 symbol* prev_result_sym = OP_SYMBOL (IC_RESULT (ic_prev));
3830 ReplaceOpWithCheaperOp (&IC_LEFT (ic), IC_RESULT (ic));
3831 if (IC_RESULT (ic_prev) != IC_RIGHT (ic))
3833 bitVectUnSetBit (OP_USES (IC_RESULT (ic_prev)), ic->key);
3834 if (/*IS_ITEMP (IC_RESULT (ic_prev)) && */
3835 prev_result_sym->liveTo == ic->seq)
3837 prev_result_sym->liveTo = ic_prev->seq;
3840 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
3842 bitVectSetBit (ic->rlive, IC_RESULT (ic)->key);
3844 if (bitVectIsZero (OP_USES (IC_RESULT (ic_prev))))
3846 bitVectUnSetBit (ic->rlive, IC_RESULT (ic)->key);
3847 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic_prev)), ic_prev->key);
3848 remiCodeFromeBBlock (ebp, ic_prev);
3849 hTabDeleteItem (&iCodehTab, ic_prev->key, ic_prev, DELETE_ITEM, NULL);
3853 /* if this is an itemp & result of a address of a true sym
3854 then mark this as rematerialisable */
3855 if (ic->op == ADDRESS_OF &&
3856 IS_ITEMP (IC_RESULT (ic)) &&
3857 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3858 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3859 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3862 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3864 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3865 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3866 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3870 /* if straight assignment then carry remat flag if
3871 this is the only definition */
3872 if (ic->op == '=' &&
3873 !POINTER_SET (ic) &&
3874 IS_SYMOP (IC_RIGHT (ic)) &&
3875 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3876 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3878 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3880 OP_SYMBOL (IC_RESULT (ic))->remat =
3881 OP_SYMBOL (IC_RIGHT (ic))->remat;
3882 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3883 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3886 /* if this is a +/- operation with a rematerizable
3887 then mark this as rematerializable as well */
3888 if ((ic->op == '+' || ic->op == '-') &&
3889 (IS_SYMOP (IC_LEFT (ic)) &&
3890 IS_ITEMP (IC_RESULT (ic)) &&
3891 OP_SYMBOL (IC_LEFT (ic))->remat &&
3892 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3893 IS_OP_LITERAL (IC_RIGHT (ic))))
3895 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3897 operandLitValue (IC_RIGHT (ic));
3898 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3899 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3900 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3903 /* mark the pointer usages */
3904 if (POINTER_SET (ic))
3906 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3907 debugLog (" marking as a pointer (set) =>");
3908 debugAopGet (" result:", IC_RESULT (ic));
3910 if (POINTER_GET (ic))
3912 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3913 debugLog (" marking as a pointer (get) =>");
3914 debugAopGet (" left:", IC_LEFT (ic));
3919 /* if we are using a symbol on the stack
3920 then we should say pic14_ptrRegReq */
3921 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3922 pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3923 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3924 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3925 pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3926 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3929 if (IS_SYMOP (IC_LEFT (ic)))
3930 pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3931 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3932 if (IS_SYMOP (IC_RIGHT (ic)))
3933 pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3934 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3935 if (IS_SYMOP (IC_RESULT (ic)))
3936 pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3937 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3940 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
3944 /* if the condition of an if instruction
3945 is defined in the previous instruction then
3946 mark the itemp as a conditional */
3947 if ((IS_CONDITIONAL (ic) ||
3948 ((ic->op == BITWISEAND ||
3951 isBitwiseOptimizable (ic))) &&
3952 ic->next && ic->next->op == IFX &&
3953 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3954 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3957 debugLog (" %d\n", __LINE__);
3958 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3962 /* reduce for support function calls */
3963 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3964 packRegsForSupport (ic, ebp);
3966 /* if a parameter is passed, it's in W, so we may not
3967 need to place a copy in a register */
3968 if (ic->op == RECEIVE)
3969 packForReceive (ic, ebp);
3971 /* some cases the redundant moves can
3972 can be eliminated for return statements */
3973 if ((ic->op == RETURN || ic->op == SEND) &&
3974 !isOperandInFarSpace (IC_LEFT (ic)) &&
3976 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3978 /* if pointer set & left has a size more than
3979 one and right is not in far space */
3980 if (POINTER_SET (ic) &&
3981 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3982 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3983 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3984 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3986 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3988 /* if pointer get */
3989 if (POINTER_GET (ic) &&
3990 !isOperandInFarSpace (IC_RESULT (ic)) &&
3991 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3992 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3993 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3995 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3998 /* if this is cast for intergral promotion then
3999 check if only use of the definition of the
4000 operand being casted/ if yes then replace
4001 the result of that arithmetic operation with
4002 this result and get rid of the cast */
4003 if (ic->op == CAST) {
4005 sym_link *fromType = operandType (IC_RIGHT (ic));
4006 sym_link *toType = operandType (IC_LEFT (ic));
4008 debugLog (" %d - casting\n", __LINE__);
4010 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
4011 getSize (fromType) != getSize (toType)) {
4014 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4017 if (IS_ARITHMETIC_OP (dic)) {
4019 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4020 IC_RESULT (dic) = IC_RESULT (ic);
4021 remiCodeFromeBBlock (ebp, ic);
4022 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4023 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4024 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4028 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
4032 /* if the type from and type to are the same
4033 then if this is the only use then packit */
4034 if (compareType (operandType (IC_RIGHT (ic)),
4035 operandType (IC_LEFT (ic))) == 1) {
4037 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4040 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4041 IC_RESULT (dic) = IC_RESULT (ic);
4042 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4043 remiCodeFromeBBlock (ebp, ic);
4044 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4045 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4053 iTempNN := (some variable in farspace) V1
4058 if (ic->op == IPUSH)
4060 packForPush (ic, ebp);
4064 /* pack registers for accumulator use, when the
4065 result of an arithmetic or bit wise operation
4066 has only one use, that use is immediately following
4067 the defintion and the using iCode has only one
4068 operand or has two operands but one is literal &
4069 the result of that operation is not on stack then
4070 we can leave the result of this operation in acc:b
4072 if ((IS_ARITHMETIC_OP (ic)
4074 || IS_BITWISE_OP (ic)
4076 || ic->op == LEFT_OP || ic->op == RIGHT_OP
4079 IS_ITEMP (IC_RESULT (ic)) &&
4080 getSize (operandType (IC_RESULT (ic))) <= 2)
4082 packRegsForAccUse (ic);
4088 dumpEbbsToDebug (eBBlock ** ebbs, int count)
4092 if (!debug || !debugF)
4095 for (i = 0; i < count; i++)
4097 fprintf (debugF, "\n----------------------------------------------------------------\n");
4098 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
4099 ebbs[i]->entryLabel->name,
4102 ebbs[i]->isLastInLoop);
4103 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4108 fprintf (debugF, "visited %d : hasFcall = %d\n",
4112 fprintf (debugF, "\ndefines bitVector :");
4113 bitVectDebugOn (ebbs[i]->defSet, debugF);
4114 fprintf (debugF, "\nlocal defines bitVector :");
4115 bitVectDebugOn (ebbs[i]->ldefs, debugF);
4116 fprintf (debugF, "\npointers Set bitvector :");
4117 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4118 fprintf (debugF, "\nin pointers Set bitvector :");
4119 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4120 fprintf (debugF, "\ninDefs Set bitvector :");
4121 bitVectDebugOn (ebbs[i]->inDefs, debugF);
4122 fprintf (debugF, "\noutDefs Set bitvector :");
4123 bitVectDebugOn (ebbs[i]->outDefs, debugF);
4124 fprintf (debugF, "\nusesDefs Set bitvector :");
4125 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4126 fprintf (debugF, "\n----------------------------------------------------------------\n");
4127 printiCChain (ebbs[i]->sch, debugF);
4130 /*-----------------------------------------------------------------*/
4131 /* assignRegisters - assigns registers to each live range as need */
4132 /*-----------------------------------------------------------------*/
4134 pic14_assignRegisters (ebbIndex * ebbi)
4136 eBBlock ** ebbs = ebbi->bbOrder;
4137 int count = ebbi->count;
4141 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
4142 debugLog ("\nebbs before optimizing:\n");
4143 dumpEbbsToDebug (ebbs, count);
4145 setToNull ((void *) &_G.funcrUsed);
4146 pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4149 /* change assignments this will remove some
4150 live ranges reducing some register pressure */
4151 for (i = 0; i < count; i++)
4152 packRegisters (ebbs[i]);
4159 debugLog("dir registers allocated so far:\n");
4160 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4163 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4164 reg = hTabNextItem(dynDirectRegNames, &hkey);
4169 if (options.dump_pack)
4170 dumpEbbsToFileExt (DUMP_PACK, ebbi);
4172 /* first determine for each live range the number of
4173 registers & the type of registers required for each */
4176 /* and serially allocate registers */
4177 serialRegAssign (ebbs, count);
4179 /* if stack was extended then tell the user */
4182 /* werror(W_TOOMANY_SPILS,"stack", */
4183 /* _G.stackExtend,currFunc->name,""); */
4189 /* werror(W_TOOMANY_SPILS,"data space", */
4190 /* _G.dataExtend,currFunc->name,""); */
4194 /* after that create the register mask
4195 for each of the instruction */
4196 createRegMask (ebbs, count);
4198 /* redo that offsets for stacked automatic variables */
4199 redoStackOffsets ();
4201 if (options.dump_rassgn)
4202 dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
4204 /* now get back the chain */
4205 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4207 debugLog ("ebbs after optimizing:\n");
4208 dumpEbbsToDebug (ebbs, count);
4213 /* free up any _G.stackSpil locations allocated */
4214 applyToSet (_G.stackSpil, deallocStackSpil);
4216 setToNull ((void *) &_G.stackSpil);
4217 setToNull ((void *) &_G.spiltSet);
4218 /* mark all registers as free */
4219 //pic14_freeAllRegs ();
4221 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");