summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authornemet <nemet@138bc75d-0d04-0410-961f-82ee72b054a4>2006-02-28 20:32:20 +0000
committernemet <nemet@138bc75d-0d04-0410-961f-82ee72b054a4>2006-02-28 20:32:20 +0000
commitfd95fba452ea7e981bbf13518b730c332c030dc3 (patch)
treeb59a2ff0c0c65abbe656b96ae1d8a37028083f6b /gcc
parent136335a28f44c3eeab45ca715f30c6dcfe59e1b4 (diff)
downloadgcc-fd95fba452ea7e981bbf13518b730c332c030dc3.tar.gz
* rtl.h (truncated_to_mode): Declare it.
(struct rtl_hooks): Add reg_truncated_to_mode hook. * rtlhooks-def.h (RTL_HOOKS_REG_TRUNCATED_TO_MODE): New macro. (RTL_HOOKS_INITIALIZER): Include it. * rtlhooks.c (reg_truncated_to_mode_general): New function. * combine.c (RTL_HOOKS_REG_TRUNCATED_TO_MODE): Override to reg_truncated_to_mode. * rtlanal.c (truncated_to_mode): Define it. * simplify-rtx.c (simplify_unary_operation_1): Use it. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@111573 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/combine.c3
-rw-r--r--gcc/rtl.h4
-rw-r--r--gcc/rtlanal.c10
-rw-r--r--gcc/rtlhooks-def.h3
-rw-r--r--gcc/rtlhooks.c7
-rw-r--r--gcc/simplify-rtx.c17
7 files changed, 49 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7ba31346670..d37067c1142 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+2006-02-28 Paolo Bonzini <bonzini@gnu.org>
+ Adam Nemet <anemet@caviumnetworks.com>
+
+ * rtl.h (truncated_to_mode): Declare it.
+ (struct rtl_hooks): Add reg_truncated_to_mode hook.
+ * rtlhooks-def.h (RTL_HOOKS_REG_TRUNCATED_TO_MODE): New macro.
+ (RTL_HOOKS_INITIALIZER): Include it.
+ * rtlhooks.c (reg_truncated_to_mode_general): New function.
+ * combine.c (RTL_HOOKS_REG_TRUNCATED_TO_MODE): Override to
+ reg_truncated_to_mode.
+ * rtlanal.c (truncated_to_mode): Define it.
+ * simplify-rtx.c (simplify_unary_operation_1): Use it.
+
2006-02-28 Jeff Law <law@redhat.com>
* tree-chrec.c (chrec_convert_aggressive): Do not eliminate
diff --git a/gcc/combine.c b/gcc/combine.c
index 443b429976e..32d3f67df4f 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -457,6 +457,9 @@ static rtx gen_lowpart_or_truncate (enum machine_mode, rtx);
#undef RTL_HOOKS_REG_NUM_SIGN_BIT_COPIES
#define RTL_HOOKS_REG_NUM_SIGN_BIT_COPIES reg_num_sign_bit_copies_for_combine
+#undef RTL_HOOKS_REG_TRUNCATED_TO_MODE
+#define RTL_HOOKS_REG_TRUNCATED_TO_MODE reg_truncated_to_mode
+
static const struct rtl_hooks combine_rtl_hooks = RTL_HOOKS_INITIALIZER;
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 6e17a224621..9c088e92598 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1047,6 +1047,7 @@ extern unsigned int subreg_regno (rtx);
extern unsigned HOST_WIDE_INT nonzero_bits (rtx, enum machine_mode);
extern unsigned int num_sign_bit_copies (rtx, enum machine_mode);
extern bool constant_pool_constant_p (rtx);
+extern bool truncated_to_mode (enum machine_mode, rtx);
/* 1 if RTX is a subreg containing a reg that is already known to be
@@ -2277,8 +2278,9 @@ struct rtl_hooks
unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT *);
rtx (*reg_num_sign_bit_copies) (rtx, enum machine_mode, rtx, enum machine_mode,
unsigned int, unsigned int *);
+ bool (*reg_truncated_to_mode) (enum machine_mode, rtx);
- /* Whenever you add entries here, make sure you adjust hosthooks-def.h. */
+ /* Whenever you add entries here, make sure you adjust rtlhooks-def.h. */
};
/* Each pass can provide its own. */
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index d8c9fb8a1bf..bbf7e71bf73 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -4808,6 +4808,16 @@ get_condition (rtx jump, rtx *earliest, int allow_cc_mode, int valid_at_insn_p)
allow_cc_mode, valid_at_insn_p);
}
+/* Suppose that truncation from the machine mode of X to MODE is not a
+ no-op. See if there is anything special about X so that we can
+ assume it already contains a truncated value of MODE. */
+
+bool
+truncated_to_mode (enum machine_mode mode, rtx x)
+{
+ return REG_P (x) && rtl_hooks.reg_truncated_to_mode (mode, x);
+}
+
/* Initialize non_rtx_starting_operands, which is used to speed up
for_each_rtx. */
diff --git a/gcc/rtlhooks-def.h b/gcc/rtlhooks-def.h
index b6c07fb76c1..748666c2dd0 100644
--- a/gcc/rtlhooks-def.h
+++ b/gcc/rtlhooks-def.h
@@ -27,6 +27,7 @@ Boston, MA 02110-1301, USA. */
#define RTL_HOOKS_GEN_LOWPART_NO_EMIT gen_lowpart_no_emit_general
#define RTL_HOOKS_REG_NONZERO_REG_BITS reg_nonzero_bits_general
#define RTL_HOOKS_REG_NUM_SIGN_BIT_COPIES reg_num_sign_bit_copies_general
+#define RTL_HOOKS_REG_TRUNCATED_TO_MODE reg_truncated_to_mode_general
/* The structure is defined in rtl.h. */
#define RTL_HOOKS_INITIALIZER { \
@@ -34,6 +35,7 @@ Boston, MA 02110-1301, USA. */
RTL_HOOKS_GEN_LOWPART_NO_EMIT, \
RTL_HOOKS_REG_NONZERO_REG_BITS, \
RTL_HOOKS_REG_NUM_SIGN_BIT_COPIES, \
+ RTL_HOOKS_REG_TRUNCATED_TO_MODE, \
}
extern rtx gen_lowpart_general (enum machine_mode, rtx);
@@ -45,5 +47,6 @@ extern rtx reg_nonzero_bits_general (rtx, enum machine_mode, rtx,
extern rtx reg_num_sign_bit_copies_general (rtx, enum machine_mode, rtx,
enum machine_mode,
unsigned int, unsigned int *);
+extern bool reg_truncated_to_mode_general (enum machine_mode, rtx);
#endif /* GCC_RTL_HOOKS_DEF_H */
diff --git a/gcc/rtlhooks.c b/gcc/rtlhooks.c
index 0034da783fa..ece7198f9a2 100644
--- a/gcc/rtlhooks.c
+++ b/gcc/rtlhooks.c
@@ -117,6 +117,13 @@ reg_nonzero_bits_general (rtx x ATTRIBUTE_UNUSED,
return NULL;
}
+bool
+reg_truncated_to_mode_general (enum machine_mode mode ATTRIBUTE_UNUSED,
+ rtx x ATTRIBUTE_UNUSED)
+{
+ return false;
+}
+
/* Assuming that X is an rtx (e.g., MEM, REG or SUBREG) for a fixed-point
number, return an rtx (MEM, SUBREG, or CONST_INT) that refers to the
least-significant part of X.
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index e84beda68b4..aded68e52df 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -631,14 +631,17 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
GET_MODE (XEXP (SUBREG_REG (op), 0)));
/* If we know that the value is already truncated, we can
- replace the TRUNCATE with a SUBREG if TRULY_NOOP_TRUNCATION
- is nonzero for the corresponding modes. But don't do this
- for an (LSHIFTRT (MULT ...)) since this will cause problems
- with the umulXi3_highpart patterns. */
- if (TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
+ replace the TRUNCATE with a SUBREG. Note that this is also
+ valid if TRULY_NOOP_TRUNCATION is false for the corresponding
+ modes we just have to apply a different definition for
+ truncation. But don't do this for an (LSHIFTRT (MULT ...))
+ since this will cause problems with the umulXi3_highpart
+ patterns. */
+ if ((TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
GET_MODE_BITSIZE (GET_MODE (op)))
- && num_sign_bit_copies (op, GET_MODE (op))
- >= (unsigned int) (GET_MODE_BITSIZE (mode) + 1)
+ ? (num_sign_bit_copies (op, GET_MODE (op))
+ >= (unsigned int) (GET_MODE_BITSIZE (mode) + 1))
+ : truncated_to_mode (mode, op))
&& ! (GET_CODE (op) == LSHIFTRT
&& GET_CODE (XEXP (op, 0)) == MULT))
return rtl_hooks.gen_lowpart_no_emit (mode, op);