X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic%2Fralloc.c;h=d51dca63908cc3bbd70662d61bd533b44c9ae55c;hb=3062f96ccb55d1d05caf9c8782f4961f87b341ce;hp=dad9f52261ad1bb01cd72b4c225b2b0309378212;hpb=25837611386183e136d41617166c3a81b52ce430;p=fw%2Fsdcc diff --git a/src/pic/ralloc.c b/src/pic/ralloc.c index dad9f522..d51dca63 100644 --- a/src/pic/ralloc.c +++ b/src/pic/ralloc.c @@ -5,39 +5,33 @@ Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998) Added Pic Port T.scott Dattalo scott@dattalo.com (2000) - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - In other words, you are welcome to use, share and improve this program. - You are forbidden to forbid anyone else to use, share and improve - what you give them. Help stamp out software-hoarding! + In other words, you are welcome to use, share and improve this program. + You are forbidden to forbid anyone else to use, share and improve + what you give them. Help stamp out software-hoarding! -------------------------------------------------------------------------*/ #include "common.h" #include "ralloc.h" +#include "device.h" #include "pcode.h" #include "gen.h" -#if defined(__BORLANDC__) || defined(_MSC_VER) -#define STRCASECMP stricmp #define FENTRY2 1 ? (void)0 : printf -#else -#define STRCASECMP strcasecmp -//#define FENTRY2(fmt,...) do { fprintf (stderr, "%s:%d: called.\n", __FUNCTION__, __LINE__); fprintf (stderr, fmt, ## __VA_ARGS__); } while (0) -#define FENTRY2 1 ? (void)0 : printf -#endif /* this should go in SDCCicode.h, but it doesn't. */ #define IS_REF(op) (IS_SYMOP(op) && op->operand.symOperand->isref == 1) @@ -52,7 +46,7 @@ /*-----------------------------------------------------------------*/ extern void genpic14Code (iCode *); -extern void assignConfigWordValue(int address, int value); +extern void pic14_assignConfigWordValue(int address, int value); /* Global data */ static struct @@ -82,13 +76,13 @@ set *dynInternalRegs=NULL; static hTab *dynDirectRegNames= NULL; // static hTab *regHash = NULL; /* a hash table containing ALL registers */ -static int dynrIdx=0x20; -static int rDirectIdx=0; +static int dynrIdx = 0x1000; int pic14_nRegs = 128; // = sizeof (regspic14) / sizeof (regs); int Gstack_base_addr=0; /* The starting address of registers that -* are used to pass and return parameters */ + * are used to pass and return parameters */ +int Gstack_size = 0; @@ -133,8 +127,9 @@ static void vsprintf (buffer, fmt, ap); fprintf (debugF, "%s", buffer); + //if (options.verbose) fprintf (stderr, "%s: %s", __FUNCTION__, buffer); /* - while (isspace(*bufferP)) bufferP++; + while (isspace((unsigned char)*bufferP)) bufferP++; if (bufferP && *bufferP) lineCurr = (lineCurr ? @@ -170,7 +165,7 @@ static void static char * debugAopGet (char *str, operand * op) { - if (str) + if (str) debugLog (str); printOperand (op, debugF); @@ -193,208 +188,106 @@ static char * 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"; + 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 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, "unknown op %d %c", op, op & 0xff); return buffer; @@ -407,12 +300,9 @@ debugLogRegType (short type) switch (type) { - case REG_GPR: - return "REG_GPR"; - case REG_PTR: - return "REG_PTR"; - case REG_CND: - return "REG_CND"; + 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); @@ -438,14 +328,27 @@ static int regname2key(char const *name) } +static regs *regWithIdx (set *dRegs, int idx, int fixed); /*-----------------------------------------------------------------*/ /* 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) +static regs* newReg(short type, PIC_OPTYPE pc_type, int rIdx, char *name, int size, int alias) { - regs *dReg; + regs *dReg, *reg_alias; + + /* check whether a matching register already exists */ + dReg = dirregWithName( name ); + if (dReg) { + //printf( "%s: already present: %s\n", __FUNCTION__, name ); + return (dReg); + } + // check whether a register at that location exists + reg_alias = regWithIdx( dynDirectRegs, rIdx, 0 ); + if (!reg_alias) reg_alias = regWithIdx( dynDirectRegs, rIdx, 1 ); + + // create a new register dReg = Safe_calloc(1,sizeof(regs)); dReg->type = type; dReg->pc_type = pc_type; @@ -456,9 +359,8 @@ static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, i sprintf(buffer,"r0x%02X", dReg->rIdx); dReg->name = Safe_strdup(buffer); } - //fprintf(stderr,"newReg: %s, rIdx = 0x%02x\n",dReg->name,rIdx); dReg->isFree = 0; - dReg->wasUsed = 1; + dReg->wasUsed = 0; if (type == REG_SFR) dReg->isFixed = 1; else @@ -471,11 +373,11 @@ static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, i dReg->address = 0; dReg->size = size; dReg->alias = alias; - dReg->reg_alias = NULL; + dReg->reg_alias = reg_alias; dReg->reglives.usedpFlows = newSet(); dReg->reglives.assignedpFlows = newSet(); - - hTabAddItem(&dynDirectRegNames, regname2key(name), dReg); + if (type != REG_STK) hTabAddItem(&dynDirectRegNames, regname2key(dReg->name), dReg); + debugLog( "%s: Created register %s.\n", __FUNCTION__, dReg->name); return dReg; } @@ -492,6 +394,7 @@ regWithIdx (set *dRegs, int idx, int fixed) dReg = setNextItem(dRegs)) { if(idx == dReg->rIdx && (fixed == (int)dReg->isFixed)) { + while (dReg->reg_alias) dReg = dReg->reg_alias; return dReg; } } @@ -575,24 +478,30 @@ regFindFree (set *dRegs) return NULL; } /*-----------------------------------------------------------------*/ -/* initStack - allocate registers for a psuedo stack */ +/* initStack - allocate registers for a pseudo stack */ /*-----------------------------------------------------------------*/ -void initStack(int base_address, int size) +void initStack(int base_address, int size, int shared) { int i; - + PIC_device *pic; + + pic = pic14_getPIC(); Gstack_base_addr = base_address; - //fprintf(stderr,"initStack"); + Gstack_size = size; + //fprintf(stderr,"initStack [base:0x%02x, size:%d]\n", base_address, size); for(i = 0; iaddress = base_address; // Pseudo stack needs a fixed location that can be known by all modules + char buffer[16]; + regs *r; + SNPRINTF(&buffer[0], 16, "STK%02d", i); + // multi-bank device, sharebank prohibited by user + r = newReg(REG_STK, PO_GPR_TEMP, base_address--, buffer, 1, shared ? (pic ? pic->bankMask : 0x180) : 0x0); r->isFixed = 1; - r->name[0] = 's'; - r->alias = 0x180; // Using shared memory for pseudo stack + r->isPublic = 1; + r->isEmitted = 1; + //r->name[0] = 's'; addSet(&dynStackRegs,r); - base_address--; } } @@ -610,7 +519,7 @@ allocProcessorRegister(int rIdx, char * name, short po_type, int alias) *-----------------------------------------------------------------*/ regs * -allocInternalRegister(int rIdx, char * name, short po_type, int alias) +allocInternalRegister(int rIdx, char * name, PIC_OPTYPE po_type, int alias) { regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias); @@ -628,12 +537,20 @@ allocInternalRegister(int rIdx, char * name, short po_type, int alias) static regs * allocReg (short type) { + regs *reg; debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type)); //fprintf(stderr,"allocReg\n"); + reg = pic14_findFreeReg (type); + + reg->isFree = 0; + reg->wasUsed = 1; + + return reg; + - return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0)); + //return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0)); } @@ -659,6 +576,8 @@ dirregWithName (char *name) while(reg) { if(STRCASECMP(reg->name, name) == 0) { + // handle registers with multiple names + while (reg->reg_alias) reg = reg->reg_alias; return(reg); } @@ -672,7 +591,7 @@ dirregWithName (char *name) int IS_CONFIG_ADDRESS(int address) { - return address == 0x2007; + return ((address == 0x2007) || (address == 0x2008)); } /*-----------------------------------------------------------------*/ @@ -683,10 +602,11 @@ allocNewDirReg (sym_link *symlnk,const char *name) { regs *reg; int address = 0; + sym_link *spec = getSpec (symlnk); /* if this is at an absolute address, then get the address. */ - if (SPEC_ABSA (symlnk) ) { - address = SPEC_ADDR (symlnk); + if (SPEC_ABSA (spec) ) { + address = SPEC_ADDR (spec); //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address); } @@ -699,30 +619,30 @@ allocNewDirReg (sym_link *symlnk,const char *name) } else { int idx; if (address) { - if (IS_BITVAR (symlnk)) + if (IS_BITVAR (spec)) idx = address >> 3; else idx = address; } else { - idx = rDirectIdx++; + idx = dynrIdx++; } reg = newReg(REG_GPR, PO_DIR, idx, (char*)name,getSize (symlnk),0 ); debugLog (" -- added %s to hash, size = %d\n", (char*)name,reg->size); - if (SPEC_ABSA (symlnk) ) { + if (SPEC_ABSA (spec) ) { reg->type = REG_SFR; } - if (IS_BITVAR (symlnk)) { + if (IS_BITVAR (spec)) { addSet(&dynDirectBitRegs, reg); reg->isBitField = 1; } else addSet(&dynDirectRegs, reg); - if (!IS_STATIC (symlnk)) { + if (!IS_STATIC (spec)) { reg->isPublic = 1; } - if (IS_EXTERN (symlnk)) { + if (IS_EXTERN (spec)) { reg->isExtern = 1; } @@ -817,7 +737,7 @@ allocDirReg (operand *op ) if(!IS_CONFIG_ADDRESS(address)) { //fprintf(stderr,"allocating new reg %s\n",name); - reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0 ); + reg = newReg(REG_GPR, PO_DIR, dynrIdx++, name,getSize (OP_SYMBOL (op)->type),0 ); debugLog (" -- added %s to hash, size = %d\n", name,reg->size); //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); @@ -862,7 +782,7 @@ allocDirReg (operand *op ) debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address); } } else { - allocNewDirReg (OP_SYM_ETYPE(op),name); + allocNewDirReg (OP_SYM_TYPE(op),name); } return reg; @@ -893,8 +813,8 @@ 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 symbol name %s, size:%d\n", __FUNCTION__,name,size); + reg = newReg(REG_GPR, PO_DIR, dynrIdx++, name,size,0 ); for (sym = setFirstItem(sfr->syms); sym; sym = setNextItem(sfr->syms)) { if (strcmp(reg->name+1,sym->name)==0) { unsigned a = SPEC_ADDR(sym->etype); @@ -970,14 +890,18 @@ typeRegWithIdx (int idx, int type, int fixed) break; case REG_STK: - if( (dReg = regWithIdx ( dynStackRegs, idx, fixed)) != NULL ) { + if( (dReg = regWithIdx ( dynStackRegs, idx, 0)) != NULL ) { + debugLog ("Found a Stack Register!\n"); + return dReg; + } else + if( (dReg = regWithIdx ( dynStackRegs, idx, 1)) != NULL ) { debugLog ("Found a Stack Register!\n"); return dReg; } else { werror (E_STACK_OUT, "Register"); /* return an existing register just to avoid the SDCC crash */ - return regWithIdx ( dynStackRegs, 0x7f, fixed); + return regWithIdx ( dynStackRegs, 0x7f, 0); } break; case REG_SFR: @@ -1143,10 +1067,7 @@ void writeSetUsedRegs(FILE *of, set *dRegs) } } -extern void assignFixedRegisters(set *regset); -extern void assignRelocatableRegisters(set *regset,int used); extern void dump_map(void); -extern void dump_sfr(FILE *of); void packBits(set *bregs) { @@ -1197,7 +1118,7 @@ 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,dynrIdx++,buffer,1,0); relocbitfield->isBitField = 1; //addSet(&dynDirectRegs,relocbitfield); addSet(&dynInternalRegs,relocbitfield); @@ -1206,7 +1127,7 @@ void packBits(set *bregs) } breg->reg_alias = relocbitfield; - breg->address = rDirectIdx; /* byte_no; */ + breg->address = dynrIdx; /* byte_no; */ breg->rIdx = bit_no++; } } @@ -1245,6 +1166,7 @@ void bitEQUs(FILE *of, set *bregs) } } + void aliasEQUs(FILE *of, set *fregs, int use_rIdx) { regs *reg; @@ -1270,62 +1192,14 @@ void aliasEQUs(FILE *of, set *fregs, int use_rIdx) void writeUsedRegs(FILE *of) { - packBits(dynDirectBitRegs); - assignFixedRegisters(dynInternalRegs); - assignFixedRegisters(dynAllocRegs); - assignFixedRegisters(dynStackRegs); - assignFixedRegisters(dynDirectRegs); - - assignRelocatableRegisters(dynInternalRegs,0); - assignRelocatableRegisters(dynAllocRegs,0); - assignRelocatableRegisters(dynStackRegs,0); + packBits(dynDirectBitRegs); - /* - assignRelocatableRegisters(dynDirectRegs,0); - printf("assignRelocatableRegisters(dynDirectRegs,0);\n"); - */ //dump_map(); - dump_sfr(of); bitEQUs(of,dynDirectBitRegs); - /* - aliasEQUs(of,dynAllocRegs,0); - aliasEQUs(of,dynDirectRegs,0); - aliasEQUs(of,dynStackRegs,0); - aliasEQUs(of,dynProcessorRegs,1); - */ } -#if 0 -/*-----------------------------------------------------------------*/ -/* allDefsOutOfRange - all definitions are out of a range */ -/*-----------------------------------------------------------------*/ -static bool -allDefsOutOfRange (bitVect * defs, int fseq, int toseq) -{ - int i; - - 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)) - - return FALSE; - - } - - return TRUE; -} -#endif - /*-----------------------------------------------------------------*/ /* computeSpillable - given a point find the spillable live ranges */ /*-----------------------------------------------------------------*/ @@ -1998,7 +1872,7 @@ tryAgain: if (sym->regs[j]) sym->regs[j]->isFree = 0; - /* this looks like an infinite loop but + /* this looks like an infinite loop but in really selectSpil will abort */ goto tryAgain; } @@ -2039,7 +1913,36 @@ deassignLRs (iCode * ic, eBBlock * ebp) /* if it does not end here */ if (sym->liveTo > ic->seq) continue; - + + /* Prevent the result from being assigned the same registers as (one) + * operand as many genXXX-functions fail otherwise. + * POINTER_GET(ic) || ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == NOT + * are known to fail. */ + if (sym->liveTo == ic->seq && IC_RESULT(ic)) + { + switch (ic->op) + { + case '=': /* assignment */ + case BITWISEAND: /* bitwise AND */ + case '|': /* bitwise OR */ + case '^': /* bitwise XOR */ + case '~': /* bitwise negate */ + case RLC: /* rotate through carry */ + case RRC: + case UNARYMINUS: + case '+': /* addition */ + case '-': /* subtraction */ + /* go ahead, these are safe to use with + * non-disjoint register sets */ + break; + + default: + /* do not release operand registers */ + //fprintf (stderr, "%s:%u: operand not freed: ", __FILE__, __LINE__); piCode (ic, stderr); fprintf (stderr, "\n"); + continue; + } // switch + } + /* if it was spilt on stack then we can mark the stack spil location as free */ if (sym->isspilt) @@ -2054,7 +1957,6 @@ deassignLRs (iCode * ic, eBBlock * ebp) if (!bitVectBitValue (_G.regAssigned, sym->key)) 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 @@ -2062,6 +1964,7 @@ deassignLRs (iCode * ic, eBBlock * ebp) if (ic->op == IFX && ic->prev && ic->prev->op == IPOP && !ic->prev->parmPush && + IS_SYMOP(IC_LEFT (ic->prev)) && !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt) psym = OP_SYMBOL (IC_LEFT (ic->prev)); @@ -2082,6 +1985,7 @@ deassignLRs (iCode * ic, eBBlock * ebp) ic->op == IPOP || ic->op == RETURN || POINTER_SET (ic)) && + IS_SYMOP (IC_RESULT (ic)) && (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 */ @@ -2108,7 +2012,7 @@ deassignLRs (iCode * ic, eBBlock * ebp) _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key); } - + /* free the remaining */ for (; i < sym->nRegs; i++) { @@ -2273,7 +2177,6 @@ serialRegAssign (eBBlock ** ebbs, int count) /* of all instructions do */ for (ic = ebbs[i]->sch; ic; ic = ic->next) { - debugLog (" op: %s\n", decodeOp (ic->op)); /* if this is an ipop that means some live @@ -2301,7 +2204,7 @@ serialRegAssign (eBBlock ** ebbs, int count) /* now we need to allocate registers only for the result */ - if (IC_RESULT (ic)) + if (IC_RESULT (ic) && IS_SYMOP (IC_RESULT (ic))) { symbol *sym = OP_SYMBOL (IC_RESULT (ic)); bitVect *spillable; @@ -2387,8 +2290,10 @@ serialRegAssign (eBBlock ** ebbs, int count) /* if we need ptr regs for the right side then mark it */ - if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type) - <= (unsigned) PTRSIZE) + if (POINTER_GET (ic) + && IS_SYMOP(IC_LEFT(ic)) + && getSize (OP_SYMBOL (IC_LEFT (ic))->type) + <= (unsigned) PTRSIZE) { pic14_ptrRegReq++; ptrRegSet = 1; @@ -2416,11 +2321,13 @@ serialRegAssign (eBBlock ** ebbs, int count) /* if it shares registers with operands make sure that they are in the same position */ if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) && + IS_SYMOP(IC_RESULT(ic)) && OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=') positionRegs (OP_SYMBOL (IC_RESULT (ic)), OP_SYMBOL (IC_LEFT (ic)), ic->lineno); /* do the same for the right operand */ if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) && + IS_SYMOP(IC_RESULT(ic)) && OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=') positionRegs (OP_SYMBOL (IC_RESULT (ic)), OP_SYMBOL (IC_RIGHT (ic)), ic->lineno); @@ -2781,7 +2688,7 @@ regTypeNum () debugLog (" %d - \n", __LINE__); - /* create a psuedo symbol & force a spil */ + /* create a pseudo symbol & force a spil */ //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1); psym = rematStr (OP_SYMBOL (IC_LEFT (ic))); psym->type = sym->type; @@ -2995,7 +2902,7 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) if(IS_VALOP(IC_RIGHT(ic))) { debugLog (" setting config word to %x\n", (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand)); - assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))), + pic14_assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))), (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand)); } @@ -3118,6 +3025,19 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) if (!dic) return 0; /* did not find */ + /* if assignment then check that right is not a bit */ + if (ASSIGNMENT (ic) && !POINTER_SET (ic)) + { + sym_link *etype = operandType (IC_RESULT (dic)); + if (IS_BITFIELD (etype)) + { + /* if result is a bit too then it's ok */ + etype = operandType (IC_RESULT (ic)); + if (!IS_BITFIELD (etype)) + return 0; + } + } + /* if the result is on stack or iaccess then it must be the same at least one of the operands */ if (OP_SYMBOL (IC_RESULT (ic))->onStack || @@ -3493,10 +3413,22 @@ isBitwiseOptimizable (iCode * ic) static void packRegsForAccUse (iCode * ic) { - iCode *uic; + //iCode *uic; debugLog ("%s\n", __FUNCTION__); + + /* result too large for WREG? */ + if (getSize (operandType (IC_RESULT (ic))) > 1) + return; + /* We have to make sure that OP_SYMBOL(IC_RESULT(ic)) + * is never used as an operand to an instruction that + * cannot have WREG as an operand (e.g. BTFSx cannot + * operate on WREG... + * For now, store all results into proper registers. */ + return; + +#if 0 /* if this is an aggregate, e.g. a one byte char array */ if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) { return; @@ -3633,8 +3565,7 @@ packRegsForAccUse (iCode * ic) accuse: debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__); OP_SYMBOL (IC_RESULT (ic))->accuse = 1; - - +#endif } /*-----------------------------------------------------------------*/ @@ -3777,7 +3708,7 @@ packRegisters (eBBlock * ebp) /* TrueSym := iTempNN:1 */ for (ic = ebp->sch; ic; ic = ic->next) { - + /* find assignment of the form TrueSym := iTempNN:1 */ if (ic->op == '=' && !POINTER_SET (ic)) change += packRegsForAssign (ic, ebp); @@ -3918,13 +3849,13 @@ packRegisters (eBBlock * ebp) } /* mark the pointer usages */ - if (POINTER_SET (ic)) + if (POINTER_SET (ic) && IS_SYMOP(IC_RESULT(ic))) { OP_SYMBOL (IC_RESULT (ic))->uptr = 1; debugLog (" marking as a pointer (set) =>"); debugAopGet (" result:", IC_RESULT (ic)); } - if (POINTER_GET (ic)) + if (POINTER_GET (ic) && IS_SYMOP(IC_LEFT(ic))) { OP_SYMBOL (IC_LEFT (ic))->uptr = 1; debugLog (" marking as a pointer (get) =>"); @@ -3996,6 +3927,7 @@ packRegisters (eBBlock * ebp) one and right is not in far space */ if (POINTER_SET (ic) && !isOperandInFarSpace (IC_RIGHT (ic)) && + IS_SYMOP(IC_RESULT(ic)) && !OP_SYMBOL (IC_RESULT (ic))->remat && !IS_OP_RUONLY (IC_RIGHT (ic)) && getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1) @@ -4005,6 +3937,7 @@ packRegisters (eBBlock * ebp) /* if pointer get */ if (POINTER_GET (ic) && !isOperandInFarSpace (IC_RESULT (ic)) && + IS_SYMOP(IC_LEFT(ic)) && !OP_SYMBOL (IC_LEFT (ic))->remat && !IS_OP_RUONLY (IC_RESULT (ic)) && getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1) @@ -4155,8 +4088,8 @@ pic14_assignRegisters (ebbIndex * ebbi) iCode *ic; int i; - debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__); - debugLog ("\nebbs before optimizing:\n"); + debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s\n", __FILE__, __FUNCTION__); + debugLog ("ebbs before optimizing:\n"); dumpEbbsToDebug (ebbs, count); setToNull ((void *) &_G.funcrUsed);