/*-----------------------------------------------------------------*/
extern void genpic14Code (iCode *);
-extern void assignConfigWordValue(int address, int value);
+extern void pic14_assignConfigWordValue(int address, int value);
/* Global data */
static struct
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;
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 ?
}
+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;
dReg->name = Safe_strdup(buffer);
}
dReg->isFree = 0;
- dReg->wasUsed = 1;
+ dReg->wasUsed = 0;
if (type == REG_SFR)
dReg->isFixed = 1;
else
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;
}
return NULL;
}
/*-----------------------------------------------------------------*/
-/* initStack - allocate registers for a psuedo stack */
+/* initStack - allocate registers for a pseudo stack */
/*-----------------------------------------------------------------*/
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; i<size; i++) {
- regs *r = newReg(REG_STK, PO_GPR_TEMP,base_address,NULL,1,0);
+ char buffer[16];
+ regs *r;
+ SNPRINTF(&buffer[0], 16, "STK%02d", i);
+ r = newReg(REG_STK, PO_GPR_TEMP,base_address,buffer,1,0);
r->address = 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--;
*-----------------------------------------------------------------*/
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);
int IS_CONFIG_ADDRESS(int address)
{
- return address == 0x2007;
+ return ((address == 0x2007) || (address == 0x2008));
}
/*-----------------------------------------------------------------*/
{
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);
}
} else {
int idx;
if (address) {
- if (IS_BITVAR (symlnk))
+ if (IS_BITVAR (spec))
idx = address >> 3;
else
idx = address;
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;
}
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;
/* 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) {
assignRelocatableRegisters(dynAllocRegs,0);
assignRelocatableRegisters(dynStackRegs,0);
+ assignRelocatableRegisters(dynDirectRegs,0);
/*
assignRelocatableRegisters(dynDirectRegs,0);
printf("assignRelocatableRegisters(dynDirectRegs,0);\n");
/* 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)
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;
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));
}
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 ||
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;
accuse:
debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
-
-
+#endif
}
/*-----------------------------------------------------------------*/
/* 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);
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);