summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/expr.c67
-rw-r--r--gcc/fold-const.c4
-rw-r--r--gcc/tm.texi8
-rw-r--r--gcc/tree.h1
5 files changed, 87 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 601d4da7997..aa8d4dda591 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -6,6 +6,13 @@
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.
diff --git a/gcc/expr.c b/gcc/expr.c
index 657737f63e0..aad427d1fa1 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -4919,6 +4919,52 @@ var_rtx (exp)
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
+
/* expand_expr: generate code for computing expression EXP.
An rtx for the computed value is returned. The value is never null.
@@ -5041,6 +5087,23 @@ expand_expr (exp, target, tmode, modifier)
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
@@ -9816,6 +9879,10 @@ do_jump (exp, if_false_label, if_true_label)
tree type;
enum machine_mode mode;
+#ifdef MAX_INTEGER_COMPUTATION_MODE
+ check_max_integer_computation_mode (exp);
+#endif
+
emit_queue ();
switch (code)
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 5daa253a449..b75da2e77fd 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -3797,6 +3797,10 @@ fold (expr)
return t;
}
+#ifdef MAX_INTEGER_COMPUTATION_MODE
+ check_max_integer_computation_mode (expr);
+#endif
+
kind = TREE_CODE_CLASS (code);
if (code == NOP_EXPR || code == FLOAT_EXPR || code == CONVERT_EXPR)
{
diff --git a/gcc/tm.texi b/gcc/tm.texi
index b03e79100f0..a4fb481e8fc 100644
--- a/gcc/tm.texi
+++ b/gcc/tm.texi
@@ -7417,4 +7417,12 @@ A C expression that returns how many instructions can be issued at the
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
diff --git a/gcc/tree.h b/gcc/tree.h
index 3a89122eab6..0407db28bcb 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -2123,6 +2123,7 @@ extern void do_pending_stack_adjust PROTO ((void));
extern struct rtx_def *expand_assignment PROTO ((tree, tree, int, int));
extern struct rtx_def *store_expr PROTO ((tree, struct rtx_def *,
int));
+extern void check_max_integer_computation_mode PROTO ((tree));
/* In emit-rtl.c */
extern void start_sequence_for_rtl_expr PROTO ((tree));
OpenPOWER on IntegriCloud