aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
authorJeffrey A Law <law@cygnus.com>1998-06-17 11:44:02 +0000
committerJeff Law <law@gcc.gnu.org>1998-06-17 05:44:02 -0600
commitdbecbbe48af59a29adadd6e6dc8895e64764adb4 (patch)
tree5f8204f11538f0d3f56395877d68c0bbfd75f9b7 /gcc/expr.c
parenta5b8127eb13cce7fa4ddf8e4337f6e9fe67d1dc4 (diff)
downloadgcc-dbecbbe48af59a29adadd6e6dc8895e64764adb4.zip
gcc-dbecbbe48af59a29adadd6e6dc8895e64764adb4.tar.gz
gcc-dbecbbe48af59a29adadd6e6dc8895e64764adb4.tar.bz2
expr.c (check_max_integer_computation_mode): New function.
* 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. From-SVN: r20538
Diffstat (limited to 'gcc/expr.c')
-rw-r--r--gcc/expr.c67
1 files changed, 67 insertions, 0 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index 657737f..aad427d 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)