case SYMBOL:
#define REGA 1
-#ifdef REGA
+//#if REGA /* { */
+ if(REGA && !getenv("PRINT_SHORT_OPERANDS")) {
fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d a2p%d re%d rm%d nos%d ru%d dp%d}", /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}" , */
(OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
op->key,
fprintf (file, "]");
}
}
-#else
- fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ?
- OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
+//#else /* } else { */
+ } else {
+ /* (getenv("PRINT_SHORT_OPERANDS") != NULL) */
+ fprintf (file, "%s ", (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
+
+ if(getenv("PRINT_SHORT_OPERANDS")[0] < '1')
+ {
+ fprintf (file, "[lr%d:%d so:%d]",
+ OP_LIVEFROM (op), OP_LIVETO (op),
+ OP_SYMBOL (op)->stack);
+ }
+
+ if(getenv("PRINT_SHORT_OPERANDS")[0] < '2')
+ {
+ fprintf (file, "{");
+ printTypeChain (operandType (op), file);
+ if (SPIL_LOC (op) && IS_ITEMP (op))
+ fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
+ fprintf (file, "}");
+ }
+
/* if assigned to registers */
- if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt)
+ if (OP_SYMBOL (op)->nRegs)
{
- int i;
- fprintf (file, "[");
- for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
- fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ?
- OP_SYMBOL (op)->regs[i]->name :
- "err"));
- fprintf (file, "]");
+ if (OP_SYMBOL (op)->isspilt)
+ {
+ if (!OP_SYMBOL (op)->remat)
+ if (OP_SYMBOL (op)->usl.spillLoc)
+ fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
+ OP_SYMBOL (op)->usl.spillLoc->rname :
+ OP_SYMBOL (op)->usl.spillLoc->name));
+ else
+ fprintf (file, "[err]");
+ else
+ fprintf (file, "[remat]");
+ }
+ else
+ {
+ int i;
+ fprintf (file, "[");
+ for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
+ fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
+ fprintf (file, "]");
+ }
}
-#endif
+//#endif /* } */
+ }
break;
case TYPE:
if (ic->op == SEND || ic->op == RECEIVE) {
fprintf(of,"{argreg = %d}",ic->argreg);
}
+ if (ic->op == IPUSH) {
+ fprintf(of,"{parmPush = %d}",ic->parmPush);
+ }
fprintf (of, "\n");
}
of = stdout;
icTab = getTableEntry (ic->op);
- fprintf (stdout, "%s(%d:%d:%d:%d:%d)\t",
+ fprintf (of, "%s(%d:%d:%d:%d:%d)\t",
ic->filename, ic->lineno,
ic->seq, ic->key, ic->depth, ic->supportRtn);
icTab->iCodePrint (of, ic, icTab->printName);
{
symbol *itmplbl;
- /* check if this alredy exists */
+ /* check if this already exists */
if (s && (itmplbl = findSym (LabelTab, NULL, s)))
return itmplbl;
if (s)
{
- itmplbl = newSymbol (s, 1);
+ itmplbl = newSymbol (s, 1);
}
else
{
return IN_FARSPACE (oclass);
}
+/*-----------------------------------------------------------------*/
+/* isiCodeInFunctionCall - return TRUE if an iCode is between a */
+/* CALL/PCALL and the first IPUSH/SEND associated with the call */
+/*-----------------------------------------------------------------*/
+int
+isiCodeInFunctionCall (iCode * ic)
+{
+ iCode * lic = ic;
+
+ /* Find the next CALL/PCALL */
+ while (lic)
+ {
+ if (lic->op == CALL || lic->op == PCALL)
+ break;
+ lic = lic->next;
+ }
+
+ if (!lic)
+ return FALSE;
+
+ /* A function call was found. Scan backwards and see if an */
+ /* IPUSH or SEND is encountered */
+ while (ic)
+ {
+ if (lic != ic && (ic->op == CALL || ic->op == PCALL))
+ return FALSE;
+ if (ic->op == SEND || (ic->op == IPUSH && ic->parmPush))
+ return TRUE;
+ ic = ic->prev;
+ }
+
+ return FALSE;
+}
+
/*-----------------------------------------------------------------*/
/* operandLitValue - literal value of an operand */
/*-----------------------------------------------------------------*/
if(IS_PTR(ltype))
{
int size = getSize(ltype);
- return(IS_GENPTR(ltype)?(size-1):size);
+ return((IS_GENPTR(ltype) && GPTRSIZE > FPTRSIZE) ? (size-1) : size);
}
if(IS_ARRAY(ltype))
case FUNCTION:
return (FPTRSIZE);
case GPOINTER:
- return (GPTRSIZE-1);
+ if (GPTRSIZE > FPTRSIZE)
+ return (GPTRSIZE-1);
+ else
+ return (FPTRSIZE);
default:
return (FPTRSIZE);
// if not a pointer to a function
if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
if (implicit) { // if not to generic, they have to match
- if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
+ if (!IS_GENPTR(type) &&
+ !((DCL_TYPE(optype) == DCL_TYPE(type)) ||
+ ((DCL_TYPE(optype) == POINTER) && (DCL_TYPE(type) == IPOINTER))
+ )
+ )
+ {
werror(E_INCOMPAT_PTYPES);
errors++;
}
restype = getSpec (operandType (IC_RESULT (ic)));
if (!IS_LITERAL(opetype) &&
!IS_BIT(opetype))
+ {
SPEC_SCLS (restype) = SPEC_SCLS (opetype);
- SPEC_OCLS (restype) = SPEC_OCLS (opetype);
-
+ SPEC_OCLS (restype) = SPEC_OCLS (opetype);
+ }
ADDTOCHAIN (ic);
return IC_RESULT (ic);
}
if (p2 && !IS_FLOAT (letype)
&& !((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype))
&& (port->support.muldiv == 1))
- && strcmp (port->target, "pic14") != 0 /* don't shift for pic */
- && strcmp (port->target, "pic16") != 0)
+ && strcmp (port->target, "pic16") != 0 /* don't shift for pic */
+ && strcmp (port->target, "pic14") != 0)
{
if ((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype)))
{
/* hack don't like this but too lazy to think of
something better */
if (IS_ADDRESS_OF_OP (parms))
- parms->left->lvalue = 1;
+ parms->left->lvalue = 1;
if (IS_CAST_OP (parms) &&
- IS_PTR (parms->ftype) &&
- IS_ADDRESS_OF_OP (parms->right))
- parms->right->left->lvalue = 1;
+ IS_PTR (parms->ftype) &&
+ IS_ADDRESS_OF_OP (parms->right))
+ parms->right->left->lvalue = 1;
pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
}
{
/* now decide whether to push or assign */
if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
- {
+ {
- /* assign */
- operand *top = operandFromSymbol (argVals->sym);
- /* clear useDef and other bitVectors */
- OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
- geniCodeAssign (top, pval, 1, 0);
- }
+ /* assign */
+ operand *top = operandFromSymbol (argVals->sym);
+ /* clear useDef and other bitVectors */
+ OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
+ geniCodeAssign (top, pval, 1, 0);
+ }
else
- {
- sym_link *p = operandType (pval);
- /* push */
- ic = newiCode (IPUSH, pval, NULL);
- ic->parmPush = 1;
- /* update the stack adjustment */
- *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
- ADDTOCHAIN (ic);
- }
+ {
+ sym_link *p = operandType (pval);
+ /* push */
+ ic = newiCode (IPUSH, pval, NULL);
+ ic->parmPush = 1;
+ /* update the stack adjustment */
+ *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
+ ADDTOCHAIN (ic);
+ }
}
argVals=argVals->next;
static void
geniCodeReceive (value * args)
{
+ unsigned char paramByteCounter = 0;
+
/* for all arguments that are passed in registers */
while (args)
{
first = 0;
}
IC_RESULT (ic) = opr;
+
+ /* misuse of parmBytes (normally used for functions)
+ * to save estimated stack position of this argument.
+ * Normally this should be zero for RECEIVE iCodes.
+ * No idea if this causes side effects on other ports. - dw
+ */
+ ic->parmBytes = paramByteCounter;
+
+ /* what stack position do we have? */
+ paramByteCounter += getSize (sym->type);
+
ADDTOCHAIN (ic);
}
int needRangeCheck = !optimize.noJTabBoundary
|| tree->values.switchVals.swDefault;
sym_link *cetype = getSpec (operandType (cond));
- int sizeofMinCost, sizeofMaxCost;
+ int sizeofMinCost, sizeofZeroMinCost, sizeofMaxCost;
int sizeofMatchJump, sizeofJumpTable;
int sizeIndex;
/* Compute the size cost of the range check and subtraction. */
sizeofMinCost = 0;
+ sizeofZeroMinCost = 0;
sizeofMaxCost = 0;
if (needRangeCheck)
{
if (!(min==0 && IS_UNSIGNED (cetype)))
sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
+ if (!IS_UNSIGNED (cetype))
+ sizeofZeroMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
sizeofMaxCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
}
if (min)
/* If the size cost of handling a non-zero minimum exceeds the */
/* cost of extending the range down to zero, then it might be */
/* better to extend the range to zero. */
- if (min > 0 && sizeofMinCost >= (min * port->jumptableCost.sizeofElement))
+ if (min > 0 && (sizeofMinCost-sizeofZeroMinCost)
+ >= (min * port->jumptableCost.sizeofElement))
{
/* Only extend the jump table if it would still be manageable. */
if (1 + max <= port->jumptableCost.maxCount)
- min = 0;
+ {
+ min = 0;
+ if (IS_UNSIGNED (cetype))
+ sizeofMinCost = 0;
+ else
+ sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
+ }
}
/* Compute the total size cost of a jump table. */
/* Compute the total size cost of a match & jump sequence */
sizeofMatchJump = cnt * port->jumptableCost.sizeofMatchJump[sizeIndex];
-
+
/* If the size cost of the jump table is uneconomical then exit */
if (sizeofMatchJump < sizeofJumpTable)
return 0;
}
}
- /* If cond is volatile, it might change after the boundary */
- /* conditions are tested to an out of bounds value, causing */
- /* a jump to a location outside of the jump table. To avoid */
- /* this possibility, use a non-volatile copy of it instead. */
- if (IS_OP_VOLATILE (cond))
- {
- operand * newcond;
- iCode * ic;
-
- newcond = newiTempOperand (operandType (cond), TRUE);
- newcond->isvolatile = 0;
- ic = newiCode ('=', NULL, cond);
- IC_RESULT (ic) = newcond;
- ADDTOCHAIN (ic);
- cond = newcond;
- }
-
/* first we rule out the boundary conditions */
/* if only optimization says so */
if (needRangeCheck)
}
goto defaultOrBreak;
}
+
+ /* If cond is volatile, it might change while we are trying to */
+ /* find the matching case. To avoid this possibility, make a */
+ /* non-volatile copy to use instead. */
+ if (IS_OP_VOLATILE (cond))
+ {
+ operand * newcond;
+ iCode * ic;
+
+ newcond = newiTempOperand (operandType (cond), TRUE);
+ newcond->isvolatile = 0;
+ ic = newiCode ('=', NULL, cond);
+ IC_RESULT (ic) = newcond;
+ ADDTOCHAIN (ic);
+ cond = newcond;
+ }
/* if we can make this a jump table */
if (geniCodeJumpTable (cond, caseVals, tree))
{
iCode *ic;
operand *op = NULL;
+ sym_link *type;
+
+ if (!options.stackAuto)
+ {
+ type = newLink(SPECIFIER);
+ SPEC_VOLATILE(type) = 1;
+ SPEC_NOUN(type) = V_BIT;
+ SPEC_SCLS(type) = S_BIT;
+ SPEC_BLEN(type) = 1;
+ SPEC_BSTR(type) = 0;
+ op = newiTempOperand(type, 1);
+ }
/* If op is NULL, the original interrupt state will saved on */
/* the stack. Otherwise, it will be saved in op. */
- /* Generate a save of the current interrupt state & disabled */
+ /* Generate a save of the current interrupt state & disable */
ic = newiCode (CRITICAL, NULL, NULL);
IC_RESULT (ic) = op;
ADDTOCHAIN (ic);