===================================================================
@@ -1348,8 +1348,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,
===================================================================
@@ -5527,8 +5527,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
===================================================================
@@ -5573,10 +5573,12 @@ the semantics of these opaque @code{UNSP
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
===================================================================
@@ -34,6 +34,7 @@ extern bool hook_bool_mode_false (enum m
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_mode_uhwi_false (enum machine_mode,
unsigned HOST_WIDE_INT);
extern bool hook_bool_tree_false (tree);
===================================================================
@@ -85,7 +85,7 @@ hook_bool_mode_true (enum machine_mode m
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 mac
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)
@@ -110,6 +110,14 @@ hook_bool_mode_uhwi_false (enum machine_
return false;
}
+/* 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)
===================================================================
@@ -112,11 +112,13 @@ #define REG_OK_STRICT
#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
&& 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
&& 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
/* 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
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
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);
===================================================================
@@ -3508,7 +3508,7 @@ force_const_mem (enum machine_mode mode,
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. */
===================================================================
@@ -1095,7 +1095,7 @@ alpha_legitimize_address (rtx x, rtx old
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;
===================================================================
@@ -81,7 +81,7 @@ extern void neon_disambiguate_copy (rtx
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);
===================================================================
@@ -1772,7 +1772,7 @@ #define THUMB_LEGITIMATE_CONSTANT_P(X) \
|| 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)))
===================================================================
@@ -6555,7 +6555,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;
===================================================================
@@ -3055,7 +3055,8 @@ bfin_legitimate_address_p (enum machine_
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
===================================================================
@@ -372,7 +372,7 @@ static int frv_memory_move_cost (enum
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_un
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;
}
===================================================================
@@ -12020,7 +12020,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))
===================================================================
@@ -316,7 +316,7 @@ static rtx ia64_struct_value_rtx (tree,
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;
}
===================================================================
@@ -163,6 +163,7 @@ static void m68k_function_arg_advance (C
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 @@ #define TARGET_PROMOTE_PROTOTYPES hook_b
#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
@@ -1982,6 +1983,14 @@ m68k_illegitimate_symbolic_constant_p (r
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. */
===================================================================
@@ -1997,7 +1997,7 @@ mips_tls_symbol_ref_1 (rtx *x, void *dat
/* 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
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);
@@ -11080,7 +11080,7 @@ mips_secondary_reload_class (enum reg_cl
/* 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. */
===================================================================
@@ -187,6 +187,7 @@ static bool pa_can_eliminate (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 @@ #define TARGET_GIMPLIFY_VA_ARG_EXPR hppa
#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
@@ -1590,6 +1591,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
===================================================================
@@ -1212,6 +1212,7 @@ static enum machine_mode rs6000_eh_retur
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 @@ #define TARGET_ASM_ASSEMBLE_VISIBILITY r
#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. */
===================================================================
@@ -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))
===================================================================
@@ -417,7 +417,7 @@ static void sparc_output_mi_thunk (FILE
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);
@@ -2920,7 +2920,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))
{
@@ -2943,11 +2943,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:
===================================================================
@@ -164,6 +164,7 @@ static rtx xtensa_static_chain (const_tr
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 @@ #define TARGET_SECONDARY_RELOAD xtensa_s
#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
@@ -2016,6 +2017,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