/*-----------------------------------------------------------------*/
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));
}
/*-----------------------------------------------------------------*/
/* if it does not end here */
if (sym->liveTo > ic->seq)
continue;
-
- /* HACK: result and operand must be disjoint for POINTER_GET/LEFT_OP/RIGHT_OP */
- if (sym->liveTo == ic->seq && (POINTER_GET(ic) || ic->op == LEFT_OP || ic->op == RIGHT_OP))
+
+ /* 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 ||
/* 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);