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");
975 if( (dReg = regWithIdx ( dynProcessorRegs, idx, fixed)) != NULL ) {
976 debugLog ("Found a Processor Register!\n");
990 /*-----------------------------------------------------------------*/
991 /* pic14_regWithIdx - returns pointer to register with index number*/
992 /*-----------------------------------------------------------------*/
994 pic14_regWithIdx (int idx)
998 if( (dReg = typeRegWithIdx(idx,REG_GPR,0)) != NULL)
1001 if( (dReg = typeRegWithIdx(idx,REG_SFR,0)) != NULL)
1007 /*-----------------------------------------------------------------*/
1008 /* pic14_regWithIdx - returns pointer to register with index number */
1009 /*-----------------------------------------------------------------*/
1011 pic14_allocWithIdx (int idx)
1016 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
1018 if( (dReg = regWithIdx ( dynAllocRegs, idx,0)) != NULL) {
1020 debugLog ("Found a Dynamic Register!\n");
1021 } else if( (dReg = regWithIdx ( dynStackRegs, idx,0)) != NULL ) {
1022 debugLog ("Found a Stack Register!\n");
1023 } else if( (dReg = regWithIdx ( dynProcessorRegs, idx,0)) != NULL ) {
1024 debugLog ("Found a Processor Register!\n");
1025 } else if( (dReg = regWithIdx ( dynInternalRegs, idx,0)) != NULL ) {
1026 debugLog ("Found an Internal Register!\n");
1027 } else if( (dReg = regWithIdx ( dynInternalRegs, idx,1)) != NULL ) {
1028 debugLog ("Found an Internal Register!\n");
1031 debugLog ("Dynamic Register not found\n");
1034 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
1035 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1036 "regWithIdx not found");
1046 /*-----------------------------------------------------------------*/
1047 /*-----------------------------------------------------------------*/
1049 pic14_findFreeReg(short type)
1056 if((dReg = regFindFree(dynAllocRegs)) != NULL)
1058 return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
1062 if((dReg = regFindFree(dynStackRegs)) != NULL)
1074 /*-----------------------------------------------------------------*/
1075 /* freeReg - frees a register */
1076 /*-----------------------------------------------------------------*/
1078 freeReg (regs * reg)
1080 debugLog ("%s\n", __FUNCTION__);
1085 /*-----------------------------------------------------------------*/
1086 /* nFreeRegs - returns number of free registers */
1087 /*-----------------------------------------------------------------*/
1089 nFreeRegs (int type)
1091 /* dynamically allocate as many as we need and worry about
1092 * fitting them into a PIC later */
1099 debugLog ("%s\n", __FUNCTION__);
1100 for (i = 0; i < pic14_nRegs; i++)
1101 if (regspic14[i].isFree && regspic14[i].type == type)
1107 /*-----------------------------------------------------------------*/
1108 /* nfreeRegsType - free registers with type */
1109 /*-----------------------------------------------------------------*/
1111 nfreeRegsType (int type)
1114 debugLog ("%s\n", __FUNCTION__);
1115 if (type == REG_PTR)
1117 if ((nfr = nFreeRegs (type)) == 0)
1118 return nFreeRegs (REG_GPR);
1121 return nFreeRegs (type);
1124 void writeSetUsedRegs(FILE *of, set *dRegs)
1129 for (dReg = setFirstItem(dRegs) ; dReg ;
1130 dReg = setNextItem(dRegs)) {
1133 fprintf (of, "\t%s\n",dReg->name);
1137 extern void assignFixedRegisters(set *regset);
1138 extern void assignRelocatableRegisters(set *regset,int used);
1139 extern void dump_map(void);
1140 extern void dump_sfr(FILE *of);
1142 void packBits(set *bregs)
1146 regs *bitfield=NULL;
1147 regs *relocbitfield=NULL;
1153 for (regset = bregs ; regset ;
1154 regset = regset->next) {
1156 breg = regset->item;
1157 breg->isBitField = 1;
1158 //fprintf(stderr,"bit reg: %s\n",breg->name);
1161 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
1163 bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1);
1164 breg->rIdx = breg->address & 7;
1165 breg->address >>= 3;
1168 //sprintf (buffer, "fbitfield%02x", breg->address);
1169 sprintf (buffer, "0x%02x", breg->address);
1170 //fprintf(stderr,"new bit field\n");
1171 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0);
1172 bitfield->isBitField = 1;
1173 bitfield->isFixed = 1;
1174 bitfield->address = breg->address;
1175 //addSet(&dynDirectRegs,bitfield);
1176 addSet(&dynInternalRegs,bitfield);
1177 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
1179 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
1182 breg->reg_alias = bitfield;
1186 if(!relocbitfield || bit_no >7) {
1189 sprintf (buffer, "bitfield%d", byte_no);
1190 //fprintf(stderr,"new relocatable bit field\n");
1191 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0);
1192 relocbitfield->isBitField = 1;
1193 //addSet(&dynDirectRegs,relocbitfield);
1194 addSet(&dynInternalRegs,relocbitfield);
1195 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1199 breg->reg_alias = relocbitfield;
1200 breg->address = rDirectIdx; /* byte_no; */
1201 breg->rIdx = bit_no++;
1209 void bitEQUs(FILE *of, set *bregs)
1211 regs *breg,*bytereg;
1214 //fprintf(stderr," %s\n",__FUNCTION__);
1215 for (breg = setFirstItem(bregs) ; breg ;
1216 breg = setNextItem(bregs)) {
1218 //fprintf(stderr,"bit reg: %s\n",breg->name);
1220 bytereg = breg->reg_alias;
1222 fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
1225 breg->rIdx & 0x0007);
1228 //fprintf(stderr, "bit field is not assigned to a register\n");
1229 fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
1239 void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
1244 for (reg = setFirstItem(fregs) ; reg ;
1245 reg = setNextItem(fregs)) {
1247 //if(!reg->isEmitted && reg->wasUsed) {
1250 fprintf (of, "%s\tEQU\t0x%03x\n",
1254 fprintf (of, "%s\tEQU\t0x%03x\n",
1262 void writeUsedRegs(FILE *of)
1264 packBits(dynDirectBitRegs);
1266 assignFixedRegisters(dynInternalRegs);
1267 assignFixedRegisters(dynAllocRegs);
1268 assignFixedRegisters(dynStackRegs);
1269 assignFixedRegisters(dynDirectRegs);
1271 assignRelocatableRegisters(dynInternalRegs,0);
1272 assignRelocatableRegisters(dynAllocRegs,0);
1273 assignRelocatableRegisters(dynStackRegs,0);
1276 assignRelocatableRegisters(dynDirectRegs,0);
1277 printf("assignRelocatableRegisters(dynDirectRegs,0);\n");
1282 bitEQUs(of,dynDirectBitRegs);
1284 aliasEQUs(of,dynAllocRegs,0);
1285 aliasEQUs(of,dynDirectRegs,0);
1286 aliasEQUs(of,dynStackRegs,0);
1287 aliasEQUs(of,dynProcessorRegs,1);
1292 /*-----------------------------------------------------------------*/
1293 /* allDefsOutOfRange - all definitions are out of a range */
1294 /*-----------------------------------------------------------------*/
1296 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
1300 debugLog ("%s\n", __FUNCTION__);
1304 for (i = 0; i < defs->size; i++)
1308 if (bitVectBitValue (defs, i) &&
1309 (ic = hTabItemWithKey (iCodehTab, i)) &&
1310 (ic->seq >= fseq && ic->seq <= toseq))
1320 /*-----------------------------------------------------------------*/
1321 /* computeSpillable - given a point find the spillable live ranges */
1322 /*-----------------------------------------------------------------*/
1324 computeSpillable (iCode * ic)
1328 debugLog ("%s\n", __FUNCTION__);
1329 /* spillable live ranges are those that are live at this
1330 point . the following categories need to be subtracted
1332 a) - those that are already spilt
1333 b) - if being used by this one
1334 c) - defined by this one */
1336 spillable = bitVectCopy (ic->rlive);
1338 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1340 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1341 bitVectUnSetBit (spillable, ic->defKey);
1342 spillable = bitVectIntersect (spillable, _G.regAssigned);
1347 /*-----------------------------------------------------------------*/
1348 /* noSpilLoc - return true if a variable has no spil location */
1349 /*-----------------------------------------------------------------*/
1351 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1353 debugLog ("%s\n", __FUNCTION__);
1354 return (sym->usl.spillLoc ? 0 : 1);
1357 /*-----------------------------------------------------------------*/
1358 /* hasSpilLoc - will return 1 if the symbol has spil location */
1359 /*-----------------------------------------------------------------*/
1361 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1363 debugLog ("%s\n", __FUNCTION__);
1364 return (sym->usl.spillLoc ? 1 : 0);
1367 /*-----------------------------------------------------------------*/
1368 /* directSpilLoc - will return 1 if the splilocation is in direct */
1369 /*-----------------------------------------------------------------*/
1371 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1373 debugLog ("%s\n", __FUNCTION__);
1374 if (sym->usl.spillLoc &&
1375 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1381 /*-----------------------------------------------------------------*/
1382 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1383 /* but is not used as a pointer */
1384 /*-----------------------------------------------------------------*/
1386 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1388 debugLog ("%s\n", __FUNCTION__);
1389 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1392 /*-----------------------------------------------------------------*/
1393 /* rematable - will return 1 if the remat flag is set */
1394 /*-----------------------------------------------------------------*/
1396 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1398 debugLog ("%s\n", __FUNCTION__);
1402 /*-----------------------------------------------------------------*/
1403 /* notUsedInRemaining - not used or defined in remain of the block */
1404 /*-----------------------------------------------------------------*/
1406 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1408 debugLog ("%s\n", __FUNCTION__);
1409 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1410 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1413 /*-----------------------------------------------------------------*/
1414 /* allLRs - return true for all */
1415 /*-----------------------------------------------------------------*/
1417 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1419 debugLog ("%s\n", __FUNCTION__);
1423 /*-----------------------------------------------------------------*/
1424 /* liveRangesWith - applies function to a given set of live range */
1425 /*-----------------------------------------------------------------*/
1427 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1428 eBBlock * ebp, iCode * ic)
1433 debugLog ("%s\n", __FUNCTION__);
1434 if (!lrs || !lrs->size)
1437 for (i = 1; i < lrs->size; i++)
1440 if (!bitVectBitValue (lrs, i))
1443 /* if we don't find it in the live range
1444 hash table we are in serious trouble */
1445 if (!(sym = hTabItemWithKey (liveRanges, i)))
1447 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1448 "liveRangesWith could not find liveRange");
1452 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1453 addSetHead (&rset, sym);
1460 /*-----------------------------------------------------------------*/
1461 /* leastUsedLR - given a set determines which is the least used */
1462 /*-----------------------------------------------------------------*/
1464 leastUsedLR (set * sset)
1466 symbol *sym = NULL, *lsym = NULL;
1468 debugLog ("%s\n", __FUNCTION__);
1469 sym = lsym = setFirstItem (sset);
1474 for (; lsym; lsym = setNextItem (sset))
1477 /* if usage is the same then prefer
1478 the spill the smaller of the two */
1479 if (lsym->used == sym->used)
1480 if (getSize (lsym->type) < getSize (sym->type))
1484 if (lsym->used < sym->used)
1489 setToNull ((void *) &sset);
1494 /*-----------------------------------------------------------------*/
1495 /* noOverLap - will iterate through the list looking for over lap */
1496 /*-----------------------------------------------------------------*/
1498 noOverLap (set * itmpStack, symbol * fsym)
1501 debugLog ("%s\n", __FUNCTION__);
1504 for (sym = setFirstItem (itmpStack); sym;
1505 sym = setNextItem (itmpStack))
1507 if (sym->liveTo > fsym->liveFrom)
1515 /*-----------------------------------------------------------------*/
1516 /* isFree - will return 1 if the a free spil location is found */
1517 /*-----------------------------------------------------------------*/
1522 V_ARG (symbol **, sloc);
1523 V_ARG (symbol *, fsym);
1525 debugLog ("%s\n", __FUNCTION__);
1526 /* if already found */
1530 /* if it is free && and the itmp assigned to
1531 this does not have any overlapping live ranges
1532 with the one currently being assigned and
1533 the size can be accomodated */
1535 noOverLap (sym->usl.itmpStack, fsym) &&
1536 getSize (sym->type) >= getSize (fsym->type))
1545 /*-----------------------------------------------------------------*/
1546 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1547 /*-----------------------------------------------------------------*/
1549 spillLRWithPtrReg (symbol * forSym)
1555 debugLog ("%s\n", __FUNCTION__);
1556 if (!_G.regAssigned ||
1557 bitVectIsZero (_G.regAssigned))
1560 r0 = pic14_regWithIdx (R0_IDX);
1561 r1 = pic14_regWithIdx (R1_IDX);
1563 /* for all live ranges */
1564 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1565 lrsym = hTabNextItem (liveRanges, &k))
1569 /* if no registers assigned to it or
1571 /* if it does not overlap with this then
1572 not need to spill it */
1574 if (lrsym->isspilt || !lrsym->nRegs ||
1575 (lrsym->liveTo < forSym->liveFrom))
1578 /* go thru the registers : if it is either
1579 r0 or r1 then spil it */
1580 for (j = 0; j < lrsym->nRegs; j++)
1581 if (lrsym->regs[j] == r0 ||
1582 lrsym->regs[j] == r1)
1591 /*-----------------------------------------------------------------*/
1592 /* createStackSpil - create a location on the stack to spil */
1593 /*-----------------------------------------------------------------*/
1595 createStackSpil (symbol * sym)
1597 symbol *sloc = NULL;
1598 int useXstack, model, noOverlay;
1600 char slocBuffer[30];
1601 debugLog ("%s\n", __FUNCTION__);
1603 /* first go try and find a free one that is already
1604 existing on the stack */
1605 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1607 /* found a free one : just update & return */
1608 sym->usl.spillLoc = sloc;
1611 addSetHead (&sloc->usl.itmpStack, sym);
1615 /* could not then have to create one , this is the hard part
1616 we need to allocate this on the stack : this is really a
1617 hack!! but cannot think of anything better at this time */
1619 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1621 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1622 __FILE__, __LINE__);
1626 sloc = newiTemp (slocBuffer);
1628 /* set the type to the spilling symbol */
1629 sloc->type = copyLinkChain (sym->type);
1630 sloc->etype = getSpec (sloc->type);
1631 SPEC_SCLS (sloc->etype) = S_DATA;
1632 SPEC_EXTR (sloc->etype) = 0;
1633 SPEC_STAT (sloc->etype) = 0;
1635 /* we don't allow it to be allocated`
1636 onto the external stack since : so we
1637 temporarily turn it off ; we also
1638 turn off memory model to prevent
1639 the spil from going to the external storage
1640 and turn off overlaying
1643 useXstack = options.useXstack;
1644 model = options.model;
1645 noOverlay = options.noOverlay;
1646 options.noOverlay = 1;
1647 options.model = options.useXstack = 0;
1651 options.useXstack = useXstack;
1652 options.model = model;
1653 options.noOverlay = noOverlay;
1654 sloc->isref = 1; /* to prevent compiler warning */
1656 /* if it is on the stack then update the stack */
1657 if (IN_STACK (sloc->etype))
1659 currFunc->stack += getSize (sloc->type);
1660 _G.stackExtend += getSize (sloc->type);
1663 _G.dataExtend += getSize (sloc->type);
1665 /* add it to the _G.stackSpil set */
1666 addSetHead (&_G.stackSpil, sloc);
1667 sym->usl.spillLoc = sloc;
1670 /* add it to the set of itempStack set
1671 of the spill location */
1672 addSetHead (&sloc->usl.itmpStack, sym);
1676 /*-----------------------------------------------------------------*/
1677 /* isSpiltOnStack - returns true if the spil location is on stack */
1678 /*-----------------------------------------------------------------*/
1680 isSpiltOnStack (symbol * sym)
1684 debugLog ("%s\n", __FUNCTION__);
1691 /* if (sym->_G.stackSpil) */
1694 if (!sym->usl.spillLoc)
1697 etype = getSpec (sym->usl.spillLoc->type);
1698 if (IN_STACK (etype))
1704 /*-----------------------------------------------------------------*/
1705 /* spillThis - spils a specific operand */
1706 /*-----------------------------------------------------------------*/
1708 spillThis (symbol * sym)
1711 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1713 /* if this is rematerializable or has a spillLocation
1714 we are okay, else we need to create a spillLocation
1716 if (!(sym->remat || sym->usl.spillLoc))
1717 createStackSpil (sym);
1720 /* mark it has spilt & put it in the spilt set */
1722 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1724 bitVectUnSetBit (_G.regAssigned, sym->key);
1726 for (i = 0; i < sym->nRegs; i++)
1730 freeReg (sym->regs[i]);
1731 sym->regs[i] = NULL;
1734 /* if spilt on stack then free up r0 & r1
1735 if they could have been assigned to some
1737 if (!pic14_ptrRegReq && isSpiltOnStack (sym))
1740 spillLRWithPtrReg (sym);
1743 if (sym->usl.spillLoc && !sym->remat)
1744 sym->usl.spillLoc->allocreq = 1;
1748 /*-----------------------------------------------------------------*/
1749 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1750 /*-----------------------------------------------------------------*/
1752 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1754 bitVect *lrcs = NULL;
1758 debugLog ("%s\n", __FUNCTION__);
1759 /* get the spillable live ranges */
1760 lrcs = computeSpillable (ic);
1762 /* get all live ranges that are rematerizable */
1763 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1766 /* return the least used of these */
1767 return leastUsedLR (selectS);
1770 /* get live ranges with spillLocations in direct space */
1771 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1773 sym = leastUsedLR (selectS);
1774 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1775 sym->usl.spillLoc->rname :
1776 sym->usl.spillLoc->name));
1778 /* mark it as allocation required */
1779 sym->usl.spillLoc->allocreq = 1;
1783 /* if the symbol is local to the block then */
1784 if (forSym->liveTo < ebp->lSeq)
1787 /* check if there are any live ranges allocated
1788 to registers that are not used in this block */
1789 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1791 sym = leastUsedLR (selectS);
1792 /* if this is not rematerializable */
1801 /* check if there are any live ranges that not
1802 used in the remainder of the block */
1803 if (!_G.blockSpil &&
1804 !isiCodeInFunctionCall (ic) &&
1805 (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1807 sym = leastUsedLR (selectS);
1810 sym->remainSpil = 1;
1817 /* find live ranges with spillocation && not used as pointers */
1818 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1821 sym = leastUsedLR (selectS);
1822 /* mark this as allocation required */
1823 sym->usl.spillLoc->allocreq = 1;
1827 /* find live ranges with spillocation */
1828 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1831 sym = leastUsedLR (selectS);
1832 sym->usl.spillLoc->allocreq = 1;
1836 /* couldn't find then we need to create a spil
1837 location on the stack , for which one? the least
1839 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1842 /* return a created spil location */
1843 sym = createStackSpil (leastUsedLR (selectS));
1844 sym->usl.spillLoc->allocreq = 1;
1848 /* this is an extreme situation we will spill
1849 this one : happens very rarely but it does happen */
1855 /*-----------------------------------------------------------------*/
1856 /* spilSomething - spil some variable & mark registers as free */
1857 /*-----------------------------------------------------------------*/
1859 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1864 debugLog ("%s\n", __FUNCTION__);
1865 /* get something we can spil */
1866 ssym = selectSpil (ic, ebp, forSym);
1868 /* mark it as spilt */
1870 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1872 /* mark it as not register assigned &
1873 take it away from the set */
1874 bitVectUnSetBit (_G.regAssigned, ssym->key);
1876 /* mark the registers as free */
1877 for (i = 0; i < ssym->nRegs; i++)
1879 freeReg (ssym->regs[i]);
1881 /* if spilt on stack then free up r0 & r1
1882 if they could have been assigned to as gprs */
1883 if (!pic14_ptrRegReq && isSpiltOnStack (ssym))
1886 spillLRWithPtrReg (ssym);
1889 /* if this was a block level spil then insert push & pop
1890 at the start & end of block respectively */
1891 if (ssym->blockSpil)
1893 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1894 /* add push to the start of the block */
1895 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1896 ebp->sch->next : ebp->sch));
1897 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1898 /* add pop to the end of the block */
1899 addiCodeToeBBlock (ebp, nic, NULL);
1902 /* if spilt because not used in the remainder of the
1903 block then add a push before this instruction and
1904 a pop at the end of the block */
1905 if (ssym->remainSpil)
1908 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1909 /* add push just before this instruction */
1910 addiCodeToeBBlock (ebp, nic, ic);
1912 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1913 /* add pop to the end of the block */
1914 addiCodeToeBBlock (ebp, nic, NULL);
1923 /*-----------------------------------------------------------------*/
1924 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1925 /*-----------------------------------------------------------------*/
1927 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1932 debugLog ("%s\n", __FUNCTION__);
1934 /* try for a ptr type */
1935 if ((reg = allocReg (REG_PTR)))
1938 /* try for gpr type */
1939 if ((reg = allocReg (REG_GPR)))
1942 /* we have to spil */
1943 if (!spilSomething (ic, ebp, sym))
1946 /* make sure partially assigned registers aren't reused */
1947 for (j=0; j<=sym->nRegs; j++)
1949 sym->regs[j]->isFree = 0;
1951 /* this looks like an infinite loop but
1952 in really selectSpil will abort */
1956 /*-----------------------------------------------------------------*/
1957 /* getRegGpr - will try for GPR if not spil */
1958 /*-----------------------------------------------------------------*/
1960 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1965 debugLog ("%s\n", __FUNCTION__);
1967 /* try for gpr type */
1968 if ((reg = allocReg (REG_GPR)))
1971 if (!pic14_ptrRegReq)
1972 if ((reg = allocReg (REG_PTR)))
1975 /* we have to spil */
1976 if (!spilSomething (ic, ebp, sym))
1979 /* make sure partially assigned registers aren't reused */
1980 for (j=0; j<=sym->nRegs; j++)
1982 sym->regs[j]->isFree = 0;
1984 /* this looks like an infinite loop but
1985 in really selectSpil will abort */
1989 /*-----------------------------------------------------------------*/
1990 /* symHasReg - symbol has a given register */
1991 /*-----------------------------------------------------------------*/
1993 symHasReg (symbol * sym, regs * reg)
1997 debugLog ("%s\n", __FUNCTION__);
1998 for (i = 0; i < sym->nRegs; i++)
1999 if (sym->regs[i] == reg)
2005 /*-----------------------------------------------------------------*/
2006 /* deassignLRs - check the live to and if they have registers & are */
2007 /* not spilt then free up the registers */
2008 /*-----------------------------------------------------------------*/
2010 deassignLRs (iCode * ic, eBBlock * ebp)
2016 debugLog ("%s\n", __FUNCTION__);
2017 for (sym = hTabFirstItem (liveRanges, &k); sym;
2018 sym = hTabNextItem (liveRanges, &k))
2021 symbol *psym = NULL;
2022 /* if it does not end here */
2023 if (sym->liveTo > ic->seq)
2026 /* if it was spilt on stack then we can
2027 mark the stack spil location as free */
2032 sym->usl.spillLoc->isFree = 1;
2038 if (!bitVectBitValue (_G.regAssigned, sym->key))
2041 /* special case check if this is an IFX &
2042 the privious one was a pop and the
2043 previous one was not spilt then keep track
2045 if (ic->op == IFX && ic->prev &&
2046 ic->prev->op == IPOP &&
2047 !ic->prev->parmPush &&
2048 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
2049 psym = OP_SYMBOL (IC_LEFT (ic->prev));
2055 bitVectUnSetBit (_G.regAssigned, sym->key);
2057 /* if the result of this one needs registers
2058 and does not have it then assign it right
2060 if (IC_RESULT (ic) &&
2061 !(SKIP_IC2 (ic) || /* not a special icode */
2062 ic->op == JUMPTABLE ||
2067 POINTER_SET (ic)) &&
2068 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
2069 result->liveTo > ic->seq && /* and will live beyond this */
2070 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
2071 result->liveFrom == ic->seq && /* does not start before here */
2072 result->regType == sym->regType && /* same register types */
2073 result->regType == sym->regType && /* same register types */
2074 result->nRegs && /* which needs registers */
2075 !result->isspilt && /* and does not already have them */
2077 !bitVectBitValue (_G.regAssigned, result->key) &&
2078 /* the number of free regs + number of regs in this LR
2079 can accomodate the what result Needs */
2080 ((nfreeRegsType (result->regType) +
2081 sym->nRegs) >= result->nRegs)
2085 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
2087 result->regs[i] = sym->regs[i];
2089 result->regs[i] = getRegGpr (ic, ebp, result);
2091 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
2095 /* free the remaining */
2096 for (; i < sym->nRegs; i++)
2100 if (!symHasReg (psym, sym->regs[i]))
2101 freeReg (sym->regs[i]);
2104 freeReg (sym->regs[i]);
2111 /*-----------------------------------------------------------------*/
2112 /* reassignLR - reassign this to registers */
2113 /*-----------------------------------------------------------------*/
2115 reassignLR (operand * op)
2117 symbol *sym = OP_SYMBOL (op);
2120 debugLog ("%s\n", __FUNCTION__);
2121 /* not spilt any more */
2122 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
2123 bitVectUnSetBit (_G.spiltSet, sym->key);
2125 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2129 for (i = 0; i < sym->nRegs; i++)
2130 sym->regs[i]->isFree = 0;
2133 /*-----------------------------------------------------------------*/
2134 /* willCauseSpill - determines if allocating will cause a spill */
2135 /*-----------------------------------------------------------------*/
2137 willCauseSpill (int nr, int rt)
2139 debugLog ("%s\n", __FUNCTION__);
2140 /* first check if there are any avlb registers
2141 of te type required */
2144 /* special case for pointer type
2145 if pointer type not avlb then
2146 check for type gpr */
2147 if (nFreeRegs (rt) >= nr)
2149 if (nFreeRegs (REG_GPR) >= nr)
2154 if (pic14_ptrRegReq)
2156 if (nFreeRegs (rt) >= nr)
2161 if (nFreeRegs (REG_PTR) +
2162 nFreeRegs (REG_GPR) >= nr)
2167 debugLog (" ... yep it will (cause a spill)\n");
2168 /* it will cause a spil */
2172 /*-----------------------------------------------------------------*/
2173 /* positionRegs - the allocator can allocate same registers to res- */
2174 /* ult and operand, if this happens make sure they are in the same */
2175 /* position as the operand otherwise chaos results */
2176 /*-----------------------------------------------------------------*/
2178 positionRegs (symbol * result, symbol * opsym, int lineno)
2180 int count = min (result->nRegs, opsym->nRegs);
2181 int i, j = 0, shared = 0;
2183 debugLog ("%s\n", __FUNCTION__);
2184 /* if the result has been spilt then cannot share */
2189 /* first make sure that they actually share */
2190 for (i = 0; i < count; i++)
2192 for (j = 0; j < count; j++)
2194 if (result->regs[i] == opsym->regs[j] && i != j)
2204 regs *tmp = result->regs[i];
2205 result->regs[i] = result->regs[j];
2206 result->regs[j] = tmp;
2211 /*------------------------------------------------------------------*/
2212 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2213 /* it should either have registers or have beed spilled. Otherwise, */
2214 /* there was an uninitialized variable, so just spill this to get */
2215 /* the operand in a valid state. */
2216 /*------------------------------------------------------------------*/
2218 verifyRegsAssigned (operand *op, iCode * ic)
2223 if (!IS_ITEMP (op)) return;
2225 sym = OP_SYMBOL (op);
2226 if (sym->isspilt) return;
2227 if (!sym->nRegs) return;
2228 if (sym->regs[0]) return;
2230 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
2231 sym->prereqv ? sym->prereqv->name : sym->name);
2236 /*-----------------------------------------------------------------*/
2237 /* serialRegAssign - serially allocate registers to the variables */
2238 /*-----------------------------------------------------------------*/
2240 serialRegAssign (eBBlock ** ebbs, int count)
2244 debugLog ("%s\n", __FUNCTION__);
2245 /* for all blocks */
2246 for (i = 0; i < count; i++)
2251 if (ebbs[i]->noPath &&
2252 (ebbs[i]->entryLabel != entryLabel &&
2253 ebbs[i]->entryLabel != returnLabel))
2256 /* of all instructions do */
2257 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2260 debugLog (" op: %s\n", decodeOp (ic->op));
2262 /* if this is an ipop that means some live
2263 range will have to be assigned again */
2265 reassignLR (IC_LEFT (ic));
2267 /* if result is present && is a true symbol */
2268 if (IC_RESULT (ic) && ic->op != IFX &&
2269 IS_TRUE_SYMOP (IC_RESULT (ic)))
2270 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2272 /* take away registers from live
2273 ranges that end at this instruction */
2274 deassignLRs (ic, ebbs[i]);
2276 /* some don't need registers */
2277 if (SKIP_IC2 (ic) ||
2278 ic->op == JUMPTABLE ||
2282 (IC_RESULT (ic) && POINTER_SET (ic)))
2285 /* now we need to allocate registers
2286 only for the result */
2289 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2295 /* Make sure any spill location is definately allocated */
2296 if (sym->isspilt && !sym->remat && sym->usl.spillLoc &&
2297 !sym->usl.spillLoc->allocreq)
2299 sym->usl.spillLoc->allocreq++;
2302 /* if it does not need or is spilt
2303 or is already assigned to registers
2304 or will not live beyond this instructions */
2307 bitVectBitValue (_G.regAssigned, sym->key) ||
2308 sym->liveTo <= ic->seq)
2311 /* if some liverange has been spilt at the block level
2312 and this one live beyond this block then spil this
2314 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2319 /* if trying to allocate this will cause
2320 a spill and there is nothing to spill
2321 or this one is rematerializable then
2323 willCS = willCauseSpill (sym->nRegs, sym->regType);
2324 spillable = computeSpillable (ic);
2326 (willCS && bitVectIsZero (spillable)))
2334 /* If the live range preceeds the point of definition
2335 then ideally we must take into account registers that
2336 have been allocated after sym->liveFrom but freed
2337 before ic->seq. This is complicated, so spill this
2338 symbol instead and let fillGaps handle the allocation. */
2339 if (sym->liveFrom < ic->seq)
2345 /* if it has a spillocation & is used less than
2346 all other live ranges then spill this */
2348 if (sym->usl.spillLoc) {
2349 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2350 allLRs, ebbs[i], ic));
2351 if (leastUsed && leastUsed->used > sym->used) {
2356 /* if none of the liveRanges have a spillLocation then better
2357 to spill this one than anything else already assigned to registers */
2358 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2359 /* if this is local to this block then we might find a block spil */
2360 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2368 if (ic->op == RECEIVE)
2369 debugLog ("When I get clever, I'll optimize the receive logic\n");
2371 /* if we need ptr regs for the right side
2373 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2374 <= (unsigned) PTRSIZE)
2379 /* else we assign registers to it */
2380 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2382 debugLog (" %d - \n", __LINE__);
2384 bitVectDebugOn(_G.regAssigned, debugF);
2385 for (j = 0; j < sym->nRegs; j++)
2387 if (sym->regType == REG_PTR)
2388 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2390 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2392 /* if the allocation failed which means
2393 this was spilt then break */
2397 debugLog (" %d - \n", __LINE__);
2399 /* if it shares registers with operands make sure
2400 that they are in the same position */
2401 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2402 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2403 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2404 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2405 /* do the same for the right operand */
2406 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2407 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2408 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2409 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2411 debugLog (" %d - \n", __LINE__);
2414 debugLog (" %d - \n", __LINE__);
2423 /* Check for and fix any problems with uninitialized operands */
2424 for (i = 0; i < count; i++)
2428 if (ebbs[i]->noPath &&
2429 (ebbs[i]->entryLabel != entryLabel &&
2430 ebbs[i]->entryLabel != returnLabel))
2433 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2440 verifyRegsAssigned (IC_COND (ic), ic);
2444 if (ic->op == JUMPTABLE)
2446 verifyRegsAssigned (IC_JTCOND (ic), ic);
2450 verifyRegsAssigned (IC_RESULT (ic), ic);
2451 verifyRegsAssigned (IC_LEFT (ic), ic);
2452 verifyRegsAssigned (IC_RIGHT (ic), ic);
2458 /*-----------------------------------------------------------------*/
2459 /* rUmaskForOp :- returns register mask for an operand */
2460 /*-----------------------------------------------------------------*/
2462 rUmaskForOp (operand * op)
2468 debugLog ("%s\n", __FUNCTION__);
2469 /* only temporaries are assigned registers */
2473 sym = OP_SYMBOL (op);
2475 /* if spilt or no registers assigned to it
2477 if (sym->isspilt || !sym->nRegs)
2480 rumask = newBitVect (pic14_nRegs);
2482 for (j = 0; j < sym->nRegs; j++)
2484 rumask = bitVectSetBit (rumask,
2485 sym->regs[j]->rIdx);
2491 /*-----------------------------------------------------------------*/
2492 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2493 /*-----------------------------------------------------------------*/
2495 regsUsedIniCode (iCode * ic)
2497 bitVect *rmask = newBitVect (pic14_nRegs);
2499 debugLog ("%s\n", __FUNCTION__);
2500 /* do the special cases first */
2503 rmask = bitVectUnion (rmask,
2504 rUmaskForOp (IC_COND (ic)));
2508 /* for the jumptable */
2509 if (ic->op == JUMPTABLE)
2511 rmask = bitVectUnion (rmask,
2512 rUmaskForOp (IC_JTCOND (ic)));
2517 /* of all other cases */
2519 rmask = bitVectUnion (rmask,
2520 rUmaskForOp (IC_LEFT (ic)));
2524 rmask = bitVectUnion (rmask,
2525 rUmaskForOp (IC_RIGHT (ic)));
2528 rmask = bitVectUnion (rmask,
2529 rUmaskForOp (IC_RESULT (ic)));
2535 /*-----------------------------------------------------------------*/
2536 /* createRegMask - for each instruction will determine the regsUsed */
2537 /*-----------------------------------------------------------------*/
2539 createRegMask (eBBlock ** ebbs, int count)
2543 debugLog ("%s\n", __FUNCTION__);
2544 /* for all blocks */
2545 for (i = 0; i < count; i++)
2549 if (ebbs[i]->noPath &&
2550 (ebbs[i]->entryLabel != entryLabel &&
2551 ebbs[i]->entryLabel != returnLabel))
2554 /* for all instructions */
2555 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2560 if (SKIP_IC2 (ic) || !ic->rlive)
2563 /* first mark the registers used in this
2565 ic->rUsed = regsUsedIniCode (ic);
2566 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2568 /* now create the register mask for those
2569 registers that are in use : this is a
2570 super set of ic->rUsed */
2571 ic->rMask = newBitVect (pic14_nRegs + 1);
2573 /* for all live Ranges alive at this point */
2574 for (j = 1; j < ic->rlive->size; j++)
2579 /* if not alive then continue */
2580 if (!bitVectBitValue (ic->rlive, j))
2583 /* find the live range we are interested in */
2584 if (!(sym = hTabItemWithKey (liveRanges, j)))
2586 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2587 "createRegMask cannot find live range");
2591 /* if no register assigned to it */
2592 if (!sym->nRegs || sym->isspilt)
2595 /* for all the registers allocated to it */
2596 for (k = 0; k < sym->nRegs; k++)
2599 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2605 /*-----------------------------------------------------------------*/
2606 /* rematStr - returns the rematerialized string for a remat var */
2607 /*-----------------------------------------------------------------*/
2609 rematStr (symbol * sym)
2612 iCode *ic = sym->rematiCode;
2613 symbol *psym = NULL;
2615 debugLog ("%s\n", __FUNCTION__);
2617 //printf ("%s\n", s);
2619 /* if plus or minus print the right hand side */
2621 if (ic->op == '+' || ic->op == '-') {
2623 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2625 sprintf (s, "(%s %c 0x%04x)",
2626 OP_SYMBOL (IC_LEFT (ric))->rname,
2628 (int) operandLitValue (IC_RIGHT (ic)));
2631 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2633 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2634 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2639 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2640 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2642 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2647 /*-----------------------------------------------------------------*/
2648 /* rematStr - returns the rematerialized string for a remat var */
2649 /*-----------------------------------------------------------------*/
2651 rematStr (symbol * sym)
2654 iCode *ic = sym->rematiCode;
2656 debugLog ("%s\n", __FUNCTION__);
2661 /* if plus or minus print the right hand side */
2663 if (ic->op == '+' || ic->op == '-') {
2664 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2667 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2671 if (ic->op == '+' || ic->op == '-')
2673 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2674 sprintf (s, "(%s %c 0x%04x)",
2675 OP_SYMBOL (IC_LEFT (ric))->rname,
2677 (int) operandLitValue (IC_RIGHT (ic)));
2680 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2682 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2686 /* we reached the end */
2687 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2691 printf ("%s\n", buffer);
2696 /*-----------------------------------------------------------------*/
2697 /* regTypeNum - computes the type & number of registers required */
2698 /*-----------------------------------------------------------------*/
2706 debugLog ("%s\n", __FUNCTION__);
2707 /* for each live range do */
2708 for (sym = hTabFirstItem (liveRanges, &k); sym;
2709 sym = hTabNextItem (liveRanges, &k)) {
2711 debugLog (" %d - %s\n", __LINE__, sym->rname);
2713 /* if used zero times then no registers needed */
2714 if ((sym->liveTo - sym->liveFrom) == 0)
2718 /* if the live range is a temporary */
2721 debugLog (" %d - itemp register\n", __LINE__);
2723 /* if the type is marked as a conditional */
2724 if (sym->regType == REG_CND)
2727 /* if used in return only then we don't
2730 if (IS_AGGREGATE (sym->type) || sym->isptr)
2731 sym->type = aggrToPtr (sym->type, FALSE);
2732 debugLog (" %d - no reg needed - accumulator used\n", __LINE__);
2738 //if (IS_AGGREGATE (sym->type) || sym->isptr)
2739 // sym->type = aggrToPtr (sym->type, FALSE);
2740 debugLog (" %d - used as a return\n", __LINE__);
2745 /* if the symbol has only one definition &
2746 that definition is a get_pointer and the
2747 pointer we are getting is rematerializable and
2750 if (bitVectnBitsOn (sym->defs) == 1 &&
2751 (ic = hTabItemWithKey (iCodehTab,
2752 bitVectFirstBit (sym->defs))) &&
2754 !IS_BITVAR (sym->etype) &&
2755 (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
2757 if (ptrPseudoSymSafe (sym, ic)) {
2761 debugLog (" %d - \n", __LINE__);
2763 /* create a psuedo symbol & force a spil */
2764 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2765 psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2766 psym->type = sym->type;
2767 psym->etype = sym->etype;
2768 psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
2769 strcpy (psym->rname, psym->name);
2771 sym->usl.spillLoc = psym;
2775 /* if in data space or idata space then try to
2776 allocate pointer register */
2780 /* if not then we require registers */
2781 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2782 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2783 getSize (sym->type));
2786 if(IS_PTR_CONST (sym->type)) {
2787 debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2791 if (sym->nRegs > 4) {
2792 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2793 printTypeChain (sym->type, stderr);
2794 fprintf (stderr, "\n");
2797 /* determine the type of register required */
2798 if (sym->nRegs == 1 &&
2799 IS_PTR (sym->type) &&
2801 sym->regType = REG_PTR;
2803 sym->regType = REG_GPR;
2806 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2810 /* for the first run we don't provide */
2811 /* registers for true symbols we will */
2812 /* see how things go */
2817 DEFSETFUNC (markRegFree)
2819 ((regs *)item)->isFree = 1;
2824 DEFSETFUNC (deallocReg)
2826 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2827 ((regs *)item)->isFree = 1;
2828 ((regs *)item)->wasUsed = 0;
2832 /*-----------------------------------------------------------------*/
2833 /* freeAllRegs - mark all registers as free */
2834 /*-----------------------------------------------------------------*/
2836 pic14_freeAllRegs ()
2840 debugLog ("%s\n", __FUNCTION__);
2842 applyToSet(dynAllocRegs,markRegFree);
2843 applyToSet(dynStackRegs,markRegFree);
2846 for (i = 0; i < pic14_nRegs; i++)
2847 regspic14[i].isFree = 1;
2851 /*-----------------------------------------------------------------*/
2852 /*-----------------------------------------------------------------*/
2854 pic14_deallocateAllRegs ()
2858 debugLog ("%s\n", __FUNCTION__);
2860 applyToSet(dynAllocRegs,deallocReg);
2863 for (i = 0; i < pic14_nRegs; i++) {
2864 if(regspic14[i].pc_type == PO_GPR_TEMP) {
2865 regspic14[i].isFree = 1;
2866 regspic14[i].wasUsed = 0;
2873 /*-----------------------------------------------------------------*/
2874 /* deallocStackSpil - this will set the stack pointer back */
2875 /*-----------------------------------------------------------------*/
2877 DEFSETFUNC (deallocStackSpil)
2881 debugLog ("%s\n", __FUNCTION__);
2886 /*-----------------------------------------------------------------*/
2887 /* farSpacePackable - returns the packable icode for far variables */
2888 /*-----------------------------------------------------------------*/
2890 farSpacePackable (iCode * ic)
2894 debugLog ("%s\n", __FUNCTION__);
2895 /* go thru till we find a definition for the
2896 symbol on the right */
2897 for (dic = ic->prev; dic; dic = dic->prev)
2900 /* if the definition is a call then no */
2901 if ((dic->op == CALL || dic->op == PCALL) &&
2902 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2907 /* if shift by unknown amount then not */
2908 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2909 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2912 /* if pointer get and size > 1 */
2913 if (POINTER_GET (dic) &&
2914 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2917 if (POINTER_SET (dic) &&
2918 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2921 /* if any three is a true symbol in far space */
2922 if (IC_RESULT (dic) &&
2923 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2924 isOperandInFarSpace (IC_RESULT (dic)))
2927 if (IC_RIGHT (dic) &&
2928 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2929 isOperandInFarSpace (IC_RIGHT (dic)) &&
2930 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2933 if (IC_LEFT (dic) &&
2934 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2935 isOperandInFarSpace (IC_LEFT (dic)) &&
2936 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2939 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2941 if ((dic->op == LEFT_OP ||
2942 dic->op == RIGHT_OP ||
2944 IS_OP_LITERAL (IC_RIGHT (dic)))
2954 /*-----------------------------------------------------------------*/
2955 /* packRegsForAssign - register reduction for assignment */
2956 /*-----------------------------------------------------------------*/
2958 packRegsForAssign (iCode * ic, eBBlock * ebp)
2963 debugLog ("%s\n", __FUNCTION__);
2965 debugAopGet (" result:", IC_RESULT (ic));
2966 debugAopGet (" left:", IC_LEFT (ic));
2967 debugAopGet (" right:", IC_RIGHT (ic));
2969 /* if this is at an absolute address, then get the address. */
2970 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2971 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2972 debugLog (" %d - found config word declaration\n", __LINE__);
2973 if(IS_VALOP(IC_RIGHT(ic))) {
2974 debugLog (" setting config word to %x\n",
2975 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2976 assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2977 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2980 /* remove the assignment from the iCode chain. */
2982 remiCodeFromeBBlock (ebp, ic);
2983 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2984 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2991 if (!IS_ITEMP (IC_RESULT (ic))) {
2992 allocDirReg(IC_RESULT (ic));
2993 debugLog (" %d - result is not temp\n", __LINE__);
2996 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2997 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2998 allocDirReg(IC_LEFT (ic));
3002 if (!IS_ITEMP (IC_RIGHT (ic))) {
3003 debugLog (" %d - not packing - right is not temp\n", __LINE__);
3005 /* only pack if this is not a function pointer */
3006 if (!IS_REF (IC_RIGHT (ic)))
3007 allocDirReg(IC_RIGHT (ic));
3011 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
3012 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
3014 debugLog (" %d - not packing - right side fails \n", __LINE__);
3018 /* if the true symbol is defined in far space or on stack
3019 then we should not since this will increase register pressure */
3020 if (isOperandInFarSpace (IC_RESULT (ic)))
3022 if ((dic = farSpacePackable (ic)))
3028 /* find the definition of iTempNN scanning backwards if we find a
3029 a use of the true symbol before we find the definition then
3031 for (dic = ic->prev; dic; dic = dic->prev)
3034 /* if there is a function call and this is
3035 a parameter & not my parameter then don't pack it */
3036 if ((dic->op == CALL || dic->op == PCALL) &&
3037 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
3038 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
3040 debugLog (" %d - \n", __LINE__);
3048 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
3049 IS_OP_VOLATILE (IC_RESULT (dic)))
3051 debugLog (" %d - dic is VOLATILE \n", __LINE__);
3056 if (IS_SYMOP (IC_RESULT (dic)) &&
3057 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
3059 /* A previous result was assigned to the same register - we'll our definition */
3060 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
3061 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
3062 if (POINTER_SET (dic))
3068 if (IS_SYMOP (IC_RIGHT (dic)) &&
3069 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
3070 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
3072 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
3077 if (IS_SYMOP (IC_LEFT (dic)) &&
3078 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
3079 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
3081 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
3086 if (POINTER_SET (dic) &&
3087 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
3089 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
3097 return 0; /* did not find */
3099 /* if the result is on stack or iaccess then it must be
3100 the same at least one of the operands */
3101 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
3102 OP_SYMBOL (IC_RESULT (ic))->iaccess)
3105 /* the operation has only one symbol
3106 operator then we can pack */
3107 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
3108 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
3111 if (!((IC_LEFT (dic) &&
3112 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
3114 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
3118 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
3119 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
3120 /* found the definition */
3121 /* replace the result with the result of */
3122 /* this assignment and remove this assignment */
3123 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3124 IC_RESULT (dic) = IC_RESULT (ic);
3126 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
3128 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
3130 /* delete from liverange table also
3131 delete from all the points inbetween and the new
3133 for (sic = dic; sic != ic; sic = sic->next)
3135 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3136 if (IS_ITEMP (IC_RESULT (dic)))
3137 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3140 remiCodeFromeBBlock (ebp, ic);
3141 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3142 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3143 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3149 /*-----------------------------------------------------------------*/
3150 /* findAssignToSym : scanning backwards looks for first assig found */
3151 /*-----------------------------------------------------------------*/
3153 findAssignToSym (operand * op, iCode * ic)
3157 debugLog ("%s\n", __FUNCTION__);
3158 for (dic = ic->prev; dic; dic = dic->prev)
3161 /* if definition by assignment */
3162 if (dic->op == '=' &&
3163 !POINTER_SET (dic) &&
3164 IC_RESULT (dic)->key == op->key
3165 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3169 /* we are interested only if defined in far space */
3170 /* or in stack space in case of + & - */
3172 /* if assigned to a non-symbol then return
3174 if (!IS_SYMOP (IC_RIGHT (dic)))
3177 /* if the symbol is in far space then
3179 if (isOperandInFarSpace (IC_RIGHT (dic)))
3182 /* for + & - operations make sure that
3183 if it is on the stack it is the same
3184 as one of the three operands */
3185 if ((ic->op == '+' || ic->op == '-') &&
3186 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3189 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3190 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3191 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3199 /* if we find an usage then we cannot delete it */
3200 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3203 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3206 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3210 /* now make sure that the right side of dic
3211 is not defined between ic & dic */
3214 iCode *sic = dic->next;
3216 for (; sic != ic; sic = sic->next)
3217 if (IC_RESULT (sic) &&
3218 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3227 /*-----------------------------------------------------------------*/
3228 /* packRegsForSupport :- reduce some registers for support calls */
3229 /*-----------------------------------------------------------------*/
3231 packRegsForSupport (iCode * ic, eBBlock * ebp)
3235 debugLog ("%s\n", __FUNCTION__);
3236 /* for the left & right operand :- look to see if the
3237 left was assigned a true symbol in far space in that
3238 case replace them */
3239 if (IS_ITEMP (IC_LEFT (ic)) &&
3240 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3242 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3248 debugAopGet ("removing left:", IC_LEFT (ic));
3250 /* found it we need to remove it from the
3252 for (sic = dic; sic != ic; sic = sic->next)
3253 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3255 IC_LEFT (ic)->operand.symOperand =
3256 IC_RIGHT (dic)->operand.symOperand;
3257 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3258 remiCodeFromeBBlock (ebp, dic);
3259 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3260 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3264 /* do the same for the right operand */
3267 IS_ITEMP (IC_RIGHT (ic)) &&
3268 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3270 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3276 /* if this is a subtraction & the result
3277 is a true symbol in far space then don't pack */
3278 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3280 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3281 if (IN_FARSPACE (SPEC_OCLS (etype)))
3285 debugAopGet ("removing right:", IC_RIGHT (ic));
3287 /* found it we need to remove it from the
3289 for (sic = dic; sic != ic; sic = sic->next)
3290 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3292 IC_RIGHT (ic)->operand.symOperand =
3293 IC_RIGHT (dic)->operand.symOperand;
3294 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3296 remiCodeFromeBBlock (ebp, dic);
3297 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3298 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3305 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3308 /*-----------------------------------------------------------------*/
3309 /* packRegsForOneuse : - will reduce some registers for single Use */
3310 /*-----------------------------------------------------------------*/
3312 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3317 debugLog ("%s\n", __FUNCTION__);
3318 /* if returning a literal then do nothing */
3322 /* only upto 2 bytes since we cannot predict
3323 the usage of b, & acc */
3324 if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
3329 /* this routine will mark the a symbol as used in one
3330 instruction use only && if the definition is local
3331 (ie. within the basic block) && has only one definition &&
3332 that definition is either a return value from a
3333 function or does not contain any variables in
3335 uses = bitVectCopy (OP_USES (op));
3336 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3337 if (!bitVectIsZero (uses)) /* has other uses */
3340 /* if it has only one defintion */
3341 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3342 return NULL; /* has more than one definition */
3344 /* get that definition */
3346 hTabItemWithKey (iCodehTab,
3347 bitVectFirstBit (OP_DEFS (op)))))
3350 /* found the definition now check if it is local */
3351 if (dic->seq < ebp->fSeq ||
3352 dic->seq > ebp->lSeq)
3353 return NULL; /* non-local */
3355 /* now check if it is the return from
3357 if (dic->op == CALL || dic->op == PCALL)
3359 if (ic->op != SEND && ic->op != RETURN &&
3360 !POINTER_SET(ic) && !POINTER_GET(ic))
3362 OP_SYMBOL (op)->ruonly = 1;
3369 /* otherwise check that the definition does
3370 not contain any symbols in far space */
3371 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3372 isOperandInFarSpace (IC_RIGHT (dic)) ||
3373 IS_OP_RUONLY (IC_LEFT (ic)) ||
3374 IS_OP_RUONLY (IC_RIGHT (ic)))
3379 /* if pointer set then make sure the pointer
3381 if (POINTER_SET (dic) &&
3382 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3385 if (POINTER_GET (dic) &&
3386 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3391 /* also make sure the intervenening instructions
3392 don't have any thing in far space */
3393 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3396 /* if there is an intervening function call then no */
3397 if (dic->op == CALL || dic->op == PCALL)
3399 /* if pointer set then make sure the pointer
3401 if (POINTER_SET (dic) &&
3402 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3405 if (POINTER_GET (dic) &&
3406 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3409 /* if address of & the result is remat then okay */
3410 if (dic->op == ADDRESS_OF &&
3411 OP_SYMBOL (IC_RESULT (dic))->remat)
3414 /* if operand has size of three or more & this
3415 operation is a '*','/' or '%' then 'b' may
3417 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3418 getSize (operandType (op)) >= 3)
3421 /* if left or right or result is in far space */
3422 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3423 isOperandInFarSpace (IC_RIGHT (dic)) ||
3424 isOperandInFarSpace (IC_RESULT (dic)) ||
3425 IS_OP_RUONLY (IC_LEFT (dic)) ||
3426 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3427 IS_OP_RUONLY (IC_RESULT (dic)))
3433 OP_SYMBOL (op)->ruonly = 1;
3438 /*-----------------------------------------------------------------*/
3439 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3440 /*-----------------------------------------------------------------*/
3442 isBitwiseOptimizable (iCode * ic)
3444 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3445 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3447 debugLog ("%s\n", __FUNCTION__);
3448 /* bitwise operations are considered optimizable
3449 under the following conditions (Jean-Louis VERN)
3461 if (IS_LITERAL (rtype) ||
3462 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3468 /*-----------------------------------------------------------------*/
3469 /* packRegsForAccUse - pack registers for acc use */
3470 /*-----------------------------------------------------------------*/
3472 packRegsForAccUse (iCode * ic)
3476 debugLog ("%s\n", __FUNCTION__);
3478 /* if this is an aggregate, e.g. a one byte char array */
3479 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3482 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3484 /* if + or - then it has to be one byte result */
3485 if ((ic->op == '+' || ic->op == '-')
3486 && getSize (operandType (IC_RESULT (ic))) > 1)
3489 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3490 /* if shift operation make sure right side is not a literal */
3491 if (ic->op == RIGHT_OP &&
3492 (isOperandLiteral (IC_RIGHT (ic)) ||
3493 getSize (operandType (IC_RESULT (ic))) > 1))
3496 if (ic->op == LEFT_OP &&
3497 (isOperandLiteral (IC_RIGHT (ic)) ||
3498 getSize (operandType (IC_RESULT (ic))) > 1))
3501 if (IS_BITWISE_OP (ic) &&
3502 getSize (operandType (IC_RESULT (ic))) > 1)
3506 /* has only one definition */
3507 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3510 /* has only one use */
3511 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3514 /* and the usage immediately follows this iCode */
3515 if (!(uic = hTabItemWithKey (iCodehTab,
3516 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3519 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3520 if (ic->next != uic)
3523 /* if it is a conditional branch then we definitely can */
3527 if (uic->op == JUMPTABLE)
3530 /* if the usage is not is an assignment
3531 or an arithmetic / bitwise / shift operation then not */
3532 if (POINTER_SET (uic) &&
3533 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3536 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3537 if (uic->op != '=' &&
3538 !IS_ARITHMETIC_OP (uic) &&
3539 !IS_BITWISE_OP (uic) &&
3540 uic->op != LEFT_OP &&
3541 uic->op != RIGHT_OP)
3544 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3545 /* if used in ^ operation then make sure right is not a
3547 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3550 /* if shift operation make sure right side is not a literal */
3551 if (uic->op == RIGHT_OP &&
3552 (isOperandLiteral (IC_RIGHT (uic)) ||
3553 getSize (operandType (IC_RESULT (uic))) > 1))
3556 if (uic->op == LEFT_OP &&
3557 (isOperandLiteral (IC_RIGHT (uic)) ||
3558 getSize (operandType (IC_RESULT (uic))) > 1))
3561 /* make sure that the result of this icode is not on the
3562 stack, since acc is used to compute stack offset */
3563 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3564 OP_SYMBOL (IC_RESULT (uic))->onStack)
3567 /* if either one of them in far space then we cannot */
3568 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3569 isOperandInFarSpace (IC_LEFT (uic))) ||
3570 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3571 isOperandInFarSpace (IC_RIGHT (uic))))
3574 /* if the usage has only one operand then we can */
3575 if (IC_LEFT (uic) == NULL ||
3576 IC_RIGHT (uic) == NULL)
3579 /* make sure this is on the left side if not
3580 a '+' since '+' is commutative */
3581 if (ic->op != '+' &&
3582 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3585 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3586 /* if one of them is a literal then we can */
3587 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3588 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3589 (getSize (operandType (IC_RESULT (uic))) <= 1))
3591 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3595 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3596 /* if the other one is not on stack then we can */
3597 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3598 (IS_ITEMP (IC_RIGHT (uic)) ||
3599 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3600 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3603 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3604 (IS_ITEMP (IC_LEFT (uic)) ||
3605 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3606 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3612 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3613 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3618 /*-----------------------------------------------------------------*/
3619 /* packForPush - hueristics to reduce iCode for pushing */
3620 /*-----------------------------------------------------------------*/
3622 packForReceive (iCode * ic, eBBlock * ebp)
3626 debugLog ("%s\n", __FUNCTION__);
3627 debugAopGet (" result:", IC_RESULT (ic));
3628 debugAopGet (" left:", IC_LEFT (ic));
3629 debugAopGet (" right:", IC_RIGHT (ic));
3634 for (dic = ic->next; dic; dic = dic->next)
3639 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3640 debugLog (" used on left\n");
3641 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3642 debugLog (" used on right\n");
3643 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3644 debugLog (" used on result\n");
3646 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3647 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3652 debugLog (" hey we can remove this unnecessary assign\n");
3654 /*-----------------------------------------------------------------*/
3655 /* packForPush - hueristics to reduce iCode for pushing */
3656 /*-----------------------------------------------------------------*/
3658 packForPush (iCode * ic, eBBlock * ebp)
3662 debugLog ("%s\n", __FUNCTION__);
3663 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3666 /* must have only definition & one usage */
3667 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3668 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3671 /* find the definition */
3672 if (!(dic = hTabItemWithKey (iCodehTab,
3673 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3676 if (dic->op != '=' || POINTER_SET (dic))
3679 /* we now we know that it has one & only one def & use
3680 and the that the definition is an assignment */
3681 IC_LEFT (ic) = IC_RIGHT (dic);
3683 remiCodeFromeBBlock (ebp, dic);
3684 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3685 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3688 void printSymType(char * str, sym_link *sl)
3690 debugLog (" %s Symbol type: ",str);
3691 printTypeChain( sl, debugF);
3696 /*-----------------------------------------------------------------*/
3697 /* some debug code to print the symbol S_TYPE. Note that
3698 * the function checkSClass in src/SDCCsymt.c dinks with
3699 * the S_TYPE in ways the PIC port doesn't fully like...*/
3700 /*-----------------------------------------------------------------*/
3701 void isData(sym_link *sl)
3711 for ( ; sl; sl=sl->next) {
3713 switch (SPEC_SCLS(sl)) {
3715 case S_DATA: fprintf (of, "data "); break;
3716 case S_XDATA: fprintf (of, "xdata "); break;
3717 case S_SFR: fprintf (of, "sfr "); break;
3718 case S_SBIT: fprintf (of, "sbit "); break;
3719 case S_CODE: fprintf (of, "code "); break;
3720 case S_IDATA: fprintf (of, "idata "); break;
3721 case S_PDATA: fprintf (of, "pdata "); break;
3722 case S_LITERAL: fprintf (of, "literal "); break;
3723 case S_STACK: fprintf (of, "stack "); break;
3724 case S_XSTACK: fprintf (of, "xstack "); break;
3725 case S_BIT: fprintf (of, "bit "); break;
3726 case S_EEPROM: fprintf (of, "eeprom "); break;
3736 /*-----------------------------------------------------------------*/
3737 /* packRegisters - does some transformations to reduce register */
3739 /*-----------------------------------------------------------------*/
3741 packRegisters (eBBlock * ebp)
3746 debugLog ("%s\n", __FUNCTION__);
3752 /* look for assignments of the form */
3753 /* iTempNN = TRueSym (someoperation) SomeOperand */
3755 /* TrueSym := iTempNN:1 */
3756 for (ic = ebp->sch; ic; ic = ic->next)
3759 /* find assignment of the form TrueSym := iTempNN:1 */
3760 if (ic->op == '=' && !POINTER_SET (ic))
3761 change += packRegsForAssign (ic, ebp);
3765 if (POINTER_SET (ic))
3766 debugLog ("pointer is set\n");
3767 debugAopGet (" result:", IC_RESULT (ic));
3768 debugAopGet (" left:", IC_LEFT (ic));
3769 debugAopGet (" right:", IC_RIGHT (ic));
3778 for (ic = ebp->sch; ic; ic = ic->next) {
3780 if(IS_SYMOP ( IC_LEFT(ic))) {
3781 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3783 debugAopGet (" left:", IC_LEFT (ic));
3784 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3785 debugLog (" is a pointer\n");
3787 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3788 debugLog (" is volatile\n");
3792 printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
3795 if(IS_SYMOP ( IC_RIGHT(ic))) {
3796 debugAopGet (" right:", IC_RIGHT (ic));
3797 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3800 if(IS_SYMOP ( IC_RESULT(ic))) {
3801 debugAopGet (" result:", IC_RESULT (ic));
3802 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3805 if (POINTER_SET (ic))
3806 debugLog (" %d - Pointer set\n", __LINE__);
3809 /* Look for two subsequent iCodes with */
3811 /* _c = iTemp & op; */
3812 /* and replace them by */
3815 if ((ic->op == BITWISEAND || ic->op == '|' || ic->op == '^') &&
3817 ic->prev->op == '=' &&
3818 IS_ITEMP (IC_LEFT (ic)) &&
3819 IC_LEFT (ic) == IC_RESULT (ic->prev) &&
3820 isOperandEqual (IC_RESULT(ic), IC_RIGHT(ic->prev)))
3822 iCode* ic_prev = ic->prev;
3823 symbol* prev_result_sym = OP_SYMBOL (IC_RESULT (ic_prev));
3825 ReplaceOpWithCheaperOp (&IC_LEFT (ic), IC_RESULT (ic));
3826 if (IC_RESULT (ic_prev) != IC_RIGHT (ic))
3828 bitVectUnSetBit (OP_USES (IC_RESULT (ic_prev)), ic->key);
3829 if (/*IS_ITEMP (IC_RESULT (ic_prev)) && */
3830 prev_result_sym->liveTo == ic->seq)
3832 prev_result_sym->liveTo = ic_prev->seq;
3835 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
3837 bitVectSetBit (ic->rlive, IC_RESULT (ic)->key);
3839 if (bitVectIsZero (OP_USES (IC_RESULT (ic_prev))))
3841 bitVectUnSetBit (ic->rlive, IC_RESULT (ic)->key);
3842 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic_prev)), ic_prev->key);
3843 remiCodeFromeBBlock (ebp, ic_prev);
3844 hTabDeleteItem (&iCodehTab, ic_prev->key, ic_prev, DELETE_ITEM, NULL);
3848 /* if this is an itemp & result of a address of a true sym
3849 then mark this as rematerialisable */
3850 if (ic->op == ADDRESS_OF &&
3851 IS_ITEMP (IC_RESULT (ic)) &&
3852 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3853 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3854 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3857 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3859 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3860 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3861 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3865 /* if straight assignment then carry remat flag if
3866 this is the only definition */
3867 if (ic->op == '=' &&
3868 !POINTER_SET (ic) &&
3869 IS_SYMOP (IC_RIGHT (ic)) &&
3870 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3871 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3873 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3875 OP_SYMBOL (IC_RESULT (ic))->remat =
3876 OP_SYMBOL (IC_RIGHT (ic))->remat;
3877 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3878 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3881 /* if this is a +/- operation with a rematerizable
3882 then mark this as rematerializable as well */
3883 if ((ic->op == '+' || ic->op == '-') &&
3884 (IS_SYMOP (IC_LEFT (ic)) &&
3885 IS_ITEMP (IC_RESULT (ic)) &&
3886 OP_SYMBOL (IC_LEFT (ic))->remat &&
3887 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3888 IS_OP_LITERAL (IC_RIGHT (ic))))
3890 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3892 operandLitValue (IC_RIGHT (ic));
3893 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3894 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3895 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3898 /* mark the pointer usages */
3899 if (POINTER_SET (ic))
3901 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3902 debugLog (" marking as a pointer (set) =>");
3903 debugAopGet (" result:", IC_RESULT (ic));
3905 if (POINTER_GET (ic))
3907 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3908 debugLog (" marking as a pointer (get) =>");
3909 debugAopGet (" left:", IC_LEFT (ic));
3914 /* if we are using a symbol on the stack
3915 then we should say pic14_ptrRegReq */
3916 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3917 pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3918 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3919 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3920 pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3921 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3924 if (IS_SYMOP (IC_LEFT (ic)))
3925 pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3926 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3927 if (IS_SYMOP (IC_RIGHT (ic)))
3928 pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3929 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3930 if (IS_SYMOP (IC_RESULT (ic)))
3931 pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3932 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3935 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
3939 /* if the condition of an if instruction
3940 is defined in the previous instruction then
3941 mark the itemp as a conditional */
3942 if ((IS_CONDITIONAL (ic) ||
3943 ((ic->op == BITWISEAND ||
3946 isBitwiseOptimizable (ic))) &&
3947 ic->next && ic->next->op == IFX &&
3948 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3949 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3952 debugLog (" %d\n", __LINE__);
3953 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3957 /* reduce for support function calls */
3958 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3959 packRegsForSupport (ic, ebp);
3961 /* if a parameter is passed, it's in W, so we may not
3962 need to place a copy in a register */
3963 if (ic->op == RECEIVE)
3964 packForReceive (ic, ebp);
3966 /* some cases the redundant moves can
3967 can be eliminated for return statements */
3968 if ((ic->op == RETURN || ic->op == SEND) &&
3969 !isOperandInFarSpace (IC_LEFT (ic)) &&
3971 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3973 /* if pointer set & left has a size more than
3974 one and right is not in far space */
3975 if (POINTER_SET (ic) &&
3976 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3977 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3978 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3979 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3981 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3983 /* if pointer get */
3984 if (POINTER_GET (ic) &&
3985 !isOperandInFarSpace (IC_RESULT (ic)) &&
3986 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3987 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3988 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3990 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3993 /* if this is cast for intergral promotion then
3994 check if only use of the definition of the
3995 operand being casted/ if yes then replace
3996 the result of that arithmetic operation with
3997 this result and get rid of the cast */
3998 if (ic->op == CAST) {
4000 sym_link *fromType = operandType (IC_RIGHT (ic));
4001 sym_link *toType = operandType (IC_LEFT (ic));
4003 debugLog (" %d - casting\n", __LINE__);
4005 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
4006 getSize (fromType) != getSize (toType)) {
4009 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4012 if (IS_ARITHMETIC_OP (dic)) {
4014 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4015 IC_RESULT (dic) = IC_RESULT (ic);
4016 remiCodeFromeBBlock (ebp, ic);
4017 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4018 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4019 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4023 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
4027 /* if the type from and type to are the same
4028 then if this is the only use then packit */
4029 if (compareType (operandType (IC_RIGHT (ic)),
4030 operandType (IC_LEFT (ic))) == 1) {
4032 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4035 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4036 IC_RESULT (dic) = IC_RESULT (ic);
4037 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4038 remiCodeFromeBBlock (ebp, ic);
4039 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4040 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4048 iTempNN := (some variable in farspace) V1
4053 if (ic->op == IPUSH)
4055 packForPush (ic, ebp);
4059 /* pack registers for accumulator use, when the
4060 result of an arithmetic or bit wise operation
4061 has only one use, that use is immediately following
4062 the defintion and the using iCode has only one
4063 operand or has two operands but one is literal &
4064 the result of that operation is not on stack then
4065 we can leave the result of this operation in acc:b
4067 if ((IS_ARITHMETIC_OP (ic)
4069 || IS_BITWISE_OP (ic)
4071 || ic->op == LEFT_OP || ic->op == RIGHT_OP
4074 IS_ITEMP (IC_RESULT (ic)) &&
4075 getSize (operandType (IC_RESULT (ic))) <= 2)
4077 packRegsForAccUse (ic);
4083 dumpEbbsToDebug (eBBlock ** ebbs, int count)
4087 if (!debug || !debugF)
4090 for (i = 0; i < count; i++)
4092 fprintf (debugF, "\n----------------------------------------------------------------\n");
4093 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
4094 ebbs[i]->entryLabel->name,
4097 ebbs[i]->isLastInLoop);
4098 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4103 fprintf (debugF, "visited %d : hasFcall = %d\n",
4107 fprintf (debugF, "\ndefines bitVector :");
4108 bitVectDebugOn (ebbs[i]->defSet, debugF);
4109 fprintf (debugF, "\nlocal defines bitVector :");
4110 bitVectDebugOn (ebbs[i]->ldefs, debugF);
4111 fprintf (debugF, "\npointers Set bitvector :");
4112 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4113 fprintf (debugF, "\nin pointers Set bitvector :");
4114 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4115 fprintf (debugF, "\ninDefs Set bitvector :");
4116 bitVectDebugOn (ebbs[i]->inDefs, debugF);
4117 fprintf (debugF, "\noutDefs Set bitvector :");
4118 bitVectDebugOn (ebbs[i]->outDefs, debugF);
4119 fprintf (debugF, "\nusesDefs Set bitvector :");
4120 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4121 fprintf (debugF, "\n----------------------------------------------------------------\n");
4122 printiCChain (ebbs[i]->sch, debugF);
4125 /*-----------------------------------------------------------------*/
4126 /* assignRegisters - assigns registers to each live range as need */
4127 /*-----------------------------------------------------------------*/
4129 pic14_assignRegisters (eBBlock ** ebbs, int count)
4134 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
4135 debugLog ("\nebbs before optimizing:\n");
4136 dumpEbbsToDebug (ebbs, count);
4138 setToNull ((void *) &_G.funcrUsed);
4139 pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4142 /* change assignments this will remove some
4143 live ranges reducing some register pressure */
4144 for (i = 0; i < count; i++)
4145 packRegisters (ebbs[i]);
4152 debugLog("dir registers allocated so far:\n");
4153 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4156 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4157 reg = hTabNextItem(dynDirectRegNames, &hkey);
4162 if (options.dump_pack)
4163 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
4165 /* first determine for each live range the number of
4166 registers & the type of registers required for each */
4169 /* and serially allocate registers */
4170 serialRegAssign (ebbs, count);
4172 /* if stack was extended then tell the user */
4175 /* werror(W_TOOMANY_SPILS,"stack", */
4176 /* _G.stackExtend,currFunc->name,""); */
4182 /* werror(W_TOOMANY_SPILS,"data space", */
4183 /* _G.dataExtend,currFunc->name,""); */
4187 /* after that create the register mask
4188 for each of the instruction */
4189 createRegMask (ebbs, count);
4191 /* redo that offsets for stacked automatic variables */
4192 redoStackOffsets ();
4194 if (options.dump_rassgn)
4195 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
4197 /* now get back the chain */
4198 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4200 debugLog ("ebbs after optimizing:\n");
4201 dumpEbbsToDebug (ebbs, count);
4206 /* free up any _G.stackSpil locations allocated */
4207 applyToSet (_G.stackSpil, deallocStackSpil);
4209 setToNull ((void *) &_G.stackSpil);
4210 setToNull ((void *) &_G.spiltSet);
4211 /* mark all registers as free */
4212 //pic14_freeAllRegs ();
4214 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");