aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2011-04-21 09:38:43 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2011-04-21 09:38:43 +0000
commit1a627b35d37649103f629cd15139387d09c4b703 (patch)
treeee9985e6dc9e4455022070aeb97c47413720a1e2 /gcc
parentfbbf66e77a385fc1901fdc33c1d977681cab39bf (diff)
downloadgcc-1a627b35d37649103f629cd15139387d09c4b703.zip
gcc-1a627b35d37649103f629cd15139387d09c4b703.tar.gz
gcc-1a627b35d37649103f629cd15139387d09c4b703.tar.bz2
target.def (legitimate_constant_p): New hook.
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<register_modes:mode>): Update accordingly. * config/s390/s390-protos.h (legitimate_constant_p): Delete. * config/s390/s390.h (LEGITIMATE_CONSTANT_P): Likewise. * config/s390/s390.c (legitimate_constant_p): Rename to... (s390_legitimate_constant_p): ...this. Make static, return a bool, and add a mode argument. (TARGET_LEGITIMATE_CONSTANT_P): Define. * config/score/score.h (LEGITIMATE_CONSTANT_P): Delete. * config/sh/sh.h (LEGITIMATE_CONSTANT_P): Delete. * config/sh/sh.c (TARGET_LEGITIMATE_CONSTANT_P): Define. (sh_legitimate_constant_p): New function. * config/sparc/sparc-protos.h (legitimate_constant_p): Delete. * config/sparc/sparc.h (LEGITIMATE_CONSTANT_P): Delete. * config/sparc/sparc.c (TARGET_LEGITIMATE_CONSTANT_P): Define. (legitimate_constant_p): Rename to... (sparc_legitimate_constant_p): ...this. Make static. Add a mode argument. (constant_address_p): Update accordingly. * config/spu/spu-protos.h (spu_legitimate_constant_p): Add a mode argument and return a bool. * config/spu/spu.h (LEGITIMATE_CONSTANT_P): Delete. * config/spu/spu.c (TARGET_LEGITIMATE_CONSTANT_P): Define. (spu_legitimate_constant_p): Add a mode argument and return a bool. (spu_rtx_costs): Update accordingly. * config/spu/predicates.md (vec_imm_operand): Likewise. * config/stormy16/stormy16.h (LEGITIMATE_CONSTANT_P): Delete. * config/v850/v850.h (LEGITIMATE_CONSTANT_P): Delete. * config/v850/v850.c (v850_legitimate_constant_p): New function. (TARGET_LEGITIMATE_CONSTANT_P): Define. * config/vax/vax-protos.h (legitimate_constant_p): Delete. * config/vax/vax.h (LEGITIMATE_CONSTANT_P): Likewise. * config/vax/vax.c (legitimate_constant_p): Likewise. * config/xtensa/xtensa.h (LEGITIMATE_CONSTANT_P): Delete. * config/xtensa/xtensa.c (TARGET_LEGITIMATE_CONSTANT_P): Define. (xtensa_legitimate_constant_p): New function. From-SVN: r172814
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog203
-rw-r--r--gcc/calls.c7
-rw-r--r--gcc/config/alpha/alpha-protos.h2
-rw-r--r--gcc/config/alpha/alpha.c9
-rw-r--r--gcc/config/alpha/alpha.h5
-rw-r--r--gcc/config/alpha/predicates.md4
-rw-r--r--gcc/config/arm/arm-protos.h1
-rw-r--r--gcc/config/arm/arm.c39
-rw-r--r--gcc/config/arm/arm.h21
-rw-r--r--gcc/config/avr/avr.h2
-rw-r--r--gcc/config/bfin/bfin-protos.h1
-rw-r--r--gcc/config/bfin/bfin.c9
-rw-r--r--gcc/config/bfin/bfin.h7
-rw-r--r--gcc/config/cris/cris.h2
-rw-r--r--gcc/config/fr30/fr30.h6
-rw-r--r--gcc/config/frv/frv-protos.h1
-rw-r--r--gcc/config/frv/frv.c15
-rw-r--r--gcc/config/frv/frv.h6
-rw-r--r--gcc/config/h8300/h8300-protos.h2
-rw-r--r--gcc/config/h8300/h8300.c8
-rw-r--r--gcc/config/h8300/h8300.h5
-rw-r--r--gcc/config/i386/i386-protos.h1
-rw-r--r--gcc/config/i386/i386.c18
-rw-r--r--gcc/config/i386/i386.h5
-rw-r--r--gcc/config/i386/i386.md6
-rw-r--r--gcc/config/ia64/ia64-protos.h2
-rw-r--r--gcc/config/ia64/ia64.c29
-rw-r--r--gcc/config/ia64/ia64.h5
-rw-r--r--gcc/config/iq2000/iq2000.h2
-rw-r--r--gcc/config/lm32/lm32-protos.h1
-rw-r--r--gcc/config/lm32/lm32.c11
-rw-r--r--gcc/config/lm32/lm32.h2
-rw-r--r--gcc/config/m32c/m32c-protos.h1
-rw-r--r--gcc/config/m32c/m32c.c9
-rw-r--r--gcc/config/m32c/m32c.h2
-rw-r--r--gcc/config/m32r/m32r.c22
-rw-r--r--gcc/config/m32r/m32r.h13
-rw-r--r--gcc/config/m68k/m68k-protos.h1
-rw-r--r--gcc/config/m68k/m68k.c13
-rw-r--r--gcc/config/m68k/m68k.h8
-rw-r--r--gcc/config/m68k/m68k.md2
-rw-r--r--gcc/config/mcore/mcore.c14
-rw-r--r--gcc/config/mcore/mcore.h7
-rw-r--r--gcc/config/mep/mep-protos.h1
-rw-r--r--gcc/config/mep/mep.c9
-rw-r--r--gcc/config/mep/mep.h3
-rw-r--r--gcc/config/microblaze/microblaze-protos.h1
-rw-r--r--gcc/config/microblaze/microblaze.c19
-rw-r--r--gcc/config/microblaze/microblaze.h6
-rw-r--r--gcc/config/mips/mips.c15
-rw-r--r--gcc/config/mips/mips.h2
-rw-r--r--gcc/config/mips/predicates.md2
-rw-r--r--gcc/config/mmix/mmix-protos.h1
-rw-r--r--gcc/config/mmix/mmix.c11
-rw-r--r--gcc/config/mmix/mmix.h3
-rw-r--r--gcc/config/mn10300/mn10300-protos.h1
-rw-r--r--gcc/config/mn10300/mn10300.c8
-rw-r--r--gcc/config/mn10300/mn10300.h4
-rw-r--r--gcc/config/moxie/moxie.h4
-rw-r--r--gcc/config/pa/pa.c40
-rw-r--r--gcc/config/pa/pa.h31
-rw-r--r--gcc/config/pdp11/pdp11.c12
-rw-r--r--gcc/config/pdp11/pdp11.h6
-rw-r--r--gcc/config/picochip/picochip.h5
-rw-r--r--gcc/config/rs6000/rs6000.c21
-rw-r--r--gcc/config/rs6000/rs6000.h16
-rw-r--r--gcc/config/rx/rx-protos.h2
-rw-r--r--gcc/config/rx/rx.c7
-rw-r--r--gcc/config/rx/rx.h2
-rw-r--r--gcc/config/rx/rx.md2
-rw-r--r--gcc/config/s390/s390-protos.h1
-rw-r--r--gcc/config/s390/s390.c9
-rw-r--r--gcc/config/s390/s390.h5
-rw-r--r--gcc/config/score/score.h2
-rw-r--r--gcc/config/sh/sh.c20
-rw-r--r--gcc/config/sh/sh.h14
-rw-r--r--gcc/config/sparc/sparc-protos.h1
-rw-r--r--gcc/config/sparc/sparc.c18
-rw-r--r--gcc/config/sparc/sparc.h6
-rw-r--r--gcc/config/spu/predicates.md2
-rw-r--r--gcc/config/spu/spu-protos.h2
-rw-r--r--gcc/config/spu/spu.c11
-rw-r--r--gcc/config/spu/spu.h2
-rw-r--r--gcc/config/stormy16/stormy16.h2
-rw-r--r--gcc/config/v850/v850.c16
-rw-r--r--gcc/config/v850/v850.h11
-rw-r--r--gcc/config/vax/vax-protos.h1
-rw-r--r--gcc/config/vax/vax.c9
-rw-r--r--gcc/config/vax/vax.h5
-rw-r--r--gcc/config/xtensa/xtensa.c11
-rw-r--r--gcc/config/xtensa/xtensa.h4
-rw-r--r--gcc/doc/tm.texi20
-rw-r--r--gcc/doc/tm.texi.in20
-rw-r--r--gcc/expr.c14
-rw-r--r--gcc/hooks.c8
-rw-r--r--gcc/hooks.h1
-rw-r--r--gcc/ira-costs.c3
-rw-r--r--gcc/recog.c8
-rw-r--r--gcc/reload.c7
-rw-r--r--gcc/reload1.c8
-rw-r--r--gcc/system.h2
-rw-r--r--gcc/target.def7
102 files changed, 615 insertions, 398 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3f346fc..95f931b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,208 @@
2011-04-21 Richard Sandiford <richard.sandiford@linaro.org>
+ * target.def (legitimate_constant_p): New hook.
+ * doc/tm.texi.in (LEGITIMATE_CONSTANT_P): Replace with...
+ (TARGET_LEGITIMATE_CONSTANT_P): ...this.
+ * doc/tm.texi: Regenerate.
+ * hooks.h (hook_bool_mode_rtx_true): Declare.
+ * hooks.c (hook_bool_mode_rtx_true): Define.
+ * system.h (LEGITIMATE_CONSTANT_P): Poison.
+ * calls.c (precompute_register_parameters): Replace uses of
+ LEGITIMATE_CONSTANT_P with targetm.legitimate_constant_p.
+ (emit_library_call_value_1): Likewise.
+ * expr.c (move_block_to_reg, can_store_by_pieces, emit_move_insn)
+ (compress_float_constant, emit_push_insn, expand_expr_real_1): Likewise.
+ * ira-costs.c (scan_one_insn): Likewise.
+ * recog.c (general_operand, immediate_operand): Likewise.
+ * reload.c (find_reloads_toplev, find_reloads_address_part): Likewise.
+ * reload1.c (init_eliminable_invariants): Likewise.
+
+ * config/alpha/alpha-protos.h (alpha_legitimate_constant_p): Add a
+ mode argument.
+ * config/alpha/alpha.h (LEGITIMATE_CONSTANT_P): Delete.
+ * config/alpha/alpha.c (alpha_legitimate_constant_p): Add a mode
+ argument.
+ (TARGET_LEGITIMATE_CONSTANT_P): Define.
+ * config/alpha/predicates.md (input_operand): Update call to
+ alpha_legitimate_constant_p.
+
+ * config/arm/arm-protos.h (arm_cannot_force_const_mem): Delete.
+ * config/arm/arm.h (ARM_LEGITIMATE_CONSTANT_P): Likewise.
+ (THUMB_LEGITIMATE_CONSTANT_P, LEGITIMATE_CONSTANT_P): Likewise.
+ * config/arm/arm.c (TARGET_LEGITIMATE_CONSTANT_P): Define.
+ (arm_legitimate_constant_p_1, thumb_legitimate_constant_p)
+ (arm_legitimate_constant_p): New functions.
+ (arm_cannot_force_const_mem): Make static.
+
+ * config/avr/avr.h (LEGITIMATE_CONSTANT_P): Delete.
+
+ * config/bfin/bfin-protos.h (bfin_legitimate_constant_p): Delete.
+ * config/bfin/bfin.h (LEGITIMATE_CONSTANT_P): Delete.
+ * config/bfin/bfin.c (expand_move): Use targetm.legitimate_constant_p
+ instead of bfin_legitimate_constant_p.
+ (bfin_legitimate_constant_p): Make static. Add a mode argument.
+ (TARGET_LEGITIMATE_CONSTANT_P): Define.
+
+ * config/cris/cris.h (LEGITIMATE_CONSTANT_P): Delete.
+
+ * config/fr30/fr30.h (LEGITIMATE_CONSTANT_P): Delete.
+
+ * config/frv/frv-protos.h (frv_legitimate_constant_p): Delete.
+ * config/frv/frv.h (LEGITIMATE_CONSTANT_P): Delete.
+ * config/frv/frv.c (TARGET_LEGITIMATE_CONSTANT_P): Define.
+ (frv_legitimate_constant_p): Make static. Add a mode argument.
+
+ * config/h8300/h8300-protos.h (h8300_legitimate_constant_p): Delete.
+ * config/h8300/h8300.h (LEGITIMATE_CONSTANT_P): Likewise.
+ * config/h8300/h8300.c (h8300_legitimate_constant_p): Likewise.
+
+ * config/i386/i386-protos.h (legitimate_constant_p): Delete.
+ * config/i386/i386.h (LEGITIMATE_CONSTANT_P): Likewise.
+ * config/i386/i386.c (legitimate_constant_p): Rename to...
+ (ix86_legitimate_constant_p): ...this. Make static. Add a mode
+ argument.
+ (ix86_cannot_force_const_mem): Update accordingly.
+ (ix86_legitimate_address_p): Likewise.
+ (TARGET_LEGITIMATE_CONSTANT_P): Define.
+ * config/i386/i386.md: Update commentary.
+
+ * config/ia64/ia64-protos.h (ia64_legitimate_constant_p): Delete.
+ * config/ia64/ia64.h (LEGITIMATE_CONSTANT_P): Likewise.
+ * config/ia64/ia64.c (TARGET_LEGITIMATE_CONSTANT_P): Define.
+ (ia64_legitimate_constant_p): Make static. Add a mode argument.
+
+ * config/iq2000/iq2000.h (LEGITIMATE_CONSTANT_P): Delete.
+
+ * config/lm32/lm32-protos.h (lm32_legitimate_constant_p): Delete.
+ * config/lm32/lm32.h (LEGITIMATE_CONSTANT_P): Likewise.
+ * config/lm32/lm32.c (TARGET_LEGITIMATE_CONSTANT_P): Define.
+ (lm32_legitimate_constant_p): Make static. Add a mode argument.
+
+ * config/m32c/m32c-protos.h (m32c_legitimate_constant_p): Delete.
+ * config/m32c/m32c.h (LEGITIMATE_CONSTANT_P): Likewise.
+ * config/m32c/m32c.c (m32c_legitimate_constant_p): Likewise.
+
+ * config/m32r/m32r.h (LEGITIMATE_CONSTANT_P): Delete.
+ * config/m32r/m32r.c (TARGET_LEGITIMATE_CONSTANT_P): Define.
+ (m32r_legitimate_constant_p): New function.
+
+ * config/m68k/m68k-protos.h (m68k_legitimate_constant_p): Declare.
+ * config/m68k/m68k.h (CONSTANT_ADDRESS_P): Call it instead of
+ LEGITIMATE_CONSTANT_P.
+ (LEGITIMATE_CONSTANT_P): Delete.
+ * config/m68k/m68k.c (m68k_expand_prologue): Call
+ m68k_legitimate_constant_p instead of LEGITIMATE_CONSTANT_P.
+ (m68k_legitimate_constant_p): New function.
+ * config/m68k/m68k.md: Update comments.
+
+ * config/mcore/mcore.h (LEGITIMATE_CONSTANT_P): Delete.
+ * config/mcore/mcore.c (TARGET_LEGITIMATE_CONSTANT_P): Define.
+ (mcore_legitimate_constant_p): New function.
+
+ * config/mep/mep-protos.h (mep_legitimate_constant_p): Delete.
+ * config/mep/mep.h (LEGITIMATE_CONSTANT_P): Likewise.
+ * config/mep/mep.c (mep_legitimate_constant_p): Make static.
+ Add a mode argument.
+ (mep_legitimate_address): Update accordingly.
+ (TARGET_LEGITIMATE_CONSTANT_P): Define.
+
+ * config/microblaze/microblaze-protos.h (microblaze_const_double_ok):
+ Delete.
+ * config/microblaze/microblaze.h (LEGITIMATE_CONSTANT_P): Likewise.
+ * config/microblaze/microblaze.c (microblaze_const_double_ok): Make
+ static. Check OP's mode for VOIDmode.
+ (microblaze_legitimate_constant_p): New function.
+ (TARGET_LEGITIMATE_CONSTANT_P): Define.
+
+ * config/mips/mips.h (LEGITIMATE_CONSTANT_P): Delete.
+ * config/mips/mips.c (mips_legitimate_constant_p): New function.
+ (mips_cannot_force_const_mem): Use it instead of LEGITIMATE_CONSTANT_P.
+ (TARGET_LEGITIMATE_CONSTANT_P): Define.
+ * config/mips/predicates.md: Update comments.
+
+ * config/mmix/mmix-protos.h (mmix_legitimate_constant_p): Delete.
+ * config/mmix/mmix.h (LEGITIMATE_CONSTANT_P): Likewise.
+ * config/mmix/mmix.c (TARGET_LEGITIMATE_CONSTANT_P): Define.
+ (mmix_legitimate_constant_p): Make static, return a bool, and take
+ a mode argument.
+ (mmix_print_operand_address): Update accordingly.
+
+ * config/mn10300/mn10300-protos.h (mn10300_legitimate_constant_p):
+ Delete.
+ * config/mn10300/mn10300.h (LEGITIMATE_CONSTANT_P): Likewise.
+ * config/mn10300/mn10300.c (mn10300_legitimate_constant_p):
+ Make static. Add a mode argument.
+ (TARGET_LEGITIMATE_CONSTANT_P): Define.
+
+ * config/moxie/moxie.h (LEGITIMATE_CONSTANT_P): Delete.
+
+ * config/pa/pa.h (LEGITIMATE_CONSTANT_P): Delete.
+ * config/pa/pa.c (TARGET_LEGITIMATE_CONSTANT_P): Define.
+ (pa_legitimate_constant_p): New function.
+
+ * config/picochip/picochip.h (LEGITIMATE_CONSTANT_P): Delete.
+
+ * config/pdp11/pdp11.h (LEGITIMATE_CONSTANT_P): Delete.
+ * config/pdp11/pdp11.c (TARGET_LEGITIMATE_CONSTANT_P): Define.
+ (pdp11_legitimate_constant_p): New function.
+
+ * config/rs6000/rs6000.h (LEGITIMATE_CONSTANT_P): Delete.
+ * config/rs6000/rs6000.c (TARGET_LEGITIMATE_CONSTANT_P): Define.
+ (rs6000_legitimate_constant_p): New function.
+
+ * config/rx/rx-protos.h (rx_is_legitimate_constant): Replace with...
+ (rx_legitimate_constant_p): ...this.
+ * config/rx/rx.h (LEGITIMATE_CONSTANT_P): Delete.
+ * config/rx/rx.c (rx_is_legitimate_constant): Replace with...
+ (rx_legitimate_constant_p): ...this.
+ (TARGET_LEGITIMATE_CONSTANT_P): Define.
+ * config/rx/rx.md (mov<register_modes:mode>): Update accordingly.
+
+ * config/s390/s390-protos.h (legitimate_constant_p): Delete.
+ * config/s390/s390.h (LEGITIMATE_CONSTANT_P): Likewise.
+ * config/s390/s390.c (legitimate_constant_p): Rename to...
+ (s390_legitimate_constant_p): ...this. Make static, return a bool,
+ and add a mode argument.
+ (TARGET_LEGITIMATE_CONSTANT_P): Define.
+
+ * config/score/score.h (LEGITIMATE_CONSTANT_P): Delete.
+
+ * config/sh/sh.h (LEGITIMATE_CONSTANT_P): Delete.
+ * config/sh/sh.c (TARGET_LEGITIMATE_CONSTANT_P): Define.
+ (sh_legitimate_constant_p): New function.
+
+ * config/sparc/sparc-protos.h (legitimate_constant_p): Delete.
+ * config/sparc/sparc.h (LEGITIMATE_CONSTANT_P): Delete.
+ * config/sparc/sparc.c (TARGET_LEGITIMATE_CONSTANT_P): Define.
+ (legitimate_constant_p): Rename to...
+ (sparc_legitimate_constant_p): ...this. Make static. Add a mode
+ argument.
+ (constant_address_p): Update accordingly.
+
+ * config/spu/spu-protos.h (spu_legitimate_constant_p): Add a mode
+ argument and return a bool.
+ * config/spu/spu.h (LEGITIMATE_CONSTANT_P): Delete.
+ * config/spu/spu.c (TARGET_LEGITIMATE_CONSTANT_P): Define.
+ (spu_legitimate_constant_p): Add a mode argument and return a bool.
+ (spu_rtx_costs): Update accordingly.
+ * config/spu/predicates.md (vec_imm_operand): Likewise.
+
+ * config/stormy16/stormy16.h (LEGITIMATE_CONSTANT_P): Delete.
+
+ * config/v850/v850.h (LEGITIMATE_CONSTANT_P): Delete.
+ * config/v850/v850.c (v850_legitimate_constant_p): New function.
+ (TARGET_LEGITIMATE_CONSTANT_P): Define.
+
+ * config/vax/vax-protos.h (legitimate_constant_p): Delete.
+ * config/vax/vax.h (LEGITIMATE_CONSTANT_P): Likewise.
+ * config/vax/vax.c (legitimate_constant_p): Likewise.
+
+ * config/xtensa/xtensa.h (LEGITIMATE_CONSTANT_P): Delete.
+ * config/xtensa/xtensa.c (TARGET_LEGITIMATE_CONSTANT_P): Define.
+ (xtensa_legitimate_constant_p): New function.
+
+2011-04-21 Richard Sandiford <richard.sandiford@linaro.org>
+
* target.def (cannot_force_const_mem): Add a mode argument.
* 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 bb95852..89b248c 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 1db3575..58723aa 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 ba0dfe6..4cbafa0 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 6f476f4..15567cd 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 e43564d..c1e3115 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 da3241d..fa25283 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 0f944fd..97d2d6f 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 76efdec..4332394 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 b0c1b49..5f4ceff 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 1e85e16..40c641c 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 2a9730f..25316cf 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 ab3f2ea..8577db7 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 c8b7d2f..57bdd46 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 ca483fa..d988408 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 c7223a7..62e2506 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 5b0c084..9e2f718 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 937ae18..0255951 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 bb2d5e7..da3b75a 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 93febd1..de41d70 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 eb77458..015df60 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 d434d75..ccba848 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 c4b18ef..b55c67b 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 10fc126..5baa2b8 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 a6956b8..ff0e723 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 107a7cc..627271e 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 6083279..6c6904b 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 a894df8..2da6149 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 a69204e..b9717ff 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 bc086d2..aad3674 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 2c7131a..ac368c8 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 3d8f77a..75a2416 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 f7c32e7..fdaa8a8 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 c603770..3770fef 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 6016ee5..1a44b1b 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 86af3b3..1580f47 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 26d3ef9..50b5b2a 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 ad02026..8017cf2 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 7553183..b01e54f 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 d853d78..3c9dbb3 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 f89037f..16697bf 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 741452e..32ff5fd 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 fa3909e..278a8cc 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 12cef58..edfbaf7 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 b8ef440..60cf4eb 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 d6d6c2f..f5de83f 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 56dca55..0a7d1c7 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 5796bc7..1cec425b 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 18cd72d..6cfbf68 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 f6a4ec9..12caf8e 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 1c1917c..4386ce0 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 7430dd3..022868b 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 2e6abd8..c609c1a 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 c96fdcb..80f0d84 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 f3ed940..09e50e0 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 058f5df..b8c19fd 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 f00c53e..635b1cb 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 b6a54b5..a0e17d8 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 1b5e0a3..86c6663 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 ab0fe6a..e3260c4 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 f3ad883..f401707 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 10052e9..fc0c92b 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 8a896ca..5d389ec 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 b65a206..abe6d64 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 201c2fb..4f095a2 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 0193db5..5ae62af 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 17f6083..544a30d 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 4d16cc3..1009c54 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 c4436d70..742d83f 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 42a64aa7..824d246 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 (<register_modes:MODE>mode, operand1);
if (CONST_INT_P (operand1)
- && ! rx_is_legitimate_constant (operand1))
+ && ! rx_legitimate_constant_p (<register_modes:MODE>mode, operand1))
FAIL;
}
)
diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h
index 1df176e..79fce84 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 8454333..7d02b7f 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 950bf3c..47e0b1a 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 736e770..1f99756 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 78f6f0f..c84c510 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 1e4dd7a..4876fd6 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 d37823f..fd9a321 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 b112f7e..4a1795e 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 4747650..79c7f57 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 8c6798d..2d2e77b 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 fa94535..675af02 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 941194b..4142e7e 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 f0f00a9..1625891 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 3853c3f..871e523 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 b0b9388..86509e0a 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 1e45686..5079936 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 6861260..a8f88bf 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
<http://www.gnu.org/licenses/>. */
extern bool legitimate_constant_address_p (rtx);
-extern bool legitimate_constant_p (rtx);
extern bool vax_mode_dependent_address_p (rtx);
#ifdef RTX_CODE
diff --git a/gcc/config/vax/vax.c b/gcc/config/vax/vax.c
index 3489f54..cc8c3f6 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 77530aa..a3e9d83 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 2ffc39f..c312f50 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 c9ff80c..d3ce147 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 ec55551..a89d0ec 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 1c96941..4637088 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 8040d51..ecaf1d7 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 a991980..7791a14 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 548dad3..11dd7a9 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 de894a2..f517386 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 c6ba1953..afe985e 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 372eccc..045e559 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 7fb4270..ea7df99 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 9229302..81daaf1 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 ce01faa..ea4d3e9 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,