aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJeff Law <law@gcc.gnu.org>1996-07-02 16:59:02 -0600
committerJeff Law <law@gcc.gnu.org>1996-07-02 16:59:02 -0600
commit5718612fc1929a7d9a3ec02c34eb6999c3d5b738 (patch)
tree706c142d025d0035e9e7bf1a0ea38934874345e1 /gcc
parentf95709dbc854fe93f231fb85b90850a303c9e065 (diff)
downloadgcc-5718612fc1929a7d9a3ec02c34eb6999c3d5b738.zip
gcc-5718612fc1929a7d9a3ec02c34eb6999c3d5b738.tar.gz
gcc-5718612fc1929a7d9a3ec02c34eb6999c3d5b738.tar.bz2
expr.c (compare): If function pointers need canonicalization before comparisons, canonicalize them.
* expr.c (compare): If function pointers need canonicalization before comparisons, canonicalize them. (do_store_flag): Do not use an sCC insn for a function pointer comparison if function pointers need canonicalization before comparing. From-SVN: r12381
Diffstat (limited to 'gcc')
-rw-r--r--gcc/expr.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index 5dd6700..1c4c6bb 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -10582,6 +10582,32 @@ compare (exp, signed_code, unsigned_code)
int unsignedp = TREE_UNSIGNED (type);
enum rtx_code code = unsignedp ? unsigned_code : signed_code;
+#ifdef HAVE_canonicalize_funcptr_for_compare
+ /* If function pointers need to be "canonicalized" before they can
+ be reliably compared, then canonicalize them. */
+ if (HAVE_canonicalize_funcptr_for_compare
+ && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == POINTER_TYPE
+ && (TREE_CODE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0))))
+ == FUNCTION_TYPE))
+ {
+ rtx new_op0 = gen_reg_rtx (mode);
+
+ emit_insn (gen_canonicalize_funcptr_for_compare (new_op0, op0));
+ op0 = new_op0;
+ }
+
+ if (HAVE_canonicalize_funcptr_for_compare
+ && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 1))) == POINTER_TYPE
+ && (TREE_CODE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 1))))
+ == FUNCTION_TYPE))
+ {
+ rtx new_op1 = gen_reg_rtx (mode);
+
+ emit_insn (gen_canonicalize_funcptr_for_compare (new_op1, op1));
+ op1 = new_op1;
+ }
+#endif
+
return compare_from_rtx (op0, op1, code, unsignedp, mode,
((mode == BLKmode)
? expr_size (TREE_OPERAND (exp, 0)) : NULL_RTX),
@@ -10716,6 +10742,19 @@ do_store_flag (exp, target, mode, only_cheap)
if (operand_mode == BLKmode)
return 0;
+ /* We won't bother with store-flag operations involving function pointers
+ when function pointers must be canonicalized before comparisons. */
+#ifdef HAVE_canonicalize_funcptr_for_compare
+ if (HAVE_canonicalize_funcptr_for_compare
+ && ((TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == POINTER_TYPE
+ && (TREE_CODE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0))))
+ == FUNCTION_TYPE))
+ || (TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 1))) == POINTER_TYPE
+ && (TREE_CODE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 1))))
+ == FUNCTION_TYPE))))
+ return 0;
+#endif
+
STRIP_NOPS (arg0);
STRIP_NOPS (arg1);