summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2011-04-21 09:37:44 +0000
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2011-04-21 09:37:44 +0000
commit7d7d7bd2b99b0a9e5d19c50590cfbad178775cab (patch)
treeeaf6c68a5f7e3822c501346ded206279f68c7bec
parent8574477d2863a9e5c9d8aad13f6033f246874764 (diff)
downloadgcc-7d7d7bd2b99b0a9e5d19c50590cfbad178775cab.tar.gz
gcc/
* target.def (cannot_force_const_mem): Add a mode argument. * doc/tm.texi.in (TARGET_CANNOT_FORCE_CONST_MEM): Update accordingly. * doc/tm.texi: Regenerate. * hooks.h (hook_bool_mode_rtx_false): Declare. * hooks.c (hook_bool_mode_const_rtx_false): Fix commentary. (hook_bool_mode_const_rtx_true): Likewise. (hook_bool_mode_rtx_false): New function. * reload.c (CONST_POOL_OK_P): Take a mode argument and require it to be non-VOID. Update call to cannot_force_const_mem. (find_reloads): Update accordingly. * varasm.c (force_const_mem): Update call to cannot_force_const_mem. * config/alpha/alpha.c (alpha_cannot_force_const_mem): Add a mode argument. * config/arm/arm-protos.h (arm_cannot_force_const_mem): Likewise. * config/arm/arm.h (LEGITIMATE_CONSTANT_P): Update call. * config/arm/arm.c (arm_cannot_force_const_mem): Add a mode argument. * config/bfin/bfin.c (bfin_cannot_force_const_mem): Likewise. * config/frv/frv.c (frv_cannot_force_const_mem): Likewise. * config/i386/i386.c (ix86_cannot_force_const_mem): Likewise. * config/ia64/ia64.c (ia64_cannot_force_const_mem): Likewise. * config/m68k/m68k.c (TARGET_CANNOT_FORCE_CONST_MEM): Redefine to... (m68k_cannot_force_const_mem): ...this new function. * config/mips/mips.c (mips_cannot_force_const_mem): Add a mode argument. (mips_const_insns, mips_legitimize_const_move): Update calls. (mips_secondary_reload_class): Likewise. * config/pa/pa.c (TARGET_CANNOT_FORCE_CONST_MEM): Redefine to... (pa_cannot_force_const_mem): ...this new function. * config/rs6000/rs6000.c (TARGET_CANNOT_FORCE_CONST_MEM): Reefine to... (rs6000_cannot_force_const_mem): ...this new function. * config/s390/s390.c (s390_cannot_force_const_mem): Add a mode argument. * config/sparc/sparc.c (sparc_cannot_force_const_mem): Likewise. * config/xtensa/xtensa.c (TARGET_CANNOT_FORCE_CONST_MEM): Redefine to... (xtensa_cannot_force_const_mem): ...this new function. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@172813 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog40
-rw-r--r--gcc/config/alpha/alpha.c2
-rw-r--r--gcc/config/arm/arm-protos.h2
-rw-r--r--gcc/config/arm/arm.c2
-rw-r--r--gcc/config/arm/arm.h2
-rw-r--r--gcc/config/bfin/bfin.c3
-rw-r--r--gcc/config/frv/frv.c5
-rw-r--r--gcc/config/i386/i386.c2
-rw-r--r--gcc/config/ia64/ia64.c6
-rw-r--r--gcc/config/m68k/m68k.c11
-rw-r--r--gcc/config/mips/mips.c8
-rw-r--r--gcc/config/pa/pa.c11
-rw-r--r--gcc/config/rs6000/rs6000.c11
-rw-r--r--gcc/config/s390/s390.c8
-rw-r--r--gcc/config/sparc/sparc.c10
-rw-r--r--gcc/config/xtensa/xtensa.c12
-rw-r--r--gcc/doc/tm.texi8
-rw-r--r--gcc/doc/tm.texi.in6
-rw-r--r--gcc/hooks.c12
-rw-r--r--gcc/hooks.h1
-rw-r--r--gcc/reload.c26
-rw-r--r--gcc/target.def4
-rw-r--r--gcc/varasm.c2
23 files changed, 143 insertions, 51 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9a2cd4f8106..3f346fc8dd8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,43 @@
+2011-04-21 Richard Sandiford <richard.sandiford@linaro.org>
+
+ * target.def (cannot_force_const_mem): Add a mode argument.
+ * doc/tm.texi.in (TARGET_CANNOT_FORCE_CONST_MEM): Update accordingly.
+ * doc/tm.texi: Regenerate.
+ * hooks.h (hook_bool_mode_rtx_false): Declare.
+ * hooks.c (hook_bool_mode_const_rtx_false): Fix commentary.
+ (hook_bool_mode_const_rtx_true): Likewise.
+ (hook_bool_mode_rtx_false): New function.
+ * reload.c (CONST_POOL_OK_P): Take a mode argument and require it
+ to be non-VOID. Update call to cannot_force_const_mem.
+ (find_reloads): Update accordingly.
+ * varasm.c (force_const_mem): Update call to cannot_force_const_mem.
+ * config/alpha/alpha.c (alpha_cannot_force_const_mem): Add a mode
+ argument.
+ * config/arm/arm-protos.h (arm_cannot_force_const_mem): Likewise.
+ * config/arm/arm.h (LEGITIMATE_CONSTANT_P): Update call.
+ * config/arm/arm.c (arm_cannot_force_const_mem): Add a mode argument.
+ * config/bfin/bfin.c (bfin_cannot_force_const_mem): Likewise.
+ * config/frv/frv.c (frv_cannot_force_const_mem): Likewise.
+ * config/i386/i386.c (ix86_cannot_force_const_mem): Likewise.
+ * config/ia64/ia64.c (ia64_cannot_force_const_mem): Likewise.
+ * config/m68k/m68k.c (TARGET_CANNOT_FORCE_CONST_MEM): Redefine to...
+ (m68k_cannot_force_const_mem): ...this new function.
+ * config/mips/mips.c (mips_cannot_force_const_mem): Add a mode
+ argument.
+ (mips_const_insns, mips_legitimize_const_move): Update calls.
+ (mips_secondary_reload_class): Likewise.
+ * config/pa/pa.c (TARGET_CANNOT_FORCE_CONST_MEM): Redefine to...
+ (pa_cannot_force_const_mem): ...this new function.
+ * config/rs6000/rs6000.c (TARGET_CANNOT_FORCE_CONST_MEM): Reefine
+ to...
+ (rs6000_cannot_force_const_mem): ...this new function.
+ * config/s390/s390.c (s390_cannot_force_const_mem): Add a mode
+ argument.
+ * config/sparc/sparc.c (sparc_cannot_force_const_mem): Likewise.
+ * config/xtensa/xtensa.c (TARGET_CANNOT_FORCE_CONST_MEM): Redefine
+ to...
+ (xtensa_cannot_force_const_mem): ...this new function.
+
2011-04-20 Nathan Froyd <froydnj@codesourcery.com>
* config/mips/mips.c (mips16_build_function_stub): Call
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index 5e85e2be471..ba0dfe633cc 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -1095,7 +1095,7 @@ alpha_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
should never be spilling symbolic operands to the constant pool, ever. */
static bool
-alpha_cannot_force_const_mem (rtx x)
+alpha_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
{
enum rtx_code code = GET_CODE (x);
return code == SYMBOL_REF || code == LABEL_REF || code == CONST;
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index 190fec0ecef..da3241d2bf3 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -82,7 +82,7 @@ extern void neon_disambiguate_copy (rtx *, rtx *, rtx *, unsigned int);
extern enum reg_class coproc_secondary_reload_class (enum machine_mode, rtx,
bool);
extern bool arm_tls_referenced_p (rtx);
-extern bool arm_cannot_force_const_mem (rtx);
+extern bool arm_cannot_force_const_mem (enum machine_mode, rtx);
extern int cirrus_memory_offset (rtx);
extern int arm_coproc_mem_operand (rtx, bool);
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 46255cbeebb..0f944fd869d 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -6500,7 +6500,7 @@ arm_tls_referenced_p (rtx x)
/* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
bool
-arm_cannot_force_const_mem (rtx x)
+arm_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
{
rtx base, offset;
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index e45b9274323..76efdec8e50 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -1763,7 +1763,7 @@ typedef struct
|| flag_pic)
#define LEGITIMATE_CONSTANT_P(X) \
- (!arm_cannot_force_const_mem (X) \
+ (!arm_cannot_force_const_mem (VOIDmode, X) \
&& (TARGET_32BIT ? ARM_LEGITIMATE_CONSTANT_P (X) \
: THUMB_LEGITIMATE_CONSTANT_P (X)))
diff --git a/gcc/config/bfin/bfin.c b/gcc/config/bfin/bfin.c
index 5d0843748a8..2a9730fa902 100644
--- a/gcc/config/bfin/bfin.c
+++ b/gcc/config/bfin/bfin.c
@@ -3055,7 +3055,8 @@ bfin_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
another way. */
static bool
-bfin_cannot_force_const_mem (rtx x ATTRIBUTE_UNUSED)
+bfin_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED,
+ rtx x ATTRIBUTE_UNUSED)
{
/* We have only one class of non-legitimate constants, and our movsi
expander knows how to handle them. Dropping these constants into the
diff --git a/gcc/config/frv/frv.c b/gcc/config/frv/frv.c
index 09137654ad1..5b0c0847e15 100644
--- a/gcc/config/frv/frv.c
+++ b/gcc/config/frv/frv.c
@@ -372,7 +372,7 @@ static int frv_memory_move_cost (enum machine_mode,
static void frv_asm_out_constructor (rtx, int);
static void frv_asm_out_destructor (rtx, int);
static bool frv_function_symbol_referenced_p (rtx);
-static bool frv_cannot_force_const_mem (rtx);
+static bool frv_cannot_force_const_mem (enum machine_mode, rtx);
static const char *unspec_got_name (int);
static void frv_output_const_unspec (FILE *,
const struct frv_unspec *);
@@ -616,7 +616,8 @@ frv_const_unspec_p (rtx x, struct frv_unspec *unspec)
4. In many cases, it's more efficient to calculate the constant in-line. */
static bool
-frv_cannot_force_const_mem (rtx x ATTRIBUTE_UNUSED)
+frv_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED,
+ rtx x ATTRIBUTE_UNUSED)
{
return TARGET_FDPIC;
}
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 7cb7c2db017..c4b18ef56ad 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -12005,7 +12005,7 @@ legitimate_constant_p (rtx x)
is checked above. */
static bool
-ix86_cannot_force_const_mem (rtx x)
+ix86_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
{
/* We can always put integral constants and vectors in memory. */
switch (GET_CODE (x))
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index 5f22b17ef67..60832793017 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -316,7 +316,7 @@ static rtx ia64_struct_value_rtx (tree, int);
static tree ia64_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
static bool ia64_scalar_mode_supported_p (enum machine_mode mode);
static bool ia64_vector_mode_supported_p (enum machine_mode mode);
-static bool ia64_cannot_force_const_mem (rtx);
+static bool ia64_cannot_force_const_mem (enum machine_mode, rtx);
static const char *ia64_mangle_type (const_tree);
static const char *ia64_invalid_conversion (const_tree, const_tree);
static const char *ia64_invalid_unary_op (int, const_tree);
@@ -1014,9 +1014,9 @@ ia64_legitimate_constant_p (rtx x)
/* Don't allow TLS addresses to get spilled to memory. */
static bool
-ia64_cannot_force_const_mem (rtx x)
+ia64_cannot_force_const_mem (enum machine_mode mode, rtx x)
{
- if (GET_MODE (x) == RFmode)
+ if (mode == RFmode)
return true;
return tls_symbolic_operand_type (x) != 0;
}
diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
index 654c0e5cfbc..7553183d541 100644
--- a/gcc/config/m68k/m68k.c
+++ b/gcc/config/m68k/m68k.c
@@ -163,6 +163,7 @@ static void m68k_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
const_tree, bool);
static rtx m68k_function_arg (CUMULATIVE_ARGS *, enum machine_mode,
const_tree, bool);
+static bool m68k_cannot_force_const_mem (enum machine_mode mode, rtx x);
/* Specify the identification number of the library being built */
@@ -256,7 +257,7 @@ const char *m68k_library_id_string = "_current_shared_library_a5_offset_";
#define TARGET_STRUCT_VALUE_RTX m68k_struct_value_rtx
#undef TARGET_CANNOT_FORCE_CONST_MEM
-#define TARGET_CANNOT_FORCE_CONST_MEM m68k_illegitimate_symbolic_constant_p
+#define TARGET_CANNOT_FORCE_CONST_MEM m68k_cannot_force_const_mem
#undef TARGET_FUNCTION_OK_FOR_SIBCALL
#define TARGET_FUNCTION_OK_FOR_SIBCALL m68k_ok_for_sibcall_p
@@ -1937,6 +1938,14 @@ m68k_illegitimate_symbolic_constant_p (rtx x)
return m68k_tls_reference_p (x, false);
}
+/* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
+
+static bool
+m68k_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
+{
+ return m68k_illegitimate_symbolic_constant_p (x);
+}
+
/* Return true if X is a legitimate constant address that can reach
bytes in the range [X, X + REACH). STRICT_P says whether we need
strict checking. */
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 2dd90e28ec2..f6a4ec98cbe 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -1997,7 +1997,7 @@ mips_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
/* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
static bool
-mips_cannot_force_const_mem (rtx x)
+mips_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
{
enum mips_symbol_type type;
rtx base, offset;
@@ -2387,7 +2387,7 @@ mips_const_insns (rtx x)
{
if (SMALL_INT (offset))
return n + 1;
- else if (!targetm.cannot_force_const_mem (x))
+ else if (!targetm.cannot_force_const_mem (GET_MODE (x), x))
return n + 1 + mips_build_integer (codes, INTVAL (offset));
}
}
@@ -3090,7 +3090,7 @@ mips_legitimize_const_move (enum machine_mode mode, rtx dest, rtx src)
forced into memory, as it usually produces better code. */
split_const (src, &base, &offset);
if (offset != const0_rtx
- && (targetm.cannot_force_const_mem (src)
+ && (targetm.cannot_force_const_mem (mode, src)
|| (!TARGET_MIPS16 && can_create_pseudo_p ())))
{
base = mips_force_temporary (dest, base);
@@ -11087,7 +11087,7 @@ mips_secondary_reload_class (enum reg_class rclass,
/* In this case we can use mtc1, mfc1, dmtc1 or dmfc1. */
return NO_REGS;
- if (CONSTANT_P (x) && !targetm.cannot_force_const_mem (x))
+ if (CONSTANT_P (x) && !targetm.cannot_force_const_mem (mode, x))
/* We can force the constant to memory and use lwc1
and ldc1. As above, we will use pairs of lwc1s if
ldc1 is not supported. */
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index aeb80613383..ab0fe6a8a09 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -187,6 +187,7 @@ static bool pa_can_eliminate (const int, const int);
static void pa_conditional_register_usage (void);
static enum machine_mode pa_c_mode_for_suffix (char);
static section *pa_function_section (tree, enum node_frequency, bool, bool);
+static bool pa_cannot_force_const_mem (enum machine_mode, rtx);
/* The following extra sections are only used for SOM. */
static GTY(()) section *som_readonly_data_section;
@@ -369,7 +370,7 @@ static const struct default_options pa_option_optimization_table[] =
#define TARGET_SCALAR_MODE_SUPPORTED_P pa_scalar_mode_supported_p
#undef TARGET_CANNOT_FORCE_CONST_MEM
-#define TARGET_CANNOT_FORCE_CONST_MEM pa_tls_referenced_p
+#define TARGET_CANNOT_FORCE_CONST_MEM pa_cannot_force_const_mem
#undef TARGET_SECONDARY_RELOAD
#define TARGET_SECONDARY_RELOAD pa_secondary_reload
@@ -1563,6 +1564,14 @@ pa_tls_referenced_p (rtx x)
return for_each_rtx (&x, &pa_tls_symbol_ref_1, 0);
}
+/* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
+
+static bool
+pa_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
+{
+ return pa_tls_referenced_p (x);
+}
+
/* Emit insns to move operands[1] into operands[0].
Return 1 if we have written out everything that needs to be done to
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 8182bf0b70d..201c2fb5cda 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -1212,6 +1212,7 @@ static enum machine_mode rs6000_eh_return_filter_mode (void);
static bool rs6000_can_eliminate (const int, const int);
static void rs6000_conditional_register_usage (void);
static void rs6000_trampoline_init (rtx, tree, rtx);
+static bool rs6000_cannot_force_const_mem (enum machine_mode, rtx);
/* Hash table stuff for keeping track of TOC entries. */
@@ -1388,7 +1389,7 @@ static const struct default_options rs6000_option_optimization_table[] =
#define TARGET_HAVE_TLS HAVE_AS_TLS
#undef TARGET_CANNOT_FORCE_CONST_MEM
-#define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
+#define TARGET_CANNOT_FORCE_CONST_MEM rs6000_cannot_force_const_mem
#undef TARGET_DELEGITIMIZE_ADDRESS
#define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
@@ -6619,6 +6620,14 @@ rs6000_tls_referenced_p (rtx x)
return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
}
+/* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
+
+static bool
+rs6000_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
+{
+ return rs6000_tls_referenced_p (x);
+}
+
/* Return 1 if *X is a thread-local symbol. This is the same as
rs6000_tls_symbol_ref except for the type of the unused argument. */
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index caee07758fe..8454333f2ed 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -2810,7 +2810,7 @@ legitimate_constant_p (rtx op)
not constant (TLS) or not known at final link time (PIC). */
static bool
-s390_cannot_force_const_mem (rtx x)
+s390_cannot_force_const_mem (enum machine_mode mode, rtx x)
{
switch (GET_CODE (x))
{
@@ -2832,11 +2832,11 @@ s390_cannot_force_const_mem (rtx x)
return flag_pic != 0;
case CONST:
- return s390_cannot_force_const_mem (XEXP (x, 0));
+ return s390_cannot_force_const_mem (mode, XEXP (x, 0));
case PLUS:
case MINUS:
- return s390_cannot_force_const_mem (XEXP (x, 0))
- || s390_cannot_force_const_mem (XEXP (x, 1));
+ return s390_cannot_force_const_mem (mode, XEXP (x, 0))
+ || s390_cannot_force_const_mem (mode, XEXP (x, 1));
case UNSPEC:
switch (XINT (x, 1))
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 03b5e668f7b..b112f7e3d47 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -417,7 +417,7 @@ static void sparc_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
static bool sparc_can_output_mi_thunk (const_tree, HOST_WIDE_INT,
HOST_WIDE_INT, const_tree);
static struct machine_function * sparc_init_machine_status (void);
-static bool sparc_cannot_force_const_mem (rtx);
+static bool sparc_cannot_force_const_mem (enum machine_mode, rtx);
static rtx sparc_tls_get_addr (void);
static rtx sparc_tls_got (void);
static const char *get_some_local_dynamic_name (void);
@@ -2924,7 +2924,7 @@ reg_unused_after (rtx reg, rtx insn)
not constant (TLS) or not known at final link time (PIC). */
static bool
-sparc_cannot_force_const_mem (rtx x)
+sparc_cannot_force_const_mem (enum machine_mode mode, rtx x)
{
switch (GET_CODE (x))
{
@@ -2947,11 +2947,11 @@ sparc_cannot_force_const_mem (rtx x)
return flag_pic != 0;
case CONST:
- return sparc_cannot_force_const_mem (XEXP (x, 0));
+ return sparc_cannot_force_const_mem (mode, XEXP (x, 0));
case PLUS:
case MINUS:
- return sparc_cannot_force_const_mem (XEXP (x, 0))
- || sparc_cannot_force_const_mem (XEXP (x, 1));
+ return sparc_cannot_force_const_mem (mode, XEXP (x, 0))
+ || sparc_cannot_force_const_mem (mode, XEXP (x, 1));
case UNSPEC:
return true;
default:
diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c
index fe70270df86..2ffc39f7fd1 100644
--- a/gcc/config/xtensa/xtensa.c
+++ b/gcc/config/xtensa/xtensa.c
@@ -164,6 +164,7 @@ static rtx xtensa_static_chain (const_tree, bool);
static void xtensa_asm_trampoline_template (FILE *);
static void xtensa_trampoline_init (rtx, tree, rtx);
static bool xtensa_output_addr_const_extra (FILE *, rtx);
+static bool xtensa_cannot_force_const_mem (enum machine_mode, rtx);
static reg_class_t xtensa_preferred_reload_class (rtx, reg_class_t);
static reg_class_t xtensa_preferred_output_reload_class (rtx, reg_class_t);
@@ -285,7 +286,7 @@ static const struct default_options xtensa_option_optimization_table[] =
#define TARGET_HAVE_TLS (TARGET_THREADPTR && HAVE_AS_TLS)
#undef TARGET_CANNOT_FORCE_CONST_MEM
-#define TARGET_CANNOT_FORCE_CONST_MEM xtensa_tls_referenced_p
+#define TARGET_CANNOT_FORCE_CONST_MEM xtensa_cannot_force_const_mem
#undef TARGET_LEGITIMATE_ADDRESS_P
#define TARGET_LEGITIMATE_ADDRESS_P xtensa_legitimate_address_p
@@ -2014,6 +2015,15 @@ xtensa_tls_referenced_p (rtx x)
}
+/* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
+
+static bool
+xtensa_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
+{
+ return xtensa_tls_referenced_p (x);
+}
+
+
/* Return the debugger register number to use for 'regno'. */
int
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index de0381fcb1b..ec555517537 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -5553,10 +5553,12 @@ the semantics of these opaque @code{UNSPEC}s by converting them back
into their original form.
@end deftypefn
-@deftypefn {Target Hook} bool TARGET_CANNOT_FORCE_CONST_MEM (rtx @var{x})
+@deftypefn {Target Hook} bool TARGET_CANNOT_FORCE_CONST_MEM (enum machine_mode @var{mode}, rtx @var{x})
This hook should return true if @var{x} is of a form that cannot (or
-should not) be spilled to the constant pool. The default version of
-this hook returns false.
+should not) be spilled to the constant pool. @var{mode} is the mode
+of @var{x}.
+
+The default version of this hook returns false.
The primary reason to define this hook is to prevent reload from
deciding that a non-legitimate constant would be better reloaded
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 8ae45957663..1c96941f643 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -5533,8 +5533,10 @@ into their original form.
@hook TARGET_CANNOT_FORCE_CONST_MEM
This hook should return true if @var{x} is of a form that cannot (or
-should not) be spilled to the constant pool. The default version of
-this hook returns false.
+should not) be spilled to the constant pool. @var{mode} is the mode
+of @var{x}.
+
+The default version of this hook returns false.
The primary reason to define this hook is to prevent reload from
deciding that a non-legitimate constant would be better reloaded
diff --git a/gcc/hooks.c b/gcc/hooks.c
index 594e34408bd..a991980a987 100644
--- a/gcc/hooks.c
+++ b/gcc/hooks.c
@@ -85,7 +85,7 @@ hook_bool_mode_true (enum machine_mode mode ATTRIBUTE_UNUSED)
return true;
}
-/* Generic hook that takes (enum machine_mode, rtx) and returns false. */
+/* Generic hook that takes (enum machine_mode, const_rtx) and returns false. */
bool
hook_bool_mode_const_rtx_false (enum machine_mode mode ATTRIBUTE_UNUSED,
const_rtx value ATTRIBUTE_UNUSED)
@@ -93,7 +93,7 @@ hook_bool_mode_const_rtx_false (enum machine_mode mode ATTRIBUTE_UNUSED,
return false;
}
-/* Generic hook that takes (enum machine_mode, rtx) and returns true. */
+/* Generic hook that takes (enum machine_mode, const_rtx) and returns true. */
bool
hook_bool_mode_const_rtx_true (enum machine_mode mode ATTRIBUTE_UNUSED,
const_rtx value ATTRIBUTE_UNUSED)
@@ -101,6 +101,14 @@ hook_bool_mode_const_rtx_true (enum machine_mode mode ATTRIBUTE_UNUSED,
return true;
}
+/* Generic hook that takes (enum machine_mode, rtx) and returns false. */
+bool
+hook_bool_mode_rtx_false (enum machine_mode mode ATTRIBUTE_UNUSED,
+ rtx value ATTRIBUTE_UNUSED)
+{
+ return false;
+}
+
/* Generic hook that takes (FILE *, const char *) and does nothing. */
void
hook_void_FILEptr_constcharptr (FILE *a ATTRIBUTE_UNUSED, const char *b ATTRIBUTE_UNUSED)
diff --git a/gcc/hooks.h b/gcc/hooks.h
index 90e3a14ae9a..548dad34751 100644
--- a/gcc/hooks.h
+++ b/gcc/hooks.h
@@ -34,6 +34,7 @@ extern bool hook_bool_mode_false (enum machine_mode);
extern bool hook_bool_mode_true (enum machine_mode);
extern bool hook_bool_mode_const_rtx_false (enum machine_mode, const_rtx);
extern bool hook_bool_mode_const_rtx_true (enum machine_mode, const_rtx);
+extern bool hook_bool_mode_rtx_false (enum machine_mode, rtx);
extern bool hook_bool_tree_false (tree);
extern bool hook_bool_const_tree_false (const_tree);
extern bool hook_bool_tree_true (tree);
diff --git a/gcc/reload.c b/gcc/reload.c
index 582371f212d..372eccc0fb9 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -112,11 +112,13 @@ a register with any other reload. */
#include "target.h"
#include "ira.h"
-/* True if X is a constant that can be forced into the constant pool. */
-#define CONST_POOL_OK_P(X) \
- (CONSTANT_P (X) \
+/* True if X is a constant that can be forced into the constant pool.
+ MODE is the mode of the operand, or VOIDmode if not known. */
+#define CONST_POOL_OK_P(MODE, X) \
+ ((MODE) != VOIDmode \
+ && CONSTANT_P (X) \
&& GET_CODE (X) != HIGH \
- && !targetm.cannot_force_const_mem (X))
+ && !targetm.cannot_force_const_mem (MODE, X))
/* True if C is a non-empty register class that has too few registers
to be safely used as a reload target class. */
@@ -3246,7 +3248,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
&& REGNO (operand) >= FIRST_PSEUDO_REGISTER
&& reg_renumber[REGNO (operand)] < 0))
win = 1;
- if (CONST_POOL_OK_P (operand))
+ if (CONST_POOL_OK_P (operand_mode[i], operand))
badop = 0;
constmemok = 1;
break;
@@ -3308,7 +3310,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
&& offsettable_memref_p (reg_equiv_mem (REGNO (operand))))
|| (reg_equiv_address (REGNO (operand)) != 0))))
win = 1;
- if (CONST_POOL_OK_P (operand)
+ if (CONST_POOL_OK_P (operand_mode[i], operand)
|| MEM_P (operand))
badop = 0;
constmemok = 1;
@@ -3424,7 +3426,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
/* If we didn't already win, we can reload
constants via force_const_mem, and other
MEMs by reloading the address like for 'o'. */
- if (CONST_POOL_OK_P (operand)
+ if (CONST_POOL_OK_P (operand_mode[i], operand)
|| MEM_P (operand))
badop = 0;
constmemok = 1;
@@ -3503,12 +3505,11 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
an early reload pass. Note that the test here is
precisely the same as in the code below that calls
force_const_mem. */
- if (CONST_POOL_OK_P (operand)
+ if (CONST_POOL_OK_P (operand_mode[i], operand)
&& ((targetm.preferred_reload_class (operand,
this_alternative[i])
== NO_REGS)
- || no_input_reloads)
- && operand_mode[i] != VOIDmode)
+ || no_input_reloads))
{
const_to_mem = 1;
if (this_alternative[i] != NO_REGS)
@@ -3911,11 +3912,10 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
op = XEXP (op, 1);
}
- if (CONST_POOL_OK_P (op)
+ if (CONST_POOL_OK_P (mode, op)
&& ((targetm.preferred_reload_class (op, goal_alternative[i])
== NO_REGS)
- || no_input_reloads)
- && mode != VOIDmode)
+ || no_input_reloads))
{
int this_address_reloaded;
rtx tem = force_const_mem (mode, op);
diff --git a/gcc/target.def b/gcc/target.def
index b25ca270edd..ce01faa92d5 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -1295,8 +1295,8 @@ DEFHOOK
DEFHOOK
(cannot_force_const_mem,
"",
- bool, (rtx x),
- hook_bool_rtx_false)
+ bool, (enum machine_mode mode, rtx x),
+ hook_bool_mode_rtx_false)
DEFHOOK_UNDOC
(cannot_copy_insn_p,
diff --git a/gcc/varasm.c b/gcc/varasm.c
index e60c95eafbe..8755dded36e 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -3476,7 +3476,7 @@ force_const_mem (enum machine_mode mode, rtx x)
void **slot;
/* If we're not allowed to drop X into the constant pool, don't. */
- if (targetm.cannot_force_const_mem (x))
+ if (targetm.cannot_force_const_mem (mode, x))
return NULL_RTX;
/* Record that this function has used a constant pool entry. */