X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic16%2Fralloc.c;h=b283377805b123adaf9a30e055f873b1bc971b66;hb=820b7c701814ded6b791cee96570d4f9bb77a85c;hp=78ca883f2aa8e30f9b75870e356d1343f5c46817;hpb=cd4659a7dfa0f7cafc09f8621fa67a537172348b;p=fw%2Fsdcc diff --git a/src/pic16/ralloc.c b/src/pic16/ralloc.c index 78ca883f..b2833778 100644 --- a/src/pic16/ralloc.c +++ b/src/pic16/ralloc.c @@ -1,6 +1,6 @@ /*------------------------------------------------------------------------ - SDCCralloc.c - source file for register allocation. (8051) specific + ralloc.c - source file for register allocation. PIC16 specific Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998) Added Pic Port T.scott Dattalo scott@dattalo.com (2000) @@ -29,6 +29,7 @@ #include "ralloc.h" #include "pcode.h" #include "gen.h" +#include "device.h" #if defined(__BORLANDC__) || defined(_MSC_VER) #define STRCASECMP stricmp @@ -45,9 +46,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 @@ -77,7 +77,14 @@ set *pic16_dynInternalRegs=NULL; static hTab *dynDirectRegNames= NULL; //static hTab *regHash = NULL; /* a hash table containing ALL registers */ -static int dynrIdx=0x20; +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_builtin_functions=NULL; + +static int dynrIdx=0x10; //0x20; // starting temporary register rIdx static int rDirectIdx=0; int pic16_nRegs = 128; // = sizeof (regspic16) / sizeof (regs); @@ -89,7 +96,7 @@ int pic16_Gstack_base_addr=0; /* The starting address of registers that static void spillThis (symbol *); -static int debug = 1; +int pic16_ralloc_debug = 0; static FILE *debugF = NULL; /*-----------------------------------------------------------------*/ /* debugLog - open a file for debugging information */ @@ -104,7 +111,7 @@ debugLog (char *fmt,...) //char *bufferP=buffer; va_list ap; - if (!debug || !dstFileName) + if (!pic16_ralloc_debug || !dstFileName) return; @@ -145,8 +152,10 @@ debugLog (char *fmt,...) static void debugNewLine (void) { - if (debugF) - fputc ('\n', debugF); + if(!pic16_ralloc_debug)return; + + if (debugF) + fputc ('\n', debugF); } /*-----------------------------------------------------------------*/ /* debugLogClose - closes the debug log file (if opened) */ @@ -154,244 +163,142 @@ debugNewLine (void) static void debugLogClose (void) { - if (debugF) - { - fclose (debugF); - debugF = NULL; - } + if (debugF) { + fclose (debugF); + debugF = NULL; + } } + #define AOP(op) op->aop static char * debugAopGet (char *str, operand * op) { - if (str) - debugLog (str); + if(!pic16_ralloc_debug)return NULL; - printOperand (op, debugF); - debugNewLine (); + if (str) + debugLog (str); - return NULL; + printOperand (op, debugF); + debugNewLine (); + return NULL; } static char * decodeOp (unsigned int op) { + if (op < 128 && op > ' ') { + buffer[0] = (op & 0xff); + buffer[1] = 0; + return buffer; + } - if (op < 128 && op > ' ') - { - buffer[0] = (op & 0xff); - buffer[1] = 0; - return buffer; - } + switch (op) { + case IDENTIFIER: return "IDENTIFIER"; + case TYPE_NAME: return "TYPE_NAME"; + case CONSTANT: return "CONSTANT"; + case STRING_LITERAL: return "STRING_LITERAL"; + case SIZEOF: return "SIZEOF"; + case PTR_OP: return "PTR_OP"; + case INC_OP: return "INC_OP"; + case DEC_OP: return "DEC_OP"; + case LEFT_OP: return "LEFT_OP"; + case RIGHT_OP: return "RIGHT_OP"; + case LE_OP: return "LE_OP"; + case GE_OP: return "GE_OP"; + case EQ_OP: return "EQ_OP"; + case NE_OP: return "NE_OP"; + case AND_OP: return "AND_OP"; + case OR_OP: return "OR_OP"; + case MUL_ASSIGN: return "MUL_ASSIGN"; + case DIV_ASSIGN: return "DIV_ASSIGN"; + case MOD_ASSIGN: return "MOD_ASSIGN"; + case ADD_ASSIGN: return "ADD_ASSIGN"; + case SUB_ASSIGN: return "SUB_ASSIGN"; + case LEFT_ASSIGN: return "LEFT_ASSIGN"; + case RIGHT_ASSIGN: return "RIGHT_ASSIGN"; + case AND_ASSIGN: return "AND_ASSIGN"; + case XOR_ASSIGN: return "XOR_ASSIGN"; + case OR_ASSIGN: return "OR_ASSIGN"; + case TYPEDEF: return "TYPEDEF"; + case EXTERN: return "EXTERN"; + case STATIC: return "STATIC"; + case AUTO: return "AUTO"; + case REGISTER: return "REGISTER"; + case CODE: return "CODE"; + case EEPROM: return "EEPROM"; + case INTERRUPT: return "INTERRUPT"; + case SFR: return "SFR"; + case AT: return "AT"; + case SBIT: return "SBIT"; + case REENTRANT: return "REENTRANT"; + case USING: return "USING"; + case XDATA: return "XDATA"; + case DATA: return "DATA"; + case IDATA: return "IDATA"; + case PDATA: return "PDATA"; + case VAR_ARGS: return "VAR_ARGS"; + case CRITICAL: return "CRITICAL"; + case NONBANKED: return "NONBANKED"; + case BANKED: return "BANKED"; + case CHAR: return "CHAR"; + case SHORT: return "SHORT"; + case INT: return "INT"; + case LONG: return "LONG"; + case SIGNED: return "SIGNED"; + case UNSIGNED: return "UNSIGNED"; + case FLOAT: return "FLOAT"; + case DOUBLE: return "DOUBLE"; + case CONST: return "CONST"; + case VOLATILE: return "VOLATILE"; + case VOID: return "VOID"; + case BIT: return "BIT"; + case STRUCT: return "STRUCT"; + case UNION: return "UNION"; + case ENUM: return "ENUM"; + case ELIPSIS: return "ELIPSIS"; + case RANGE: return "RANGE"; + case FAR: return "FAR"; + case CASE: return "CASE"; + case DEFAULT: return "DEFAULT"; + case IF: return "IF"; + case ELSE: return "ELSE"; + case SWITCH: return "SWITCH"; + case WHILE: return "WHILE"; + case DO: return "DO"; + case FOR: return "FOR"; + case GOTO: return "GOTO"; + case CONTINUE: return "CONTINUE"; + case BREAK: return "BREAK"; + case RETURN: return "RETURN"; + case INLINEASM: return "INLINEASM"; + case IFX: return "IFX"; + case ADDRESS_OF: return "ADDRESS_OF"; + case GET_VALUE_AT_ADDRESS: return "GET_VALUE_AT_ADDRESS"; + case SPIL: return "SPIL"; + case UNSPIL: return "UNSPIL"; + case GETHBIT: return "GETHBIT"; + case BITWISEAND: return "BITWISEAND"; + case UNARYMINUS: return "UNARYMINUS"; + case IPUSH: return "IPUSH"; + case IPOP: return "IPOP"; + case PCALL: return "PCALL"; + case ENDFUNCTION: return "ENDFUNCTION"; + case JUMPTABLE: return "JUMPTABLE"; + case RRC: return "RRC"; + case RLC: return "RLC"; + case CAST: return "CAST"; + case CALL: return "CALL"; + case PARAM: return "PARAM "; + case NULLOP: return "NULLOP"; + case BLOCK: return "BLOCK"; + case LABEL: return "LABEL"; + case RECEIVE: return "RECEIVE"; + case SEND: return "SEND"; + } + sprintf (buffer, "unkown op %d %c", op, op & 0xff); - switch (op) - { - case IDENTIFIER: - return "IDENTIFIER"; - case TYPE_NAME: - return "TYPE_NAME"; - case CONSTANT: - return "CONSTANT"; - case STRING_LITERAL: - return "STRING_LITERAL"; - case SIZEOF: - return "SIZEOF"; - case PTR_OP: - return "PTR_OP"; - case INC_OP: - return "INC_OP"; - case DEC_OP: - return "DEC_OP"; - case LEFT_OP: - return "LEFT_OP"; - case RIGHT_OP: - return "RIGHT_OP"; - case LE_OP: - return "LE_OP"; - case GE_OP: - return "GE_OP"; - case EQ_OP: - return "EQ_OP"; - case NE_OP: - return "NE_OP"; - case AND_OP: - return "AND_OP"; - case OR_OP: - return "OR_OP"; - case MUL_ASSIGN: - return "MUL_ASSIGN"; - case DIV_ASSIGN: - return "DIV_ASSIGN"; - case MOD_ASSIGN: - return "MOD_ASSIGN"; - case ADD_ASSIGN: - return "ADD_ASSIGN"; - case SUB_ASSIGN: - return "SUB_ASSIGN"; - case LEFT_ASSIGN: - return "LEFT_ASSIGN"; - case RIGHT_ASSIGN: - return "RIGHT_ASSIGN"; - case AND_ASSIGN: - return "AND_ASSIGN"; - case XOR_ASSIGN: - return "XOR_ASSIGN"; - case OR_ASSIGN: - return "OR_ASSIGN"; - case TYPEDEF: - return "TYPEDEF"; - case EXTERN: - return "EXTERN"; - case STATIC: - return "STATIC"; - case AUTO: - return "AUTO"; - case REGISTER: - return "REGISTER"; - case CODE: - return "CODE"; - case EEPROM: - return "EEPROM"; - case INTERRUPT: - return "INTERRUPT"; - case SFR: - return "SFR"; - case AT: - return "AT"; - case SBIT: - return "SBIT"; - case REENTRANT: - return "REENTRANT"; - case USING: - return "USING"; - case XDATA: - return "XDATA"; - case DATA: - return "DATA"; - case IDATA: - return "IDATA"; - case PDATA: - return "PDATA"; - case VAR_ARGS: - return "VAR_ARGS"; - case CRITICAL: - return "CRITICAL"; - case NONBANKED: - return "NONBANKED"; - case BANKED: - return "BANKED"; - case CHAR: - return "CHAR"; - case SHORT: - return "SHORT"; - case INT: - return "INT"; - case LONG: - return "LONG"; - case SIGNED: - return "SIGNED"; - case UNSIGNED: - return "UNSIGNED"; - case FLOAT: - return "FLOAT"; - case DOUBLE: - return "DOUBLE"; - case CONST: - return "CONST"; - case VOLATILE: - return "VOLATILE"; - case VOID: - return "VOID"; - case BIT: - return "BIT"; - case STRUCT: - return "STRUCT"; - case UNION: - return "UNION"; - case ENUM: - return "ENUM"; - case ELIPSIS: - return "ELIPSIS"; - case RANGE: - return "RANGE"; - case FAR: - return "FAR"; - case CASE: - return "CASE"; - case DEFAULT: - return "DEFAULT"; - case IF: - return "IF"; - case ELSE: - return "ELSE"; - case SWITCH: - return "SWITCH"; - case WHILE: - return "WHILE"; - case DO: - return "DO"; - case FOR: - return "FOR"; - case GOTO: - return "GOTO"; - case CONTINUE: - return "CONTINUE"; - case BREAK: - return "BREAK"; - case RETURN: - return "RETURN"; - case INLINEASM: - return "INLINEASM"; - case IFX: - return "IFX"; - case ADDRESS_OF: - return "ADDRESS_OF"; - case GET_VALUE_AT_ADDRESS: - return "GET_VALUE_AT_ADDRESS"; - case SPIL: - return "SPIL"; - case UNSPIL: - return "UNSPIL"; - case GETHBIT: - return "GETHBIT"; - case BITWISEAND: - return "BITWISEAND"; - case UNARYMINUS: - return "UNARYMINUS"; - case IPUSH: - return "IPUSH"; - case IPOP: - return "IPOP"; - case PCALL: - return "PCALL"; - case ENDFUNCTION: - return "ENDFUNCTION"; - case JUMPTABLE: - return "JUMPTABLE"; - case RRC: - return "RRC"; - case RLC: - return "RLC"; - case CAST: - return "CAST"; - case CALL: - return "CALL"; - case PARAM: - return "PARAM "; - case NULLOP: - return "NULLOP"; - case BLOCK: - return "BLOCK"; - case LABEL: - return "LABEL"; - case RECEIVE: - return "RECEIVE"; - case SEND: - return "SEND"; - } - sprintf (buffer, "unkown op %d %c", op, op & 0xff); return buffer; } /*-----------------------------------------------------------------*/ @@ -399,18 +306,14 @@ decodeOp (unsigned int op) static char * debugLogRegType (short type) { + if(!pic16_ralloc_debug)return NULL; + switch (type) { + case REG_GPR: return "REG_GPR"; + case REG_PTR: return "REG_PTR"; + case REG_CND: return "REG_CND"; + } + sprintf (buffer, "unknown reg type %d", type); - switch (type) - { - case REG_GPR: - return "REG_GPR"; - case REG_PTR: - return "REG_PTR"; - case REG_CND: - return "REG_CND"; - } - - sprintf (buffer, "unknown reg type %d", type); return buffer; } @@ -436,41 +339,50 @@ 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) +regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias, operand *refop) { 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 = 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); + } + - 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(); + dReg->isFree = 0; + dReg->wasUsed = 1; + dReg->isEmitted = 0; + + if(type == REG_SFR) { + dReg->isFixed = 1; + dReg->address = rIdx; + dReg->accessBank = 1; + } else { + dReg->isFixed = 0; + dReg->address = 0; + dReg->accessBank = 0; + } - hTabAddItem(&dynDirectRegNames, regname2key(name), dReg); +// fprintf(stderr,"newReg: %s, rIdx = 0x%02x\taccess= %d\tregop= %p\n",dReg->name,rIdx, dReg->accessBank, refop); + + dReg->size = size; + dReg->alias = alias; + dReg->reg_alias = NULL; + dReg->reglives.usedpFlows = newSet(); + dReg->reglives.assignedpFlows = newSet(); + dReg->regop = refop; + + if(!(type == REG_SFR && alias == 0x80)) + hTabAddItem(&dynDirectRegNames, regname2key(name), dReg); return dReg; } @@ -505,8 +417,12 @@ regFindFree (set *dRegs) for (dReg = setFirstItem(dRegs) ; dReg ; dReg = setNextItem(dRegs)) { - if(dReg->isFree) +// fprintf(stderr, "%s:%d checking register %s (%p) [rIdx: 0x%02x] if free= %d\n", +// __FILE__, __LINE__, dReg->name, dReg, dReg->rIdx, dReg->isFree); + + if(dReg->isFree) { return dReg; + } } return NULL; @@ -523,7 +439,7 @@ void pic16_initStack(int base_address, int size) //fprintf(stderr,"initStack"); for(i = 0; iwasUsed = 0; // we do not know if they are going to be used at all + reg->accessBank = 1; // implicit add access Bank + + return addSet(&pic16_dynProcessorRegs, reg); } /*-----------------------------------------------------------------* @@ -542,13 +463,14 @@ pic16_allocProcessorRegister(int rIdx, char * name, short po_type, int alias) regs * pic16_allocInternalRegister(int rIdx, char * name, short po_type, int alias) { - regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias); + regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias, NULL); - //fprintf(stderr,"pic16_allocInternalRegister %s addr =0x%x\n",name,rIdx); - if(reg) { - reg->wasUsed = 0; - return addSet(&pic16_dynInternalRegs,reg); - } +// 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); + } return NULL; } @@ -558,12 +480,45 @@ pic16_allocInternalRegister(int rIdx, char * name, short po_type, int alias) static regs * allocReg (short type) { + regs * reg=NULL; + +#if 0 + if(dynrIdx > pic16_nRegs) + return NULL; +#endif + + /* try to reuse some unused registers */ + reg = regFindFree( pic16_dynAllocRegs ); + + if(reg) { +// fprintf(stderr, "%s: found FREE register %s\n", __FILE__, reg->name); + } + + if(!reg) { + reg = newReg(REG_GPR, PO_GPR_TEMP, dynrIdx++, NULL, 1, 0, NULL); +// addSet(&pic16_dynAllocRegs, reg); + } - debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type)); - //fprintf(stderr,"allocReg\n"); + addSet(&pic16_dynAllocRegs, reg); + reg->isFree=0; - return addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0)); +// debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type)); + +// 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); + + if(reg) { + reg->accessBank = 1; /* this is a temporary register alloc in accessBank */ + reg->isLocal = 1; /* this is a local frame register */ + } + + 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); + } + + return (reg); // addSet(&pic16_dynAllocRegs,reg); } @@ -584,6 +539,8 @@ pic16_dirregWithName (char *name) hkey = regname2key(name); +// fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey); + reg = hTabFirstItemWK(dynDirectRegNames, hkey); while(reg) { @@ -599,11 +556,6 @@ pic16_dirregWithName (char *name) return NULL; // name wasn't found in the hash table } -static int IS_CONFIG_ADDRESS(int address) -{ - - return address >= 0x300000 && address <= 0x300000d; -} /*-----------------------------------------------------------------*/ /* pic16_allocDirReg - allocates register of given type */ @@ -611,107 +563,167 @@ static int IS_CONFIG_ADDRESS(int address) regs * pic16_allocDirReg (operand *op ) { - regs *reg; char *name; - if(!IS_SYMOP(op)) { - debugLog ("%s BAD, op is NULL\n", __FUNCTION__); - return NULL; - } + 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; + 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_OCLS( OP_SYM_ETYPE(op))) { // patch 13 + 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); // + } // + return NULL; // + } // patch 13 - //if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && (*name == '_')) - //name++; + debugLog ("%s:%d symbol name %s\n", __FUNCTION__, __LINE__, name); +// fprintf(stderr, "%s symbol name %s\n", __FUNCTION__,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(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))); + } - if (IS_CODE ( OP_SYM_ETYPE(op)) ) - return NULL; + + 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__); - /* 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); -/* - 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 = pic16_dirregWithName(name); - } + if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) ) + debugLog(" %d integral\n",__LINE__); - if(!reg) { - int address = 0; + if (IS_LITERAL ( OP_SYM_ETYPE(op)) ) + debugLog(" %d literal\n",__LINE__); - /* 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 (IS_SPEC ( OP_SYM_ETYPE(op)) ) + debugLog(" %d specifier\n",__LINE__); - /* 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); + debugAopGet(NULL, op); + } - 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); + if (IS_CODE ( OP_SYM_ETYPE(op)) ) + return NULL; - //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); + /* 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=NULL; +// reg = regWithIdx (pic16_dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1); - if (SPEC_ABSA ( 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))); +#endif + } else { +// fprintf(stderr,"ralloc:%d %s \n", __LINE__,name); + + reg = pic16_dirregWithName(name); + } - //fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name); - reg->type = REG_SFR; - } + if(!reg) { + int address = 0; + int regtype = REG_GPR; + + /* 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 (IS_BITVAR (OP_SYM_ETYPE(op))) { - addSet(&pic16_dynDirectBitRegs, reg); - reg->isBitField = 1; - } else - addSet(&pic16_dynDirectRegs, 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 */ + if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) { - } else { - debugLog (" -- %s is declared at address 0x30000x\n",name); +// if(pic16_debug_verbose) +// fprintf(stderr, "%s:%d symbol %s in codespace\n", __FILE__, __LINE__, +// OP_SYMBOL(op)->name); - } - } + debugLog("%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name); + return NULL; + } - 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(1) { //!PIC16_IS_CONFIG_ADDRESS(address)) { +// fprintf(stderr,"%s:allocating new reg %s\n",__FUNCTION__, name); + + /* this is an error, why added? -- VR */ +// if(SPEC_SCLS(OP_SYM_ETYPE(op)))regtype = REG_SFR; + + if(OP_SYMBOL(op)->onStack) { +// fprintf(stderr, "%s:%d onStack %s\n", __FILE__, __LINE__, OP_SYMBOL(op)->name); + OP_SYMBOL(op)->onStack = 0; + SPEC_OCLS(OP_SYM_ETYPE(op)) = data; + regtype = REG_GPR; + } + + if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) { // patch 13 + if(pic16_debug_verbose) // + { // + fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%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))); + + fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__, // + OP_SYMBOL(op)->name); // + } // +// return NULL; // + } // patch 13 + + 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); + +// hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* commented out */ + +// 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))) { +// 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); + checkAddReg(&pic16_dynDirectRegs, reg); + } + + } else { + debugLog (" -- %s is declared at address 0x30000x\n",name); +// fprintf(stderr, " -- %s is declared at address 0x30000x\n",name); + + return NULL; + } + } + + 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; } @@ -720,7 +732,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; @@ -738,12 +750,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 ); + 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 (" -- added %s to hash, size = %d\n", name,reg->size); + 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); - //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); + //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* initially commented out */ addSet(&pic16_dynDirectRegs, reg); } @@ -753,13 +766,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) { @@ -805,13 +818,13 @@ 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( (dReg = pic16_typeRegWithIdx(idx,REG_STK,0)) != NULL) return dReg; return NULL; @@ -827,6 +840,7 @@ 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) { @@ -835,6 +849,7 @@ pic16_allocWithIdx (int idx) debugLog ("Found a Stack Register!\n"); } else if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx,0)) != 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 ) { debugLog ("Found an Internal Register!\n"); } else { @@ -866,7 +881,7 @@ pic16_findFreeReg(short type) case REG_GPR: if((dReg = regFindFree(pic16_dynAllocRegs)) != NULL) return dReg; - return addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0)); + return allocReg( REG_GPR ); //addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL)); case REG_STK: @@ -888,8 +903,9 @@ pic16_findFreeReg(short type) static void freeReg (regs * reg) { - debugLog ("%s\n", __FUNCTION__); - reg->isFree = 1; + debugLog ("%s\n", __FUNCTION__); +// fprintf(stderr, "%s:%d register %s (%p) is freed\n", __FILE__, __LINE__, reg->name, reg); + reg->isFree = 1; } @@ -899,20 +915,27 @@ freeReg (regs * reg) static int nFreeRegs (int type) { + regs *reg; + int nfr=0; + + + /* although I fixed the register allocation/freeing scheme + * the for loop below doesn't give valid results. I do not + * know why yet. -- VR 10-Jan-2003 */ + + return 100; + + /* 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; - debugLog ("%s\n", __FUNCTION__); - for (i = 0; i < pic16_nRegs; i++) - if (regspic16[i].isFree && regspic16[i].type == type) - nfr++; + + for(reg = setFirstItem(pic16_dynAllocRegs); reg; reg=setNextItem(pic16_dynAllocRegs)) + if((reg->type == type) && reg->isFree)nfr++; + + fprintf(stderr, "%s:%d # of free registers= %d\n", __FILE__, __LINE__, nfr); return nfr; -#endif } /*-----------------------------------------------------------------*/ @@ -947,11 +970,14 @@ static void writeSetUsedRegs(FILE *of, set *dRegs) } #endif -extern void pic16_assignFixedRegisters(set *regset); -extern void pic16_assignRelocatableRegisters(set *regset,int used); -extern void pic16_dump_map(void); -extern void pic16_dump_cblock(FILE *of); +extern void pic16_groupRegistersInSection(set *regset); +extern void pic16_dump_equates(FILE *of, set *equs); +//extern void pic16_dump_map(void); +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); static void packBits(set *bregs) { @@ -974,14 +1000,14 @@ 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; if(!bitfield) { sprintf (buffer, "fbitfield%02x", breg->address); //fprintf(stderr,"new bit field\n"); - bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0); + bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0, NULL); bitfield->isBitField = 1; bitfield->isFixed = 1; bitfield->address = breg->address; @@ -1000,7 +1026,7 @@ static void packBits(set *bregs) 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 = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0, NULL); relocbitfield->isBitField = 1; addSet(&pic16_dynDirectRegs,relocbitfield); //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield); @@ -1017,6 +1043,7 @@ static void packBits(set *bregs) +#if 0 static void bitEQUs(FILE *of, set *bregs) { regs *breg,*bytereg; @@ -1072,30 +1099,52 @@ static void aliasEQUs(FILE *of, set *fregs, int use_rIdx) } } +#endif void pic16_writeUsedRegs(FILE *of) { - packBits(pic16_dynDirectBitRegs); - + packBits(pic16_dynDirectBitRegs); + + pic16_groupRegistersInSection(pic16_dynAllocRegs); + pic16_groupRegistersInSection(pic16_dynInternalRegs); + pic16_groupRegistersInSection(pic16_dynStackRegs); + pic16_groupRegistersInSection(pic16_dynDirectRegs); + pic16_groupRegistersInSection(pic16_dynDirectBitRegs); + pic16_groupRegistersInSection(pic16_dynProcessorRegs); + + +#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_assignFixedRegisters(pic16_dynAllocRegs); - pic16_assignFixedRegisters(pic16_dynStackRegs); - pic16_assignFixedRegisters(pic16_dynDirectRegs); +// pic16_dump_map(); +// pic16_dump_cblock(of); - pic16_assignRelocatableRegisters(pic16_dynInternalRegs,0); - pic16_assignRelocatableRegisters(pic16_dynAllocRegs,0); - pic16_assignRelocatableRegisters(pic16_dynStackRegs,0); - pic16_assignRelocatableRegisters(pic16_dynDirectRegs,0); + /* dump equates */ + pic16_dump_equates(of, pic16_equ_data); - //pic16_dump_map(); + /* dump initialised data */ + pic16_dump_isection(of, rel_idataSymSet, 0); + pic16_dump_isection(of, fix_idataSymSet, 1); - pic16_dump_cblock(of); - bitEQUs(of,pic16_dynDirectBitRegs); - aliasEQUs(of,pic16_dynAllocRegs,0); - aliasEQUs(of,pic16_dynDirectRegs,0); - aliasEQUs(of,pic16_dynStackRegs,0); - aliasEQUs(of,pic16_dynProcessorRegs,1); +// pic16_dump_idata(of, idataSymSet); + /* dump internal registers */ + pic16_dump_int_registers(of, pic16_int_regs); + + /* dump other variables */ + pic16_dump_usection(of, pic16_rel_udata, 0); + pic16_dump_usection(of, pic16_fix_udata, 1); + } #if 0 @@ -1296,7 +1345,7 @@ leastUsedLR (set * sset) } - setToNull ((void **) &sset); + setToNull ((void *) &sset); sym->blockSpil = 0; return sym; } @@ -1735,6 +1784,7 @@ static regs * getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym) { regs *reg; + int j; debugLog ("%s\n", __FUNCTION__); tryAgain: @@ -1750,6 +1800,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; @@ -1762,6 +1817,7 @@ static regs * getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym) { regs *reg; + int j; debugLog ("%s\n", __FUNCTION__); tryAgain: @@ -1777,6 +1833,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; @@ -2002,6 +2063,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 */ /*-----------------------------------------------------------------*/ @@ -2028,6 +2114,15 @@ serialRegAssign (eBBlock ** ebbs, int count) debugLog (" op: %s\n", 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 */ if (ic->op == IPOP) @@ -2171,6 +2266,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); + } + } + } /*-----------------------------------------------------------------*/ @@ -2427,6 +2556,7 @@ regTypeNum () sym = hTabNextItem (liveRanges, &k)) { debugLog (" %d - %s\n", __LINE__, sym->rname); + //fprintf(stderr," %d - %s\n", __LINE__, sym->rname); /* if used zero times then no registers needed */ if ((sym->liveTo - sym->liveFrom) == 0) @@ -2461,21 +2591,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; @@ -2493,9 +2623,14 @@ regTypeNum () getSize (sym->type)); +#if 0 if(IS_PTR_CONST (sym->type)) { - debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs); - sym->nRegs = 2; +#else + if(IS_CODEPTR (sym->type)) { +#endif + // 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) { @@ -2545,17 +2680,10 @@ DEFSETFUNC (pic16_deallocReg) void pic16_freeAllRegs () { - // int i; - debugLog ("%s\n", __FUNCTION__); applyToSet(pic16_dynAllocRegs,markRegFree); applyToSet(pic16_dynStackRegs,markRegFree); - -/* - for (i = 0; i < pic16_nRegs; i++) - regspic16[i].isFree = 1; -*/ } /*-----------------------------------------------------------------*/ @@ -2563,20 +2691,9 @@ pic16_freeAllRegs () void pic16_deallocateAllRegs () { - // int i; - debugLog ("%s\n", __FUNCTION__); applyToSet(pic16_dynAllocRegs,pic16_deallocReg); - -/* - for (i = 0; i < pic16_nRegs; i++) { - if(regspic16[i].pc_type == PO_GPR_TEMP) { - regspic16[i].isFree = 1; - regspic16[i].wasUsed = 0; - } - } -*/ } @@ -2670,23 +2787,33 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) iCode *dic, *sic; - debugLog ("%s\n", __FUNCTION__); - + debugLog ("%d\t%s\n", __LINE__, __FUNCTION__); + debugLog ("ic->op = %s\n", decodeOp( ic->op ) ); debugAopGet (" result:", IC_RESULT (ic)); debugAopGet (" left:", IC_LEFT (ic)); debugAopGet (" right:", IC_RIGHT (ic)); +// fprintf(stderr, "%s:%d symbol = %s\n", __FILE__, __LINE__, OP_SYMBOL( IC_RESULT(ic))->name); + +#if 0 /* 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))))) { + if(PIC16_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, "%s:%d setting config word to %x\n", __FILE__, __LINE__, + (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); @@ -2697,23 +2824,23 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) } } +#endif + debugLog(" %d - actuall processing\n", __LINE__ ); if (!IS_ITEMP (IC_RESULT (ic))) { pic16_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__); - pic16_allocDirReg(IC_LEFT (ic)); - } -*/ + +/* See BUGLOG0001 - VR */ +#if 1 if (!IS_ITEMP (IC_RIGHT (ic))) { debugLog (" %d - not packing - right is not temp\n", __LINE__); pic16_allocDirReg(IC_RIGHT (ic)); return 0; } +#endif if (OP_SYMBOL (IC_RIGHT (ic))->isind || OP_LIVETO (IC_RIGHT (ic)) > ic->seq) @@ -2732,6 +2859,7 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) return 0; } + /* 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 */ @@ -2749,9 +2877,12 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) break; } + if (SKIP_IC2 (dic)) continue; + debugLog("%d\tSearching for iTempNN\n", __LINE__); + if (IS_TRUE_SYMOP (IC_RESULT (dic)) && IS_OP_VOLATILE (IC_RESULT (dic))) { @@ -2760,6 +2891,16 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) break; } +#if 1 + if( IS_SYMOP( IC_RESULT(dic)) && + IS_BITFIELD( OP_SYMBOL(IC_RESULT(dic))->etype ) ) { + + debugLog (" %d - result is bitfield\n", __LINE__); + dic = NULL; + break; + } +#endif + if (IS_SYMOP (IC_RESULT (dic)) && IC_RESULT (dic)->key == IC_RIGHT (ic)->key) { @@ -2803,12 +2944,38 @@ 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) { +#if 0 + /* clear the onStack flag, the port doesn't support it yet! FIXME */ + if(OP_SYMBOL(IC_RESULT(ic))->onStack) + OP_SYMBOL(IC_RESULT(ic))->onStack = 0; +#endif + + /* the operation has only one symbol operator then we can pack */ if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) || @@ -2846,6 +3013,8 @@ pack: remiCodeFromeBBlock (ebp, ic); bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key); + + debugLog(" %d\n", __LINE__ ); hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL); OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key); return 1; @@ -2853,6 +3022,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 */ /*-----------------------------------------------------------------*/ @@ -2893,6 +3073,11 @@ findAssignToSym (operand * op, iCode * ic) OP_SYMBOL (IC_RIGHT (dic))->onStack) { +#if 0 + if(OP_SYMBOL(IC_RESULT(ic))->onStack) + OP_SYMBOL(IC_RESULT(ic))->onStack = 0; +#endif + 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) @@ -2930,7 +3115,10 @@ findAssignToSym (operand * op, iCode * ic) } +#endif + +#ifndef NO_packRegsForSupport /*-----------------------------------------------------------------*/ /* packRegsForSupport :- reduce some registers for support calls */ /*-----------------------------------------------------------------*/ @@ -3008,10 +3196,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 */ /*-----------------------------------------------------------------*/ @@ -3028,7 +3218,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; @@ -3141,6 +3331,8 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp) return sic; } +#endif + /*-----------------------------------------------------------------*/ /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */ @@ -3172,6 +3364,9 @@ isBitwiseOptimizable (iCode * ic) return FALSE; } + +#ifndef NO_packRegsForAccUse + /*-----------------------------------------------------------------*/ /* packRegsForAccUse - pack registers for acc use */ /*-----------------------------------------------------------------*/ @@ -3200,24 +3395,29 @@ packRegsForAccUse (iCode * ic) getSize (operandType (IC_RESULT (ic))) > 1)) return; + debugLog (" %s:%d\n", __FUNCTION__,__LINE__); if (ic->op == LEFT_OP && (isOperandLiteral (IC_RIGHT (ic)) || getSize (operandType (IC_RESULT (ic))) > 1)) return; + debugLog (" %s:%d\n", __FUNCTION__,__LINE__); if (IS_BITWISE_OP (ic) && getSize (operandType (IC_RESULT (ic))) > 1) return; + debugLog (" %s:%d\n", __FUNCTION__,__LINE__); /* has only one definition */ if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1) return; + debugLog (" %s:%d\n", __FUNCTION__,__LINE__); /* has only one use */ if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1) return; + debugLog (" %s:%d\n", __FUNCTION__,__LINE__); /* and the usage immediately follows this iCode */ if (!(uic = hTabItemWithKey (iCodehTab, bitVectFirstBit (OP_USES (IC_RESULT (ic)))))) @@ -3289,6 +3489,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))) || @@ -3298,6 +3499,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 */ @@ -3321,6 +3523,8 @@ accuse: } +#endif + /*-----------------------------------------------------------------*/ /* packForPush - hueristics to reduce iCode for pushing */ @@ -3394,10 +3598,11 @@ packForPush (iCode * ic, eBBlock * ebp) static void printSymType(char * str, sym_link *sl) { - debugLog (" %s Symbol type: ",str); - printTypeChain( sl, debugF); - debugLog ("\n"); - + if(!pic16_ralloc_debug)return; + + debugLog (" %s Symbol type: ",str); + printTypeChain( sl, debugF); + debugLog ("\n"); } /*-----------------------------------------------------------------*/ @@ -3409,42 +3614,43 @@ static 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)) { + if(!pic16_ralloc_debug)return; - 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(!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 */ -/*-----------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------*/ +/* pic16_packRegisters - does some transformations to reduce */ +/* register pressure */ +/* */ +/*--------------------------------------------------------------------*/ static void -packRegisters (eBBlock * ebp) +pic16_packRegisters (eBBlock * ebp) { iCode *ic; int change = 0; @@ -3461,9 +3667,11 @@ packRegisters (eBBlock * ebp) /* TrueSym := iTempNN:1 */ for (ic = ebp->sch; ic; ic = ic->next) { - +// debugLog("%d\n", __LINE__); /* find assignment of the form TrueSym := iTempNN:1 */ - if (ic->op == '=' && !POINTER_SET (ic)) + /* see BUGLOG0001 for workaround with the CAST - VR */ +// if ( (ic->op == '=' || ic->op == CAST) && !POINTER_SET (ic) ) // patch 11 + if ( (ic->op == '=') && !POINTER_SET (ic) ) // patch 11 change += packRegsForAssign (ic, ebp); /* debug stuff */ if (ic->op == '=') @@ -3486,16 +3694,28 @@ packRegisters (eBBlock * ebp) if(IS_SYMOP ( IC_LEFT(ic))) { sym_link *etype = getSpec (operandType (IC_LEFT (ic))); - debugAopGet (" left:", IC_LEFT (ic)); + debugAopGet ("x 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_PTR(OP_SYMBOL(IC_LEFT(ic))->type)) + debugLog (" is a ptr\n"); + if(IS_OP_VOLATILE(IC_LEFT(ic))) debugLog (" is volatile\n"); isData(etype); - printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type); + if(IS_OP_VOLATILE(IC_LEFT(ic))) { + debugLog (" %d - left is not temp, allocating\n", __LINE__); + pic16_allocDirReg(IC_LEFT (ic)); + } + + printSymType("c ", OP_SYMBOL(IC_LEFT(ic))->type); } if(IS_SYMOP ( IC_RIGHT(ic))) { @@ -3508,6 +3728,19 @@ packRegisters (eBBlock * ebp) printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type); } + 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__); @@ -3576,8 +3809,11 @@ packRegisters (eBBlock * ebp) debugAopGet (" left:", IC_LEFT (ic)); } + //debugLog(" %d %s\n", __LINE__, __FUNCTION__); + if (!SKIP_IC2 (ic)) { + //debugLog(" %d %s\n", __LINE__, __FUNCTION__ ); /* if we are using a symbol on the stack then we should say pic16_ptrRegReq */ if (ic->op == IFX && IS_SYMOP (IC_COND (ic))) @@ -3588,6 +3824,8 @@ packRegisters (eBBlock * ebp) OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0); else { + + //debugLog(" %d %s\n", __LINE__, __FUNCTION__ ); if (IS_SYMOP (IC_LEFT (ic))) pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack || OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0); @@ -3621,22 +3859,29 @@ packRegisters (eBBlock * ebp) continue; } + 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) && @@ -3646,7 +3891,9 @@ 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)) && @@ -3655,8 +3902,10 @@ packRegisters (eBBlock * ebp) getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1) 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 @@ -3677,6 +3926,7 @@ packRegisters (eBBlock * ebp) if (dic) { if (IS_ARITHMETIC_OP (dic)) { + debugLog(" %d %s\n", __LINE__, __FUNCTION__ ); bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key); IC_RESULT (dic) = IC_RESULT (ic); @@ -3698,7 +3948,9 @@ packRegisters (eBBlock * ebp) iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp); if (dic) { - + + debugLog(" %d\n", __LINE__); + bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key); IC_RESULT (dic) = IC_RESULT (ic); bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key); @@ -3710,7 +3962,7 @@ packRegisters (eBBlock * ebp) } } } - +#endif /* pack for PUSH iTempNN := (some variable in farspace) V1 push iTempNN ; @@ -3723,6 +3975,7 @@ packRegisters (eBBlock * ebp) } +#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 @@ -3739,9 +3992,10 @@ packRegisters (eBBlock * ebp) ) && IS_ITEMP (IC_RESULT (ic)) && - getSize (operandType (IC_RESULT (ic))) <= 2) + getSize (operandType (IC_RESULT (ic))) <= 1) packRegsForAccUse (ic); +#endif } } @@ -3751,7 +4005,7 @@ dumpEbbsToDebug (eBBlock ** ebbs, int count) { int i; - if (!debug || !debugF) + if (!pic16_ralloc_debug || !debugF) return; for (i = 0; i < count; i++) @@ -3809,7 +4063,7 @@ pic16_assignRegisters (eBBlock ** ebbs, int count) /* change assignments this will remove some live ranges reducing some register pressure */ for (i = 0; i < count; i++) - packRegisters (ebbs[i]); + pic16_packRegisters (ebbs[i]); { regs *reg; @@ -3821,11 +4075,16 @@ pic16_assignRegisters (eBBlock ** ebbs, int count) while(reg) { debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size); +// fprintf(stderr, " -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size); reg = hTabNextItem(dynDirectRegNames, &hkey); } } + /* liveranges probably changed by register packing + so we compute them again */ + recomputeLiveRanges (ebbs, count); + if (options.dump_pack) dumpEbbsToFileExt (DUMP_PACK, ebbs, count); @@ -3836,6 +4095,12 @@ pic16_assignRegisters (eBBlock ** ebbs, int count) /* and serially allocate registers */ serialRegAssign (ebbs, count); +// debugLog ("ebbs after serialRegAssign:\n"); +// dumpEbbsToDebug (ebbs, count); + + + //pic16_freeAllRegs(); + /* if stack was extended then tell the user */ if (_G.stackExtend) { @@ -3873,10 +4138,10 @@ pic16_assignRegisters (eBBlock ** ebbs, int count) /* free up any _G.stackSpil locations allocated */ applyToSet (_G.stackSpil, deallocStackSpil); _G.slocNum = 0; - setToNull ((void **) &_G.stackSpil); - setToNull ((void **) &_G.spiltSet); + setToNull ((void *) &_G.stackSpil); + setToNull ((void *) &_G.spiltSet); /* mark all registers as free */ - //pic16_freeAllRegs (); + pic16_freeAllRegs (); debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n"); debugLogClose ();