From c6d5ff8310ce6c8c675b9be815bcb091e6cb51ba Mon Sep 17 00:00:00 2001 From: Michael Meissner Date: Wed, 20 Mar 2013 15:50:27 +0000 Subject: [PATCH] predicates.md (indexed_address, [...]): New predicates. [gcc] 2013-03-20 Pat Haugen * config/rs6000/predicates.md (indexed_address, update_address_mem update_indexed_address_mem): New predicates. * config/rs6000/vsx.md (vsx_extract__zero): Set correct "type" attribute for load/store instructions. * config/rs6000/dfp.md (movsd_store): Likewise. (movsd_load): Likewise. * config/rs6000/rs6000.md (zero_extenddi2_internal1): Likewise. (unnamed HI->DI extend define_insn): Likewise. (unnamed SI->DI extend define_insn): Likewise. (unnamed QI->SI extend define_insn): Likewise. (unnamed QI->HI extend define_insn): Likewise. (unnamed HI->SI extend define_insn): Likewise. (unnamed HI->SI extend define_insn): Likewise. (extendsfdf2_fpr): Likewise. (movsi_internal1): Likewise. (movsi_internal1_single): Likewise. (movhi_internal): Likewise. (movqi_internal): Likewise. (movcc_internal1): Correct mnemonic for stw insn. Set correct "type" attribute for load/store instructions. (mov_hardfloat): Set correct "type" attribute for load/store instructions. (mov_softfloat): Likewise. (mov_hardfloat32): Likewise. (mov_hardfloat64): Likewise. (mov_softfloat64): Likewise. (movdi_internal32): Likewise. (movdi_internal64): Likewise. (probe_stack_): Likewise. 2013-03-20 Michael Meissner * config/rs6000/vector.md (VEC_R): Add 32-bit integer, binary floating point, and decimal floating point to reload iterator. * config/rs6000/constraints.md (wl constraint): New constraints to return FLOAT_REGS if certain options are used to reduce the number of separate patterns that exist in the file. (wx constraint): Likewise. (wz constraint): Likewise. * config/rs6000/rs6000.c (rs6000_debug_reg_global): If -mdebug=reg, print wg, wl, wx, and wz constraints. (rs6000_init_hard_regno_mode_ok): Initialize new constraints. Initialize the reload functions for 64-bit binary/decimal floating point types. (reg_offset_addressing_ok_p): If we are on a power7 or later, use LFIWZX and STFIWX to load/store 32-bit decimal types, and don't create the buffer on the stack to overcome not having a 32-bit load and store. (rs6000_emit_move): Likewise. (rs6000_secondary_memory_needed_rtx): Likewise. (rs6000_alloc_sdmode_stack_slot): Likewise. (rs6000_preferred_reload_class): On VSX, we can create SFmode 0.0f via xxlxor, just like DFmode 0.0. * config/rs6000/rs6000.h (TARGET_NO_SDMODE_STACK): New macro, define as 1 if we are running on a power7 or newer. (enum r6000_reg_class_enum): Add new constraints. * config/rs6000/dfp.md (movsd): Delete, combine with binary floating point moves in rs6000.md. Combine power6x (mfpgpr) moves with other moves by using conditional constraits (wg). Use LFIWZX and STFIWX for loading SDmode on power7. Use xxlxor to create 0.0f. (movsd splitter): Likewise. (movsd_hardfloat): Likewise. (movsd_softfloat): Likewise. * config/rs6000/rs6000.md (FMOVE32): New iterators to combine binary and decimal floating point moves. (fmove_ok): New attributes to combine binary and decimal floating point moves, and to combine power6x (mfpgpr) moves along normal floating moves. (real_value_to_target): Likewise. (f32_lr): Likewise. (f32_lm): Likewise. (f32_li): Likewise. (f32_sr): Likewise. (f32_sm): Likewise. (f32_si): Likewise. (movsf): Combine binary and decimal floating point moves. Combine power6x (mfpgpr) moves with other moves by using conditional constraits (wg). Use LFIWZX and STFIWX for loading SDmode on power7. (mov for SFmode/SDmode); Likewise. (SFmode/SDmode splitters): Likewise. (movsf_hardfloat): Likewise. (mov_hardfloat for SFmode/SDmode): Likewise. (movsf_softfloat): Likewise. (mov_softfloat for SFmode/SDmode): Likewise. * doc/md.texi (PowerPC and IBM RS6000 constraints): Document wl, wx and wz constraints. * config/rs6000/constraints.md (wg constraint): New constraint to return FLOAT_REGS if -mmfpgpr (power6x) was used. * config/rs6000/rs6000.h (enum r6000_reg_class_enum): Add wg constraint. * config/rs6000/rs6000.c (rs6000_debug_reg_global): If -mdebug=reg, print wg, wl, wx, and wz constraints. (rs6000_init_hard_regno_mode_ok): Initialize new constraints. Initialize the reload functions for 64-bit binary/decimal floating point types. (reg_offset_addressing_ok_p): If we are on a power7 or later, use LFIWZX and STFIWX to load/store 32-bit decimal types, and don't create the buffer on the stack to overcome not having a 32-bit load and store. (rs6000_emit_move): Likewise. (rs6000_secondary_memory_needed_rtx): Likewise. (rs6000_alloc_sdmode_stack_slot): Likewise. (rs6000_preferred_reload_class): On VSX, we can create SFmode 0.0f via xxlxor, just like DFmode 0.0. * config/rs6000/dfp.md (movdd): Delete, combine with binary floating point moves in rs6000.md. Combine power6x (mfpgpr) moves with other moves by using conditional constraits (wg). Use LFIWZX and STFIWX for loading SDmode on power7. (movdd splitters): Likewise. (movdd_hardfloat32): Likewise. (movdd_softfloat32): Likewise. (movdd_hardfloat64_mfpgpr): Likewise. (movdd_hardfloat64): Likewise. (movdd_softfloat64): Likewise. * config/rs6000/rs6000.md (FMOVE64): New iterators to combine 64-bit binary and decimal floating point moves. (FMOVE64X): Likewise. (movdf): Combine 64-bit binary and decimal floating point moves. Combine power6x (mfpgpr) moves with other moves by using conditional constraits (wg). (mov for DFmode/DDmode): Likewise. (DFmode/DDmode splitters): Likewise. (movdf_hardfloat32): Likewise. (mov_hardfloat32 for DFmode/DDmode): Likewise. (movdf_softfloat32): Likewise. (movdf_hardfloat64_mfpgpr): Likewise. (movdf_hardfloat64): Likewise. (mov_hardfloat64 for DFmode/DDmode): Likewise. (movdf_softfloat64): Likewise. (mov_softfloat64 for DFmode/DDmode): Likewise. (reload__load): Move to later in the file so they aren't in the middle of the floating point move insns. (reload__store): Likewise. * doc/md.texi (PowerPC and IBM RS6000 constraints): Document wg constraint. * config/rs6000/rs6000.c (rs6000_debug_reg_global): Print out wg constraint if -mdebug=reg. (rs6000_initi_hard_regno_mode_ok): Enable wg constraint if -mfpgpr. Enable using dd reload support if needed. * config/rs6000/dfp.md (movtd): Delete, combine with 128-bit binary and decimal floating point moves in rs6000.md. (movtd_internal): Likewise. * config/rs6000/rs6000.md (FMOVE128): Combine 128-bit binary and decimal floating point moves. (movtf): Likewise. (movtf_internal): Likewise. (mov_internal, TDmode/TFmode): Likewise. (movtf_softfloat): Likewise. (mov_softfloat, TDmode/TFmode): Likewise. * config/rs6000/rs6000.md (movdi_mfpgpr): Delete, combine with movdi_internal64, using wg constraint for move direct operations. (movdi_internal64): Likewise. * config/rs6000/rs6000.c (rs6000_debug_reg_global): Print MODES_TIEABLE_P for selected modes. Print the numerical value of the various virtual registers. Use GPR/FPR first/last values, instead of hard coding the register numbers. Print which modes have reload functions registered. (rs6000_option_override_internal): If -mdebug=reg, trace the options settings before/after setting cpu, target and subtarget settings. (rs6000_secondary_reload_trace): Improve the RTL dump for -mdebug=addr and for secondary reload failures in rs6000_secondary_reload_inner. (rs6000_secondary_reload_fail): Likewise. (rs6000_secondary_reload_inner): Likewise. * config/rs6000/rs6000.md (FIRST_GPR_REGNO): Add convenience macros for first/last GPR and FPR registers. (LAST_GPR_REGNO): Likewise. (FIRST_FPR_REGNO): Likewise. (LAST_FPR_REGNO): Likewise. * config/rs6000/vector.md (mul3): Use the combined macro VECTOR_UNIT_ALTIVEC_OR_VSX_P instead of separate calls to VECTOR_UNIT_ALTIVEC_P and VECTOR_UNIT_VSX_P. (vcond): Likewise. (vcondu): Likewise. (vector_gtu): Likewise. (vector_gte): Likewise. (xor3): Don't allow logical operations on TImode in 32-bit to prevent the compiler from converting DImode operations to TImode. (ior3): Likewise. (and3): Likewise. (one_cmpl2): Likewise. (nor3): Likewise. (andc3): Likewise. * config/rs6000/constraints.md (wt constraint): New constraint that returns VSX_REGS if TImode is allowed in VSX registers. * config/rs6000/predicates.md (easy_fp_constant): 0.0f is an easy constant under VSX. * config/rs6000/rs6000-modes.def (PTImode): Define, PTImode is similar to TImode, but it is restricted to being in the GPRs. * config/rs6000/rs6000.opt (-mvsx-timode): New switch to allow TImode to occupy a single VSX register. * config/rs6000/rs6000-cpus.def (ISA_2_6_MASKS_SERVER): Default to -mvsx-timode for power7/power8. (power7 cpu): Likewise. (power8 cpu): Likewise. * config/rs6000/rs6000.c (rs6000_hard_regno_nregs_internal): Make sure that TFmode/TDmode take up two registers if they are ever allowed in the upper VSX registers. (rs6000_hard_regno_mode_ok): If -mvsx-timode, allow TImode in VSX registers. (rs6000_init_hard_regno_mode_ok): Likewise. (rs6000_debug_reg_global): Add debugging for PTImode and wt constraint. Print if LRA is turned on. (rs6000_option_override_internal): Give an error if -mvsx-timode and VSX is not enabled. (invalid_e500_subreg): Handle PTImode, restricting it to GPRs. If -mvsx-timode, restrict TImode to reg+reg addressing, and PTImode to reg+offset addressing. Use PTImode when checking offset addresses for validity. (reg_offset_addressing_ok_p): Likewise. (rs6000_legitimate_offset_address_p): Likewise. (rs6000_legitimize_address): Likewise. (rs6000_legitimize_reload_address): Likewise. (rs6000_legitimate_address_p): Likewise. (rs6000_eliminate_indexed_memrefs): Likewise. (rs6000_emit_move): Likewise. (rs6000_secondary_reload): Likewise. (rs6000_secondary_reload_inner): Handle PTImode. Allow 64-bit reloads to fpr registers to continue to use reg+offset addressing, but 64-bit reloads to altivec registers need reg+reg addressing. Drop test for PRE_MODIFY, since VSX loads/stores no longer support it. Treat LO_SUM like a PLUS operation. (rs6000_secondary_reload_class): If type is 64-bit, prefer to use FLOAT_REGS instead of VSX_RGS to allow use of reg+offset addressing. (rs6000_cannot_change_mode_class): Do not allow TImode in VSX registers to share a register with a smaller sized type, since VSX puts scalars in the upper 64-bits. (print_operand): Add support for PTImode. (rs6000_register_move_cost): Use VECTOR_MEM_VSX_P instead of VECTOR_UNIT_VSX_P to catch types that can be loaded in VSX registers, but don't have arithmetic support. (rs6000_memory_move_cost): Add test for VSX. (rs6000_opt_masks): Add -mvsx-timode. * config/rs6000/vsx.md (VSm): Change to use 64-bit aligned moves for TImode. (VSs): Likewise. (VSr): Use wt constraint for TImode. (VSv): Drop TImode support. (vsx_movti): Delete, replace with versions for 32-bit and 64-bit. (vsx_movti_64bit): Likewise. (vsx_movti_32bit): Likewise. (vec_store_): Use VSX iterator instead of vector iterator. (vsx_and3): Delete use of '?' constraint on inputs, just put one '?' on the appropriate output constraint. Do not allow TImode logical operations on 32-bit systems. (vsx_ior3): Likewise. (vsx_xor3): Likewise. (vsx_one_cmpl2): Likewise. (vsx_nor3): Likewise. (vsx_andc3): Likewise. (vsx_concat_): Likewise. (vsx_xxpermdi_): Fix thinko for non V2DF/V2DI modes. * config/rs6000/rs6000.h (MASK_VSX_TIMODE): Map from OPTION_MASK_VSX_TIMODE. (enum rs6000_reg_class_enum): Add RS6000_CONSTRAINT_wt. (STACK_SAVEAREA_MODE): Use PTImode instead of TImode. * config/rs6000/rs6000.md (INT mode attribute): Add PTImode. (TI2 iterator): New iterator for TImode, PTImode. (wd mode attribute): Add values for vector types. (movti_string): Replace TI move operations with operations for TImode and PTImode. Add support for TImode being allowed in VSX registers. (mov_string, TImode/PTImode): Likewise. (movti_ppc64): Likewise. (mov_ppc64, TImode/PTImode): Likewise. (TI mode splitters): Likewise. * doc/md.texi (PowerPC and IBM RS6000 constraints): Document wt constraint. [gcc/testsuite] 2013-03-20 Michael Meissner * gcc.target/powerpc/mmfpgpr.c: New test. * gcc.target/powerpc/sd-vsx.c: Likewise. * gcc.target/powerpc/sd-pwr6.c: Likewise. * gcc.target/powerpc/vsx-float0.c: Likewise. From-SVN: r196831 --- gcc/ChangeLog | 306 +++++++ gcc/config/rs6000/constraints.md | 17 + gcc/config/rs6000/dfp.md | 315 +------ gcc/config/rs6000/predicates.md | 27 + gcc/config/rs6000/rs6000-cpus.def | 10 +- gcc/config/rs6000/rs6000-modes.def | 3 + gcc/config/rs6000/rs6000.c | 462 ++++++++-- gcc/config/rs6000/rs6000.h | 13 +- gcc/config/rs6000/rs6000.md | 865 +++++++++++++----- gcc/config/rs6000/rs6000.opt | 4 + gcc/config/rs6000/vector.md | 34 +- gcc/config/rs6000/vsx.md | 159 +++- gcc/doc/md.texi | 15 + gcc/testsuite/ChangeLog | 7 + gcc/testsuite/gcc.target/powerpc/mmfpgpr.c | 22 + gcc/testsuite/gcc.target/powerpc/sd-pwr6.c | 19 + gcc/testsuite/gcc.target/powerpc/sd-vsx.c | 20 + gcc/testsuite/gcc.target/powerpc/vsx-float0.c | 16 + 18 files changed, 1660 insertions(+), 654 deletions(-) create mode 100644 gcc/testsuite/gcc.target/powerpc/mmfpgpr.c create mode 100644 gcc/testsuite/gcc.target/powerpc/sd-pwr6.c create mode 100644 gcc/testsuite/gcc.target/powerpc/sd-vsx.c create mode 100644 gcc/testsuite/gcc.target/powerpc/vsx-float0.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1f4bb6d82670..1cc25b054b1e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,309 @@ +2013-03-20 Pat Haugen + + * config/rs6000/predicates.md (indexed_address, update_address_mem + update_indexed_address_mem): New predicates. + * config/rs6000/vsx.md (vsx_extract__zero): Set correct "type" + attribute for load/store instructions. + * config/rs6000/dfp.md (movsd_store): Likewise. + (movsd_load): Likewise. + * config/rs6000/rs6000.md (zero_extenddi2_internal1): Likewise. + (unnamed HI->DI extend define_insn): Likewise. + (unnamed SI->DI extend define_insn): Likewise. + (unnamed QI->SI extend define_insn): Likewise. + (unnamed QI->HI extend define_insn): Likewise. + (unnamed HI->SI extend define_insn): Likewise. + (unnamed HI->SI extend define_insn): Likewise. + (extendsfdf2_fpr): Likewise. + (movsi_internal1): Likewise. + (movsi_internal1_single): Likewise. + (movhi_internal): Likewise. + (movqi_internal): Likewise. + (movcc_internal1): Correct mnemonic for stw insn. Set correct "type" + attribute for load/store instructions. + (mov_hardfloat): Set correct "type" attribute for load/store + instructions. + (mov_softfloat): Likewise. + (mov_hardfloat32): Likewise. + (mov_hardfloat64): Likewise. + (mov_softfloat64): Likewise. + (movdi_internal32): Likewise. + (movdi_internal64): Likewise. + (probe_stack_): Likewise. + +2013-03-20 Michael Meissner + + * config/rs6000/vector.md (VEC_R): Add 32-bit integer, binary + floating point, and decimal floating point to reload iterator. + + * config/rs6000/constraints.md (wl constraint): New constraints to + return FLOAT_REGS if certain options are used to reduce the number + of separate patterns that exist in the file. + (wx constraint): Likewise. + (wz constraint): Likewise. + + * config/rs6000/rs6000.c (rs6000_debug_reg_global): If + -mdebug=reg, print wg, wl, wx, and wz constraints. + (rs6000_init_hard_regno_mode_ok): Initialize new constraints. + Initialize the reload functions for 64-bit binary/decimal floating + point types. + (reg_offset_addressing_ok_p): If we are on a power7 or later, use + LFIWZX and STFIWX to load/store 32-bit decimal types, and don't + create the buffer on the stack to overcome not having a 32-bit + load and store. + (rs6000_emit_move): Likewise. + (rs6000_secondary_memory_needed_rtx): Likewise. + (rs6000_alloc_sdmode_stack_slot): Likewise. + (rs6000_preferred_reload_class): On VSX, we can create SFmode 0.0f + via xxlxor, just like DFmode 0.0. + + * config/rs6000/rs6000.h (TARGET_NO_SDMODE_STACK): New macro, + define as 1 if we are running on a power7 or newer. + (enum r6000_reg_class_enum): Add new constraints. + + * config/rs6000/dfp.md (movsd): Delete, combine with binary + floating point moves in rs6000.md. Combine power6x (mfpgpr) moves + with other moves by using conditional constraits (wg). Use LFIWZX + and STFIWX for loading SDmode on power7. Use xxlxor to create + 0.0f. + (movsd splitter): Likewise. + (movsd_hardfloat): Likewise. + (movsd_softfloat): Likewise. + + * config/rs6000/rs6000.md (FMOVE32): New iterators to combine + binary and decimal floating point moves. + (fmove_ok): New attributes to combine binary and decimal floating + point moves, and to combine power6x (mfpgpr) moves along normal + floating moves. + (real_value_to_target): Likewise. + (f32_lr): Likewise. + (f32_lm): Likewise. + (f32_li): Likewise. + (f32_sr): Likewise. + (f32_sm): Likewise. + (f32_si): Likewise. + (movsf): Combine binary and decimal floating point moves. Combine + power6x (mfpgpr) moves with other moves by using conditional + constraits (wg). Use LFIWZX and STFIWX for loading SDmode on + power7. + (mov for SFmode/SDmode); Likewise. + (SFmode/SDmode splitters): Likewise. + (movsf_hardfloat): Likewise. + (mov_hardfloat for SFmode/SDmode): Likewise. + (movsf_softfloat): Likewise. + (mov_softfloat for SFmode/SDmode): Likewise. + + * doc/md.texi (PowerPC and IBM RS6000 constraints): Document wl, + wx and wz constraints. + + * config/rs6000/constraints.md (wg constraint): New constraint to + return FLOAT_REGS if -mmfpgpr (power6x) was used. + + * config/rs6000/rs6000.h (enum r6000_reg_class_enum): Add wg + constraint. + + * config/rs6000/rs6000.c (rs6000_debug_reg_global): If + -mdebug=reg, print wg, wl, wx, and wz constraints. + (rs6000_init_hard_regno_mode_ok): Initialize new constraints. + Initialize the reload functions for 64-bit binary/decimal floating + point types. + (reg_offset_addressing_ok_p): If we are on a power7 or later, use + LFIWZX and STFIWX to load/store 32-bit decimal types, and don't + create the buffer on the stack to overcome not having a 32-bit + load and store. + (rs6000_emit_move): Likewise. + (rs6000_secondary_memory_needed_rtx): Likewise. + (rs6000_alloc_sdmode_stack_slot): Likewise. + (rs6000_preferred_reload_class): On VSX, we can create SFmode 0.0f + via xxlxor, just like DFmode 0.0. + + + * config/rs6000/dfp.md (movdd): Delete, combine with binary + floating point moves in rs6000.md. Combine power6x (mfpgpr) moves + with other moves by using conditional constraits (wg). Use LFIWZX + and STFIWX for loading SDmode on power7. + (movdd splitters): Likewise. + (movdd_hardfloat32): Likewise. + (movdd_softfloat32): Likewise. + (movdd_hardfloat64_mfpgpr): Likewise. + (movdd_hardfloat64): Likewise. + (movdd_softfloat64): Likewise. + + * config/rs6000/rs6000.md (FMOVE64): New iterators to combine + 64-bit binary and decimal floating point moves. + (FMOVE64X): Likewise. + (movdf): Combine 64-bit binary and decimal floating point moves. + Combine power6x (mfpgpr) moves with other moves by using + conditional constraits (wg). + (mov for DFmode/DDmode): Likewise. + (DFmode/DDmode splitters): Likewise. + (movdf_hardfloat32): Likewise. + (mov_hardfloat32 for DFmode/DDmode): Likewise. + (movdf_softfloat32): Likewise. + (movdf_hardfloat64_mfpgpr): Likewise. + (movdf_hardfloat64): Likewise. + (mov_hardfloat64 for DFmode/DDmode): Likewise. + (movdf_softfloat64): Likewise. + (mov_softfloat64 for DFmode/DDmode): Likewise. + (reload__load): Move to later in the file so they aren't in + the middle of the floating point move insns. + (reload__store): Likewise. + + * doc/md.texi (PowerPC and IBM RS6000 constraints): Document wg + constraint. + + * config/rs6000/rs6000.c (rs6000_debug_reg_global): Print out wg + constraint if -mdebug=reg. + (rs6000_initi_hard_regno_mode_ok): Enable wg constraint if + -mfpgpr. Enable using dd reload support if needed. + + * config/rs6000/dfp.md (movtd): Delete, combine with 128-bit + binary and decimal floating point moves in rs6000.md. + (movtd_internal): Likewise. + + * config/rs6000/rs6000.md (FMOVE128): Combine 128-bit binary and + decimal floating point moves. + (movtf): Likewise. + (movtf_internal): Likewise. + (mov_internal, TDmode/TFmode): Likewise. + (movtf_softfloat): Likewise. + (mov_softfloat, TDmode/TFmode): Likewise. + + * config/rs6000/rs6000.md (movdi_mfpgpr): Delete, combine with + movdi_internal64, using wg constraint for move direct operations. + (movdi_internal64): Likewise. + + * config/rs6000/rs6000.c (rs6000_debug_reg_global): Print + MODES_TIEABLE_P for selected modes. Print the numerical value of + the various virtual registers. Use GPR/FPR first/last values, + instead of hard coding the register numbers. Print which modes + have reload functions registered. + (rs6000_option_override_internal): If -mdebug=reg, trace the + options settings before/after setting cpu, target and subtarget + settings. + (rs6000_secondary_reload_trace): Improve the RTL dump for + -mdebug=addr and for secondary reload failures in + rs6000_secondary_reload_inner. + (rs6000_secondary_reload_fail): Likewise. + (rs6000_secondary_reload_inner): Likewise. + + * config/rs6000/rs6000.md (FIRST_GPR_REGNO): Add convenience + macros for first/last GPR and FPR registers. + (LAST_GPR_REGNO): Likewise. + (FIRST_FPR_REGNO): Likewise. + (LAST_FPR_REGNO): Likewise. + + * config/rs6000/vector.md (mul3): Use the combined macro + VECTOR_UNIT_ALTIVEC_OR_VSX_P instead of separate calls to + VECTOR_UNIT_ALTIVEC_P and VECTOR_UNIT_VSX_P. + (vcond): Likewise. + (vcondu): Likewise. + (vector_gtu): Likewise. + (vector_gte): Likewise. + (xor3): Don't allow logical operations on TImode in 32-bit + to prevent the compiler from converting DImode operations to + TImode. + (ior3): Likewise. + (and3): Likewise. + (one_cmpl2): Likewise. + (nor3): Likewise. + (andc3): Likewise. + + * config/rs6000/constraints.md (wt constraint): New constraint + that returns VSX_REGS if TImode is allowed in VSX registers. + + * config/rs6000/predicates.md (easy_fp_constant): 0.0f is an easy + constant under VSX. + + * config/rs6000/rs6000-modes.def (PTImode): Define, PTImode is + similar to TImode, but it is restricted to being in the GPRs. + + * config/rs6000/rs6000.opt (-mvsx-timode): New switch to allow + TImode to occupy a single VSX register. + + * config/rs6000/rs6000-cpus.def (ISA_2_6_MASKS_SERVER): Default to + -mvsx-timode for power7/power8. + (power7 cpu): Likewise. + (power8 cpu): Likewise. + + * config/rs6000/rs6000.c (rs6000_hard_regno_nregs_internal): Make + sure that TFmode/TDmode take up two registers if they are ever + allowed in the upper VSX registers. + (rs6000_hard_regno_mode_ok): If -mvsx-timode, allow TImode in VSX + registers. + (rs6000_init_hard_regno_mode_ok): Likewise. + (rs6000_debug_reg_global): Add debugging for PTImode and wt + constraint. Print if LRA is turned on. + (rs6000_option_override_internal): Give an error if -mvsx-timode + and VSX is not enabled. + (invalid_e500_subreg): Handle PTImode, restricting it to GPRs. If + -mvsx-timode, restrict TImode to reg+reg addressing, and PTImode + to reg+offset addressing. Use PTImode when checking offset + addresses for validity. + (reg_offset_addressing_ok_p): Likewise. + (rs6000_legitimate_offset_address_p): Likewise. + (rs6000_legitimize_address): Likewise. + (rs6000_legitimize_reload_address): Likewise. + (rs6000_legitimate_address_p): Likewise. + (rs6000_eliminate_indexed_memrefs): Likewise. + (rs6000_emit_move): Likewise. + (rs6000_secondary_reload): Likewise. + (rs6000_secondary_reload_inner): Handle PTImode. Allow 64-bit + reloads to fpr registers to continue to use reg+offset addressing, + but 64-bit reloads to altivec registers need reg+reg addressing. + Drop test for PRE_MODIFY, since VSX loads/stores no longer support + it. Treat LO_SUM like a PLUS operation. + (rs6000_secondary_reload_class): If type is 64-bit, prefer to use + FLOAT_REGS instead of VSX_RGS to allow use of reg+offset + addressing. + (rs6000_cannot_change_mode_class): Do not allow TImode in VSX + registers to share a register with a smaller sized type, since VSX + puts scalars in the upper 64-bits. + (print_operand): Add support for PTImode. + (rs6000_register_move_cost): Use VECTOR_MEM_VSX_P instead of + VECTOR_UNIT_VSX_P to catch types that can be loaded in VSX + registers, but don't have arithmetic support. + (rs6000_memory_move_cost): Add test for VSX. + (rs6000_opt_masks): Add -mvsx-timode. + + * config/rs6000/vsx.md (VSm): Change to use 64-bit aligned moves + for TImode. + (VSs): Likewise. + (VSr): Use wt constraint for TImode. + (VSv): Drop TImode support. + (vsx_movti): Delete, replace with versions for 32-bit and 64-bit. + (vsx_movti_64bit): Likewise. + (vsx_movti_32bit): Likewise. + (vec_store_): Use VSX iterator instead of vector iterator. + (vsx_and3): Delete use of '?' constraint on inputs, just put + one '?' on the appropriate output constraint. Do not allow TImode + logical operations on 32-bit systems. + (vsx_ior3): Likewise. + (vsx_xor3): Likewise. + (vsx_one_cmpl2): Likewise. + (vsx_nor3): Likewise. + (vsx_andc3): Likewise. + (vsx_concat_): Likewise. + (vsx_xxpermdi_): Fix thinko for non V2DF/V2DI modes. + + * config/rs6000/rs6000.h (MASK_VSX_TIMODE): Map from + OPTION_MASK_VSX_TIMODE. + (enum rs6000_reg_class_enum): Add RS6000_CONSTRAINT_wt. + (STACK_SAVEAREA_MODE): Use PTImode instead of TImode. + + * config/rs6000/rs6000.md (INT mode attribute): Add PTImode. + (TI2 iterator): New iterator for TImode, PTImode. + (wd mode attribute): Add values for vector types. + (movti_string): Replace TI move operations with operations for + TImode and PTImode. Add support for TImode being allowed in VSX + registers. + (mov_string, TImode/PTImode): Likewise. + (movti_ppc64): Likewise. + (mov_ppc64, TImode/PTImode): Likewise. + (TI mode splitters): Likewise. + + * doc/md.texi (PowerPC and IBM RS6000 constraints): Document wt + constraint. + 2013-03-20 Marc Glisse PR tree-optimization/56355 diff --git a/gcc/config/rs6000/constraints.md b/gcc/config/rs6000/constraints.md index ccb61edce45b..463d69c6ba46 100644 --- a/gcc/config/rs6000/constraints.md +++ b/gcc/config/rs6000/constraints.md @@ -64,10 +64,27 @@ (define_register_constraint "ws" "rs6000_constraints[RS6000_CONSTRAINT_ws]" "@internal") +;; TImode in VSX registers +(define_register_constraint "wt" "rs6000_constraints[RS6000_CONSTRAINT_wt]" + "@internal") + ;; any VSX register (define_register_constraint "wa" "rs6000_constraints[RS6000_CONSTRAINT_wa]" "@internal") +;; Register constraints to simplify move patterns +(define_register_constraint "wg" "rs6000_constraints[RS6000_CONSTRAINT_wg]" + "Floating point register if -mmfpgpr is used, or NO_REGS.") + +(define_register_constraint "wl" "rs6000_constraints[RS6000_CONSTRAINT_wl]" + "Floating point register if the LFIWAX instruction is enabled or NO_REGS.") + +(define_register_constraint "wx" "rs6000_constraints[RS6000_CONSTRAINT_wx]" + "Floating point register if the STFIWX instruction is enabled or NO_REGS.") + +(define_register_constraint "wz" "rs6000_constraints[RS6000_CONSTRAINT_wz]" + "Floating point register if the LFIWZX instruction is enabled or NO_REGS.") + ;; Altivec style load/store that ignores the bottom bits of the address (define_memory_constraint "wZ" "Indexed or indirect memory operand, ignoring the bottom 4 bits" diff --git a/gcc/config/rs6000/dfp.md b/gcc/config/rs6000/dfp.md index f73e115e3423..052ac482e0f4 100644 --- a/gcc/config/rs6000/dfp.md +++ b/gcc/config/rs6000/dfp.md @@ -29,77 +29,6 @@ ]) -(define_expand "movsd" - [(set (match_operand:SD 0 "nonimmediate_operand" "") - (match_operand:SD 1 "any_operand" ""))] - "TARGET_HARD_FLOAT && TARGET_FPRS" - "{ rs6000_emit_move (operands[0], operands[1], SDmode); DONE; }") - -(define_split - [(set (match_operand:SD 0 "gpc_reg_operand" "") - (match_operand:SD 1 "const_double_operand" ""))] - "reload_completed - && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31) - || (GET_CODE (operands[0]) == SUBREG - && GET_CODE (SUBREG_REG (operands[0])) == REG - && REGNO (SUBREG_REG (operands[0])) <= 31))" - [(set (match_dup 2) (match_dup 3))] - " -{ - long l; - REAL_VALUE_TYPE rv; - - REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]); - REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l); - - if (! TARGET_POWERPC64) - operands[2] = operand_subword (operands[0], 0, 0, SDmode); - else - operands[2] = gen_lowpart (SImode, operands[0]); - - operands[3] = gen_int_mode (l, SImode); -}") - -(define_insn "movsd_hardfloat" - [(set (match_operand:SD 0 "nonimmediate_operand" "=r,r,m,f,*c*l,!r,*h,!r,!r") - (match_operand:SD 1 "input_operand" "r,m,r,f,r,h,0,G,Fn"))] - "(gpc_reg_operand (operands[0], SDmode) - || gpc_reg_operand (operands[1], SDmode)) - && (TARGET_HARD_FLOAT && TARGET_FPRS)" - "@ - mr %0,%1 - lwz%U1%X1 %0,%1 - stw%U0%X0 %1,%0 - fmr %0,%1 - mt%0 %1 - mf%1 %0 - nop - # - #" - [(set_attr "type" "*,load,store,fp,mtjmpr,mfjmpr,*,*,*") - (set_attr "length" "4,4,4,4,4,4,4,4,8")]) - -(define_insn "movsd_softfloat" - [(set (match_operand:SD 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,r,*h") - (match_operand:SD 1 "input_operand" "r,r,h,m,r,I,L,R,G,Fn,0"))] - "(gpc_reg_operand (operands[0], SDmode) - || gpc_reg_operand (operands[1], SDmode)) - && (TARGET_SOFT_FLOAT || !TARGET_FPRS)" - "@ - mr %0,%1 - mt%0 %1 - mf%1 %0 - lwz%U1%X1 %0,%1 - stw%U0%X0 %1,%0 - li %0,%1 - lis %0,%v1 - la %0,%a1 - # - # - nop" - [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*,*") - (set_attr "length" "4,4,4,4,4,4,4,4,4,8,4")]) - (define_insn "movsd_store" [(set (match_operand:DD 0 "nonimmediate_operand" "=m") (unspec:DD [(match_operand:SD 1 "input_operand" "d")] @@ -108,7 +37,14 @@ || gpc_reg_operand (operands[1], SDmode)) && TARGET_HARD_FLOAT && TARGET_FPRS" "stfd%U0%X0 %1,%0" - [(set_attr "type" "fpstore") + [(set (attr "type") + (if_then_else + (match_test "update_indexed_address_mem (operands[0], VOIDmode)") + (const_string "fpstore_ux") + (if_then_else + (match_test "update_address_mem (operands[0], VOIDmode)") + (const_string "fpstore_u") + (const_string "fpstore")))) (set_attr "length" "4")]) (define_insn "movsd_load" @@ -119,7 +55,14 @@ || gpc_reg_operand (operands[1], DDmode)) && TARGET_HARD_FLOAT && TARGET_FPRS" "lfd%U1%X1 %0,%1" - [(set_attr "type" "fpload") + [(set (attr "type") + (if_then_else + (match_test "update_indexed_address_mem (operands[1], VOIDmode)") + (const_string "fpload_ux") + (if_then_else + (match_test "update_address_mem (operands[1], VOIDmode)") + (const_string "fpload_u") + (const_string "fpload")))) (set_attr "length" "4")]) ;; Hardware support for decimal floating point operations. @@ -182,211 +125,6 @@ "fnabs %0,%1" [(set_attr "type" "fp")]) -(define_expand "movdd" - [(set (match_operand:DD 0 "nonimmediate_operand" "") - (match_operand:DD 1 "any_operand" ""))] - "" - "{ rs6000_emit_move (operands[0], operands[1], DDmode); DONE; }") - -(define_split - [(set (match_operand:DD 0 "gpc_reg_operand" "") - (match_operand:DD 1 "const_int_operand" ""))] - "! TARGET_POWERPC64 && reload_completed - && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31) - || (GET_CODE (operands[0]) == SUBREG - && GET_CODE (SUBREG_REG (operands[0])) == REG - && REGNO (SUBREG_REG (operands[0])) <= 31))" - [(set (match_dup 2) (match_dup 4)) - (set (match_dup 3) (match_dup 1))] - " -{ - int endian = (WORDS_BIG_ENDIAN == 0); - HOST_WIDE_INT value = INTVAL (operands[1]); - - operands[2] = operand_subword (operands[0], endian, 0, DDmode); - operands[3] = operand_subword (operands[0], 1 - endian, 0, DDmode); -#if HOST_BITS_PER_WIDE_INT == 32 - operands[4] = (value & 0x80000000) ? constm1_rtx : const0_rtx; -#else - operands[4] = GEN_INT (value >> 32); - operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000); -#endif -}") - -(define_split - [(set (match_operand:DD 0 "gpc_reg_operand" "") - (match_operand:DD 1 "const_double_operand" ""))] - "! TARGET_POWERPC64 && reload_completed - && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31) - || (GET_CODE (operands[0]) == SUBREG - && GET_CODE (SUBREG_REG (operands[0])) == REG - && REGNO (SUBREG_REG (operands[0])) <= 31))" - [(set (match_dup 2) (match_dup 4)) - (set (match_dup 3) (match_dup 5))] - " -{ - int endian = (WORDS_BIG_ENDIAN == 0); - long l[2]; - REAL_VALUE_TYPE rv; - - REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]); - REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l); - - operands[2] = operand_subword (operands[0], endian, 0, DDmode); - operands[3] = operand_subword (operands[0], 1 - endian, 0, DDmode); - operands[4] = gen_int_mode (l[endian], SImode); - operands[5] = gen_int_mode (l[1 - endian], SImode); -}") - -(define_split - [(set (match_operand:DD 0 "gpc_reg_operand" "") - (match_operand:DD 1 "const_double_operand" ""))] - "TARGET_POWERPC64 && reload_completed - && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31) - || (GET_CODE (operands[0]) == SUBREG - && GET_CODE (SUBREG_REG (operands[0])) == REG - && REGNO (SUBREG_REG (operands[0])) <= 31))" - [(set (match_dup 2) (match_dup 3))] - " -{ - int endian = (WORDS_BIG_ENDIAN == 0); - long l[2]; - REAL_VALUE_TYPE rv; -#if HOST_BITS_PER_WIDE_INT >= 64 - HOST_WIDE_INT val; -#endif - - REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]); - REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l); - - operands[2] = gen_lowpart (DImode, operands[0]); - /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */ -#if HOST_BITS_PER_WIDE_INT >= 64 - val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32 - | ((HOST_WIDE_INT)(unsigned long)l[1 - endian])); - - operands[3] = gen_int_mode (val, DImode); -#else - operands[3] = immed_double_const (l[1 - endian], l[endian], DImode); -#endif -}") - -;; Don't have reload use general registers to load a constant. First, -;; it might not work if the output operand is the equivalent of -;; a non-offsettable memref, but also it is less efficient than loading -;; the constant into an FP register, since it will probably be used there. -;; The "??" is a kludge until we can figure out a more reasonable way -;; of handling these non-offsettable values. -(define_insn "*movdd_hardfloat32" - [(set (match_operand:DD 0 "nonimmediate_operand" "=!r,??r,m,d,d,m,!r,!r,!r") - (match_operand:DD 1 "input_operand" "r,m,r,d,m,d,G,H,F"))] - "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS - && (gpc_reg_operand (operands[0], DDmode) - || gpc_reg_operand (operands[1], DDmode))" - "* -{ - switch (which_alternative) - { - default: - gcc_unreachable (); - case 0: - case 1: - case 2: - return \"#\"; - case 3: - return \"fmr %0,%1\"; - case 4: - return \"lfd%U1%X1 %0,%1\"; - case 5: - return \"stfd%U0%X0 %1,%0\"; - case 6: - case 7: - case 8: - return \"#\"; - } -}" - [(set_attr "type" "two,load,store,fp,fpload,fpstore,*,*,*") - (set_attr "length" "8,16,16,4,4,4,8,12,16")]) - -(define_insn "*movdd_softfloat32" - [(set (match_operand:DD 0 "nonimmediate_operand" "=r,r,m,r,r,r") - (match_operand:DD 1 "input_operand" "r,m,r,G,H,F"))] - "! TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS) - && (gpc_reg_operand (operands[0], DDmode) - || gpc_reg_operand (operands[1], DDmode))" - "#" - [(set_attr "type" "two,load,store,*,*,*") - (set_attr "length" "8,8,8,8,12,16")]) - -; ld/std require word-aligned displacements -> 'Y' constraint. -; List Y->r and r->Y before r->r for reload. -(define_insn "*movdd_hardfloat64_mfpgpr" - [(set (match_operand:DD 0 "nonimmediate_operand" "=Y,r,!r,d,d,m,*c*l,!r,*h,!r,!r,!r,r,d") - (match_operand:DD 1 "input_operand" "r,Y,r,d,m,d,r,h,0,G,H,F,d,r"))] - "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS - && (gpc_reg_operand (operands[0], DDmode) - || gpc_reg_operand (operands[1], DDmode))" - "@ - std%U0%X0 %1,%0 - ld%U1%X1 %0,%1 - mr %0,%1 - fmr %0,%1 - lfd%U1%X1 %0,%1 - stfd%U0%X0 %1,%0 - mt%0 %1 - mf%1 %0 - nop - # - # - # - mftgpr %0,%1 - mffgpr %0,%1" - [(set_attr "type" "store,load,*,fp,fpload,fpstore,mtjmpr,mfjmpr,*,*,*,*,mftgpr,mffgpr") - (set_attr "length" "4,4,4,4,4,4,4,4,4,8,12,16,4,4")]) - -; ld/std require word-aligned displacements -> 'Y' constraint. -; List Y->r and r->Y before r->r for reload. -(define_insn "*movdd_hardfloat64" - [(set (match_operand:DD 0 "nonimmediate_operand" "=Y,r,!r,d,d,m,*c*l,!r,*h,!r,!r,!r") - (match_operand:DD 1 "input_operand" "r,Y,r,d,m,d,r,h,0,G,H,F"))] - "TARGET_POWERPC64 && !TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS - && (gpc_reg_operand (operands[0], DDmode) - || gpc_reg_operand (operands[1], DDmode))" - "@ - std%U0%X0 %1,%0 - ld%U1%X1 %0,%1 - mr %0,%1 - fmr %0,%1 - lfd%U1%X1 %0,%1 - stfd%U0%X0 %1,%0 - mt%0 %1 - mf%1 %0 - nop - # - # - #" - [(set_attr "type" "store,load,*,fp,fpload,fpstore,mtjmpr,mfjmpr,*,*,*,*") - (set_attr "length" "4,4,4,4,4,4,4,4,4,8,12,16")]) - -(define_insn "*movdd_softfloat64" - [(set (match_operand:DD 0 "nonimmediate_operand" "=r,Y,r,cl,r,r,r,r,*h") - (match_operand:DD 1 "input_operand" "Y,r,r,r,h,G,H,F,0"))] - "TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS) - && (gpc_reg_operand (operands[0], DDmode) - || gpc_reg_operand (operands[1], DDmode))" - "@ - ld%U1%X1 %0,%1 - std%U0%X0 %1,%0 - mr %0,%1 - mt%0 %1 - mf%1 %0 - # - # - # - nop" - [(set_attr "type" "load,store,*,mtjmpr,mfjmpr,*,*,*,*") - (set_attr "length" "4,4,4,4,4,8,12,16,4")]) - (define_expand "negtd2" [(set (match_operand:TD 0 "gpc_reg_operand" "") (neg:TD (match_operand:TD 1 "gpc_reg_operand" "")))] @@ -420,27 +158,6 @@ "fnabs %0,%1" [(set_attr "type" "fp")]) -(define_expand "movtd" - [(set (match_operand:TD 0 "general_operand" "") - (match_operand:TD 1 "any_operand" ""))] - "TARGET_HARD_FLOAT && TARGET_FPRS" - "{ rs6000_emit_move (operands[0], operands[1], TDmode); DONE; }") - -; It's important to list the Y->r and r->Y moves before r->r because -; otherwise reload, given m->r, will try to pick r->r and reload it, -; which doesn't make progress. -(define_insn_and_split "*movtd_internal" - [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r") - (match_operand:TD 1 "input_operand" "d,m,d,r,YGHF,r"))] - "TARGET_HARD_FLOAT && TARGET_FPRS - && (gpc_reg_operand (operands[0], TDmode) - || gpc_reg_operand (operands[1], TDmode))" - "#" - "&& reload_completed" - [(pc)] -{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; } - [(set_attr "length" "8,8,8,20,20,16")]) - ;; Hardware support for decimal floating point operations. (define_insn "extendddtd2" diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index 868ba567976a..8112f26fe198 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -329,6 +329,11 @@ && mode != DImode) return 1; + /* The constant 0.0 is easy under VSX. */ + if ((mode == SFmode || mode == DFmode || mode == SDmode || mode == DDmode) + && VECTOR_UNIT_VSX_P (DFmode) && op == CONST0_RTX (mode)) + return 1; + if (DECIMAL_FLOAT_MODE_P (mode)) return 0; @@ -552,6 +557,28 @@ && REG_P (XEXP (op, 1)))") (match_operand 0 "address_operand"))) +;; Return 1 if the operand is an index-form address. +(define_special_predicate "indexed_address" + (match_test "(GET_CODE (op) == PLUS + && REG_P (XEXP (op, 0)) + && REG_P (XEXP (op, 1)))")) + +;; Return 1 if the operand is a MEM with an update-form address. This may +;; also include update-indexed form. +(define_special_predicate "update_address_mem" + (match_test "(MEM_P (op) + && (GET_CODE (XEXP (op, 0)) == PRE_INC + || GET_CODE (XEXP (op, 0)) == PRE_DEC + || GET_CODE (XEXP (op, 0)) == PRE_MODIFY))")) + +;; Return 1 if the operand is a MEM with an update-indexed-form address. Note +;; that PRE_INC/PRE_DEC will always be non-indexed (i.e. non X-form) since the +;; increment is based on the mode size and will therefor always be a const. +(define_special_predicate "update_indexed_address_mem" + (match_test "(MEM_P (op) + && GET_CODE (XEXP (op, 0)) == PRE_MODIFY + && indexed_address (XEXP (XEXP (op, 0), 1), mode))")) + ;; Used for the destination of the fix_truncdfsi2 expander. ;; If stfiwx will be used, the result goes to memory; otherwise, ;; we're going to emit a store and a load of a subreg, so the dest is a diff --git a/gcc/config/rs6000/rs6000-cpus.def b/gcc/config/rs6000/rs6000-cpus.def index 3f17c6f2395f..0564018b3f01 100644 --- a/gcc/config/rs6000/rs6000-cpus.def +++ b/gcc/config/rs6000/rs6000-cpus.def @@ -42,7 +42,8 @@ #define ISA_2_6_MASKS_SERVER (ISA_2_5_MASKS_SERVER \ | OPTION_MASK_POPCNTD \ | OPTION_MASK_ALTIVEC \ - | OPTION_MASK_VSX) + | OPTION_MASK_VSX \ + | OPTION_MASK_VSX_TIMODE) #define POWERPC_7400_MASK (OPTION_MASK_PPC_GFXOPT | OPTION_MASK_ALTIVEC) @@ -76,7 +77,8 @@ | OPTION_MASK_RECIP_PRECISION \ | OPTION_MASK_SOFT_FLOAT \ | OPTION_MASK_STRICT_ALIGN_OPTIONAL \ - | OPTION_MASK_VSX) + | OPTION_MASK_VSX \ + | OPTION_MASK_VSX_TIMODE) #endif @@ -165,11 +167,11 @@ RS6000_CPU ("power6x", PROCESSOR_POWER6, MASK_POWERPC64 | MASK_PPC_GPOPT RS6000_CPU ("power7", PROCESSOR_POWER7, /* Don't add MASK_ISEL by default */ POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD - | MASK_VSX | MASK_RECIP_PRECISION) + | MASK_VSX | MASK_RECIP_PRECISION | MASK_VSX_TIMODE) RS6000_CPU ("power8", PROCESSOR_POWER7, /* Don't add MASK_ISEL by default */ POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD - | MASK_VSX | MASK_RECIP_PRECISION) + | MASK_VSX | MASK_RECIP_PRECISION | MASK_VSX_TIMODE) RS6000_CPU ("powerpc", PROCESSOR_POWERPC, 0) RS6000_CPU ("powerpc64", PROCESSOR_POWERPC64, MASK_PPC_GFXOPT | MASK_POWERPC64) RS6000_CPU ("rs64", PROCESSOR_RS64A, MASK_PPC_GFXOPT | MASK_POWERPC64) diff --git a/gcc/config/rs6000/rs6000-modes.def b/gcc/config/rs6000/rs6000-modes.def index bc18f8a168c2..54548be70385 100644 --- a/gcc/config/rs6000/rs6000-modes.def +++ b/gcc/config/rs6000/rs6000-modes.def @@ -41,3 +41,6 @@ VECTOR_MODE (INT, DI, 1); VECTOR_MODES (FLOAT, 8); /* V4HF V2SF */ VECTOR_MODES (FLOAT, 16); /* V8HF V4SF V2DF */ VECTOR_MODES (FLOAT, 32); /* V16HF V8SF V4DF */ + +/* Replacement for TImode that only is allowed in GPRs. */ +PARTIAL_INT_MODE (TI); diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index fbf57be44a34..921ff4b04161 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -1516,8 +1516,9 @@ rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode) { unsigned HOST_WIDE_INT reg_size; + /* TF/TD modes are special in that they always take 2 registers. */ if (FP_REGNO_P (regno)) - reg_size = (VECTOR_MEM_VSX_P (mode) + reg_size = ((VECTOR_MEM_VSX_P (mode) && mode != TDmode && mode != TFmode) ? UNITS_PER_VSX_WORD : UNITS_PER_FP_WORD); @@ -1561,14 +1562,18 @@ rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode) return ALTIVEC_REGNO_P (last_regno); } + /* Allow TImode in all VSX registers if the user asked for it. Note, PTImode + can only go in GPRs. */ + if (mode == TImode && TARGET_VSX_TIMODE && VSX_REGNO_P (regno)) + return 1; + /* The GPRs can hold any mode, but values bigger than one register cannot go past R31. */ if (INT_REGNO_P (regno)) return INT_REGNO_P (last_regno); /* The float registers (except for VSX vector modes) can only hold floating - modes and DImode. This excludes the 32-bit decimal float mode for - now. */ + modes and DImode. */ if (FP_REGNO_P (regno)) { if (SCALAR_FLOAT_MODE_P (mode) @@ -1602,9 +1607,8 @@ rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode) if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode)) return 1; - /* We cannot put TImode anywhere except general register and it must be able - to fit within the register set. In the future, allow TImode in the - Altivec or VSX registers. */ + /* We cannot put non-VSX TImode or PTImode anywhere except general register + and it must be able to fit within the register set. */ return GET_MODE_SIZE (mode) <= UNITS_PER_WORD; } @@ -1693,6 +1697,7 @@ rs6000_debug_reg_global (void) static const char *const tf[2] = { "false", "true" }; const char *nl = (const char *)0; int m; + size_t m1, m2, v; char costly_num[20]; char nop_num[20]; char flags_buffer[40]; @@ -1713,10 +1718,67 @@ rs6000_debug_reg_global (void) "other" }; - fprintf (stderr, "Register information: (last virtual reg = %d)\n", - LAST_VIRTUAL_REGISTER); - rs6000_debug_reg_print (0, 31, "gr"); - rs6000_debug_reg_print (32, 63, "fp"); + /* Modes we want tieable information on. */ + static const enum machine_mode print_tieable_modes[] = { + QImode, + HImode, + SImode, + DImode, + TImode, + PTImode, + SFmode, + DFmode, + TFmode, + SDmode, + DDmode, + TDmode, + V8QImode, + V4HImode, + V2SImode, + V16QImode, + V8HImode, + V4SImode, + V2DImode, + V32QImode, + V16HImode, + V8SImode, + V4DImode, + V2SFmode, + V4SFmode, + V2DFmode, + V8SFmode, + V4DFmode, + CCmode, + CCUNSmode, + CCEQmode, + }; + + /* Virtual regs we are interested in. */ + const static struct { + int regno; /* register number. */ + const char *name; /* register name. */ + } virtual_regs[] = { + { STACK_POINTER_REGNUM, "stack pointer:" }, + { TOC_REGNUM, "toc: " }, + { STATIC_CHAIN_REGNUM, "static chain: " }, + { RS6000_PIC_OFFSET_TABLE_REGNUM, "pic offset: " }, + { HARD_FRAME_POINTER_REGNUM, "hard frame: " }, + { ARG_POINTER_REGNUM, "arg pointer: " }, + { FRAME_POINTER_REGNUM, "frame pointer:" }, + { FIRST_PSEUDO_REGISTER, "first pseudo: " }, + { FIRST_VIRTUAL_REGISTER, "first virtual:" }, + { VIRTUAL_INCOMING_ARGS_REGNUM, "incoming_args:" }, + { VIRTUAL_STACK_VARS_REGNUM, "stack_vars: " }, + { VIRTUAL_STACK_DYNAMIC_REGNUM, "stack_dynamic:" }, + { VIRTUAL_OUTGOING_ARGS_REGNUM, "outgoing_args:" }, + { VIRTUAL_CFA_REGNUM, "cfa (frame): " }, + { VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM, "stack boundry:" }, + { LAST_VIRTUAL_REGISTER, "last virtual: " }, + }; + + fputs ("\nHard register information:\n", stderr); + rs6000_debug_reg_print (FIRST_GPR_REGNO, LAST_GPR_REGNO, "gr"); + rs6000_debug_reg_print (FIRST_FPR_REGNO, LAST_FPR_REGNO, "fp"); rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO, LAST_ALTIVEC_REGNO, "vs"); @@ -1729,6 +1791,10 @@ rs6000_debug_reg_global (void) rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a"); rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f"); + fputs ("\nVirtual/stack/frame registers:\n", stderr); + for (v = 0; v < ARRAY_SIZE (virtual_regs); v++) + fprintf (stderr, "%s regno = %3d\n", virtual_regs[v].name, virtual_regs[v].regno); + fprintf (stderr, "\n" "d reg_class = %s\n" @@ -1737,28 +1803,74 @@ rs6000_debug_reg_global (void) "wa reg_class = %s\n" "wd reg_class = %s\n" "wf reg_class = %s\n" - "ws reg_class = %s\n\n", + "wg reg_class = %s\n" + "wl reg_class = %s\n" + "ws reg_class = %s\n" + "wt reg_class = %s\n" + "wx reg_class = %s\n" + "wz reg_class = %s\n" + "\n", reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]], reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]], reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]], reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]], reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]], reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]], - reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]); + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wg]], + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wl]], + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]], + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wt]], + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wx]], + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wz]]); for (m = 0; m < NUM_MACHINE_MODES; ++m) - if (rs6000_vector_unit[m] || rs6000_vector_mem[m]) + if (rs6000_vector_unit[m] || rs6000_vector_mem[m] + || (rs6000_vector_reload[m][0] != CODE_FOR_nothing) + || (rs6000_vector_reload[m][1] != CODE_FOR_nothing)) { nl = "\n"; - fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n", + fprintf (stderr, + "Vector mode: %-5s arithmetic: %-10s move: %-10s " + "reload-out: %c reload-in: %c\n", GET_MODE_NAME (m), rs6000_debug_vector_unit[ rs6000_vector_unit[m] ], - rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]); + rs6000_debug_vector_unit[ rs6000_vector_mem[m] ], + (rs6000_vector_reload[m][0] != CODE_FOR_nothing) ? 'y' : 'n', + (rs6000_vector_reload[m][1] != CODE_FOR_nothing) ? 'y' : 'n'); } if (nl) fputs (nl, stderr); + for (m1 = 0; m1 < ARRAY_SIZE (print_tieable_modes); m1++) + { + enum machine_mode mode1 = print_tieable_modes[m1]; + bool first_time = true; + + nl = (const char *)0; + for (m2 = 0; m2 < ARRAY_SIZE (print_tieable_modes); m2++) + { + enum machine_mode mode2 = print_tieable_modes[m2]; + if (mode1 != mode2 && MODES_TIEABLE_P (mode1, mode2)) + { + if (first_time) + { + fprintf (stderr, "Tieable modes %s:", GET_MODE_NAME (mode1)); + nl = "\n"; + first_time = false; + } + + fprintf (stderr, " %s", GET_MODE_NAME (mode2)); + } + } + + if (!first_time) + fputs ("\n", stderr); + } + + if (nl) + fputs (nl, stderr); + if (rs6000_recip_control) { fprintf (stderr, "\nReciprocal mask = 0x%x\n", rs6000_recip_control); @@ -1938,6 +2050,9 @@ rs6000_debug_reg_global (void) if (TARGET_LINK_STACK) fprintf (stderr, DEBUG_FMT_S, "link_stack", "true"); + if (targetm.lra_p ()) + fprintf (stderr, DEBUG_FMT_S, "lra", "true"); + fprintf (stderr, DEBUG_FMT_S, "plt-format", TARGET_SECURE_PLT ? "secure" : "bss"); fprintf (stderr, DEBUG_FMT_S, "struct-return", @@ -2083,6 +2198,13 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p) rs6000_vector_align[DFmode] = align64; } + /* Allow TImode in VSX register and set the VSX memory macros. */ + if (TARGET_VSX && TARGET_VSX_TIMODE) + { + rs6000_vector_mem[TImode] = VECTOR_VSX; + rs6000_vector_align[TImode] = align64; + } + /* TODO add SPE and paired floating point vector support. */ /* Register class constraints for the constraints that depend on compile @@ -2106,11 +2228,27 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p) rs6000_constraints[RS6000_CONSTRAINT_ws] = (TARGET_VSX_SCALAR_MEMORY ? VSX_REGS : FLOAT_REGS); + if (TARGET_VSX_TIMODE) + rs6000_constraints[RS6000_CONSTRAINT_wt] = VSX_REGS; } + /* Add conditional constraints based on various options, to allow us to + collapse multiple insn patterns. */ if (TARGET_ALTIVEC) rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS; + if (TARGET_MFPGPR) + rs6000_constraints[RS6000_CONSTRAINT_wg] = FLOAT_REGS; + + if (TARGET_LFIWAX) + rs6000_constraints[RS6000_CONSTRAINT_wl] = FLOAT_REGS; + + if (TARGET_STFIWX) + rs6000_constraints[RS6000_CONSTRAINT_wx] = FLOAT_REGS; + + if (TARGET_LFIWZX) + rs6000_constraints[RS6000_CONSTRAINT_wz] = FLOAT_REGS; + /* Set up the reload helper functions. */ if (TARGET_VSX || TARGET_ALTIVEC) { @@ -2132,6 +2270,13 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p) { rs6000_vector_reload[DFmode][0] = CODE_FOR_reload_df_di_store; rs6000_vector_reload[DFmode][1] = CODE_FOR_reload_df_di_load; + rs6000_vector_reload[DDmode][0] = CODE_FOR_reload_dd_di_store; + rs6000_vector_reload[DDmode][1] = CODE_FOR_reload_dd_di_load; + } + if (TARGET_VSX_TIMODE) + { + rs6000_vector_reload[TImode][0] = CODE_FOR_reload_ti_di_store; + rs6000_vector_reload[TImode][1] = CODE_FOR_reload_ti_di_load; } } else @@ -2152,6 +2297,13 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p) { rs6000_vector_reload[DFmode][0] = CODE_FOR_reload_df_si_store; rs6000_vector_reload[DFmode][1] = CODE_FOR_reload_df_si_load; + rs6000_vector_reload[DDmode][0] = CODE_FOR_reload_dd_si_store; + rs6000_vector_reload[DDmode][1] = CODE_FOR_reload_dd_si_load; + } + if (TARGET_VSX_TIMODE) + { + rs6000_vector_reload[TImode][0] = CODE_FOR_reload_ti_si_store; + rs6000_vector_reload[TImode][1] = CODE_FOR_reload_ti_si_load; } } } @@ -2641,6 +2793,9 @@ rs6000_option_override_internal (bool global_init_p) } } + if (TARGET_DEBUG_REG || TARGET_DEBUG_TARGET) + rs6000_print_isa_options (stderr, 0, "before defaults", rs6000_isa_flags); + /* For the newer switches (vsx, dfp, etc.) set some of the older options, unless the user explicitly used the -mno-