Wed Jun 17 08:38:13 1998 Jeffrey A Law (law@cygnus.com)
+ * expr.c (check_max_integer_computation_mode): New function.
+ (expand_expr): Avoid integer computations in modes wider than
+ MAX_INTEGER_COMPUTATION_MODE.
+ * fold-const.c (fold): Likewise.
+ * tree.h (check_max_integer_computation_mode): Declare.
+ * tm.texi (MAX_INTEGER_COMPUTATION_MODE): Document it.
+
* configure.in (nm): Make a link to "nm" in the build tree too.
* mn10300.md (andsi3): Fix typo.
return 0;
}
}
+
+#ifdef MAX_INTEGER_COMPUTATION_MODE
+void
+check_max_integer_computation_mode (exp)
+ tree exp;
+{
+ enum tree_code code = TREE_CODE (exp);
+ enum machine_mode mode;
+
+ /* First check the type of the overall operation. We need only look at
+ unary, binary and relational operations. */
+ if (TREE_CODE_CLASS (code) == '1'
+ || TREE_CODE_CLASS (code) == '2'
+ || TREE_CODE_CLASS (code) == '<')
+ {
+ mode = TYPE_MODE (TREE_TYPE (exp));
+ if (GET_MODE_CLASS (mode) == MODE_INT
+ && mode > MAX_INTEGER_COMPUTATION_MODE)
+ fatal ("unsupported wide integer operation");
+ }
+
+ /* Check operand of a unary op. */
+ if (TREE_CODE_CLASS (code) == '1')
+ {
+ mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
+ if (GET_MODE_CLASS (mode) == MODE_INT
+ && mode > MAX_INTEGER_COMPUTATION_MODE)
+ fatal ("unsupported wide integer operation");
+ }
+
+ /* Check operands of a binary/comparison op. */
+ if (TREE_CODE_CLASS (code) == '2' || TREE_CODE_CLASS (code) == '<')
+ {
+ mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
+ if (GET_MODE_CLASS (mode) == MODE_INT
+ && mode > MAX_INTEGER_COMPUTATION_MODE)
+ fatal ("unsupported wide integer operation");
+
+ mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 1)));
+ if (GET_MODE_CLASS (mode) == MODE_INT
+ && mode > MAX_INTEGER_COMPUTATION_MODE)
+ fatal ("unsupported wide integer operation");
+ }
+}
+#endif
+
\f
/* expand_expr: generate code for computing expression EXP.
An rtx for the computed value is returned. The value is never null.
target = 0;
}
+#ifdef MAX_INTEGER_COMPUTATION_MODE
+ if (target)
+ {
+ enum machine_mode mode = GET_MODE (target);
+
+ if (GET_MODE_CLASS (mode) == MODE_INT
+ && mode > MAX_INTEGER_COMPUTATION_MODE)
+ fatal ("unsupported wide integer operation");
+ }
+
+ if (GET_MODE_CLASS (tmode) == MODE_INT
+ && tmode > MAX_INTEGER_COMPUTATION_MODE)
+ fatal ("unsupported wide integer operation");
+
+ check_max_integer_computation_mode (exp);
+#endif
+
/* If will do cse, generate all results into pseudo registers
since 1) that allows cse to find more things
and 2) otherwise cse could produce an insn the machine
tree type;
enum machine_mode mode;
+#ifdef MAX_INTEGER_COMPUTATION_MODE
+ check_max_integer_computation_mode (exp);
+#endif
+
emit_queue ();
switch (code)
same time if the machine is a superscalar machine. This is only used by
the @samp{Haifa} scheduler, and not the traditional scheduler.
+@findex MAX_INTEGER_COMPUTATION_MODE
+@item MAX_INTEGER_COMPUTATION_MODE
+Define this to the largest integer machine mode which can be used for
+operations other than load, store and copy operations.
+
+You need only define this macro if the target holds values larger than
+@code{word_mode} in general purpose registers. Most targets should not define
+this macro.
@end table