From: rsandifo Date: Thu, 21 Apr 2011 09:38:43 +0000 (+0000) Subject: gcc/ X-Git-Url: http://git.sourceforge.jp/view?a=commitdiff_plain;h=ca3163600e6f061e70fd1bf05ce1529e1b831dac;p=pf3gnuchains%2Fgcc-fork.git gcc/ * 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): 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@172814 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3f346fc8dd8..95f931b7570 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,208 @@ 2011-04-21 Richard Sandiford + * 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): 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 + * 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. diff --git a/gcc/calls.c b/gcc/calls.c index bb95852bf84..89b248cef38 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -690,7 +690,7 @@ precompute_register_parameters (int num_actuals, struct arg_data *args, /* 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, @@ -3447,7 +3447,8 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, /* 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; @@ -3488,7 +3489,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, /* 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)) diff --git a/gcc/config/alpha/alpha-protos.h b/gcc/config/alpha/alpha-protos.h index 1db35757bd6..58723aa81a4 100644 --- a/gcc/config/alpha/alpha-protos.h +++ b/gcc/config/alpha/alpha-protos.h @@ -34,7 +34,7 @@ extern void alpha_output_filename (FILE *, const char *); 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); diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index ba0dfe633cc..4cbafa02f91 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -2023,15 +2023,14 @@ alpha_extract_integer (rtx x, HOST_WIDE_INT *p0, HOST_WIDE_INT *p1) *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)) @@ -9864,6 +9863,8 @@ alpha_conditional_register_usage (void) #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 diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h index 6f476f4515b..15567cd3cf7 100644 --- a/gcc/config/alpha/alpha.h +++ b/gcc/config/alpha/alpha.h @@ -808,11 +808,6 @@ extern int alpha_memory_latency; (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. diff --git a/gcc/config/alpha/predicates.md b/gcc/config/alpha/predicates.md index e43564dbc34..c1e3115aead 100644 --- a/gcc/config/alpha/predicates.md +++ b/gcc/config/alpha/predicates.md @@ -218,14 +218,14 @@ 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: diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index da3241d2bf3..fa252833dae 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -82,7 +82,6 @@ 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 (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 0f944fd869d..97d2d6f47e5 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -144,6 +144,8 @@ static void arm_internal_label (FILE *, const char *, unsigned long); 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); @@ -528,6 +530,9 @@ static const struct default_options arm_option_optimization_table[] = #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 @@ -6497,9 +6502,41 @@ arm_tls_referenced_p (rtx x) 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; diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index 76efdec8e50..43323942a44 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -1746,27 +1746,6 @@ typedef struct #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 diff --git a/gcc/config/avr/avr.h b/gcc/config/avr/avr.h index b0c1b49486e..5f4ceff0214 100644 --- a/gcc/config/avr/avr.h +++ b/gcc/config/avr/avr.h @@ -421,8 +421,6 @@ do { \ } \ } while(0) -#define LEGITIMATE_CONSTANT_P(X) 1 - #define BRANCH_COST(speed_p, predictable_p) 0 #define SLOW_BYTE_ACCESS 0 diff --git a/gcc/config/bfin/bfin-protos.h b/gcc/config/bfin/bfin-protos.h index 1e85e16ffea..40c641c46c0 100644 --- a/gcc/config/bfin/bfin-protos.h +++ b/gcc/config/bfin/bfin-protos.h @@ -73,7 +73,6 @@ extern char *bfin_asm_long (void); 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); diff --git a/gcc/config/bfin/bfin.c b/gcc/config/bfin/bfin.c index 2a9730fa902..25316cf679c 100644 --- a/gcc/config/bfin/bfin.c +++ b/gcc/config/bfin/bfin.c @@ -2163,7 +2163,7 @@ expand_move (rtx *operands, enum machine_mode mode) 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; @@ -3070,8 +3070,8 @@ bfin_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, 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; @@ -6682,6 +6682,9 @@ bfin_conditional_register_usage (void) #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 diff --git a/gcc/config/bfin/bfin.h b/gcc/config/bfin/bfin.h index ab3f2ea2c22..8577db7a6de 100644 --- a/gcc/config/bfin/bfin.h +++ b/gcc/config/bfin/bfin.h @@ -784,13 +784,6 @@ typedef struct { /* 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' diff --git a/gcc/config/cris/cris.h b/gcc/config/cris/cris.h index c8b7d2ff4c5..57bdd4677c2 100644 --- a/gcc/config/cris/cris.h +++ b/gcc/config/cris/cris.h @@ -1020,8 +1020,6 @@ struct cum_args {int regs;}; } \ while (0) -#define LEGITIMATE_CONSTANT_P(X) 1 - /* Node: Condition Code */ diff --git a/gcc/config/fr30/fr30.h b/gcc/config/fr30/fr30.h index ca483fa88ea..d9884084907 100644 --- a/gcc/config/fr30/fr30.h +++ b/gcc/config/fr30/fr30.h @@ -667,12 +667,6 @@ enum reg_class 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 - /*}}}*/ /*{{{ Describing Relative Costs of Operations */ diff --git a/gcc/config/frv/frv-protos.h b/gcc/config/frv/frv-protos.h index c7223a76420..62e2506f31e 100644 --- a/gcc/config/frv/frv-protos.h +++ b/gcc/config/frv/frv-protos.h @@ -79,7 +79,6 @@ extern int frv_hard_regno_mode_ok (int, enum machine_mode); 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 */ diff --git a/gcc/config/frv/frv.c b/gcc/config/frv/frv.c index 5b0c0847e15..9e2f7189b1b 100644 --- a/gcc/config/frv/frv.c +++ b/gcc/config/frv/frv.c @@ -372,6 +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_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 *, @@ -472,6 +473,8 @@ static const struct default_options frv_option_optimization_table[] = #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 @@ -603,7 +606,7 @@ frv_const_unspec_p (rtx x, struct frv_unspec *unspec) 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. @@ -6749,16 +6752,14 @@ frv_class_max_nregs (enum reg_class rclass, enum machine_mode mode) `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. @@ -6775,7 +6776,7 @@ frv_legitimate_constant_p (rtx x) 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. */ diff --git a/gcc/config/frv/frv.h b/gcc/config/frv/frv.h index 937ae1809a5..02559517322 100644 --- a/gcc/config/frv/frv.h +++ b/gcc/config/frv/frv.h @@ -1502,12 +1502,6 @@ __asm__("\n" \ #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 diff --git a/gcc/config/h8300/h8300-protos.h b/gcc/config/h8300/h8300-protos.h index bb2d5e76097..da3b75ab3bd 100644 --- a/gcc/config/h8300/h8300-protos.h +++ b/gcc/config/h8300/h8300-protos.h @@ -60,8 +60,6 @@ extern int byte_accesses_mergeable_p (rtx, rtx); 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); diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c index 93febd1e517..de41d702f46 100644 --- a/gcc/config/h8300/h8300.c +++ b/gcc/config/h8300/h8300.c @@ -5749,14 +5749,6 @@ h8300_hard_regno_scratch_ok (unsigned int regno) } -/* 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 diff --git a/gcc/config/h8300/h8300.h b/gcc/config/h8300/h8300.h index eb774587ecf..015df600154 100644 --- a/gcc/config/h8300/h8300.h +++ b/gcc/config/h8300/h8300.h @@ -528,11 +528,6 @@ struct cum_arg && 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. diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index d434d758794..ccba8484bdc 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -55,7 +55,6 @@ extern bool ix86_expand_movmem (rtx, rtx, rtx, rtx, rtx, rtx); 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); diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index c4b18ef56ad..b55c67bb564 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -11918,8 +11918,8 @@ darwin_local_data_pic (rtx disp) /* 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)) { @@ -12005,7 +12005,7 @@ legitimate_constant_p (rtx 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)) @@ -12018,7 +12018,7 @@ ix86_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x) default: break; } - return !legitimate_constant_p (x); + return !ix86_legitimate_constant_p (mode, x); } @@ -12356,7 +12356,8 @@ ix86_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED, /* 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 @@ -12386,9 +12387,9 @@ ix86_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED, 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 @@ -35454,6 +35455,9 @@ ix86_autovectorize_vector_sizes (void) #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 diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 10fc1260b58..5baa2b842e8 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -1644,11 +1644,6 @@ typedef struct ix86_args { #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. diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index a6956b8a316..ff0e723593c 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -4056,7 +4056,7 @@ "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) @@ -4162,7 +4162,7 @@ "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) @@ -6076,7 +6076,7 @@ ;; 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" "") diff --git a/gcc/config/ia64/ia64-protos.h b/gcc/config/ia64/ia64-protos.h index 107a7ccb983..627271e8d7d 100644 --- a/gcc/config/ia64/ia64-protos.h +++ b/gcc/config/ia64/ia64-protos.h @@ -26,8 +26,6 @@ extern int ia64_st_address_bypass_p (rtx, rtx); 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); diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index 60832793017..6c6904bc4f2 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -316,6 +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_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); @@ -605,6 +606,9 @@ static const struct default_options ia64_option_optimization_table[] = #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 @@ -953,8 +957,8 @@ tls_symbolic_operand_type (rtx addr) /* 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)) { @@ -963,8 +967,7 @@ ia64_legitimate_constant_p (rtx 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); @@ -986,25 +989,21 @@ ia64_legitimate_constant_p (rtx 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; diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h index a894df8dff7..2da614998e1 100644 --- a/gcc/config/ia64/ia64.h +++ b/gcc/config/ia64/ia64.h @@ -1200,11 +1200,6 @@ do { \ 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) /* Condition Code Status */ diff --git a/gcc/config/iq2000/iq2000.h b/gcc/config/iq2000/iq2000.h index a69204e007b..b9717ff0f52 100644 --- a/gcc/config/iq2000/iq2000.h +++ b/gcc/config/iq2000/iq2000.h @@ -389,8 +389,6 @@ typedef struct iq2000_args #define REG_OK_FOR_INDEX_P(X) 0 -#define LEGITIMATE_CONSTANT_P(X) (1) - /* Describing Relative Costs of Operations. */ diff --git a/gcc/config/lm32/lm32-protos.h b/gcc/config/lm32/lm32-protos.h index bc086d2ee0b..aad36743279 100644 --- a/gcc/config/lm32/lm32-protos.h +++ b/gcc/config/lm32/lm32-protos.h @@ -36,4 +36,3 @@ extern rtx lm32_legitimize_pic_address (rtx, enum machine_mode, rtx); 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); diff --git a/gcc/config/lm32/lm32.c b/gcc/config/lm32/lm32.c index 2c7131a5dfc..ac368c84bac 100644 --- a/gcc/config/lm32/lm32.c +++ b/gcc/config/lm32/lm32.c @@ -81,6 +81,7 @@ static rtx lm32_function_arg (CUMULATIVE_ARGS * cum, 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[] = @@ -119,6 +120,8 @@ 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; @@ -1235,13 +1238,13 @@ lm32_move_ok (enum machine_mode mode, rtx operands[2]) { 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; diff --git a/gcc/config/lm32/lm32.h b/gcc/config/lm32/lm32.h index 3d8f77a5a77..75a24160fd9 100644 --- a/gcc/config/lm32/lm32.h +++ b/gcc/config/lm32/lm32.h @@ -346,8 +346,6 @@ enum reg_class #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. */ /*-------------------------*/ diff --git a/gcc/config/m32c/m32c-protos.h b/gcc/config/m32c/m32c-protos.h index f7c32e7e877..fdaa8a8beac 100644 --- a/gcc/config/m32c/m32c-protos.h +++ b/gcc/config/m32c/m32c-protos.h @@ -65,7 +65,6 @@ int m32c_hard_regno_ok (int, MM); 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); diff --git a/gcc/config/m32c/m32c.c b/gcc/config/m32c/m32c.c index c603770ad60..3770fefb6da 100644 --- a/gcc/config/m32c/m32c.c +++ b/gcc/config/m32c/m32c.c @@ -2148,15 +2148,6 @@ m32c_legitimize_reload_address (rtx * x, 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 diff --git a/gcc/config/m32c/m32c.h b/gcc/config/m32c/m32c.h index 6016ee56a13..1a44b1b156d 100644 --- a/gcc/config/m32c/m32c.h +++ b/gcc/config/m32c/m32c.h @@ -570,8 +570,6 @@ typedef struct m32c_cumulative_args 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 diff --git a/gcc/config/m32r/m32r.c b/gcc/config/m32r/m32r.c index 86af3b3a8c9..1580f47edd1 100644 --- a/gcc/config/m32r/m32r.c +++ b/gcc/config/m32r/m32r.c @@ -99,6 +99,7 @@ static void m32r_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, 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); /* M32R specific attributes. */ @@ -211,6 +212,9 @@ static const struct default_options m32r_option_optimization_table[] = #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 @@ -2935,3 +2939,21 @@ m32r_conditional_register_usage (void) 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); +} diff --git a/gcc/config/m32r/m32r.h b/gcc/config/m32r/m32r.h index 26d3ef978c4..50b5b2aa1a3 100644 --- a/gcc/config/m32r/m32r.h +++ b/gcc/config/m32r/m32r.h @@ -749,19 +749,6 @@ L2: .word STATIC || 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)) /* Condition code usage. */ diff --git a/gcc/config/m68k/m68k-protos.h b/gcc/config/m68k/m68k-protos.h index ad02026309a..8017cf25ed0 100644 --- a/gcc/config/m68k/m68k-protos.h +++ b/gcc/config/m68k/m68k-protos.h @@ -56,6 +56,7 @@ extern void notice_update_cc (rtx, rtx); 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); diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c index 7553183d541..b01e54f505e 100644 --- a/gcc/config/m68k/m68k.c +++ b/gcc/config/m68k/m68k.c @@ -299,6 +299,9 @@ const char *m68k_library_id_string = "_current_shared_library_a5_offset_"; #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, @@ -1034,7 +1037,7 @@ m68k_expand_prologue (void) && 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); @@ -2163,6 +2166,14 @@ m68k_legitimate_mem_p (rtx x, struct m68k_address *address) 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. */ diff --git a/gcc/config/m68k/m68k.h b/gcc/config/m68k/m68k.h index d853d783fd0..3c9dbb3ceb4 100644 --- a/gcc/config/m68k/m68k.h +++ b/gcc/config/m68k/m68k.h @@ -664,13 +664,7 @@ __transfer_from_trampoline () \ ((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 diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md index f89037f2e96..16697bf95f7 100644 --- a/gcc/config/m68k/m68k.md +++ b/gcc/config/m68k/m68k.md @@ -1383,7 +1383,7 @@ ;; ??? 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" "") diff --git a/gcc/config/mcore/mcore.c b/gcc/config/mcore/mcore.c index 741452ec05f..32ff5fddf96 100644 --- a/gcc/config/mcore/mcore.c +++ b/gcc/config/mcore/mcore.c @@ -138,6 +138,7 @@ static unsigned int mcore_function_arg_boundary (enum machine_mode, 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); /* MCore specific attributes. */ @@ -247,6 +248,9 @@ static const struct default_options mcore_option_optimization_table[] = #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; /* Adjust the stack and return the number of bytes taken to do it. */ @@ -3205,3 +3209,13 @@ mcore_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) 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; +} diff --git a/gcc/config/mcore/mcore.h b/gcc/config/mcore/mcore.h index fa3909e628f..278a8ccf0dc 100644 --- a/gcc/config/mcore/mcore.h +++ b/gcc/config/mcore/mcore.h @@ -529,13 +529,6 @@ extern const enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER]; /* 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. diff --git a/gcc/config/mep/mep-protos.h b/gcc/config/mep/mep-protos.h index 12cef58a882..edfbaf7575c 100644 --- a/gcc/config/mep/mep-protos.h +++ b/gcc/config/mep/mep-protos.h @@ -43,7 +43,6 @@ extern void mep_split_wide_move (rtx *, enum machine_mode); #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); diff --git a/gcc/config/mep/mep.c b/gcc/config/mep/mep.c index b8ef4402c56..60cf4ebff71 100644 --- a/gcc/config/mep/mep.c +++ b/gcc/config/mep/mep.c @@ -1195,9 +1195,10 @@ mep_multi_slot (rtx x) 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 @@ -1300,7 +1301,7 @@ mep_legitimate_address (enum machine_mode mode, rtx x, int strict) 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 @@ -7477,6 +7478,8 @@ mep_asm_init_sections (void) #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; diff --git a/gcc/config/mep/mep.h b/gcc/config/mep/mep.h index d6d6c2f25d0..f5de83f5d1d 100644 --- a/gcc/config/mep/mep.h +++ b/gcc/config/mep/mep.h @@ -566,9 +566,6 @@ typedef struct #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 diff --git a/gcc/config/microblaze/microblaze-protos.h b/gcc/config/microblaze/microblaze-protos.h index 56dca55dc45..0a7d1c7f56d 100644 --- a/gcc/config/microblaze/microblaze-protos.h +++ b/gcc/config/microblaze/microblaze-protos.h @@ -35,7 +35,6 @@ extern void microblaze_expand_divide (rtx *); 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); diff --git a/gcc/config/microblaze/microblaze.c b/gcc/config/microblaze/microblaze.c index 5796bc7c166..1cec425b15d 100644 --- a/gcc/config/microblaze/microblaze.c +++ b/gcc/config/microblaze/microblaze.c @@ -152,7 +152,7 @@ int microblaze_no_unsafe_delay; 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; @@ -210,7 +210,7 @@ static int microblaze_interrupt_function_p (tree); 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; @@ -218,7 +218,7 @@ microblaze_const_double_ok (rtx op, enum machine_mode mode) if (GET_CODE (op) != CONST_DOUBLE) return 0; - if (mode == VOIDmode) + if (GET_MODE (op) == VOIDmode) return 1; if (mode != SFmode && mode != DFmode) @@ -2951,6 +2951,16 @@ microblaze_adjust_cost (rtx insn ATTRIBUTE_UNUSED, rtx link, 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); +} #undef TARGET_ENCODE_SECTION_INFO #define TARGET_ENCODE_SECTION_INFO microblaze_encode_section_info @@ -3040,6 +3050,9 @@ microblaze_adjust_cost (rtx insn ATTRIBUTE_UNUSED, rtx link, #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; #include "gt-microblaze.h" diff --git a/gcc/config/microblaze/microblaze.h b/gcc/config/microblaze/microblaze.h index 18cd72d0ee5..6cfbf68fae7 100644 --- a/gcc/config/microblaze/microblaze.h +++ b/gcc/config/microblaze/microblaze.h @@ -524,12 +524,6 @@ typedef struct microblaze_args 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 diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index f6a4ec98cbe..12caf8e9169 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -1535,6 +1535,14 @@ mips_build_integer (struct mips_integer_op *codes, } } +/* 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; +} + /* Return true if symbols of type TYPE require a GOT access. */ static bool @@ -1997,7 +2005,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 (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; @@ -2016,7 +2024,7 @@ mips_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x) 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); @@ -16572,6 +16580,9 @@ mips_shift_truncation_mask (enum machine_mode mode) #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 diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index 1c1917c18ac..4386ce0028e 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -2317,8 +2317,6 @@ typedef struct mips_args { #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'. */ diff --git a/gcc/config/mips/predicates.md b/gcc/config/mips/predicates.md index 7430dd32b78..022868becd9 100644 --- a/gcc/config/mips/predicates.md +++ b/gcc/config/mips/predicates.md @@ -173,7 +173,7 @@ (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; diff --git a/gcc/config/mmix/mmix-protos.h b/gcc/config/mmix/mmix-protos.h index 2e6abd85aaf..c609c1a2e35 100644 --- a/gcc/config/mmix/mmix-protos.h +++ b/gcc/config/mmix/mmix-protos.h @@ -73,7 +73,6 @@ extern rtx mmix_return_addr_rtx (int, rtx); 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); diff --git a/gcc/config/mmix/mmix.c b/gcc/config/mmix/mmix.c index c96fdcb66a5..80f0d8439a4 100644 --- a/gcc/config/mmix/mmix.c +++ b/gcc/config/mmix/mmix.c @@ -130,6 +130,7 @@ static void mmix_target_asm_function_prologue (FILE *, HOST_WIDE_INT); 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); @@ -252,6 +253,8 @@ static const struct default_options mmix_option_optimization_table[] = #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 @@ -1152,10 +1155,10 @@ mmix_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED, 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); @@ -1829,7 +1832,7 @@ mmix_print_operand_address (FILE *stream, rtx 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; diff --git a/gcc/config/mmix/mmix.h b/gcc/config/mmix/mmix.h index f3ed940b881..09e50e04b10 100644 --- a/gcc/config/mmix/mmix.h +++ b/gcc/config/mmix/mmix.h @@ -614,9 +614,6 @@ typedef struct { int regs; int lib; } CUMULATIVE_ARGS; #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 */ diff --git a/gcc/config/mn10300/mn10300-protos.h b/gcc/config/mn10300/mn10300-protos.h index 058f5df8751..b8c19fd8760 100644 --- a/gcc/config/mn10300/mn10300-protos.h +++ b/gcc/config/mn10300/mn10300-protos.h @@ -30,7 +30,6 @@ extern rtx mn10300_legitimize_reload_address (rtx, Mmode, int, int, int); 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); diff --git a/gcc/config/mn10300/mn10300.c b/gcc/config/mn10300/mn10300.c index f00c53eaee0..635b1cb4583 100644 --- a/gcc/config/mn10300/mn10300.c +++ b/gcc/config/mn10300/mn10300.c @@ -2051,13 +2051,13 @@ mn10300_legitimize_reload_address (rtx x, 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)) { @@ -3209,6 +3209,8 @@ mn10300_reorg (void) #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 diff --git a/gcc/config/mn10300/mn10300.h b/gcc/config/mn10300/mn10300.h index b6a54b53bd3..a0e17d845db 100644 --- a/gcc/config/mn10300/mn10300.h +++ b/gcc/config/mn10300/mn10300.h @@ -557,10 +557,6 @@ do { \ } 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) mn10300_legitimate_constant_p (X) - /* Zero if this needs fixing up to become PIC. */ #define LEGITIMATE_PIC_OPERAND_P(X) \ diff --git a/gcc/config/moxie/moxie.h b/gcc/config/moxie/moxie.h index 1b5e0a3f8aa..86c66631441 100644 --- a/gcc/config/moxie/moxie.h +++ b/gcc/config/moxie/moxie.h @@ -441,10 +441,6 @@ enum reg_class /* 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 diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index ab0fe6a8a09..e3260c4105f 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -188,6 +188,7 @@ 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); +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; @@ -397,6 +398,9 @@ static const struct default_options pa_option_optimization_table[] = #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; /* Parse the -mfixed-range= option string. */ @@ -10276,4 +10280,40 @@ pa_function_section (tree decl, enum node_frequency freq, 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" diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h index f3ad883fb58..f401707c9df 100644 --- a/gcc/config/pa/pa.h +++ b/gcc/config/pa/pa.h @@ -806,37 +806,6 @@ extern int may_call_alloca; #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. */ diff --git a/gcc/config/pdp11/pdp11.c b/gcc/config/pdp11/pdp11.c index 10052e9f654..fc0c92b8d02 100644 --- a/gcc/config/pdp11/pdp11.c +++ b/gcc/config/pdp11/pdp11.c @@ -157,6 +157,7 @@ static rtx pdp11_function_arg (CUMULATIVE_ARGS *, enum machine_mode, 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. */ @@ -243,6 +244,9 @@ static const struct default_options pdp11_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 /* Implement TARGET_HANDLE_OPTION. */ @@ -1926,4 +1930,12 @@ pdp11_function_section (tree decl ATTRIBUTE_UNUSED, 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; diff --git a/gcc/config/pdp11/pdp11.h b/gcc/config/pdp11/pdp11.h index 8a896ca7551..5d389ec4edb 100644 --- a/gcc/config/pdp11/pdp11.h +++ b/gcc/config/pdp11/pdp11.h @@ -418,12 +418,6 @@ extern int may_call_alloca; #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. diff --git a/gcc/config/picochip/picochip.h b/gcc/config/picochip/picochip.h index b65a206bb90..abe6d6432b5 100644 --- a/gcc/config/picochip/picochip.h +++ b/gcc/config/picochip/picochip.h @@ -452,11 +452,6 @@ do { \ 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 - /* Condition Code Status */ diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 201c2fb5cda..4f095a26207 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -1213,6 +1213,7 @@ 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); +static bool rs6000_legitimate_constant_p (enum machine_mode, rtx); /* Hash table stuff for keeping track of TOC entries. */ @@ -1670,6 +1671,9 @@ static const struct default_options rs6000_option_optimization_table[] = #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; @@ -28275,5 +28279,22 @@ rs6000_address_for_altivec (rtx x) 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" diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index 0193db52eb2..5ae62af7ebf 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -1728,22 +1728,6 @@ typedef struct rs6000_args || 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) \ diff --git a/gcc/config/rx/rx-protos.h b/gcc/config/rx/rx-protos.h index 17f60833e71..544a30dd38b 100644 --- a/gcc/config/rx/rx-protos.h +++ b/gcc/config/rx/rx-protos.h @@ -36,7 +36,7 @@ extern void rx_emit_stack_popm (rtx *, bool); 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); diff --git a/gcc/config/rx/rx.c b/gcc/config/rx/rx.c index 4d16cc3cab0..1009c5409bc 100644 --- a/gcc/config/rx/rx.c +++ b/gcc/config/rx/rx.c @@ -1347,7 +1347,7 @@ gen_safe_add (rtx dest, rtx src, rtx val, bool is_frame_related) 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)); @@ -2446,7 +2446,7 @@ rx_is_ms_bitfield_layout (const_tree record_type ATTRIBUTE_UNUSED) 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)) { @@ -3052,6 +3052,9 @@ rx_adjust_insn_length (rtx insn, int current_length) #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" */ diff --git a/gcc/config/rx/rx.h b/gcc/config/rx/rx.h index c4436d70e4a..742d83f3414 100644 --- a/gcc/config/rx/rx.h +++ b/gcc/config/rx/rx.h @@ -144,8 +144,6 @@ #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 diff --git a/gcc/config/rx/rx.md b/gcc/config/rx/rx.md index 42a64aa7e8e..824d246cb84 100644 --- a/gcc/config/rx/rx.md +++ b/gcc/config/rx/rx.md @@ -556,7 +556,7 @@ if (MEM_P (operand0) && MEM_P (operand1)) operands[1] = copy_to_mode_reg (mode, operand1); if (CONST_INT_P (operand1) - && ! rx_is_legitimate_constant (operand1)) + && ! rx_legitimate_constant_p (mode, operand1)) FAIL; } ) diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h index 1df176e2346..79fce849a16 100644 --- a/gcc/config/s390/s390-protos.h +++ b/gcc/config/s390/s390-protos.h @@ -66,7 +66,6 @@ extern bool tls_symbolic_reference_mentioned_p (rtx); 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); diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 8454333f2ed..7d02b7f2fbf 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -2777,15 +2777,15 @@ legitimate_pic_operand_p (rtx op) /* 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 @@ -10829,6 +10829,9 @@ s390_loop_unroll_adjust (unsigned nunroll, struct loop *loop) #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 diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h index 950bf3c255b..47e0b1a5662 100644 --- a/gcc/config/s390/s390.h +++ b/gcc/config/s390/s390.h @@ -697,11 +697,6 @@ do { \ } \ } 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 \ diff --git a/gcc/config/score/score.h b/gcc/config/score/score.h index 736e770673e..1f9975600fe 100644 --- a/gcc/config/score/score.h +++ b/gcc/config/score/score.h @@ -598,8 +598,6 @@ typedef struct score_args #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) diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index 78f6f0f4fa3..c84c510eba3 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -305,6 +305,7 @@ static int sh2a_function_vector_p (tree); 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); static const struct attribute_spec sh_attribute_table[] = { @@ -598,6 +599,9 @@ static const struct default_options sh_option_optimization_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) @@ -12625,6 +12629,22 @@ sh_conditional_register_usage (void) 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; diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h index 1e4dd7adc31..4876fd6c9cd 100644 --- a/gcc/config/sh/sh.h +++ b/gcc/config/sh/sh.h @@ -1761,20 +1761,6 @@ struct sh_args { #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 diff --git a/gcc/config/sparc/sparc-protos.h b/gcc/config/sparc/sparc-protos.h index d37823f566f..fd9a3211fdb 100644 --- a/gcc/config/sparc/sparc-protos.h +++ b/gcc/config/sparc/sparc-protos.h @@ -56,7 +56,6 @@ extern void sparc_emit_fixunsdi (rtx [2], enum machine_mode); 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, diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index b112f7e3d47..4a1795ef5ae 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -382,6 +382,7 @@ static void sparc_output_addr_vec (rtx); 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); @@ -660,6 +661,9 @@ static const struct default_options sparc_option_optimization_table[] = #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 @@ -3017,8 +3021,8 @@ pic_address_needs_scratch (rtx x) /* 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)) { @@ -3035,8 +3039,8 @@ legitimate_constant_p (rtx 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; @@ -3045,7 +3049,7 @@ legitimate_constant_p (rtx x) /* 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; @@ -3072,10 +3076,10 @@ constant_address_p (rtx x) 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; diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index 47476509041..79c7f572b68 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -1539,12 +1539,6 @@ do { \ #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. diff --git a/gcc/config/spu/predicates.md b/gcc/config/spu/predicates.md index 8c6798d8063..2d2e77b5e44 100644 --- a/gcc/config/spu/predicates.md +++ b/gcc/config/spu/predicates.md @@ -58,7 +58,7 @@ (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") diff --git a/gcc/config/spu/spu-protos.h b/gcc/config/spu/spu-protos.h index fa945352731..675af028723 100644 --- a/gcc/config/spu/spu-protos.h +++ b/gcc/config/spu/spu-protos.h @@ -52,7 +52,7 @@ extern int arith_immediate_p (rtx op, enum machine_mode mode, 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, diff --git a/gcc/config/spu/spu.c b/gcc/config/spu/spu.c index 941194b4b67..4142e7e229a 100644 --- a/gcc/config/spu/spu.c +++ b/gcc/config/spu/spu.c @@ -477,6 +477,9 @@ static const struct attribute_spec spu_attribute_table[] = #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 @@ -3733,8 +3736,8 @@ ea_symbol_ref (rtx *px, void *data ATTRIBUTE_UNUSED) - 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); @@ -3746,7 +3749,7 @@ spu_legitimate_constant_p (rtx x) /* 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)) @@ -5439,7 +5442,7 @@ spu_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int *total, 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. */ diff --git a/gcc/config/spu/spu.h b/gcc/config/spu/spu.h index f0f00a998d6..16258911ef3 100644 --- a/gcc/config/spu/spu.h +++ b/gcc/config/spu/spu.h @@ -393,8 +393,6 @@ targetm.resolve_overloaded_builtin = spu_resolve_overloaded_builtin; \ #define MAX_REGS_PER_ADDRESS 2 -#define LEGITIMATE_CONSTANT_P(X) spu_legitimate_constant_p(X) - /* Costs */ diff --git a/gcc/config/stormy16/stormy16.h b/gcc/config/stormy16/stormy16.h index 3853c3f3ec6..871e523a67b 100644 --- a/gcc/config/stormy16/stormy16.h +++ b/gcc/config/stormy16/stormy16.h @@ -342,8 +342,6 @@ enum reg_class #define MAX_REGS_PER_ADDRESS 1 -#define LEGITIMATE_CONSTANT_P(X) 1 - /* Describing Relative Costs of Operations. */ diff --git a/gcc/config/v850/v850.c b/gcc/config/v850/v850.c index b0b9388a0ab..86509e0ac4c 100644 --- a/gcc/config/v850/v850.c +++ b/gcc/config/v850/v850.c @@ -3117,6 +3117,19 @@ v850_issue_rate (void) { 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))))); +} /* V850 specific attributes. */ @@ -3234,6 +3247,9 @@ static const struct attribute_spec v850_attribute_table[] = #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" diff --git a/gcc/config/v850/v850.h b/gcc/config/v850/v850.h index 1e45686e54f..5079936f416 100644 --- a/gcc/config/v850/v850.h +++ b/gcc/config/v850/v850.h @@ -633,17 +633,6 @@ do { \ } 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) \ - (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. diff --git a/gcc/config/vax/vax-protos.h b/gcc/config/vax/vax-protos.h index 6861260f300..a8f88bfa126 100644 --- a/gcc/config/vax/vax-protos.h +++ b/gcc/config/vax/vax-protos.h @@ -19,7 +19,6 @@ along with GCC; see the file COPYING3. If not see . */ extern bool legitimate_constant_address_p (rtx); -extern bool legitimate_constant_p (rtx); extern bool vax_mode_dependent_address_p (rtx); #ifdef RTX_CODE diff --git a/gcc/config/vax/vax.c b/gcc/config/vax/vax.c index 3489f54c081..cc8c3f67e94 100644 --- a/gcc/config/vax/vax.c +++ b/gcc/config/vax/vax.c @@ -1603,15 +1603,6 @@ legitimate_constant_address_p (rtx x) 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 diff --git a/gcc/config/vax/vax.h b/gcc/config/vax/vax.h index 77530aa97eb..a3e9d83e8f8 100644 --- a/gcc/config/vax/vax.h +++ b/gcc/config/vax/vax.h @@ -412,11 +412,6 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES }; #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. diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c index 2ffc39f7fd1..c312f50eca2 100644 --- a/gcc/config/xtensa/xtensa.c +++ b/gcc/config/xtensa/xtensa.c @@ -173,6 +173,7 @@ static reg_class_t xtensa_secondary_reload (bool, rtx, reg_class_t, 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; @@ -309,6 +310,9 @@ static const struct default_options xtensa_option_optimization_table[] = #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; @@ -3719,5 +3723,12 @@ xtensa_trampoline_init (rtx m_tramp, tree fndecl, rtx chain) 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" diff --git a/gcc/config/xtensa/xtensa.h b/gcc/config/xtensa/xtensa.h index c9ff80c4664..d3ce1479443 100644 --- a/gcc/config/xtensa/xtensa.h +++ b/gcc/config/xtensa/xtensa.h @@ -671,10 +671,6 @@ typedef struct xtensa_args || 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. */ diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index ec555517537..a89d0ecc83d 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -2522,7 +2522,7 @@ instruction for loading an immediate value into a floating-point 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 @@ -2559,8 +2559,8 @@ instruction for loading an immediate value into a floating-point 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} @@ -5535,13 +5535,13 @@ These are obsolete macros, replaced by the @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 diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 1c96941f643..4637088a819 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -2510,7 +2510,7 @@ instruction for loading an immediate value into a floating-point 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 @@ -2547,8 +2547,8 @@ instruction for loading an immediate value into a floating-point 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} @@ -5513,13 +5513,13 @@ These are obsolete macros, replaced by the @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 diff --git a/gcc/expr.c b/gcc/expr.c index 8040d5116b8..ecaf1d798a2 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -1485,7 +1485,7 @@ move_block_to_reg (int regno, rtx x, int nregs, enum machine_mode mode) 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. */ @@ -2296,7 +2296,7 @@ can_store_by_pieces (unsigned HOST_WIDE_INT len, offset -= size; cst = (*constfun) (constfundata, offset, mode); - if (!LEGITIMATE_CONSTANT_P (cst)) + if (!targetm.legitimate_constant_p (mode, cst)) return 0; if (!reverse) @@ -3329,7 +3329,7 @@ emit_move_insn (rtx x, rtx y) y_cst = y; - if (!LEGITIMATE_CONSTANT_P (y)) + if (!targetm.legitimate_constant_p (mode, y)) { y = force_const_mem (mode, y); @@ -3385,7 +3385,7 @@ compress_float_constant (rtx x, rtx 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); @@ -3408,7 +3408,7 @@ compress_float_constant (rtx x, rtx y) 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. */ @@ -3820,7 +3820,7 @@ emit_push_insn (rtx x, enum machine_mode mode, tree type, rtx size, 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; @@ -9093,7 +9093,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, 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); diff --git a/gcc/hooks.c b/gcc/hooks.c index a991980a987..7791a14fbee 100644 --- a/gcc/hooks.c +++ b/gcc/hooks.c @@ -109,6 +109,14 @@ hook_bool_mode_rtx_false (enum machine_mode mode ATTRIBUTE_UNUSED, 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) diff --git a/gcc/hooks.h b/gcc/hooks.h index 548dad34751..11dd7a9d816 100644 --- a/gcc/hooks.h +++ b/gcc/hooks.h @@ -35,6 +35,7 @@ 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_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); diff --git a/gcc/ira-costs.c b/gcc/ira-costs.c index de894a25223..f517386ceef 100644 --- a/gcc/ira-costs.c +++ b/gcc/ira-costs.c @@ -1294,7 +1294,8 @@ scan_one_insn (rtx insn) && (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; diff --git a/gcc/recog.c b/gcc/recog.c index c6ba1953ac9..afe985e2f27 100644 --- a/gcc/recog.c +++ b/gcc/recog.c @@ -930,7 +930,9 @@ general_operand (rtx op, enum machine_mode mode) 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. */ @@ -1107,7 +1109,9 @@ immediate_operand (rtx op, enum machine_mode 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. */ diff --git a/gcc/reload.c b/gcc/reload.c index 372eccc0fb9..045e5594195 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -4721,7 +4721,8 @@ find_reloads_toplev (rtx x, int opnum, enum reload_type type, 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), @@ -6047,7 +6048,7 @@ find_reloads_address_part (rtx x, rtx *loc, enum reg_class rclass, 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); @@ -6057,7 +6058,7 @@ find_reloads_address_part (rtx x, rtx *loc, enum reg_class rclass, 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)) { diff --git a/gcc/reload1.c b/gcc/reload1.c index 7fb427078f3..ea7df99580d 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -4161,6 +4161,9 @@ init_eliminable_invariants (rtx first, bool do_subregs) } 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, @@ -4173,12 +4176,11 @@ init_eliminable_invariants (rtx first, bool do_subregs) 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; } diff --git a/gcc/system.h b/gcc/system.h index 92293022991..81daaf1320d 100644 --- a/gcc/system.h +++ b/gcc/system.h @@ -768,7 +768,7 @@ extern void fancy_abort (const char *, int, const char *) ATTRIBUTE_NORETURN; 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 diff --git a/gcc/target.def b/gcc/target.def index ce01faa92d5..ea4d3e95aec 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -1291,6 +1291,13 @@ DEFHOOK 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,