X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic%2Fralloc.c;h=d8b5d8df9a6a0f979f3301a8f847e06f1f39f690;hb=aa0ca082f440cf7b9cf126faf97e03fbbf0c0bc2;hp=4d4bd48fab901389da4869db29ecd62ec6a15064;hpb=73dcfcdb63f80c8d624e320f41ffb74b2b77e252;p=fw%2Fsdcc diff --git a/src/pic/ralloc.c b/src/pic/ralloc.c index 4d4bd48f..d8b5d8df 100644 --- a/src/pic/ralloc.c +++ b/src/pic/ralloc.c @@ -52,7 +52,7 @@ /*-----------------------------------------------------------------*/ extern void genpic14Code (iCode *); -extern void assignConfigWordValue(int address, int value); +extern void pic14_assignConfigWordValue(int address, int value); /* Global data */ static struct @@ -88,7 +88,8 @@ static int rDirectIdx=0; int pic14_nRegs = 128; // = sizeof (regspic14) / sizeof (regs); int Gstack_base_addr=0; /* The starting address of registers that -* are used to pass and return parameters */ + * are used to pass and return parameters */ +int Gstack_size = 0; @@ -133,8 +134,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 ? @@ -334,13 +336,28 @@ 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; + + /* check whether a matching register already exists */ + dReg = dirregWithName( name ); + if (dReg) { + //printf( "%s: already present: %s\n", __FUNCTION__, name ); + return (dReg); + } + dReg = regWithIdx( dynDirectRegs, rIdx, 0 ); + if (!dReg) dReg = regWithIdx( dynDirectRegs, rIdx, 1 ); + if (dReg) + { + //printf( "%s: already present %s (idx:%d/%x)", __FUNCTION__, name, rIdx, rIdx ); + return (dReg); + } dReg = Safe_calloc(1,sizeof(regs)); dReg->type = type; @@ -353,7 +370,7 @@ static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, i dReg->name = Safe_strdup(buffer); } dReg->isFree = 0; - dReg->wasUsed = 1; + dReg->wasUsed = 0; if (type == REG_SFR) dReg->isFixed = 1; else @@ -370,8 +387,14 @@ static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, i dReg->reglives.usedpFlows = newSet(); dReg->reglives.assignedpFlows = newSet(); - hTabAddItem(&dynDirectRegNames, regname2key(name), dReg); - + hTabAddItem(&dynDirectRegNames, regname2key(dReg->name), dReg); +#ifdef __GNUC__ + debugLog( "%s: Created register %s (%p).\n", + __FUNCTION__, dReg->name, __builtin_return_address(0) ); +#else + debugLog( "%s: Created register %s.\n", + __FUNCTION__, dReg->name); +#endif return dReg; } @@ -470,7 +493,7 @@ 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) { @@ -478,13 +501,18 @@ void initStack(int base_address, int size) int i; 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 r->isFixed = 1; - r->name[0] = 's'; + r->isPublic = 1; + //r->name[0] = 's'; r->alias = 0x180; // Using shared memory for pseudo stack addSet(&dynStackRegs,r); base_address--; @@ -505,7 +533,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); @@ -575,7 +603,7 @@ dirregWithName (char *name) int IS_CONFIG_ADDRESS(int address) { - return address == 0x2007; + return ((address == 0x2007) || (address == 0x2008)); } /*-----------------------------------------------------------------*/ @@ -586,10 +614,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); } @@ -602,7 +631,7 @@ 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; @@ -612,20 +641,20 @@ allocNewDirReg (sym_link *symlnk,const char *name) 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; } @@ -765,7 +794,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; @@ -796,7 +825,7 @@ 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); + //fprintf (stderr,"%s symbol name %s, size:%d\n", __FUNCTION__,name,size); reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0 ); for (sym = setFirstItem(sfr->syms); sym; sym = setNextItem(sfr->syms)) { if (strcmp(reg->name+1,sym->name)==0) { @@ -1184,6 +1213,7 @@ void writeUsedRegs(FILE *of) assignRelocatableRegisters(dynAllocRegs,0); assignRelocatableRegisters(dynStackRegs,0); + assignRelocatableRegisters(dynDirectRegs,0); /* assignRelocatableRegisters(dynDirectRegs,0); printf("assignRelocatableRegisters(dynDirectRegs,0);\n"); @@ -1942,14 +1972,36 @@ deassignLRs (iCode * ic, eBBlock * ebp) /* if it does not end here */ if (sym->liveTo > ic->seq) continue; - - /* HACK: result and addr must be disjoint for POINTER_GET */ - if (sym->liveTo == ic->seq && POINTER_GET(ic)) + + /* 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)) { - //piCode (ic, stderr); fprintf (stderr, " -- registers NOT deallocated\n"); - continue; + 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) @@ -2695,7 +2747,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; @@ -2909,7 +2961,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)); } @@ -3032,6 +3084,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 || @@ -3407,10 +3472,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; @@ -3547,8 +3624,7 @@ packRegsForAccUse (iCode * ic) accuse: debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__); OP_SYMBOL (IC_RESULT (ic))->accuse = 1; - - +#endif } /*-----------------------------------------------------------------*/ @@ -3691,7 +3767,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); @@ -4071,8 +4147,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);