#define STRCASECMP strcasecmp
#endif
+#ifndef debugf
+#define debugf(frm, rest) _debugf(__FILE__, __LINE__, frm, rest)
+#endif
+void _debugf(char *f, int l, char *frm, ...);
+
+#define NEWREG_DEBUG 0
//#define USE_ONSTACK
set *pic16_dynDirectRegs=NULL;
set *pic16_dynDirectBitRegs=NULL;
set *pic16_dynInternalRegs=NULL;
+set *pic16_dynAccessRegs=NULL;
-static hTab *dynDirectRegNames= NULL;
+static hTab *dynDirectRegNames=NULL;
+static hTab *dynAllocRegNames=NULL;
+static hTab *dynProcRegNames=NULL;
+static hTab *dynAccessRegNames=NULL;
//static hTab *regHash = NULL; /* a hash table containing ALL registers */
extern set *sectNames;
set *pic16_fix_udata=NULL; /* absolute uninitialized registers */
set *pic16_equ_data=NULL; /* registers used by equates */
set *pic16_int_regs=NULL; /* internal registers placed in access bank 0 to 0x7f */
+set *pic16_acs_udata=NULL; /* access bank variables */
set *pic16_builtin_functions=NULL;
* are used to pass and return parameters */
-
+int _inRegAllocator=0; /* flag that marks whther allocReg happens while
+ * inside the register allocator function */
+
static void spillThis (symbol *);
int pic16_ralloc_debug = 0;
return NULL;
}
-static char *
-decodeOp (unsigned int op)
+char *
+pic16_decodeOp (unsigned int op)
{
if (op < 128 && op > ' ') {
buffer[0] = (op & 0xff);
dReg->accessBank = 0;
}
-// fprintf(stderr,"newReg: %s, rIdx = 0x%02x\taccess= %d\tregop= %p\n",dReg->name,rIdx, dReg->accessBank, refop);
-
+#if NEWREG_DEBUG
+ fprintf(stderr,"newReg: %s, rIdx = 0x%02x\taccess= %d\tregop= %p\n",dReg->name,rIdx, dReg->accessBank, refop);
+#endif
dReg->size = size;
dReg->alias = alias;
dReg->reg_alias = NULL;
/* regWithIdx - Search through a set of registers that matches idx */
/*-----------------------------------------------------------------*/
static regs *
-regWithIdx (set *dRegs, int idx, int fixed)
+regWithIdx (set *dRegs, int idx, unsigned fixed)
{
regs *dReg;
reg->wasUsed = 0; // we do not know if they are going to be used at all
reg->accessBank = 1; // implicit add access Bank
+ hTabAddItem(&dynProcRegNames, regname2key(reg->name), reg);
+
return addSet(&pic16_dynProcessorRegs, reg);
}
return NULL;
}
+
+
/*-----------------------------------------------------------------*/
/* allocReg - allocates register of given type */
/*-----------------------------------------------------------------*/
{
regs * reg=NULL;
+#define MAX_P16_NREGS 6
+
+
#if 0
if(dynrIdx > pic16_nRegs)
return NULL;
reg = regFindFree( pic16_dynAllocRegs );
if(reg) {
-// fprintf(stderr, "%s: found FREE register %s\n", __FILE__, reg->name);
+// fprintf(stderr, "%s: [%s] found FREE register %s, rIdx: %d\n", __FILE__, (_inRegAllocator)?"ralloc":"", reg->name, reg->rIdx);
}
if(!reg) {
reg = newReg(REG_GPR, PO_GPR_TEMP, dynrIdx++, NULL, 1, 0, NULL);
+// fprintf(stderr, "%s: [%s] allocating NEW register %s, rIdx: %d\n", __FILE__, (_inRegAllocator)?"ralloc":"", reg->name, reg->rIdx);
+
+#if 1
+ if(_inRegAllocator && (dynrIdx > MAX_P16_NREGS)) {
+// debugf("allocating more registers than available\n", 0);
+// return (NULL);
+ }
+#endif
+
// addSet(&pic16_dynAllocRegs, reg);
}
addSet(&pic16_dynAllocRegs, reg);
+ hTabAddItem(&dynAllocRegNames, regname2key(reg->name), reg);
reg->isFree=0;
- debugLog ("%s of type %s for register rIdx: %d\n", __FUNCTION__, debugLogRegType (type), dynrIdx-1);
-
-// 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);
+ debugLog ("%s of type %s for register rIdx: %d (0x%x)\n", __FUNCTION__, debugLogRegType (type), dynrIdx-1, dynrIdx-1);
+#if 0
+ fprintf(stderr,"%s:%d: %s\t%s addr= 0x%x\trIdx= 0x%02x isFree: %d\n",
+ __FILE__, __LINE__, __FUNCTION__, reg->name, reg->address, reg->rIdx, reg->isFree);
+#endif
if(reg) {
reg->accessBank = 1; /* this is a temporary register alloc in accessBank */
reg->isLocal = 1; /* this is a local frame register */
while(reg) {
if(STRCASECMP(reg->name, name) == 0) {
+// fprintf(stderr, "%s:%d: FOUND name = %s\thash = %d\n", __FUNCTION__, __LINE__, reg->name, hkey);
return(reg);
}
return NULL; // name wasn't found in the hash table
}
+/*-----------------------------------------------------------------*/
+/* pic16_allocregWithName - search for register by name */
+/*-----------------------------------------------------------------*/
+regs *
+pic16_allocregWithName (char *name)
+{
+ int hkey;
+ regs *reg;
+
+ if(!name)
+ return NULL;
+
+ /* hash the name to get a key */
+
+ hkey = regname2key(name);
+
+// fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
+
+ reg = hTabFirstItemWK(dynAllocRegNames, hkey);
+
+ while(reg) {
+
+ if(STRCASECMP(reg->name, name) == 0) {
+ return(reg);
+ }
+
+ reg = hTabNextItemWK (dynAllocRegNames);
+
+ }
+
+ return NULL; // name wasn't found in the hash table
+
+}
+
+
+/*-----------------------------------------------------------------*/
+/* pic16_procregWithName - search for register by name */
+/*-----------------------------------------------------------------*/
+regs *
+pic16_procregWithName (char *name)
+{
+ int hkey;
+ regs *reg;
+
+ if(!name)
+ return NULL;
+
+ /* hash the name to get a key */
+
+ hkey = regname2key(name);
+
+// fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
+
+ reg = hTabFirstItemWK(dynProcRegNames, hkey);
+
+ while(reg) {
+
+ if(STRCASECMP(reg->name, name) == 0) {
+ return(reg);
+ }
+
+ reg = hTabNextItemWK (dynProcRegNames);
+
+ }
+
+ return NULL; // name wasn't found in the hash table
+
+}
+
+/*-----------------------------------------------------------------*/
+/* pic16_accessregWithName - search for register by name */
+/*-----------------------------------------------------------------*/
+regs *
+pic16_accessregWithName (char *name)
+{
+ int hkey;
+ regs *reg;
+
+ if(!name)
+ return NULL;
+
+ /* hash the name to get a key */
+
+ hkey = regname2key(name);
+
+// fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
+
+ reg = hTabFirstItemWK(dynAccessRegNames, hkey);
+
+ while(reg) {
+
+ if(STRCASECMP(reg->name, name) == 0) {
+ return(reg);
+ }
+
+ reg = hTabNextItemWK (dynAccessRegNames);
+
+ }
+
+ return NULL; // name wasn't found in the hash table
+
+}
+
+regs *pic16_regWithName(char *name)
+{
+ regs *reg;
+
+ reg = pic16_dirregWithName( name );
+ if(reg)return reg;
+
+ reg = pic16_procregWithName( name );
+ if(reg)return reg;
+
+ reg = pic16_allocregWithName( name );
+ if(reg)return reg;
+
+ reg = pic16_accessregWithName( name );
+ if(reg)return reg;
+
+ return NULL;
+}
+
/*-----------------------------------------------------------------*/
/* pic16_allocDirReg - allocates register of given type */
name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
+
if(!SPEC_OCLS( OP_SYM_ETYPE(op))) {
+#if 1
if(pic16_debug_verbose)
{
fprintf(stderr, "%s:%d symbol %s(r:%s) is not assigned to a memmap\n", __FILE__, __LINE__,
OP_SYMBOL(op)->name, OP_SYMBOL(op)->rname);
}
+#endif
+ return NULL;
+ }
+
+ if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
+ || !IN_FARSPACE(SPEC_OCLS( OP_SYM_ETYPE(op))) ) {
+
+#if 0
+ if(pic16_debug_verbose) {
+ fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d eeprom: %d regparm: %d isparm: %d\n",
+ IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
+ IN_FARSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
+ IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
+ IN_REGSP( SPEC_OCLS( OP_SYM_ETYPE(op))),
+ IN_STACK( OP_SYM_ETYPE(op)),
+ SPEC_OCLS(OP_SYM_ETYPE(op)) == eeprom,
+ IS_REGPARM(OP_SYM_ETYPE(op)),
+ IS_PARM(op));
+
+ fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__,
+ OP_SYMBOL(op)->name);
+ }
+#endif
+
+ }
+
+
+
+ if (IS_CODE ( OP_SYM_ETYPE(op)) ) {
+// fprintf(stderr, "%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
return NULL;
}
+ if(IS_ITEMP(op))return NULL;
+
+// if(IS_STATIC(OP_SYM_ETYPE(op)))return NULL;
+
+ if(IN_STACK(OP_SYM_ETYPE(op)))return NULL;
+
debugLog ("%s:%d symbol name %s\n", __FUNCTION__, __LINE__, name);
-// fprintf(stderr, "%s symbol name %s\n", __FUNCTION__,name);
+// fprintf(stderr, "%s symbol name %s\tSTATIC:%d\n", __FUNCTION__,name, IS_STATIC(OP_SYM_ETYPE(op)));
{
if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
debugAopGet(NULL, op);
}
- if (IS_CODE ( OP_SYM_ETYPE(op)) )
- return NULL;
-
- /* First, search the hash table to see if there is a register with this name */
- if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && !(IS_BITVAR (OP_SYM_ETYPE(op))) ) {
- reg=NULL;
-// reg = regWithIdx (pic16_dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1);
-#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);
- }
+ reg = pic16_dirregWithName(name);
if(!reg) {
int address = 0;
/* Register wasn't found in hash, so let's create
* a new one and put it in the hash table AND in the
* dynDirectRegNames set */
- if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) {
+ if(IS_CODE(OP_SYM_ETYPE(op)) || IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) {
debugLog("%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
return NULL;
}
-#ifndef USE_ONSTACK
+#if 0
if(OP_SYMBOL(op)->onStack) {
fprintf(stderr, "%s:%d onStack %s offset: %d\n", __FILE__, __LINE__,
OP_SYMBOL(op)->name, OP_SYMBOL(op)->stack);
- OP_SYMBOL(op)->onStack = 0;
- SPEC_OCLS(OP_SYM_ETYPE(op)) = data;
- regtype = REG_GPR;
- return (reg);
-#endif
}
+#endif
- if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) {
+ if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
+ || !IN_FARSPACE(SPEC_OCLS( OP_SYM_ETYPE(op))) ) {
+
+#if 0
if(pic16_debug_verbose)
{
fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d eeprom: %d\n",
fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__,
OP_SYMBOL(op)->name);
}
+#endif
}
reg = newReg(regtype, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0, op);
debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
+ if( SPEC_SCLS( OP_SYM_ETYPE( op ) ) == S_REGISTER ) {
+ fprintf(stderr, "%s:%d symbol %s is declared as register\n", __FILE__, __LINE__,
+ name);
+
+ reg->accessBank = 1;
+ checkAddReg(&pic16_dynAccessRegs, reg);
+ hTabAddItem(&dynAccessRegNames, regname2key(name), reg);
+
+ return (reg);
+ }
+
// if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
// fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
} else {
// fprintf(stderr, "%s:%d adding %s in direct registers\n", __FILE__, __LINE__, reg->name);
// addSet(&pic16_dynDirectRegs, reg);
- checkAddReg(&pic16_dynDirectRegs, reg);
+
+#if 1
+ if(!(IS_STATIC(OP_SYM_ETYPE(op))
+ && OP_SYMBOL(op)->ival
+ ))
+#endif
+ checkAddReg(&pic16_dynDirectRegs, reg);
}
} else {
// debugLog (" -- %s is declared at address 0x30000x\n",name);
- return NULL;
+ return (reg); /* This was NULL before, but since we found it
+ * why not just return it?! */
}
if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
* a new one and put it in the hash table AND in the
* dynDirectRegNames set */
-// fprintf (stderr,"%s:%d symbol name %s\tregop= %p\n", __FUNCTION__, __LINE__, name, op);
+ 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 ("Found a Dynamic Register!\n");
} else if( (dReg = regWithIdx ( pic16_dynStackRegs, idx,0)) != NULL ) {
debugLog ("Found a Stack Register!\n");
- } else if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx,0)) != NULL ) {
+ } else if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx,1)) != NULL ) {
debugLog ("Found a Processor Register!\n");
fprintf(stderr, "Found a processor register! %s\n", dReg->name);
} else if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx,0)) != NULL ) {
extern void pic16_groupRegistersInSection(set *regset);
extern void pic16_dump_equates(FILE *of, set *equs);
+extern void pic16_dump_access(FILE *of, set *section);
//extern void pic16_dump_map(void);
extern void pic16_dump_usection(FILE *of, set *section, int fix);
extern void pic16_dump_isection(FILE *of, set *section, int fix);
{
packBits(pic16_dynDirectBitRegs);
+// fprintf(stderr, "%s: pic16_dynAllocRegs\n", __FUNCTION__);
pic16_groupRegistersInSection(pic16_dynAllocRegs);
+
+// fprintf(stderr, "%s: pic16_dynInternalRegs\n", __FUNCTION__);
pic16_groupRegistersInSection(pic16_dynInternalRegs);
+
+// fprintf(stderr, "%s: pic16_dynStackRegs\n", __FUNCTION__);
pic16_groupRegistersInSection(pic16_dynStackRegs);
+
+// fprintf(stderr, "%s: pic16_dynDirectRegs\n", __FUNCTION__);
pic16_groupRegistersInSection(pic16_dynDirectRegs);
+
+// fprintf(stderr, "%s: pic16_dynDirectBitsRegs\n", __FUNCTION__);
pic16_groupRegistersInSection(pic16_dynDirectBitRegs);
+
+// fprintf(stderr, "%s: pic16_dynProcessorRegs\n", __FUNCTION__);
pic16_groupRegistersInSection(pic16_dynProcessorRegs);
+// fprintf(stderr, "%s: pic16_dynAccessRegs\n", __FUNCTION__);
+ pic16_groupRegistersInSection(pic16_dynAccessRegs);
/* dump equates */
pic16_dump_equates(of, pic16_equ_data);
// pic16_dump_esection(of, pic16_rel_eedata, 0);
// pic16_dump_esection(of, pic16_fix_eedata, 0);
+ /* dump access bank symbols */
+ pic16_dump_access(of, pic16_acs_udata);
+
/* dump initialised data */
pic16_dump_isection(of, rel_idataSymSet, 0);
pic16_dump_isection(of, fix_idataSymSet, 1);
/* check if there are any live ranges that not
used in the remainder of the block */
- if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
+ if (!_G.blockSpil &&
+ !isiCodeInFunctionCall (ic) &&
+ (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
{
sym = leastUsedLR (selectS);
if (!sym->remat)
if (!bitVectBitValue (_G.regAssigned, sym->key))
continue;
+ /* special case for shifting: there is a case where shift count
+ * can be allocated in the same register as the result, so do not
+ * free right registers if same as result registers, cause genShiftLeft
+ * will fail -- VR */
+ if(ic->op == LEFT_OP)
+ continue;
+
/* special case check if this is an IFX &
the privious one was a pop and the
previous one was not spilt then keep track
(result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
result->liveTo > ic->seq && /* and will live beyond this */
result->liveTo <= ebp->lSeq && /* does not go beyond this block */
+ result->liveFrom == ic->seq && /* does not start before here */
result->regType == sym->regType && /* same register types */
result->nRegs && /* which needs registers */
!result->isspilt && /* and does not already have them */
serialRegAssign (eBBlock ** ebbs, int count)
{
int i;
-
+ iCode *ic;
+
debugLog ("%s\n", __FUNCTION__);
/* for all blocks */
for (i = 0; i < count; i++)
{
-
- iCode *ic;
-
if (ebbs[i]->noPath &&
(ebbs[i]->entryLabel != entryLabel &&
ebbs[i]->entryLabel != returnLabel))
for (ic = ebbs[i]->sch; ic; ic = ic->next)
{
- debugLog (" op: %s\n", decodeOp (ic->op));
+ debugLog (" op: %s\n", pic16_decodeOp (ic->op));
if(IC_RESULT(ic) && !IS_ITEMP( IC_RESULT(ic)))
pic16_allocDirReg(IC_RESULT(ic));
if (ic->op == RECEIVE)
debugLog ("When I get clever, I'll optimize the receive logic\n");
+ if(POINTER_GET(ic) && IS_BITFIELD(getSpec(operandType(IC_RESULT(ic))))
+ && (SPEC_BLEN(getSpec(operandType(IC_RESULT(ic))))==1)
+ && (ic->next->op == IFX)
+ && (OP_LIVETO(IC_RESULT(ic)) == ic->next->seq)) {
+
+ /* skip register allocation since none will be used */
+ for(j=0;j<sym->nRegs;j++)
+ sym->regs[j] = newReg(REG_TMP, PO_GPR_TEMP, 0, "bad", 1, 0, NULL);
+// OP_SYMBOL(IC_RESULT(ic))->nRegs = 0;
+
+ continue;
+ }
+
/* if we need ptr regs for the right side
then mark it */
- if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
+ if (POINTER_GET (ic) && IS_SYMOP( IC_LEFT(ic) ) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
<= (unsigned) PTRSIZE)
{
pic16_ptrRegReq++;
/* else we assign registers to it */
_G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
- debugLog (" %d - nRegs: %d\n", __LINE__, sym->nRegs);
if(debugF)
bitVectDebugOn(_G.regAssigned, debugF);
if (IS_AGGREGATE (sym->type) || sym->isptr)
sym->type = aggrToPtr (sym->type, FALSE);
debugLog (" %d - no reg needed - used as a return\n", __LINE__);
-
continue;
}
/* registers for true symbols we will */
/* see how things go */
sym->nRegs = 0;
+
}
}
iCode *dic, *sic;
debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
- debugLog ("ic->op = %s\n", decodeOp( ic->op ) );
+ debugLog ("ic->op = %s\n", pic16_decodeOp( ic->op ) );
debugAopGet (" result:", IC_RESULT (ic));
debugAopGet (" left:", IC_LEFT (ic));
debugAopGet (" right:", IC_RIGHT (ic));
debugLog (" %d - result is not temp\n", __LINE__);
}
+// if(IS_VALOP(IC_RIGHT(ic)))return 0;
/* See BUGLOG0001 - VR */
#if 1
- if (!IS_ITEMP (IC_RIGHT (ic))) {
+ if (!IS_ITEMP (IC_RIGHT (ic)) /*&& (!IS_PARM(IC_RESULT(ic)))*/) {
debugLog (" %d - not packing - right is not temp\n", __LINE__);
pic16_allocDirReg(IC_RIGHT (ic));
return 0;
if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
OP_SYMBOL (IC_RESULT (ic))->iaccess)
{
-
-#ifndef USE_ONSTACK
- /* 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;
- return 0;
- }
-#endif
-
-
/* the operation has only one symbol
operator then we can pack */
if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
if ((ic->op == '+' || ic->op == '-') &&
OP_SYMBOL (IC_RIGHT (dic))->onStack)
{
-
-#if USE_ONSTACK
- if(OP_SYMBOL(IC_RESULT(ic))->onStack) {
- OP_SYMBOL(IC_RESULT(ic))->onStack = 0;
- return NULL;
- }
-#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)
for (dic = ic->next; dic; dic = dic->next)
{
-
-
-
if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
- debugLog (" used on left\n");
+ debugLog (" used on left\n");
if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
- debugLog (" used on right\n");
+ debugLog (" used on right\n");
if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
- debugLog (" used on result\n");
+ debugLog (" used on result\n");
if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
- (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
+ (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
return;
-
}
debugLog (" hey we can remove this unnecessary assign\n");
packForPush (iCode * ic, eBBlock * ebp)
{
iCode *dic;
-
+
debugLog ("%s\n", __FUNCTION__);
if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
return;
+#if 0
+ {
+ int n1, n2;
+
+ n1 = bitVectnBitsOn( OP_DEFS(IC_LEFT(ic)));
+ n2 = bitVectnBitsOn( OP_USES(IC_LEFT(ic)));
+ debugf3("defs: %d\tuses: %d\t%s\n", n1, n2, printILine(ic));
+ debugf2("IC_LEFT(ic): from %d to %d\n", OP_LIVEFROM(IC_LEFT(ic)), OP_LIVETO(IC_LEFT(ic)));
+ }
+#endif
+
/* must have only definition & one usage */
if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
return;
+ /* if definition is not assignment,
+ * or is not pointer (because pointer might have changed) */
if (dic->op != '=' || POINTER_SET (dic))
return;
+ /* we must ensure that we can use the delete the assignment,
+ * because the source might have been modified in between.
+ * Until I know how to fix this, I'll use the adhoc fix
+ * to check the liveranges */
+ if((OP_LIVEFROM(IC_RIGHT(dic))==0) || (OP_LIVETO(IC_RIGHT(dic))==0))
+ return;
+// debugf2("IC_RIGHT(dic): from %d to %d\n", OP_LIVEFROM(IC_RIGHT(dic)), OP_LIVETO(IC_RIGHT(dic)));
+
+
+
/* we now we know that it has one & only one def & use
and the that the definition is an assignment */
IC_LEFT (ic) = IC_RIGHT (dic);
+
+ debugf("remiCodeFromeBBlock: %s\n", printILine(dic));
remiCodeFromeBBlock (ebp, dic);
bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
{
FILE *of = stderr;
- if(!pic16_ralloc_debug)return;
-
- if(!sl)return;
-
- if(debugF)
- of = debugF;
-
- for ( ; sl; sl=sl->next) {
- if(!IS_DECL(sl) ) {
- switch (SPEC_SCLS(sl)) {
- case S_DATA: fprintf (of, "data "); break;
- case S_XDATA: fprintf (of, "xdata "); break;
- case S_SFR: fprintf (of, "sfr "); break;
- case S_SBIT: fprintf (of, "sbit "); break;
- case S_CODE: fprintf (of, "code "); break;
- case S_IDATA: fprintf (of, "idata "); break;
- case S_PDATA: fprintf (of, "pdata "); break;
- case S_LITERAL: fprintf (of, "literal "); break;
- case S_STACK: fprintf (of, "stack "); break;
- case S_XSTACK: fprintf (of, "xstack "); break;
- case S_BIT: fprintf (of, "bit "); break;
- case S_EEPROM: fprintf (of, "eeprom "); break;
- default: break;
- }
-
- }
- }
+ if(!pic16_ralloc_debug)return;
+
+ if(!sl)return;
+
+ if(debugF)
+ of = debugF;
+
+ for ( ; sl; sl=sl->next) {
+ if(!IS_DECL(sl) ) {
+ switch (SPEC_SCLS(sl)) {
+ case S_DATA: fprintf (of, "data "); break;
+ case S_XDATA: fprintf (of, "xdata "); break;
+ case S_SFR: fprintf (of, "sfr "); break;
+ case S_SBIT: fprintf (of, "sbit "); break;
+ case S_CODE: fprintf (of, "code "); break;
+ case S_IDATA: fprintf (of, "idata "); break;
+ case S_PDATA: fprintf (of, "pdata "); break;
+ case S_LITERAL: fprintf (of, "literal "); break;
+ case S_STACK: fprintf (of, "stack "); break;
+ case S_XSTACK: fprintf (of, "xstack "); break;
+ case S_BIT: fprintf (of, "bit "); break;
+ case S_EEPROM: fprintf (of, "eeprom "); break;
+ default: break;
+ }
+ }
+ }
}
{
// debugLog("%d\n", __LINE__);
/* find assignment of the form TrueSym := iTempNN:1 */
- /* see BUGLOG0001 for workaround with the CAST - VR */
-// if ( (ic->op == '=' || ic->op == CAST) && !POINTER_SET (ic) ) // patch 11
if ( (ic->op == '=') && !POINTER_SET (ic) ) // patch 11
change += packRegsForAssign (ic, ebp);
/* debug stuff */
if (POINTER_SET (ic))
- debugLog (" %d - Pointer set\n", __LINE__);
-
+ debugLog (" %d - Pointer set\n", __LINE__);
+
+ /* Look for two subsequent iCodes with */
+ /* iTemp := _c; */
+ /* _c = iTemp & op; */
+ /* and replace them by */
+ /* iTemp := _c; */
+ /* _c = _c & op; */
+ if ((ic->op == BITWISEAND || ic->op == '|' || ic->op == '^')
+ && ic->prev
+ && ic->prev->op == '='
+ && IS_ITEMP (IC_LEFT (ic))
+ && IC_LEFT (ic) == IC_RESULT (ic->prev)
+ && isOperandEqual (IC_RESULT(ic), IC_RIGHT(ic->prev)))
+ {
+ iCode* ic_prev = ic->prev;
+ symbol* prev_result_sym = OP_SYMBOL (IC_RESULT (ic_prev));
+
+ ReplaceOpWithCheaperOp (&IC_LEFT (ic), IC_RESULT (ic));
+ if (IC_RESULT (ic_prev) != IC_RIGHT (ic)) {
+ bitVectUnSetBit (OP_USES (IC_RESULT (ic_prev)), ic->key);
+ if (/*IS_ITEMP (IC_RESULT (ic_prev)) && */
+ prev_result_sym->liveTo == ic->seq)
+ {
+ prev_result_sym->liveTo = ic_prev->seq;
+ }
+ }
+ bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
+
+ bitVectSetBit (ic->rlive, IC_RESULT (ic)->key);
+ if (bitVectIsZero (OP_USES (IC_RESULT (ic_prev)))) {
+ bitVectUnSetBit (ic->rlive, IC_RESULT (ic)->key);
+ bitVectUnSetBit (OP_DEFS (IC_RESULT (ic_prev)), ic_prev->key);
+ remiCodeFromeBBlock (ebp, ic_prev);
+ hTabDeleteItem (&iCodehTab, ic_prev->key, ic_prev, DELETE_ITEM, NULL);
+ }
+ }
+
/* if this is an itemp & result of a address of a true sym
then mark this as rematerialisable */
if (ic->op == ADDRESS_OF &&
}
if (POINTER_GET (ic))
{
- OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
- debugLog (" marking as a pointer (get) =>");
- debugAopGet (" left:", IC_LEFT (ic));
+ if(IS_SYMOP(IC_LEFT(ic))) {
+ OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
+ debugLog (" marking as a pointer (get) =>");
+ debugAopGet (" left:", IC_LEFT (ic));
+ }
}
//debugLog(" %d %s\n", __LINE__, __FUNCTION__);
}
}
#endif
+
+#if 1
+ /* there are some problems with packing variables
+ * it seems that the live range estimator doesn't
+ * estimate correctly the liveranges of some symbols */
+
/* pack for PUSH
iTempNN := (some variable in farspace) V1
push iTempNN ;
{
packForPush (ic, ebp);
}
-
+#endif
#ifndef NO_packRegsForAccUse
/* pack registers for accumulator use, when the
debugLog ("\nebbs before optimizing:\n");
dumpEbbsToDebug (ebbs, count);
+ _inRegAllocator = 1;
+
setToNull ((void *) &_G.funcrUsed);
pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
/* and serially allocate registers */
serialRegAssign (ebbs, count);
-// debugLog ("ebbs after serialRegAssign:\n");
-// dumpEbbsToDebug (ebbs, count);
-
+#if 0
+ debugLog ("ebbs after serialRegAssign:\n");
+ dumpEbbsToDebug (ebbs, count);
+#endif
//pic16_freeAllRegs();
debugLog ("ebbs after optimizing:\n");
dumpEbbsToDebug (ebbs, count);
+ _inRegAllocator = 0;
genpic16Code (ic);
/* mark all registers as free */
pic16_freeAllRegs ();
+
debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");
debugLogClose ();
return;