vright = (root->right->type == EX_VALUE ?
root->right->opval.val : NULL);
+ //#define EXPERIMENTAL
+#ifdef EXPERIMENTAL
+ /* if left is unsigned and right is literal */
+ if (vleft && vright &&
+ IS_UNSIGNED(vleft->etype) &&
+ IS_LITERAL(vright->etype)) {
+ double dval=floatFromVal(vright);
+ int op=root->opval.op;
+
+ fprintf (stderr,"op: '");
+ switch (op) {
+ case LE_OP: fprintf (stderr, "<= '"); break;
+ case EQ_OP: fprintf (stderr, "== '"); break;
+ case GE_OP: fprintf (stderr, ">= '"); break;
+ default: fprintf (stderr, "%c '", op); break;
+ }
+ fprintf (stderr, "%f\n", dval);
+
+ switch (op)
+ {
+ case EQ_OP:
+ case LE_OP:
+ case '<':
+ if (dval<0 || (op=='<' && dval==0)) {
+ // unsigned is never < 0
+ werror (W_IF_NEVER_TRUE);
+ optExpr = newAst_VALUE (constVal("0"));
+ return decorateType (optExpr);
+ }
+ if (dval==0) {
+ if (op==LE_OP) {
+ // change this into a cheaper EQ_OP
+ fprintf (stderr, "warning *** changed '<=' to '==' because of unsigned\n");
+ root->opval.op=EQ_OP;
+ return root;
+ }
+ }
+ break;
+ case GE_OP:
+ case '>':
+ if (dval>0 || (op==GE_OP && dval==0)) {
+ // unsigned is never < 0
+ werror (W_IF_ALWAYS_TRUE);
+ optExpr = newAst_VALUE (constVal("1"));
+ return decorateType (optExpr);
+ }
+ if (dval==0) {
+ if (op=='>') {
+ // change this into a cheaper reversed EQ_OP
+ fprintf (stderr, "warning *** changed '>' to '!=' because of unsigned\n");
+ root->opval.op=EQ_OP;
+ }
+ }
+ }
+ }
+#endif
+
/* if left is a BITVAR in BITSPACE */
/* and right is a LITERAL then opt- */
/* imize else do nothing */
/*-----------------------------------------------------------------*/
/* isOperandOnStack - will return true if operand is on stack */
/*-----------------------------------------------------------------*/
+#if 0
bool
isOperandOnStack (operand * op)
{
return ((IN_STACK (etype)) ? TRUE : FALSE);
}
+#else
+bool
+isOperandOnStack (operand * op)
+{
+ sym_link *etype;
+
+ if (!op)
+ return FALSE;
+
+ if (!IS_SYMOP (op))
+ return FALSE;
+
+ etype = getSpec (operandType (op));
+ if (IN_STACK (etype) ||
+ OP_SYMBOL(op)->onStack ||
+ (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
+ return TRUE;
+
+ return FALSE;
+}
+#endif
/*-----------------------------------------------------------------*/
/* operandLitValue - literal value of an operand */
#define IFFUNC_CALLEESAVES(x) (IS_FUNC(x) && FUNC_CALLEESAVES(x))
#define FUNC_ISISR(x) (x->funcAttrs.intrtn)
#define IFFUNC_ISISR(x) (IS_FUNC(x) && FUNC_ISISR(x))
-//#define FUNC_RBANK(x) (x->funcAttrs.rbank)
#define IFFUNC_RBANK(x) (IS_FUNC(x) && FUNC_RBANK(x))
#define FUNC_INTNO(x) (x->funcAttrs.intno)
#define FUNC_REGBANK(x) (x->funcAttrs.regbank)
#define IS_GENPTR(x) (IS_DECL(x) && DCL_TYPE(x) == GPOINTER)
#define IS_FUNC(x) (IS_DECL(x) && DCL_TYPE(x) == FUNCTION)
#define IS_LONG(x) (IS_SPEC(x) && x->select.s._long)
+#define IS_UNSIGNED(x) (IS_SPEC(x) && x->select.s._unsigned)
#define IS_TYPEDEF(x)(IS_SPEC(x) && x->select.s._typedef)
#define IS_CONSTANT(x) (IS_SPEC(x) && ( x->select.s._const == 1))
#define IS_STRUCT(x) (IS_SPEC(x) && x->select.s.noun == V_STRUCT)
/* make sure that the result of this icode is not on the
stack, since acc is used to compute stack offset */
+#if 0
if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
OP_SYMBOL (IC_RESULT (uic))->onStack)
return;
+#else
+ ifSymbolOnStack(IC_RESULT(uic))
+ return;
+#endif
/* if either one of them in far space then we cannot */
if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
/* make sure that the result of this icode is not on the
stack, since acc is used to compute stack offset */
+#if 0
if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
OP_SYMBOL (IC_RESULT (uic))->onStack)
+ return;
+#else
+ ifSymbolOnStack(IC_RESULT(uic))
return;
+#endif
/* if either one of them in far space then we cannot */
if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
{ W_DOUBLE_UNSUPPORTED, ERROR_LEVEL_WARNING,
"type 'double' not supported assuming 'float'" },
{ W_IF_NEVER_TRUE, ERROR_LEVEL_WARNING,
- "if-statement condition always false.if-statement not generated" },
+ "if-statement condition always false, if-statement not generated" },
{ W_FUNC_NO_RETURN, ERROR_LEVEL_WARNING,
"no 'return' statement found for function '%s'" },
{ W_PRE_PROC_WARNING, ERROR_LEVEL_WARNING,
"symbol name too long, truncated to %d chars" },
{ W_CAST_STRUCT_PTR,ERROR_LEVEL_WARNING,
"cast of struct %s * to struct %s * " },
+{ W_IF_ALWAYS_TRUE, ERROR_LEVEL_WARNING,
+ "if-statement condition always true, if-statement not generated" },
};
/*
#define W_PTR2INTEGRAL_NOCAST 155
#define W_SYMBOL_NAME_TOO_LONG 156
#define W_CAST_STRUCT_PTR 157 /* pointer to different structure types */
+#define W_IF_ALWAYS_TRUE 158
/** Describes the maximum error level that will be logged. Any level
* includes all of the levels listed after it.