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 -------------------------------------------------------------------------*/
33 #if defined(__BORLANDC__) || defined(_MSC_VER)
34 #define STRCASECMP stricmp
35 #define FENTRY2 1 ? (void)0 : printf
37 #define STRCASECMP strcasecmp
38 //#define FENTRY2(fmt,...) do { fprintf (stderr, "%s:%d: called.\n", __FUNCTION__, __LINE__); fprintf (stderr, fmt, ## __VA_ARGS__); } while (0)
39 #define FENTRY2 1 ? (void)0 : printf
42 /* this should go in SDCCicode.h, but it doesn't. */
43 #define IS_REF(op) (IS_SYMOP(op) && op->operand.symOperand->isref == 1)
45 /*-----------------------------------------------------------------*/
46 /* At this point we start getting processor specific although */
47 /* some routines are non-processor specific & can be reused when */
48 /* targetting other processors. The decision for this will have */
49 /* to be made on a routine by routine basis */
50 /* routines used to pack registers are most definitely not reusable */
51 /* since the pack the registers depending strictly on the MCU */
52 /*-----------------------------------------------------------------*/
54 extern void genpic14Code (iCode *);
55 extern void assignConfigWordValue(int address, int value);
65 bitVect *funcrUsed; /* registers used in a function */
71 /* Shared with gen.c */
72 int pic14_ptrRegReq; /* one byte pointer register required */
75 set *dynAllocRegs=NULL;
76 set *dynStackRegs=NULL;
77 set *dynProcessorRegs=NULL;
78 set *dynDirectRegs=NULL;
79 set *dynDirectBitRegs=NULL;
80 set *dynInternalRegs=NULL;
82 static hTab *dynDirectRegNames= NULL;
83 // static hTab *regHash = NULL; /* a hash table containing ALL registers */
85 static int dynrIdx=0x20;
86 static int rDirectIdx=0;
88 int pic14_nRegs = 128; // = sizeof (regspic14) / sizeof (regs);
90 int Gstack_base_addr=0; /* The starting address of registers that
91 * are used to pass and return parameters */
96 static void spillThis (symbol *);
98 static FILE *debugF = NULL;
99 /*-----------------------------------------------------------------*/
100 /* debugLog - open a file for debugging information */
101 /*-----------------------------------------------------------------*/
102 //static void debugLog(char *inst,char *fmt, ...)
104 debugLog (char *fmt,...)
106 static int append = 0; // First time through, open the file without append.
109 //char *bufferP=buffer;
112 if (!debug || !dstFileName)
118 /* create the file name */
119 strcpy (buffer, dstFileName);
120 strcat (buffer, ".d");
122 if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
124 werror (E_FILE_OPEN_ERR, buffer);
127 append = 1; // Next time debubLog is called, we'll append the debug info
133 vsprintf (buffer, fmt, ap);
135 fprintf (debugF, "%s", buffer);
137 while (isspace(*bufferP)) bufferP++;
139 if (bufferP && *bufferP)
140 lineCurr = (lineCurr ?
141 connectLine(lineCurr,newLineNode(lb)) :
142 (lineHead = newLineNode(lb)));
143 lineCurr->isInline = _G.inLine;
144 lineCurr->isDebug = _G.debugLine;
154 fputc ('\n', debugF);
156 /*-----------------------------------------------------------------*/
157 /* debugLogClose - closes the debug log file (if opened) */
158 /*-----------------------------------------------------------------*/
168 #define AOP(op) op->aop
171 debugAopGet (char *str, operand * op)
176 printOperand (op, debugF);
184 decodeOp (unsigned int op)
187 if (op < 128 && op > ' ')
189 buffer[0] = (op & 0xff);
203 return "STRING_LITERAL";
239 return "LEFT_ASSIGN";
241 return "RIGHT_ASSIGN";
356 case GET_VALUE_AT_ADDRESS:
357 return "GET_VALUE_AT_ADDRESS";
375 return "ENDFUNCTION";
399 sprintf (buffer, "unknown op %d %c", op, op & 0xff);
402 /*-----------------------------------------------------------------*/
403 /*-----------------------------------------------------------------*/
405 debugLogRegType (short type)
418 sprintf (buffer, "unknown reg type %d", type);
422 /*-----------------------------------------------------------------*/
423 /*-----------------------------------------------------------------*/
424 static int regname2key(char const *name)
433 key += (*name++) + 1;
437 return ( (key + (key >> 4) + (key>>8)) & 0x3f);
441 /*-----------------------------------------------------------------*/
442 /* newReg - allocate and init memory for a new register */
443 /*-----------------------------------------------------------------*/
444 static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias)
449 dReg = Safe_calloc(1,sizeof(regs));
451 dReg->pc_type = pc_type;
454 dReg->name = Safe_strdup(name);
456 sprintf(buffer,"r0x%02X", dReg->rIdx);
457 dReg->name = Safe_strdup(buffer);
459 //fprintf(stderr,"newReg: %s, rIdx = 0x%02x\n",dReg->name,rIdx);
474 dReg->reg_alias = NULL;
475 dReg->reglives.usedpFlows = newSet();
476 dReg->reglives.assignedpFlows = newSet();
478 hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
483 /*-----------------------------------------------------------------*/
484 /* regWithIdx - Search through a set of registers that matches idx */
485 /*-----------------------------------------------------------------*/
487 regWithIdx (set *dRegs, int idx, int fixed)
491 for (dReg = setFirstItem(dRegs) ; dReg ;
492 dReg = setNextItem(dRegs)) {
494 if(idx == dReg->rIdx && (fixed == (int)dReg->isFixed)) {
502 /*-----------------------------------------------------------------*/
503 /* regWithName - Search through a set of registers that matches name */
504 /*-----------------------------------------------------------------*/
506 regWithName (set *dRegs, const char *name)
510 for (dReg = setFirstItem(dRegs) ; dReg ;
511 dReg = setNextItem(dRegs)) {
513 if((strcmp(name,dReg->name)==0)) {
521 /*-----------------------------------------------------------------*/
522 /* regWithName - Search for a registers that matches name */
523 /*-----------------------------------------------------------------*/
525 regFindWithName (const char *name)
529 if( (dReg = regWithName ( dynDirectRegs, name)) != NULL ) {
530 debugLog ("Found a Direct Register!\n");
533 if( (dReg = regWithName ( dynDirectBitRegs, name)) != NULL) {
534 debugLog ("Found a Direct Bit Register!\n");
538 if (*name=='_') name++; // Step passed '_'
540 if( (dReg = regWithName ( dynAllocRegs, name)) != NULL) {
541 debugLog ("Found a Dynamic Register!\n");
544 if( (dReg = regWithName ( dynProcessorRegs, name)) != NULL) {
545 debugLog ("Found a Processor Register!\n");
548 if( (dReg = regWithName ( dynInternalRegs, name)) != NULL) {
549 debugLog ("Found an Internal Register!\n");
552 if( (dReg = regWithName ( dynStackRegs, name)) != NULL) {
553 debugLog ("Found an Stack Register!\n");
560 /*-----------------------------------------------------------------*/
561 /* regFindFree - Search for a free register in a set of registers */
562 /*-----------------------------------------------------------------*/
564 regFindFree (set *dRegs)
568 for (dReg = setFirstItem(dRegs) ; dReg ;
569 dReg = setNextItem(dRegs)) {
577 /*-----------------------------------------------------------------*/
578 /* initStack - allocate registers for a psuedo stack */
579 /*-----------------------------------------------------------------*/
580 void initStack(int base_address, int size)
585 Gstack_base_addr = base_address;
586 //fprintf(stderr,"initStack");
588 for(i = 0; i<size; i++) {
589 regs *r = newReg(REG_STK, PO_GPR_TEMP,base_address,NULL,1,0);
590 r->address = base_address; // Pseudo stack needs a fixed location that can be known by all modules
593 r->alias = 0x180; // Using shared memory for pseudo stack
594 addSet(&dynStackRegs,r);
599 /*-----------------------------------------------------------------*
600 *-----------------------------------------------------------------*/
602 allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
605 //fprintf(stderr,"allocProcessorRegister %s addr =0x%x\n",name,rIdx);
606 return addSet(&dynProcessorRegs,newReg(REG_SFR, po_type, rIdx, name,1,alias));
609 /*-----------------------------------------------------------------*
610 *-----------------------------------------------------------------*/
613 allocInternalRegister(int rIdx, char * name, short po_type, int alias)
615 regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias);
617 //fprintf(stderr,"allocInternalRegister %s addr =0x%x\n",name,rIdx);
620 return addSet(&dynInternalRegs,reg);
625 /*-----------------------------------------------------------------*/
626 /* allocReg - allocates register of given type */
627 /*-----------------------------------------------------------------*/
629 allocReg (short type)
632 debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
633 //fprintf(stderr,"allocReg\n");
636 return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
641 /*-----------------------------------------------------------------*/
642 /* dirregWithName - search for register by name */
643 /*-----------------------------------------------------------------*/
645 dirregWithName (char *name)
653 /* hash the name to get a key */
655 hkey = regname2key(name);
657 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
661 if(STRCASECMP(reg->name, name) == 0) {
665 reg = hTabNextItemWK (dynDirectRegNames);
669 return NULL; // name wasn't found in the hash table
672 int IS_CONFIG_ADDRESS(int address)
675 return address == 0x2007;
678 /*-----------------------------------------------------------------*/
679 /* allocNewDirReg - allocates a new register of given type */
680 /*-----------------------------------------------------------------*/
682 allocNewDirReg (sym_link *symlnk,const char *name)
687 /* if this is at an absolute address, then get the address. */
688 if (SPEC_ABSA (symlnk) ) {
689 address = SPEC_ADDR (symlnk);
690 //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
693 /* Register wasn't found in hash, so let's create
694 * a new one and put it in the hash table AND in the
695 * dynDirectRegNames set */
696 if (IS_CONFIG_ADDRESS(address)) {
697 debugLog (" -- %s is declared at address 0x2007\n",name);
702 if (IS_BITVAR (symlnk))
709 reg = newReg(REG_GPR, PO_DIR, idx, (char*)name,getSize (symlnk),0 );
710 debugLog (" -- added %s to hash, size = %d\n", (char*)name,reg->size);
712 if (SPEC_ABSA (symlnk) ) {
716 if (IS_BITVAR (symlnk)) {
717 addSet(&dynDirectBitRegs, reg);
720 addSet(&dynDirectRegs, reg);
722 if (!IS_STATIC (symlnk)) {
725 if (IS_EXTERN (symlnk)) {
731 if (address && reg) {
733 reg->address = address;
734 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
740 /*-----------------------------------------------------------------*/
741 /* allocDirReg - allocates register of given type */
742 /*-----------------------------------------------------------------*/
744 allocDirReg (operand *op )
751 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
755 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
757 /* If the symbol is at a fixed address, then remove the leading underscore
758 * from the name. This is hack to allow the .asm include file named registers
759 * to match the .c declared register names */
761 //if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && (*name == '_'))
764 debugLog ("%s symbol name %s\n", __FUNCTION__,name);
766 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
767 debugLog(" %d const char\n",__LINE__);
768 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
771 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
772 if (IS_CODE ( OP_SYM_ETYPE(op)) )
773 debugLog(" %d code space\n",__LINE__);
775 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
776 debugLog(" %d integral\n",__LINE__);
777 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
778 debugLog(" %d literal\n",__LINE__);
779 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
780 debugLog(" %d specifier\n",__LINE__);
781 debugAopGet(NULL, op);
784 if (IS_CODE ( OP_SYM_ETYPE(op)) )
787 /* First, search the hash table to see if there is a register with this name */
788 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && !(IS_BITVAR (OP_SYM_ETYPE(op))) ) {
789 reg = regWithIdx (dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1);
792 fprintf(stderr,"ralloc %s is at fixed address but not a processor reg, addr=0x%x\n",
793 name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
795 fprintf(stderr,"ralloc %s at fixed address has already been declared, addr=0x%x\n",
796 name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
799 //fprintf(stderr,"ralloc:%d %s \n", __LINE__,name);
801 reg = dirregWithName(name);
808 /* if this is at an absolute address, then get the address. */
809 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
810 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
811 //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
814 /* Register wasn't found in hash, so let's create
815 * a new one and put it in the hash table AND in the
816 * dynDirectRegNames set */
817 if(!IS_CONFIG_ADDRESS(address)) {
818 //fprintf(stderr,"allocating new reg %s\n",name);
820 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0 );
821 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
823 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
825 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
827 //fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
831 if (IS_BITVAR (OP_SYM_ETYPE(op))) {
832 addSet(&dynDirectBitRegs, reg);
835 addSet(&dynDirectRegs, reg);
837 if (!IS_STATIC (OP_SYM_ETYPE(op))) {
840 if (IS_EXTERN (OP_SYM_ETYPE(op))) {
846 debugLog (" -- %s is declared at address 0x2007\n",name);
851 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
853 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
854 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
859 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
861 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
862 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
865 allocNewDirReg (OP_SYM_ETYPE(op),name);
872 /*-----------------------------------------------------------------*/
873 /* allocRegByName - allocates register with given name */
874 /*-----------------------------------------------------------------*/
876 allocRegByName (char *name, int size)
882 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
886 /* First, search the hash table to see if there is a register with this name */
887 reg = dirregWithName(name);
893 /* Register wasn't found in hash, so let's create
894 * a new one and put it in the hash table AND in the
895 * dynDirectRegNames set */
896 //fprintf (stderr,"%s symbol name %s\n", __FUNCTION__,name);
897 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0 );
898 for (sym = setFirstItem(sfr->syms); sym; sym = setNextItem(sfr->syms)) {
899 if (strcmp(reg->name+1,sym->name)==0) {
900 unsigned a = SPEC_ADDR(sym->etype);
904 if (!IS_STATIC (sym->etype)) {
907 if (IS_EXTERN (sym->etype)) {
910 if (IS_BITVAR (sym->etype))
917 for (sym = setFirstItem(data->syms); sym; sym = setNextItem(data->syms)) {
918 if (strcmp(reg->name+1,sym->name)==0) {
919 unsigned a = SPEC_ADDR(sym->etype);
921 if (!IS_STATIC (sym->etype)) {
924 if (IS_EXTERN (sym->etype)) {
927 if (IS_BITVAR (sym->etype))
935 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
937 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
938 if (reg->isBitField) {
939 addSet(&dynDirectBitRegs, reg);
941 addSet(&dynDirectRegs, reg);
947 /*-----------------------------------------------------------------*/
948 /* RegWithIdx - returns pointer to register with index number */
949 /*-----------------------------------------------------------------*/
951 typeRegWithIdx (int idx, int type, int fixed)
956 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
961 if( (dReg = regWithIdx ( dynAllocRegs, idx, fixed)) != NULL) {
963 debugLog ("Found a Dynamic Register!\n");
966 if( (dReg = regWithIdx ( dynDirectRegs, idx, fixed)) != NULL ) {
967 debugLog ("Found a Direct Register!\n");
973 if( (dReg = regWithIdx ( dynStackRegs, idx, fixed)) != NULL ) {
974 debugLog ("Found a Stack Register!\n");
978 werror (E_STACK_OUT, "Register");
979 /* return an existing register just to avoid the SDCC crash */
980 return regWithIdx ( dynStackRegs, 0x7f, fixed);
984 if( (dReg = regWithIdx ( dynProcessorRegs, idx, fixed)) != NULL ) {
985 debugLog ("Found a Processor Register!\n");
999 /*-----------------------------------------------------------------*/
1000 /* pic14_regWithIdx - returns pointer to register with index number*/
1001 /*-----------------------------------------------------------------*/
1003 pic14_regWithIdx (int idx)
1007 if( (dReg = typeRegWithIdx(idx,REG_GPR,0)) != NULL)
1010 if( (dReg = typeRegWithIdx(idx,REG_SFR,0)) != NULL)
1016 /*-----------------------------------------------------------------*/
1017 /* pic14_regWithIdx - returns pointer to register with index number */
1018 /*-----------------------------------------------------------------*/
1020 pic14_allocWithIdx (int idx)
1025 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
1027 if( (dReg = regWithIdx ( dynAllocRegs, idx,0)) != NULL) {
1029 debugLog ("Found a Dynamic Register!\n");
1030 } else if( (dReg = regWithIdx ( dynStackRegs, idx,0)) != NULL ) {
1031 debugLog ("Found a Stack Register!\n");
1032 } else if( (dReg = regWithIdx ( dynProcessorRegs, idx,0)) != NULL ) {
1033 debugLog ("Found a Processor Register!\n");
1034 } else if( (dReg = regWithIdx ( dynInternalRegs, idx,0)) != NULL ) {
1035 debugLog ("Found an Internal Register!\n");
1036 } else if( (dReg = regWithIdx ( dynInternalRegs, idx,1)) != NULL ) {
1037 debugLog ("Found an Internal Register!\n");
1040 debugLog ("Dynamic Register not found\n");
1043 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
1044 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1045 "regWithIdx not found");
1055 /*-----------------------------------------------------------------*/
1056 /*-----------------------------------------------------------------*/
1058 pic14_findFreeReg(short type)
1065 if((dReg = regFindFree(dynAllocRegs)) != NULL)
1067 return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
1071 if((dReg = regFindFree(dynStackRegs)) != NULL)
1083 /*-----------------------------------------------------------------*/
1084 /* freeReg - frees a register */
1085 /*-----------------------------------------------------------------*/
1087 freeReg (regs * reg)
1089 debugLog ("%s\n", __FUNCTION__);
1094 /*-----------------------------------------------------------------*/
1095 /* nFreeRegs - returns number of free registers */
1096 /*-----------------------------------------------------------------*/
1098 nFreeRegs (int type)
1100 /* dynamically allocate as many as we need and worry about
1101 * fitting them into a PIC later */
1108 debugLog ("%s\n", __FUNCTION__);
1109 for (i = 0; i < pic14_nRegs; i++)
1110 if (regspic14[i].isFree && regspic14[i].type == type)
1116 /*-----------------------------------------------------------------*/
1117 /* nfreeRegsType - free registers with type */
1118 /*-----------------------------------------------------------------*/
1120 nfreeRegsType (int type)
1123 debugLog ("%s\n", __FUNCTION__);
1124 if (type == REG_PTR)
1126 if ((nfr = nFreeRegs (type)) == 0)
1127 return nFreeRegs (REG_GPR);
1130 return nFreeRegs (type);
1133 void writeSetUsedRegs(FILE *of, set *dRegs)
1138 for (dReg = setFirstItem(dRegs) ; dReg ;
1139 dReg = setNextItem(dRegs)) {
1142 fprintf (of, "\t%s\n",dReg->name);
1146 extern void assignFixedRegisters(set *regset);
1147 extern void assignRelocatableRegisters(set *regset,int used);
1148 extern void dump_map(void);
1149 extern void dump_sfr(FILE *of);
1151 void packBits(set *bregs)
1155 regs *bitfield=NULL;
1156 regs *relocbitfield=NULL;
1162 for (regset = bregs ; regset ;
1163 regset = regset->next) {
1165 breg = regset->item;
1166 breg->isBitField = 1;
1167 //fprintf(stderr,"bit reg: %s\n",breg->name);
1170 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
1172 bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1);
1173 breg->rIdx = breg->address & 7;
1174 breg->address >>= 3;
1177 //sprintf (buffer, "fbitfield%02x", breg->address);
1178 sprintf (buffer, "0x%02x", breg->address);
1179 //fprintf(stderr,"new bit field\n");
1180 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0);
1181 bitfield->isBitField = 1;
1182 bitfield->isFixed = 1;
1183 bitfield->address = breg->address;
1184 //addSet(&dynDirectRegs,bitfield);
1185 addSet(&dynInternalRegs,bitfield);
1186 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
1188 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
1191 breg->reg_alias = bitfield;
1195 if(!relocbitfield || bit_no >7) {
1198 sprintf (buffer, "bitfield%d", byte_no);
1199 //fprintf(stderr,"new relocatable bit field\n");
1200 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0);
1201 relocbitfield->isBitField = 1;
1202 //addSet(&dynDirectRegs,relocbitfield);
1203 addSet(&dynInternalRegs,relocbitfield);
1204 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1208 breg->reg_alias = relocbitfield;
1209 breg->address = rDirectIdx; /* byte_no; */
1210 breg->rIdx = bit_no++;
1218 void bitEQUs(FILE *of, set *bregs)
1220 regs *breg,*bytereg;
1223 //fprintf(stderr," %s\n",__FUNCTION__);
1224 for (breg = setFirstItem(bregs) ; breg ;
1225 breg = setNextItem(bregs)) {
1227 //fprintf(stderr,"bit reg: %s\n",breg->name);
1229 bytereg = breg->reg_alias;
1231 fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
1234 breg->rIdx & 0x0007);
1237 //fprintf(stderr, "bit field is not assigned to a register\n");
1238 fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
1248 void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
1253 for (reg = setFirstItem(fregs) ; reg ;
1254 reg = setNextItem(fregs)) {
1256 //if(!reg->isEmitted && reg->wasUsed) {
1259 fprintf (of, "%s\tEQU\t0x%03x\n",
1263 fprintf (of, "%s\tEQU\t0x%03x\n",
1271 void writeUsedRegs(FILE *of)
1273 packBits(dynDirectBitRegs);
1275 assignFixedRegisters(dynInternalRegs);
1276 assignFixedRegisters(dynAllocRegs);
1277 assignFixedRegisters(dynStackRegs);
1278 assignFixedRegisters(dynDirectRegs);
1280 assignRelocatableRegisters(dynInternalRegs,0);
1281 assignRelocatableRegisters(dynAllocRegs,0);
1282 assignRelocatableRegisters(dynStackRegs,0);
1285 assignRelocatableRegisters(dynDirectRegs,0);
1286 printf("assignRelocatableRegisters(dynDirectRegs,0);\n");
1291 bitEQUs(of,dynDirectBitRegs);
1293 aliasEQUs(of,dynAllocRegs,0);
1294 aliasEQUs(of,dynDirectRegs,0);
1295 aliasEQUs(of,dynStackRegs,0);
1296 aliasEQUs(of,dynProcessorRegs,1);
1301 /*-----------------------------------------------------------------*/
1302 /* allDefsOutOfRange - all definitions are out of a range */
1303 /*-----------------------------------------------------------------*/
1305 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
1309 debugLog ("%s\n", __FUNCTION__);
1313 for (i = 0; i < defs->size; i++)
1317 if (bitVectBitValue (defs, i) &&
1318 (ic = hTabItemWithKey (iCodehTab, i)) &&
1319 (ic->seq >= fseq && ic->seq <= toseq))
1329 /*-----------------------------------------------------------------*/
1330 /* computeSpillable - given a point find the spillable live ranges */
1331 /*-----------------------------------------------------------------*/
1333 computeSpillable (iCode * ic)
1337 debugLog ("%s\n", __FUNCTION__);
1338 /* spillable live ranges are those that are live at this
1339 point . the following categories need to be subtracted
1341 a) - those that are already spilt
1342 b) - if being used by this one
1343 c) - defined by this one */
1345 spillable = bitVectCopy (ic->rlive);
1347 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1349 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1350 bitVectUnSetBit (spillable, ic->defKey);
1351 spillable = bitVectIntersect (spillable, _G.regAssigned);
1356 /*-----------------------------------------------------------------*/
1357 /* noSpilLoc - return true if a variable has no spil location */
1358 /*-----------------------------------------------------------------*/
1360 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1362 debugLog ("%s\n", __FUNCTION__);
1363 return (sym->usl.spillLoc ? 0 : 1);
1366 /*-----------------------------------------------------------------*/
1367 /* hasSpilLoc - will return 1 if the symbol has spil location */
1368 /*-----------------------------------------------------------------*/
1370 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1372 debugLog ("%s\n", __FUNCTION__);
1373 return (sym->usl.spillLoc ? 1 : 0);
1376 /*-----------------------------------------------------------------*/
1377 /* directSpilLoc - will return 1 if the splilocation is in direct */
1378 /*-----------------------------------------------------------------*/
1380 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1382 debugLog ("%s\n", __FUNCTION__);
1383 if (sym->usl.spillLoc &&
1384 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1390 /*-----------------------------------------------------------------*/
1391 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1392 /* but is not used as a pointer */
1393 /*-----------------------------------------------------------------*/
1395 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1397 debugLog ("%s\n", __FUNCTION__);
1398 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1401 /*-----------------------------------------------------------------*/
1402 /* rematable - will return 1 if the remat flag is set */
1403 /*-----------------------------------------------------------------*/
1405 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1407 debugLog ("%s\n", __FUNCTION__);
1411 /*-----------------------------------------------------------------*/
1412 /* notUsedInRemaining - not used or defined in remain of the block */
1413 /*-----------------------------------------------------------------*/
1415 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1417 debugLog ("%s\n", __FUNCTION__);
1418 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1419 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1422 /*-----------------------------------------------------------------*/
1423 /* allLRs - return true for all */
1424 /*-----------------------------------------------------------------*/
1426 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1428 debugLog ("%s\n", __FUNCTION__);
1432 /*-----------------------------------------------------------------*/
1433 /* liveRangesWith - applies function to a given set of live range */
1434 /*-----------------------------------------------------------------*/
1436 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1437 eBBlock * ebp, iCode * ic)
1442 debugLog ("%s\n", __FUNCTION__);
1443 if (!lrs || !lrs->size)
1446 for (i = 1; i < lrs->size; i++)
1449 if (!bitVectBitValue (lrs, i))
1452 /* if we don't find it in the live range
1453 hash table we are in serious trouble */
1454 if (!(sym = hTabItemWithKey (liveRanges, i)))
1456 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1457 "liveRangesWith could not find liveRange");
1461 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1462 addSetHead (&rset, sym);
1469 /*-----------------------------------------------------------------*/
1470 /* leastUsedLR - given a set determines which is the least used */
1471 /*-----------------------------------------------------------------*/
1473 leastUsedLR (set * sset)
1475 symbol *sym = NULL, *lsym = NULL;
1477 debugLog ("%s\n", __FUNCTION__);
1478 sym = lsym = setFirstItem (sset);
1483 for (; lsym; lsym = setNextItem (sset))
1486 /* if usage is the same then prefer
1487 the spill the smaller of the two */
1488 if (lsym->used == sym->used)
1489 if (getSize (lsym->type) < getSize (sym->type))
1493 if (lsym->used < sym->used)
1498 setToNull ((void *) &sset);
1503 /*-----------------------------------------------------------------*/
1504 /* noOverLap - will iterate through the list looking for over lap */
1505 /*-----------------------------------------------------------------*/
1507 noOverLap (set * itmpStack, symbol * fsym)
1510 debugLog ("%s\n", __FUNCTION__);
1513 for (sym = setFirstItem (itmpStack); sym;
1514 sym = setNextItem (itmpStack))
1516 if (sym->liveTo > fsym->liveFrom)
1524 /*-----------------------------------------------------------------*/
1525 /* isFree - will return 1 if the a free spil location is found */
1526 /*-----------------------------------------------------------------*/
1531 V_ARG (symbol **, sloc);
1532 V_ARG (symbol *, fsym);
1534 debugLog ("%s\n", __FUNCTION__);
1535 /* if already found */
1539 /* if it is free && and the itmp assigned to
1540 this does not have any overlapping live ranges
1541 with the one currently being assigned and
1542 the size can be accomodated */
1544 noOverLap (sym->usl.itmpStack, fsym) &&
1545 getSize (sym->type) >= getSize (fsym->type))
1554 /*-----------------------------------------------------------------*/
1555 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1556 /*-----------------------------------------------------------------*/
1558 spillLRWithPtrReg (symbol * forSym)
1564 debugLog ("%s\n", __FUNCTION__);
1565 if (!_G.regAssigned ||
1566 bitVectIsZero (_G.regAssigned))
1569 r0 = pic14_regWithIdx (R0_IDX);
1570 r1 = pic14_regWithIdx (R1_IDX);
1572 /* for all live ranges */
1573 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1574 lrsym = hTabNextItem (liveRanges, &k))
1578 /* if no registers assigned to it or
1580 /* if it does not overlap with this then
1581 not need to spill it */
1583 if (lrsym->isspilt || !lrsym->nRegs ||
1584 (lrsym->liveTo < forSym->liveFrom))
1587 /* go thru the registers : if it is either
1588 r0 or r1 then spil it */
1589 for (j = 0; j < lrsym->nRegs; j++)
1590 if (lrsym->regs[j] == r0 ||
1591 lrsym->regs[j] == r1)
1600 /*-----------------------------------------------------------------*/
1601 /* createStackSpil - create a location on the stack to spil */
1602 /*-----------------------------------------------------------------*/
1604 createStackSpil (symbol * sym)
1606 symbol *sloc = NULL;
1607 int useXstack, model, noOverlay;
1609 char slocBuffer[30];
1610 debugLog ("%s\n", __FUNCTION__);
1614 /* first go try and find a free one that is already
1615 existing on the stack */
1616 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1618 /* found a free one : just update & return */
1619 sym->usl.spillLoc = sloc;
1622 addSetHead (&sloc->usl.itmpStack, sym);
1626 /* could not then have to create one , this is the hard part
1627 we need to allocate this on the stack : this is really a
1628 hack!! but cannot think of anything better at this time */
1630 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1632 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1633 __FILE__, __LINE__);
1637 sloc = newiTemp (slocBuffer);
1639 /* set the type to the spilling symbol */
1640 sloc->type = copyLinkChain (sym->type);
1641 sloc->etype = getSpec (sloc->type);
1642 SPEC_SCLS (sloc->etype) = S_DATA;
1643 SPEC_EXTR (sloc->etype) = 0;
1644 SPEC_STAT (sloc->etype) = 0;
1646 /* we don't allow it to be allocated`
1647 onto the external stack since : so we
1648 temporarily turn it off ; we also
1649 turn off memory model to prevent
1650 the spil from going to the external storage
1651 and turn off overlaying
1654 useXstack = options.useXstack;
1655 model = options.model;
1656 noOverlay = options.noOverlay;
1657 options.noOverlay = 1;
1658 options.model = options.useXstack = 0;
1662 options.useXstack = useXstack;
1663 options.model = model;
1664 options.noOverlay = noOverlay;
1665 sloc->isref = 1; /* to prevent compiler warning */
1667 /* if it is on the stack then update the stack */
1668 if (IN_STACK (sloc->etype))
1670 currFunc->stack += getSize (sloc->type);
1671 _G.stackExtend += getSize (sloc->type);
1674 _G.dataExtend += getSize (sloc->type);
1676 /* add it to the _G.stackSpil set */
1677 addSetHead (&_G.stackSpil, sloc);
1678 sym->usl.spillLoc = sloc;
1681 /* add it to the set of itempStack set
1682 of the spill location */
1683 addSetHead (&sloc->usl.itmpStack, sym);
1687 /*-----------------------------------------------------------------*/
1688 /* isSpiltOnStack - returns true if the spil location is on stack */
1689 /*-----------------------------------------------------------------*/
1691 isSpiltOnStack (symbol * sym)
1695 debugLog ("%s\n", __FUNCTION__);
1704 /* if (sym->_G.stackSpil) */
1707 if (!sym->usl.spillLoc)
1710 etype = getSpec (sym->usl.spillLoc->type);
1711 if (IN_STACK (etype))
1717 /*-----------------------------------------------------------------*/
1718 /* spillThis - spils a specific operand */
1719 /*-----------------------------------------------------------------*/
1721 spillThis (symbol * sym)
1724 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1725 FENTRY2("sym: %s, spillLoc:%p (%s)\n", sym->rname, sym->usl.spillLoc, sym->usl.spillLoc ? sym->usl.spillLoc->rname : "<unknown>");
1727 /* if this is rematerializable or has a spillLocation
1728 we are okay, else we need to create a spillLocation
1730 if (!(sym->remat || sym->usl.spillLoc))
1731 createStackSpil (sym);
1734 /* mark it has spilt & put it in the spilt set */
1736 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1738 bitVectUnSetBit (_G.regAssigned, sym->key);
1740 for (i = 0; i < sym->nRegs; i++)
1744 freeReg (sym->regs[i]);
1745 sym->regs[i] = NULL;
1749 /* if spilt on stack then free up r0 & r1
1750 if they could have been assigned to some
1752 if (!pic14_ptrRegReq && isSpiltOnStack (sym))
1755 spillLRWithPtrReg (sym);
1758 if (sym->usl.spillLoc && !sym->remat)
1759 sym->usl.spillLoc->allocreq = 1;
1764 /*-----------------------------------------------------------------*/
1765 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1766 /*-----------------------------------------------------------------*/
1768 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1770 bitVect *lrcs = NULL;
1774 debugLog ("%s\n", __FUNCTION__);
1776 /* get the spillable live ranges */
1777 lrcs = computeSpillable (ic);
1780 /* get all live ranges that are rematerizable */
1781 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1783 /* return the least used of these */
1784 return leastUsedLR (selectS);
1787 /* get live ranges with spillLocations in direct space */
1788 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1790 sym = leastUsedLR (selectS);
1791 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1792 sym->usl.spillLoc->rname :
1793 sym->usl.spillLoc->name));
1795 /* mark it as allocation required */
1796 sym->usl.spillLoc->allocreq = 1;
1800 /* if the symbol is local to the block then */
1801 if (forSym->liveTo < ebp->lSeq)
1804 /* check if there are any live ranges allocated
1805 to registers that are not used in this block */
1806 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1808 sym = leastUsedLR (selectS);
1809 /* if this is not rematerializable */
1818 /* check if there are any live ranges that not
1819 used in the remainder of the block */
1820 if (!_G.blockSpil &&
1821 !isiCodeInFunctionCall (ic) &&
1822 (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1824 sym = leastUsedLR (selectS);
1827 sym->remainSpil = 1;
1834 /* find live ranges with spillocation && not used as pointers */
1835 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1838 sym = leastUsedLR (selectS);
1839 /* mark this as allocation required */
1840 sym->usl.spillLoc->allocreq = 1;
1844 /* find live ranges with spillocation */
1845 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1848 sym = leastUsedLR (selectS);
1849 sym->usl.spillLoc->allocreq = 1;
1853 /* couldn't find then we need to create a spil
1854 location on the stack , for which one? the least
1856 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1859 /* return a created spil location */
1860 sym = createStackSpil (leastUsedLR (selectS));
1861 sym->usl.spillLoc->allocreq = 1;
1865 /* this is an extreme situation we will spill
1866 this one : happens very rarely but it does happen */
1872 /*-----------------------------------------------------------------*/
1873 /* spilSomething - spil some variable & mark registers as free */
1874 /*-----------------------------------------------------------------*/
1876 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1881 debugLog ("%s\n", __FUNCTION__);
1882 /* get something we can spil */
1883 ssym = selectSpil (ic, ebp, forSym);
1885 /* mark it as spilt */
1887 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1889 /* mark it as not register assigned &
1890 take it away from the set */
1891 bitVectUnSetBit (_G.regAssigned, ssym->key);
1893 /* mark the registers as free */
1894 for (i = 0; i < ssym->nRegs; i++)
1896 freeReg (ssym->regs[i]);
1898 /* if spilt on stack then free up r0 & r1
1899 if they could have been assigned to as gprs */
1900 if (!pic14_ptrRegReq && isSpiltOnStack (ssym))
1903 spillLRWithPtrReg (ssym);
1906 /* if this was a block level spil then insert push & pop
1907 at the start & end of block respectively */
1908 if (ssym->blockSpil)
1910 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1911 /* add push to the start of the block */
1912 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1913 ebp->sch->next : ebp->sch));
1914 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1915 /* add pop to the end of the block */
1916 addiCodeToeBBlock (ebp, nic, NULL);
1919 /* if spilt because not used in the remainder of the
1920 block then add a push before this instruction and
1921 a pop at the end of the block */
1922 if (ssym->remainSpil)
1925 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1926 /* add push just before this instruction */
1927 addiCodeToeBBlock (ebp, nic, ic);
1929 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1930 /* add pop to the end of the block */
1931 addiCodeToeBBlock (ebp, nic, NULL);
1940 /*-----------------------------------------------------------------*/
1941 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1942 /*-----------------------------------------------------------------*/
1944 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1949 debugLog ("%s\n", __FUNCTION__);
1951 /* try for a ptr type */
1952 if ((reg = allocReg (REG_PTR)))
1955 /* try for gpr type */
1956 if ((reg = allocReg (REG_GPR)))
1959 /* we have to spil */
1960 if (!spilSomething (ic, ebp, sym))
1963 /* make sure partially assigned registers aren't reused */
1964 for (j=0; j<=sym->nRegs; j++)
1966 sym->regs[j]->isFree = 0;
1968 /* this looks like an infinite loop but
1969 in really selectSpil will abort */
1973 /*-----------------------------------------------------------------*/
1974 /* getRegGpr - will try for GPR if not spil */
1975 /*-----------------------------------------------------------------*/
1977 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1982 debugLog ("%s\n", __FUNCTION__);
1984 /* try for gpr type */
1985 if ((reg = allocReg (REG_GPR)))
1988 if (!pic14_ptrRegReq)
1989 if ((reg = allocReg (REG_PTR)))
1992 /* we have to spil */
1993 if (!spilSomething (ic, ebp, sym))
1996 /* make sure partially assigned registers aren't reused */
1997 for (j=0; j<=sym->nRegs; j++)
1999 sym->regs[j]->isFree = 0;
2001 /* this looks like an infinite loop but
2002 in really selectSpil will abort */
2006 /*-----------------------------------------------------------------*/
2007 /* symHasReg - symbol has a given register */
2008 /*-----------------------------------------------------------------*/
2010 symHasReg (symbol * sym, regs * reg)
2014 debugLog ("%s\n", __FUNCTION__);
2015 for (i = 0; i < sym->nRegs; i++)
2016 if (sym->regs[i] == reg)
2022 /*-----------------------------------------------------------------*/
2023 /* deassignLRs - check the live to and if they have registers & are */
2024 /* not spilt then free up the registers */
2025 /*-----------------------------------------------------------------*/
2027 deassignLRs (iCode * ic, eBBlock * ebp)
2033 debugLog ("%s\n", __FUNCTION__);
2034 for (sym = hTabFirstItem (liveRanges, &k); sym;
2035 sym = hTabNextItem (liveRanges, &k))
2038 symbol *psym = NULL;
2039 /* if it does not end here */
2040 if (sym->liveTo > ic->seq)
2043 /* if it was spilt on stack then we can
2044 mark the stack spil location as free */
2049 sym->usl.spillLoc->isFree = 1;
2055 if (!bitVectBitValue (_G.regAssigned, sym->key))
2058 /* special case check if this is an IFX &
2059 the privious one was a pop and the
2060 previous one was not spilt then keep track
2062 if (ic->op == IFX && ic->prev &&
2063 ic->prev->op == IPOP &&
2064 !ic->prev->parmPush &&
2065 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
2066 psym = OP_SYMBOL (IC_LEFT (ic->prev));
2072 bitVectUnSetBit (_G.regAssigned, sym->key);
2074 /* if the result of this one needs registers
2075 and does not have it then assign it right
2077 if (IC_RESULT (ic) &&
2078 !(SKIP_IC2 (ic) || /* not a special icode */
2079 ic->op == JUMPTABLE ||
2084 POINTER_SET (ic)) &&
2085 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
2086 result->liveTo > ic->seq && /* and will live beyond this */
2087 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
2088 result->liveFrom == ic->seq && /* does not start before here */
2089 result->regType == sym->regType && /* same register types */
2090 result->regType == sym->regType && /* same register types */
2091 result->nRegs && /* which needs registers */
2092 !result->isspilt && /* and does not already have them */
2094 !bitVectBitValue (_G.regAssigned, result->key) &&
2095 /* the number of free regs + number of regs in this LR
2096 can accomodate the what result Needs */
2097 ((nfreeRegsType (result->regType) +
2098 sym->nRegs) >= result->nRegs)
2102 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
2104 result->regs[i] = sym->regs[i];
2106 result->regs[i] = getRegGpr (ic, ebp, result);
2108 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
2112 /* free the remaining */
2113 for (; i < sym->nRegs; i++)
2117 if (!symHasReg (psym, sym->regs[i]))
2118 freeReg (sym->regs[i]);
2121 freeReg (sym->regs[i]);
2128 /*-----------------------------------------------------------------*/
2129 /* reassignLR - reassign this to registers */
2130 /*-----------------------------------------------------------------*/
2132 reassignLR (operand * op)
2134 symbol *sym = OP_SYMBOL (op);
2137 debugLog ("%s\n", __FUNCTION__);
2138 /* not spilt any more */
2139 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
2140 bitVectUnSetBit (_G.spiltSet, sym->key);
2142 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2146 for (i = 0; i < sym->nRegs; i++)
2147 sym->regs[i]->isFree = 0;
2150 /*-----------------------------------------------------------------*/
2151 /* willCauseSpill - determines if allocating will cause a spill */
2152 /*-----------------------------------------------------------------*/
2154 willCauseSpill (int nr, int rt)
2156 debugLog ("%s\n", __FUNCTION__);
2157 /* first check if there are any avlb registers
2158 of te type required */
2161 /* special case for pointer type
2162 if pointer type not avlb then
2163 check for type gpr */
2164 if (nFreeRegs (rt) >= nr)
2166 if (nFreeRegs (REG_GPR) >= nr)
2171 if (pic14_ptrRegReq)
2173 if (nFreeRegs (rt) >= nr)
2178 if (nFreeRegs (REG_PTR) +
2179 nFreeRegs (REG_GPR) >= nr)
2184 debugLog (" ... yep it will (cause a spill)\n");
2185 /* it will cause a spil */
2189 /*-----------------------------------------------------------------*/
2190 /* positionRegs - the allocator can allocate same registers to res- */
2191 /* ult and operand, if this happens make sure they are in the same */
2192 /* position as the operand otherwise chaos results */
2193 /*-----------------------------------------------------------------*/
2195 positionRegs (symbol * result, symbol * opsym, int lineno)
2197 int count = min (result->nRegs, opsym->nRegs);
2198 int i, j = 0, shared = 0;
2200 debugLog ("%s\n", __FUNCTION__);
2201 /* if the result has been spilt then cannot share */
2206 /* first make sure that they actually share */
2207 for (i = 0; i < count; i++)
2209 for (j = 0; j < count; j++)
2211 if (result->regs[i] == opsym->regs[j] && i != j)
2221 regs *tmp = result->regs[i];
2222 result->regs[i] = result->regs[j];
2223 result->regs[j] = tmp;
2228 /*------------------------------------------------------------------*/
2229 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2230 /* it should either have registers or have beed spilled. Otherwise, */
2231 /* there was an uninitialized variable, so just spill this to get */
2232 /* the operand in a valid state. */
2233 /*------------------------------------------------------------------*/
2235 verifyRegsAssigned (operand *op, iCode * ic)
2240 if (!IS_ITEMP (op)) return;
2242 sym = OP_SYMBOL (op);
2243 if (sym->isspilt) return;
2244 if (!sym->nRegs) return;
2245 if (sym->regs[0]) return;
2247 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
2248 sym->prereqv ? sym->prereqv->name : sym->name);
2253 /*-----------------------------------------------------------------*/
2254 /* serialRegAssign - serially allocate registers to the variables */
2255 /*-----------------------------------------------------------------*/
2257 serialRegAssign (eBBlock ** ebbs, int count)
2261 debugLog ("%s\n", __FUNCTION__);
2262 /* for all blocks */
2263 for (i = 0; i < count; i++)
2268 if (ebbs[i]->noPath &&
2269 (ebbs[i]->entryLabel != entryLabel &&
2270 ebbs[i]->entryLabel != returnLabel))
2273 /* of all instructions do */
2274 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2277 debugLog (" op: %s\n", decodeOp (ic->op));
2279 /* if this is an ipop that means some live
2280 range will have to be assigned again */
2282 reassignLR (IC_LEFT (ic));
2284 /* if result is present && is a true symbol */
2285 if (IC_RESULT (ic) && ic->op != IFX &&
2286 IS_TRUE_SYMOP (IC_RESULT (ic)))
2287 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2289 /* take away registers from live
2290 ranges that end at this instruction */
2291 deassignLRs (ic, ebbs[i]);
2293 /* some don't need registers */
2294 if (SKIP_IC2 (ic) ||
2295 ic->op == JUMPTABLE ||
2299 (IC_RESULT (ic) && POINTER_SET (ic)))
2302 /* now we need to allocate registers
2303 only for the result */
2306 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2312 /* Make sure any spill location is definately allocated */
2313 if (sym->isspilt && !sym->remat && sym->usl.spillLoc &&
2314 !sym->usl.spillLoc->allocreq)
2316 sym->usl.spillLoc->allocreq++;
2319 /* if it does not need or is spilt
2320 or is already assigned to registers
2321 or will not live beyond this instructions */
2324 bitVectBitValue (_G.regAssigned, sym->key) ||
2325 sym->liveTo <= ic->seq)
2328 /* if some liverange has been spilt at the block level
2329 and this one live beyond this block then spil this
2331 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2336 /* if trying to allocate this will cause
2337 a spill and there is nothing to spill
2338 or this one is rematerializable then
2340 willCS = willCauseSpill (sym->nRegs, sym->regType);
2341 spillable = computeSpillable (ic);
2343 (willCS && bitVectIsZero (spillable)))
2351 /* If the live range preceeds the point of definition
2352 then ideally we must take into account registers that
2353 have been allocated after sym->liveFrom but freed
2354 before ic->seq. This is complicated, so spill this
2355 symbol instead and let fillGaps handle the allocation. */
2356 if (sym->liveFrom < ic->seq)
2362 /* if it has a spillocation & is used less than
2363 all other live ranges then spill this */
2365 if (sym->usl.spillLoc) {
2366 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2367 allLRs, ebbs[i], ic));
2368 if (leastUsed && leastUsed->used > sym->used) {
2373 /* if none of the liveRanges have a spillLocation then better
2374 to spill this one than anything else already assigned to registers */
2375 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2376 /* if this is local to this block then we might find a block spil */
2377 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2385 if (ic->op == RECEIVE)
2386 debugLog ("When I get clever, I'll optimize the receive logic\n");
2388 /* if we need ptr regs for the right side
2390 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2391 <= (unsigned) PTRSIZE)
2396 /* else we assign registers to it */
2397 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2399 debugLog (" %d - \n", __LINE__);
2401 bitVectDebugOn(_G.regAssigned, debugF);
2402 for (j = 0; j < sym->nRegs; j++)
2404 if (sym->regType == REG_PTR)
2405 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2407 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2409 /* if the allocation failed which means
2410 this was spilt then break */
2414 debugLog (" %d - \n", __LINE__);
2416 /* if it shares registers with operands make sure
2417 that they are in the same position */
2418 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2419 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2420 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2421 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2422 /* do the same for the right operand */
2423 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2424 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2425 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2426 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2428 debugLog (" %d - \n", __LINE__);
2431 debugLog (" %d - \n", __LINE__);
2440 /* Check for and fix any problems with uninitialized operands */
2441 for (i = 0; i < count; i++)
2445 if (ebbs[i]->noPath &&
2446 (ebbs[i]->entryLabel != entryLabel &&
2447 ebbs[i]->entryLabel != returnLabel))
2450 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2457 verifyRegsAssigned (IC_COND (ic), ic);
2461 if (ic->op == JUMPTABLE)
2463 verifyRegsAssigned (IC_JTCOND (ic), ic);
2467 verifyRegsAssigned (IC_RESULT (ic), ic);
2468 verifyRegsAssigned (IC_LEFT (ic), ic);
2469 verifyRegsAssigned (IC_RIGHT (ic), ic);
2475 /*-----------------------------------------------------------------*/
2476 /* rUmaskForOp :- returns register mask for an operand */
2477 /*-----------------------------------------------------------------*/
2479 rUmaskForOp (operand * op)
2485 debugLog ("%s\n", __FUNCTION__);
2486 /* only temporaries are assigned registers */
2490 sym = OP_SYMBOL (op);
2492 /* if spilt or no registers assigned to it
2494 if (sym->isspilt || !sym->nRegs)
2497 rumask = newBitVect (pic14_nRegs);
2499 for (j = 0; j < sym->nRegs; j++)
2501 rumask = bitVectSetBit (rumask,
2502 sym->regs[j]->rIdx);
2508 /*-----------------------------------------------------------------*/
2509 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2510 /*-----------------------------------------------------------------*/
2512 regsUsedIniCode (iCode * ic)
2514 bitVect *rmask = newBitVect (pic14_nRegs);
2516 debugLog ("%s\n", __FUNCTION__);
2517 /* do the special cases first */
2520 rmask = bitVectUnion (rmask,
2521 rUmaskForOp (IC_COND (ic)));
2525 /* for the jumptable */
2526 if (ic->op == JUMPTABLE)
2528 rmask = bitVectUnion (rmask,
2529 rUmaskForOp (IC_JTCOND (ic)));
2534 /* of all other cases */
2536 rmask = bitVectUnion (rmask,
2537 rUmaskForOp (IC_LEFT (ic)));
2541 rmask = bitVectUnion (rmask,
2542 rUmaskForOp (IC_RIGHT (ic)));
2545 rmask = bitVectUnion (rmask,
2546 rUmaskForOp (IC_RESULT (ic)));
2552 /*-----------------------------------------------------------------*/
2553 /* createRegMask - for each instruction will determine the regsUsed */
2554 /*-----------------------------------------------------------------*/
2556 createRegMask (eBBlock ** ebbs, int count)
2560 debugLog ("%s\n", __FUNCTION__);
2561 /* for all blocks */
2562 for (i = 0; i < count; i++)
2566 if (ebbs[i]->noPath &&
2567 (ebbs[i]->entryLabel != entryLabel &&
2568 ebbs[i]->entryLabel != returnLabel))
2571 /* for all instructions */
2572 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2577 if (SKIP_IC2 (ic) || !ic->rlive)
2580 /* first mark the registers used in this
2582 ic->rUsed = regsUsedIniCode (ic);
2583 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2585 /* now create the register mask for those
2586 registers that are in use : this is a
2587 super set of ic->rUsed */
2588 ic->rMask = newBitVect (pic14_nRegs + 1);
2590 /* for all live Ranges alive at this point */
2591 for (j = 1; j < ic->rlive->size; j++)
2596 /* if not alive then continue */
2597 if (!bitVectBitValue (ic->rlive, j))
2600 /* find the live range we are interested in */
2601 if (!(sym = hTabItemWithKey (liveRanges, j)))
2603 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2604 "createRegMask cannot find live range");
2608 /* if no register assigned to it */
2609 if (!sym->nRegs || sym->isspilt)
2612 /* for all the registers allocated to it */
2613 for (k = 0; k < sym->nRegs; k++)
2616 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2622 /* This was the active version */
2623 /*-----------------------------------------------------------------*/
2624 /* rematStr - returns the rematerialized string for a remat var */
2625 /*-----------------------------------------------------------------*/
2627 rematStr (symbol * sym)
2630 iCode *ic = sym->rematiCode;
2631 symbol *psym = NULL;
2633 debugLog ("%s\n", __FUNCTION__);
2635 //printf ("%s\n", s);
2637 /* if plus or minus print the right hand side */
2639 if (ic->op == '+' || ic->op == '-') {
2641 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2643 sprintf (s, "(%s %c 0x%04x)",
2644 OP_SYMBOL (IC_LEFT (ric))->rname,
2646 (int) operandLitValue (IC_RIGHT (ic)));
2649 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2651 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2652 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2657 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2658 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2660 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2666 /* deprecated version */
2667 /*-----------------------------------------------------------------*/
2668 /* rematStr - returns the rematerialized string for a remat var */
2669 /*-----------------------------------------------------------------*/
2671 rematStr (symbol * sym)
2674 iCode *ic = sym->rematiCode;
2676 debugLog ("%s\n", __FUNCTION__);
2681 /* if plus or minus print the right hand side */
2683 if (ic->op == '+' || ic->op == '-') {
2684 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2687 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2691 if (ic->op == '+' || ic->op == '-')
2693 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2694 sprintf (s, "(%s %c 0x%04x)",
2695 OP_SYMBOL (IC_LEFT (ric))->rname,
2697 (int) operandLitValue (IC_RIGHT (ic)));
2700 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2702 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2706 /* we reached the end */
2707 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2711 printf ("%s\n", buffer);
2716 /*-----------------------------------------------------------------*/
2717 /* regTypeNum - computes the type & number of registers required */
2718 /*-----------------------------------------------------------------*/
2726 debugLog ("%s\n", __FUNCTION__);
2727 /* for each live range do */
2728 for (sym = hTabFirstItem (liveRanges, &k); sym;
2729 sym = hTabNextItem (liveRanges, &k)) {
2731 debugLog (" %d - %s\n", __LINE__, sym->rname);
2733 /* if used zero times then no registers needed */
2734 if ((sym->liveTo - sym->liveFrom) == 0)
2738 /* if the live range is a temporary */
2741 debugLog (" %d - itemp register\n", __LINE__);
2743 /* if the type is marked as a conditional */
2744 if (sym->regType == REG_CND)
2747 /* if used in return only then we don't
2750 if (IS_AGGREGATE (sym->type) || sym->isptr)
2751 sym->type = aggrToPtr (sym->type, FALSE);
2752 debugLog (" %d - no reg needed - accumulator used\n", __LINE__);
2758 //if (IS_AGGREGATE (sym->type) || sym->isptr)
2759 // sym->type = aggrToPtr (sym->type, FALSE);
2760 debugLog (" %d - used as a return\n", __LINE__);
2765 /* if the symbol has only one definition &
2766 that definition is a get_pointer and the
2767 pointer we are getting is rematerializable and
2771 if (bitVectnBitsOn (sym->defs) == 1 &&
2772 (ic = hTabItemWithKey (iCodehTab,
2773 bitVectFirstBit (sym->defs))) &&
2775 !IS_BITVAR (sym->etype) &&
2776 (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
2778 if (ptrPseudoSymSafe (sym, ic)) {
2782 debugLog (" %d - \n", __LINE__);
2784 /* create a psuedo symbol & force a spil */
2785 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2786 psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2787 psym->type = sym->type;
2788 psym->etype = sym->etype;
2789 psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
2790 strcpy (psym->rname, psym->name);
2792 sym->usl.spillLoc = psym;
2796 /* if in data space or idata space then try to
2797 allocate pointer register */
2802 /* if not then we require registers */
2803 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2804 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2805 getSize (sym->type));
2808 if(IS_PTR_CONST (sym->type)) {
2809 debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2813 if (sym->nRegs > 4) {
2814 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2815 printTypeChain (sym->type, stderr);
2816 fprintf (stderr, "\n");
2819 /* determine the type of register required */
2820 if (sym->nRegs == 1 &&
2821 IS_PTR (sym->type) &&
2823 sym->regType = REG_PTR;
2825 sym->regType = REG_GPR;
2828 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2832 /* for the first run we don't provide */
2833 /* registers for true symbols we will */
2834 /* see how things go */
2839 DEFSETFUNC (markRegFree)
2841 ((regs *)item)->isFree = 1;
2846 DEFSETFUNC (deallocReg)
2848 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2849 ((regs *)item)->isFree = 1;
2850 ((regs *)item)->wasUsed = 0;
2854 /*-----------------------------------------------------------------*/
2855 /* freeAllRegs - mark all registers as free */
2856 /*-----------------------------------------------------------------*/
2858 pic14_freeAllRegs ()
2862 debugLog ("%s\n", __FUNCTION__);
2864 applyToSet(dynAllocRegs,markRegFree);
2865 applyToSet(dynStackRegs,markRegFree);
2868 for (i = 0; i < pic14_nRegs; i++)
2869 regspic14[i].isFree = 1;
2873 /*-----------------------------------------------------------------*/
2874 /*-----------------------------------------------------------------*/
2876 pic14_deallocateAllRegs ()
2880 debugLog ("%s\n", __FUNCTION__);
2882 applyToSet(dynAllocRegs,deallocReg);
2885 for (i = 0; i < pic14_nRegs; i++) {
2886 if(regspic14[i].pc_type == PO_GPR_TEMP) {
2887 regspic14[i].isFree = 1;
2888 regspic14[i].wasUsed = 0;
2895 /*-----------------------------------------------------------------*/
2896 /* deallocStackSpil - this will set the stack pointer back */
2897 /*-----------------------------------------------------------------*/
2899 DEFSETFUNC (deallocStackSpil)
2903 debugLog ("%s\n", __FUNCTION__);
2908 /*-----------------------------------------------------------------*/
2909 /* farSpacePackable - returns the packable icode for far variables */
2910 /*-----------------------------------------------------------------*/
2912 farSpacePackable (iCode * ic)
2916 debugLog ("%s\n", __FUNCTION__);
2917 /* go thru till we find a definition for the
2918 symbol on the right */
2919 for (dic = ic->prev; dic; dic = dic->prev)
2922 /* if the definition is a call then no */
2923 if ((dic->op == CALL || dic->op == PCALL) &&
2924 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2929 /* if shift by unknown amount then not */
2930 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2931 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2934 /* if pointer get and size > 1 */
2935 if (POINTER_GET (dic) &&
2936 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2939 if (POINTER_SET (dic) &&
2940 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2943 /* if any three is a true symbol in far space */
2944 if (IC_RESULT (dic) &&
2945 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2946 isOperandInFarSpace (IC_RESULT (dic)))
2949 if (IC_RIGHT (dic) &&
2950 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2951 isOperandInFarSpace (IC_RIGHT (dic)) &&
2952 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2955 if (IC_LEFT (dic) &&
2956 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2957 isOperandInFarSpace (IC_LEFT (dic)) &&
2958 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2961 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2963 if ((dic->op == LEFT_OP ||
2964 dic->op == RIGHT_OP ||
2966 IS_OP_LITERAL (IC_RIGHT (dic)))
2976 /*-----------------------------------------------------------------*/
2977 /* packRegsForAssign - register reduction for assignment */
2978 /*-----------------------------------------------------------------*/
2980 packRegsForAssign (iCode * ic, eBBlock * ebp)
2985 debugLog ("%s\n", __FUNCTION__);
2987 debugAopGet (" result:", IC_RESULT (ic));
2988 debugAopGet (" left:", IC_LEFT (ic));
2989 debugAopGet (" right:", IC_RIGHT (ic));
2991 /* if this is at an absolute address, then get the address. */
2992 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2993 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2994 debugLog (" %d - found config word declaration\n", __LINE__);
2995 if(IS_VALOP(IC_RIGHT(ic))) {
2996 debugLog (" setting config word to %x\n",
2997 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2998 assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2999 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
3002 /* remove the assignment from the iCode chain. */
3004 remiCodeFromeBBlock (ebp, ic);
3005 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3006 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3013 if (!IS_ITEMP (IC_RESULT (ic))) {
3014 allocDirReg(IC_RESULT (ic));
3015 debugLog (" %d - result is not temp\n", __LINE__);
3018 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
3019 debugLog (" %d - left is not temp, allocating\n", __LINE__);
3020 allocDirReg(IC_LEFT (ic));
3024 if (!IS_ITEMP (IC_RIGHT (ic))) {
3025 debugLog (" %d - not packing - right is not temp\n", __LINE__);
3027 /* only pack if this is not a function pointer */
3028 if (!IS_REF (IC_RIGHT (ic)))
3029 allocDirReg(IC_RIGHT (ic));
3033 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
3034 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
3036 debugLog (" %d - not packing - right side fails \n", __LINE__);
3040 /* if the true symbol is defined in far space or on stack
3041 then we should not since this will increase register pressure */
3042 if (isOperandInFarSpace (IC_RESULT (ic)))
3044 if ((dic = farSpacePackable (ic)))
3050 /* find the definition of iTempNN scanning backwards if we find a
3051 a use of the true symbol before we find the definition then
3053 for (dic = ic->prev; dic; dic = dic->prev)
3056 /* if there is a function call and this is
3057 a parameter & not my parameter then don't pack it */
3058 if ((dic->op == CALL || dic->op == PCALL) &&
3059 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
3060 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
3062 debugLog (" %d - \n", __LINE__);
3070 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
3071 IS_OP_VOLATILE (IC_RESULT (dic)))
3073 debugLog (" %d - dic is VOLATILE \n", __LINE__);
3078 if (IS_SYMOP (IC_RESULT (dic)) &&
3079 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
3081 /* A previous result was assigned to the same register - we'll our definition */
3082 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
3083 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
3084 if (POINTER_SET (dic))
3090 if (IS_SYMOP (IC_RIGHT (dic)) &&
3091 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
3092 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
3094 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
3099 if (IS_SYMOP (IC_LEFT (dic)) &&
3100 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
3101 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
3103 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
3108 if (POINTER_SET (dic) &&
3109 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
3111 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
3119 return 0; /* did not find */
3121 /* if the result is on stack or iaccess then it must be
3122 the same at least one of the operands */
3123 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
3124 OP_SYMBOL (IC_RESULT (ic))->iaccess)
3127 /* the operation has only one symbol
3128 operator then we can pack */
3129 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
3130 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
3133 if (!((IC_LEFT (dic) &&
3134 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
3136 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
3140 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
3141 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
3142 /* found the definition */
3143 /* replace the result with the result of */
3144 /* this assignment and remove this assignment */
3145 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3146 IC_RESULT (dic) = IC_RESULT (ic);
3148 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
3150 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
3152 /* delete from liverange table also
3153 delete from all the points inbetween and the new
3155 for (sic = dic; sic != ic; sic = sic->next)
3157 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3158 if (IS_ITEMP (IC_RESULT (dic)))
3159 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3162 remiCodeFromeBBlock (ebp, ic);
3163 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3164 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3165 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3171 /*-----------------------------------------------------------------*/
3172 /* findAssignToSym : scanning backwards looks for first assig found */
3173 /*-----------------------------------------------------------------*/
3175 findAssignToSym (operand * op, iCode * ic)
3179 debugLog ("%s\n", __FUNCTION__);
3180 for (dic = ic->prev; dic; dic = dic->prev)
3183 /* if definition by assignment */
3184 if (dic->op == '=' &&
3185 !POINTER_SET (dic) &&
3186 IC_RESULT (dic)->key == op->key
3187 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3191 /* we are interested only if defined in far space */
3192 /* or in stack space in case of + & - */
3194 /* if assigned to a non-symbol then return
3196 if (!IS_SYMOP (IC_RIGHT (dic)))
3199 /* if the symbol is in far space then
3201 if (isOperandInFarSpace (IC_RIGHT (dic)))
3204 /* for + & - operations make sure that
3205 if it is on the stack it is the same
3206 as one of the three operands */
3207 if ((ic->op == '+' || ic->op == '-') &&
3208 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3211 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3212 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3213 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3221 /* if we find an usage then we cannot delete it */
3222 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3225 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3228 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3232 /* now make sure that the right side of dic
3233 is not defined between ic & dic */
3236 iCode *sic = dic->next;
3238 for (; sic != ic; sic = sic->next)
3239 if (IC_RESULT (sic) &&
3240 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3249 /*-----------------------------------------------------------------*/
3250 /* packRegsForSupport :- reduce some registers for support calls */
3251 /*-----------------------------------------------------------------*/
3253 packRegsForSupport (iCode * ic, eBBlock * ebp)
3257 debugLog ("%s\n", __FUNCTION__);
3258 /* for the left & right operand :- look to see if the
3259 left was assigned a true symbol in far space in that
3260 case replace them */
3261 if (IS_ITEMP (IC_LEFT (ic)) &&
3262 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3264 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3270 debugAopGet ("removing left:", IC_LEFT (ic));
3272 /* found it we need to remove it from the
3274 for (sic = dic; sic != ic; sic = sic->next)
3275 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3277 IC_LEFT (ic)->operand.symOperand =
3278 IC_RIGHT (dic)->operand.symOperand;
3279 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3280 remiCodeFromeBBlock (ebp, dic);
3281 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3282 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3286 /* do the same for the right operand */
3289 IS_ITEMP (IC_RIGHT (ic)) &&
3290 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3292 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3298 /* if this is a subtraction & the result
3299 is a true symbol in far space then don't pack */
3300 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3302 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3303 if (IN_FARSPACE (SPEC_OCLS (etype)))
3307 debugAopGet ("removing right:", IC_RIGHT (ic));
3309 /* found it we need to remove it from the
3311 for (sic = dic; sic != ic; sic = sic->next)
3312 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3314 IC_RIGHT (ic)->operand.symOperand =
3315 IC_RIGHT (dic)->operand.symOperand;
3316 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3318 remiCodeFromeBBlock (ebp, dic);
3319 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3320 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3327 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3330 /*-----------------------------------------------------------------*/
3331 /* packRegsForOneuse : - will reduce some registers for single Use */
3332 /*-----------------------------------------------------------------*/
3334 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3339 debugLog ("%s\n", __FUNCTION__);
3340 /* if returning a literal then do nothing */
3344 /* only upto 2 bytes since we cannot predict
3345 the usage of b, & acc */
3346 if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
3351 /* this routine will mark the a symbol as used in one
3352 instruction use only && if the definition is local
3353 (ie. within the basic block) && has only one definition &&
3354 that definition is either a return value from a
3355 function or does not contain any variables in
3357 uses = bitVectCopy (OP_USES (op));
3358 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3359 if (!bitVectIsZero (uses)) /* has other uses */
3362 /* if it has only one defintion */
3363 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3364 return NULL; /* has more than one definition */
3366 /* get that definition */
3368 hTabItemWithKey (iCodehTab,
3369 bitVectFirstBit (OP_DEFS (op)))))
3372 /* found the definition now check if it is local */
3373 if (dic->seq < ebp->fSeq ||
3374 dic->seq > ebp->lSeq)
3375 return NULL; /* non-local */
3377 /* now check if it is the return from
3379 if (dic->op == CALL || dic->op == PCALL)
3381 if (ic->op != SEND && ic->op != RETURN &&
3382 !POINTER_SET(ic) && !POINTER_GET(ic))
3384 OP_SYMBOL (op)->ruonly = 1;
3391 /* otherwise check that the definition does
3392 not contain any symbols in far space */
3393 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3394 isOperandInFarSpace (IC_RIGHT (dic)) ||
3395 IS_OP_RUONLY (IC_LEFT (ic)) ||
3396 IS_OP_RUONLY (IC_RIGHT (ic)))
3401 /* if pointer set then make sure the pointer
3403 if (POINTER_SET (dic) &&
3404 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3407 if (POINTER_GET (dic) &&
3408 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3413 /* also make sure the intervenening instructions
3414 don't have any thing in far space */
3415 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3418 /* if there is an intervening function call then no */
3419 if (dic->op == CALL || dic->op == PCALL)
3421 /* if pointer set then make sure the pointer
3423 if (POINTER_SET (dic) &&
3424 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3427 if (POINTER_GET (dic) &&
3428 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3431 /* if address of & the result is remat then okay */
3432 if (dic->op == ADDRESS_OF &&
3433 OP_SYMBOL (IC_RESULT (dic))->remat)
3436 /* if operand has size of three or more & this
3437 operation is a '*','/' or '%' then 'b' may
3439 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3440 getSize (operandType (op)) >= 3)
3443 /* if left or right or result is in far space */
3444 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3445 isOperandInFarSpace (IC_RIGHT (dic)) ||
3446 isOperandInFarSpace (IC_RESULT (dic)) ||
3447 IS_OP_RUONLY (IC_LEFT (dic)) ||
3448 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3449 IS_OP_RUONLY (IC_RESULT (dic)))
3455 OP_SYMBOL (op)->ruonly = 1;
3460 /*-----------------------------------------------------------------*/
3461 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3462 /*-----------------------------------------------------------------*/
3464 isBitwiseOptimizable (iCode * ic)
3466 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3467 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3469 debugLog ("%s\n", __FUNCTION__);
3470 /* bitwise operations are considered optimizable
3471 under the following conditions (Jean-Louis VERN)
3483 if (IS_LITERAL (rtype) ||
3484 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3490 /*-----------------------------------------------------------------*/
3491 /* packRegsForAccUse - pack registers for acc use */
3492 /*-----------------------------------------------------------------*/
3494 packRegsForAccUse (iCode * ic)
3498 debugLog ("%s\n", __FUNCTION__);
3500 /* if this is an aggregate, e.g. a one byte char array */
3501 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3504 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3506 /* if + or - then it has to be one byte result */
3507 if ((ic->op == '+' || ic->op == '-')
3508 && getSize (operandType (IC_RESULT (ic))) > 1)
3511 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3512 /* if shift operation make sure right side is not a literal */
3513 if (ic->op == RIGHT_OP &&
3514 (isOperandLiteral (IC_RIGHT (ic)) ||
3515 getSize (operandType (IC_RESULT (ic))) > 1))
3518 if (ic->op == LEFT_OP &&
3519 (isOperandLiteral (IC_RIGHT (ic)) ||
3520 getSize (operandType (IC_RESULT (ic))) > 1))
3523 if (IS_BITWISE_OP (ic) &&
3524 getSize (operandType (IC_RESULT (ic))) > 1)
3528 /* has only one definition */
3529 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3532 /* has only one use */
3533 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3536 /* and the usage immediately follows this iCode */
3537 if (!(uic = hTabItemWithKey (iCodehTab,
3538 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3541 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3542 if (ic->next != uic)
3545 /* if it is a conditional branch then we definitely can */
3549 if (uic->op == JUMPTABLE)
3552 /* if the usage is not is an assignment
3553 or an arithmetic / bitwise / shift operation then not */
3554 if (POINTER_SET (uic) &&
3555 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3558 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3559 if (uic->op != '=' &&
3560 !IS_ARITHMETIC_OP (uic) &&
3561 !IS_BITWISE_OP (uic) &&
3562 uic->op != LEFT_OP &&
3563 uic->op != RIGHT_OP)
3566 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3567 /* if used in ^ operation then make sure right is not a
3569 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3572 /* if shift operation make sure right side is not a literal */
3573 if (uic->op == RIGHT_OP &&
3574 (isOperandLiteral (IC_RIGHT (uic)) ||
3575 getSize (operandType (IC_RESULT (uic))) > 1))
3578 if (uic->op == LEFT_OP &&
3579 (isOperandLiteral (IC_RIGHT (uic)) ||
3580 getSize (operandType (IC_RESULT (uic))) > 1))
3583 /* make sure that the result of this icode is not on the
3584 stack, since acc is used to compute stack offset */
3585 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3586 OP_SYMBOL (IC_RESULT (uic))->onStack)
3589 /* if either one of them in far space then we cannot */
3590 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3591 isOperandInFarSpace (IC_LEFT (uic))) ||
3592 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3593 isOperandInFarSpace (IC_RIGHT (uic))))
3596 /* if the usage has only one operand then we can */
3597 if (IC_LEFT (uic) == NULL ||
3598 IC_RIGHT (uic) == NULL)
3601 /* make sure this is on the left side if not
3602 a '+' since '+' is commutative */
3603 if (ic->op != '+' &&
3604 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3607 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3608 /* if one of them is a literal then we can */
3609 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3610 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3611 (getSize (operandType (IC_RESULT (uic))) <= 1))
3613 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3617 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3618 /* if the other one is not on stack then we can */
3619 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3620 (IS_ITEMP (IC_RIGHT (uic)) ||
3621 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3622 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3625 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3626 (IS_ITEMP (IC_LEFT (uic)) ||
3627 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3628 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3634 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3635 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3640 /*-----------------------------------------------------------------*/
3641 /* packForPush - hueristics to reduce iCode for pushing */
3642 /*-----------------------------------------------------------------*/
3644 packForReceive (iCode * ic, eBBlock * ebp)
3648 debugLog ("%s\n", __FUNCTION__);
3649 debugAopGet (" result:", IC_RESULT (ic));
3650 debugAopGet (" left:", IC_LEFT (ic));
3651 debugAopGet (" right:", IC_RIGHT (ic));
3656 for (dic = ic->next; dic; dic = dic->next)
3661 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3662 debugLog (" used on left\n");
3663 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3664 debugLog (" used on right\n");
3665 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3666 debugLog (" used on result\n");
3668 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3669 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3674 debugLog (" hey we can remove this unnecessary assign\n");
3676 /*-----------------------------------------------------------------*/
3677 /* packForPush - hueristics to reduce iCode for pushing */
3678 /*-----------------------------------------------------------------*/
3680 packForPush (iCode * ic, eBBlock * ebp)
3684 debugLog ("%s\n", __FUNCTION__);
3685 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3688 /* must have only definition & one usage */
3689 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3690 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3693 /* find the definition */
3694 if (!(dic = hTabItemWithKey (iCodehTab,
3695 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3698 if (dic->op != '=' || POINTER_SET (dic))
3701 /* we now we know that it has one & only one def & use
3702 and the that the definition is an assignment */
3703 IC_LEFT (ic) = IC_RIGHT (dic);
3705 remiCodeFromeBBlock (ebp, dic);
3706 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3707 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3710 void printSymType(char * str, sym_link *sl)
3712 debugLog (" %s Symbol type: ",str);
3713 printTypeChain( sl, debugF);
3718 /*-----------------------------------------------------------------*/
3719 /* some debug code to print the symbol S_TYPE. Note that
3720 * the function checkSClass in src/SDCCsymt.c dinks with
3721 * the S_TYPE in ways the PIC port doesn't fully like...*/
3722 /*-----------------------------------------------------------------*/
3723 void isData(sym_link *sl)
3733 for ( ; sl; sl=sl->next) {
3735 switch (SPEC_SCLS(sl)) {
3737 case S_DATA: fprintf (of, "data "); break;
3738 case S_XDATA: fprintf (of, "xdata "); break;
3739 case S_SFR: fprintf (of, "sfr "); break;
3740 case S_SBIT: fprintf (of, "sbit "); break;
3741 case S_CODE: fprintf (of, "code "); break;
3742 case S_IDATA: fprintf (of, "idata "); break;
3743 case S_PDATA: fprintf (of, "pdata "); break;
3744 case S_LITERAL: fprintf (of, "literal "); break;
3745 case S_STACK: fprintf (of, "stack "); break;
3746 case S_XSTACK: fprintf (of, "xstack "); break;
3747 case S_BIT: fprintf (of, "bit "); break;
3748 case S_EEPROM: fprintf (of, "eeprom "); break;
3758 /*-----------------------------------------------------------------*/
3759 /* packRegisters - does some transformations to reduce register */
3761 /*-----------------------------------------------------------------*/
3763 packRegisters (eBBlock * ebp)
3768 debugLog ("%s\n", __FUNCTION__);
3774 /* look for assignments of the form */
3775 /* iTempNN = TRueSym (someoperation) SomeOperand */
3777 /* TrueSym := iTempNN:1 */
3778 for (ic = ebp->sch; ic; ic = ic->next)
3781 /* find assignment of the form TrueSym := iTempNN:1 */
3782 if (ic->op == '=' && !POINTER_SET (ic))
3783 change += packRegsForAssign (ic, ebp);
3787 if (POINTER_SET (ic))
3788 debugLog ("pointer is set\n");
3789 debugAopGet (" result:", IC_RESULT (ic));
3790 debugAopGet (" left:", IC_LEFT (ic));
3791 debugAopGet (" right:", IC_RIGHT (ic));
3800 for (ic = ebp->sch; ic; ic = ic->next) {
3802 if(IS_SYMOP ( IC_LEFT(ic))) {
3803 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3805 debugAopGet (" left:", IC_LEFT (ic));
3806 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3807 debugLog (" is a pointer\n");
3809 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3810 debugLog (" is volatile\n");
3814 printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
3817 if(IS_SYMOP ( IC_RIGHT(ic))) {
3818 debugAopGet (" right:", IC_RIGHT (ic));
3819 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3822 if(IS_SYMOP ( IC_RESULT(ic))) {
3823 debugAopGet (" result:", IC_RESULT (ic));
3824 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3827 if (POINTER_SET (ic))
3828 debugLog (" %d - Pointer set\n", __LINE__);
3831 /* Look for two subsequent iCodes with */
3833 /* _c = iTemp & op; */
3834 /* and replace them by */
3837 if ((ic->op == BITWISEAND || ic->op == '|' || ic->op == '^') &&
3839 ic->prev->op == '=' &&
3840 IS_ITEMP (IC_LEFT (ic)) &&
3841 IC_LEFT (ic) == IC_RESULT (ic->prev) &&
3842 isOperandEqual (IC_RESULT(ic), IC_RIGHT(ic->prev)))
3844 iCode* ic_prev = ic->prev;
3845 symbol* prev_result_sym = OP_SYMBOL (IC_RESULT (ic_prev));
3847 ReplaceOpWithCheaperOp (&IC_LEFT (ic), IC_RESULT (ic));
3848 if (IC_RESULT (ic_prev) != IC_RIGHT (ic))
3850 bitVectUnSetBit (OP_USES (IC_RESULT (ic_prev)), ic->key);
3851 if (/*IS_ITEMP (IC_RESULT (ic_prev)) && */
3852 prev_result_sym->liveTo == ic->seq)
3854 prev_result_sym->liveTo = ic_prev->seq;
3857 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
3859 bitVectSetBit (ic->rlive, IC_RESULT (ic)->key);
3861 if (bitVectIsZero (OP_USES (IC_RESULT (ic_prev))))
3863 bitVectUnSetBit (ic->rlive, IC_RESULT (ic)->key);
3864 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic_prev)), ic_prev->key);
3865 remiCodeFromeBBlock (ebp, ic_prev);
3866 hTabDeleteItem (&iCodehTab, ic_prev->key, ic_prev, DELETE_ITEM, NULL);
3870 /* if this is an itemp & result of a address of a true sym
3871 then mark this as rematerialisable */
3872 if (ic->op == ADDRESS_OF &&
3873 IS_ITEMP (IC_RESULT (ic)) &&
3874 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3875 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3876 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3879 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3881 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3882 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3883 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3887 /* if straight assignment then carry remat flag if
3888 this is the only definition */
3889 if (ic->op == '=' &&
3890 !POINTER_SET (ic) &&
3891 IS_SYMOP (IC_RIGHT (ic)) &&
3892 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3893 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3895 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3897 OP_SYMBOL (IC_RESULT (ic))->remat =
3898 OP_SYMBOL (IC_RIGHT (ic))->remat;
3899 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3900 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3903 /* if this is a +/- operation with a rematerizable
3904 then mark this as rematerializable as well */
3905 if ((ic->op == '+' || ic->op == '-') &&
3906 (IS_SYMOP (IC_LEFT (ic)) &&
3907 IS_ITEMP (IC_RESULT (ic)) &&
3908 OP_SYMBOL (IC_LEFT (ic))->remat &&
3909 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3910 IS_OP_LITERAL (IC_RIGHT (ic))))
3912 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3914 operandLitValue (IC_RIGHT (ic));
3915 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3916 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3917 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3920 /* mark the pointer usages */
3921 if (POINTER_SET (ic))
3923 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3924 debugLog (" marking as a pointer (set) =>");
3925 debugAopGet (" result:", IC_RESULT (ic));
3927 if (POINTER_GET (ic))
3929 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3930 debugLog (" marking as a pointer (get) =>");
3931 debugAopGet (" left:", IC_LEFT (ic));
3936 /* if we are using a symbol on the stack
3937 then we should say pic14_ptrRegReq */
3938 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3939 pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3940 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3941 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3942 pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3943 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3946 if (IS_SYMOP (IC_LEFT (ic)))
3947 pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3948 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3949 if (IS_SYMOP (IC_RIGHT (ic)))
3950 pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3951 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3952 if (IS_SYMOP (IC_RESULT (ic)))
3953 pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3954 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3957 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
3961 /* if the condition of an if instruction
3962 is defined in the previous instruction then
3963 mark the itemp as a conditional */
3964 if ((IS_CONDITIONAL (ic) ||
3965 ((ic->op == BITWISEAND ||
3968 isBitwiseOptimizable (ic))) &&
3969 ic->next && ic->next->op == IFX &&
3970 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3971 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3974 debugLog (" %d\n", __LINE__);
3975 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3979 /* reduce for support function calls */
3980 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3981 packRegsForSupport (ic, ebp);
3983 /* if a parameter is passed, it's in W, so we may not
3984 need to place a copy in a register */
3985 if (ic->op == RECEIVE)
3986 packForReceive (ic, ebp);
3988 /* some cases the redundant moves can
3989 can be eliminated for return statements */
3990 if ((ic->op == RETURN || ic->op == SEND) &&
3991 !isOperandInFarSpace (IC_LEFT (ic)) &&
3993 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3995 /* if pointer set & left has a size more than
3996 one and right is not in far space */
3997 if (POINTER_SET (ic) &&
3998 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3999 !OP_SYMBOL (IC_RESULT (ic))->remat &&
4000 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
4001 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
4003 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
4005 /* if pointer get */
4006 if (POINTER_GET (ic) &&
4007 !isOperandInFarSpace (IC_RESULT (ic)) &&
4008 !OP_SYMBOL (IC_LEFT (ic))->remat &&
4009 !IS_OP_RUONLY (IC_RESULT (ic)) &&
4010 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
4012 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
4015 /* if this is cast for intergral promotion then
4016 check if only use of the definition of the
4017 operand being casted/ if yes then replace
4018 the result of that arithmetic operation with
4019 this result and get rid of the cast */
4020 if (ic->op == CAST) {
4022 sym_link *fromType = operandType (IC_RIGHT (ic));
4023 sym_link *toType = operandType (IC_LEFT (ic));
4025 debugLog (" %d - casting\n", __LINE__);
4027 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
4028 getSize (fromType) != getSize (toType)) {
4031 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4034 if (IS_ARITHMETIC_OP (dic)) {
4036 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4037 IC_RESULT (dic) = IC_RESULT (ic);
4038 remiCodeFromeBBlock (ebp, ic);
4039 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4040 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4041 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4045 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
4049 /* if the type from and type to are the same
4050 then if this is the only use then packit */
4051 if (compareType (operandType (IC_RIGHT (ic)),
4052 operandType (IC_LEFT (ic))) == 1) {
4054 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4057 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4058 IC_RESULT (dic) = IC_RESULT (ic);
4059 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4060 remiCodeFromeBBlock (ebp, ic);
4061 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4062 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4070 iTempNN := (some variable in farspace) V1
4075 if (ic->op == IPUSH)
4077 packForPush (ic, ebp);
4081 /* pack registers for accumulator use, when the
4082 result of an arithmetic or bit wise operation
4083 has only one use, that use is immediately following
4084 the defintion and the using iCode has only one
4085 operand or has two operands but one is literal &
4086 the result of that operation is not on stack then
4087 we can leave the result of this operation in acc:b
4089 if ((IS_ARITHMETIC_OP (ic)
4091 || IS_BITWISE_OP (ic)
4093 || ic->op == LEFT_OP || ic->op == RIGHT_OP
4096 IS_ITEMP (IC_RESULT (ic)) &&
4097 getSize (operandType (IC_RESULT (ic))) <= 2)
4099 packRegsForAccUse (ic);
4105 dumpEbbsToDebug (eBBlock ** ebbs, int count)
4109 if (!debug || !debugF)
4112 for (i = 0; i < count; i++)
4114 fprintf (debugF, "\n----------------------------------------------------------------\n");
4115 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
4116 ebbs[i]->entryLabel->name,
4119 ebbs[i]->isLastInLoop);
4120 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4125 fprintf (debugF, "visited %d : hasFcall = %d\n",
4129 fprintf (debugF, "\ndefines bitVector :");
4130 bitVectDebugOn (ebbs[i]->defSet, debugF);
4131 fprintf (debugF, "\nlocal defines bitVector :");
4132 bitVectDebugOn (ebbs[i]->ldefs, debugF);
4133 fprintf (debugF, "\npointers Set bitvector :");
4134 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4135 fprintf (debugF, "\nin pointers Set bitvector :");
4136 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4137 fprintf (debugF, "\ninDefs Set bitvector :");
4138 bitVectDebugOn (ebbs[i]->inDefs, debugF);
4139 fprintf (debugF, "\noutDefs Set bitvector :");
4140 bitVectDebugOn (ebbs[i]->outDefs, debugF);
4141 fprintf (debugF, "\nusesDefs Set bitvector :");
4142 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4143 fprintf (debugF, "\n----------------------------------------------------------------\n");
4144 printiCChain (ebbs[i]->sch, debugF);
4147 /*-----------------------------------------------------------------*/
4148 /* assignRegisters - assigns registers to each live range as need */
4149 /*-----------------------------------------------------------------*/
4151 pic14_assignRegisters (ebbIndex * ebbi)
4153 eBBlock ** ebbs = ebbi->bbOrder;
4154 int count = ebbi->count;
4158 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
4159 debugLog ("\nebbs before optimizing:\n");
4160 dumpEbbsToDebug (ebbs, count);
4162 setToNull ((void *) &_G.funcrUsed);
4163 pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4166 /* change assignments this will remove some
4167 live ranges reducing some register pressure */
4168 for (i = 0; i < count; i++)
4169 packRegisters (ebbs[i]);
4176 debugLog("dir registers allocated so far:\n");
4177 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4180 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4181 reg = hTabNextItem(dynDirectRegNames, &hkey);
4186 if (options.dump_pack)
4187 dumpEbbsToFileExt (DUMP_PACK, ebbi);
4189 /* first determine for each live range the number of
4190 registers & the type of registers required for each */
4193 /* and serially allocate registers */
4194 serialRegAssign (ebbs, count);
4196 /* if stack was extended then tell the user */
4199 /* werror(W_TOOMANY_SPILS,"stack", */
4200 /* _G.stackExtend,currFunc->name,""); */
4206 /* werror(W_TOOMANY_SPILS,"data space", */
4207 /* _G.dataExtend,currFunc->name,""); */
4211 /* after that create the register mask
4212 for each of the instruction */
4213 createRegMask (ebbs, count);
4215 /* redo that offsets for stacked automatic variables */
4216 redoStackOffsets ();
4218 if (options.dump_rassgn)
4219 dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
4221 /* now get back the chain */
4222 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4224 debugLog ("ebbs after optimizing:\n");
4225 dumpEbbsToDebug (ebbs, count);
4230 /* free up any _G.stackSpil locations allocated */
4231 applyToSet (_G.stackSpil, deallocStackSpil);
4233 setToNull ((void *) &_G.stackSpil);
4234 setToNull ((void *) &_G.spiltSet);
4235 /* mark all registers as free */
4236 //pic14_freeAllRegs ();
4238 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");