+2011-04-21 Richard Sandiford <richard.sandiford@linaro.org>
+
+ * target.def (legitimate_constant_p): New hook.
+ * doc/tm.texi.in (LEGITIMATE_CONSTANT_P): Replace with...
+ (TARGET_LEGITIMATE_CONSTANT_P): ...this.
+ * doc/tm.texi: Regenerate.
+ * hooks.h (hook_bool_mode_rtx_true): Declare.
+ * hooks.c (hook_bool_mode_rtx_true): Define.
+ * system.h (LEGITIMATE_CONSTANT_P): Poison.
+ * calls.c (precompute_register_parameters): Replace uses of
+ LEGITIMATE_CONSTANT_P with targetm.legitimate_constant_p.
+ (emit_library_call_value_1): Likewise.
+ * expr.c (move_block_to_reg, can_store_by_pieces, emit_move_insn)
+ (compress_float_constant, emit_push_insn, expand_expr_real_1): Likewise.
+ * ira-costs.c (scan_one_insn): Likewise.
+ * recog.c (general_operand, immediate_operand): Likewise.
+ * reload.c (find_reloads_toplev, find_reloads_address_part): Likewise.
+ * reload1.c (init_eliminable_invariants): Likewise.
+
+ * config/alpha/alpha-protos.h (alpha_legitimate_constant_p): Add a
+ mode argument.
+ * config/alpha/alpha.h (LEGITIMATE_CONSTANT_P): Delete.
+ * config/alpha/alpha.c (alpha_legitimate_constant_p): Add a mode
+ argument.
+ (TARGET_LEGITIMATE_CONSTANT_P): Define.
+ * config/alpha/predicates.md (input_operand): Update call to
+ alpha_legitimate_constant_p.
+
+ * config/arm/arm-protos.h (arm_cannot_force_const_mem): Delete.
+ * config/arm/arm.h (ARM_LEGITIMATE_CONSTANT_P): Likewise.
+ (THUMB_LEGITIMATE_CONSTANT_P, LEGITIMATE_CONSTANT_P): Likewise.
+ * config/arm/arm.c (TARGET_LEGITIMATE_CONSTANT_P): Define.
+ (arm_legitimate_constant_p_1, thumb_legitimate_constant_p)
+ (arm_legitimate_constant_p): New functions.
+ (arm_cannot_force_const_mem): Make static.
+
+ * config/avr/avr.h (LEGITIMATE_CONSTANT_P): Delete.
+
+ * config/bfin/bfin-protos.h (bfin_legitimate_constant_p): Delete.
+ * config/bfin/bfin.h (LEGITIMATE_CONSTANT_P): Delete.
+ * config/bfin/bfin.c (expand_move): Use targetm.legitimate_constant_p
+ instead of bfin_legitimate_constant_p.
+ (bfin_legitimate_constant_p): Make static. Add a mode argument.
+ (TARGET_LEGITIMATE_CONSTANT_P): Define.
+
+ * config/cris/cris.h (LEGITIMATE_CONSTANT_P): Delete.
+
+ * config/fr30/fr30.h (LEGITIMATE_CONSTANT_P): Delete.
+
+ * config/frv/frv-protos.h (frv_legitimate_constant_p): Delete.
+ * config/frv/frv.h (LEGITIMATE_CONSTANT_P): Delete.
+ * config/frv/frv.c (TARGET_LEGITIMATE_CONSTANT_P): Define.
+ (frv_legitimate_constant_p): Make static. Add a mode argument.
+
+ * config/h8300/h8300-protos.h (h8300_legitimate_constant_p): Delete.
+ * config/h8300/h8300.h (LEGITIMATE_CONSTANT_P): Likewise.
+ * config/h8300/h8300.c (h8300_legitimate_constant_p): Likewise.
+
+ * config/i386/i386-protos.h (legitimate_constant_p): Delete.
+ * config/i386/i386.h (LEGITIMATE_CONSTANT_P): Likewise.
+ * config/i386/i386.c (legitimate_constant_p): Rename to...
+ (ix86_legitimate_constant_p): ...this. Make static. Add a mode
+ argument.
+ (ix86_cannot_force_const_mem): Update accordingly.
+ (ix86_legitimate_address_p): Likewise.
+ (TARGET_LEGITIMATE_CONSTANT_P): Define.
+ * config/i386/i386.md: Update commentary.
+
+ * config/ia64/ia64-protos.h (ia64_legitimate_constant_p): Delete.
+ * config/ia64/ia64.h (LEGITIMATE_CONSTANT_P): Likewise.
+ * config/ia64/ia64.c (TARGET_LEGITIMATE_CONSTANT_P): Define.
+ (ia64_legitimate_constant_p): Make static. Add a mode argument.
+
+ * config/iq2000/iq2000.h (LEGITIMATE_CONSTANT_P): Delete.
+
+ * config/lm32/lm32-protos.h (lm32_legitimate_constant_p): Delete.
+ * config/lm32/lm32.h (LEGITIMATE_CONSTANT_P): Likewise.
+ * config/lm32/lm32.c (TARGET_LEGITIMATE_CONSTANT_P): Define.
+ (lm32_legitimate_constant_p): Make static. Add a mode argument.
+
+ * config/m32c/m32c-protos.h (m32c_legitimate_constant_p): Delete.
+ * config/m32c/m32c.h (LEGITIMATE_CONSTANT_P): Likewise.
+ * config/m32c/m32c.c (m32c_legitimate_constant_p): Likewise.
+
+ * config/m32r/m32r.h (LEGITIMATE_CONSTANT_P): Delete.
+ * config/m32r/m32r.c (TARGET_LEGITIMATE_CONSTANT_P): Define.
+ (m32r_legitimate_constant_p): New function.
+
+ * config/m68k/m68k-protos.h (m68k_legitimate_constant_p): Declare.
+ * config/m68k/m68k.h (CONSTANT_ADDRESS_P): Call it instead of
+ LEGITIMATE_CONSTANT_P.
+ (LEGITIMATE_CONSTANT_P): Delete.
+ * config/m68k/m68k.c (m68k_expand_prologue): Call
+ m68k_legitimate_constant_p instead of LEGITIMATE_CONSTANT_P.
+ (m68k_legitimate_constant_p): New function.
+ * config/m68k/m68k.md: Update comments.
+
+ * config/mcore/mcore.h (LEGITIMATE_CONSTANT_P): Delete.
+ * config/mcore/mcore.c (TARGET_LEGITIMATE_CONSTANT_P): Define.
+ (mcore_legitimate_constant_p): New function.
+
+ * config/mep/mep-protos.h (mep_legitimate_constant_p): Delete.
+ * config/mep/mep.h (LEGITIMATE_CONSTANT_P): Likewise.
+ * config/mep/mep.c (mep_legitimate_constant_p): Make static.
+ Add a mode argument.
+ (mep_legitimate_address): Update accordingly.
+ (TARGET_LEGITIMATE_CONSTANT_P): Define.
+
+ * config/microblaze/microblaze-protos.h (microblaze_const_double_ok):
+ Delete.
+ * config/microblaze/microblaze.h (LEGITIMATE_CONSTANT_P): Likewise.
+ * config/microblaze/microblaze.c (microblaze_const_double_ok): Make
+ static. Check OP's mode for VOIDmode.
+ (microblaze_legitimate_constant_p): New function.
+ (TARGET_LEGITIMATE_CONSTANT_P): Define.
+
+ * config/mips/mips.h (LEGITIMATE_CONSTANT_P): Delete.
+ * config/mips/mips.c (mips_legitimate_constant_p): New function.
+ (mips_cannot_force_const_mem): Use it instead of LEGITIMATE_CONSTANT_P.
+ (TARGET_LEGITIMATE_CONSTANT_P): Define.
+ * config/mips/predicates.md: Update comments.
+
+ * config/mmix/mmix-protos.h (mmix_legitimate_constant_p): Delete.
+ * config/mmix/mmix.h (LEGITIMATE_CONSTANT_P): Likewise.
+ * config/mmix/mmix.c (TARGET_LEGITIMATE_CONSTANT_P): Define.
+ (mmix_legitimate_constant_p): Make static, return a bool, and take
+ a mode argument.
+ (mmix_print_operand_address): Update accordingly.
+
+ * config/mn10300/mn10300-protos.h (mn10300_legitimate_constant_p):
+ Delete.
+ * config/mn10300/mn10300.h (LEGITIMATE_CONSTANT_P): Likewise.
+ * config/mn10300/mn10300.c (mn10300_legitimate_constant_p):
+ Make static. Add a mode argument.
+ (TARGET_LEGITIMATE_CONSTANT_P): Define.
+
+ * config/moxie/moxie.h (LEGITIMATE_CONSTANT_P): Delete.
+
+ * config/pa/pa.h (LEGITIMATE_CONSTANT_P): Delete.
+ * config/pa/pa.c (TARGET_LEGITIMATE_CONSTANT_P): Define.
+ (pa_legitimate_constant_p): New function.
+
+ * config/picochip/picochip.h (LEGITIMATE_CONSTANT_P): Delete.
+
+ * config/pdp11/pdp11.h (LEGITIMATE_CONSTANT_P): Delete.
+ * config/pdp11/pdp11.c (TARGET_LEGITIMATE_CONSTANT_P): Define.
+ (pdp11_legitimate_constant_p): New function.
+
+ * config/rs6000/rs6000.h (LEGITIMATE_CONSTANT_P): Delete.
+ * config/rs6000/rs6000.c (TARGET_LEGITIMATE_CONSTANT_P): Define.
+ (rs6000_legitimate_constant_p): New function.
+
+ * config/rx/rx-protos.h (rx_is_legitimate_constant): Replace with...
+ (rx_legitimate_constant_p): ...this.
+ * config/rx/rx.h (LEGITIMATE_CONSTANT_P): Delete.
+ * config/rx/rx.c (rx_is_legitimate_constant): Replace with...
+ (rx_legitimate_constant_p): ...this.
+ (TARGET_LEGITIMATE_CONSTANT_P): Define.
+ * config/rx/rx.md (mov<register_modes:mode>): Update accordingly.
+
+ * config/s390/s390-protos.h (legitimate_constant_p): Delete.
+ * config/s390/s390.h (LEGITIMATE_CONSTANT_P): Likewise.
+ * config/s390/s390.c (legitimate_constant_p): Rename to...
+ (s390_legitimate_constant_p): ...this. Make static, return a bool,
+ and add a mode argument.
+ (TARGET_LEGITIMATE_CONSTANT_P): Define.
+
+ * config/score/score.h (LEGITIMATE_CONSTANT_P): Delete.
+
+ * config/sh/sh.h (LEGITIMATE_CONSTANT_P): Delete.
+ * config/sh/sh.c (TARGET_LEGITIMATE_CONSTANT_P): Define.
+ (sh_legitimate_constant_p): New function.
+
+ * config/sparc/sparc-protos.h (legitimate_constant_p): Delete.
+ * config/sparc/sparc.h (LEGITIMATE_CONSTANT_P): Delete.
+ * config/sparc/sparc.c (TARGET_LEGITIMATE_CONSTANT_P): Define.
+ (legitimate_constant_p): Rename to...
+ (sparc_legitimate_constant_p): ...this. Make static. Add a mode
+ argument.
+ (constant_address_p): Update accordingly.
+
+ * config/spu/spu-protos.h (spu_legitimate_constant_p): Add a mode
+ argument and return a bool.
+ * config/spu/spu.h (LEGITIMATE_CONSTANT_P): Delete.
+ * config/spu/spu.c (TARGET_LEGITIMATE_CONSTANT_P): Define.
+ (spu_legitimate_constant_p): Add a mode argument and return a bool.
+ (spu_rtx_costs): Update accordingly.
+ * config/spu/predicates.md (vec_imm_operand): Likewise.
+
+ * config/stormy16/stormy16.h (LEGITIMATE_CONSTANT_P): Delete.
+
+ * config/v850/v850.h (LEGITIMATE_CONSTANT_P): Delete.
+ * config/v850/v850.c (v850_legitimate_constant_p): New function.
+ (TARGET_LEGITIMATE_CONSTANT_P): Define.
+
+ * config/vax/vax-protos.h (legitimate_constant_p): Delete.
+ * config/vax/vax.h (LEGITIMATE_CONSTANT_P): Likewise.
+ * config/vax/vax.c (legitimate_constant_p): Likewise.
+
+ * config/xtensa/xtensa.h (LEGITIMATE_CONSTANT_P): Delete.
+ * config/xtensa/xtensa.c (TARGET_LEGITIMATE_CONSTANT_P): Define.
+ (xtensa_legitimate_constant_p): New function.
+
2011-04-21 Richard Sandiford <richard.sandiford@linaro.org>
* target.def (cannot_force_const_mem): Add a mode argument.
/* If the value is a non-legitimate constant, force it into a
pseudo now. TLS symbols sometimes need a call to resolve. */
if (CONSTANT_P (args[i].value)
- && !LEGITIMATE_CONSTANT_P (args[i].value))
+ && !targetm.legitimate_constant_p (args[i].mode, args[i].value))
args[i].value = force_reg (args[i].mode, args[i].value);
/* If we are to promote the function arg to a wider mode,
/* Make sure it is a reasonable operand for a move or push insn. */
if (!REG_P (addr) && !MEM_P (addr)
- && ! (CONSTANT_P (addr) && LEGITIMATE_CONSTANT_P (addr)))
+ && !(CONSTANT_P (addr)
+ && targetm.legitimate_constant_p (Pmode, addr)))
addr = force_operand (addr, NULL_RTX);
argvec[count].value = addr;
/* Make sure it is a reasonable operand for a move or push insn. */
if (!REG_P (val) && !MEM_P (val)
- && ! (CONSTANT_P (val) && LEGITIMATE_CONSTANT_P (val)))
+ && !(CONSTANT_P (val) && targetm.legitimate_constant_p (mode, val)))
val = force_operand (val, NULL_RTX);
if (pass_by_reference (&args_so_far, mode, NULL_TREE, 1))
extern rtx alpha_tablejump_addr_vec (rtx);
extern rtx alpha_tablejump_best_label (rtx);
-extern bool alpha_legitimate_constant_p (rtx);
+extern bool alpha_legitimate_constant_p (enum machine_mode, rtx);
extern rtx alpha_legitimize_reload_address (rtx, enum machine_mode,
int, int, int);
*p1 = i1;
}
-/* Implement LEGITIMATE_CONSTANT_P. This is all constants for which we
- are willing to load the value into a register via a move pattern.
+/* Implement TARGET_LEGITIMATE_CONSTANT_P. This is all constants for which
+ we are willing to load the value into a register via a move pattern.
Normally this is all symbolic constants, integral constants that
take three or fewer instructions, and floating-point zero. */
bool
-alpha_legitimate_constant_p (rtx x)
+alpha_legitimate_constant_p (enum machine_mode mode, rtx x)
{
- enum machine_mode mode = GET_MODE (x);
HOST_WIDE_INT i0, i1;
switch (GET_CODE (x))
#define TARGET_FUNCTION_OK_FOR_SIBCALL alpha_function_ok_for_sibcall
#undef TARGET_CANNOT_COPY_INSN_P
#define TARGET_CANNOT_COPY_INSN_P alpha_cannot_copy_insn_p
+#undef TARGET_LEGITIMATE_CONSTANT_P
+#define TARGET_LEGITIMATE_CONSTANT_P alpha_legitimate_constant_p
#undef TARGET_CANNOT_FORCE_CONST_MEM
#define TARGET_CANNOT_FORCE_CONST_MEM alpha_cannot_force_const_mem
(CONST_INT_P (X) \
&& (unsigned HOST_WIDE_INT) (INTVAL (X) + 0x8000) < 0x10000)
-/* Include all constant integers and constant doubles, but not
- floating-point, except for floating-point zero. */
-
-#define LEGITIMATE_CONSTANT_P alpha_legitimate_constant_p
-
/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
and check its validity for a certain class.
We have two alternate definitions for each of them.
case CONST_VECTOR:
if (reload_in_progress || reload_completed)
- return alpha_legitimate_constant_p (op);
+ return alpha_legitimate_constant_p (mode, op);
return op == CONST0_RTX (mode);
case CONST_INT:
if (mode == QImode || mode == HImode)
return true;
if (reload_in_progress || reload_completed)
- return alpha_legitimate_constant_p (op);
+ return alpha_legitimate_constant_p (mode, op);
return add_operand (op, mode);
default:
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 (enum machine_mode, rtx);
extern int cirrus_memory_offset (rtx);
extern int arm_coproc_mem_operand (rtx, bool);
static void arm_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
tree);
static bool arm_have_conditional_execution (void);
+static bool arm_cannot_force_const_mem (enum machine_mode, rtx);
+static bool arm_legitimate_constant_p (enum machine_mode, rtx);
static bool arm_rtx_costs_1 (rtx, enum rtx_code, int*, bool);
static bool arm_size_rtx_costs (rtx, enum rtx_code, enum rtx_code, int *);
static bool arm_slowmul_rtx_costs (rtx, enum rtx_code, enum rtx_code, int *, bool);
#undef TARGET_HAVE_CONDITIONAL_EXECUTION
#define TARGET_HAVE_CONDITIONAL_EXECUTION arm_have_conditional_execution
+#undef TARGET_LEGITIMATE_CONSTANT_P
+#define TARGET_LEGITIMATE_CONSTANT_P arm_legitimate_constant_p
+
#undef TARGET_CANNOT_FORCE_CONST_MEM
#define TARGET_CANNOT_FORCE_CONST_MEM arm_cannot_force_const_mem
return for_each_rtx (&x, arm_tls_operand_p_1, NULL);
}
+/* Implement TARGET_LEGITIMATE_CONSTANT_P.
+
+ On the ARM, allow any integer (invalid ones are removed later by insn
+ patterns), nice doubles and symbol_refs which refer to the function's
+ constant pool XXX.
+
+ When generating pic allow anything. */
+
+static bool
+arm_legitimate_constant_p_1 (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
+{
+ return flag_pic || !label_mentioned_p (x);
+}
+
+static bool
+thumb_legitimate_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
+{
+ return (GET_CODE (x) == CONST_INT
+ || GET_CODE (x) == CONST_DOUBLE
+ || CONSTANT_ADDRESS_P (x)
+ || flag_pic);
+}
+
+static bool
+arm_legitimate_constant_p (enum machine_mode mode, rtx x)
+{
+ return (!arm_cannot_force_const_mem (mode, x)
+ && (TARGET_32BIT
+ ? arm_legitimate_constant_p_1 (mode, x)
+ : thumb_legitimate_constant_p (mode, x)));
+}
+
/* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
-bool
+static bool
arm_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
{
rtx base, offset;
#define TARGET_DEFAULT_WORD_RELOCATIONS 0
#endif
-/* Nonzero if the constant value X is a legitimate general operand.
- It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE.
-
- On the ARM, allow any integer (invalid ones are removed later by insn
- patterns), nice doubles and symbol_refs which refer to the function's
- constant pool XXX.
-
- When generating pic allow anything. */
-#define ARM_LEGITIMATE_CONSTANT_P(X) (flag_pic || ! label_mentioned_p (X))
-
-#define THUMB_LEGITIMATE_CONSTANT_P(X) \
- ( GET_CODE (X) == CONST_INT \
- || GET_CODE (X) == CONST_DOUBLE \
- || CONSTANT_ADDRESS_P (X) \
- || flag_pic)
-
-#define LEGITIMATE_CONSTANT_P(X) \
- (!arm_cannot_force_const_mem (VOIDmode, X) \
- && (TARGET_32BIT ? ARM_LEGITIMATE_CONSTANT_P (X) \
- : THUMB_LEGITIMATE_CONSTANT_P (X)))
-
#ifndef SUBTARGET_NAME_ENCODING_LENGTHS
#define SUBTARGET_NAME_ENCODING_LENGTHS
#endif
} \
} while(0)
-#define LEGITIMATE_CONSTANT_P(X) 1
-
#define BRANCH_COST(speed_p, predictable_p) 0
#define SLOW_BYTE_ACCESS 0
extern char *bfin_asm_short (void);
extern int log2constp (unsigned HOST_WIDE_INT);
-extern bool bfin_legitimate_constant_p (rtx);
extern int hard_regno_mode_ok (int, Mmode);
extern void init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx);
extern HOST_WIDE_INT bfin_initial_elimination_offset (int, int);
else if (mode == SImode && GET_CODE (op) == CONST
&& GET_CODE (XEXP (op, 0)) == PLUS
&& GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF
- && !bfin_legitimate_constant_p (op))
+ && !targetm.legitimate_constant_p (mode, op))
{
rtx dest = operands[0];
rtx op0, op1;
This ensures that flat binaries never have to deal with relocations
crossing section boundaries. */
-bool
-bfin_legitimate_constant_p (rtx x)
+static bool
+bfin_legitimate_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
{
rtx sym;
HOST_WIDE_INT offset;
#undef TARGET_DELEGITIMIZE_ADDRESS
#define TARGET_DELEGITIMIZE_ADDRESS bfin_delegitimize_address
+#undef TARGET_LEGITIMATE_CONSTANT_P
+#define TARGET_LEGITIMATE_CONSTANT_P bfin_legitimate_constant_p
+
#undef TARGET_CANNOT_FORCE_CONST_MEM
#define TARGET_CANNOT_FORCE_CONST_MEM bfin_cannot_force_const_mem
/* Addressing Modes */
-/* Nonzero if the constant value X is a legitimate general operand.
- symbol_ref are not legitimate and will be put into constant pool.
- See force_const_mem().
- If -mno-pool, all constants are legitimate.
- */
-#define LEGITIMATE_CONSTANT_P(X) bfin_legitimate_constant_p (X)
-
/* A number, the maximum number of registers that can appear in a
valid memory address. Note that it is up to you to specify a
value equal to the maximum number that `TARGET_LEGITIMATE_ADDRESS_P'
} \
while (0)
-#define LEGITIMATE_CONSTANT_P(X) 1
-
/* Node: Condition Code */
will reload one or both registers only if neither labeling works. */
#define REG_OK_FOR_INDEX_P(X) REG_OK_FOR_BASE_P (X)
-/* A C expression that is nonzero if X is a legitimate constant for an
- immediate operand on the target machine. You can assume that X satisfies
- `CONSTANT_P', so you need not check this. In fact, `1' is a suitable
- definition for this macro on machines where anything `CONSTANT_P' is valid. */
-#define LEGITIMATE_CONSTANT_P(X) 1
-
/*}}}*/ \f
/*{{{ Describing Relative Costs of Operations */
extern int frv_hard_regno_nregs (int, enum machine_mode);
extern int frv_class_max_nregs (enum reg_class rclass,
enum machine_mode mode);
-extern int frv_legitimate_constant_p (rtx);
extern enum machine_mode frv_select_cc_mode (enum rtx_code, rtx, rtx);
#endif /* RTX_CODE */
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_legitimate_constant_p (enum machine_mode, 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 *,
#undef TARGET_FUNCTION_OK_FOR_SIBCALL
#define TARGET_FUNCTION_OK_FOR_SIBCALL frv_function_ok_for_sibcall
+#undef TARGET_LEGITIMATE_CONSTANT_P
+#define TARGET_LEGITIMATE_CONSTANT_P frv_legitimate_constant_p
#undef TARGET_CANNOT_FORCE_CONST_MEM
#define TARGET_CANNOT_FORCE_CONST_MEM frv_cannot_force_const_mem
We never allow constants to be forced into memory for TARGET_FDPIC.
This is necessary for several reasons:
- 1. Since LEGITIMATE_CONSTANT_P rejects constant pool addresses, the
+ 1. Since frv_legitimate_constant_p rejects constant pool addresses, the
target-independent code will try to force them into the constant
pool, thus leading to infinite recursion.
`CONSTANT_P', so you need not check this. In fact, `1' is a suitable
definition for this macro on machines where anything `CONSTANT_P' is valid. */
-int
-frv_legitimate_constant_p (rtx x)
+static bool
+frv_legitimate_constant_p (enum machine_mode mode, rtx x)
{
- enum machine_mode mode = GET_MODE (x);
-
/* frv_cannot_force_const_mem always returns true for FDPIC. This
means that the move expanders will be expected to deal with most
kinds of constant, regardless of what we return here.
- However, among its other duties, LEGITIMATE_CONSTANT_P decides whether
+ However, among its other duties, frv_legitimate_constant_p decides whether
a constant can be entered into reg_equiv_constant[]. If we return true,
reload can create new instances of the constant whenever it likes.
return TRUE;
/* double integer constants are ok. */
- if (mode == VOIDmode || mode == DImode)
+ if (GET_MODE (x) == VOIDmode || mode == DImode)
return TRUE;
/* 0 is always ok. */
#define FIND_BASE_TERM frv_find_base_term
-/* A C expression that is nonzero if X is a legitimate constant for an
- immediate operand on the target machine. You can assume that X satisfies
- `CONSTANT_P', so you need not check this. In fact, `1' is a suitable
- definition for this macro on machines where anything `CONSTANT_P' is valid. */
-#define LEGITIMATE_CONSTANT_P(X) frv_legitimate_constant_p (X)
-
/* The load-and-update commands allow pre-modification in addresses.
The index has to be in a register. */
#define HAVE_PRE_MODIFY_REG 1
extern int same_cmp_preceding_p (rtx);
extern int same_cmp_following_p (rtx);
-extern int h8300_legitimate_constant_p (rtx);
-
/* Used in builtins.c */
extern rtx h8300_return_addr_rtx (int, rtx);
}
-/* Return nonzero if X is a legitimate constant. */
-
-int
-h8300_legitimate_constant_p (rtx x ATTRIBUTE_UNUSED)
-{
- return 1;
-}
-
/* Return nonzero if X is a REG or SUBREG suitable as a base register. */
static int
&& INTVAL (X) < (TARGET_H8300 ? 0x10000 : 0x1000000)) \
|| (GET_CODE (X) == HIGH || GET_CODE (X) == CONST))
-/* Nonzero if the constant value X is a legitimate general operand.
- It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
-
-#define LEGITIMATE_CONSTANT_P(X) (h8300_legitimate_constant_p (X))
-
/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
and check its validity for a certain class.
We have two alternate definitions for each of them.
extern bool ix86_expand_setmem (rtx, rtx, rtx, rtx, rtx, rtx);
extern bool ix86_expand_strlen (rtx, rtx, rtx, rtx);
-extern bool legitimate_constant_p (rtx);
extern bool constant_address_p (rtx);
extern bool legitimate_pic_operand_p (rtx);
extern bool legitimate_pic_address_disp_p (rtx);
/* Determine if a given RTX is a valid constant. We already know this
satisfies CONSTANT_P. */
-bool
-legitimate_constant_p (rtx x)
+static bool
+ix86_legitimate_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
{
switch (GET_CODE (x))
{
is checked above. */
static bool
-ix86_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
+ix86_cannot_force_const_mem (enum machine_mode mode, rtx x)
{
/* We can always put integral constants and vectors in memory. */
switch (GET_CODE (x))
default:
break;
}
- return !legitimate_constant_p (x);
+ return !ix86_legitimate_constant_p (mode, x);
}
/* Displacement is an invalid pic construct. */
return false;
#if TARGET_MACHO
- else if (MACHO_DYNAMIC_NO_PIC_P && !legitimate_constant_p (disp))
+ else if (MACHO_DYNAMIC_NO_PIC_P
+ && !ix86_legitimate_constant_p (Pmode, disp))
/* displacment must be referenced via non_lazy_pointer */
return false;
#endif
else if (GET_CODE (disp) != LABEL_REF
&& !CONST_INT_P (disp)
&& (GET_CODE (disp) != CONST
- || !legitimate_constant_p (disp))
+ || !ix86_legitimate_constant_p (Pmode, disp))
&& (GET_CODE (disp) != SYMBOL_REF
- || !legitimate_constant_p (disp)))
+ || !ix86_legitimate_constant_p (Pmode, disp)))
/* Displacement is not constant. */
return false;
else if (TARGET_64BIT
#undef TARGET_LEGITIMATE_ADDRESS_P
#define TARGET_LEGITIMATE_ADDRESS_P ix86_legitimate_address_p
+#undef TARGET_LEGITIMATE_CONSTANT_P
+#define TARGET_LEGITIMATE_CONSTANT_P ix86_legitimate_constant_p
+
#undef TARGET_FRAME_POINTER_REQUIRED
#define TARGET_FRAME_POINTER_REQUIRED ix86_frame_pointer_required
#define CONSTANT_ADDRESS_P(X) constant_address_p (X)
-/* Nonzero if the constant value X is a legitimate general operand.
- It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
-
-#define LEGITIMATE_CONSTANT_P(X) legitimate_constant_p (X)
-
/* If defined, a C expression to determine the base term of address X.
This macro is used in only one place: `find_base_term' in alias.c.
"TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
{
/* ??? Needed for compress_float_constant since all fp constants
- are LEGITIMATE_CONSTANT_P. */
+ are TARGET_LEGITIMATE_CONSTANT_P. */
if (GET_CODE (operands[1]) == CONST_DOUBLE)
{
if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
"TARGET_80387"
{
/* ??? Needed for compress_float_constant since all fp constants
- are LEGITIMATE_CONSTANT_P. */
+ are TARGET_LEGITIMATE_CONSTANT_P. */
if (GET_CODE (operands[1]) == CONST_DOUBLE)
{
if (standard_80387_constant_p (operands[1]) > 0)
;; Convert lea to the lea pattern to avoid flags dependency.
;; ??? This pattern handles immediate operands that do not satisfy immediate
-;; operand predicate (LEGITIMATE_CONSTANT_P) in the previous pattern.
+;; operand predicate (TARGET_LEGITIMATE_CONSTANT_P) in the previous pattern.
(define_split
[(set (match_operand:DI 0 "register_operand" "")
(plus:DI (match_operand:DI 1 "register_operand" "")
extern int ia64_ld_address_bypass_p (rtx, rtx);
extern int ia64_produce_address_p (rtx);
-extern bool ia64_legitimate_constant_p (rtx);
-
extern rtx ia64_expand_move (rtx, rtx);
extern int ia64_move_ok (rtx, rtx);
extern int ia64_load_pair_ok (rtx, rtx);
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_legitimate_constant_p (enum machine_mode, 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);
#undef TARGET_HANDLE_OPTION
#define TARGET_HANDLE_OPTION ia64_handle_option
+#undef TARGET_LEGITIMATE_CONSTANT_P
+#define TARGET_LEGITIMATE_CONSTANT_P ia64_legitimate_constant_p
+
#undef TARGET_CANNOT_FORCE_CONST_MEM
#define TARGET_CANNOT_FORCE_CONST_MEM ia64_cannot_force_const_mem
/* Return true if X is a constant that is valid for some immediate
field in an instruction. */
-bool
-ia64_legitimate_constant_p (rtx x)
+static bool
+ia64_legitimate_constant_p (enum machine_mode mode, rtx x)
{
switch (GET_CODE (x))
{
return true;
case CONST_DOUBLE:
- if (GET_MODE (x) == VOIDmode || GET_MODE (x) == SFmode
- || GET_MODE (x) == DFmode)
+ if (GET_MODE (x) == VOIDmode || mode == SFmode || mode == DFmode)
return true;
return satisfies_constraint_G (x);
op = XEXP (XEXP (op, 0), 0);
}
- if (any_offset_symbol_operand (op, GET_MODE (op))
- || function_operand (op, GET_MODE (op)))
+ if (any_offset_symbol_operand (op, mode)
+ || function_operand (op, mode))
return true;
- if (aligned_offset_symbol_operand (op, GET_MODE (op)))
+ if (aligned_offset_symbol_operand (op, mode))
return (addend & 0x3fff) == 0;
return false;
}
return false;
case CONST_VECTOR:
- {
- enum machine_mode mode = GET_MODE (x);
-
- if (mode == V2SFmode)
- return satisfies_constraint_Y (x);
+ if (mode == V2SFmode)
+ return satisfies_constraint_Y (x);
- return (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
- && GET_MODE_SIZE (mode) <= 8);
- }
+ return (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
+ && GET_MODE_SIZE (mode) <= 8);
default:
return false;
use as an index register. This is needed for POST_MODIFY. */
#define REG_OK_FOR_INDEX_P(X) REG_OK_FOR_BASE_P (X)
-
-/* A C expression that is nonzero if X is a legitimate constant for an
- immediate operand on the target machine. */
-
-#define LEGITIMATE_CONSTANT_P(X) ia64_legitimate_constant_p (X)
\f
/* Condition Code Status */
#define REG_OK_FOR_INDEX_P(X) 0
-#define LEGITIMATE_CONSTANT_P(X) (1)
-
\f
/* Describing Relative Costs of Operations. */
extern void lm32_expand_scc (rtx operands[]);
extern void lm32_expand_conditional_branch (rtx operands[]);
extern bool lm32_move_ok (enum machine_mode, rtx operands[2]);
-extern bool lm32_legitimate_constant_p (rtx);
static void lm32_function_arg_advance (CUMULATIVE_ARGS * cum,
enum machine_mode mode,
const_tree type, bool named);
+static bool lm32_legitimate_constant_p (enum machine_mode, rtx);
/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */
static const struct default_options lm32_option_optimization_table[] =
#define TARGET_LEGITIMATE_ADDRESS_P lm32_legitimate_address_p
#undef TARGET_EXCEPT_UNWIND_INFO
#define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info
+#undef TARGET_LEGITIMATE_CONSTANT_P
+#define TARGET_LEGITIMATE_CONSTANT_P lm32_legitimate_constant_p
struct gcc_target targetm = TARGET_INITIALIZER;
return true;
}
-/* Implement LEGITIMATE_CONSTANT_P. */
+/* Implement TARGET_LEGITIMATE_CONSTANT_P. */
-bool
-lm32_legitimate_constant_p (rtx x)
+static bool
+lm32_legitimate_constant_p (enum machine_mode mode, rtx x)
{
/* 32-bit addresses require multiple instructions. */
- if (!flag_pic && reloc_operand (x, GET_MODE (x)))
+ if (!flag_pic && reloc_operand (x, mode))
return false;
return true;
#define REG_OK_FOR_BASE_P(X) NONSTRICT_REG_OK_FOR_BASE_P(X)
#endif
-#define LEGITIMATE_CONSTANT_P(X) lm32_legitimate_constant_p (X)
-
/*-------------------------*/
/* Condition Code Status. */
/*-------------------------*/
bool m32c_illegal_subreg_p (rtx);
bool m32c_immd_dbl_mov (rtx *, MM);
rtx m32c_incoming_return_addr_rtx (void);
-int m32c_legitimate_constant_p (rtx);
int m32c_legitimize_reload_address (rtx *, MM, int, int, int);
int m32c_limit_reload_class (MM, int);
int m32c_modes_tieable_p (MM, MM);
return 0;
}
-/* Implements LEGITIMATE_CONSTANT_P. We split large constants anyway,
- so we can allow anything. */
-int
-m32c_legitimate_constant_p (rtx x ATTRIBUTE_UNUSED)
-{
- return 1;
-}
-
-
/* Return the appropriate mode for a named address pointer. */
#undef TARGET_ADDR_SPACE_POINTER_MODE
#define TARGET_ADDR_SPACE_POINTER_MODE m32c_addr_space_pointer_mode
if (m32c_legitimize_reload_address(&(X),MODE,OPNUM,TYPE,IND_LEVELS)) \
goto WIN;
-#define LEGITIMATE_CONSTANT_P(X) m32c_legitimate_constant_p (X)
-
/* Address spaces. */
#define ADDR_SPACE_FAR 1
static bool m32r_can_eliminate (const int, const int);
static void m32r_conditional_register_usage (void);
static void m32r_trampoline_init (rtx, tree, rtx);
+static bool m32r_legitimate_constant_p (enum machine_mode, rtx);
\f
/* M32R specific attributes. */
#undef TARGET_TRAMPOLINE_INIT
#define TARGET_TRAMPOLINE_INIT m32r_trampoline_init
+#undef TARGET_LEGITIMATE_CONSTANT_P
+#define TARGET_LEGITIMATE_CONSTANT_P m32r_legitimate_constant_p
+
#undef TARGET_EXCEPT_UNWIND_INFO
#define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info
call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
}
}
+
+/* Implement TARGET_LEGITIMATE_CONSTANT_P
+
+ We don't allow (plus symbol large-constant) as the relocations can't
+ describe it. INTVAL > 32767 handles both 16-bit and 24-bit relocations.
+ We allow all CONST_DOUBLE's as the md file patterns will force the
+ constant to memory if they can't handle them. */
+
+static bool
+m32r_legitimate_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
+{
+ return !(GET_CODE (x) == CONST
+ && GET_CODE (XEXP (x, 0)) == PLUS
+ && (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
+ || GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF)
+ && CONST_INT_P (XEXP (XEXP (x, 0), 1))
+ && UINTVAL (XEXP (XEXP (x, 0), 1)) > 32767);
+}
|| CONST_INT_P (X) \
|| (GET_CODE (X) == CONST \
&& ! (flag_pic && ! m32r_legitimate_pic_operand_p (X))))
-
-/* Nonzero if the constant value X is a legitimate general operand.
- We don't allow (plus symbol large-constant) as the relocations can't
- describe it. INTVAL > 32767 handles both 16-bit and 24-bit relocations.
- We allow all CONST_DOUBLE's as the md file patterns will force the
- constant to memory if they can't handle them. */
-
-#define LEGITIMATE_CONSTANT_P(X) \
- (! (GET_CODE (X) == CONST \
- && GET_CODE (XEXP (X, 0)) == PLUS \
- && (GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF || GET_CODE (XEXP (XEXP (X, 0), 0)) == LABEL_REF) \
- && CONST_INT_P (XEXP (XEXP (X, 0), 1)) \
- && (unsigned HOST_WIDE_INT) INTVAL (XEXP (XEXP (X, 0), 1)) > 32767))
\f
/* Condition code usage. */
extern bool m68k_legitimate_base_reg_p (rtx, bool);
extern bool m68k_legitimate_index_reg_p (rtx, bool);
extern bool m68k_illegitimate_symbolic_constant_p (rtx);
+extern bool m68k_legitimate_constant_p (enum machine_mode, rtx);
extern bool m68k_matches_q_p (rtx);
extern bool m68k_matches_u_p (rtx);
extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx);
#undef TARGET_FUNCTION_ARG_ADVANCE
#define TARGET_FUNCTION_ARG_ADVANCE m68k_function_arg_advance
+#undef TARGET_LEGITIMATE_CONSTANT_P
+#define TARGET_LEGITIMATE_CONSTANT_P m68k_legitimate_constant_p
+
static const struct attribute_spec m68k_attribute_table[] =
{
/* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
&& GET_CODE (stack_limit_rtx) == SYMBOL_REF)
{
limit = plus_constant (stack_limit_rtx, current_frame.size + 4);
- if (!LEGITIMATE_CONSTANT_P (limit))
+ if (!m68k_legitimate_constant_p (Pmode, limit))
{
emit_move_insn (gen_rtx_REG (Pmode, D0_REG), limit);
limit = gen_rtx_REG (Pmode, D0_REG);
address));
}
+/* Implement TARGET_LEGITIMATE_CONSTANT_P. */
+
+bool
+m68k_legitimate_constant_p (enum machine_mode mode, rtx x)
+{
+ return mode != XFmode && !m68k_illegitimate_symbolic_constant_p (x);
+}
+
/* Return true if X matches the 'Q' constraint. It must be a memory
with a base address and no constant offset or index. */
((GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \
|| GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST \
|| GET_CODE (X) == HIGH) \
- && LEGITIMATE_CONSTANT_P (X))
-
-/* Nonzero if the constant value X is a legitimate general operand.
- It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
-#define LEGITIMATE_CONSTANT_P(X) \
- (GET_MODE (X) != XFmode \
- && !m68k_illegitimate_symbolic_constant_p (X))
+ && m68k_legitimate_constant_p (Pmode, X))
#ifndef REG_OK_STRICT
#define REG_STRICT_P 0
;; ??? The XFmode patterns are schizophrenic about whether constants are
;; allowed. Most but not all have predicates and constraint that disallow
;; constants. Most but not all have output templates that handle constants.
-;; See also LEGITIMATE_CONSTANT_P.
+;; See also TARGET_LEGITIMATE_CONSTANT_P.
(define_expand "movxf"
[(set (match_operand:XF 0 "nonimmediate_operand" "")
static void mcore_asm_trampoline_template (FILE *);
static void mcore_trampoline_init (rtx, tree, rtx);
static void mcore_option_override (void);
+static bool mcore_legitimate_constant_p (enum machine_mode, rtx);
\f
/* MCore specific attributes. */
#undef TARGET_EXCEPT_UNWIND_INFO
#define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info
+#undef TARGET_LEGITIMATE_CONSTANT_P
+#define TARGET_LEGITIMATE_CONSTANT_P mcore_legitimate_constant_p
+
struct gcc_target targetm = TARGET_INITIALIZER;
\f
/* Adjust the stack and return the number of bytes taken to do it. */
mem = adjust_address (m_tramp, SImode, 12);
emit_move_insn (mem, fnaddr);
}
+
+/* Implement TARGET_LEGITIMATE_CONSTANT_P
+
+ On the MCore, allow anything but a double. */
+
+static bool
+mcore_legitimate_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
+{
+ return GET_CODE (x) != CONST_DOUBLE;
+}
/* Recognize any constant value that is a valid address. */
#define CONSTANT_ADDRESS_P(X) (GET_CODE (X) == LABEL_REF)
-/* Nonzero if the constant value X is a legitimate general operand.
- It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE.
-
- On the MCore, allow anything but a double. */
-#define LEGITIMATE_CONSTANT_P(X) (GET_CODE(X) != CONST_DOUBLE \
- && CONSTANT_P (X))
-
/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
and check its validity for a certain class.
We have two alternate definitions for each of them.
#ifdef RTX_CODE
extern bool mep_expand_setcc (rtx *);
extern rtx mep_expand_cbranch (rtx *);
-extern bool mep_legitimate_constant_p (rtx);
#endif
extern const char *mep_emit_cbranch (rtx *, int);
extern void mep_expand_call (rtx *, int);
return get_attr_slot (x) == SLOT_MULTI;
}
+/* Implement TARGET_LEGITIMATE_CONSTANT_P. */
-bool
-mep_legitimate_constant_p (rtx x)
+static bool
+mep_legitimate_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
{
/* We can't convert symbol values to gp- or tp-rel values after
reload, as reload might have used $gp or $tp for other
if ((mode == SImode || mode == SFmode)
&& CONSTANT_P (x)
- && LEGITIMATE_CONSTANT_P (x)
+ && mep_legitimate_constant_p (mode, x)
&& the_tag != 't' && the_tag != 'b')
{
if (GET_CODE (x) != CONST_INT
#define TARGET_CONDITIONAL_REGISTER_USAGE mep_conditional_register_usage
#undef TARGET_TRAMPOLINE_INIT
#define TARGET_TRAMPOLINE_INIT mep_trampoline_init
+#undef TARGET_LEGITIMATE_CONSTANT_P
+#define TARGET_LEGITIMATE_CONSTANT_P mep_legitimate_constant_p
struct gcc_target targetm = TARGET_INITIALIZER;
#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL)
-#define LEGITIMATE_CONSTANT_P(X) \
- mep_legitimate_constant_p(X)
-
#define SELECT_CC_MODE(OP, X, Y) CCmode
\f
extern void microblaze_expand_conditional_branch (enum machine_mode, rtx *);
extern void microblaze_expand_conditional_branch_sf (rtx *);
extern int microblaze_can_use_return_insn (void);
-extern int microblaze_const_double_ok (rtx, enum machine_mode);
extern void print_operand (FILE *, rtx, int);
extern void print_operand_address (FILE *, rtx);
extern void init_cumulative_args (CUMULATIVE_ARGS *,tree, rtx);
enum pipeline_type microblaze_pipe = MICROBLAZE_PIPE_5;
/* High and low marks for floating point values which we will accept
- as legitimate constants for LEGITIMATE_CONSTANT_P. These are
+ as legitimate constants for TARGET_LEGITIMATE_CONSTANT_P. These are
initialized in override_options. */
REAL_VALUE_TYPE dfhigh, dflow, sfhigh, sflow;
section *sdata2_section;
/* Return truth value if a CONST_DOUBLE is ok to be a legitimate constant. */
-int
+static bool
microblaze_const_double_ok (rtx op, enum machine_mode mode)
{
REAL_VALUE_TYPE d;
if (GET_CODE (op) != CONST_DOUBLE)
return 0;
- if (mode == VOIDmode)
+ if (GET_MODE (op) == VOIDmode)
return 1;
if (mode != SFmode && mode != DFmode)
return 0;
return cost;
}
+
+/* Implement TARGET_LEGITIMATE_CONSTANT_P.
+
+ At present, GAS doesn't understand li.[sd], so don't allow it
+ to be generated at present. */
+static bool
+microblaze_legitimate_constant_p (enum machine_mode mode, rtx x)
+{
+ return GET_CODE (x) != CONST_DOUBLE || microblaze_const_double_ok (x, mode);
+}
\f
#undef TARGET_ENCODE_SECTION_INFO
#define TARGET_ENCODE_SECTION_INFO microblaze_encode_section_info
#undef TARGET_EXCEPT_UNWIND_INFO
#define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info
+#undef TARGET_LEGITIMATE_CONSTANT_P
+#define TARGET_LEGITIMATE_CONSTANT_P microblaze_legitimate_constant_p
+
struct gcc_target targetm = TARGET_INITIALIZER;
\f
#include "gt-microblaze.h"
addresses which require two reload registers. */
#define LEGITIMATE_PIC_OPERAND_P(X) (!pic_address_needs_scratch (X))
-/* At present, GAS doesn't understand li.[sd], so don't allow it
- to be generated at present. */
-#define LEGITIMATE_CONSTANT_P(X) \
- (GET_CODE (X) != CONST_DOUBLE \
- || microblaze_const_double_ok (X, GET_MODE (X)))
-
#define CASE_VECTOR_MODE (SImode)
#ifndef DEFAULT_SIGNED_CHAR
}
}
\f
+/* Implement TARGET_LEGITIMATE_CONSTANT_P. */
+
+static bool
+mips_legitimate_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
+{
+ return mips_const_insns (x) > 0;
+}
+\f
/* Return true if symbols of type TYPE require a GOT access. */
static bool
/* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
static bool
-mips_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
+mips_cannot_force_const_mem (enum machine_mode mode, rtx x)
{
enum mips_symbol_type type;
rtx base, offset;
references, reload will consider forcing C into memory and using
one of the instruction's memory alternatives. Returning false
here will force it to use an input reload instead. */
- if (CONST_INT_P (x) && LEGITIMATE_CONSTANT_P (x))
+ if (CONST_INT_P (x) && mips_legitimate_constant_p (mode, x))
return true;
split_const (x, &base, &offset);
#undef TARGET_CANNOT_FORCE_CONST_MEM
#define TARGET_CANNOT_FORCE_CONST_MEM mips_cannot_force_const_mem
+#undef TARGET_LEGITIMATE_CONSTANT_P
+#define TARGET_LEGITIMATE_CONSTANT_P mips_legitimate_constant_p
+
#undef TARGET_ENCODE_SECTION_INFO
#define TARGET_ENCODE_SECTION_INFO mips_encode_section_info
#define CONSTANT_ADDRESS_P(X) \
(CONSTANT_P (X) && memory_address_p (SImode, X))
-#define LEGITIMATE_CONSTANT_P(X) (mips_const_insns (X) > 0)
-
/* This handles the magic '..CURRENT_FUNCTION' symbol, which means
'the start of the function that this code is output in'. */
(define_predicate "splittable_const_int_operand"
(match_code "const_int")
{
- /* When generating mips16 code, LEGITIMATE_CONSTANT_P rejects
+ /* When generating mips16 code, TARGET_LEGITIMATE_CONSTANT_P rejects
CONST_INTs that can't be loaded using simple insns. */
if (TARGET_MIPS16)
return false;
extern rtx mmix_eh_return_stackadj_rtx (void);
extern rtx mmix_eh_return_handler_rtx (void);
extern int mmix_constant_address_p (rtx);
-extern int mmix_legitimate_constant_p (rtx);
extern void mmix_print_operand (FILE *, rtx, int);
extern void mmix_print_operand_address (FILE *, rtx);
extern void mmix_expand_prologue (void);
static void mmix_target_asm_function_end_prologue (FILE *);
static void mmix_target_asm_function_epilogue (FILE *, HOST_WIDE_INT);
static bool mmix_legitimate_address_p (enum machine_mode, rtx, bool);
+static bool mmix_legitimate_constant_p (enum machine_mode, rtx);
static void mmix_reorg (void);
static void mmix_asm_output_mi_thunk
(FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, tree);
#undef TARGET_LEGITIMATE_ADDRESS_P
#define TARGET_LEGITIMATE_ADDRESS_P mmix_legitimate_address_p
+#undef TARGET_LEGITIMATE_CONSTANT_P
+#define TARGET_LEGITIMATE_CONSTANT_P mmix_legitimate_constant_p
#undef TARGET_FRAME_POINTER_REQUIRED
#define TARGET_FRAME_POINTER_REQUIRED mmix_frame_pointer_required
return TARGET_BASE_ADDRESSES && mmix_constant_address_p (x);
}
-/* LEGITIMATE_CONSTANT_P. */
+/* Implement TARGET_LEGITIMATE_CONSTANT_P. */
-int
-mmix_legitimate_constant_p (rtx x)
+static bool
+mmix_legitimate_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
{
RTX_CODE code = GET_CODE (x);
}
}
- if (TARGET_BASE_ADDRESSES && mmix_legitimate_constant_p (x))
+ if (TARGET_BASE_ADDRESSES && mmix_legitimate_constant_p (Pmode, x))
{
output_addr_const (stream, x);
return;
#define REG_OK_FOR_INDEX_P(X) REG_OK_FOR_BASE_P (X)
-#define LEGITIMATE_CONSTANT_P(X) \
- mmix_legitimate_constant_p (X)
-
/* Node: Condition Code */
extern bool mn10300_function_value_regno_p (const unsigned int);
extern int mn10300_get_live_callee_saved_regs (void);
extern bool mn10300_hard_regno_mode_ok (unsigned int, Mmode);
-extern bool mn10300_legitimate_constant_p (rtx);
extern bool mn10300_modes_tieable (Mmode, Mmode);
extern Cstar mn10300_output_add (rtx[3], bool);
extern void mn10300_print_operand (FILE *, rtx, int);
return any_change ? x : NULL_RTX;
}
-/* Used by LEGITIMATE_CONSTANT_P(). Returns TRUE if X is a valid
+/* Implement TARGET_LEGITIMATE_CONSTANT_P. Returns TRUE if X is a valid
constant. Note that some "constants" aren't valid, such as TLS
symbols and unconverted GOT-based references, so we eliminate
those here. */
-bool
-mn10300_legitimate_constant_p (rtx x)
+static bool
+mn10300_legitimate_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
{
switch (GET_CODE (x))
{
#define TARGET_LEGITIMATE_ADDRESS_P mn10300_legitimate_address_p
#undef TARGET_DELEGITIMIZE_ADDRESS
#define TARGET_DELEGITIMIZE_ADDRESS mn10300_delegitimize_address
+#undef TARGET_LEGITIMATE_CONSTANT_P
+#define TARGET_LEGITIMATE_CONSTANT_P mn10300_legitimate_constant_p
#undef TARGET_PREFERRED_RELOAD_CLASS
#define TARGET_PREFERRED_RELOAD_CLASS mn10300_preferred_reload_class
} while (0)
\f
-/* Nonzero if the constant value X is a legitimate general operand.
- It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
-#define LEGITIMATE_CONSTANT_P(X) mn10300_legitimate_constant_p (X)
-
/* Zero if this needs fixing up to become PIC. */
#define LEGITIMATE_PIC_OPERAND_P(X) \
/* All load operations zero extend. */
#define LOAD_EXTEND_OP(MEM) ZERO_EXTEND
-/* A C expression that is nonzero if X is a legitimate constant for
- an immediate operand on the target machine. */
-#define LEGITIMATE_CONSTANT_P(X) 1
-
/* A number, the maximum number of registers that can appear in a
valid memory address. */
#define MAX_REGS_PER_ADDRESS 1
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);
+static bool pa_legitimate_constant_p (enum machine_mode, rtx);
/* The following extra sections are only used for SOM. */
static GTY(()) section *som_readonly_data_section;
#undef TARGET_ASM_FUNCTION_SECTION
#define TARGET_ASM_FUNCTION_SECTION pa_function_section
+#undef TARGET_LEGITIMATE_CONSTANT_P
+#define TARGET_LEGITIMATE_CONSTANT_P pa_legitimate_constant_p
+
struct gcc_target targetm = TARGET_INITIALIZER;
\f
/* Parse the -mfixed-range= option string. */
return default_function_section (decl, freq, startup, exit);
}
+/* Implement TARGET_LEGITIMATE_CONSTANT_P.
+
+ In 64-bit mode, we reject CONST_DOUBLES. We also reject CONST_INTS
+ that need more than three instructions to load prior to reload. This
+ limit is somewhat arbitrary. It takes three instructions to load a
+ CONST_INT from memory but two are memory accesses. It may be better
+ to increase the allowed range for CONST_INTS. We may also be able
+ to handle CONST_DOUBLES. */
+
+static bool
+pa_legitimate_constant_p (enum machine_mode mode, rtx x)
+{
+ if (GET_MODE_CLASS (mode) == MODE_FLOAT && x != CONST0_RTX (mode))
+ return false;
+
+ if (!NEW_HP_ASSEMBLER && !TARGET_GAS && GET_CODE (x) == LABEL_REF)
+ return false;
+
+ if (TARGET_64BIT && GET_CODE (x) == CONST_DOUBLE)
+ return false;
+
+ if (TARGET_64BIT
+ && HOST_BITS_PER_WIDE_INT > 32
+ && GET_CODE (x) == CONST_INT
+ && !reload_in_progress
+ && !reload_completed
+ && !LEGITIMATE_64BIT_CONST_INT_P (INTVAL (x))
+ && !cint_ok_for_move (INTVAL (x)))
+ return false;
+
+ if (function_label_operand (x, mode))
+ return false;
+
+ return true;
+}
+
#include "gt-pa.h"
#define LEGITIMATE_64BIT_CONST_INT_P(X) \
((X) >= MIN_LEGIT_64BIT_CONST_INT && (X) < MAX_LEGIT_64BIT_CONST_INT)
-/* A C expression that is nonzero if X is a legitimate constant for an
- immediate operand.
-
- We include all constant integers and constant doubles, but not
- floating-point, except for floating-point zero. We reject LABEL_REFs
- if we're not using gas or the new HP assembler.
-
- In 64-bit mode, we reject CONST_DOUBLES. We also reject CONST_INTS
- that need more than three instructions to load prior to reload. This
- limit is somewhat arbitrary. It takes three instructions to load a
- CONST_INT from memory but two are memory accesses. It may be better
- to increase the allowed range for CONST_INTS. We may also be able
- to handle CONST_DOUBLES. */
-
-#define LEGITIMATE_CONSTANT_P(X) \
- ((GET_MODE_CLASS (GET_MODE (X)) != MODE_FLOAT \
- || (X) == CONST0_RTX (GET_MODE (X))) \
- && (NEW_HP_ASSEMBLER \
- || TARGET_GAS \
- || GET_CODE (X) != LABEL_REF) \
- && (!TARGET_64BIT \
- || GET_CODE (X) != CONST_DOUBLE) \
- && (!TARGET_64BIT \
- || HOST_BITS_PER_WIDE_INT <= 32 \
- || GET_CODE (X) != CONST_INT \
- || reload_in_progress \
- || reload_completed \
- || LEGITIMATE_64BIT_CONST_INT_P (INTVAL (X)) \
- || cint_ok_for_move (INTVAL (X))) \
- && !function_label_operand (X, VOIDmode))
-
/* Target flags set on a symbol_ref. */
/* Set by ASM_OUTPUT_SYMBOL_REF when a symbol_ref is output. */
static void pdp11_function_arg_advance (CUMULATIVE_ARGS *,
enum machine_mode, const_tree, bool);
static void pdp11_conditional_register_usage (void);
+static bool pdp11_legitimate_constant_p (enum machine_mode, rtx);
/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */
#undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
#define TARGET_PRINT_OPERAND_PUNCT_VALID_P pdp11_asm_print_operand_punct_valid_p
+
+#undef TARGET_LEGITIMATE_CONSTANT_P
+#define TARGET_LEGITIMATE_CONSTANT_P pdp11_legitimate_constant_p
\f
/* Implement TARGET_HANDLE_OPTION. */
return NULL;
}
+/* Implement TARGET_LEGITIMATE_CONSTANT_P. */
+
+static bool
+pdp11_legitimate_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
+{
+ return GET_CODE (x) != CONST_DOUBLE || legitimate_const_double_p (x);
+}
+
struct gcc_target targetm = TARGET_INITIALIZER;
#define MAX_REGS_PER_ADDRESS 1
-/* Nonzero if the constant value X is a legitimate general operand.
- It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
-
-#define LEGITIMATE_CONSTANT_P(X) \
- (GET_CODE (X) != CONST_DOUBLE || legitimate_const_double_p (X))
-
/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
and check its validity for a certain class.
We have two alternate definitions for each of them.
goto WIN; \
} while(0); \
-/* Nonzero if the constant rtx X is a legitimate general operand. X
- satisfies CONSTANT_P. */
-
-#define LEGITIMATE_CONSTANT_P(X) 1
-
\f
/* Condition Code Status */
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);
+static bool rs6000_legitimate_constant_p (enum machine_mode, rtx);
/* Hash table stuff for keeping track of TOC entries. */
#undef TARGET_SET_CURRENT_FUNCTION
#define TARGET_SET_CURRENT_FUNCTION rs6000_set_current_function
+#undef TARGET_LEGITIMATE_CONSTANT_P
+#define TARGET_LEGITIMATE_CONSTANT_P rs6000_legitimate_constant_p
+
struct gcc_target targetm = TARGET_INITIALIZER;
\f
return x;
}
+/* Implement TARGET_LEGITIMATE_CONSTANT_P.
+
+ On the RS/6000, all integer constants are acceptable, most won't be valid
+ for particular insns, though. Only easy FP constants are acceptable. */
+
+static bool
+rs6000_legitimate_constant_p (enum machine_mode mode, rtx x)
+{
+ if (rs6000_tls_referenced_p (x))
+ return false;
+
+ return ((GET_CODE (x) != CONST_DOUBLE && GET_CODE (x) != CONST_VECTOR)
+ || GET_MODE (x) == VOIDmode
+ || (TARGET_POWERPC64 && mode == DImode)
+ || easy_fp_constant (x, mode)
+ || easy_vector_constant (x, mode));
+}
#include "gt-rs6000.h"
|| GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST \
|| GET_CODE (X) == HIGH)
-/* Nonzero if the constant value X is a legitimate general operand.
- It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE.
-
- On the RS/6000, all integer constants are acceptable, most won't be valid
- for particular insns, though. Only easy FP constants are
- acceptable. */
-
-#define LEGITIMATE_CONSTANT_P(X) \
- (((GET_CODE (X) != CONST_DOUBLE \
- && GET_CODE (X) != CONST_VECTOR) \
- || GET_MODE (X) == VOIDmode \
- || (TARGET_POWERPC64 && GET_MODE (X) == DImode) \
- || easy_fp_constant (X, GET_MODE (X)) \
- || easy_vector_constant (X, GET_MODE (X))) \
- && !rs6000_tls_referenced_p (X))
-
#define EASY_VECTOR_15(n) ((n) >= -16 && (n) <= 15)
#define EASY_VECTOR_15_ADD_SELF(n) (!EASY_VECTOR_15((n)) \
&& EASY_VECTOR_15((n) >> 1) \
extern void rx_emit_stack_pushm (rtx *);
extern void rx_expand_epilogue (bool);
extern char * rx_gen_move_template (rtx *, bool);
-extern bool rx_is_legitimate_constant (rtx);
+extern bool rx_legitimate_constant_p (enum machine_mode, rtx);
extern bool rx_is_restricted_memory_address (rtx, Mmode);
extern bool rx_match_ccmode (rtx, Mmode);
extern void rx_notice_update_cc (rtx body, rtx insn);
insn = emit_insn (gen_addsi3 (dest, src, val));
else
{
- /* Wrap VAL in an UNSPEC so that rx_is_legitimate_constant
+ /* Wrap VAL in an UNSPEC so that rx_legitimate_constant_p
will not reject it. */
val = gen_rtx_CONST (SImode, gen_rtx_UNSPEC (SImode, gen_rtvec (1, val), UNSPEC_CONST));
insn = emit_insn (gen_addsi3 (dest, src, val));
operand on the RX. X is already known to satisfy CONSTANT_P. */
bool
-rx_is_legitimate_constant (rtx x)
+rx_legitimate_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
{
switch (GET_CODE (x))
{
#undef TARGET_FLAGS_REGNUM
#define TARGET_FLAGS_REGNUM CC_REG
+#undef TARGET_LEGITIMATE_CONSTANT_P
+#define TARGET_LEGITIMATE_CONSTANT_P rx_legitimate_constant_p
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* #include "gt-rx.h" */
#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-#define LEGITIMATE_CONSTANT_P(X) rx_is_legitimate_constant (X)
-
#define HAVE_PRE_DECCREMENT 1
#define HAVE_POST_INCREMENT 1
if (MEM_P (operand0) && MEM_P (operand1))
operands[1] = copy_to_mode_reg (<register_modes:MODE>mode, operand1);
if (CONST_INT_P (operand1)
- && ! rx_is_legitimate_constant (operand1))
+ && ! rx_legitimate_constant_p (<register_modes:MODE>mode, operand1))
FAIL;
}
)
extern bool legitimate_la_operand_p (rtx);
extern bool preferred_la_operand_p (rtx, rtx);
extern int legitimate_pic_operand_p (rtx);
-extern int legitimate_constant_p (rtx);
extern bool legitimate_reload_constant_p (rtx);
extern rtx legitimize_pic_address (rtx, rtx);
extern rtx legitimize_reload_address (rtx, enum machine_mode, int, int);
/* Returns true if the constant value OP is a legitimate general operand.
It is given that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
-int
-legitimate_constant_p (rtx op)
+static bool
+s390_legitimate_constant_p (enum machine_mode mode, rtx op)
{
/* Accept all non-symbolic constants. */
if (!SYMBOLIC_CONST (op))
return 1;
/* Accept immediate LARL operands. */
- if (TARGET_CPU_ZARCH && larl_operand (op, VOIDmode))
+ if (TARGET_CPU_ZARCH && larl_operand (op, mode))
return 1;
/* Thread-local symbols are never legal constants. This is
#undef TARGET_LEGITIMATE_ADDRESS_P
#define TARGET_LEGITIMATE_ADDRESS_P s390_legitimate_address_p
+#undef TARGET_LEGITIMATE_CONSTANT_P
+#define TARGET_LEGITIMATE_CONSTANT_P s390_legitimate_constant_p
+
#undef TARGET_CAN_ELIMINATE
#define TARGET_CAN_ELIMINATE s390_can_eliminate
} \
} while (0)
-/* Nonzero if the constant value X is a legitimate general operand.
- It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
-#define LEGITIMATE_CONSTANT_P(X) \
- legitimate_constant_p (X)
-
/* Helper macro for s390.c and s390.md to check for symbolic constants. */
#define SYMBOLIC_CONST(X) \
(GET_CODE (X) == SYMBOL_REF \
#define REG_OK_FOR_INDEX_P(X) 0
-#define LEGITIMATE_CONSTANT_P(X) 1
-
/* Condition Code Status. */
#define SELECT_CC_MODE(OP, X, Y) score_select_cc_mode (OP, X, Y)
static void sh_trampoline_init (rtx, tree, rtx);
static rtx sh_trampoline_adjust_address (rtx);
static void sh_conditional_register_usage (void);
+static bool sh_legitimate_constant_p (enum machine_mode, rtx);
\f
static const struct attribute_spec sh_attribute_table[] =
{
#undef TARGET_TRAMPOLINE_ADJUST_ADDRESS
#define TARGET_TRAMPOLINE_ADJUST_ADDRESS sh_trampoline_adjust_address
+#undef TARGET_LEGITIMATE_CONSTANT_P
+#define TARGET_LEGITIMATE_CONSTANT_P sh_legitimate_constant_p
+
/* Machine-specific symbol_ref flags. */
#define SYMBOL_FLAG_FUNCVEC_FUNCTION (SYMBOL_FLAG_MACH_DEP << 0)
SET_HARD_REG_BIT (reg_class_contents[SIBCALL_REGS], regno);
}
+/* Implement TARGET_LEGITIMATE_CONSTANT_P
+
+ can_store_by_pieces constructs VOIDmode CONST_DOUBLEs. */
+
+static bool
+sh_legitimate_constant_p (enum machine_mode mode, rtx x)
+{
+ return (TARGET_SHMEDIA
+ ? ((mode != DFmode && GET_MODE_CLASS (mode) != MODE_VECTOR_FLOAT)
+ || x == CONST0_RTX (mode)
+ || !TARGET_SHMEDIA_FPU
+ || TARGET_SHMEDIA64)
+ : (GET_CODE (x) != CONST_DOUBLE
+ || mode == DFmode || mode == SFmode
+ || mode == DImode || GET_MODE (x) == VOIDmode));
+}
enum sh_divide_strategy_e sh_div_strategy = SH_DIV_STRATEGY_DEFAULT;
#define CONSTANT_ADDRESS_P(X) (GET_CODE (X) == LABEL_REF)
-/* Nonzero if the constant value X is a legitimate general operand. */
-/* can_store_by_pieces constructs VOIDmode CONST_DOUBLEs. */
-
-#define LEGITIMATE_CONSTANT_P(X) \
- (TARGET_SHMEDIA \
- ? ((GET_MODE (X) != DFmode \
- && GET_MODE_CLASS (GET_MODE (X)) != MODE_VECTOR_FLOAT) \
- || (X) == CONST0_RTX (GET_MODE (X)) \
- || ! TARGET_SHMEDIA_FPU \
- || TARGET_SHMEDIA64) \
- : (GET_CODE (X) != CONST_DOUBLE \
- || GET_MODE (X) == DFmode || GET_MODE (X) == SFmode \
- || GET_MODE (X) == DImode || GET_MODE (X) == VOIDmode))
-
/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
and check its validity for a certain class.
The suitable hard regs are always accepted and all pseudo regs
extern void emit_tfmode_binop (enum rtx_code, rtx *);
extern void emit_tfmode_unop (enum rtx_code, rtx *);
extern void emit_tfmode_cvt (enum rtx_code, rtx *);
-extern bool legitimate_constant_p (rtx);
extern bool constant_address_p (rtx);
extern bool legitimate_pic_operand_p (rtx);
extern rtx sparc_legitimize_reload_address (rtx, enum machine_mode, int, int,
static void sparc_output_addr_diff_vec (rtx);
static void sparc_output_deferred_case_vectors (void);
static bool sparc_legitimate_address_p (enum machine_mode, rtx, bool);
+static bool sparc_legitimate_constant_p (enum machine_mode, rtx);
static rtx sparc_builtin_saveregs (void);
static int epilogue_renumber (rtx *, int);
static bool sparc_assemble_integer (rtx, unsigned int, int);
#undef TARGET_LEGITIMATE_ADDRESS_P
#define TARGET_LEGITIMATE_ADDRESS_P sparc_legitimate_address_p
+#undef TARGET_LEGITIMATE_CONSTANT_P
+#define TARGET_LEGITIMATE_CONSTANT_P sparc_legitimate_constant_p
+
#undef TARGET_TRAMPOLINE_INIT
#define TARGET_TRAMPOLINE_INIT sparc_trampoline_init
/* Determine if a given RTX is a valid constant. We already know this
satisfies CONSTANT_P. */
-bool
-legitimate_constant_p (rtx x)
+static bool
+sparc_legitimate_constant_p (enum machine_mode mode, rtx x)
{
switch (GET_CODE (x))
{
/* Floating point constants are generally not ok.
The only exception is 0.0 in VIS. */
if (TARGET_VIS
- && SCALAR_FLOAT_MODE_P (GET_MODE (x))
- && const_zero_operand (x, GET_MODE (x)))
+ && SCALAR_FLOAT_MODE_P (mode)
+ && const_zero_operand (x, mode))
return true;
return false;
/* Vector constants are generally not ok.
The only exception is 0 in VIS. */
if (TARGET_VIS
- && const_zero_operand (x, GET_MODE (x)))
+ && const_zero_operand (x, mode))
return true;
return false;
case CONST:
if (flag_pic && pic_address_needs_scratch (x))
return false;
- return legitimate_constant_p (x);
+ return sparc_legitimate_constant_p (Pmode, x);
case SYMBOL_REF:
- return !flag_pic && legitimate_constant_p (x);
+ return !flag_pic && sparc_legitimate_constant_p (Pmode, x);
default:
return false;
#define LEGITIMATE_PIC_OPERAND_P(X) legitimate_pic_operand_p (X)
-/* Nonzero if the constant value X is a legitimate general operand.
- Anything can be made to work except floating point constants.
- If TARGET_VIS, 0.0 can be made to work as well. */
-
-#define LEGITIMATE_CONSTANT_P(X) legitimate_constant_p (X)
-
/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
and check its validity for a certain class.
We have two alternate definitions for each of them.
(define_predicate "vec_imm_operand"
(and (match_code "const_int,const_double,const_vector")
- (match_test "spu_legitimate_constant_p (op)")))
+ (match_test "spu_legitimate_constant_p (mode, op)")))
(define_predicate "spu_arith_operand"
(match_code "reg,subreg,const_int,const_vector")
extern bool exp2_immediate_p (rtx op, enum machine_mode mode, int low,
int high);
extern int spu_constant_address_p (rtx x);
-extern int spu_legitimate_constant_p (rtx x);
+extern bool spu_legitimate_constant_p (enum machine_mode, rtx);
extern int spu_initial_elimination_offset (int from, int to);
extern rtx spu_function_value (const_tree type, const_tree func);
extern void spu_setup_incoming_varargs (int *cum, enum machine_mode mode,
#undef TARGET_LEGITIMATE_ADDRESS_P
#define TARGET_LEGITIMATE_ADDRESS_P spu_legitimate_address_p
+#undef TARGET_LEGITIMATE_CONSTANT_P
+#define TARGET_LEGITIMATE_CONSTANT_P spu_legitimate_constant_p
+
#undef TARGET_TRAMPOLINE_INIT
#define TARGET_TRAMPOLINE_INIT spu_trampoline_init
- a 64-bit constant where the high and low bits are identical
(DImode, DFmode)
- a 128-bit constant where the four 32-bit words match. */
-int
-spu_legitimate_constant_p (rtx x)
+bool
+spu_legitimate_constant_p (enum machine_mode mode, rtx x)
{
if (GET_CODE (x) == HIGH)
x = XEXP (x, 0);
/* V4SI with all identical symbols is valid. */
if (!flag_pic
- && GET_MODE (x) == V4SImode
+ && mode == V4SImode
&& (GET_CODE (CONST_VECTOR_ELT (x, 0)) == SYMBOL_REF
|| GET_CODE (CONST_VECTOR_ELT (x, 0)) == LABEL_REF
|| GET_CODE (CONST_VECTOR_ELT (x, 0)) == CONST))
of a CONST_VECTOR here (or in CONST_COSTS) doesn't help though
because this cost will only be compared against a single insn.
if (code == CONST_VECTOR)
- return (LEGITIMATE_CONSTANT_P(x)) ? cost : COSTS_N_INSNS(6);
+ return spu_legitimate_constant_p (mode, x) ? cost : COSTS_N_INSNS (6);
*/
/* Use defaults for float operations. Not accurate but good enough. */
#define MAX_REGS_PER_ADDRESS 2
-#define LEGITIMATE_CONSTANT_P(X) spu_legitimate_constant_p(X)
-
\f
/* Costs */
#define MAX_REGS_PER_ADDRESS 1
-#define LEGITIMATE_CONSTANT_P(X) 1
-
\f
/* Describing Relative Costs of Operations. */
{
return (TARGET_V850E2_ALL? 2 : 1);
}
+
+/* Implement TARGET_LEGITIMATE_CONSTANT_P. */
+
+static bool
+v850_legitimate_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
+{
+ return (GET_CODE (x) == CONST_DOUBLE
+ || !(GET_CODE (x) == CONST
+ && GET_CODE (XEXP (x, 0)) == PLUS
+ && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
+ && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
+ && !CONST_OK_FOR_K (INTVAL (XEXP (XEXP (x, 0), 1)))));
+}
\f
/* V850 specific attributes. */
#undef TARGET_OPTION_OPTIMIZATION_TABLE
#define TARGET_OPTION_OPTIMIZATION_TABLE v850_option_optimization_table
+#undef TARGET_LEGITIMATE_CONSTANT_P
+#define TARGET_LEGITIMATE_CONSTANT_P v850_legitimate_constant_p
+
struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-v850.h"
} while (0)
\f
-/* Nonzero if the constant value X is a legitimate general operand.
- It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
-
-#define LEGITIMATE_CONSTANT_P(X) \
- (GET_CODE (X) == CONST_DOUBLE \
- || !(GET_CODE (X) == CONST \
- && GET_CODE (XEXP (X, 0)) == PLUS \
- && GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF \
- && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT \
- && ! CONST_OK_FOR_K (INTVAL (XEXP (XEXP (X, 0), 1)))))
-
/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
return the mode to be used for the comparison.
<http://www.gnu.org/licenses/>. */
extern bool legitimate_constant_address_p (rtx);
-extern bool legitimate_constant_p (rtx);
extern bool vax_mode_dependent_address_p (rtx);
#ifdef RTX_CODE
return true;
}
-/* True if the constant value X is a legitimate general operand.
- It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
-
-bool
-legitimate_constant_p (rtx x ATTRIBUTE_UNUSED)
-{
- return true;
-}
-
/* The other macros defined here are used only in legitimate_address_p (). */
/* Nonzero if X is a hard reg that can be used as an index
#define CONSTANT_ADDRESS_P(X) legitimate_constant_address_p (X)
-/* Nonzero if the constant value X is a legitimate general operand.
- It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
-
-#define LEGITIMATE_CONSTANT_P(X) legitimate_constant_p (X)
-
/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
and check its validity for a certain class.
We have two alternate definitions for each of them.
struct secondary_reload_info *);
static bool constantpool_address_p (const_rtx addr);
+static bool xtensa_legitimate_constant_p (enum machine_mode, rtx);
static const int reg_nonleaf_alloc_order[FIRST_PSEUDO_REGISTER] =
REG_ALLOC_ORDER;
#undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
#define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA xtensa_output_addr_const_extra
+#undef TARGET_LEGITIMATE_CONSTANT_P
+#define TARGET_LEGITIMATE_CONSTANT_P xtensa_legitimate_constant_p
+
struct gcc_target targetm = TARGET_INITIALIZER;
\f
LCT_NORMAL, VOIDmode, 1, XEXP (m_tramp, 0), Pmode);
}
+/* Implement TARGET_LEGITIMATE_CONSTANT_P. */
+
+static bool
+xtensa_legitimate_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
+{
+ return !xtensa_tls_referenced_p (x);
+}
#include "gt-xtensa.h"
|| GET_CODE (X) == CONST_INT || GET_CODE (X) == HIGH \
|| (GET_CODE (X) == CONST)))
-/* Nonzero if the constant value X is a legitimate general operand.
- It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
-#define LEGITIMATE_CONSTANT_P(X) (! xtensa_tls_referenced_p (X))
-
/* A C expression that is nonzero if X is a legitimate immediate
operand on the target machine when generating position independent
code. */
register, so @code{TARGET_PREFERRED_RELOAD_CLASS} returns @code{NO_REGS} when
@var{x} is a floating-point constant. If the constant can't be loaded
into any kind of register, code generation will be better if
-@code{LEGITIMATE_CONSTANT_P} makes the constant illegitimate instead
+@code{TARGET_LEGITIMATE_CONSTANT_P} makes the constant illegitimate instead
of using @code{TARGET_PREFERRED_RELOAD_CLASS}.
If an insn has pseudos in it after register allocation, reload will go
register, so @code{PREFERRED_RELOAD_CLASS} returns @code{NO_REGS} when
@var{x} is a floating-point constant. If the constant can't be loaded
into any kind of register, code generation will be better if
-@code{LEGITIMATE_CONSTANT_P} makes the constant illegitimate instead
-of using @code{PREFERRED_RELOAD_CLASS}.
+@code{TARGET_LEGITIMATE_CONSTANT_P} makes the constant illegitimate instead
+of using @code{TARGET_PREFERRED_RELOAD_CLASS}.
If an insn has pseudos in it after register allocation, reload will go
through the alternatives and call repeatedly @code{PREFERRED_RELOAD_CLASS}
@code{TARGET_MODE_DEPENDENT_ADDRESS_P} target hook.
@end defmac
-@defmac LEGITIMATE_CONSTANT_P (@var{x})
-A C expression that is nonzero if @var{x} is a legitimate constant for
-an immediate operand on the target machine. You can assume that
-@var{x} satisfies @code{CONSTANT_P}, so you need not check this. In fact,
-@samp{1} is a suitable definition for this macro on machines where
-anything @code{CONSTANT_P} is valid.
-@end defmac
+@deftypefn {Target Hook} bool TARGET_LEGITIMATE_CONSTANT_P (enum machine_mode @var{mode}, rtx @var{x})
+This hook returns true if @var{x} is a legitimate constant for a
+@var{mode}-mode immediate operand on the target machine. You can assume that
+@var{x} satisfies @code{CONSTANT_P}, so you need not check this.
+
+The default definition returns true.
+@end deftypefn
@deftypefn {Target Hook} rtx TARGET_DELEGITIMIZE_ADDRESS (rtx @var{x})
This hook is used to undo the possibly obfuscating effects of the
register, so @code{TARGET_PREFERRED_RELOAD_CLASS} returns @code{NO_REGS} when
@var{x} is a floating-point constant. If the constant can't be loaded
into any kind of register, code generation will be better if
-@code{LEGITIMATE_CONSTANT_P} makes the constant illegitimate instead
+@code{TARGET_LEGITIMATE_CONSTANT_P} makes the constant illegitimate instead
of using @code{TARGET_PREFERRED_RELOAD_CLASS}.
If an insn has pseudos in it after register allocation, reload will go
register, so @code{PREFERRED_RELOAD_CLASS} returns @code{NO_REGS} when
@var{x} is a floating-point constant. If the constant can't be loaded
into any kind of register, code generation will be better if
-@code{LEGITIMATE_CONSTANT_P} makes the constant illegitimate instead
-of using @code{PREFERRED_RELOAD_CLASS}.
+@code{TARGET_LEGITIMATE_CONSTANT_P} makes the constant illegitimate instead
+of using @code{TARGET_PREFERRED_RELOAD_CLASS}.
If an insn has pseudos in it after register allocation, reload will go
through the alternatives and call repeatedly @code{PREFERRED_RELOAD_CLASS}
@code{TARGET_MODE_DEPENDENT_ADDRESS_P} target hook.
@end defmac
-@defmac LEGITIMATE_CONSTANT_P (@var{x})
-A C expression that is nonzero if @var{x} is a legitimate constant for
-an immediate operand on the target machine. You can assume that
-@var{x} satisfies @code{CONSTANT_P}, so you need not check this. In fact,
-@samp{1} is a suitable definition for this macro on machines where
-anything @code{CONSTANT_P} is valid.
-@end defmac
+@hook TARGET_LEGITIMATE_CONSTANT_P
+This hook returns true if @var{x} is a legitimate constant for a
+@var{mode}-mode immediate operand on the target machine. You can assume that
+@var{x} satisfies @code{CONSTANT_P}, so you need not check this.
+
+The default definition returns true.
+@end deftypefn
@hook TARGET_DELEGITIMIZE_ADDRESS
This hook is used to undo the possibly obfuscating effects of the
if (nregs == 0)
return;
- if (CONSTANT_P (x) && ! LEGITIMATE_CONSTANT_P (x))
+ if (CONSTANT_P (x) && !targetm.legitimate_constant_p (mode, x))
x = validize_mem (force_const_mem (mode, x));
/* See if the machine can do this with a load multiple insn. */
offset -= size;
cst = (*constfun) (constfundata, offset, mode);
- if (!LEGITIMATE_CONSTANT_P (cst))
+ if (!targetm.legitimate_constant_p (mode, cst))
return 0;
if (!reverse)
y_cst = y;
- if (!LEGITIMATE_CONSTANT_P (y))
+ if (!targetm.legitimate_constant_p (mode, y))
{
y = force_const_mem (mode, y);
REAL_VALUE_FROM_CONST_DOUBLE (r, y);
- if (LEGITIMATE_CONSTANT_P (y))
+ if (targetm.legitimate_constant_p (dstmode, y))
oldcost = rtx_cost (y, SET, speed);
else
oldcost = rtx_cost (force_const_mem (dstmode, y), SET, speed);
trunc_y = CONST_DOUBLE_FROM_REAL_VALUE (r, srcmode);
- if (LEGITIMATE_CONSTANT_P (trunc_y))
+ if (targetm.legitimate_constant_p (srcmode, trunc_y))
{
/* Skip if the target needs extra instructions to perform
the extension. */
by setting SKIP to 0. */
skip = (reg_parm_stack_space == 0) ? 0 : not_stack;
- if (CONSTANT_P (x) && ! LEGITIMATE_CONSTANT_P (x))
+ if (CONSTANT_P (x) && !targetm.legitimate_constant_p (mode, x))
x = validize_mem (force_const_mem (mode, x));
/* If X is a hard register in a non-integer mode, copy it into a pseudo;
constant and we don't need a memory reference. */
if (CONSTANT_P (op0)
&& mode2 != BLKmode
- && LEGITIMATE_CONSTANT_P (op0)
+ && targetm.legitimate_constant_p (mode2, op0)
&& !must_force_mem)
op0 = force_reg (mode2, op0);
return false;
}
+/* Generic hook that takes (enum machine_mode, rtx) and returns true. */
+bool
+hook_bool_mode_rtx_true (enum machine_mode mode ATTRIBUTE_UNUSED,
+ rtx value ATTRIBUTE_UNUSED)
+{
+ return true;
+}
+
/* Generic hook that takes (FILE *, const char *) and does nothing. */
void
hook_void_FILEptr_constcharptr (FILE *a ATTRIBUTE_UNUSED, const char *b ATTRIBUTE_UNUSED)
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_rtx_true (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);
&& (note = find_reg_note (insn, REG_EQUIV, NULL_RTX)) != NULL_RTX
&& ((MEM_P (XEXP (note, 0)))
|| (CONSTANT_P (XEXP (note, 0))
- && LEGITIMATE_CONSTANT_P (XEXP (note, 0))
+ && targetm.legitimate_constant_p (GET_MODE (SET_DEST (set)),
+ XEXP (note, 0))
&& REG_N_SETS (REGNO (SET_DEST (set))) == 1)))
{
enum reg_class cl = GENERAL_REGS;
return ((GET_MODE (op) == VOIDmode || GET_MODE (op) == mode
|| mode == VOIDmode)
&& (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op))
- && LEGITIMATE_CONSTANT_P (op));
+ && targetm.legitimate_constant_p (mode == VOIDmode
+ ? GET_MODE (op)
+ : mode, op));
/* Except for certain constants with VOIDmode, already checked for,
OP's mode must match MODE if MODE specifies a mode. */
&& (GET_MODE (op) == mode || mode == VOIDmode
|| GET_MODE (op) == VOIDmode)
&& (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op))
- && LEGITIMATE_CONSTANT_P (op));
+ && targetm.legitimate_constant_p (mode == VOIDmode
+ ? GET_MODE (op)
+ : mode, op));
}
/* Returns 1 if OP is an operand that is a CONST_INT. */
simplify_gen_subreg (GET_MODE (x), reg_equiv_constant (regno),
GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x));
gcc_assert (tem);
- if (CONSTANT_P (tem) && !LEGITIMATE_CONSTANT_P (tem))
+ if (CONSTANT_P (tem)
+ && !targetm.legitimate_constant_p (GET_MODE (x), tem))
{
tem = force_const_mem (GET_MODE (x), tem);
i = find_reloads_address (GET_MODE (tem), &tem, XEXP (tem, 0),
enum reload_type type, int ind_levels)
{
if (CONSTANT_P (x)
- && (! LEGITIMATE_CONSTANT_P (x)
+ && (!targetm.legitimate_constant_p (mode, x)
|| targetm.preferred_reload_class (x, rclass) == NO_REGS))
{
x = force_const_mem (mode, x);
else if (GET_CODE (x) == PLUS
&& CONSTANT_P (XEXP (x, 1))
- && (! LEGITIMATE_CONSTANT_P (XEXP (x, 1))
+ && (!targetm.legitimate_constant_p (GET_MODE (x), XEXP (x, 1))
|| targetm.preferred_reload_class (XEXP (x, 1), rclass)
== NO_REGS))
{
}
else if (function_invariant_p (x))
{
+ enum machine_mode mode;
+
+ mode = GET_MODE (SET_DEST (set));
if (GET_CODE (x) == PLUS)
{
/* This is PLUS of frame pointer and a constant,
reg_equiv_invariant (i) = x;
num_eliminable_invariants++;
}
- else if (LEGITIMATE_CONSTANT_P (x))
+ else if (targetm.legitimate_constant_p (mode, x))
reg_equiv_constant (i) = x;
else
{
- reg_equiv_memory_loc (i)
- = force_const_mem (GET_MODE (SET_DEST (set)), x);
+ reg_equiv_memory_loc (i) = force_const_mem (mode, x);
if (! reg_equiv_memory_loc (i))
reg_equiv_init (i) = NULL_RTX;
}
LABEL_ALIGN_MAX_SKIP LOOP_ALIGN_MAX_SKIP \
LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP JUMP_ALIGN_MAX_SKIP \
CAN_DEBUG_WITHOUT_FP UNLIKELY_EXECUTED_TEXT_SECTION_NAME \
- HOT_TEXT_SECTION_NAME
+ HOT_TEXT_SECTION_NAME LEGITIMATE_CONSTANT_P
/* Other obsolete target macros, or macros that used to be in target
headers and were not used, and may be obsolete or may never have
unsigned, (unsigned nunroll, struct loop *loop),
NULL)
+/* True if X is a legitimate MODE-mode immediate operand. */
+DEFHOOK
+(legitimate_constant_p,
+ "",
+ bool, (enum machine_mode mode, rtx x),
+ hook_bool_mode_rtx_true)
+
/* True if the constant X cannot be placed in the constant pool. */
DEFHOOK
(cannot_force_const_mem,