X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic%2Fralloc.c;h=6f6ea8e8801f5fa0c0f720c940bdb34f16d57794;hb=89ced3c908df7524953073632212e98f40566081;hp=87921515ea21a5a2c8b226df26f36053cfea2931;hpb=8aa6b044fa1c62dd74cc3dd4d05326977bc28163;p=fw%2Fsdcc diff --git a/src/pic/ralloc.c b/src/pic/ralloc.c index 87921515..6f6ea8e8 100644 --- a/src/pic/ralloc.c +++ b/src/pic/ralloc.c @@ -29,6 +29,15 @@ #include "pcode.h" #include "gen.h" +#if defined(__BORLANDC__) || defined(_MSC_VER) +#define STRCASECMP stricmp +#else +#define STRCASECMP strcasecmp +#endif + +/* this should go in SDCCicode.h, but it doesn't. */ +#define IS_REF(op) (IS_SYMOP(op) && op->operand.symOperand->isref == 1) + /*-----------------------------------------------------------------*/ /* At this point we start getting processor specific although */ /* some routines are non-processor specific & can be reused when */ @@ -39,6 +48,7 @@ /*-----------------------------------------------------------------*/ extern void genpic14Code (iCode *); +extern void assignConfigWordValue(int address, int value); /* Global data */ static struct @@ -57,35 +67,28 @@ _G; /* Shared with gen.c */ int pic14_ptrRegReq; /* one byte pointer register required */ -/* pic14 registers */ -regs regspic14[] = -{ - - {REG_GPR, PO_GPR_TEMP, 0x0C, "r0x0C", "r0x0C", 0x0C, 1, 0}, - {REG_GPR, PO_GPR_TEMP, 0x0D, "r0x0D", "r0x0C", 0x0D, 1, 0}, - {REG_GPR, PO_GPR_TEMP, 0x0E, "r0x0E", "r0x0C", 0x0E, 1, 0}, - {REG_GPR, PO_GPR_TEMP, 0x0F, "r0x0F", "r0x0C", 0x0F, 1, 0}, - {REG_GPR, PO_GPR_TEMP, 0x10, "r0x10", "r0x10", 0x10, 1, 0}, - {REG_GPR, PO_GPR_TEMP, 0x11, "r0x11", "r0x11", 0x11, 1, 0}, - {REG_GPR, PO_GPR_TEMP, 0x12, "r0x12", "r0x12", 0x12, 1, 0}, - {REG_GPR, PO_GPR_TEMP, 0x13, "r0x13", "r0x13", 0x13, 1, 0}, - {REG_GPR, PO_GPR_TEMP, 0x14, "r0x14", "r0x14", 0x14, 1, 0}, - {REG_GPR, PO_GPR_TEMP, 0x15, "r0x15", "r0x15", 0x15, 1, 0}, - {REG_GPR, PO_GPR_TEMP, 0x16, "r0x16", "r0x16", 0x16, 1, 0}, - {REG_GPR, PO_GPR_TEMP, 0x17, "r0x17", "r0x17", 0x17, 1, 0}, - {REG_GPR, PO_GPR_TEMP, 0x18, "r0x18", "r0x18", 0x18, 1, 0}, - {REG_GPR, PO_GPR_TEMP, 0x19, "r0x19", "r0x19", 0x19, 1, 0}, - {REG_GPR, PO_GPR_TEMP, 0x1A, "r0x1A", "r0x1A", 0x1A, 1, 0}, - {REG_GPR, PO_GPR_TEMP, 0x1B, "r0x1B", "r0x1B", 0x1B, 1, 0}, - {REG_GPR, PO_GPR_TEMP, 0x1C, "r0x1C", "r0x1C", 0x1C, 1, 0}, - {REG_GPR, PO_GPR_TEMP, 0x1D, "r0x1D", "r0x1D", 0x1D, 1, 0}, - {REG_GPR, PO_GPR_TEMP, 0x1E, "r0x1E", "r0x1E", 0x1E, 1, 0}, - {REG_GPR, PO_GPR_TEMP, 0x1F, "r0x1F", "r0x1F", 0x1F, 1, 0}, - {REG_PTR, PO_FSR, 4, "FSR", "FSR", 4, 1, 0}, - -}; - -int pic14_nRegs = sizeof (regspic14) / sizeof (regs); + +set *dynAllocRegs=NULL; +set *dynStackRegs=NULL; +set *dynProcessorRegs=NULL; +set *dynDirectRegs=NULL; +set *dynDirectBitRegs=NULL; +set *dynInternalRegs=NULL; + +static hTab *dynDirectRegNames= NULL; +// static hTab *regHash = NULL; /* a hash table containing ALL registers */ + +static int dynrIdx=0x20; +static int rDirectIdx=0; + +int pic14_nRegs = 128; // = sizeof (regspic14) / sizeof (regs); + +int Gstack_base_addr=0; /* The starting address of registers that + * are used to pass and return parameters */ + + + + static void spillThis (symbol *); static int debug = 1; static FILE *debugF = NULL; @@ -102,14 +105,14 @@ debugLog (char *fmt,...) //char *bufferP=buffer; va_list ap; - if (!debug || !srcFileName) + if (!debug || !dstFileName) return; if (!debugF) { /* create the file name */ - strcpy (buffer, srcFileName); + strcpy (buffer, dstFileName); strcat (buffer, ".d"); if (!(debugF = fopen (buffer, (append ? "a+" : "w")))) @@ -316,20 +319,6 @@ decodeOp (unsigned int op) return "RANGE"; case FAR: return "FAR"; - case _XDATA: - return "_XDATA"; - case _CODE: - return "_CODE"; - case _GENERIC: - return "_GENERIC"; - case _NEAR: - return "_NEAR"; - case _PDATA: - return "_PDATA"; - case _IDATA: - return "_IDATA"; - case _EEPROM: - return "_EEPROM"; case CASE: return "CASE"; case DEFAULT: @@ -422,86 +411,479 @@ debugLogRegType (short type) return "REG_CND"; } - sprintf (buffer, "unkown reg type %d", type); + sprintf (buffer, "unknown reg type %d", type); return buffer; } +/*-----------------------------------------------------------------*/ +/*-----------------------------------------------------------------*/ +static int regname2key(char const *name) +{ + int key = 0; + + if(!name) + return 0; + + while(*name) { + + key += (*name++) + 1; + + } + + return ( (key + (key >> 4) + (key>>8)) & 0x3f); + +} + +/*-----------------------------------------------------------------*/ +/* newReg - allocate and init memory for a new register */ +/*-----------------------------------------------------------------*/ +static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias) +{ + + regs *dReg; + + dReg = Safe_calloc(1,sizeof(regs)); + dReg->type = type; + dReg->pc_type = pc_type; + dReg->rIdx = rIdx; + if(name) + dReg->name = Safe_strdup(name); + else { + sprintf(buffer,"r0x%02X", dReg->rIdx); + if(type == REG_STK) + *buffer = 's'; + dReg->name = Safe_strdup(buffer); + } + //fprintf(stderr,"newReg: %s, rIdx = 0x%02x\n",dReg->name,rIdx); + dReg->isFree = 0; + dReg->wasUsed = 1; + if(type == REG_SFR) + dReg->isFixed = 1; + else + dReg->isFixed = 0; + + dReg->isMapped = 0; + dReg->isEmitted = 0; + dReg->address = 0; + dReg->size = size; + dReg->alias = alias; + dReg->reg_alias = NULL; + dReg->reglives.usedpFlows = newSet(); + dReg->reglives.assignedpFlows = newSet(); + + hTabAddItem(&dynDirectRegNames, regname2key(name), dReg); + + return dReg; +} + +/*-----------------------------------------------------------------*/ +/* regWithIdx - Search through a set of registers that matches idx */ +/*-----------------------------------------------------------------*/ +static regs * +regWithIdx (set *dRegs, int idx, int fixed) +{ + regs *dReg; + + for (dReg = setFirstItem(dRegs) ; dReg ; + dReg = setNextItem(dRegs)) { + + if(idx == dReg->rIdx && (fixed == (int)dReg->isFixed)) { + return dReg; + } + } + + return NULL; +} + +/*-----------------------------------------------------------------*/ +/* regFindFree - Search for a free register in a set of registers */ +/*-----------------------------------------------------------------*/ +static regs * +regFindFree (set *dRegs) +{ + regs *dReg; + + for (dReg = setFirstItem(dRegs) ; dReg ; + dReg = setNextItem(dRegs)) { + + if(dReg->isFree) + return dReg; + } + + return NULL; +} +/*-----------------------------------------------------------------*/ +/* initStack - allocate registers for a psuedo stack */ +/*-----------------------------------------------------------------*/ +void initStack(int base_address, int size) +{ + + int i; + + Gstack_base_addr = base_address; + //fprintf(stderr,"initStack"); + + for(i = 0; iwasUsed = 0; + return addSet(&dynInternalRegs,reg); + } + + return NULL; +} /*-----------------------------------------------------------------*/ /* allocReg - allocates register of given type */ /*-----------------------------------------------------------------*/ static regs * allocReg (short type) { - int i; debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type)); + //fprintf(stderr,"allocReg\n"); - for (i = 0; i < pic14_nRegs; i++) - { - /* if type is given as 0 then any - free register will do */ - if (!type && - regspic14[i].isFree) - { - regspic14[i].isFree = 0; - regspic14[i].wasUsed = 1; - if (currFunc) - currFunc->regsUsed = - bitVectSetBit (currFunc->regsUsed, i); - debugLog (" returning %s\n", regspic14[i].name); - return ®spic14[i]; - } - /* other wise look for specific type - of register */ - if (regspic14[i].isFree && - regspic14[i].type == type) - { - regspic14[i].isFree = 0; - regspic14[i].wasUsed = 1; - if (currFunc) - currFunc->regsUsed = - bitVectSetBit (currFunc->regsUsed, i); - debugLog (" returning %s\n", regspic14[i].name); - return ®spic14[i]; - } + return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0)); + +} + + +/*-----------------------------------------------------------------*/ +/* dirregWithName - search for register by name */ +/*-----------------------------------------------------------------*/ +regs * +dirregWithName (char *name) +{ + int hkey; + regs *reg; + + if(!name) + return NULL; + + /* hash the name to get a key */ + + hkey = regname2key(name); + + reg = hTabFirstItemWK(dynDirectRegNames, hkey); + + while(reg) { + + if(STRCASECMP(reg->name, name) == 0) { + return(reg); + } + + reg = hTabNextItemWK (dynDirectRegNames); + + } + + return NULL; // name wasn't found in the hash table +} + +int IS_CONFIG_ADDRESS(int address) +{ + + return address == 0x2007; +} + +/*-----------------------------------------------------------------*/ +/* allocDirReg - allocates register of given type */ +/*-----------------------------------------------------------------*/ +regs * +allocDirReg (operand *op ) +{ + + regs *reg; + char *name; + + if(!IS_SYMOP(op)) { + debugLog ("%s BAD, op is NULL\n", __FUNCTION__); + return NULL; + } + + name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name; + + /* If the symbol is at a fixed address, then remove the leading underscore + * from the name. This is hack to allow the .asm include file named registers + * to match the .c declared register names */ + + //if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && (*name == '_')) + //name++; + + debugLog ("%s symbol name %s\n", __FUNCTION__,name); + { + if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) { + debugLog(" %d const char\n",__LINE__); + debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op))); + } + + debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op))); + if (IS_CODE ( OP_SYM_ETYPE(op)) ) + debugLog(" %d code space\n",__LINE__); + + if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) ) + debugLog(" %d integral\n",__LINE__); + if (IS_LITERAL ( OP_SYM_ETYPE(op)) ) + debugLog(" %d literal\n",__LINE__); + if (IS_SPEC ( OP_SYM_ETYPE(op)) ) + debugLog(" %d specifier\n",__LINE__); + debugAopGet(NULL, op); + } + + if (IS_CODE ( OP_SYM_ETYPE(op)) ) + return NULL; + + /* First, search the hash table to see if there is a register with this name */ + if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && !(IS_BITVAR (OP_SYM_ETYPE(op))) ) { + reg = regWithIdx (dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1); +/* + if(!reg) + fprintf(stderr,"ralloc %s is at fixed address but not a processor reg, addr=0x%x\n", + name, SPEC_ADDR ( OP_SYM_ETYPE(op))); + else + fprintf(stderr,"ralloc %s at fixed address has already been declared, addr=0x%x\n", + name, SPEC_ADDR ( OP_SYM_ETYPE(op))); +*/ + } else { + //fprintf(stderr,"ralloc:%d %s \n", __LINE__,name); + + reg = dirregWithName(name); + } + + if(!reg) { + int address = 0; + + /* if this is at an absolute address, then get the address. */ + if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) { + address = SPEC_ADDR ( OP_SYM_ETYPE(op)); + //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address); + } + + /* Register wasn't found in hash, so let's create + * a new one and put it in the hash table AND in the + * dynDirectRegNames set */ + if(!IS_CONFIG_ADDRESS(address)) { + //fprintf(stderr,"allocating new reg %s\n",name); + + reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0 ); + debugLog (" -- added %s to hash, size = %d\n", name,reg->size); + + //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); + + if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) { + + //fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name); + reg->type = REG_SFR; + } + + if (IS_BITVAR (OP_SYM_ETYPE(op))) { + addSet(&dynDirectBitRegs, reg); + reg->isBitField = 1; + } else + addSet(&dynDirectRegs, reg); + + } else { + debugLog (" -- %s is declared at address 0x2007\n",name); + + } + } + + if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) { + reg->isFixed = 1; + reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op)); + debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address); + } + + return reg; +} + +/*-----------------------------------------------------------------*/ +/* allocDirReg - allocates register of given type */ +/*-----------------------------------------------------------------*/ +regs * +allocRegByName (char *name, int size) +{ + + regs *reg; + + if(!name) { + fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__); + exit(1); + } + + /* First, search the hash table to see if there is a register with this name */ + reg = dirregWithName(name); + + if(!reg) { + + /* Register wasn't found in hash, so let's create + * a new one and put it in the hash table AND in the + * dynDirectRegNames set */ + //fprintf (stderr,"%s symbol name %s\n", __FUNCTION__,name); + reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0 ); + + debugLog (" -- added %s to hash, size = %d\n", name,reg->size); + + //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); + addSet(&dynDirectRegs, reg); + } + + return reg; +} + +/*-----------------------------------------------------------------*/ +/* RegWithIdx - returns pointer to register with index number */ +/*-----------------------------------------------------------------*/ +regs * +typeRegWithIdx (int idx, int type, int fixed) +{ + + regs *dReg; + + debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx); + + switch (type) { + + case REG_GPR: + if( (dReg = regWithIdx ( dynAllocRegs, idx, fixed)) != NULL) { + + debugLog ("Found a Dynamic Register!\n"); + return dReg; + } + if( (dReg = regWithIdx ( dynDirectRegs, idx, fixed)) != NULL ) { + debugLog ("Found a Direct Register!\n"); + return dReg; + } + + break; + case REG_STK: + if( (dReg = regWithIdx ( dynStackRegs, idx, fixed)) != NULL ) { + debugLog ("Found a Stack Register!\n"); + return dReg; + } + break; + case REG_SFR: + if( (dReg = regWithIdx ( dynProcessorRegs, idx, fixed)) != NULL ) { + debugLog ("Found a Processor Register!\n"); + return dReg; } + + case REG_CND: + case REG_PTR: + default: + break; + } + + return NULL; } /*-----------------------------------------------------------------*/ -/* pic14_regWithIdx - returns pointer to register wit index number */ +/* pic14_regWithIdx - returns pointer to register with index number*/ /*-----------------------------------------------------------------*/ regs * pic14_regWithIdx (int idx) { - int i; + regs *dReg; - debugLog ("%s\n", __FUNCTION__); + if( (dReg = typeRegWithIdx(idx,REG_GPR,0)) != NULL) + return dReg; - for (i = 0; i < pic14_nRegs; i++) - if (regspic14[i].rIdx == idx) - return ®spic14[i]; + if( (dReg = typeRegWithIdx(idx,REG_SFR,0)) != NULL) + return dReg; - return ®spic14[0]; + if( (dReg = typeRegWithIdx(idx,REG_STK,0)) != NULL) + return dReg; - werror (E_INTERNAL_ERROR, __FILE__, __LINE__, - "regWithIdx not found"); - exit (1); + return NULL; } /*-----------------------------------------------------------------*/ +/* pic14_regWithIdx - returns pointer to register with index number */ /*-----------------------------------------------------------------*/ regs * -pic14_findFreeReg(void) +pic14_allocWithIdx (int idx) { - int i; - for (i = 0; i < pic14_nRegs; i++) - if (regspic14[i].isFree) - return ®spic14[i]; + regs *dReg; - return NULL; + debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx); + + if( (dReg = regWithIdx ( dynAllocRegs, idx,0)) != NULL) { + + debugLog ("Found a Dynamic Register!\n"); + } else if( (dReg = regWithIdx ( dynStackRegs, idx,0)) != NULL ) { + debugLog ("Found a Stack Register!\n"); + } else if( (dReg = regWithIdx ( dynProcessorRegs, idx,0)) != NULL ) { + debugLog ("Found a Processor Register!\n"); + } else if( (dReg = regWithIdx ( dynInternalRegs, idx,0)) != NULL ) { + debugLog ("Found an Internal Register!\n"); + } else if( (dReg = regWithIdx ( dynInternalRegs, idx,1)) != NULL ) { + debugLog ("Found an Internal Register!\n"); + } else { + + debugLog ("Dynamic Register not found\n"); + + + //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx); + werror (E_INTERNAL_ERROR, __FILE__, __LINE__, + "regWithIdx not found"); + exit (1); + + } + + dReg->wasUsed = 1; + dReg->isFree = 0; + + return dReg; +} +/*-----------------------------------------------------------------*/ +/*-----------------------------------------------------------------*/ +regs * +pic14_findFreeReg(short type) +{ + // int i; + regs* dReg; + + switch (type) { + case REG_GPR: + if((dReg = regFindFree(dynAllocRegs)) != NULL) + return dReg; + return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0)); + + case REG_STK: + + if((dReg = regFindFree(dynStackRegs)) != NULL) + return dReg; + + return NULL; + + case REG_PTR: + case REG_CND: + case REG_SFR: + default: + return NULL; + } } /*-----------------------------------------------------------------*/ /* freeReg - frees a register */ @@ -520,6 +902,11 @@ freeReg (regs * reg) static int nFreeRegs (int type) { + /* dynamically allocate as many as we need and worry about + * fitting them into a PIC later */ + + return 100; +#if 0 int i; int nfr = 0; @@ -528,6 +915,7 @@ nFreeRegs (int type) if (regspic14[i].isFree && regspic14[i].type == type) nfr++; return nfr; +#endif } /*-----------------------------------------------------------------*/ @@ -547,7 +935,174 @@ nfreeRegsType (int type) return nFreeRegs (type); } +void writeSetUsedRegs(FILE *of, set *dRegs) +{ + + regs *dReg; + + for (dReg = setFirstItem(dRegs) ; dReg ; + dReg = setNextItem(dRegs)) { + + if(dReg->wasUsed) + fprintf (of, "\t%s\n",dReg->name); + } + +} +extern void assignFixedRegisters(set *regset); +extern void assignRelocatableRegisters(set *regset,int used); +extern void dump_map(void); +extern void dump_sfr(FILE *of); + +void packBits(set *bregs) +{ + set *regset; + regs *breg; + regs *bitfield=NULL; + regs *relocbitfield=NULL; + int bit_no=0; + int byte_no=-1; + char buffer[20]; + + + for (regset = bregs ; regset ; + regset = regset->next) { + + breg = regset->item; + breg->isBitField = 1; + //fprintf(stderr,"bit reg: %s\n",breg->name); + + if(breg->isFixed) { + //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address); + + bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1); + breg->rIdx = breg->address & 7; + breg->address >>= 3; + + if(!bitfield) { + //sprintf (buffer, "fbitfield%02x", breg->address); + sprintf (buffer, "0x%02x", breg->address); + //fprintf(stderr,"new bit field\n"); + bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0); + bitfield->isBitField = 1; + bitfield->isFixed = 1; + bitfield->address = breg->address; + //addSet(&dynDirectRegs,bitfield); + addSet(&dynInternalRegs,bitfield); + //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield); + } else { + //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address); + ; + } + breg->reg_alias = bitfield; + bitfield = NULL; + + } else { + if(!relocbitfield || bit_no >7) { + byte_no++; + bit_no=0; + sprintf (buffer, "bitfield%d", byte_no); + //fprintf(stderr,"new relocatable bit field\n"); + relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0); + relocbitfield->isBitField = 1; + //addSet(&dynDirectRegs,relocbitfield); + addSet(&dynInternalRegs,relocbitfield); + //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield); + + } + + breg->reg_alias = relocbitfield; + breg->address = rDirectIdx; /* byte_no; */ + breg->rIdx = bit_no++; + } + } + +} + + + +void bitEQUs(FILE *of, set *bregs) +{ + regs *breg,*bytereg; + int bit_no=0; + + //fprintf(stderr," %s\n",__FUNCTION__); + for (breg = setFirstItem(bregs) ; breg ; + breg = setNextItem(bregs)) { + + //fprintf(stderr,"bit reg: %s\n",breg->name); + + bytereg = breg->reg_alias; + if(bytereg) + fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n", + breg->name, + bytereg->name, + breg->rIdx & 0x0007); + + else { + //fprintf(stderr, "bit field is not assigned to a register\n"); + fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n", + breg->name, + bit_no>>3, + bit_no & 0x0007); + + bit_no++; + } + } + +} +void aliasEQUs(FILE *of, set *fregs, int use_rIdx) +{ + regs *reg; + + + for (reg = setFirstItem(fregs) ; reg ; + reg = setNextItem(fregs)) { + + //if(!reg->isEmitted && reg->wasUsed) { + if(reg->wasUsed) { + if(use_rIdx) + fprintf (of, "%s\tEQU\t0x%03x\n", + reg->name, + reg->rIdx); + else + fprintf (of, "%s\tEQU\t0x%03x\n", + reg->name, + reg->address); + } + } + +} + +void writeUsedRegs(FILE *of) +{ + packBits(dynDirectBitRegs); + + assignFixedRegisters(dynInternalRegs); + assignFixedRegisters(dynAllocRegs); + assignFixedRegisters(dynStackRegs); + assignFixedRegisters(dynDirectRegs); + assignRelocatableRegisters(dynInternalRegs,0); + assignRelocatableRegisters(dynAllocRegs,0); + assignRelocatableRegisters(dynStackRegs,0); + +/* + assignRelocatableRegisters(dynDirectRegs,0); + printf("assignRelocatableRegisters(dynDirectRegs,0);\n"); +*/ + //dump_map(); + + dump_sfr(of); + bitEQUs(of,dynDirectBitRegs); +/* + aliasEQUs(of,dynAllocRegs,0); + aliasEQUs(of,dynDirectRegs,0); + aliasEQUs(of,dynStackRegs,0); + aliasEQUs(of,dynProcessorRegs,1); +*/ +} + +#if 0 /*-----------------------------------------------------------------*/ /* allDefsOutOfRange - all definitions are out of a range */ /*-----------------------------------------------------------------*/ @@ -574,6 +1129,7 @@ allDefsOutOfRange (bitVect * defs, int fseq, int toseq) return TRUE; } +#endif /*-----------------------------------------------------------------*/ /* computeSpillable - given a point find the spillable live ranges */ @@ -657,18 +1213,6 @@ rematable (symbol * sym, eBBlock * ebp, iCode * ic) return sym->remat; } -/*-----------------------------------------------------------------*/ -/* notUsedInBlock - not used in this block */ -/*-----------------------------------------------------------------*/ -static int -notUsedInBlock (symbol * sym, eBBlock * ebp, iCode * ic) -{ - debugLog ("%s\n", __FUNCTION__); - return (!bitVectBitsInCommon (sym->defs, ebp->usesDefs) && - allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq)); -/* return (!bitVectBitsInCommon(sym->defs,ebp->usesDefs)); */ -} - /*-----------------------------------------------------------------*/ /* notUsedInRemaining - not used or defined in remain of the block */ /*-----------------------------------------------------------------*/ @@ -900,6 +1444,7 @@ createStackSpil (symbol * sym) sloc->etype = getSpec (sloc->type); SPEC_SCLS (sloc->etype) = S_DATA; SPEC_EXTR (sloc->etype) = 0; + SPEC_STAT (sloc->etype) = 0; /* we don't allow it to be allocated` onto the external stack since : so we @@ -1566,8 +2111,11 @@ serialRegAssign (eBBlock ** ebbs, int count) /* if none of the liveRanges have a spillLocation then better to spill this one than anything else already assigned to registers */ if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) { - spillThis (sym); - continue; + /* if this is local to this block then we might find a block spil */ + if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) { + spillThis (sym); + continue; + } } } } @@ -1587,7 +2135,8 @@ serialRegAssign (eBBlock ** ebbs, int count) _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key); debugLog (" %d - \n", __LINE__); - + if(debugF) + bitVectDebugOn(_G.regAssigned, debugF); for (j = 0; j < sym->nRegs; j++) { if (sym->regType == REG_PTR) @@ -1595,7 +2144,7 @@ serialRegAssign (eBBlock ** ebbs, int count) else sym->regs[j] = getRegGpr (ic, ebbs[i], sym); - /* if the allocation falied which means + /* if the allocation failed which means this was spilt then break */ if (!sym->regs[j]) break; @@ -1774,6 +2323,48 @@ createRegMask (eBBlock ** ebbs, int count) } } +/*-----------------------------------------------------------------*/ +/* rematStr - returns the rematerialized string for a remat var */ +/*-----------------------------------------------------------------*/ +static symbol * +rematStr (symbol * sym) +{ + char *s = buffer; + iCode *ic = sym->rematiCode; + symbol *psym = NULL; + + debugLog ("%s\n", __FUNCTION__); + + //printf ("%s\n", s); + + /* if plus or minus print the right hand side */ + + if (ic->op == '+' || ic->op == '-') { + + iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode; + + sprintf (s, "(%s %c 0x%04x)", + OP_SYMBOL (IC_LEFT (ric))->rname, + ic->op, + (int) operandLitValue (IC_RIGHT (ic))); + + + //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s); + + psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1); + psym->offset = (int) operandLitValue (IC_RIGHT (ic)); + + return psym; + } + + sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname); + psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1); + + //printf ("ralloc.c:%d %s\n", __LINE__,buffer); + return psym; +} + +#if 0 /*-----------------------------------------------------------------*/ /* rematStr - returns the rematerialized string for a remat var */ /*-----------------------------------------------------------------*/ @@ -1809,6 +2400,7 @@ rematStr (symbol * sym) //s += strlen(s); //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode; //continue ; + //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s); return buffer; } @@ -1820,6 +2412,7 @@ rematStr (symbol * sym) printf ("%s\n", buffer); return buffer; } +#endif /*-----------------------------------------------------------------*/ /* regTypeNum - computes the type & number of registers required */ @@ -1834,116 +2427,150 @@ regTypeNum () debugLog ("%s\n", __FUNCTION__); /* for each live range do */ for (sym = hTabFirstItem (liveRanges, &k); sym; - sym = hTabNextItem (liveRanges, &k)) - { - - debugLog (" %d - %s\n", __LINE__, sym->rname); + sym = hTabNextItem (liveRanges, &k)) { - /* if used zero times then no registers needed */ - if ((sym->liveTo - sym->liveFrom) == 0) - continue; + debugLog (" %d - %s\n", __LINE__, sym->rname); + /* if used zero times then no registers needed */ + if ((sym->liveTo - sym->liveFrom) == 0) + continue; - /* if the live range is a temporary */ - if (sym->isitmp) - { - debugLog (" %d - \n", __LINE__); + /* if the live range is a temporary */ + if (sym->isitmp) { - /* if the type is marked as a conditional */ - if (sym->regType == REG_CND) - continue; + debugLog (" %d - itemp register\n", __LINE__); - /* if used in return only then we don't - need registers */ - if (sym->ruonly || sym->accuse) - { - if (IS_AGGREGATE (sym->type) || sym->isptr) - sym->type = aggrToPtr (sym->type, FALSE); - debugLog (" %d - \n", __LINE__); + /* if the type is marked as a conditional */ + if (sym->regType == REG_CND) + continue; - continue; - } + /* if used in return only then we don't + need registers */ + if (sym->accuse) { + if (IS_AGGREGATE (sym->type) || sym->isptr) + sym->type = aggrToPtr (sym->type, FALSE); + debugLog (" %d - no reg needed - accumulator used\n", __LINE__); - /* if the symbol has only one definition & - that definition is a get_pointer and the - pointer we are getting is rematerializable and - in "data" space */ - - if (bitVectnBitsOn (sym->defs) == 1 && - (ic = hTabItemWithKey (iCodehTab, - bitVectFirstBit (sym->defs))) && - POINTER_GET (ic) && - !sym->noSpilLoc && - !IS_BITVAR (sym->etype)) - { + continue; + } - debugLog (" %d - \n", __LINE__); + if (sym->ruonly) { + //if (IS_AGGREGATE (sym->type) || sym->isptr) + // sym->type = aggrToPtr (sym->type, FALSE); + debugLog (" %d - used as a return\n", __LINE__); - /* if remat in data space */ - if (OP_SYMBOL (IC_LEFT (ic))->remat && - DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) - { + //continue; + } - /* create a psuedo symbol & force a spil */ - symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1); - psym->type = sym->type; - psym->etype = sym->etype; - strcpy (psym->rname, psym->name); - sym->isspilt = 1; - sym->usl.spillLoc = psym; - continue; - } + /* if the symbol has only one definition & + that definition is a get_pointer and the + pointer we are getting is rematerializable and + in "data" space */ + + if (bitVectnBitsOn (sym->defs) == 1 && + (ic = hTabItemWithKey (iCodehTab, + bitVectFirstBit (sym->defs))) && + POINTER_GET (ic) && + !sym->noSpilLoc && + !IS_BITVAR (sym->etype)) { + + + debugLog (" %d - \n", __LINE__); + + /* if remat in data space */ + if (OP_SYMBOL (IC_LEFT (ic))->remat && + DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) { + + /* create a psuedo symbol & force a spil */ + //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1); + symbol *psym = rematStr (OP_SYMBOL (IC_LEFT (ic))); + psym->type = sym->type; + psym->etype = sym->etype; + strcpy (psym->rname, psym->name); + sym->isspilt = 1; + sym->usl.spillLoc = psym; + continue; + } - /* if in data space or idata space then try to - allocate pointer register */ + /* if in data space or idata space then try to + allocate pointer register */ - } + } - /* if not then we require registers */ - sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ? - getSize (sym->type = aggrToPtr (sym->type, FALSE)) : - getSize (sym->type)); + /* if not then we require registers */ + sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ? + getSize (sym->type = aggrToPtr (sym->type, FALSE)) : + getSize (sym->type)); - if (sym->nRegs > 4) - { - fprintf (stderr, "allocated more than 4 or 0 registers for type "); - printTypeChain (sym->type, stderr); - fprintf (stderr, "\n"); - } - debugLog (" %d - \n", __LINE__); +#if 0 + if(IS_PTR_CONST (sym->type)) { +#else + if(IS_CODEPTR (sym->type)) { +#endif + debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs); + sym->nRegs = 2; + } - /* determine the type of register required */ - if (sym->nRegs == 1 && - IS_PTR (sym->type) && - sym->uptr) - sym->regType = REG_PTR; - else - sym->regType = REG_GPR; - debugLog (" reg type %s\n", debugLogRegType (sym->regType)); + if (sym->nRegs > 4) { + fprintf (stderr, "allocated more than 4 or 0 registers for type "); + printTypeChain (sym->type, stderr); + fprintf (stderr, "\n"); + } - } + /* determine the type of register required */ + if (sym->nRegs == 1 && + IS_PTR (sym->type) && + sym->uptr) + sym->regType = REG_PTR; else - /* for the first run we don't provide */ - /* registers for true symbols we will */ - /* see how things go */ - sym->nRegs = 0; + sym->regType = REG_GPR; + + + debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType)); + } + else + /* for the first run we don't provide */ + /* registers for true symbols we will */ + /* see how things go */ + sym->nRegs = 0; + } } +DEFSETFUNC (markRegFree) +{ + ((regs *)item)->isFree = 1; + + return 0; +} +DEFSETFUNC (deallocReg) +{ + fprintf(stderr,"deallocting register %s\n",((regs *)item)->name); + ((regs *)item)->isFree = 1; + ((regs *)item)->wasUsed = 0; + + return 0; +} /*-----------------------------------------------------------------*/ /* freeAllRegs - mark all registers as free */ /*-----------------------------------------------------------------*/ void pic14_freeAllRegs () { - int i; + // int i; debugLog ("%s\n", __FUNCTION__); + + applyToSet(dynAllocRegs,markRegFree); + applyToSet(dynStackRegs,markRegFree); + +/* for (i = 0; i < pic14_nRegs; i++) regspic14[i].isFree = 1; +*/ } /*-----------------------------------------------------------------*/ @@ -1951,13 +2578,20 @@ pic14_freeAllRegs () void pic14_deallocateAllRegs () { - int i; + // int i; debugLog ("%s\n", __FUNCTION__); + + applyToSet(dynAllocRegs,deallocReg); + +/* for (i = 0; i < pic14_nRegs; i++) { - regspic14[i].isFree = 1; - regspic14[i].wasUsed = 0; + if(regspic14[i].pc_type == PO_GPR_TEMP) { + regspic14[i].isFree = 1; + regspic14[i].wasUsed = 0; + } } +*/ } @@ -2057,10 +2691,52 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) debugAopGet (" left:", IC_LEFT (ic)); debugAopGet (" right:", IC_RIGHT (ic)); - if (!IS_ITEMP (IC_RIGHT (ic)) || - OP_SYMBOL (IC_RIGHT (ic))->isind || + /* if this is at an absolute address, then get the address. */ + if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) { + if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) { + debugLog (" %d - found config word declaration\n", __LINE__); + if(IS_VALOP(IC_RIGHT(ic))) { + debugLog (" setting config word to %x\n", + (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand)); + assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))), + (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand)); + } + + /* remove the assignment from the iCode chain. */ + + remiCodeFromeBBlock (ebp, ic); + bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key); + hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL); + + return 1; + + } + } + + if (!IS_ITEMP (IC_RESULT (ic))) { + allocDirReg(IC_RESULT (ic)); + debugLog (" %d - result is not temp\n", __LINE__); + } +/* + if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) { + debugLog (" %d - left is not temp, allocating\n", __LINE__); + allocDirReg(IC_LEFT (ic)); + } +*/ + + if (!IS_ITEMP (IC_RIGHT (ic))) { + debugLog (" %d - not packing - right is not temp\n", __LINE__); + + /* only pack if this is not a function pointer */ + if (!IS_REF (IC_RIGHT (ic))) + allocDirReg(IC_RIGHT (ic)); + return 0; + } + + if (OP_SYMBOL (IC_RIGHT (ic))->isind || OP_LIVETO (IC_RIGHT (ic)) > ic->seq) { + debugLog (" %d - not packing - right side fails \n", __LINE__); return 0; } @@ -2097,7 +2773,7 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) if (IS_TRUE_SYMOP (IC_RESULT (dic)) && IS_OP_VOLATILE (IC_RESULT (dic))) { - debugLog (" %d - \n", __LINE__); + debugLog (" %d - dic is VOLATILE \n", __LINE__); dic = NULL; break; } @@ -2105,7 +2781,9 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) if (IS_SYMOP (IC_RESULT (dic)) && IC_RESULT (dic)->key == IC_RIGHT (ic)->key) { - debugLog (" %d - dic key == ic key -- pointer set=%c\n", __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N')); + /* A previous result was assigned to the same register - we'll our definition */ + debugLog (" %d - dic result key == ic right key -- pointer set=%c\n", + __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N')); if (POINTER_SET (dic)) dic = NULL; @@ -2116,7 +2794,7 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) (IC_RIGHT (dic)->key == IC_RESULT (ic)->key || IC_RIGHT (dic)->key == IC_RIGHT (ic)->key)) { - debugLog (" %d - \n", __LINE__); + debugLog (" %d - dic right key == ic rightor result key\n", __LINE__); dic = NULL; break; } @@ -2125,7 +2803,7 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) (IC_LEFT (dic)->key == IC_RESULT (ic)->key || IC_LEFT (dic)->key == IC_RIGHT (ic)->key)) { - debugLog (" %d - \n", __LINE__); + debugLog (" %d - dic left key == ic rightor result key\n", __LINE__); dic = NULL; break; } @@ -2133,7 +2811,8 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) if (POINTER_SET (dic) && IC_RESULT (dic)->key == IC_RESULT (ic)->key) { - debugLog (" %d - \n", __LINE__); + debugLog (" %d - dic result key == ic result key -- pointer set=Y\n", + __LINE__); dic = NULL; break; } @@ -2162,9 +2841,11 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) } pack: debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname); + debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname); /* found the definition */ /* replace the result with the result of */ /* this assignment and remove this assignment */ + bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key); IC_RESULT (dic) = IC_RESULT (ic); if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq) @@ -2182,8 +2863,9 @@ pack: } remiCodeFromeBBlock (ebp, ic); + bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key); hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL); - OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key); + OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key); return 1; @@ -2299,6 +2981,7 @@ packRegsForSupport (iCode * ic, eBBlock * ebp) IC_RIGHT (dic)->operand.symOperand; IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key; remiCodeFromeBBlock (ebp, dic); + bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key); hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL); change++; } @@ -2336,6 +3019,7 @@ right: IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key; remiCodeFromeBBlock (ebp, dic); + bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key); hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL); change++; } @@ -2397,7 +3081,8 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp) a function call */ if (dic->op == CALL || dic->op == PCALL) { - if (ic->op != SEND && ic->op != RETURN) + if (ic->op != SEND && ic->op != RETURN && + !POINTER_SET(ic) && !POINTER_GET(ic)) { OP_SYMBOL (op)->ruonly = 1; return dic; @@ -2514,11 +3199,19 @@ packRegsForAccUse (iCode * ic) iCode *uic; debugLog ("%s\n", __FUNCTION__); + + /* if this is an aggregate, e.g. a one byte char array */ + if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) { + return; + } + debugLog (" %s:%d\n", __FUNCTION__,__LINE__); + /* if + or - then it has to be one byte result */ if ((ic->op == '+' || ic->op == '-') && getSize (operandType (IC_RESULT (ic))) > 1) return; + debugLog (" %s:%d\n", __FUNCTION__,__LINE__); /* if shift operation make sure right side is not a literal */ if (ic->op == RIGHT_OP && (isOperandLiteral (IC_RIGHT (ic)) || @@ -2548,6 +3241,7 @@ packRegsForAccUse (iCode * ic) bitVectFirstBit (OP_USES (IC_RESULT (ic)))))) return; + debugLog (" %s:%d\n", __FUNCTION__,__LINE__); if (ic->next != uic) return; @@ -2564,6 +3258,7 @@ packRegsForAccUse (iCode * ic) getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1) return; + debugLog (" %s:%d\n", __FUNCTION__,__LINE__); if (uic->op != '=' && !IS_ARITHMETIC_OP (uic) && !IS_BITWISE_OP (uic) && @@ -2571,6 +3266,7 @@ packRegsForAccUse (iCode * ic) uic->op != RIGHT_OP) return; + debugLog (" %s:%d\n", __FUNCTION__,__LINE__); /* if used in ^ operation then make sure right is not a literl */ if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic))) @@ -2611,14 +3307,17 @@ packRegsForAccUse (iCode * ic) IC_LEFT (uic)->key != IC_RESULT (ic)->key) return; + debugLog (" %s:%d\n", __FUNCTION__,__LINE__); /* if one of them is a literal then we can */ - if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) || - (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) + if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) || + (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) && + (getSize (operandType (IC_RESULT (uic))) <= 1)) { OP_SYMBOL (IC_RESULT (ic))->accuse = 1; return; } + debugLog (" %s:%d\n", __FUNCTION__,__LINE__); /* if the other one is not on stack then we can */ if (IC_LEFT (uic)->key == IC_RESULT (ic)->key && (IS_ITEMP (IC_RIGHT (uic)) || @@ -2635,6 +3334,7 @@ packRegsForAccUse (iCode * ic) return; accuse: + debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__); OP_SYMBOL (IC_RESULT (ic))->accuse = 1; @@ -2706,9 +3406,57 @@ packForPush (iCode * ic, eBBlock * ebp) IC_LEFT (ic) = IC_RIGHT (dic); remiCodeFromeBBlock (ebp, dic); + bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key); hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL); } +void printSymType(char * str, sym_link *sl) +{ + debugLog (" %s Symbol type: ",str); + printTypeChain( sl, debugF); + debugLog ("\n"); + +} + +/*-----------------------------------------------------------------*/ +/* some debug code to print the symbol S_TYPE. Note that + * the function checkSClass in src/SDCCsymt.c dinks with + * the S_TYPE in ways the PIC port doesn't fully like...*/ +/*-----------------------------------------------------------------*/ +void isData(sym_link *sl) +{ + FILE *of = stderr; + + if(!sl) + return; + + if(debugF) + of = debugF; + + for ( ; sl; sl=sl->next) { + if(!IS_DECL(sl) ) { + switch (SPEC_SCLS(sl)) { + + case S_DATA: fprintf (of, "data "); break; + case S_XDATA: fprintf (of, "xdata "); break; + case S_SFR: fprintf (of, "sfr "); break; + case S_SBIT: fprintf (of, "sbit "); break; + case S_CODE: fprintf (of, "code "); break; + case S_IDATA: fprintf (of, "idata "); break; + case S_PDATA: fprintf (of, "pdata "); break; + case S_LITERAL: fprintf (of, "literal "); break; + case S_STACK: fprintf (of, "stack "); break; + case S_XSTACK: fprintf (of, "xstack "); break; + case S_BIT: fprintf (of, "bit "); break; + case S_EEPROM: fprintf (of, "eeprom "); break; + default: break; + } + + } + + } + +} /*-----------------------------------------------------------------*/ /* packRegisters - does some transformations to reduce register */ /* pressure */ @@ -2721,259 +3469,303 @@ packRegisters (eBBlock * ebp) debugLog ("%s\n", __FUNCTION__); - while (1) - { + while (1) { - change = 0; + change = 0; - /* look for assignments of the form */ - /* iTempNN = TRueSym (someoperation) SomeOperand */ - /* .... */ - /* TrueSym := iTempNN:1 */ - for (ic = ebp->sch; ic; ic = ic->next) - { + /* look for assignments of the form */ + /* iTempNN = TRueSym (someoperation) SomeOperand */ + /* .... */ + /* TrueSym := iTempNN:1 */ + for (ic = ebp->sch; ic; ic = ic->next) + { - /* find assignment of the form TrueSym := iTempNN:1 */ - if (ic->op == '=' && !POINTER_SET (ic)) - change += packRegsForAssign (ic, ebp); - /* debug stuff */ - if (ic->op == '=') - { - if (POINTER_SET (ic)) - debugLog ("pointer is set\n"); - debugAopGet (" result:", IC_RESULT (ic)); - debugAopGet (" left:", IC_LEFT (ic)); - debugAopGet (" right:", IC_RIGHT (ic)); - } + /* find assignment of the form TrueSym := iTempNN:1 */ + if (ic->op == '=' && !POINTER_SET (ic)) + change += packRegsForAssign (ic, ebp); + /* debug stuff */ + if (ic->op == '=') + { + if (POINTER_SET (ic)) + debugLog ("pointer is set\n"); + debugAopGet (" result:", IC_RESULT (ic)); + debugAopGet (" left:", IC_LEFT (ic)); + debugAopGet (" right:", IC_RIGHT (ic)); + } - } + } + + if (!change) + break; + } + + for (ic = ebp->sch; ic; ic = ic->next) { + + if(IS_SYMOP ( IC_LEFT(ic))) { + sym_link *etype = getSpec (operandType (IC_LEFT (ic))); - if (!change) - break; + debugAopGet (" left:", IC_LEFT (ic)); +#if 0 + if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type)) +#else + if(IS_CODEPTR(OP_SYMBOL(IC_LEFT(ic))->type)) +#endif + debugLog (" is a pointer\n"); + + if(IS_OP_VOLATILE(IC_LEFT(ic))) + debugLog (" is volatile\n"); + + isData(etype); + + printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type); } - for (ic = ebp->sch; ic; ic = ic->next) - { + if(IS_SYMOP ( IC_RIGHT(ic))) { + debugAopGet (" right:", IC_RIGHT (ic)); + printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type); + } - /* if this is an itemp & result of a address of a true sym - then mark this as rematerialisable */ - if (ic->op == ADDRESS_OF && - IS_ITEMP (IC_RESULT (ic)) && - IS_TRUE_SYMOP (IC_LEFT (ic)) && - bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 && - !OP_SYMBOL (IC_LEFT (ic))->onStack) - { + if(IS_SYMOP ( IC_RESULT(ic))) { + debugAopGet (" result:", IC_RESULT (ic)); + printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type); + } - OP_SYMBOL (IC_RESULT (ic))->remat = 1; - OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic; - OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL; + if (POINTER_SET (ic)) + debugLog (" %d - Pointer set\n", __LINE__); - } - /* if straight assignment then carry remat flag if - this is the only definition */ - if (ic->op == '=' && - !POINTER_SET (ic) && - IS_SYMOP (IC_RIGHT (ic)) && - OP_SYMBOL (IC_RIGHT (ic))->remat && - bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1) - { + /* if this is an itemp & result of a address of a true sym + then mark this as rematerialisable */ + if (ic->op == ADDRESS_OF && + IS_ITEMP (IC_RESULT (ic)) && + IS_TRUE_SYMOP (IC_LEFT (ic)) && + bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 && + !OP_SYMBOL (IC_LEFT (ic))->onStack) + { - OP_SYMBOL (IC_RESULT (ic))->remat = - OP_SYMBOL (IC_RIGHT (ic))->remat; - OP_SYMBOL (IC_RESULT (ic))->rematiCode = - OP_SYMBOL (IC_RIGHT (ic))->rematiCode; - } + debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__); - /* if this is a +/- operation with a rematerizable - then mark this as rematerializable as well */ - if ((ic->op == '+' || ic->op == '-') && - (IS_SYMOP (IC_LEFT (ic)) && - IS_ITEMP (IC_RESULT (ic)) && - OP_SYMBOL (IC_LEFT (ic))->remat && - bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 && - IS_OP_LITERAL (IC_RIGHT (ic)))) - { + OP_SYMBOL (IC_RESULT (ic))->remat = 1; + OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic; + OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL; - //int i = - operandLitValue (IC_RIGHT (ic)); - OP_SYMBOL (IC_RESULT (ic))->remat = 1; - OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic; - OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL; - } + } - /* mark the pointer usages */ - if (POINTER_SET (ic)) - { - OP_SYMBOL (IC_RESULT (ic))->uptr = 1; - debugLog (" marking as a pointer (set)\n"); - } - if (POINTER_GET (ic)) - { - OP_SYMBOL (IC_LEFT (ic))->uptr = 1; - debugLog (" marking as a pointer (get)\n"); - } + /* if straight assignment then carry remat flag if + this is the only definition */ + if (ic->op == '=' && + !POINTER_SET (ic) && + IS_SYMOP (IC_RIGHT (ic)) && + OP_SYMBOL (IC_RIGHT (ic))->remat && + bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1) + { + debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__); - if (!SKIP_IC2 (ic)) - { - /* if we are using a symbol on the stack - then we should say pic14_ptrRegReq */ - if (ic->op == IFX && IS_SYMOP (IC_COND (ic))) - pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack || - OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0); - else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic))) - pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack || - OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0); - else - { - if (IS_SYMOP (IC_LEFT (ic))) - pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack || - OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0); - if (IS_SYMOP (IC_RIGHT (ic))) - pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack || - OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0); - if (IS_SYMOP (IC_RESULT (ic))) - pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack || - OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0); - } - } + OP_SYMBOL (IC_RESULT (ic))->remat = + OP_SYMBOL (IC_RIGHT (ic))->remat; + OP_SYMBOL (IC_RESULT (ic))->rematiCode = + OP_SYMBOL (IC_RIGHT (ic))->rematiCode; + } - /* if the condition of an if instruction - is defined in the previous instruction then - mark the itemp as a conditional */ - if ((IS_CONDITIONAL (ic) || - ((ic->op == BITWISEAND || - ic->op == '|' || - ic->op == '^') && - isBitwiseOptimizable (ic))) && - ic->next && ic->next->op == IFX && - isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) && - OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq) - { + /* if this is a +/- operation with a rematerizable + then mark this as rematerializable as well */ + if ((ic->op == '+' || ic->op == '-') && + (IS_SYMOP (IC_LEFT (ic)) && + IS_ITEMP (IC_RESULT (ic)) && + OP_SYMBOL (IC_LEFT (ic))->remat && + bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 && + IS_OP_LITERAL (IC_RIGHT (ic)))) + { + debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__); + //int i = + operandLitValue (IC_RIGHT (ic)); + OP_SYMBOL (IC_RESULT (ic))->remat = 1; + OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic; + OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL; + } - OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND; - continue; - } + /* mark the pointer usages */ + if (POINTER_SET (ic)) + { + OP_SYMBOL (IC_RESULT (ic))->uptr = 1; + debugLog (" marking as a pointer (set) =>"); + debugAopGet (" result:", IC_RESULT (ic)); + } + if (POINTER_GET (ic)) + { + OP_SYMBOL (IC_LEFT (ic))->uptr = 1; + debugLog (" marking as a pointer (get) =>"); + debugAopGet (" left:", IC_LEFT (ic)); + } - /* reduce for support function calls */ - if (ic->supportRtn || ic->op == '+' || ic->op == '-') - packRegsForSupport (ic, ebp); - - /* if a parameter is passed, it's in W, so we may not - need to place a copy in a register */ - if (ic->op == RECEIVE) - packForReceive (ic, ebp); - - /* some cases the redundant moves can - can be eliminated for return statements */ - if ((ic->op == RETURN || ic->op == SEND) && - !isOperandInFarSpace (IC_LEFT (ic)) && - !options.model) - packRegsForOneuse (ic, IC_LEFT (ic), ebp); - - /* if pointer set & left has a size more than - one and right is not in far space */ - if (POINTER_SET (ic) && - !isOperandInFarSpace (IC_RIGHT (ic)) && - !OP_SYMBOL (IC_RESULT (ic))->remat && - !IS_OP_RUONLY (IC_RIGHT (ic)) && - getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1) - - packRegsForOneuse (ic, IC_RESULT (ic), ebp); - - /* if pointer get */ - if (POINTER_GET (ic) && - !isOperandInFarSpace (IC_RESULT (ic)) && - !OP_SYMBOL (IC_LEFT (ic))->remat && - !IS_OP_RUONLY (IC_RESULT (ic)) && - getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1) - - packRegsForOneuse (ic, IC_LEFT (ic), ebp); - - - /* if this is cast for intergral promotion then - check if only use of the definition of the - operand being casted/ if yes then replace - the result of that arithmetic operation with - this result and get rid of the cast */ - if (ic->op == CAST) - { - sym_link *fromType = operandType (IC_RIGHT (ic)); - sym_link *toType = operandType (IC_LEFT (ic)); + if (!SKIP_IC2 (ic)) + { + /* if we are using a symbol on the stack + then we should say pic14_ptrRegReq */ + if (ic->op == IFX && IS_SYMOP (IC_COND (ic))) + pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack || + OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0); + else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic))) + pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack || + OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0); + else + { + if (IS_SYMOP (IC_LEFT (ic))) + pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack || + OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0); + if (IS_SYMOP (IC_RIGHT (ic))) + pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack || + OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0); + if (IS_SYMOP (IC_RESULT (ic))) + pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack || + OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0); + } - if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) && - getSize (fromType) != getSize (toType)) - { + debugLog (" %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq); - iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp); - if (dic) - { - if (IS_ARITHMETIC_OP (dic)) - { - IC_RESULT (dic) = IC_RESULT (ic); - remiCodeFromeBBlock (ebp, ic); - hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL); - OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key); - ic = ic->prev; - } - else - OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0; - } - } - else - { + } - /* if the type from and type to are the same - then if this is the only use then packit */ - if (compareType (operandType (IC_RIGHT (ic)), - operandType (IC_LEFT (ic))) == 1) - { - iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp); - if (dic) - { - IC_RESULT (dic) = IC_RESULT (ic); - remiCodeFromeBBlock (ebp, ic); - hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL); - OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key); - ic = ic->prev; - } - } - } - } + /* if the condition of an if instruction + is defined in the previous instruction then + mark the itemp as a conditional */ + if ((IS_CONDITIONAL (ic) || + ((ic->op == BITWISEAND || + ic->op == '|' || + ic->op == '^') && + isBitwiseOptimizable (ic))) && + ic->next && ic->next->op == IFX && + isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) && + OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq) + { - /* pack for PUSH - iTempNN := (some variable in farspace) V1 - push iTempNN ; - ------------- - push V1 - */ - if (ic->op == IPUSH) - { - packForPush (ic, ebp); + debugLog (" %d\n", __LINE__); + OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND; + continue; + } + + /* reduce for support function calls */ + if (ic->supportRtn || ic->op == '+' || ic->op == '-') + packRegsForSupport (ic, ebp); + + /* if a parameter is passed, it's in W, so we may not + need to place a copy in a register */ + if (ic->op == RECEIVE) + packForReceive (ic, ebp); + + /* some cases the redundant moves can + can be eliminated for return statements */ + if ((ic->op == RETURN || ic->op == SEND) && + !isOperandInFarSpace (IC_LEFT (ic)) && + !options.model) + packRegsForOneuse (ic, IC_LEFT (ic), ebp); + + /* if pointer set & left has a size more than + one and right is not in far space */ + if (POINTER_SET (ic) && + !isOperandInFarSpace (IC_RIGHT (ic)) && + !OP_SYMBOL (IC_RESULT (ic))->remat && + !IS_OP_RUONLY (IC_RIGHT (ic)) && + getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1) + + packRegsForOneuse (ic, IC_RESULT (ic), ebp); + + /* if pointer get */ + if (POINTER_GET (ic) && + !isOperandInFarSpace (IC_RESULT (ic)) && + !OP_SYMBOL (IC_LEFT (ic))->remat && + !IS_OP_RUONLY (IC_RESULT (ic)) && + getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1) + + packRegsForOneuse (ic, IC_LEFT (ic), ebp); + + + /* if this is cast for intergral promotion then + check if only use of the definition of the + operand being casted/ if yes then replace + the result of that arithmetic operation with + this result and get rid of the cast */ + if (ic->op == CAST) { + + sym_link *fromType = operandType (IC_RIGHT (ic)); + sym_link *toType = operandType (IC_LEFT (ic)); + + debugLog (" %d - casting\n", __LINE__); + + if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) && + getSize (fromType) != getSize (toType)) { + + + iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp); + if (dic) { + + if (IS_ARITHMETIC_OP (dic)) { + + bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key); + IC_RESULT (dic) = IC_RESULT (ic); + remiCodeFromeBBlock (ebp, ic); + bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key); + hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL); + OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key); + ic = ic->prev; + } else + + OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0; + } + } else { + + /* if the type from and type to are the same + then if this is the only use then packit */ + if (compareType (operandType (IC_RIGHT (ic)), + operandType (IC_LEFT (ic))) == 1) { + + iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp); + if (dic) { + + bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key); + IC_RESULT (dic) = IC_RESULT (ic); + bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key); + remiCodeFromeBBlock (ebp, ic); + hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL); + OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key); + ic = ic->prev; + } } + } + } + /* pack for PUSH + iTempNN := (some variable in farspace) V1 + push iTempNN ; + ------------- + push V1 + */ + if (ic->op == IPUSH) + { + packForPush (ic, ebp); + } - /* pack registers for accumulator use, when the - result of an arithmetic or bit wise operation - has only one use, that use is immediately following - the defintion and the using iCode has only one - operand or has two operands but one is literal & - the result of that operation is not on stack then - we can leave the result of this operation in acc:b - combination */ - if ((IS_ARITHMETIC_OP (ic) - || IS_BITWISE_OP (ic) + /* pack registers for accumulator use, when the + result of an arithmetic or bit wise operation + has only one use, that use is immediately following + the defintion and the using iCode has only one + operand or has two operands but one is literal & + the result of that operation is not on stack then + we can leave the result of this operation in acc:b + combination */ + if ((IS_ARITHMETIC_OP (ic) - || ic->op == LEFT_OP || ic->op == RIGHT_OP + || IS_BITWISE_OP (ic) - ) && - IS_ITEMP (IC_RESULT (ic)) && - getSize (operandType (IC_RESULT (ic))) <= 2) + || ic->op == LEFT_OP || ic->op == RIGHT_OP - packRegsForAccUse (ic); + ) && + IS_ITEMP (IC_RESULT (ic)) && + getSize (operandType (IC_RESULT (ic))) <= 2) - } + packRegsForAccUse (ic); + + } } static void @@ -3029,7 +3821,7 @@ pic14_assignRegisters (eBBlock ** ebbs, int count) int i; debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__); - debugLog ("ebbs before optimizing:\n"); + debugLog ("\nebbs before optimizing:\n"); dumpEbbsToDebug (ebbs, count); setToNull ((void *) &_G.funcrUsed); @@ -3041,6 +3833,21 @@ pic14_assignRegisters (eBBlock ** ebbs, int count) for (i = 0; i < count; i++) packRegisters (ebbs[i]); + { + regs *reg; + int hkey; + int i=0; + + debugLog("dir registers allocated so far:\n"); + reg = hTabFirstItem(dynDirectRegNames, &hkey); + + while(reg) { + debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size); + reg = hTabNextItem(dynDirectRegNames, &hkey); + } + + } + if (options.dump_pack) dumpEbbsToFileExt (DUMP_PACK, ebbs, count); @@ -3091,7 +3898,7 @@ pic14_assignRegisters (eBBlock ** ebbs, int count) setToNull ((void **) &_G.stackSpil); setToNull ((void **) &_G.spiltSet); /* mark all registers as free */ - pic14_freeAllRegs (); + //pic14_freeAllRegs (); debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n"); debugLogClose ();