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 && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1805 sym = leastUsedLR (selectS);
1808 sym->remainSpil = 1;
1815 /* find live ranges with spillocation && not used as pointers */
1816 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1819 sym = leastUsedLR (selectS);
1820 /* mark this as allocation required */
1821 sym->usl.spillLoc->allocreq = 1;
1825 /* find live ranges with spillocation */
1826 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1829 sym = leastUsedLR (selectS);
1830 sym->usl.spillLoc->allocreq = 1;
1834 /* couldn't find then we need to create a spil
1835 location on the stack , for which one? the least
1837 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1840 /* return a created spil location */
1841 sym = createStackSpil (leastUsedLR (selectS));
1842 sym->usl.spillLoc->allocreq = 1;
1846 /* this is an extreme situation we will spill
1847 this one : happens very rarely but it does happen */
1853 /*-----------------------------------------------------------------*/
1854 /* spilSomething - spil some variable & mark registers as free */
1855 /*-----------------------------------------------------------------*/
1857 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1862 debugLog ("%s\n", __FUNCTION__);
1863 /* get something we can spil */
1864 ssym = selectSpil (ic, ebp, forSym);
1866 /* mark it as spilt */
1868 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1870 /* mark it as not register assigned &
1871 take it away from the set */
1872 bitVectUnSetBit (_G.regAssigned, ssym->key);
1874 /* mark the registers as free */
1875 for (i = 0; i < ssym->nRegs; i++)
1877 freeReg (ssym->regs[i]);
1879 /* if spilt on stack then free up r0 & r1
1880 if they could have been assigned to as gprs */
1881 if (!pic14_ptrRegReq && isSpiltOnStack (ssym))
1884 spillLRWithPtrReg (ssym);
1887 /* if this was a block level spil then insert push & pop
1888 at the start & end of block respectively */
1889 if (ssym->blockSpil)
1891 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1892 /* add push to the start of the block */
1893 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1894 ebp->sch->next : ebp->sch));
1895 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1896 /* add pop to the end of the block */
1897 addiCodeToeBBlock (ebp, nic, NULL);
1900 /* if spilt because not used in the remainder of the
1901 block then add a push before this instruction and
1902 a pop at the end of the block */
1903 if (ssym->remainSpil)
1906 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1907 /* add push just before this instruction */
1908 addiCodeToeBBlock (ebp, nic, ic);
1910 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1911 /* add pop to the end of the block */
1912 addiCodeToeBBlock (ebp, nic, NULL);
1921 /*-----------------------------------------------------------------*/
1922 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1923 /*-----------------------------------------------------------------*/
1925 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1930 debugLog ("%s\n", __FUNCTION__);
1932 /* try for a ptr type */
1933 if ((reg = allocReg (REG_PTR)))
1936 /* try for gpr type */
1937 if ((reg = allocReg (REG_GPR)))
1940 /* we have to spil */
1941 if (!spilSomething (ic, ebp, sym))
1944 /* make sure partially assigned registers aren't reused */
1945 for (j=0; j<=sym->nRegs; j++)
1947 sym->regs[j]->isFree = 0;
1949 /* this looks like an infinite loop but
1950 in really selectSpil will abort */
1954 /*-----------------------------------------------------------------*/
1955 /* getRegGpr - will try for GPR if not spil */
1956 /*-----------------------------------------------------------------*/
1958 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1963 debugLog ("%s\n", __FUNCTION__);
1965 /* try for gpr type */
1966 if ((reg = allocReg (REG_GPR)))
1969 if (!pic14_ptrRegReq)
1970 if ((reg = allocReg (REG_PTR)))
1973 /* we have to spil */
1974 if (!spilSomething (ic, ebp, sym))
1977 /* make sure partially assigned registers aren't reused */
1978 for (j=0; j<=sym->nRegs; j++)
1980 sym->regs[j]->isFree = 0;
1982 /* this looks like an infinite loop but
1983 in really selectSpil will abort */
1987 /*-----------------------------------------------------------------*/
1988 /* symHasReg - symbol has a given register */
1989 /*-----------------------------------------------------------------*/
1991 symHasReg (symbol * sym, regs * reg)
1995 debugLog ("%s\n", __FUNCTION__);
1996 for (i = 0; i < sym->nRegs; i++)
1997 if (sym->regs[i] == reg)
2003 /*-----------------------------------------------------------------*/
2004 /* deassignLRs - check the live to and if they have registers & are */
2005 /* not spilt then free up the registers */
2006 /*-----------------------------------------------------------------*/
2008 deassignLRs (iCode * ic, eBBlock * ebp)
2014 debugLog ("%s\n", __FUNCTION__);
2015 for (sym = hTabFirstItem (liveRanges, &k); sym;
2016 sym = hTabNextItem (liveRanges, &k))
2019 symbol *psym = NULL;
2020 /* if it does not end here */
2021 if (sym->liveTo > ic->seq)
2024 /* if it was spilt on stack then we can
2025 mark the stack spil location as free */
2030 sym->usl.spillLoc->isFree = 1;
2036 if (!bitVectBitValue (_G.regAssigned, sym->key))
2039 /* special case check if this is an IFX &
2040 the privious one was a pop and the
2041 previous one was not spilt then keep track
2043 if (ic->op == IFX && ic->prev &&
2044 ic->prev->op == IPOP &&
2045 !ic->prev->parmPush &&
2046 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
2047 psym = OP_SYMBOL (IC_LEFT (ic->prev));
2053 bitVectUnSetBit (_G.regAssigned, sym->key);
2055 /* if the result of this one needs registers
2056 and does not have it then assign it right
2058 if (IC_RESULT (ic) &&
2059 !(SKIP_IC2 (ic) || /* not a special icode */
2060 ic->op == JUMPTABLE ||
2065 POINTER_SET (ic)) &&
2066 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
2067 result->liveTo > ic->seq && /* and will live beyond this */
2068 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
2069 result->regType == sym->regType && /* same register types */
2070 result->nRegs && /* which needs registers */
2071 !result->isspilt && /* and does not already have them */
2073 !bitVectBitValue (_G.regAssigned, result->key) &&
2074 /* the number of free regs + number of regs in this LR
2075 can accomodate the what result Needs */
2076 ((nfreeRegsType (result->regType) +
2077 sym->nRegs) >= result->nRegs)
2081 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
2083 result->regs[i] = sym->regs[i];
2085 result->regs[i] = getRegGpr (ic, ebp, result);
2087 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
2091 /* free the remaining */
2092 for (; i < sym->nRegs; i++)
2096 if (!symHasReg (psym, sym->regs[i]))
2097 freeReg (sym->regs[i]);
2100 freeReg (sym->regs[i]);
2107 /*-----------------------------------------------------------------*/
2108 /* reassignLR - reassign this to registers */
2109 /*-----------------------------------------------------------------*/
2111 reassignLR (operand * op)
2113 symbol *sym = OP_SYMBOL (op);
2116 debugLog ("%s\n", __FUNCTION__);
2117 /* not spilt any more */
2118 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
2119 bitVectUnSetBit (_G.spiltSet, sym->key);
2121 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2125 for (i = 0; i < sym->nRegs; i++)
2126 sym->regs[i]->isFree = 0;
2129 /*-----------------------------------------------------------------*/
2130 /* willCauseSpill - determines if allocating will cause a spill */
2131 /*-----------------------------------------------------------------*/
2133 willCauseSpill (int nr, int rt)
2135 debugLog ("%s\n", __FUNCTION__);
2136 /* first check if there are any avlb registers
2137 of te type required */
2140 /* special case for pointer type
2141 if pointer type not avlb then
2142 check for type gpr */
2143 if (nFreeRegs (rt) >= nr)
2145 if (nFreeRegs (REG_GPR) >= nr)
2150 if (pic14_ptrRegReq)
2152 if (nFreeRegs (rt) >= nr)
2157 if (nFreeRegs (REG_PTR) +
2158 nFreeRegs (REG_GPR) >= nr)
2163 debugLog (" ... yep it will (cause a spill)\n");
2164 /* it will cause a spil */
2168 /*-----------------------------------------------------------------*/
2169 /* positionRegs - the allocator can allocate same registers to res- */
2170 /* ult and operand, if this happens make sure they are in the same */
2171 /* position as the operand otherwise chaos results */
2172 /*-----------------------------------------------------------------*/
2174 positionRegs (symbol * result, symbol * opsym, int lineno)
2176 int count = min (result->nRegs, opsym->nRegs);
2177 int i, j = 0, shared = 0;
2179 debugLog ("%s\n", __FUNCTION__);
2180 /* if the result has been spilt then cannot share */
2185 /* first make sure that they actually share */
2186 for (i = 0; i < count; i++)
2188 for (j = 0; j < count; j++)
2190 if (result->regs[i] == opsym->regs[j] && i != j)
2200 regs *tmp = result->regs[i];
2201 result->regs[i] = result->regs[j];
2202 result->regs[j] = tmp;
2207 /*-----------------------------------------------------------------*/
2208 /* serialRegAssign - serially allocate registers to the variables */
2209 /*-----------------------------------------------------------------*/
2211 serialRegAssign (eBBlock ** ebbs, int count)
2215 debugLog ("%s\n", __FUNCTION__);
2216 /* for all blocks */
2217 for (i = 0; i < count; i++)
2222 if (ebbs[i]->noPath &&
2223 (ebbs[i]->entryLabel != entryLabel &&
2224 ebbs[i]->entryLabel != returnLabel))
2227 /* of all instructions do */
2228 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2231 debugLog (" op: %s\n", decodeOp (ic->op));
2233 /* if this is an ipop that means some live
2234 range will have to be assigned again */
2236 reassignLR (IC_LEFT (ic));
2238 /* if result is present && is a true symbol */
2239 if (IC_RESULT (ic) && ic->op != IFX &&
2240 IS_TRUE_SYMOP (IC_RESULT (ic)))
2241 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2243 /* take away registers from live
2244 ranges that end at this instruction */
2245 deassignLRs (ic, ebbs[i]);
2247 /* some don't need registers */
2248 if (SKIP_IC2 (ic) ||
2249 ic->op == JUMPTABLE ||
2253 (IC_RESULT (ic) && POINTER_SET (ic)))
2256 /* now we need to allocate registers
2257 only for the result */
2260 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2266 /* if it does not need or is spilt
2267 or is already assigned to registers
2268 or will not live beyond this instructions */
2271 bitVectBitValue (_G.regAssigned, sym->key) ||
2272 sym->liveTo <= ic->seq)
2275 /* if some liverange has been spilt at the block level
2276 and this one live beyond this block then spil this
2278 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2283 /* if trying to allocate this will cause
2284 a spill and there is nothing to spill
2285 or this one is rematerializable then
2287 willCS = willCauseSpill (sym->nRegs, sym->regType);
2288 spillable = computeSpillable (ic);
2290 (willCS && bitVectIsZero (spillable)))
2298 /* if it has a spillocation & is used less than
2299 all other live ranges then spill this */
2301 if (sym->usl.spillLoc) {
2302 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2303 allLRs, ebbs[i], ic));
2304 if (leastUsed && leastUsed->used > sym->used) {
2309 /* if none of the liveRanges have a spillLocation then better
2310 to spill this one than anything else already assigned to registers */
2311 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2312 /* if this is local to this block then we might find a block spil */
2313 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2321 if (ic->op == RECEIVE)
2322 debugLog ("When I get clever, I'll optimize the receive logic\n");
2324 /* if we need ptr regs for the right side
2326 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2327 <= (unsigned) PTRSIZE)
2332 /* else we assign registers to it */
2333 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2335 debugLog (" %d - \n", __LINE__);
2337 bitVectDebugOn(_G.regAssigned, debugF);
2338 for (j = 0; j < sym->nRegs; j++)
2340 if (sym->regType == REG_PTR)
2341 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2343 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2345 /* if the allocation failed which means
2346 this was spilt then break */
2350 debugLog (" %d - \n", __LINE__);
2352 /* if it shares registers with operands make sure
2353 that they are in the same position */
2354 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2355 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2356 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2357 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2358 /* do the same for the right operand */
2359 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2360 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2361 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2362 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2364 debugLog (" %d - \n", __LINE__);
2367 debugLog (" %d - \n", __LINE__);
2377 /*-----------------------------------------------------------------*/
2378 /* rUmaskForOp :- returns register mask for an operand */
2379 /*-----------------------------------------------------------------*/
2381 rUmaskForOp (operand * op)
2387 debugLog ("%s\n", __FUNCTION__);
2388 /* only temporaries are assigned registers */
2392 sym = OP_SYMBOL (op);
2394 /* if spilt or no registers assigned to it
2396 if (sym->isspilt || !sym->nRegs)
2399 rumask = newBitVect (pic14_nRegs);
2401 for (j = 0; j < sym->nRegs; j++)
2403 rumask = bitVectSetBit (rumask,
2404 sym->regs[j]->rIdx);
2410 /*-----------------------------------------------------------------*/
2411 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2412 /*-----------------------------------------------------------------*/
2414 regsUsedIniCode (iCode * ic)
2416 bitVect *rmask = newBitVect (pic14_nRegs);
2418 debugLog ("%s\n", __FUNCTION__);
2419 /* do the special cases first */
2422 rmask = bitVectUnion (rmask,
2423 rUmaskForOp (IC_COND (ic)));
2427 /* for the jumptable */
2428 if (ic->op == JUMPTABLE)
2430 rmask = bitVectUnion (rmask,
2431 rUmaskForOp (IC_JTCOND (ic)));
2436 /* of all other cases */
2438 rmask = bitVectUnion (rmask,
2439 rUmaskForOp (IC_LEFT (ic)));
2443 rmask = bitVectUnion (rmask,
2444 rUmaskForOp (IC_RIGHT (ic)));
2447 rmask = bitVectUnion (rmask,
2448 rUmaskForOp (IC_RESULT (ic)));
2454 /*-----------------------------------------------------------------*/
2455 /* createRegMask - for each instruction will determine the regsUsed */
2456 /*-----------------------------------------------------------------*/
2458 createRegMask (eBBlock ** ebbs, int count)
2462 debugLog ("%s\n", __FUNCTION__);
2463 /* for all blocks */
2464 for (i = 0; i < count; i++)
2468 if (ebbs[i]->noPath &&
2469 (ebbs[i]->entryLabel != entryLabel &&
2470 ebbs[i]->entryLabel != returnLabel))
2473 /* for all instructions */
2474 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2479 if (SKIP_IC2 (ic) || !ic->rlive)
2482 /* first mark the registers used in this
2484 ic->rUsed = regsUsedIniCode (ic);
2485 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2487 /* now create the register mask for those
2488 registers that are in use : this is a
2489 super set of ic->rUsed */
2490 ic->rMask = newBitVect (pic14_nRegs + 1);
2492 /* for all live Ranges alive at this point */
2493 for (j = 1; j < ic->rlive->size; j++)
2498 /* if not alive then continue */
2499 if (!bitVectBitValue (ic->rlive, j))
2502 /* find the live range we are interested in */
2503 if (!(sym = hTabItemWithKey (liveRanges, j)))
2505 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2506 "createRegMask cannot find live range");
2510 /* if no register assigned to it */
2511 if (!sym->nRegs || sym->isspilt)
2514 /* for all the registers allocated to it */
2515 for (k = 0; k < sym->nRegs; k++)
2518 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2524 /*-----------------------------------------------------------------*/
2525 /* rematStr - returns the rematerialized string for a remat var */
2526 /*-----------------------------------------------------------------*/
2528 rematStr (symbol * sym)
2531 iCode *ic = sym->rematiCode;
2532 symbol *psym = NULL;
2534 debugLog ("%s\n", __FUNCTION__);
2536 //printf ("%s\n", s);
2538 /* if plus or minus print the right hand side */
2540 if (ic->op == '+' || ic->op == '-') {
2542 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2544 sprintf (s, "(%s %c 0x%04x)",
2545 OP_SYMBOL (IC_LEFT (ric))->rname,
2547 (int) operandLitValue (IC_RIGHT (ic)));
2550 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2552 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2553 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2558 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2559 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2561 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2566 /*-----------------------------------------------------------------*/
2567 /* rematStr - returns the rematerialized string for a remat var */
2568 /*-----------------------------------------------------------------*/
2570 rematStr (symbol * sym)
2573 iCode *ic = sym->rematiCode;
2575 debugLog ("%s\n", __FUNCTION__);
2580 /* if plus or minus print the right hand side */
2582 if (ic->op == '+' || ic->op == '-') {
2583 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2586 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2590 if (ic->op == '+' || ic->op == '-')
2592 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2593 sprintf (s, "(%s %c 0x%04x)",
2594 OP_SYMBOL (IC_LEFT (ric))->rname,
2596 (int) operandLitValue (IC_RIGHT (ic)));
2599 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2601 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2605 /* we reached the end */
2606 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2610 printf ("%s\n", buffer);
2615 /*-----------------------------------------------------------------*/
2616 /* regTypeNum - computes the type & number of registers required */
2617 /*-----------------------------------------------------------------*/
2625 debugLog ("%s\n", __FUNCTION__);
2626 /* for each live range do */
2627 for (sym = hTabFirstItem (liveRanges, &k); sym;
2628 sym = hTabNextItem (liveRanges, &k)) {
2630 debugLog (" %d - %s\n", __LINE__, sym->rname);
2632 /* if used zero times then no registers needed */
2633 if ((sym->liveTo - sym->liveFrom) == 0)
2637 /* if the live range is a temporary */
2640 debugLog (" %d - itemp register\n", __LINE__);
2642 /* if the type is marked as a conditional */
2643 if (sym->regType == REG_CND)
2646 /* if used in return only then we don't
2649 if (IS_AGGREGATE (sym->type) || sym->isptr)
2650 sym->type = aggrToPtr (sym->type, FALSE);
2651 debugLog (" %d - no reg needed - accumulator used\n", __LINE__);
2657 //if (IS_AGGREGATE (sym->type) || sym->isptr)
2658 // sym->type = aggrToPtr (sym->type, FALSE);
2659 debugLog (" %d - used as a return\n", __LINE__);
2664 /* if the symbol has only one definition &
2665 that definition is a get_pointer and the
2666 pointer we are getting is rematerializable and
2669 if (bitVectnBitsOn (sym->defs) == 1 &&
2670 (ic = hTabItemWithKey (iCodehTab,
2671 bitVectFirstBit (sym->defs))) &&
2674 !IS_BITVAR (sym->etype)) {
2677 debugLog (" %d - \n", __LINE__);
2679 /* if remat in data space */
2680 if (OP_SYMBOL (IC_LEFT (ic))->remat &&
2681 DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) {
2683 /* create a psuedo symbol & force a spil */
2684 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2685 symbol *psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2686 psym->type = sym->type;
2687 psym->etype = sym->etype;
2688 strcpy (psym->rname, psym->name);
2690 sym->usl.spillLoc = psym;
2694 /* if in data space or idata space then try to
2695 allocate pointer register */
2699 /* if not then we require registers */
2700 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2701 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2702 getSize (sym->type));
2705 if(IS_PTR_CONST (sym->type)) {
2706 debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2710 if (sym->nRegs > 4) {
2711 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2712 printTypeChain (sym->type, stderr);
2713 fprintf (stderr, "\n");
2716 /* determine the type of register required */
2717 if (sym->nRegs == 1 &&
2718 IS_PTR (sym->type) &&
2720 sym->regType = REG_PTR;
2722 sym->regType = REG_GPR;
2725 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2729 /* for the first run we don't provide */
2730 /* registers for true symbols we will */
2731 /* see how things go */
2736 DEFSETFUNC (markRegFree)
2738 ((regs *)item)->isFree = 1;
2743 DEFSETFUNC (deallocReg)
2745 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2746 ((regs *)item)->isFree = 1;
2747 ((regs *)item)->wasUsed = 0;
2751 /*-----------------------------------------------------------------*/
2752 /* freeAllRegs - mark all registers as free */
2753 /*-----------------------------------------------------------------*/
2755 pic14_freeAllRegs ()
2759 debugLog ("%s\n", __FUNCTION__);
2761 applyToSet(dynAllocRegs,markRegFree);
2762 applyToSet(dynStackRegs,markRegFree);
2765 for (i = 0; i < pic14_nRegs; i++)
2766 regspic14[i].isFree = 1;
2770 /*-----------------------------------------------------------------*/
2771 /*-----------------------------------------------------------------*/
2773 pic14_deallocateAllRegs ()
2777 debugLog ("%s\n", __FUNCTION__);
2779 applyToSet(dynAllocRegs,deallocReg);
2782 for (i = 0; i < pic14_nRegs; i++) {
2783 if(regspic14[i].pc_type == PO_GPR_TEMP) {
2784 regspic14[i].isFree = 1;
2785 regspic14[i].wasUsed = 0;
2792 /*-----------------------------------------------------------------*/
2793 /* deallocStackSpil - this will set the stack pointer back */
2794 /*-----------------------------------------------------------------*/
2796 DEFSETFUNC (deallocStackSpil)
2800 debugLog ("%s\n", __FUNCTION__);
2805 /*-----------------------------------------------------------------*/
2806 /* farSpacePackable - returns the packable icode for far variables */
2807 /*-----------------------------------------------------------------*/
2809 farSpacePackable (iCode * ic)
2813 debugLog ("%s\n", __FUNCTION__);
2814 /* go thru till we find a definition for the
2815 symbol on the right */
2816 for (dic = ic->prev; dic; dic = dic->prev)
2819 /* if the definition is a call then no */
2820 if ((dic->op == CALL || dic->op == PCALL) &&
2821 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2826 /* if shift by unknown amount then not */
2827 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2828 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2831 /* if pointer get and size > 1 */
2832 if (POINTER_GET (dic) &&
2833 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2836 if (POINTER_SET (dic) &&
2837 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2840 /* if any three is a true symbol in far space */
2841 if (IC_RESULT (dic) &&
2842 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2843 isOperandInFarSpace (IC_RESULT (dic)))
2846 if (IC_RIGHT (dic) &&
2847 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2848 isOperandInFarSpace (IC_RIGHT (dic)) &&
2849 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2852 if (IC_LEFT (dic) &&
2853 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2854 isOperandInFarSpace (IC_LEFT (dic)) &&
2855 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2858 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2860 if ((dic->op == LEFT_OP ||
2861 dic->op == RIGHT_OP ||
2863 IS_OP_LITERAL (IC_RIGHT (dic)))
2873 /*-----------------------------------------------------------------*/
2874 /* packRegsForAssign - register reduction for assignment */
2875 /*-----------------------------------------------------------------*/
2877 packRegsForAssign (iCode * ic, eBBlock * ebp)
2882 debugLog ("%s\n", __FUNCTION__);
2884 debugAopGet (" result:", IC_RESULT (ic));
2885 debugAopGet (" left:", IC_LEFT (ic));
2886 debugAopGet (" right:", IC_RIGHT (ic));
2888 /* if this is at an absolute address, then get the address. */
2889 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2890 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2891 debugLog (" %d - found config word declaration\n", __LINE__);
2892 if(IS_VALOP(IC_RIGHT(ic))) {
2893 debugLog (" setting config word to %x\n",
2894 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2895 assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2896 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2899 /* remove the assignment from the iCode chain. */
2901 remiCodeFromeBBlock (ebp, ic);
2902 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2903 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2910 if (!IS_ITEMP (IC_RESULT (ic))) {
2911 allocDirReg(IC_RESULT (ic));
2912 debugLog (" %d - result is not temp\n", __LINE__);
2915 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2916 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2917 allocDirReg(IC_LEFT (ic));
2921 if (!IS_ITEMP (IC_RIGHT (ic))) {
2922 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2924 /* only pack if this is not a function pointer */
2925 if (!IS_REF (IC_RIGHT (ic)))
2926 allocDirReg(IC_RIGHT (ic));
2930 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2931 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2933 debugLog (" %d - not packing - right side fails \n", __LINE__);
2937 /* if the true symbol is defined in far space or on stack
2938 then we should not since this will increase register pressure */
2939 if (isOperandInFarSpace (IC_RESULT (ic)))
2941 if ((dic = farSpacePackable (ic)))
2947 /* find the definition of iTempNN scanning backwards if we find a
2948 a use of the true symbol before we find the definition then
2950 for (dic = ic->prev; dic; dic = dic->prev)
2953 /* if there is a function call and this is
2954 a parameter & not my parameter then don't pack it */
2955 if ((dic->op == CALL || dic->op == PCALL) &&
2956 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2957 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2959 debugLog (" %d - \n", __LINE__);
2967 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2968 IS_OP_VOLATILE (IC_RESULT (dic)))
2970 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2975 if (IS_SYMOP (IC_RESULT (dic)) &&
2976 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2978 /* A previous result was assigned to the same register - we'll our definition */
2979 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2980 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2981 if (POINTER_SET (dic))
2987 if (IS_SYMOP (IC_RIGHT (dic)) &&
2988 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2989 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2991 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
2996 if (IS_SYMOP (IC_LEFT (dic)) &&
2997 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2998 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
3000 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
3005 if (POINTER_SET (dic) &&
3006 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
3008 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
3016 return 0; /* did not find */
3018 /* if the result is on stack or iaccess then it must be
3019 the same atleast one of the operands */
3020 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
3021 OP_SYMBOL (IC_RESULT (ic))->iaccess)
3024 /* the operation has only one symbol
3025 operator then we can pack */
3026 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
3027 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
3030 if (!((IC_LEFT (dic) &&
3031 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
3033 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
3037 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
3038 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
3039 /* found the definition */
3040 /* replace the result with the result of */
3041 /* this assignment and remove this assignment */
3042 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3043 IC_RESULT (dic) = IC_RESULT (ic);
3045 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
3047 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
3049 /* delete from liverange table also
3050 delete from all the points inbetween and the new
3052 for (sic = dic; sic != ic; sic = sic->next)
3054 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3055 if (IS_ITEMP (IC_RESULT (dic)))
3056 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3059 remiCodeFromeBBlock (ebp, ic);
3060 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3061 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3062 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3068 /*-----------------------------------------------------------------*/
3069 /* findAssignToSym : scanning backwards looks for first assig found */
3070 /*-----------------------------------------------------------------*/
3072 findAssignToSym (operand * op, iCode * ic)
3076 debugLog ("%s\n", __FUNCTION__);
3077 for (dic = ic->prev; dic; dic = dic->prev)
3080 /* if definition by assignment */
3081 if (dic->op == '=' &&
3082 !POINTER_SET (dic) &&
3083 IC_RESULT (dic)->key == op->key
3084 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3088 /* we are interested only if defined in far space */
3089 /* or in stack space in case of + & - */
3091 /* if assigned to a non-symbol then return
3093 if (!IS_SYMOP (IC_RIGHT (dic)))
3096 /* if the symbol is in far space then
3098 if (isOperandInFarSpace (IC_RIGHT (dic)))
3101 /* for + & - operations make sure that
3102 if it is on the stack it is the same
3103 as one of the three operands */
3104 if ((ic->op == '+' || ic->op == '-') &&
3105 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3108 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3109 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3110 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3118 /* if we find an usage then we cannot delete it */
3119 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3122 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3125 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3129 /* now make sure that the right side of dic
3130 is not defined between ic & dic */
3133 iCode *sic = dic->next;
3135 for (; sic != ic; sic = sic->next)
3136 if (IC_RESULT (sic) &&
3137 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3146 /*-----------------------------------------------------------------*/
3147 /* packRegsForSupport :- reduce some registers for support calls */
3148 /*-----------------------------------------------------------------*/
3150 packRegsForSupport (iCode * ic, eBBlock * ebp)
3154 debugLog ("%s\n", __FUNCTION__);
3155 /* for the left & right operand :- look to see if the
3156 left was assigned a true symbol in far space in that
3157 case replace them */
3158 if (IS_ITEMP (IC_LEFT (ic)) &&
3159 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3161 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3167 debugAopGet ("removing left:", IC_LEFT (ic));
3169 /* found it we need to remove it from the
3171 for (sic = dic; sic != ic; sic = sic->next)
3172 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3174 IC_LEFT (ic)->operand.symOperand =
3175 IC_RIGHT (dic)->operand.symOperand;
3176 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3177 remiCodeFromeBBlock (ebp, dic);
3178 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3179 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3183 /* do the same for the right operand */
3186 IS_ITEMP (IC_RIGHT (ic)) &&
3187 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3189 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3195 /* if this is a subtraction & the result
3196 is a true symbol in far space then don't pack */
3197 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3199 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3200 if (IN_FARSPACE (SPEC_OCLS (etype)))
3204 debugAopGet ("removing right:", IC_RIGHT (ic));
3206 /* found it we need to remove it from the
3208 for (sic = dic; sic != ic; sic = sic->next)
3209 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3211 IC_RIGHT (ic)->operand.symOperand =
3212 IC_RIGHT (dic)->operand.symOperand;
3213 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3215 remiCodeFromeBBlock (ebp, dic);
3216 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3217 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3224 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3227 /*-----------------------------------------------------------------*/
3228 /* packRegsForOneuse : - will reduce some registers for single Use */
3229 /*-----------------------------------------------------------------*/
3231 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3236 debugLog ("%s\n", __FUNCTION__);
3237 /* if returning a literal then do nothing */
3241 /* only upto 2 bytes since we cannot predict
3242 the usage of b, & acc */
3243 if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
3248 /* this routine will mark the a symbol as used in one
3249 instruction use only && if the definition is local
3250 (ie. within the basic block) && has only one definition &&
3251 that definition is either a return value from a
3252 function or does not contain any variables in
3254 uses = bitVectCopy (OP_USES (op));
3255 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3256 if (!bitVectIsZero (uses)) /* has other uses */
3259 /* if it has only one defintion */
3260 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3261 return NULL; /* has more than one definition */
3263 /* get that definition */
3265 hTabItemWithKey (iCodehTab,
3266 bitVectFirstBit (OP_DEFS (op)))))
3269 /* found the definition now check if it is local */
3270 if (dic->seq < ebp->fSeq ||
3271 dic->seq > ebp->lSeq)
3272 return NULL; /* non-local */
3274 /* now check if it is the return from
3276 if (dic->op == CALL || dic->op == PCALL)
3278 if (ic->op != SEND && ic->op != RETURN &&
3279 !POINTER_SET(ic) && !POINTER_GET(ic))
3281 OP_SYMBOL (op)->ruonly = 1;
3288 /* otherwise check that the definition does
3289 not contain any symbols in far space */
3290 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3291 isOperandInFarSpace (IC_RIGHT (dic)) ||
3292 IS_OP_RUONLY (IC_LEFT (ic)) ||
3293 IS_OP_RUONLY (IC_RIGHT (ic)))
3298 /* if pointer set then make sure the pointer
3300 if (POINTER_SET (dic) &&
3301 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3304 if (POINTER_GET (dic) &&
3305 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3310 /* also make sure the intervenening instructions
3311 don't have any thing in far space */
3312 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3315 /* if there is an intervening function call then no */
3316 if (dic->op == CALL || dic->op == PCALL)
3318 /* if pointer set then make sure the pointer
3320 if (POINTER_SET (dic) &&
3321 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3324 if (POINTER_GET (dic) &&
3325 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3328 /* if address of & the result is remat then okay */
3329 if (dic->op == ADDRESS_OF &&
3330 OP_SYMBOL (IC_RESULT (dic))->remat)
3333 /* if operand has size of three or more & this
3334 operation is a '*','/' or '%' then 'b' may
3336 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3337 getSize (operandType (op)) >= 3)
3340 /* if left or right or result is in far space */
3341 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3342 isOperandInFarSpace (IC_RIGHT (dic)) ||
3343 isOperandInFarSpace (IC_RESULT (dic)) ||
3344 IS_OP_RUONLY (IC_LEFT (dic)) ||
3345 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3346 IS_OP_RUONLY (IC_RESULT (dic)))
3352 OP_SYMBOL (op)->ruonly = 1;
3357 /*-----------------------------------------------------------------*/
3358 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3359 /*-----------------------------------------------------------------*/
3361 isBitwiseOptimizable (iCode * ic)
3363 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3364 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3366 debugLog ("%s\n", __FUNCTION__);
3367 /* bitwise operations are considered optimizable
3368 under the following conditions (Jean-Louis VERN)
3380 if (IS_LITERAL (rtype) ||
3381 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3387 /*-----------------------------------------------------------------*/
3388 /* packRegsForAccUse - pack registers for acc use */
3389 /*-----------------------------------------------------------------*/
3391 packRegsForAccUse (iCode * ic)
3395 debugLog ("%s\n", __FUNCTION__);
3397 /* if this is an aggregate, e.g. a one byte char array */
3398 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3401 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3403 /* if + or - then it has to be one byte result */
3404 if ((ic->op == '+' || ic->op == '-')
3405 && getSize (operandType (IC_RESULT (ic))) > 1)
3408 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3409 /* if shift operation make sure right side is not a literal */
3410 if (ic->op == RIGHT_OP &&
3411 (isOperandLiteral (IC_RIGHT (ic)) ||
3412 getSize (operandType (IC_RESULT (ic))) > 1))
3415 if (ic->op == LEFT_OP &&
3416 (isOperandLiteral (IC_RIGHT (ic)) ||
3417 getSize (operandType (IC_RESULT (ic))) > 1))
3420 if (IS_BITWISE_OP (ic) &&
3421 getSize (operandType (IC_RESULT (ic))) > 1)
3425 /* has only one definition */
3426 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3429 /* has only one use */
3430 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3433 /* and the usage immediately follows this iCode */
3434 if (!(uic = hTabItemWithKey (iCodehTab,
3435 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3438 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3439 if (ic->next != uic)
3442 /* if it is a conditional branch then we definitely can */
3446 if (uic->op == JUMPTABLE)
3449 /* if the usage is not is an assignment
3450 or an arithmetic / bitwise / shift operation then not */
3451 if (POINTER_SET (uic) &&
3452 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3455 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3456 if (uic->op != '=' &&
3457 !IS_ARITHMETIC_OP (uic) &&
3458 !IS_BITWISE_OP (uic) &&
3459 uic->op != LEFT_OP &&
3460 uic->op != RIGHT_OP)
3463 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3464 /* if used in ^ operation then make sure right is not a
3466 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3469 /* if shift operation make sure right side is not a literal */
3470 if (uic->op == RIGHT_OP &&
3471 (isOperandLiteral (IC_RIGHT (uic)) ||
3472 getSize (operandType (IC_RESULT (uic))) > 1))
3475 if (uic->op == LEFT_OP &&
3476 (isOperandLiteral (IC_RIGHT (uic)) ||
3477 getSize (operandType (IC_RESULT (uic))) > 1))
3480 /* make sure that the result of this icode is not on the
3481 stack, since acc is used to compute stack offset */
3482 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3483 OP_SYMBOL (IC_RESULT (uic))->onStack)
3486 /* if either one of them in far space then we cannot */
3487 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3488 isOperandInFarSpace (IC_LEFT (uic))) ||
3489 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3490 isOperandInFarSpace (IC_RIGHT (uic))))
3493 /* if the usage has only one operand then we can */
3494 if (IC_LEFT (uic) == NULL ||
3495 IC_RIGHT (uic) == NULL)
3498 /* make sure this is on the left side if not
3499 a '+' since '+' is commutative */
3500 if (ic->op != '+' &&
3501 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3504 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3505 /* if one of them is a literal then we can */
3506 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3507 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3508 (getSize (operandType (IC_RESULT (uic))) <= 1))
3510 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3514 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3515 /* if the other one is not on stack then we can */
3516 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3517 (IS_ITEMP (IC_RIGHT (uic)) ||
3518 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3519 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3522 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3523 (IS_ITEMP (IC_LEFT (uic)) ||
3524 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3525 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3531 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3532 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3537 /*-----------------------------------------------------------------*/
3538 /* packForPush - hueristics to reduce iCode for pushing */
3539 /*-----------------------------------------------------------------*/
3541 packForReceive (iCode * ic, eBBlock * ebp)
3545 debugLog ("%s\n", __FUNCTION__);
3546 debugAopGet (" result:", IC_RESULT (ic));
3547 debugAopGet (" left:", IC_LEFT (ic));
3548 debugAopGet (" right:", IC_RIGHT (ic));
3553 for (dic = ic->next; dic; dic = dic->next)
3558 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3559 debugLog (" used on left\n");
3560 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3561 debugLog (" used on right\n");
3562 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3563 debugLog (" used on result\n");
3565 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3566 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3571 debugLog (" hey we can remove this unnecessary assign\n");
3573 /*-----------------------------------------------------------------*/
3574 /* packForPush - hueristics to reduce iCode for pushing */
3575 /*-----------------------------------------------------------------*/
3577 packForPush (iCode * ic, eBBlock * ebp)
3581 debugLog ("%s\n", __FUNCTION__);
3582 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3585 /* must have only definition & one usage */
3586 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3587 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3590 /* find the definition */
3591 if (!(dic = hTabItemWithKey (iCodehTab,
3592 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3595 if (dic->op != '=' || POINTER_SET (dic))
3598 /* we now we know that it has one & only one def & use
3599 and the that the definition is an assignment */
3600 IC_LEFT (ic) = IC_RIGHT (dic);
3602 remiCodeFromeBBlock (ebp, dic);
3603 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3604 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3607 void printSymType(char * str, sym_link *sl)
3609 debugLog (" %s Symbol type: ",str);
3610 printTypeChain( sl, debugF);
3615 /*-----------------------------------------------------------------*/
3616 /* some debug code to print the symbol S_TYPE. Note that
3617 * the function checkSClass in src/SDCCsymt.c dinks with
3618 * the S_TYPE in ways the PIC port doesn't fully like...*/
3619 /*-----------------------------------------------------------------*/
3620 void isData(sym_link *sl)
3630 for ( ; sl; sl=sl->next) {
3632 switch (SPEC_SCLS(sl)) {
3634 case S_DATA: fprintf (of, "data "); break;
3635 case S_XDATA: fprintf (of, "xdata "); break;
3636 case S_SFR: fprintf (of, "sfr "); break;
3637 case S_SBIT: fprintf (of, "sbit "); break;
3638 case S_CODE: fprintf (of, "code "); break;
3639 case S_IDATA: fprintf (of, "idata "); break;
3640 case S_PDATA: fprintf (of, "pdata "); break;
3641 case S_LITERAL: fprintf (of, "literal "); break;
3642 case S_STACK: fprintf (of, "stack "); break;
3643 case S_XSTACK: fprintf (of, "xstack "); break;
3644 case S_BIT: fprintf (of, "bit "); break;
3645 case S_EEPROM: fprintf (of, "eeprom "); break;
3654 /*-----------------------------------------------------------------*/
3655 /* packRegisters - does some transformations to reduce register */
3657 /*-----------------------------------------------------------------*/
3659 packRegisters (eBBlock * ebp)
3664 debugLog ("%s\n", __FUNCTION__);
3670 /* look for assignments of the form */
3671 /* iTempNN = TRueSym (someoperation) SomeOperand */
3673 /* TrueSym := iTempNN:1 */
3674 for (ic = ebp->sch; ic; ic = ic->next)
3677 /* find assignment of the form TrueSym := iTempNN:1 */
3678 if (ic->op == '=' && !POINTER_SET (ic))
3679 change += packRegsForAssign (ic, ebp);
3683 if (POINTER_SET (ic))
3684 debugLog ("pointer is set\n");
3685 debugAopGet (" result:", IC_RESULT (ic));
3686 debugAopGet (" left:", IC_LEFT (ic));
3687 debugAopGet (" right:", IC_RIGHT (ic));
3696 for (ic = ebp->sch; ic; ic = ic->next) {
3698 if(IS_SYMOP ( IC_LEFT(ic))) {
3699 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3701 debugAopGet (" left:", IC_LEFT (ic));
3702 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3703 debugLog (" is a pointer\n");
3705 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3706 debugLog (" is volatile\n");
3710 printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
3713 if(IS_SYMOP ( IC_RIGHT(ic))) {
3714 debugAopGet (" right:", IC_RIGHT (ic));
3715 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3718 if(IS_SYMOP ( IC_RESULT(ic))) {
3719 debugAopGet (" result:", IC_RESULT (ic));
3720 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3723 if (POINTER_SET (ic))
3724 debugLog (" %d - Pointer set\n", __LINE__);
3727 /* if this is an itemp & result of a address of a true sym
3728 then mark this as rematerialisable */
3729 if (ic->op == ADDRESS_OF &&
3730 IS_ITEMP (IC_RESULT (ic)) &&
3731 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3732 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3733 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3736 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3738 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3739 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3740 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3744 /* if straight assignment then carry remat flag if
3745 this is the only definition */
3746 if (ic->op == '=' &&
3747 !POINTER_SET (ic) &&
3748 IS_SYMOP (IC_RIGHT (ic)) &&
3749 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3750 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3752 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3754 OP_SYMBOL (IC_RESULT (ic))->remat =
3755 OP_SYMBOL (IC_RIGHT (ic))->remat;
3756 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3757 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3760 /* if this is a +/- operation with a rematerizable
3761 then mark this as rematerializable as well */
3762 if ((ic->op == '+' || ic->op == '-') &&
3763 (IS_SYMOP (IC_LEFT (ic)) &&
3764 IS_ITEMP (IC_RESULT (ic)) &&
3765 OP_SYMBOL (IC_LEFT (ic))->remat &&
3766 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3767 IS_OP_LITERAL (IC_RIGHT (ic))))
3769 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3771 operandLitValue (IC_RIGHT (ic));
3772 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3773 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3774 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3777 /* mark the pointer usages */
3778 if (POINTER_SET (ic))
3780 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3781 debugLog (" marking as a pointer (set) =>");
3782 debugAopGet (" result:", IC_RESULT (ic));
3784 if (POINTER_GET (ic))
3786 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3787 debugLog (" marking as a pointer (get) =>");
3788 debugAopGet (" left:", IC_LEFT (ic));
3793 /* if we are using a symbol on the stack
3794 then we should say pic14_ptrRegReq */
3795 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3796 pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3797 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3798 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3799 pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3800 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3803 if (IS_SYMOP (IC_LEFT (ic)))
3804 pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3805 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3806 if (IS_SYMOP (IC_RIGHT (ic)))
3807 pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3808 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3809 if (IS_SYMOP (IC_RESULT (ic)))
3810 pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3811 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3814 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
3818 /* if the condition of an if instruction
3819 is defined in the previous instruction then
3820 mark the itemp as a conditional */
3821 if ((IS_CONDITIONAL (ic) ||
3822 ((ic->op == BITWISEAND ||
3825 isBitwiseOptimizable (ic))) &&
3826 ic->next && ic->next->op == IFX &&
3827 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3828 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3831 debugLog (" %d\n", __LINE__);
3832 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3836 /* reduce for support function calls */
3837 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3838 packRegsForSupport (ic, ebp);
3840 /* if a parameter is passed, it's in W, so we may not
3841 need to place a copy in a register */
3842 if (ic->op == RECEIVE)
3843 packForReceive (ic, ebp);
3845 /* some cases the redundant moves can
3846 can be eliminated for return statements */
3847 if ((ic->op == RETURN || ic->op == SEND) &&
3848 !isOperandInFarSpace (IC_LEFT (ic)) &&
3850 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3852 /* if pointer set & left has a size more than
3853 one and right is not in far space */
3854 if (POINTER_SET (ic) &&
3855 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3856 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3857 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3858 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3860 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3862 /* if pointer get */
3863 if (POINTER_GET (ic) &&
3864 !isOperandInFarSpace (IC_RESULT (ic)) &&
3865 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3866 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3867 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3869 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3872 /* if this is cast for intergral promotion then
3873 check if only use of the definition of the
3874 operand being casted/ if yes then replace
3875 the result of that arithmetic operation with
3876 this result and get rid of the cast */
3877 if (ic->op == CAST) {
3879 sym_link *fromType = operandType (IC_RIGHT (ic));
3880 sym_link *toType = operandType (IC_LEFT (ic));
3882 debugLog (" %d - casting\n", __LINE__);
3884 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3885 getSize (fromType) != getSize (toType)) {
3888 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3891 if (IS_ARITHMETIC_OP (dic)) {
3893 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3894 IC_RESULT (dic) = IC_RESULT (ic);
3895 remiCodeFromeBBlock (ebp, ic);
3896 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3897 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3898 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3902 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3906 /* if the type from and type to are the same
3907 then if this is the only use then packit */
3908 if (compareType (operandType (IC_RIGHT (ic)),
3909 operandType (IC_LEFT (ic))) == 1) {
3911 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3914 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3915 IC_RESULT (dic) = IC_RESULT (ic);
3916 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3917 remiCodeFromeBBlock (ebp, ic);
3918 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3919 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3927 iTempNN := (some variable in farspace) V1
3932 if (ic->op == IPUSH)
3934 packForPush (ic, ebp);
3938 /* pack registers for accumulator use, when the
3939 result of an arithmetic or bit wise operation
3940 has only one use, that use is immediately following
3941 the defintion and the using iCode has only one
3942 operand or has two operands but one is literal &
3943 the result of that operation is not on stack then
3944 we can leave the result of this operation in acc:b
3946 if ((IS_ARITHMETIC_OP (ic)
3948 || IS_BITWISE_OP (ic)
3950 || ic->op == LEFT_OP || ic->op == RIGHT_OP
3953 IS_ITEMP (IC_RESULT (ic)) &&
3954 getSize (operandType (IC_RESULT (ic))) <= 2)
3956 packRegsForAccUse (ic);
3962 dumpEbbsToDebug (eBBlock ** ebbs, int count)
3966 if (!debug || !debugF)
3969 for (i = 0; i < count; i++)
3971 fprintf (debugF, "\n----------------------------------------------------------------\n");
3972 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
3973 ebbs[i]->entryLabel->name,
3976 ebbs[i]->isLastInLoop);
3977 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
3982 fprintf (debugF, "visited %d : hasFcall = %d\n",
3986 fprintf (debugF, "\ndefines bitVector :");
3987 bitVectDebugOn (ebbs[i]->defSet, debugF);
3988 fprintf (debugF, "\nlocal defines bitVector :");
3989 bitVectDebugOn (ebbs[i]->ldefs, debugF);
3990 fprintf (debugF, "\npointers Set bitvector :");
3991 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
3992 fprintf (debugF, "\nin pointers Set bitvector :");
3993 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
3994 fprintf (debugF, "\ninDefs Set bitvector :");
3995 bitVectDebugOn (ebbs[i]->inDefs, debugF);
3996 fprintf (debugF, "\noutDefs Set bitvector :");
3997 bitVectDebugOn (ebbs[i]->outDefs, debugF);
3998 fprintf (debugF, "\nusesDefs Set bitvector :");
3999 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4000 fprintf (debugF, "\n----------------------------------------------------------------\n");
4001 printiCChain (ebbs[i]->sch, debugF);
4004 /*-----------------------------------------------------------------*/
4005 /* assignRegisters - assigns registers to each live range as need */
4006 /*-----------------------------------------------------------------*/
4008 pic14_assignRegisters (eBBlock ** ebbs, int count)
4013 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
4014 debugLog ("\nebbs before optimizing:\n");
4015 dumpEbbsToDebug (ebbs, count);
4017 setToNull ((void *) &_G.funcrUsed);
4018 pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4021 /* change assignments this will remove some
4022 live ranges reducing some register pressure */
4023 for (i = 0; i < count; i++)
4024 packRegisters (ebbs[i]);
4031 debugLog("dir registers allocated so far:\n");
4032 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4035 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4036 reg = hTabNextItem(dynDirectRegNames, &hkey);
4041 if (options.dump_pack)
4042 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
4044 /* first determine for each live range the number of
4045 registers & the type of registers required for each */
4048 /* and serially allocate registers */
4049 serialRegAssign (ebbs, count);
4051 /* if stack was extended then tell the user */
4054 /* werror(W_TOOMANY_SPILS,"stack", */
4055 /* _G.stackExtend,currFunc->name,""); */
4061 /* werror(W_TOOMANY_SPILS,"data space", */
4062 /* _G.dataExtend,currFunc->name,""); */
4066 /* after that create the register mask
4067 for each of the instruction */
4068 createRegMask (ebbs, count);
4070 /* redo that offsets for stacked automatic variables */
4071 redoStackOffsets ();
4073 if (options.dump_rassgn)
4074 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
4076 /* now get back the chain */
4077 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4079 debugLog ("ebbs after optimizing:\n");
4080 dumpEbbsToDebug (ebbs, count);
4085 /* free up any _G.stackSpil locations allocated */
4086 applyToSet (_G.stackSpil, deallocStackSpil);
4088 setToNull ((void *) &_G.stackSpil);
4089 setToNull ((void *) &_G.spiltSet);
4090 /* mark all registers as free */
4091 //pic14_freeAllRegs ();
4093 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");