X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic16%2Fralloc.c;h=bfeeac608e7f3381765908abf2b47a3b9dfe31c4;hb=6474449850aeace128aebe2d7f387ac7c550bcc5;hp=848702fe658937c38aed87c0f057e00b62c8ea52;hpb=476f65e63356c85584ef8e42481ddecf5c09e488;p=fw%2Fsdcc diff --git a/src/pic16/ralloc.c b/src/pic16/ralloc.c index 848702fe..bfeeac60 100644 --- a/src/pic16/ralloc.c +++ b/src/pic16/ralloc.c @@ -37,6 +37,15 @@ #define STRCASECMP strcasecmp #endif +#ifndef debugf +#define debugf(frm, rest) _debugf(__FILE__, __LINE__, frm, rest) +#endif +void _debugf(char *f, int l, char *frm, ...); + +#define NEWREG_DEBUG 0 +//#define USE_ONSTACK + + /*-----------------------------------------------------------------*/ /* At this point we start getting processor specific although */ /* some routines are non-processor specific & can be reused when */ @@ -46,9 +55,8 @@ /* since the pack the registers depending strictly on the MCU */ /*-----------------------------------------------------------------*/ -static regs *typeRegWithIdx (int idx, int type, int fixed); +regs *pic16_typeRegWithIdx (int idx, int type, int fixed); extern void genpic16Code (iCode *); -extern void pic16_assignConfigWordValue(int address, int value); /* Global data */ static struct @@ -74,17 +82,25 @@ set *pic16_dynProcessorRegs=NULL; set *pic16_dynDirectRegs=NULL; set *pic16_dynDirectBitRegs=NULL; set *pic16_dynInternalRegs=NULL; +set *pic16_dynAccessRegs=NULL; -static hTab *dynDirectRegNames= NULL; +static hTab *dynDirectRegNames=NULL; +static hTab *dynAllocRegNames=NULL; +static hTab *dynProcRegNames=NULL; +static hTab *dynAccessRegNames=NULL; //static hTab *regHash = NULL; /* a hash table containing ALL registers */ -set *pic16_rel_udata=NULL; -set *pic16_fix_udata=NULL; -set *pic16_equ_data=NULL; +extern set *sectNames; + +set *pic16_rel_udata=NULL; /* relocatable uninitialized registers */ +set *pic16_fix_udata=NULL; /* absolute uninitialized registers */ +set *pic16_equ_data=NULL; /* registers used by equates */ +set *pic16_int_regs=NULL; /* internal registers placed in access bank 0 to 0x7f */ +set *pic16_acs_udata=NULL; /* access bank variables */ set *pic16_builtin_functions=NULL; -static int dynrIdx=0x10; //0x20; // starting temporary register rIdx +static int dynrIdx=0x00; //0x20; // starting temporary register rIdx static int rDirectIdx=0; int pic16_nRegs = 128; // = sizeof (regspic16) / sizeof (regs); @@ -93,7 +109,9 @@ int pic16_Gstack_base_addr=0; /* The starting address of registers that * are used to pass and return parameters */ - +int _inRegAllocator=0; /* flag that marks whther allocReg happens while + * inside the register allocator function */ + static void spillThis (symbol *); int pic16_ralloc_debug = 0; @@ -185,8 +203,8 @@ debugAopGet (char *str, operand * op) return NULL; } -static char * -decodeOp (unsigned int op) +char * +pic16_decodeOp (unsigned int op) { if (op < 128 && op > ' ') { buffer[0] = (op & 0xff); @@ -339,7 +357,7 @@ static int regname2key(char const *name) /*-----------------------------------------------------------------*/ /* 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, operand *refop) +regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias, operand *refop) { regs *dReg; @@ -357,23 +375,24 @@ static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, i dReg->name = Safe_strdup(buffer); } -// fprintf(stderr,"newReg: %s, rIdx = 0x%02x\n",dReg->name,rIdx); dReg->isFree = 0; dReg->wasUsed = 1; - -// dReg->isMapped = 0; dReg->isEmitted = 0; - dReg->accessBank = 0; if(type == REG_SFR) { dReg->isFixed = 1; dReg->address = rIdx; + dReg->accessBank = 1; } else { dReg->isFixed = 0; dReg->address = 0; + dReg->accessBank = 0; } - + +#if NEWREG_DEBUG + fprintf(stderr,"newReg: %s, rIdx = 0x%02x\taccess= %d\tregop= %p\n",dReg->name,rIdx, dReg->accessBank, refop); +#endif dReg->size = size; dReg->alias = alias; dReg->reg_alias = NULL; @@ -381,7 +400,8 @@ static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, i dReg->reglives.assignedpFlows = newSet(); dReg->regop = refop; - hTabAddItem(&dynDirectRegNames, regname2key(name), dReg); + if(!(type == REG_SFR && alias == 0x80)) + hTabAddItem(&dynDirectRegNames, regname2key(name), dReg); return dReg; } @@ -390,7 +410,7 @@ static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, i /* regWithIdx - Search through a set of registers that matches idx */ /*-----------------------------------------------------------------*/ static regs * -regWithIdx (set *dRegs, int idx, int fixed) +regWithIdx (set *dRegs, int idx, unsigned fixed) { regs *dReg; @@ -453,6 +473,8 @@ pic16_allocProcessorRegister(int rIdx, char * name, short po_type, int alias) reg->wasUsed = 0; // we do not know if they are going to be used at all reg->accessBank = 1; // implicit add access Bank + hTabAddItem(&dynProcRegNames, regname2key(reg->name), reg); + return addSet(&pic16_dynProcessorRegs, reg); } @@ -466,13 +488,15 @@ pic16_allocInternalRegister(int rIdx, char * name, short po_type, int alias) // fprintf(stderr,"%s:%d: %s %s addr =0x%x\n",__FILE__, __LINE__, __FUNCTION__, name, rIdx); - if(reg) { - reg->wasUsed = 0; - return addSet(&pic16_dynInternalRegs,reg); - } + if(reg) { + reg->wasUsed = 0; + return addSet(&pic16_dynInternalRegs,reg); + } return NULL; } + + /*-----------------------------------------------------------------*/ /* allocReg - allocates register of given type */ /*-----------------------------------------------------------------*/ @@ -481,38 +505,56 @@ allocReg (short type) { regs * reg=NULL; +#define MAX_P16_NREGS 6 + + #if 0 if(dynrIdx > pic16_nRegs) return NULL; #endif -#if STACK_SUPPORT - if(USE_STACK) { - /* try to reuse some unused registers */ - reg = regFindFree( pic16_dynAllocRegs ); + /* try to reuse some unused registers */ + reg = regFindFree( pic16_dynAllocRegs ); + + if(reg) { +// fprintf(stderr, "%s: [%s] found FREE register %s, rIdx: %d\n", __FILE__, (_inRegAllocator)?"ralloc":"", reg->name, reg->rIdx); } -#endif if(!reg) { reg = newReg(REG_GPR, PO_GPR_TEMP, dynrIdx++, NULL, 1, 0, NULL); - addSet(&pic16_dynAllocRegs, reg); +// fprintf(stderr, "%s: [%s] allocating NEW register %s, rIdx: %d\n", __FILE__, (_inRegAllocator)?"ralloc":"", reg->name, reg->rIdx); + +#if 1 + if(_inRegAllocator && (dynrIdx > MAX_P16_NREGS)) { +// debugf("allocating more registers than available\n", 0); +// return (NULL); + } +#endif + +// addSet(&pic16_dynAllocRegs, reg); } - reg->isFree=0; - debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type)); + addSet(&pic16_dynAllocRegs, reg); + hTabAddItem(&dynAllocRegNames, regname2key(reg->name), reg); -// fprintf(stderr,"%s:%d: %s\t%s addr= 0x%x\trIdx= 0x%02x isFree: %d\n", -// __FILE__, __LINE__, __FUNCTION__, reg->name, reg->address, reg->rIdx, reg->isFree); + reg->isFree=0; + debugLog ("%s of type %s for register rIdx: %d (0x%x)\n", __FUNCTION__, debugLogRegType (type), dynrIdx-1, dynrIdx-1); + +#if 0 + fprintf(stderr,"%s:%d: %s\t%s addr= 0x%x\trIdx= 0x%02x isFree: %d\n", + __FILE__, __LINE__, __FUNCTION__, reg->name, reg->address, reg->rIdx, reg->isFree); +#endif if(reg) { reg->accessBank = 1; /* this is a temporary register alloc in accessBank */ reg->isLocal = 1; /* this is a local frame register */ +// reg->wasUsed = 1; } -#if STACK_SUPPORT - if (currFunc) + if (currFunc) { +// fprintf(stderr, "%s:%d adding %s into function %s regsUsed\n", __FUNCTION__, __LINE__, reg->name, currFunc->name); currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, reg->rIdx); -#endif + } return (reg); // addSet(&pic16_dynAllocRegs,reg); @@ -542,6 +584,7 @@ pic16_dirregWithName (char *name) while(reg) { if(STRCASECMP(reg->name, name) == 0) { +// fprintf(stderr, "%s:%d: FOUND name = %s\thash = %d\n", __FUNCTION__, __LINE__, reg->name, hkey); return(reg); } @@ -552,134 +595,323 @@ pic16_dirregWithName (char *name) return NULL; // name wasn't found in the hash table } -static int IS_CONFIG_ADDRESS(int address) +/*-----------------------------------------------------------------*/ +/* pic16_allocregWithName - search for register by name */ +/*-----------------------------------------------------------------*/ +regs * +pic16_allocregWithName (char *name) { + int hkey; + regs *reg; + + if(!name) + return NULL; + + /* hash the name to get a key */ + + hkey = regname2key(name); + +// fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey); + + reg = hTabFirstItemWK(dynAllocRegNames, hkey); + + while(reg) { + + if(STRCASECMP(reg->name, name) == 0) { + return(reg); + } + + reg = hTabNextItemWK (dynAllocRegNames); + + } + + return NULL; // name wasn't found in the hash table - return address >= 0x300000 && address <= 0x300000d; } + /*-----------------------------------------------------------------*/ -/* pic16_allocDirReg - allocates register of given type */ +/* pic16_procregWithName - search for register by name */ /*-----------------------------------------------------------------*/ regs * -pic16_allocDirReg (operand *op ) +pic16_procregWithName (char *name) { - + int hkey; regs *reg; - char *name; - if(!IS_SYMOP(op)) { - debugLog ("%s BAD, op is NULL\n", __FUNCTION__); + if(!name) return NULL; - } - name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name; + /* hash the name to get a key */ - /* 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 */ + hkey = regname2key(name); - //if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && (*name == '_')) - //name++; +// fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey); - /* The above hack is not necessery anymore, since .asm include files are not - * used by current implementation of the port -- VR 03-Jan-04 */ + reg = hTabFirstItemWK(dynProcRegNames, hkey); - debugLog ("%s symbol name %s\n", __FUNCTION__,name); -// fprintf(stderr, "%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))); -// fprintf(stderr, " %d const char\n",__LINE__); -// fprintf(stderr, " 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); + while(reg) { + + if(STRCASECMP(reg->name, name) == 0) { + return(reg); + } + + reg = hTabNextItemWK (dynProcRegNames); + } - if (IS_CODE ( OP_SYM_ETYPE(op)) ) + return NULL; // name wasn't found in the hash table + +} + +/*-----------------------------------------------------------------*/ +/* pic16_accessregWithName - search for register by name */ +/*-----------------------------------------------------------------*/ +regs * +pic16_accessregWithName (char *name) +{ + int hkey; + regs *reg; + + if(!name) 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 (pic16_dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1); + /* hash the name to get a key */ + + hkey = regname2key(name); + +// fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey); + + reg = hTabFirstItemWK(dynAccessRegNames, hkey); + + while(reg) { + + if(STRCASECMP(reg->name, name) == 0) { + return(reg); + } + + reg = hTabNextItemWK (dynAccessRegNames); + + } + + return NULL; // name wasn't found in the hash table + +} + +regs *pic16_regWithName(char *name) +{ + regs *reg; + + reg = pic16_dirregWithName( name ); + if(reg)return reg; + + reg = pic16_procregWithName( name ); + if(reg)return reg; + + reg = pic16_allocregWithName( name ); + if(reg)return reg; + + reg = pic16_accessregWithName( name ); + if(reg)return reg; + + return NULL; +} + + +/*-----------------------------------------------------------------*/ +/* pic16_allocDirReg - allocates register of given type */ +/*-----------------------------------------------------------------*/ +regs * +pic16_allocDirReg (operand *op ) +{ + regs *reg; + char *name; + + if(!IS_SYMOP(op)) { + debugLog ("%s BAD, op is NULL\n", __FUNCTION__); +// fprintf(stderr, "%s BAD, op is NULL\n", __FUNCTION__); + return NULL; + } + + name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name; + + + if(!SPEC_OCLS( OP_SYM_ETYPE(op))) { +#if 1 + if(pic16_debug_verbose) + { + fprintf(stderr, "%s:%d symbol %s(r:%s) is not assigned to a memmap\n", __FILE__, __LINE__, + OP_SYMBOL(op)->name, OP_SYMBOL(op)->rname); + } +#endif + return NULL; + } + + if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))) + || !IN_FARSPACE(SPEC_OCLS( OP_SYM_ETYPE(op))) ) { #if 0 - if(!reg) - fprintf(stderr,"%s:%d: ralloc %s is at fixed address but not a processor reg, addr=0x%x\n", - __FUNCTION__, __LINE__, name, SPEC_ADDR ( OP_SYM_ETYPE(op))); - else - fprintf(stderr,"%s:%d: ralloc %s at fixed address has already been declared, addr=0x%x\n", - __FUNCTION__, __LINE__, name, SPEC_ADDR ( OP_SYM_ETYPE(op))); + if(pic16_debug_verbose) { + fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d eeprom: %d regparm: %d isparm: %d\n", + IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))), + IN_FARSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))), + IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))), + IN_REGSP( SPEC_OCLS( OP_SYM_ETYPE(op))), + IN_STACK( OP_SYM_ETYPE(op)), + SPEC_OCLS(OP_SYM_ETYPE(op)) == eeprom, + IS_REGPARM(OP_SYM_ETYPE(op)), + IS_PARM(op)); + + fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__, + OP_SYMBOL(op)->name); + } #endif - } else { -// fprintf(stderr,"ralloc:%d %s \n", __LINE__,name); + + } + + + + if (IS_CODE ( OP_SYM_ETYPE(op)) ) { +// fprintf(stderr, "%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name); + return NULL; + } + + if(IS_ITEMP(op))return NULL; + +// if(IS_STATIC(OP_SYM_ETYPE(op)))return NULL; + + if(IN_STACK(OP_SYM_ETYPE(op)))return NULL; + + debugLog ("%s:%d symbol name %s\n", __FUNCTION__, __LINE__, name); +// fprintf(stderr, "%s symbol name %s\tSTATIC:%d\n", __FUNCTION__,name, IS_STATIC(OP_SYM_ETYPE(op))); + + { + 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))); +// fprintf(stderr, " %d const char\n",__LINE__); +// fprintf(stderr, " 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); + } + + + reg = pic16_dirregWithName(name); + + if(!reg) { + int address = 0; + int regtype = REG_GPR; - reg = pic16_dirregWithName(name); - } + /* 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); + } - if(!reg) { - int address = 0; + /* 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_CODE(OP_SYM_ETYPE(op)) || IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) { + debugLog("%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name); + return NULL; + } - /* 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(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) { - if(pic16_debug_verbose) - fprintf(stderr, "%s:%d symbol %s in codespace\n", __FILE__, __LINE__, - OP_SYMBOL(op)->name); - return NULL; - } - if(!IS_CONFIG_ADDRESS(address)) { - //fprintf(stderr,"%s:allocating new reg %s\n",__FUNCTION__, name); +#if 0 + if(OP_SYMBOL(op)->onStack) { + fprintf(stderr, "%s:%d onStack %s offset: %d\n", __FILE__, __LINE__, + OP_SYMBOL(op)->name, OP_SYMBOL(op)->stack); + } +#endif - reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0, op); - debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size); + if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))) + || !IN_FARSPACE(SPEC_OCLS( OP_SYM_ETYPE(op))) ) { - //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* commented out */ +#if 0 + if(pic16_debug_verbose) + { + fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d eeprom: %d\n", + IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))), + IN_FARSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))), + IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))), + IN_REGSP( SPEC_OCLS( OP_SYM_ETYPE(op))), + IN_STACK( OP_SYM_ETYPE(op)), + SPEC_OCLS(OP_SYM_ETYPE(op)) == eeprom); + + fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__, + OP_SYMBOL(op)->name); + } +#endif + } - if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) { + reg = newReg(regtype, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0, op); + debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size); + + if( SPEC_SCLS( OP_SYM_ETYPE( op ) ) == S_REGISTER ) { + fprintf(stderr, "%s:%d symbol %s is declared as register\n", __FILE__, __LINE__, + name); + + reg->accessBank = 1; + checkAddReg(&pic16_dynAccessRegs, reg); + hTabAddItem(&dynAccessRegNames, regname2key(name), reg); + + return (reg); + } - //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(&pic16_dynDirectBitRegs, reg); - reg->isBitField = 1; - } else - addSet(&pic16_dynDirectRegs, 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; +// } - } else { - debugLog (" -- %s is declared at address 0x30000x\n",name); - fprintf(stderr, " -- %s is declared at address 0x30000x\n",name); + if (IS_BITVAR (OP_SYM_ETYPE(op))) { +// fprintf(stderr, "%s:%d adding %s in bit registers\n", __FILE__, __LINE__, reg->name); + addSet(&pic16_dynDirectBitRegs, reg); + reg->isBitField = 1; + } else { +// fprintf(stderr, "%s:%d adding %s in direct registers\n", __FILE__, __LINE__, reg->name); +// addSet(&pic16_dynDirectRegs, reg); - return NULL; - } - } +#if 1 + if(!(IS_STATIC(OP_SYM_ETYPE(op)) + && OP_SYMBOL(op)->ival + )) +#endif + checkAddReg(&pic16_dynDirectRegs, reg); + } + + } else { +// debugLog (" -- %s is declared at address 0x30000x\n",name); + return (reg); /* This was NULL before, but since we found it + * why not just return it?! */ + } - 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); - } + if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) { + reg->isFixed = 1; + reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op)); + + /* work around for user defined registers in access bank */ + if((reg->address>= 0x00 && reg->address < 0x80) + || (reg->address >= 0xf80 && reg->address <= 0xfff)) + reg->accessBank = 1; + + debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address); + } return reg; } @@ -688,7 +920,7 @@ pic16_allocDirReg (operand *op ) /* pic16_allocRegByName - allocates register of given type */ /*-----------------------------------------------------------------*/ regs * -pic16_allocRegByName (char *name, int size) +pic16_allocRegByName (char *name, int size, operand *op) { regs *reg; @@ -706,11 +938,13 @@ pic16_allocRegByName (char *name, int size) /* 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, NULL); + + fprintf (stderr,"%s:%d symbol name %s\tregop= %p\n", __FUNCTION__, __LINE__, name, op); + + reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0, op); debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size); - //fprintf(stderr, " -- added %s to hash, size = %d\n", name,reg->size); + //fprintf(stderr, " -- added %s to hash, size = %d\n", name,reg->size); //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* initially commented out */ addSet(&pic16_dynDirectRegs, reg); @@ -722,13 +956,13 @@ pic16_allocRegByName (char *name, int size) /*-----------------------------------------------------------------*/ /* RegWithIdx - returns pointer to register with index number */ /*-----------------------------------------------------------------*/ -static regs * -typeRegWithIdx (int idx, int type, int fixed) +regs *pic16_typeRegWithIdx (int idx, int type, int fixed) { regs *dReg; debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx); +// fprintf(stderr, "%s - requesting index = 0x%x\n", __FUNCTION__, idx); switch (type) { @@ -751,7 +985,7 @@ typeRegWithIdx (int idx, int type, int fixed) } break; case REG_SFR: - if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx, fixed)) != NULL ) { + if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx, 1)) != NULL ) { debugLog ("Found a Processor Register!\n"); return dReg; } @@ -774,14 +1008,16 @@ pic16_regWithIdx (int idx) { regs *dReg; - if( (dReg = typeRegWithIdx(idx,REG_GPR,0)) != NULL) + if( (dReg = pic16_typeRegWithIdx(idx,REG_GPR,0)) != NULL) return dReg; - if( (dReg = typeRegWithIdx(idx,REG_SFR,0)) != NULL) + if( (dReg = pic16_typeRegWithIdx(idx,REG_SFR,0)) != NULL) return dReg; - if( (dReg = typeRegWithIdx(idx,REG_STK,0)) != NULL) +#if 0 + if( (dReg = pic16_typeRegWithIdx(idx,REG_STK,0)) != NULL) return dReg; +#endif return NULL; } @@ -796,13 +1032,14 @@ pic16_allocWithIdx (int idx) regs *dReg; debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx); +// fprintf(stderr, "%s - allocating with index = 0x%x\n", __FUNCTION__,idx); if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx,0)) != NULL) { debugLog ("Found a Dynamic Register!\n"); } else if( (dReg = regWithIdx ( pic16_dynStackRegs, idx,0)) != NULL ) { debugLog ("Found a Stack Register!\n"); - } else if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx,0)) != NULL ) { + } else if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx,1)) != NULL ) { debugLog ("Found a Processor Register!\n"); fprintf(stderr, "Found a processor register! %s\n", dReg->name); } else if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx,0)) != NULL ) { @@ -928,9 +1165,14 @@ static void writeSetUsedRegs(FILE *of, set *dRegs) extern void pic16_groupRegistersInSection(set *regset); extern void pic16_dump_equates(FILE *of, set *equs); +extern void pic16_dump_access(FILE *of, set *section); //extern void pic16_dump_map(void); -extern void pic16_dump_section(FILE *of, set *section, int fix); +extern void pic16_dump_usection(FILE *of, set *section, int fix); +extern void pic16_dump_isection(FILE *of, set *section, int fix); +extern void pic16_dump_int_registers(FILE *of, set *section); +extern void pic16_dump_idata(FILE *of, set *idataSymSet); +extern void pic16_dump_gsection(FILE *of, set *sections); static void packBits(set *bregs) { @@ -953,7 +1195,7 @@ static void packBits(set *bregs) if(breg->isFixed) { //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address); - bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1); + bitfield = pic16_typeRegWithIdx (breg->address >> 3, -1 , 1); breg->rIdx = breg->address & 7; breg->address >>= 3; @@ -994,137 +1236,56 @@ static void packBits(set *bregs) } - - -#if 0 -static 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++; - } - } - -} - -static 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(use_rIdx) { - if (reg->type != REG_SFR) { - fprintf (of, "%s\tEQU\t0x%03x\n", - reg->name, - reg->rIdx); - } - } - else - fprintf (of, "%s\tEQU\t0x%03x\n", - reg->name, - reg->address); - } - } - -} -#endif - void pic16_writeUsedRegs(FILE *of) { packBits(pic16_dynDirectBitRegs); +// fprintf(stderr, "%s: pic16_dynAllocRegs\n", __FUNCTION__); pic16_groupRegistersInSection(pic16_dynAllocRegs); + +// fprintf(stderr, "%s: pic16_dynInternalRegs\n", __FUNCTION__); pic16_groupRegistersInSection(pic16_dynInternalRegs); + +// fprintf(stderr, "%s: pic16_dynStackRegs\n", __FUNCTION__); pic16_groupRegistersInSection(pic16_dynStackRegs); + +// fprintf(stderr, "%s: pic16_dynDirectRegs\n", __FUNCTION__); pic16_groupRegistersInSection(pic16_dynDirectRegs); + +// fprintf(stderr, "%s: pic16_dynDirectBitsRegs\n", __FUNCTION__); pic16_groupRegistersInSection(pic16_dynDirectBitRegs); + +// fprintf(stderr, "%s: pic16_dynProcessorRegs\n", __FUNCTION__); pic16_groupRegistersInSection(pic16_dynProcessorRegs); +// fprintf(stderr, "%s: pic16_dynAccessRegs\n", __FUNCTION__); + pic16_groupRegistersInSection(pic16_dynAccessRegs); -#if 0 - pic16_assignFixedRegisters(pic16_dynAllocRegs); - pic16_assignFixedRegisters(pic16_dynStackRegs); - pic16_assignFixedRegisters(pic16_dynDirectRegs); - pic16_assignFixedRegisters(pic16_dynProcessorRegs); - - pic16_assignRelocatableRegisters(pic16_dynDirectBitRegs, 0); - pic16_assignRelocatableRegisters(pic16_dynInternalRegs,0); - pic16_assignRelocatableRegisters(pic16_dynAllocRegs,0); - pic16_assignRelocatableRegisters(pic16_dynStackRegs,0); - pic16_assignRelocatableRegisters(pic16_dynDirectRegs,0); -#endif - -// pic16_dump_map(); -// pic16_dump_cblock(of); - + /* dump equates */ pic16_dump_equates(of, pic16_equ_data); - - pic16_dump_section(of, pic16_rel_udata, 0); - pic16_dump_section(of, pic16_fix_udata, 1); - -#if 0 - bitEQUs(of,pic16_dynDirectBitRegs); - aliasEQUs(of,pic16_dynAllocRegs,0); - aliasEQUs(of,pic16_dynDirectRegs,0); - aliasEQUs(of,pic16_dynStackRegs,0); - aliasEQUs(of,pic16_dynProcessorRegs,1); -#endif - -} -#if 0 -/*-----------------------------------------------------------------*/ -/* allDefsOutOfRange - all definitions are out of a range */ -/*-----------------------------------------------------------------*/ -static bool -allDefsOutOfRange (bitVect * defs, int fseq, int toseq) -{ - int i; +// pic16_dump_esection(of, pic16_rel_eedata, 0); +// pic16_dump_esection(of, pic16_fix_eedata, 0); - debugLog ("%s\n", __FUNCTION__); - if (!defs) - return TRUE; - - for (i = 0; i < defs->size; i++) - { - iCode *ic; - - if (bitVectBitValue (defs, i) && - (ic = hTabItemWithKey (iCodehTab, i)) && - (ic->seq >= fseq && ic->seq <= toseq)) + /* dump access bank symbols */ + pic16_dump_access(of, pic16_acs_udata); - return FALSE; + /* dump initialised data */ + pic16_dump_isection(of, rel_idataSymSet, 0); + pic16_dump_isection(of, fix_idataSymSet, 1); - } + /* dump internal registers */ + pic16_dump_int_registers(of, pic16_int_regs); + + /* dump generic section variables */ + pic16_dump_gsection(of, sectNames); - return TRUE; + /* dump other variables */ + pic16_dump_usection(of, pic16_rel_udata, 0); + pic16_dump_usection(of, pic16_fix_udata, 1); + } -#endif + /*-----------------------------------------------------------------*/ /* computeSpillable - given a point find the spillable live ranges */ @@ -1609,7 +1770,9 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym) /* check if there are any live ranges that not used in the remainder of the block */ - if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic))) + if (!_G.blockSpil && + !isiCodeInFunctionCall (ic) && + (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic))) { sym = leastUsedLR (selectS); if (!sym->remat) @@ -1734,6 +1897,7 @@ static regs * getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym) { regs *reg; + int j; debugLog ("%s\n", __FUNCTION__); tryAgain: @@ -1749,6 +1913,11 @@ tryAgain: if (!spilSomething (ic, ebp, sym)) return NULL; + /* make sure partially assigned registers aren't reused */ + for (j=0; j<=sym->nRegs; j++) + if (sym->regs[j]) + sym->regs[j]->isFree = 0; + /* this looks like an infinite loop but in really selectSpil will abort */ goto tryAgain; @@ -1761,6 +1930,7 @@ static regs * getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym) { regs *reg; + int j; debugLog ("%s\n", __FUNCTION__); tryAgain: @@ -1776,6 +1946,11 @@ tryAgain: if (!spilSomething (ic, ebp, sym)) return NULL; + /* make sure partially assigned registers aren't reused */ + for (j=0; j<=sym->nRegs; j++) + if (sym->regs[j]) + sym->regs[j]->isFree = 0; + /* this looks like an infinite loop but in really selectSpil will abort */ goto tryAgain; @@ -1833,6 +2008,13 @@ deassignLRs (iCode * ic, eBBlock * ebp) if (!bitVectBitValue (_G.regAssigned, sym->key)) continue; + /* special case for shifting: there is a case where shift count + * can be allocated in the same register as the result, so do not + * free right registers if same as result registers, cause genShiftLeft + * will fail -- VR */ + if(ic->op == LEFT_OP) + continue; + /* special case check if this is an IFX & the privious one was a pop and the previous one was not spilt then keep track @@ -1863,6 +2045,7 @@ deassignLRs (iCode * ic, eBBlock * ebp) (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */ result->liveTo > ic->seq && /* and will live beyond this */ result->liveTo <= ebp->lSeq && /* does not go beyond this block */ + result->liveFrom == ic->seq && /* does not start before here */ result->regType == sym->regType && /* same register types */ result->nRegs && /* which needs registers */ !result->isspilt && /* and does not already have them */ @@ -2001,6 +2184,31 @@ xchgPositions: } } +/*------------------------------------------------------------------*/ +/* verifyRegsAssigned - make sure an iTemp is properly initialized; */ +/* it should either have registers or have beed spilled. Otherwise, */ +/* there was an uninitialized variable, so just spill this to get */ +/* the operand in a valid state. */ +/*------------------------------------------------------------------*/ +static void +verifyRegsAssigned (operand *op, iCode * ic) +{ + symbol * sym; + + if (!op) return; + if (!IS_ITEMP (op)) return; + + sym = OP_SYMBOL (op); + if (sym->isspilt) return; + if (!sym->nRegs) return; + if (sym->regs[0]) return; + + werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT, + sym->prereqv ? sym->prereqv->name : sym->name); + spillThis (sym); +} + + /*-----------------------------------------------------------------*/ /* serialRegAssign - serially allocate registers to the variables */ /*-----------------------------------------------------------------*/ @@ -2008,14 +2216,12 @@ static void serialRegAssign (eBBlock ** ebbs, int count) { int i; - + iCode *ic; + debugLog ("%s\n", __FUNCTION__); /* for all blocks */ for (i = 0; i < count; i++) { - - iCode *ic; - if (ebbs[i]->noPath && (ebbs[i]->entryLabel != entryLabel && ebbs[i]->entryLabel != returnLabel)) @@ -2025,7 +2231,16 @@ serialRegAssign (eBBlock ** ebbs, int count) for (ic = ebbs[i]->sch; ic; ic = ic->next) { - debugLog (" op: %s\n", decodeOp (ic->op)); + debugLog (" op: %s\n", pic16_decodeOp (ic->op)); + + if(IC_RESULT(ic) && !IS_ITEMP( IC_RESULT(ic))) + pic16_allocDirReg(IC_RESULT(ic)); + + if(IC_LEFT(ic) && !IS_ITEMP( IC_LEFT(ic))) + pic16_allocDirReg(IC_LEFT(ic)); + + if(IC_RIGHT(ic) && !IS_ITEMP( IC_RIGHT(ic))) + pic16_allocDirReg(IC_RIGHT(ic)); /* if this is an ipop that means some live range will have to be assigned again */ @@ -2092,6 +2307,17 @@ serialRegAssign (eBBlock ** ebbs, int count) } + /* If the live range preceeds the point of definition + then ideally we must take into account registers that + have been allocated after sym->liveFrom but freed + before ic->seq. This is complicated, so spill this + symbol instead and let fillGaps handle the allocation. */ + if (sym->liveFrom < ic->seq) + { + spillThis (sym); + continue; + } + /* if it has a spillocation & is used less than all other live ranges then spill this */ if (willCS) { @@ -2118,9 +2344,22 @@ serialRegAssign (eBBlock ** ebbs, int count) if (ic->op == RECEIVE) debugLog ("When I get clever, I'll optimize the receive logic\n"); + if(POINTER_GET(ic) && IS_BITFIELD(getSpec(operandType(IC_RESULT(ic)))) + && (SPEC_BLEN(getSpec(operandType(IC_RESULT(ic))))==1) + && (ic->next->op == IFX) + && (OP_LIVETO(IC_RESULT(ic)) == ic->next->seq)) { + + /* skip register allocation since none will be used */ + for(j=0;jnRegs;j++) + sym->regs[j] = newReg(REG_TMP, PO_GPR_TEMP, 0, "bad", 1, 0, NULL); +// OP_SYMBOL(IC_RESULT(ic))->nRegs = 0; + + continue; + } + /* if we need ptr regs for the right side then mark it */ - if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type) + if (POINTER_GET (ic) && IS_SYMOP( IC_LEFT(ic) ) && getSize (OP_SYMBOL (IC_LEFT (ic))->type) <= (unsigned) PTRSIZE) { pic16_ptrRegReq++; @@ -2129,7 +2368,6 @@ serialRegAssign (eBBlock ** ebbs, int count) /* else we assign registers to it */ _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key); - debugLog (" %d - \n", __LINE__); if(debugF) bitVectDebugOn(_G.regAssigned, debugF); @@ -2170,6 +2408,40 @@ serialRegAssign (eBBlock ** ebbs, int count) } } } + + /* Check for and fix any problems with uninitialized operands */ + for (i = 0; i < count; i++) + { + iCode *ic; + + if (ebbs[i]->noPath && + (ebbs[i]->entryLabel != entryLabel && + ebbs[i]->entryLabel != returnLabel)) + continue; + + for (ic = ebbs[i]->sch; ic; ic = ic->next) + { + if (SKIP_IC2 (ic)) + continue; + + if (ic->op == IFX) + { + verifyRegsAssigned (IC_COND (ic), ic); + continue; + } + + if (ic->op == JUMPTABLE) + { + verifyRegsAssigned (IC_JTCOND (ic), ic); + continue; + } + + verifyRegsAssigned (IC_RESULT (ic), ic); + verifyRegsAssigned (IC_LEFT (ic), ic); + verifyRegsAssigned (IC_RIGHT (ic), ic); + } + } + } /*-----------------------------------------------------------------*/ @@ -2448,7 +2720,6 @@ regTypeNum () if (IS_AGGREGATE (sym->type) || sym->isptr) sym->type = aggrToPtr (sym->type, FALSE); debugLog (" %d - no reg needed - used as a return\n", __LINE__); - continue; } @@ -2461,21 +2732,21 @@ regTypeNum () (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) { + !IS_BITVAR (sym->etype) && + (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) { + if (ptrPseudoSymSafe (sym, ic)) { + + symbol *psym; + + debugLog (" %d - \n", __LINE__); + /* 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 = rematStr (OP_SYMBOL (IC_LEFT (ic))); psym->type = sym->type; psym->etype = sym->etype; + psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic))); strcpy (psym->rname, psym->name); sym->isspilt = 1; sym->usl.spillLoc = psym; @@ -2498,8 +2769,9 @@ regTypeNum () #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; + // what IS this ???? (HJD) + debugLog (" %d const pointer type requires %d registers, changing to 3\n",__LINE__,sym->nRegs); // patch 14 + sym->nRegs = 3; // patch 14 } if (sym->nRegs > 4) { @@ -2525,6 +2797,7 @@ regTypeNum () /* registers for true symbols we will */ /* see how things go */ sym->nRegs = 0; + } } @@ -2657,37 +2930,13 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) iCode *dic, *sic; debugLog ("%d\t%s\n", __LINE__, __FUNCTION__); - debugLog ("ic->op = %s\n", decodeOp( ic->op ) ); + debugLog ("ic->op = %s\n", pic16_decodeOp( ic->op ) ); debugAopGet (" result:", IC_RESULT (ic)); debugAopGet (" left:", IC_LEFT (ic)); debugAopGet (" right:", IC_RIGHT (ic)); - /* 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)); - fprintf(stderr, " setting config word to %x\n", - (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand)); - pic16_assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))), - (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand)); - } - - - debugLog(" %d\n", __LINE__); - - /* 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; +// fprintf(stderr, "%s:%d symbol = %s\n", __FILE__, __LINE__, OP_SYMBOL( IC_RESULT(ic))->name); - } - } debugLog(" %d - actuall processing\n", __LINE__ ); if (!IS_ITEMP (IC_RESULT (ic))) { @@ -2695,16 +2944,11 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) debugLog (" %d - result is not temp\n", __LINE__); } -#if 0 - if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) { - debugLog (" %d - left is not temp, allocating\n", __LINE__); - pic16_allocDirReg(IC_LEFT (ic)); - } -#endif +// if(IS_VALOP(IC_RIGHT(ic)))return 0; /* See BUGLOG0001 - VR */ #if 1 - if (!IS_ITEMP (IC_RIGHT (ic))) { + if (!IS_ITEMP (IC_RIGHT (ic)) /*&& (!IS_PARM(IC_RESULT(ic)))*/) { debugLog (" %d - not packing - right is not temp\n", __LINE__); pic16_allocDirReg(IC_RIGHT (ic)); return 0; @@ -2729,14 +2973,6 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) } -#if 0 - if(ic->op == CALL || ic->op == PCALL) { - addSet(&pic16_builtin_functions, OP_SYMBOL( IC_LEFT(ic))); - debugLog ("%d This is a call, function: %s\n", __LINE__, OP_SYMBOL(IC_LEFT(ic))->name); - return 0; - } -#endif - /* find the definition of iTempNN scanning backwards if we find a a use of the true symbol before we find the definition then we cannot pack */ @@ -2760,21 +2996,6 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) debugLog("%d\tSearching for iTempNN\n", __LINE__); -#if 0 - if(IS_TRUE_SYMOP( IC_RESULT(dic))) { - debugLog("%d - dic result is a TRUE_SYMOP\n", __LINE__); - debugAopGet(" result is ", IC_RESULT(dic)); - } - if(IS_TRUE_SYMOP( IC_LEFT(dic))) { - debugLog("%d - dic left is a SYMOP\n", __LINE__); - debugAopGet(" left is ", IC_LEFT(dic)); - } - if(IS_TRUE_SYMOP( IC_RIGHT(dic))) { - debugLog("%d - dic right is a SYMOP\n", __LINE__); - debugAopGet(" right is ", IC_RIGHT(dic)); - } -#endif - if (IS_TRUE_SYMOP (IC_RESULT (dic)) && IS_OP_VOLATILE (IC_RESULT (dic))) { @@ -2783,21 +3004,11 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) break; } -#if 0 - if (IS_TRUE_SYMOP( IC_RIGHT (dic)) && - IS_OP_VOLATILE (IC_RIGHT(dic))) - { - debugLog (" %d - dic right is VOLATILE\n", __LINE__); - dic = NULL; - break; - } -#endif +#if 1 + if( IS_SYMOP( IC_RESULT(dic)) && + IS_BITFIELD( OP_SYMBOL(IC_RESULT(dic))->etype ) ) { -#if 0 - if (IS_TRUE_SYMOP( IC_LEFT (dic)) && - IS_OP_VOLATILE (IC_LEFT(dic))) - { - debugLog (" %d - dic left is VOLATILE\n", __LINE__); + debugLog (" %d - result is bitfield\n", __LINE__); dic = NULL; break; } @@ -2846,12 +3057,30 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) if (!dic) return 0; /* did not find */ +#if 1 + /* This code is taken from the hc08 port. Do not know + * if it fits for pic16, but I leave it here just in case */ + + /* if assignment then check that right is not a bit */ + if (ASSIGNMENT (dic) && !POINTER_SET (dic)) { + sym_link *etype = operandType (IC_RIGHT (dic)); + + if (IS_BITFIELD (etype)) { + /* if result is a bit too then it's ok */ + etype = operandType (IC_RESULT (dic)); + if (!IS_BITFIELD (etype)) { + debugLog(" %d bitfields\n"); + return 0; + } + } + } +#endif + /* if the result is on stack or iaccess then it must be the same atleast one of the operands */ if (OP_SYMBOL (IC_RESULT (ic))->onStack || OP_SYMBOL (IC_RESULT (ic))->iaccess) { - /* the operation has only one symbol operator then we can pack */ if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) || @@ -2898,6 +3127,17 @@ pack: } +#if 1 + +#define NO_packRegsForAccUse +#define NO_packRegsForSupport +#define NO_packRegsForOneuse +#define NO_cast_peep + +#endif + + +#ifndef NO_packRegsForSupport /*-----------------------------------------------------------------*/ /* findAssignToSym : scanning backwards looks for first assig found */ /*-----------------------------------------------------------------*/ @@ -2937,7 +3177,6 @@ findAssignToSym (operand * op, iCode * ic) if ((ic->op == '+' || ic->op == '-') && OP_SYMBOL (IC_RIGHT (dic))->onStack) { - if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key && IC_LEFT (ic)->key != IC_RIGHT (dic)->key && IC_RIGHT (ic)->key != IC_RIGHT (dic)->key) @@ -2975,7 +3214,10 @@ findAssignToSym (operand * op, iCode * ic) } +#endif + +#ifndef NO_packRegsForSupport /*-----------------------------------------------------------------*/ /* packRegsForSupport :- reduce some registers for support calls */ /*-----------------------------------------------------------------*/ @@ -3053,10 +3295,12 @@ right: return change; } +#endif -#define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly) +#define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly) +#ifndef NO_packRegsForOneuse /*-----------------------------------------------------------------*/ /* packRegsForOneuse : - will reduce some registers for single Use */ /*-----------------------------------------------------------------*/ @@ -3073,7 +3317,7 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp) /* only upto 2 bytes since we cannot predict the usage of b, & acc */ - if (getSize (operandType (op)) > (pic16_fReturnSizePic - 2) && + if (getSize (operandType (op)) > (pic16_fReturnSizePic - 3) && /* was 2, changed to 3 -- VR */ ic->op != RETURN && ic->op != SEND) return NULL; @@ -3186,6 +3430,8 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp) return sic; } +#endif + /*-----------------------------------------------------------------*/ /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */ @@ -3217,6 +3463,9 @@ isBitwiseOptimizable (iCode * ic) return FALSE; } + +#ifndef NO_packRegsForAccUse + /*-----------------------------------------------------------------*/ /* packRegsForAccUse - pack registers for acc use */ /*-----------------------------------------------------------------*/ @@ -3339,6 +3588,7 @@ packRegsForAccUse (iCode * ic) IC_LEFT (uic)->key != IC_RESULT (ic)->key) return; +#if 1 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))) || @@ -3348,6 +3598,7 @@ packRegsForAccUse (iCode * ic) OP_SYMBOL (IC_RESULT (ic))->accuse = 1; return; } +#endif debugLog (" %s:%d\n", __FUNCTION__,__LINE__); /* if the other one is not on stack then we can */ @@ -3371,6 +3622,8 @@ accuse: } +#endif + /*-----------------------------------------------------------------*/ /* packForPush - hueristics to reduce iCode for pushing */ @@ -3390,20 +3643,16 @@ packForReceive (iCode * ic, eBBlock * ebp) for (dic = ic->next; dic; dic = dic->next) { - - - if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) - debugLog (" used on left\n"); + debugLog (" used on left\n"); if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key) - debugLog (" used on right\n"); + debugLog (" used on right\n"); if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key) - debugLog (" used on result\n"); + debugLog (" used on result\n"); if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) || - (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)) + (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)) return; - } debugLog (" hey we can remove this unnecessary assign\n"); @@ -3415,11 +3664,22 @@ static void packForPush (iCode * ic, eBBlock * ebp) { iCode *dic; - + debugLog ("%s\n", __FUNCTION__); if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic))) return; +#if 0 + { + int n1, n2; + + n1 = bitVectnBitsOn( OP_DEFS(IC_LEFT(ic))); + n2 = bitVectnBitsOn( OP_USES(IC_LEFT(ic))); + debugf3("defs: %d\tuses: %d\t%s\n", n1, n2, printILine(ic)); + debugf2("IC_LEFT(ic): from %d to %d\n", OP_LIVEFROM(IC_LEFT(ic)), OP_LIVETO(IC_LEFT(ic))); + } +#endif + /* must have only definition & one usage */ if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 || bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1) @@ -3430,12 +3690,26 @@ packForPush (iCode * ic, eBBlock * ebp) bitVectFirstBit (OP_DEFS (IC_LEFT (ic)))))) return; + /* if definition is not assignment, + * or is not pointer (because pointer might have changed) */ if (dic->op != '=' || POINTER_SET (dic)) return; + /* we must ensure that we can use the delete the assignment, + * because the source might have been modified in between. + * Until I know how to fix this, I'll use the adhoc fix + * to check the liveranges */ + if((OP_LIVEFROM(IC_RIGHT(dic))==0) || (OP_LIVETO(IC_RIGHT(dic))==0)) + return; +// debugf2("IC_RIGHT(dic): from %d to %d\n", OP_LIVEFROM(IC_RIGHT(dic)), OP_LIVETO(IC_RIGHT(dic))); + + + /* we now we know that it has one & only one def & use and the that the definition is an assignment */ IC_LEFT (ic) = IC_RIGHT (dic); + + debugf("remiCodeFromeBBlock: %s\n", printILine(dic)); remiCodeFromeBBlock (ebp, dic); bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key); @@ -3460,35 +3734,35 @@ static void isData(sym_link *sl) { FILE *of = stderr; - if(!pic16_ralloc_debug)return; - - 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; - } - - } - } + if(!pic16_ralloc_debug)return; + + 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; + } + } + } } + /*--------------------------------------------------------------------*/ /* pic16_packRegisters - does some transformations to reduce */ /* register pressure */ @@ -3514,8 +3788,7 @@ pic16_packRegisters (eBBlock * ebp) { // debugLog("%d\n", __LINE__); /* find assignment of the form TrueSym := iTempNN:1 */ - /* see BUGLOG0001 for workaround with the CAST - VR */ - if ((ic->op == '=' || ic->op == CAST) && !POINTER_SET (ic)) + if ( (ic->op == '=') && !POINTER_SET (ic) ) // patch 11 change += packRegsForAssign (ic, ebp); /* debug stuff */ if (ic->op == '=') @@ -3572,10 +3845,59 @@ pic16_packRegisters (eBBlock * ebp) printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type); } - if (POINTER_SET (ic)) - debugLog (" %d - Pointer set\n", __LINE__); + if(IS_TRUE_SYMOP ( IC_RIGHT(ic))) { + debugAopGet (" right:", IC_RIGHT (ic)); + printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type); +// pic16_allocDirReg(IC_RIGHT(ic)); + } + + if(IS_TRUE_SYMOP ( IC_RESULT(ic))) { + debugAopGet (" result:", IC_RESULT (ic)); + printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type); +// pic16_allocDirReg(IC_RESULT(ic)); + } + if (POINTER_SET (ic)) + debugLog (" %d - Pointer set\n", __LINE__); + + /* Look for two subsequent iCodes with */ + /* iTemp := _c; */ + /* _c = iTemp & op; */ + /* and replace them by */ + /* iTemp := _c; */ + /* _c = _c & op; */ + if ((ic->op == BITWISEAND || ic->op == '|' || ic->op == '^') + && ic->prev + && ic->prev->op == '=' + && IS_ITEMP (IC_LEFT (ic)) + && IC_LEFT (ic) == IC_RESULT (ic->prev) + && isOperandEqual (IC_RESULT(ic), IC_RIGHT(ic->prev))) + { + iCode* ic_prev = ic->prev; + symbol* prev_result_sym = OP_SYMBOL (IC_RESULT (ic_prev)); + + ReplaceOpWithCheaperOp (&IC_LEFT (ic), IC_RESULT (ic)); + if (IC_RESULT (ic_prev) != IC_RIGHT (ic)) { + bitVectUnSetBit (OP_USES (IC_RESULT (ic_prev)), ic->key); + if (/*IS_ITEMP (IC_RESULT (ic_prev)) && */ + prev_result_sym->liveTo == ic->seq) + { + prev_result_sym->liveTo = ic_prev->seq; + } + } + bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key); + + bitVectSetBit (ic->rlive, IC_RESULT (ic)->key); + + if (bitVectIsZero (OP_USES (IC_RESULT (ic_prev)))) { + bitVectUnSetBit (ic->rlive, IC_RESULT (ic)->key); + bitVectUnSetBit (OP_DEFS (IC_RESULT (ic_prev)), ic_prev->key); + remiCodeFromeBBlock (ebp, ic_prev); + hTabDeleteItem (&iCodehTab, ic_prev->key, ic_prev, DELETE_ITEM, NULL); + } + } + /* if this is an itemp & result of a address of a true sym then mark this as rematerialisable */ if (ic->op == ADDRESS_OF && @@ -3635,9 +3957,11 @@ pic16_packRegisters (eBBlock * ebp) } if (POINTER_GET (ic)) { - OP_SYMBOL (IC_LEFT (ic))->uptr = 1; - debugLog (" marking as a pointer (get) =>"); - debugAopGet (" left:", IC_LEFT (ic)); + if(IS_SYMOP(IC_LEFT(ic))) { + OP_SYMBOL (IC_LEFT (ic))->uptr = 1; + debugLog (" marking as a pointer (get) =>"); + debugAopGet (" left:", IC_LEFT (ic)); + } } //debugLog(" %d %s\n", __LINE__, __FUNCTION__); @@ -3692,22 +4016,27 @@ pic16_packRegisters (eBBlock * ebp) debugLog(" %d\n", __LINE__); +#ifndef NO_packRegsForSupport /* reduce for support function calls */ if (ic->supportRtn || ic->op == '+' || ic->op == '-') packRegsForSupport (ic, ebp); +#endif /* 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); +#ifndef NO_packRegsForOneuse /* 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); +#endif +#ifndef NO_packRegsForOneuse /* if pointer set & left has a size more than one and right is not in far space */ if (POINTER_SET (ic) && @@ -3717,7 +4046,9 @@ pic16_packRegisters (eBBlock * ebp) getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1) packRegsForOneuse (ic, IC_RESULT (ic), ebp); +#endif +#ifndef NO_packRegsForOneuse /* if pointer get */ if (POINTER_GET (ic) && !isOperandInFarSpace (IC_RESULT (ic)) && @@ -3727,7 +4058,9 @@ pic16_packRegisters (eBBlock * ebp) packRegsForOneuse (ic, IC_LEFT (ic), ebp); debugLog("%d - return from packRegsForOneuse\n", __LINE__); +#endif +#ifndef NO_cast_peep /* if this is cast for intergral promotion then check if only use of the definition of the operand being casted/ if yes then replace @@ -3784,7 +4117,13 @@ pic16_packRegisters (eBBlock * ebp) } } } +#endif +#if 1 + /* there are some problems with packing variables + * it seems that the live range estimator doesn't + * estimate correctly the liveranges of some symbols */ + /* pack for PUSH iTempNN := (some variable in farspace) V1 push iTempNN ; @@ -3795,8 +4134,9 @@ pic16_packRegisters (eBBlock * ebp) { packForPush (ic, ebp); } +#endif - +#ifndef NO_packRegsForAccUse /* pack registers for accumulator use, when the result of an arithmetic or bit wise operation has only one use, that use is immediately following @@ -3813,9 +4153,10 @@ pic16_packRegisters (eBBlock * ebp) ) && IS_ITEMP (IC_RESULT (ic)) && - getSize (operandType (IC_RESULT (ic))) <= 2) + getSize (operandType (IC_RESULT (ic))) <= 1) packRegsForAccUse (ic); +#endif } } @@ -3876,6 +4217,8 @@ pic16_assignRegisters (eBBlock ** ebbs, int count) debugLog ("\nebbs before optimizing:\n"); dumpEbbsToDebug (ebbs, count); + _inRegAllocator = 1; + setToNull ((void *) &_G.funcrUsed); pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0; @@ -3915,6 +4258,11 @@ pic16_assignRegisters (eBBlock ** ebbs, int count) /* and serially allocate registers */ serialRegAssign (ebbs, count); +#if 0 + debugLog ("ebbs after serialRegAssign:\n"); + dumpEbbsToDebug (ebbs, count); +#endif + //pic16_freeAllRegs(); /* if stack was extended then tell the user */ @@ -3948,6 +4296,7 @@ pic16_assignRegisters (eBBlock ** ebbs, int count) debugLog ("ebbs after optimizing:\n"); dumpEbbsToDebug (ebbs, count); + _inRegAllocator = 0; genpic16Code (ic); @@ -3959,6 +4308,7 @@ pic16_assignRegisters (eBBlock ** ebbs, int count) /* mark all registers as free */ pic16_freeAllRegs (); + debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n"); debugLogClose (); return;