From: Matthew Fortune Date: Fri, 19 Dec 2014 20:17:36 +0000 (+0000) Subject: MIPS32R6 and MIPS64R6 support X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=82f84ecbb47c8e8e5e1a6be471e81b74d10ecd18;p=gcc.git MIPS32R6 and MIPS64R6 support gcc/ * config.gcc: Add mipsisa64r6 and mipsisa32r6 cpu support. * config/mips/constraints.md (ZD): Add r6 restrictions. * config/mips/gnu-user.h (DRIVER_SELF_SPECS): Add MIPS_ISA_LEVEL_SPEC. * config/mips/loongson.md (div3, mod3): Move to mips.md. * config/mips/mips-cpus.def (mips32r6, mips64r6): Define. * config/mips/mips-modes.def (CCF): New mode. * config/mips/mips-protos.h (mips_9bit_offset_address_p): New prototype. * config/mips/mips-tables.opt: Regenerate. * config/mips/mips.c (MIPS_JR): Use JALR $, for R6. (mips_rtx_cost_data): Add pseudo-processors W32 and W64. (mips_9bit_offset_address_p): New function. (mips_rtx_costs): Account for R6 multiply and FMA instructions. (mips_emit_compare): Implement R6 FPU comparisons. (mips_expand_conditional_move): Implement R6 selects. (mips_expand_conditional_trap): Account for removed trap immediate. (mips_expand_block_move): Disable inline move when LWL/LWR are removed. (mips_print_float_branch_condition): Update for R6 FPU branches. (mips_print_operand): Handle CCF mode compares. (mips_interrupt_extra_call_saved_reg_p): Do not attempt to callee-save MD_REGS for R6. (mips_hard_regno_mode_ok_p): Support CCF mode. (mips_mode_ok_for_mov_fmt_p): Likewise. (mips_secondary_reload_class): CCFmode can be loaded directly. (mips_set_fast_mult_zero_zero_p): Account for R6 multiply instructions. (mips_option_override): Ensure R6 is used with fp64. Set default mips_nan modes. Check for mips_nan support. Prevent DSP with R6. (mips_conditional_register_usage): Disable MD_REGS for R6. Disable FPSW for R6. (mips_mulsidi3_gen_fn): Support R6 multiply instructions. * config/mips/mips.h (ISA_MIPS32R6, ISA_MIPS64R6): Define. (TARGET_CPU_CPP_BUILTINS): Rework for mips32/mips64. (ISA_HAS_JR): New macro. (ISA_HAS_HILO): New macro. (ISA_HAS_R6MUL): Likewise. (ISA_HAS_R6DMUL): Likewise. (ISA_HAS_R6DIV): Likewise. (ISA_HAS_R6DDIV): Likewise. (ISA_HAS_CCF): Likewise. (ISA_HAS_SEL): Likewise. (ISA_HAS_COND_TRAPI): Likewise. (ISA_HAS_FP_MADDF_MSUBF): Likewise. (ISA_HAS_LWL_LWR): Likewise. (ISA_HAS_IEEE_754_LEGACY): Likewise. (ISA_HAS_IEEE_754_2008): Likewise. (ISA_HAS_PREFETCH_9BIT): Likewise. (MIPSR6_9BIT_OFFSET_P): New macro. (BASE_DRIVER_SELF_SPECS): Use MIPS_ISA_DRIVER_SELF_SPECS. (DRIVER_SELF_SPECS): Use MIPS_ISA_LEVEL_SPEC. (MULTILIB_ISA_DEFAULT): Handle mips32r6 and mips64r6. (MIPS_ISA_LEVEL_SPEC): Likewise. (MIPS_ISA_SYNCI_SPEC): Likewise. (ISA_HAS_64BIT_REGS): Likewise. (ISA_HAS_BRANCHLIKELY): Likewise. (ISA_HAS_MUL3): Likewise. (ISA_HAS_DMULT): Likewise. (ISA_HAS_DDIV): Likewise. (ISA_HAS_DIV): Likewise. (ISA_HAS_MULT): Likewise. (ISA_HAS_FP_CONDMOVE): Likewise. (ISA_HAS_8CC): Likewise. (ISA_HAS_FP4): Likewise. (ISA_HAS_PAIRED_SINGLE): Likewise. (ISA_HAS_MADD_MSUB): Likewise. (ISA_HAS_FP_RECIP_RSQRT): Likewise. * config/mips/mips.md (processor): Add w32 and w64. (FPCC): New mode iterator. (reg): Add CCF mode. (fpcmp): New mode attribute. (fcond): Add ordered, ltgt and ne codes. (fcond): Update code attribute. (sel): New code attribute. (selinv): Likewise. (ctrap4): Update condition. (*conditional_trap_reg): New define_insn. (*conditional_trap): Update condition. (mul3): Expand R6 multiply instructions. (mulsi3_highpart): Likewise. (muldi3_highpart): Likewise. (mul3_mul3_loongson): Rename... (mul3_mul3_hilo): To this. Add R6 mul instruction. (mulsidi3_32bit_r6): New expander. (mulsidi3_32bit): Restrict to pre-r6 multiplies. (mulsidi3_32bit_r4000): Likewise. (mulsidi3_64bit): Likewise. (mulsi3_highpart_internal): Likewise. (mulsidi3_64bit_r6dmul): New instruction. (mulsi3_highpart_r6): Likewise. (muldi3_highpart_r6): Likewise. (fma4): Likewise. (movccf): Likewise. (*sel_using_): Likewise. (*sel): Likewise. (div3): Moved from loongson.md. Add R6 instructions. (mod3): Likewise. (extvmisalign): Require ISA_HAS_LWL_LWR. (extzvmisalign): Likewise. (insvmisalign): Likewise. (mips_cache): Account for R6 displacement field sizes. (*branch_fp): Rename... (*branch_fp_): To this. Add CCFmode support. (*branch_fp_inverted): Rename... (*branch_fp_inverted_): To this. Add CCFmode support. (s_): Rename... (s__using_): To this. Add FCCmode condition support. (s_ swapped): Rename... (s__using_ swapped): To this. Add CCFmode condition support. (movcc GPR): Expand R6 selects. (movcc FPR): Expand R6 selects. (*tls_get_tp__split): Do not .set push for >= mips32r2. * config/mips/netbsd.h (TARGET_CPU_CPP_BUILTINS): Update similarly to mips.h. (ASM_SPEC): Add mips32r6, mips64r6. * config/mips/t-isa3264 (MULTILIB_OPTIONS, MULTILIB_DIRNAMES): Update for mips32r6/mips64r6. * doc/invoke.texi: Document -mips32r6,-mips64r6. * doc/md.texi: Update comment for ZD constraint. libgcc/ * config.host: Support mipsisa32r6 and mipsisa64r6. * config/mips/mips16.S: Do not build for R6. gcc/testsuite/ * gcc.dg/torture/mips-hilo-2.c: Unconditionally pass for R6 onwards. * gcc.dg/torture/pr19683-1.c: Likewise. * gcc.target/mips/branch-cost-2.c: Require MOVN. * gcc.target/mips/movcc-1.c: Likewise. * gcc.target/mips/movcc-2.c: Likewise. * gcc.target/mips/movcc-3.c: Likewise. * gcc.target/mips/call-saved-4.c: Require LDC. * gcc.target/mips/dmult-1.c: Require R5 or earlier. * gcc.target/mips/fpcmp-1.c: Likewise. * gcc.target/mips/fpcmp-2.c: Likewise. * gcc.target/mips/neg-abs-2.c: Likewise. * gcc.target/mips/timode-1.c: Likewise. * gcc.target/mips/unaligned-1.c: Likewise. * gcc.target/mips/madd-3.c: Require MADD. * gcc.target/mips/madd-9.c: Likewise. * gcc.target/mips/maddu-3.c: Likewise. * gcc.target/mips/msub-3.c: Likewise. * gcc.target/mips/msubu-3.c: Likewise. * gcc.target/mips/mult-1.c: Require INS and not DMUL. * gcc.target/mips/mips-ps-type-2.c: Require MADD.PS. * gcc.target/mips/mips.exp (mips_option_groups): Add ins, dmul, ldc, movn, madd, maddps. (mips-dg-options): INS available from R2. LDC available from MIPS II, DMUL is present in octeon. Describe all features removed from R6. Co-Authored-By: Steve Ellcey From-SVN: r218973 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a800fed4a18..9dce19b0d81 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,126 @@ +2014-12-19 Matthew Fortune + + * config.gcc: Add mipsisa64r6 and mipsisa32r6 cpu support. + * config/mips/constraints.md (ZD): Add r6 restrictions. + * config/mips/gnu-user.h (DRIVER_SELF_SPECS): Add MIPS_ISA_LEVEL_SPEC. + * config/mips/loongson.md + (div3, mod3): Move to mips.md. + * config/mips/mips-cpus.def (mips32r6, mips64r6): Define. + * config/mips/mips-modes.def (CCF): New mode. + * config/mips/mips-protos.h + (mips_9bit_offset_address_p): New prototype. + * config/mips/mips-tables.opt: Regenerate. + * config/mips/mips.c (MIPS_JR): Use JALR $, for R6. + (mips_rtx_cost_data): Add pseudo-processors W32 and W64. + (mips_9bit_offset_address_p): New function. + (mips_rtx_costs): Account for R6 multiply and FMA instructions. + (mips_emit_compare): Implement R6 FPU comparisons. + (mips_expand_conditional_move): Implement R6 selects. + (mips_expand_conditional_trap): Account for removed trap immediate. + (mips_expand_block_move): Disable inline move when LWL/LWR are removed. + (mips_print_float_branch_condition): Update for R6 FPU branches. + (mips_print_operand): Handle CCF mode compares. + (mips_interrupt_extra_call_saved_reg_p): Do not attempt to callee-save + MD_REGS for R6. + (mips_hard_regno_mode_ok_p): Support CCF mode. + (mips_mode_ok_for_mov_fmt_p): Likewise. + (mips_secondary_reload_class): CCFmode can be loaded directly. + (mips_set_fast_mult_zero_zero_p): Account for R6 multiply instructions. + (mips_option_override): Ensure R6 is used with fp64. Set default + mips_nan modes. Check for mips_nan support. Prevent DSP with R6. + (mips_conditional_register_usage): Disable MD_REGS for R6. Disable + FPSW for R6. + (mips_mulsidi3_gen_fn): Support R6 multiply instructions. + * config/mips/mips.h (ISA_MIPS32R6, ISA_MIPS64R6): Define. + (TARGET_CPU_CPP_BUILTINS): Rework for mips32/mips64. + (ISA_HAS_JR): New macro. + (ISA_HAS_HILO): New macro. + (ISA_HAS_R6MUL): Likewise. + (ISA_HAS_R6DMUL): Likewise. + (ISA_HAS_R6DIV): Likewise. + (ISA_HAS_R6DDIV): Likewise. + (ISA_HAS_CCF): Likewise. + (ISA_HAS_SEL): Likewise. + (ISA_HAS_COND_TRAPI): Likewise. + (ISA_HAS_FP_MADDF_MSUBF): Likewise. + (ISA_HAS_LWL_LWR): Likewise. + (ISA_HAS_IEEE_754_LEGACY): Likewise. + (ISA_HAS_IEEE_754_2008): Likewise. + (ISA_HAS_PREFETCH_9BIT): Likewise. + (MIPSR6_9BIT_OFFSET_P): New macro. + (BASE_DRIVER_SELF_SPECS): Use MIPS_ISA_DRIVER_SELF_SPECS. + (DRIVER_SELF_SPECS): Use MIPS_ISA_LEVEL_SPEC. + (MULTILIB_ISA_DEFAULT): Handle mips32r6 and mips64r6. + (MIPS_ISA_LEVEL_SPEC): Likewise. + (MIPS_ISA_SYNCI_SPEC): Likewise. + (ISA_HAS_64BIT_REGS): Likewise. + (ISA_HAS_BRANCHLIKELY): Likewise. + (ISA_HAS_MUL3): Likewise. + (ISA_HAS_DMULT): Likewise. + (ISA_HAS_DDIV): Likewise. + (ISA_HAS_DIV): Likewise. + (ISA_HAS_MULT): Likewise. + (ISA_HAS_FP_CONDMOVE): Likewise. + (ISA_HAS_8CC): Likewise. + (ISA_HAS_FP4): Likewise. + (ISA_HAS_PAIRED_SINGLE): Likewise. + (ISA_HAS_MADD_MSUB): Likewise. + (ISA_HAS_FP_RECIP_RSQRT): Likewise. + * config/mips/mips.md (processor): Add w32 and w64. + (FPCC): New mode iterator. + (reg): Add CCF mode. + (fpcmp): New mode attribute. + (fcond): Add ordered, ltgt and ne codes. + (fcond): Update code attribute. + (sel): New code attribute. + (selinv): Likewise. + (ctrap4): Update condition. + (*conditional_trap_reg): New define_insn. + (*conditional_trap): Update condition. + (mul3): Expand R6 multiply instructions. + (mulsi3_highpart): Likewise. + (muldi3_highpart): Likewise. + (mul3_mul3_loongson): Rename... + (mul3_mul3_hilo): To this. Add R6 mul instruction. + (mulsidi3_32bit_r6): New expander. + (mulsidi3_32bit): Restrict to pre-r6 multiplies. + (mulsidi3_32bit_r4000): Likewise. + (mulsidi3_64bit): Likewise. + (mulsi3_highpart_internal): Likewise. + (mulsidi3_64bit_r6dmul): New instruction. + (mulsi3_highpart_r6): Likewise. + (muldi3_highpart_r6): Likewise. + (fma4): Likewise. + (movccf): Likewise. + (*sel_using_): Likewise. + (*sel): Likewise. + (div3): Moved from loongson.md. Add R6 instructions. + (mod3): Likewise. + (extvmisalign): Require ISA_HAS_LWL_LWR. + (extzvmisalign): Likewise. + (insvmisalign): Likewise. + (mips_cache): Account for R6 displacement field sizes. + (*branch_fp): Rename... + (*branch_fp_): To this. Add CCFmode support. + (*branch_fp_inverted): Rename... + (*branch_fp_inverted_): To this. Add CCFmode support. + (s_): Rename... + (s__using_): To this. Add FCCmode + condition support. + (s_ swapped): Rename... + (s__using_ swapped): To this. Add + CCFmode condition support. + (movcc GPR): Expand R6 selects. + (movcc FPR): Expand R6 selects. + (*tls_get_tp__split): Do not .set push for >= mips32r2. + * config/mips/netbsd.h (TARGET_CPU_CPP_BUILTINS): Update similarly to + mips.h. + (ASM_SPEC): Add mips32r6, mips64r6. + * config/mips/t-isa3264 (MULTILIB_OPTIONS, MULTILIB_DIRNAMES): Update + for mips32r6/mips64r6. + * doc/invoke.texi: Document -mips32r6,-mips64r6. + * doc/md.texi: Update comment for ZD constraint. + 2014-12-19 Segher Boessenkool PR target/64268 diff --git a/gcc/config.gcc b/gcc/config.gcc index 8541274a243..259f63b30fb 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -1973,6 +1973,9 @@ mips*-*-linux*) # Linux MIPS, either endian. tm_file="dbxelf.h elfos.h gnu-user.h linux.h linux-android.h glibc-stdint.h ${tm_file} mips/gnu-user.h mips/linux.h mips/linux-common.h" extra_options="${extra_options} linux-android.opt" case ${target} in + mipsisa32r6*) + default_mips_arch=mips32r6 + ;; mipsisa32r2*) default_mips_arch=mips32r2 ;; @@ -1991,6 +1994,11 @@ mips*-*-linux*) # Linux MIPS, either endian. target_cpu_default=MASK_SOFT_FLOAT_ABI enable_mips_multilibs="yes" ;; + mipsisa64r6*-*-linux*) + default_mips_abi=n32 + default_mips_arch=mips64r6 + enable_mips_multilibs="yes" + ;; mipsisa64r2*-*-linux*) default_mips_abi=n32 default_mips_arch=mips64r2 @@ -2033,12 +2041,18 @@ mips*-sde-elf*) ;; esac case ${target} in + mipsisa32r6*) + tm_defines="MIPS_ISA_DEFAULT=37 MIPS_ABI_DEFAULT=ABI_32" + ;; mipsisa32r2*) tm_defines="MIPS_ISA_DEFAULT=33 MIPS_ABI_DEFAULT=ABI_32" ;; mipsisa32*) tm_defines="MIPS_ISA_DEFAULT=32 MIPS_ABI_DEFAULT=ABI_32" ;; + mipsisa64r6*) + tm_defines="MIPS_ISA_DEFAULT=69 MIPS_ABI_DEFAULT=ABI_N32" + ;; mipsisa64r2*) tm_defines="MIPS_ISA_DEFAULT=65 MIPS_ABI_DEFAULT=ABI_N32" ;; @@ -2049,17 +2063,25 @@ mips*-sde-elf*) ;; mipsisa32-*-elf* | mipsisa32el-*-elf* | \ mipsisa32r2-*-elf* | mipsisa32r2el-*-elf* | \ +mipsisa32r6-*-elf* | mipsisa32r6el-*-elf* | \ mipsisa64-*-elf* | mipsisa64el-*-elf* | \ -mipsisa64r2-*-elf* | mipsisa64r2el-*-elf*) +mipsisa64r2-*-elf* | mipsisa64r2el-*-elf* | \ +mipsisa64r6-*-elf* | mipsisa64r6el-*-elf*) tm_file="elfos.h newlib-stdint.h ${tm_file} mips/elf.h" tmake_file="mips/t-isa3264" case ${target} in + mipsisa32r6*) + tm_defines="${tm_defines} MIPS_ISA_DEFAULT=37" + ;; mipsisa32r2*) tm_defines="${tm_defines} MIPS_ISA_DEFAULT=33" ;; mipsisa32*) tm_defines="${tm_defines} MIPS_ISA_DEFAULT=32" ;; + mipsisa64r6*) + tm_defines="${tm_defines} MIPS_ISA_DEFAULT=69" + ;; mipsisa64r2*) tm_defines="${tm_defines} MIPS_ISA_DEFAULT=65" ;; @@ -4192,8 +4214,10 @@ case ${target} in mips4) tm_defines="$tm_defines MIPS_ISA_DEFAULT=4" ;; mips32) tm_defines="$tm_defines MIPS_ISA_DEFAULT=32" ;; mips32r2) tm_defines="$tm_defines MIPS_ISA_DEFAULT=33" ;; + mips32r6) tm_defines="$tm_defines MIPS_ISA_DEFAULT=37" ;; mips64) tm_defines="$tm_defines MIPS_ISA_DEFAULT=64" ;; mips64r2) tm_defines="$tm_defines MIPS_ISA_DEFAULT=65" ;; + mips64r6) tm_defines="$tm_defines MIPS_ISA_DEFAULT=69" ;; esac case ${default_mips_abi} in 32) tm_defines="$tm_defines MIPS_ABI_DEFAULT=ABI_32" ;; diff --git a/gcc/config/mips/constraints.md b/gcc/config/mips/constraints.md index fa33c305f8a..816880c1157 100644 --- a/gcc/config/mips/constraints.md +++ b/gcc/config/mips/constraints.md @@ -321,13 +321,13 @@ (match_test "mips_address_insns (XEXP (op, 0), mode, false)")))) (define_address_constraint "ZD" - "When compiling microMIPS code, this constraint matches an address operand - that is formed from a base register and a 12-bit offset. These operands - can be used for microMIPS instructions such as @code{prefetch}. When - not compiling for microMIPS code, @code{ZD} is equivalent to @code{p}." + "An address suitable for a @code{prefetch} instruction, or for any other + instruction with the same addressing mode as @code{prefetch}." (if_then_else (match_test "TARGET_MICROMIPS") (match_test "umips_12bit_offset_address_p (op, mode)") - (match_test "mips_address_insns (op, mode, false)"))) + (if_then_else (match_test "ISA_HAS_PREFETCH_9BIT") + (match_test "mips_9bit_offset_address_p (op, mode)") + (match_test "mips_address_insns (op, mode, false)")))) (define_memory_constraint "ZR" "@internal diff --git a/gcc/config/mips/gnu-user.h b/gcc/config/mips/gnu-user.h index 6c02054bf2e..6501a27bd47 100644 --- a/gcc/config/mips/gnu-user.h +++ b/gcc/config/mips/gnu-user.h @@ -132,6 +132,7 @@ extern const char *host_detect_local_cpu (int argc, const char **argv); #undef DRIVER_SELF_SPECS #define DRIVER_SELF_SPECS \ + MIPS_ISA_LEVEL_SPEC, \ BASE_DRIVER_SELF_SPECS, \ LINUX_DRIVER_SELF_SPECS diff --git a/gcc/config/mips/loongson.md b/gcc/config/mips/loongson.md index 474033d1e2c..08691313c69 100644 --- a/gcc/config/mips/loongson.md +++ b/gcc/config/mips/loongson.md @@ -907,33 +907,3 @@ mips_expand_vec_reduc (operands[0], operands[1], gen_umin3); DONE; }) - -;; Integer division and modulus. For integer multiplication, see mips.md. - -(define_insn "div3" - [(set (match_operand:GPR 0 "register_operand" "=&d") - (any_div:GPR (match_operand:GPR 1 "register_operand" "d") - (match_operand:GPR 2 "register_operand" "d")))] - "TARGET_LOONGSON_2EF || TARGET_LOONGSON_3A" - { - if (TARGET_LOONGSON_2EF) - return mips_output_division ("div.g\t%0,%1,%2", operands); - else - return mips_output_division ("gsdiv\t%0,%1,%2", operands); - } - [(set_attr "type" "idiv3") - (set_attr "mode" "")]) - -(define_insn "mod3" - [(set (match_operand:GPR 0 "register_operand" "=&d") - (any_mod:GPR (match_operand:GPR 1 "register_operand" "d") - (match_operand:GPR 2 "register_operand" "d")))] - "TARGET_LOONGSON_2EF || TARGET_LOONGSON_3A" - { - if (TARGET_LOONGSON_2EF) - return mips_output_division ("mod.g\t%0,%1,%2", operands); - else - return mips_output_division ("gsmod\t%0,%1,%2", operands); - } - [(set_attr "type" "idiv3") - (set_attr "mode" "")]) diff --git a/gcc/config/mips/mips-cpus.def b/gcc/config/mips/mips-cpus.def index e2985b8b6fd..0d21783b3f7 100644 --- a/gcc/config/mips/mips-cpus.def +++ b/gcc/config/mips/mips-cpus.def @@ -50,11 +50,13 @@ MIPS_CPU ("mips32r2", PROCESSOR_74KF2_1, 33, PTF_AVOID_BRANCHLIKELY) as mips32r2. */ MIPS_CPU ("mips32r3", PROCESSOR_M4K, 34, PTF_AVOID_BRANCHLIKELY) MIPS_CPU ("mips32r5", PROCESSOR_P5600, 36, PTF_AVOID_BRANCHLIKELY) +MIPS_CPU ("mips32r6", PROCESSOR_W32, 37, PTF_AVOID_BRANCHLIKELY) MIPS_CPU ("mips64", PROCESSOR_5KC, 64, PTF_AVOID_BRANCHLIKELY) /* ??? For now just tune the generic MIPS64r2 and above for 5KC as well. */ MIPS_CPU ("mips64r2", PROCESSOR_5KC, 65, PTF_AVOID_BRANCHLIKELY) MIPS_CPU ("mips64r3", PROCESSOR_5KC, 66, PTF_AVOID_BRANCHLIKELY) MIPS_CPU ("mips64r5", PROCESSOR_5KC, 68, PTF_AVOID_BRANCHLIKELY) +MIPS_CPU ("mips64r6", PROCESSOR_W64, 69, PTF_AVOID_BRANCHLIKELY) /* MIPS I processors. */ MIPS_CPU ("r3000", PROCESSOR_R3000, 1, 0) diff --git a/gcc/config/mips/mips-modes.def b/gcc/config/mips/mips-modes.def index fa1d1e7d682..96d72c16ad4 100644 --- a/gcc/config/mips/mips-modes.def +++ b/gcc/config/mips/mips-modes.def @@ -46,3 +46,6 @@ ADJUST_ALIGNMENT (CCV4, 16); /* For MIPS DSP control registers. */ CC_MODE (CCDSP); + +/* For floating point conditions in FP registers. */ +CC_MODE (CCF); diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h index adeda598a9d..087403e57f6 100644 --- a/gcc/config/mips/mips-protos.h +++ b/gcc/config/mips/mips-protos.h @@ -347,6 +347,7 @@ extern bool umips_load_store_pair_p (bool, rtx *); extern void umips_output_load_store_pair (bool, rtx *); extern bool umips_movep_target_p (rtx, rtx); extern bool umips_12bit_offset_address_p (rtx, machine_mode); +extern bool mips_9bit_offset_address_p (rtx, machine_mode); extern bool lwsp_swsp_address_p (rtx, machine_mode); extern bool m16_based_address_p (rtx, machine_mode, int (*)(rtx_def*, machine_mode)); diff --git a/gcc/config/mips/mips-tables.opt b/gcc/config/mips/mips-tables.opt index 99d2ed8d5e4..c8cdfa7a401 100644 --- a/gcc/config/mips/mips-tables.opt +++ b/gcc/config/mips/mips-tables.opt @@ -82,593 +82,605 @@ EnumValue Enum(mips_mips_opt_value) String(32r5) Value(7) EnumValue -Enum(mips_arch_opt_value) String(mips64) Value(8) Canonical +Enum(mips_arch_opt_value) String(mips32r6) Value(8) Canonical EnumValue -Enum(mips_mips_opt_value) String(64) Value(8) +Enum(mips_mips_opt_value) String(32r6) Value(8) EnumValue -Enum(mips_arch_opt_value) String(mips64r2) Value(9) Canonical +Enum(mips_arch_opt_value) String(mips64) Value(9) Canonical EnumValue -Enum(mips_mips_opt_value) String(64r2) Value(9) +Enum(mips_mips_opt_value) String(64) Value(9) EnumValue -Enum(mips_arch_opt_value) String(mips64r3) Value(10) Canonical +Enum(mips_arch_opt_value) String(mips64r2) Value(10) Canonical EnumValue -Enum(mips_mips_opt_value) String(64r3) Value(10) +Enum(mips_mips_opt_value) String(64r2) Value(10) EnumValue -Enum(mips_arch_opt_value) String(mips64r5) Value(11) Canonical +Enum(mips_arch_opt_value) String(mips64r3) Value(11) Canonical EnumValue -Enum(mips_mips_opt_value) String(64r5) Value(11) +Enum(mips_mips_opt_value) String(64r3) Value(11) EnumValue -Enum(mips_arch_opt_value) String(r3000) Value(12) Canonical +Enum(mips_arch_opt_value) String(mips64r5) Value(12) Canonical EnumValue -Enum(mips_arch_opt_value) String(r3k) Value(12) +Enum(mips_mips_opt_value) String(64r5) Value(12) EnumValue -Enum(mips_arch_opt_value) String(3000) Value(12) +Enum(mips_arch_opt_value) String(mips64r6) Value(13) Canonical EnumValue -Enum(mips_arch_opt_value) String(3k) Value(12) +Enum(mips_mips_opt_value) String(64r6) Value(13) EnumValue -Enum(mips_arch_opt_value) String(r2000) Value(13) Canonical +Enum(mips_arch_opt_value) String(r3000) Value(14) Canonical EnumValue -Enum(mips_arch_opt_value) String(r2k) Value(13) +Enum(mips_arch_opt_value) String(r3k) Value(14) EnumValue -Enum(mips_arch_opt_value) String(2000) Value(13) +Enum(mips_arch_opt_value) String(3000) Value(14) EnumValue -Enum(mips_arch_opt_value) String(2k) Value(13) +Enum(mips_arch_opt_value) String(3k) Value(14) EnumValue -Enum(mips_arch_opt_value) String(r3900) Value(14) Canonical +Enum(mips_arch_opt_value) String(r2000) Value(15) Canonical EnumValue -Enum(mips_arch_opt_value) String(3900) Value(14) +Enum(mips_arch_opt_value) String(r2k) Value(15) EnumValue -Enum(mips_arch_opt_value) String(r6000) Value(15) Canonical +Enum(mips_arch_opt_value) String(2000) Value(15) EnumValue -Enum(mips_arch_opt_value) String(r6k) Value(15) +Enum(mips_arch_opt_value) String(2k) Value(15) EnumValue -Enum(mips_arch_opt_value) String(6000) Value(15) +Enum(mips_arch_opt_value) String(r3900) Value(16) Canonical EnumValue -Enum(mips_arch_opt_value) String(6k) Value(15) +Enum(mips_arch_opt_value) String(3900) Value(16) EnumValue -Enum(mips_arch_opt_value) String(r4000) Value(16) Canonical +Enum(mips_arch_opt_value) String(r6000) Value(17) Canonical EnumValue -Enum(mips_arch_opt_value) String(r4k) Value(16) +Enum(mips_arch_opt_value) String(r6k) Value(17) EnumValue -Enum(mips_arch_opt_value) String(4000) Value(16) +Enum(mips_arch_opt_value) String(6000) Value(17) EnumValue -Enum(mips_arch_opt_value) String(4k) Value(16) +Enum(mips_arch_opt_value) String(6k) Value(17) EnumValue -Enum(mips_arch_opt_value) String(vr4100) Value(17) Canonical +Enum(mips_arch_opt_value) String(r4000) Value(18) Canonical EnumValue -Enum(mips_arch_opt_value) String(4100) Value(17) +Enum(mips_arch_opt_value) String(r4k) Value(18) EnumValue -Enum(mips_arch_opt_value) String(r4100) Value(17) +Enum(mips_arch_opt_value) String(4000) Value(18) EnumValue -Enum(mips_arch_opt_value) String(vr4111) Value(18) Canonical +Enum(mips_arch_opt_value) String(4k) Value(18) EnumValue -Enum(mips_arch_opt_value) String(4111) Value(18) +Enum(mips_arch_opt_value) String(vr4100) Value(19) Canonical EnumValue -Enum(mips_arch_opt_value) String(r4111) Value(18) +Enum(mips_arch_opt_value) String(4100) Value(19) EnumValue -Enum(mips_arch_opt_value) String(vr4120) Value(19) Canonical +Enum(mips_arch_opt_value) String(r4100) Value(19) EnumValue -Enum(mips_arch_opt_value) String(4120) Value(19) +Enum(mips_arch_opt_value) String(vr4111) Value(20) Canonical EnumValue -Enum(mips_arch_opt_value) String(r4120) Value(19) +Enum(mips_arch_opt_value) String(4111) Value(20) EnumValue -Enum(mips_arch_opt_value) String(vr4130) Value(20) Canonical +Enum(mips_arch_opt_value) String(r4111) Value(20) EnumValue -Enum(mips_arch_opt_value) String(4130) Value(20) +Enum(mips_arch_opt_value) String(vr4120) Value(21) Canonical EnumValue -Enum(mips_arch_opt_value) String(r4130) Value(20) +Enum(mips_arch_opt_value) String(4120) Value(21) EnumValue -Enum(mips_arch_opt_value) String(vr4300) Value(21) Canonical +Enum(mips_arch_opt_value) String(r4120) Value(21) EnumValue -Enum(mips_arch_opt_value) String(4300) Value(21) +Enum(mips_arch_opt_value) String(vr4130) Value(22) Canonical EnumValue -Enum(mips_arch_opt_value) String(r4300) Value(21) +Enum(mips_arch_opt_value) String(4130) Value(22) EnumValue -Enum(mips_arch_opt_value) String(r4400) Value(22) Canonical +Enum(mips_arch_opt_value) String(r4130) Value(22) EnumValue -Enum(mips_arch_opt_value) String(4400) Value(22) +Enum(mips_arch_opt_value) String(vr4300) Value(23) Canonical EnumValue -Enum(mips_arch_opt_value) String(r4600) Value(23) Canonical +Enum(mips_arch_opt_value) String(4300) Value(23) EnumValue -Enum(mips_arch_opt_value) String(4600) Value(23) +Enum(mips_arch_opt_value) String(r4300) Value(23) EnumValue -Enum(mips_arch_opt_value) String(orion) Value(24) Canonical +Enum(mips_arch_opt_value) String(r4400) Value(24) Canonical EnumValue -Enum(mips_arch_opt_value) String(r4650) Value(25) Canonical +Enum(mips_arch_opt_value) String(4400) Value(24) EnumValue -Enum(mips_arch_opt_value) String(4650) Value(25) +Enum(mips_arch_opt_value) String(r4600) Value(25) Canonical EnumValue -Enum(mips_arch_opt_value) String(r4700) Value(26) Canonical +Enum(mips_arch_opt_value) String(4600) Value(25) EnumValue -Enum(mips_arch_opt_value) String(4700) Value(26) +Enum(mips_arch_opt_value) String(orion) Value(26) Canonical EnumValue -Enum(mips_arch_opt_value) String(r5900) Value(27) Canonical +Enum(mips_arch_opt_value) String(r4650) Value(27) Canonical EnumValue -Enum(mips_arch_opt_value) String(5900) Value(27) +Enum(mips_arch_opt_value) String(4650) Value(27) EnumValue -Enum(mips_arch_opt_value) String(loongson2e) Value(28) Canonical +Enum(mips_arch_opt_value) String(r4700) Value(28) Canonical EnumValue -Enum(mips_arch_opt_value) String(loongson2f) Value(29) Canonical +Enum(mips_arch_opt_value) String(4700) Value(28) EnumValue -Enum(mips_arch_opt_value) String(r8000) Value(30) Canonical +Enum(mips_arch_opt_value) String(r5900) Value(29) Canonical EnumValue -Enum(mips_arch_opt_value) String(r8k) Value(30) +Enum(mips_arch_opt_value) String(5900) Value(29) EnumValue -Enum(mips_arch_opt_value) String(8000) Value(30) +Enum(mips_arch_opt_value) String(loongson2e) Value(30) Canonical EnumValue -Enum(mips_arch_opt_value) String(8k) Value(30) +Enum(mips_arch_opt_value) String(loongson2f) Value(31) Canonical EnumValue -Enum(mips_arch_opt_value) String(r10000) Value(31) Canonical +Enum(mips_arch_opt_value) String(r8000) Value(32) Canonical EnumValue -Enum(mips_arch_opt_value) String(r10k) Value(31) +Enum(mips_arch_opt_value) String(r8k) Value(32) EnumValue -Enum(mips_arch_opt_value) String(10000) Value(31) +Enum(mips_arch_opt_value) String(8000) Value(32) EnumValue -Enum(mips_arch_opt_value) String(10k) Value(31) +Enum(mips_arch_opt_value) String(8k) Value(32) EnumValue -Enum(mips_arch_opt_value) String(r12000) Value(32) Canonical +Enum(mips_arch_opt_value) String(r10000) Value(33) Canonical EnumValue -Enum(mips_arch_opt_value) String(r12k) Value(32) +Enum(mips_arch_opt_value) String(r10k) Value(33) EnumValue -Enum(mips_arch_opt_value) String(12000) Value(32) +Enum(mips_arch_opt_value) String(10000) Value(33) EnumValue -Enum(mips_arch_opt_value) String(12k) Value(32) +Enum(mips_arch_opt_value) String(10k) Value(33) EnumValue -Enum(mips_arch_opt_value) String(r14000) Value(33) Canonical +Enum(mips_arch_opt_value) String(r12000) Value(34) Canonical EnumValue -Enum(mips_arch_opt_value) String(r14k) Value(33) +Enum(mips_arch_opt_value) String(r12k) Value(34) EnumValue -Enum(mips_arch_opt_value) String(14000) Value(33) +Enum(mips_arch_opt_value) String(12000) Value(34) EnumValue -Enum(mips_arch_opt_value) String(14k) Value(33) +Enum(mips_arch_opt_value) String(12k) Value(34) EnumValue -Enum(mips_arch_opt_value) String(r16000) Value(34) Canonical +Enum(mips_arch_opt_value) String(r14000) Value(35) Canonical EnumValue -Enum(mips_arch_opt_value) String(r16k) Value(34) +Enum(mips_arch_opt_value) String(r14k) Value(35) EnumValue -Enum(mips_arch_opt_value) String(16000) Value(34) +Enum(mips_arch_opt_value) String(14000) Value(35) EnumValue -Enum(mips_arch_opt_value) String(16k) Value(34) +Enum(mips_arch_opt_value) String(14k) Value(35) EnumValue -Enum(mips_arch_opt_value) String(vr5000) Value(35) Canonical +Enum(mips_arch_opt_value) String(r16000) Value(36) Canonical EnumValue -Enum(mips_arch_opt_value) String(vr5k) Value(35) +Enum(mips_arch_opt_value) String(r16k) Value(36) EnumValue -Enum(mips_arch_opt_value) String(5000) Value(35) +Enum(mips_arch_opt_value) String(16000) Value(36) EnumValue -Enum(mips_arch_opt_value) String(5k) Value(35) +Enum(mips_arch_opt_value) String(16k) Value(36) EnumValue -Enum(mips_arch_opt_value) String(r5000) Value(35) +Enum(mips_arch_opt_value) String(vr5000) Value(37) Canonical EnumValue -Enum(mips_arch_opt_value) String(r5k) Value(35) +Enum(mips_arch_opt_value) String(vr5k) Value(37) EnumValue -Enum(mips_arch_opt_value) String(vr5400) Value(36) Canonical +Enum(mips_arch_opt_value) String(5000) Value(37) EnumValue -Enum(mips_arch_opt_value) String(5400) Value(36) +Enum(mips_arch_opt_value) String(5k) Value(37) EnumValue -Enum(mips_arch_opt_value) String(r5400) Value(36) +Enum(mips_arch_opt_value) String(r5000) Value(37) EnumValue -Enum(mips_arch_opt_value) String(vr5500) Value(37) Canonical +Enum(mips_arch_opt_value) String(r5k) Value(37) EnumValue -Enum(mips_arch_opt_value) String(5500) Value(37) +Enum(mips_arch_opt_value) String(vr5400) Value(38) Canonical EnumValue -Enum(mips_arch_opt_value) String(r5500) Value(37) +Enum(mips_arch_opt_value) String(5400) Value(38) EnumValue -Enum(mips_arch_opt_value) String(rm7000) Value(38) Canonical +Enum(mips_arch_opt_value) String(r5400) Value(38) EnumValue -Enum(mips_arch_opt_value) String(rm7k) Value(38) +Enum(mips_arch_opt_value) String(vr5500) Value(39) Canonical EnumValue -Enum(mips_arch_opt_value) String(7000) Value(38) +Enum(mips_arch_opt_value) String(5500) Value(39) EnumValue -Enum(mips_arch_opt_value) String(7k) Value(38) +Enum(mips_arch_opt_value) String(r5500) Value(39) EnumValue -Enum(mips_arch_opt_value) String(r7000) Value(38) +Enum(mips_arch_opt_value) String(rm7000) Value(40) Canonical EnumValue -Enum(mips_arch_opt_value) String(r7k) Value(38) +Enum(mips_arch_opt_value) String(rm7k) Value(40) EnumValue -Enum(mips_arch_opt_value) String(rm9000) Value(39) Canonical +Enum(mips_arch_opt_value) String(7000) Value(40) EnumValue -Enum(mips_arch_opt_value) String(rm9k) Value(39) +Enum(mips_arch_opt_value) String(7k) Value(40) EnumValue -Enum(mips_arch_opt_value) String(9000) Value(39) +Enum(mips_arch_opt_value) String(r7000) Value(40) EnumValue -Enum(mips_arch_opt_value) String(9k) Value(39) +Enum(mips_arch_opt_value) String(r7k) Value(40) EnumValue -Enum(mips_arch_opt_value) String(r9000) Value(39) +Enum(mips_arch_opt_value) String(rm9000) Value(41) Canonical EnumValue -Enum(mips_arch_opt_value) String(r9k) Value(39) +Enum(mips_arch_opt_value) String(rm9k) Value(41) EnumValue -Enum(mips_arch_opt_value) String(4kc) Value(40) Canonical +Enum(mips_arch_opt_value) String(9000) Value(41) EnumValue -Enum(mips_arch_opt_value) String(r4kc) Value(40) +Enum(mips_arch_opt_value) String(9k) Value(41) EnumValue -Enum(mips_arch_opt_value) String(4km) Value(41) Canonical +Enum(mips_arch_opt_value) String(r9000) Value(41) EnumValue -Enum(mips_arch_opt_value) String(r4km) Value(41) +Enum(mips_arch_opt_value) String(r9k) Value(41) EnumValue -Enum(mips_arch_opt_value) String(4kp) Value(42) Canonical +Enum(mips_arch_opt_value) String(4kc) Value(42) Canonical EnumValue -Enum(mips_arch_opt_value) String(r4kp) Value(42) +Enum(mips_arch_opt_value) String(r4kc) Value(42) EnumValue -Enum(mips_arch_opt_value) String(4ksc) Value(43) Canonical +Enum(mips_arch_opt_value) String(4km) Value(43) Canonical EnumValue -Enum(mips_arch_opt_value) String(r4ksc) Value(43) +Enum(mips_arch_opt_value) String(r4km) Value(43) EnumValue -Enum(mips_arch_opt_value) String(m4k) Value(44) Canonical +Enum(mips_arch_opt_value) String(4kp) Value(44) Canonical EnumValue -Enum(mips_arch_opt_value) String(m14kc) Value(45) Canonical +Enum(mips_arch_opt_value) String(r4kp) Value(44) EnumValue -Enum(mips_arch_opt_value) String(m14k) Value(46) Canonical +Enum(mips_arch_opt_value) String(4ksc) Value(45) Canonical EnumValue -Enum(mips_arch_opt_value) String(m14ke) Value(47) Canonical +Enum(mips_arch_opt_value) String(r4ksc) Value(45) EnumValue -Enum(mips_arch_opt_value) String(m14kec) Value(48) Canonical +Enum(mips_arch_opt_value) String(m4k) Value(46) Canonical EnumValue -Enum(mips_arch_opt_value) String(4kec) Value(49) Canonical +Enum(mips_arch_opt_value) String(m14kc) Value(47) Canonical EnumValue -Enum(mips_arch_opt_value) String(r4kec) Value(49) +Enum(mips_arch_opt_value) String(m14k) Value(48) Canonical EnumValue -Enum(mips_arch_opt_value) String(4kem) Value(50) Canonical +Enum(mips_arch_opt_value) String(m14ke) Value(49) Canonical EnumValue -Enum(mips_arch_opt_value) String(r4kem) Value(50) +Enum(mips_arch_opt_value) String(m14kec) Value(50) Canonical EnumValue -Enum(mips_arch_opt_value) String(4kep) Value(51) Canonical +Enum(mips_arch_opt_value) String(4kec) Value(51) Canonical EnumValue -Enum(mips_arch_opt_value) String(r4kep) Value(51) +Enum(mips_arch_opt_value) String(r4kec) Value(51) EnumValue -Enum(mips_arch_opt_value) String(4ksd) Value(52) Canonical +Enum(mips_arch_opt_value) String(4kem) Value(52) Canonical EnumValue -Enum(mips_arch_opt_value) String(r4ksd) Value(52) +Enum(mips_arch_opt_value) String(r4kem) Value(52) EnumValue -Enum(mips_arch_opt_value) String(24kc) Value(53) Canonical +Enum(mips_arch_opt_value) String(4kep) Value(53) Canonical EnumValue -Enum(mips_arch_opt_value) String(r24kc) Value(53) +Enum(mips_arch_opt_value) String(r4kep) Value(53) EnumValue -Enum(mips_arch_opt_value) String(24kf2_1) Value(54) Canonical +Enum(mips_arch_opt_value) String(4ksd) Value(54) Canonical EnumValue -Enum(mips_arch_opt_value) String(r24kf2_1) Value(54) +Enum(mips_arch_opt_value) String(r4ksd) Value(54) EnumValue -Enum(mips_arch_opt_value) String(24kf) Value(55) Canonical +Enum(mips_arch_opt_value) String(24kc) Value(55) Canonical EnumValue -Enum(mips_arch_opt_value) String(r24kf) Value(55) +Enum(mips_arch_opt_value) String(r24kc) Value(55) EnumValue -Enum(mips_arch_opt_value) String(24kf1_1) Value(56) Canonical +Enum(mips_arch_opt_value) String(24kf2_1) Value(56) Canonical EnumValue -Enum(mips_arch_opt_value) String(r24kf1_1) Value(56) +Enum(mips_arch_opt_value) String(r24kf2_1) Value(56) EnumValue -Enum(mips_arch_opt_value) String(24kfx) Value(57) Canonical +Enum(mips_arch_opt_value) String(24kf) Value(57) Canonical EnumValue -Enum(mips_arch_opt_value) String(r24kfx) Value(57) +Enum(mips_arch_opt_value) String(r24kf) Value(57) EnumValue -Enum(mips_arch_opt_value) String(24kx) Value(58) Canonical +Enum(mips_arch_opt_value) String(24kf1_1) Value(58) Canonical EnumValue -Enum(mips_arch_opt_value) String(r24kx) Value(58) +Enum(mips_arch_opt_value) String(r24kf1_1) Value(58) EnumValue -Enum(mips_arch_opt_value) String(24kec) Value(59) Canonical +Enum(mips_arch_opt_value) String(24kfx) Value(59) Canonical EnumValue -Enum(mips_arch_opt_value) String(r24kec) Value(59) +Enum(mips_arch_opt_value) String(r24kfx) Value(59) EnumValue -Enum(mips_arch_opt_value) String(24kef2_1) Value(60) Canonical +Enum(mips_arch_opt_value) String(24kx) Value(60) Canonical EnumValue -Enum(mips_arch_opt_value) String(r24kef2_1) Value(60) +Enum(mips_arch_opt_value) String(r24kx) Value(60) EnumValue -Enum(mips_arch_opt_value) String(24kef) Value(61) Canonical +Enum(mips_arch_opt_value) String(24kec) Value(61) Canonical EnumValue -Enum(mips_arch_opt_value) String(r24kef) Value(61) +Enum(mips_arch_opt_value) String(r24kec) Value(61) EnumValue -Enum(mips_arch_opt_value) String(24kef1_1) Value(62) Canonical +Enum(mips_arch_opt_value) String(24kef2_1) Value(62) Canonical EnumValue -Enum(mips_arch_opt_value) String(r24kef1_1) Value(62) +Enum(mips_arch_opt_value) String(r24kef2_1) Value(62) EnumValue -Enum(mips_arch_opt_value) String(24kefx) Value(63) Canonical +Enum(mips_arch_opt_value) String(24kef) Value(63) Canonical EnumValue -Enum(mips_arch_opt_value) String(r24kefx) Value(63) +Enum(mips_arch_opt_value) String(r24kef) Value(63) EnumValue -Enum(mips_arch_opt_value) String(24kex) Value(64) Canonical +Enum(mips_arch_opt_value) String(24kef1_1) Value(64) Canonical EnumValue -Enum(mips_arch_opt_value) String(r24kex) Value(64) +Enum(mips_arch_opt_value) String(r24kef1_1) Value(64) EnumValue -Enum(mips_arch_opt_value) String(34kc) Value(65) Canonical +Enum(mips_arch_opt_value) String(24kefx) Value(65) Canonical EnumValue -Enum(mips_arch_opt_value) String(r34kc) Value(65) +Enum(mips_arch_opt_value) String(r24kefx) Value(65) EnumValue -Enum(mips_arch_opt_value) String(34kf2_1) Value(66) Canonical +Enum(mips_arch_opt_value) String(24kex) Value(66) Canonical EnumValue -Enum(mips_arch_opt_value) String(r34kf2_1) Value(66) +Enum(mips_arch_opt_value) String(r24kex) Value(66) EnumValue -Enum(mips_arch_opt_value) String(34kf) Value(67) Canonical +Enum(mips_arch_opt_value) String(34kc) Value(67) Canonical EnumValue -Enum(mips_arch_opt_value) String(r34kf) Value(67) +Enum(mips_arch_opt_value) String(r34kc) Value(67) EnumValue -Enum(mips_arch_opt_value) String(34kf1_1) Value(68) Canonical +Enum(mips_arch_opt_value) String(34kf2_1) Value(68) Canonical EnumValue -Enum(mips_arch_opt_value) String(r34kf1_1) Value(68) +Enum(mips_arch_opt_value) String(r34kf2_1) Value(68) EnumValue -Enum(mips_arch_opt_value) String(34kfx) Value(69) Canonical +Enum(mips_arch_opt_value) String(34kf) Value(69) Canonical EnumValue -Enum(mips_arch_opt_value) String(r34kfx) Value(69) +Enum(mips_arch_opt_value) String(r34kf) Value(69) EnumValue -Enum(mips_arch_opt_value) String(34kx) Value(70) Canonical +Enum(mips_arch_opt_value) String(34kf1_1) Value(70) Canonical EnumValue -Enum(mips_arch_opt_value) String(r34kx) Value(70) +Enum(mips_arch_opt_value) String(r34kf1_1) Value(70) EnumValue -Enum(mips_arch_opt_value) String(34kn) Value(71) Canonical +Enum(mips_arch_opt_value) String(34kfx) Value(71) Canonical EnumValue -Enum(mips_arch_opt_value) String(r34kn) Value(71) +Enum(mips_arch_opt_value) String(r34kfx) Value(71) EnumValue -Enum(mips_arch_opt_value) String(74kc) Value(72) Canonical +Enum(mips_arch_opt_value) String(34kx) Value(72) Canonical EnumValue -Enum(mips_arch_opt_value) String(r74kc) Value(72) +Enum(mips_arch_opt_value) String(r34kx) Value(72) EnumValue -Enum(mips_arch_opt_value) String(74kf2_1) Value(73) Canonical +Enum(mips_arch_opt_value) String(34kn) Value(73) Canonical EnumValue -Enum(mips_arch_opt_value) String(r74kf2_1) Value(73) +Enum(mips_arch_opt_value) String(r34kn) Value(73) EnumValue -Enum(mips_arch_opt_value) String(74kf) Value(74) Canonical +Enum(mips_arch_opt_value) String(74kc) Value(74) Canonical EnumValue -Enum(mips_arch_opt_value) String(r74kf) Value(74) +Enum(mips_arch_opt_value) String(r74kc) Value(74) EnumValue -Enum(mips_arch_opt_value) String(74kf1_1) Value(75) Canonical +Enum(mips_arch_opt_value) String(74kf2_1) Value(75) Canonical EnumValue -Enum(mips_arch_opt_value) String(r74kf1_1) Value(75) +Enum(mips_arch_opt_value) String(r74kf2_1) Value(75) EnumValue -Enum(mips_arch_opt_value) String(74kfx) Value(76) Canonical +Enum(mips_arch_opt_value) String(74kf) Value(76) Canonical EnumValue -Enum(mips_arch_opt_value) String(r74kfx) Value(76) +Enum(mips_arch_opt_value) String(r74kf) Value(76) EnumValue -Enum(mips_arch_opt_value) String(74kx) Value(77) Canonical +Enum(mips_arch_opt_value) String(74kf1_1) Value(77) Canonical EnumValue -Enum(mips_arch_opt_value) String(r74kx) Value(77) +Enum(mips_arch_opt_value) String(r74kf1_1) Value(77) EnumValue -Enum(mips_arch_opt_value) String(74kf3_2) Value(78) Canonical +Enum(mips_arch_opt_value) String(74kfx) Value(78) Canonical EnumValue -Enum(mips_arch_opt_value) String(r74kf3_2) Value(78) +Enum(mips_arch_opt_value) String(r74kfx) Value(78) EnumValue -Enum(mips_arch_opt_value) String(1004kc) Value(79) Canonical +Enum(mips_arch_opt_value) String(74kx) Value(79) Canonical EnumValue -Enum(mips_arch_opt_value) String(r1004kc) Value(79) +Enum(mips_arch_opt_value) String(r74kx) Value(79) EnumValue -Enum(mips_arch_opt_value) String(1004kf2_1) Value(80) Canonical +Enum(mips_arch_opt_value) String(74kf3_2) Value(80) Canonical EnumValue -Enum(mips_arch_opt_value) String(r1004kf2_1) Value(80) +Enum(mips_arch_opt_value) String(r74kf3_2) Value(80) EnumValue -Enum(mips_arch_opt_value) String(1004kf) Value(81) Canonical +Enum(mips_arch_opt_value) String(1004kc) Value(81) Canonical EnumValue -Enum(mips_arch_opt_value) String(r1004kf) Value(81) +Enum(mips_arch_opt_value) String(r1004kc) Value(81) EnumValue -Enum(mips_arch_opt_value) String(1004kf1_1) Value(82) Canonical +Enum(mips_arch_opt_value) String(1004kf2_1) Value(82) Canonical EnumValue -Enum(mips_arch_opt_value) String(r1004kf1_1) Value(82) +Enum(mips_arch_opt_value) String(r1004kf2_1) Value(82) EnumValue -Enum(mips_arch_opt_value) String(p5600) Value(83) Canonical +Enum(mips_arch_opt_value) String(1004kf) Value(83) Canonical EnumValue -Enum(mips_arch_opt_value) String(5kc) Value(84) Canonical +Enum(mips_arch_opt_value) String(r1004kf) Value(83) EnumValue -Enum(mips_arch_opt_value) String(r5kc) Value(84) +Enum(mips_arch_opt_value) String(1004kf1_1) Value(84) Canonical EnumValue -Enum(mips_arch_opt_value) String(5kf) Value(85) Canonical +Enum(mips_arch_opt_value) String(r1004kf1_1) Value(84) EnumValue -Enum(mips_arch_opt_value) String(r5kf) Value(85) +Enum(mips_arch_opt_value) String(p5600) Value(85) Canonical EnumValue -Enum(mips_arch_opt_value) String(20kc) Value(86) Canonical +Enum(mips_arch_opt_value) String(5kc) Value(86) Canonical EnumValue -Enum(mips_arch_opt_value) String(r20kc) Value(86) +Enum(mips_arch_opt_value) String(r5kc) Value(86) EnumValue -Enum(mips_arch_opt_value) String(sb1) Value(87) Canonical +Enum(mips_arch_opt_value) String(5kf) Value(87) Canonical EnumValue -Enum(mips_arch_opt_value) String(sb1a) Value(88) Canonical +Enum(mips_arch_opt_value) String(r5kf) Value(87) EnumValue -Enum(mips_arch_opt_value) String(sr71000) Value(89) Canonical +Enum(mips_arch_opt_value) String(20kc) Value(88) Canonical EnumValue -Enum(mips_arch_opt_value) String(sr71k) Value(89) +Enum(mips_arch_opt_value) String(r20kc) Value(88) EnumValue -Enum(mips_arch_opt_value) String(xlr) Value(90) Canonical +Enum(mips_arch_opt_value) String(sb1) Value(89) Canonical EnumValue -Enum(mips_arch_opt_value) String(loongson3a) Value(91) Canonical +Enum(mips_arch_opt_value) String(sb1a) Value(90) Canonical EnumValue -Enum(mips_arch_opt_value) String(octeon) Value(92) Canonical +Enum(mips_arch_opt_value) String(sr71000) Value(91) Canonical EnumValue -Enum(mips_arch_opt_value) String(octeon+) Value(93) Canonical +Enum(mips_arch_opt_value) String(sr71k) Value(91) EnumValue -Enum(mips_arch_opt_value) String(octeon2) Value(94) Canonical +Enum(mips_arch_opt_value) String(xlr) Value(92) Canonical EnumValue -Enum(mips_arch_opt_value) String(octeon3) Value(95) Canonical +Enum(mips_arch_opt_value) String(loongson3a) Value(93) Canonical EnumValue -Enum(mips_arch_opt_value) String(xlp) Value(96) Canonical +Enum(mips_arch_opt_value) String(octeon) Value(94) Canonical + +EnumValue +Enum(mips_arch_opt_value) String(octeon+) Value(95) Canonical + +EnumValue +Enum(mips_arch_opt_value) String(octeon2) Value(96) Canonical + +EnumValue +Enum(mips_arch_opt_value) String(octeon3) Value(97) Canonical + +EnumValue +Enum(mips_arch_opt_value) String(xlp) Value(98) Canonical diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 1aea23e66e5..3b8daca0121 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -182,9 +182,10 @@ along with GCC; see the file COPYING3. If not see #define MIPS_LUI(DEST, VALUE) \ ((0xf << 26) | ((DEST) << 16) | (VALUE)) -/* Return the opcode to jump to register DEST. */ +/* Return the opcode to jump to register DEST. When the JR opcode is not + available use JALR $0, DEST. */ #define MIPS_JR(DEST) \ - (((DEST) << 21) | 0x8) + (((DEST) << 21) | (ISA_HAS_JR ? 0x8 : 0x9)) /* Return the opcode for: @@ -1225,6 +1226,32 @@ static const struct mips_rtx_cost_data COSTS_N_INSNS (8), /* int_div_di */ 2, /* branch_cost */ 4 /* memory_latency */ + }, + { /* W32 */ + COSTS_N_INSNS (4), /* fp_add */ + COSTS_N_INSNS (4), /* fp_mult_sf */ + COSTS_N_INSNS (5), /* fp_mult_df */ + COSTS_N_INSNS (17), /* fp_div_sf */ + COSTS_N_INSNS (32), /* fp_div_df */ + COSTS_N_INSNS (5), /* int_mult_si */ + COSTS_N_INSNS (5), /* int_mult_di */ + COSTS_N_INSNS (41), /* int_div_si */ + COSTS_N_INSNS (41), /* int_div_di */ + 1, /* branch_cost */ + 4 /* memory_latency */ + }, + { /* W64 */ + COSTS_N_INSNS (4), /* fp_add */ + COSTS_N_INSNS (4), /* fp_mult_sf */ + COSTS_N_INSNS (5), /* fp_mult_df */ + COSTS_N_INSNS (17), /* fp_div_sf */ + COSTS_N_INSNS (32), /* fp_div_df */ + COSTS_N_INSNS (5), /* int_mult_si */ + COSTS_N_INSNS (5), /* int_mult_di */ + COSTS_N_INSNS (41), /* int_div_si */ + COSTS_N_INSNS (41), /* int_div_di */ + 1, /* branch_cost */ + 4 /* memory_latency */ } }; @@ -2593,6 +2620,20 @@ umips_12bit_offset_address_p (rtx x, machine_mode mode) && UMIPS_12BIT_OFFSET_P (INTVAL (addr.offset))); } +/* Return true if X is a legitimate address with a 9-bit offset. + MODE is the mode of the value being accessed. */ + +bool +mips_9bit_offset_address_p (rtx x, machine_mode mode) +{ + struct mips_address_info addr; + + return (mips_classify_address (&addr, x, mode, false) + && addr.type == ADDRESS_REG + && CONST_INT_P (addr.offset) + && MIPS_9BIT_OFFSET_P (INTVAL (addr.offset))); +} + /* Return the number of instructions needed to load constant X, assuming that BASE_INSN_LENGTH is the length of one instruction. Return 0 if X isn't a valid constant. */ @@ -4102,6 +4143,11 @@ mips_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED, *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) > UNITS_PER_WORD ? 4 : 1); return false; + case FMA: + if (ISA_HAS_FP_MADDF_MSUBF) + *total = mips_fp_mult_cost (mode); + return false; + case MULT: if (float_mode_p) *total = mips_fp_mult_cost (mode); @@ -4112,7 +4158,7 @@ mips_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED, ? mips_cost->int_mult_si * 3 + 6 : COSTS_N_INSNS (ISA_HAS_MUL3 ? 7 : 9)); else if (!speed) - *total = COSTS_N_INSNS (ISA_HAS_MUL3 ? 1 : 2) + 1; + *total = COSTS_N_INSNS ((ISA_HAS_MUL3 || ISA_HAS_R6MUL) ? 1 : 2) + 1; else if (mode == DImode) *total = mips_cost->int_mult_di; else @@ -4188,6 +4234,52 @@ mips_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED, } *total = mips_zero_extend_cost (mode, XEXP (x, 0)); return false; + case TRUNCATE: + /* Costings for highpart multiplies. Matching patterns of the form: + + (lshiftrt:DI (mult:DI (sign_extend:DI (...) + (sign_extend:DI (...)) + (const_int 32) + */ + if (ISA_HAS_R6MUL + && (GET_CODE (XEXP (x, 0)) == ASHIFTRT + || GET_CODE (XEXP (x, 0)) == LSHIFTRT) + && CONST_INT_P (XEXP (XEXP (x, 0), 1)) + && ((INTVAL (XEXP (XEXP (x, 0), 1)) == 32 + && GET_MODE (XEXP (x, 0)) == DImode) + || (ISA_HAS_R6DMUL + && INTVAL (XEXP (XEXP (x, 0), 1)) == 64 + && GET_MODE (XEXP (x, 0)) == TImode)) + && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT + && ((GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == SIGN_EXTEND + && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == SIGN_EXTEND) + || (GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == ZERO_EXTEND + && (GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) + == ZERO_EXTEND)))) + { + if (!speed) + *total = COSTS_N_INSNS (1) + 1; + else if (mode == DImode) + *total = mips_cost->int_mult_di; + else + *total = mips_cost->int_mult_si; + + /* Sign extension is free, zero extension costs for DImode when + on a 64bit core / when DMUL is present. */ + for (int i = 0; i < 2; ++i) + { + rtx op = XEXP (XEXP (XEXP (x, 0), 0), i); + if (ISA_HAS_R6DMUL + && GET_CODE (op) == ZERO_EXTEND + && GET_MODE (op) == DImode) + *total += rtx_cost (op, MULT, i, speed); + else + *total += rtx_cost (XEXP (op, 0), GET_CODE (op), 0, speed); + } + + return true; + } + return false; case FLOAT: case UNSIGNED_FLOAT: @@ -4971,17 +5063,32 @@ mips_emit_compare (enum rtx_code *code, rtx *op0, rtx *op1, bool need_eq_ne_p) { enum rtx_code cmp_code; - /* Floating-point tests use a separate C.cond.fmt comparison to - set a condition code register. The branch or conditional move - will then compare that register against zero. + /* Floating-point tests use a separate C.cond.fmt or CMP.cond.fmt + comparison to set a register. The branch or conditional move will + then compare that register against zero. Set CMP_CODE to the code of the comparison instruction and *CODE to the code that the branch or move should use. */ cmp_code = *code; - *code = mips_reversed_fp_cond (&cmp_code) ? EQ : NE; - *op0 = (ISA_HAS_8CC - ? mips_allocate_fcc (CCmode) - : gen_rtx_REG (CCmode, FPSW_REGNUM)); + if (ISA_HAS_CCF) + { + /* All FP conditions can be implemented directly with CMP.cond.fmt + or by reversing the operands. */ + *code = NE; + *op0 = gen_reg_rtx (CCFmode); + } + else + { + /* Three FP conditions cannot be implemented by reversing the + operands for C.cond.fmt, instead a reversed condition code is + required and a test for false. */ + *code = mips_reversed_fp_cond (&cmp_code) ? EQ : NE; + if (ISA_HAS_8CC) + *op0 = mips_allocate_fcc (CCmode); + else + *op0 = gen_rtx_REG (CCmode, FPSW_REGNUM); + } + *op1 = const0_rtx; mips_emit_binary (cmp_code, *op0, cmp_op0, cmp_op1); } @@ -5071,9 +5178,45 @@ mips_expand_conditional_move (rtx *operands) mips_emit_compare (&code, &op0, &op1, true); cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1); - emit_insn (gen_rtx_SET (VOIDmode, operands[0], - gen_rtx_IF_THEN_ELSE (GET_MODE (operands[0]), cond, - operands[2], operands[3]))); + + /* There is no direct support for general conditional GP move involving + two registers using SEL. */ + if (ISA_HAS_SEL + && INTEGRAL_MODE_P (GET_MODE (operands[2])) + && register_operand (operands[2], VOIDmode) + && register_operand (operands[3], VOIDmode)) + { + machine_mode mode = GET_MODE (operands[0]); + rtx temp = gen_reg_rtx (mode); + rtx temp2 = gen_reg_rtx (mode); + + emit_insn (gen_rtx_SET (VOIDmode, temp, + gen_rtx_IF_THEN_ELSE (mode, cond, + operands[2], const0_rtx))); + + /* Flip the test for the second operand. */ + cond = gen_rtx_fmt_ee ((code == EQ) ? NE : EQ, GET_MODE (op0), op0, op1); + + emit_insn (gen_rtx_SET (VOIDmode, temp2, + gen_rtx_IF_THEN_ELSE (mode, cond, + operands[3], const0_rtx))); + + /* Merge the two results, at least one is guaranteed to be zero. */ + emit_insn (gen_rtx_SET (VOIDmode, operands[0], + gen_rtx_IOR (mode, temp, temp2))); + } + else + { + if (FLOAT_MODE_P (GET_MODE (operands[2])) && !ISA_HAS_SEL) + { + operands[2] = force_reg (GET_MODE (operands[0]), operands[2]); + operands[3] = force_reg (GET_MODE (operands[0]), operands[3]); + } + + emit_insn (gen_rtx_SET (VOIDmode, operands[0], + gen_rtx_IF_THEN_ELSE (GET_MODE (operands[0]), cond, + operands[2], operands[3]))); + } } /* Perform the comparison in COMPARISON, then trap if the condition holds. */ @@ -5107,7 +5250,9 @@ mips_expand_conditional_trap (rtx comparison) mode = GET_MODE (XEXP (comparison, 0)); op0 = force_reg (mode, op0); - if (!arith_operand (op1, mode)) + if (!(ISA_HAS_COND_TRAPI + ? arith_operand (op1, mode) + : reg_or_0_operand (op1, mode))) op1 = force_reg (mode, op1); emit_insn (gen_rtx_TRAP_IF (VOIDmode, @@ -7469,6 +7614,10 @@ mips_block_move_loop (rtx dest, rtx src, HOST_WIDE_INT length, bool mips_expand_block_move (rtx dest, rtx src, rtx length) { + /* Disable entirely for R6 initially. */ + if (!ISA_HAS_LWL_LWR) + return false; + if (CONST_INT_P (length)) { if (INTVAL (length) <= MIPS_MAX_MOVE_BYTES_STRAIGHT) @@ -8231,11 +8380,17 @@ mips_print_float_branch_condition (FILE *file, enum rtx_code code, int letter) switch (code) { case EQ: - fputs ("c1f", file); + if (ISA_HAS_CCF) + fputs ("c1eqz", file); + else + fputs ("c1f", file); break; case NE: - fputs ("c1t", file); + if (ISA_HAS_CCF) + fputs ("c1nez", file); + else + fputs ("c1t", file); break; default: @@ -8365,7 +8520,7 @@ mips_print_operand (FILE *file, rtx op, int letter) break; case 'Z': - if (ISA_HAS_8CC) + if (ISA_HAS_8CC || ISA_HAS_CCF) { mips_print_operand (file, op, 0); fputc (',', file); @@ -9917,7 +10072,8 @@ mips_must_initialize_gp_p (void) static bool mips_interrupt_extra_call_saved_reg_p (unsigned int regno) { - if (MD_REG_P (regno)) + if ((ISA_HAS_HILO || TARGET_DSP) + && MD_REG_P (regno)) return true; if (TARGET_DSP && DSP_ACC_REG_P (regno)) @@ -11891,7 +12047,7 @@ mips_hard_regno_mode_ok_p (unsigned int regno, machine_mode mode) size = GET_MODE_SIZE (mode); mclass = GET_MODE_CLASS (mode); - if (GP_REG_P (regno)) + if (GP_REG_P (regno) && mode != CCFmode) return ((regno - GP_REG_FIRST) & 1) == 0 || size <= UNITS_PER_WORD; if (FP_REG_P (regno) @@ -11903,6 +12059,13 @@ mips_hard_regno_mode_ok_p (unsigned int regno, machine_mode mode) if (TARGET_O32_FP64A_ABI && size <= 4 && (regno & 1) != 0) return false; + /* The FPXX ABI requires double-precision values to be placed in + even-numbered registers. Disallow odd-numbered registers with + CCFmode because CCFmode double-precision compares will write a + 64-bit value to a register. */ + if (mode == CCFmode) + return !(TARGET_FLOATXX && (regno & 1) != 0); + /* Allow 64-bit vector modes for Loongson-2E/2F. */ if (TARGET_LOONGSON_VECTORS && (mode == V2SImode @@ -12062,6 +12225,7 @@ mips_mode_ok_for_mov_fmt_p (machine_mode mode) { switch (mode) { + case CCFmode: case SFmode: return TARGET_HARD_FLOAT; @@ -15934,8 +16098,10 @@ mips_mult_zero_zero_cost (struct mips_sim *state, bool setting) static void mips_set_fast_mult_zero_zero_p (struct mips_sim *state) { - if (TARGET_MIPS16) - /* No MTLO or MTHI available. */ + if (TARGET_MIPS16 || !ISA_HAS_HILO) + /* No MTLO or MTHI available for MIPS16. Also, when there are no HI or LO + registers then there is no reason to zero them, arbitrarily choose to + say that "MULT $0,$0" would be faster. */ mips_tuning_info.fast_mult_zero_zero_p = true; else { @@ -17179,7 +17345,10 @@ mips_option_override (void) if ((target_flags_explicit & MASK_FLOAT64) != 0) { - if (TARGET_SINGLE_FLOAT && TARGET_FLOAT64) + if (mips_isa_rev >= 6 && !TARGET_FLOAT64) + error ("the %qs architecture does not support %<-mfp32%>", + mips_arch_info->name); + else if (TARGET_SINGLE_FLOAT && TARGET_FLOAT64) error ("unsupported combination: %s", "-mfp64 -msingle-float"); else if (TARGET_64BIT && TARGET_DOUBLE_FLOAT && !TARGET_FLOAT64) error ("unsupported combination: %s", "-mgp64 -mfp32 -mdouble-float"); @@ -17195,9 +17364,13 @@ mips_option_override (void) } else { - /* -msingle-float selects 32-bit float registers. Otherwise the - float registers should be the same size as the integer ones. */ - if (TARGET_64BIT && TARGET_DOUBLE_FLOAT) + /* -msingle-float selects 32-bit float registers. On r6 and later, + -mdouble-float selects 64-bit float registers, since the old paired + register model is not supported. In other cases the float registers + should be the same size as the integer ones. */ + if (mips_isa_rev >= 6 && TARGET_DOUBLE_FLOAT && !TARGET_FLOATXX) + target_flags |= MASK_FLOAT64; + else if (TARGET_64BIT && TARGET_DOUBLE_FLOAT) target_flags |= MASK_FLOAT64; else target_flags &= ~MASK_FLOAT64; @@ -17205,6 +17378,8 @@ mips_option_override (void) if (mips_abi != ABI_32 && TARGET_FLOATXX) error ("%<-mfpxx%> can only be used with the o32 ABI"); + else if (TARGET_FLOAT64 && TARGET_FLOATXX) + error ("unsupported combination: %s", "-mfp64 -mfpxx"); else if (ISA_MIPS1 && !TARGET_FLOAT32) error ("%<-march=%s%> requires %<-mfp32%>", mips_arch_info->name); else if (TARGET_FLOATXX && !mips_lra_flag) @@ -17382,6 +17557,27 @@ mips_option_override (void) } } + /* Set NaN and ABS defaults. */ + if (mips_nan == MIPS_IEEE_754_DEFAULT && !ISA_HAS_IEEE_754_LEGACY) + mips_nan = MIPS_IEEE_754_2008; + if (mips_abs == MIPS_IEEE_754_DEFAULT && !ISA_HAS_IEEE_754_LEGACY) + mips_abs = MIPS_IEEE_754_2008; + + /* Check for IEEE 754 legacy/2008 support. */ + if ((mips_nan == MIPS_IEEE_754_LEGACY + || mips_abs == MIPS_IEEE_754_LEGACY) + && !ISA_HAS_IEEE_754_LEGACY) + warning (0, "the %qs architecture does not support %<-m%s=legacy%>", + mips_arch_info->name, + mips_nan == MIPS_IEEE_754_LEGACY ? "nan" : "abs"); + + if ((mips_nan == MIPS_IEEE_754_2008 + || mips_abs == MIPS_IEEE_754_2008) + && !ISA_HAS_IEEE_754_2008) + warning (0, "the %qs architecture does not support %<-m%s=2008%>", + mips_arch_info->name, + mips_nan == MIPS_IEEE_754_2008 ? "nan" : "abs"); + /* Pre-IEEE 754-2008 MIPS hardware has a quirky almost-IEEE format for all its floating point. */ if (mips_nan != MIPS_IEEE_754_2008) @@ -17436,6 +17632,14 @@ mips_option_override (void) if (TARGET_DSPR2) TARGET_DSP = true; + if (TARGET_DSP && mips_isa_rev >= 6) + { + error ("the %qs architecture does not support DSP instructions", + mips_arch_info->name); + TARGET_DSP = false; + TARGET_DSPR2 = false; + } + /* .eh_frame addresses should be the same width as a C pointer. Most MIPS ABIs support only one pointer size, so the assembler will usually know exactly how big an .eh_frame address is. @@ -17616,6 +17820,10 @@ mips_conditional_register_usage (void) AND_COMPL_HARD_REG_SET (accessible_reg_set, reg_class_contents[(int) DSP_ACC_REGS]); + if (!ISA_HAS_HILO) + AND_COMPL_HARD_REG_SET (accessible_reg_set, + reg_class_contents[(int) MD_REGS]); + if (!TARGET_HARD_FLOAT) { AND_COMPL_HARD_REG_SET (accessible_reg_set, @@ -17630,7 +17838,8 @@ mips_conditional_register_usage (void) RTL that refers directly to ST_REG_FIRST. */ AND_COMPL_HARD_REG_SET (accessible_reg_set, reg_class_contents[(int) ST_REGS]); - SET_HARD_REG_BIT (accessible_reg_set, FPSW_REGNUM); + if (!ISA_HAS_CCF) + SET_HARD_REG_BIT (accessible_reg_set, FPSW_REGNUM); fixed_regs[FPSW_REGNUM] = call_used_regs[FPSW_REGNUM] = 1; } if (TARGET_MIPS16) @@ -17805,6 +18014,8 @@ mips_mulsidi3_gen_fn (enum rtx_code ext_code) the extension is not needed for signed multiplication. In order to ensure that we always remove the redundant sign-extension in this case we still expand mulsidi3 for DMUL. */ + if (ISA_HAS_R6DMUL) + return signed_p ? gen_mulsidi3_64bit_r6dmul : NULL; if (ISA_HAS_DMUL3) return signed_p ? gen_mulsidi3_64bit_dmul : NULL; if (TARGET_MIPS16) @@ -17817,6 +18028,8 @@ mips_mulsidi3_gen_fn (enum rtx_code ext_code) } else { + if (ISA_HAS_R6MUL) + return (signed_p ? gen_mulsidi3_32bit_r6 : gen_umulsidi3_32bit_r6); if (TARGET_MIPS16) return (signed_p ? gen_mulsidi3_32bit_mips16 diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index 8a388294219..4da256dab00 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -210,10 +210,12 @@ struct mips_cpu_info { #define ISA_MIPS32R2 (mips_isa == 33) #define ISA_MIPS32R3 (mips_isa == 34) #define ISA_MIPS32R5 (mips_isa == 36) +#define ISA_MIPS32R6 (mips_isa == 37) #define ISA_MIPS64 (mips_isa == 64) #define ISA_MIPS64R2 (mips_isa == 65) #define ISA_MIPS64R3 (mips_isa == 66) #define ISA_MIPS64R5 (mips_isa == 68) +#define ISA_MIPS64R6 (mips_isa == 69) /* Architecture target defines. */ #define TARGET_LOONGSON_2E (mips_arch == PROCESSOR_LOONGSON_2E) @@ -458,42 +460,12 @@ struct mips_cpu_info { builtin_define ("__mips=4"); \ builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS4"); \ } \ - else if (ISA_MIPS32) \ + else if (mips_isa >= 32 && mips_isa < 64) \ { \ builtin_define ("__mips=32"); \ builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS32"); \ } \ - else if (ISA_MIPS32R2) \ - { \ - builtin_define ("__mips=32"); \ - builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS32"); \ - } \ - else if (ISA_MIPS32R3) \ - { \ - builtin_define ("__mips=32"); \ - builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS32"); \ - } \ - else if (ISA_MIPS32R5) \ - { \ - builtin_define ("__mips=32"); \ - builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS32"); \ - } \ - else if (ISA_MIPS64) \ - { \ - builtin_define ("__mips=64"); \ - builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS64"); \ - } \ - else if (ISA_MIPS64R2) \ - { \ - builtin_define ("__mips=64"); \ - builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS64"); \ - } \ - else if (ISA_MIPS64R3) \ - { \ - builtin_define ("__mips=64"); \ - builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS64"); \ - } \ - else if (ISA_MIPS64R5) \ + else if (mips_isa >= 64) \ { \ builtin_define ("__mips=64"); \ builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS64"); \ @@ -673,10 +645,14 @@ struct mips_cpu_info { #define MULTILIB_ISA_DEFAULT "mips32" #elif MIPS_ISA_DEFAULT == 33 #define MULTILIB_ISA_DEFAULT "mips32r2" +#elif MIPS_ISA_DEFAULT == 37 +#define MULTILIB_ISA_DEFAULT "mips32r6" #elif MIPS_ISA_DEFAULT == 64 #define MULTILIB_ISA_DEFAULT "mips64" #elif MIPS_ISA_DEFAULT == 65 #define MULTILIB_ISA_DEFAULT "mips64r2" +#elif MIPS_ISA_DEFAULT == 69 +#define MULTILIB_ISA_DEFAULT "mips64r6" #else #define MULTILIB_ISA_DEFAULT "mips1" #endif @@ -743,11 +719,13 @@ struct mips_cpu_info { |march=34k*|march=74k*|march=m14k*|march=1004k*: -mips32r2} \ %{march=mips32r3: -mips32r3} \ %{march=mips32r5|march=p5600: -mips32r5} \ + %{march=mips32r6: -mips32r6} \ %{march=mips64|march=5k*|march=20k*|march=sb1*|march=sr71000 \ |march=xlr: -mips64} \ %{march=mips64r2|march=loongson3a|march=octeon|march=xlp: -mips64r2} \ %{march=mips64r3: -mips64r3} \ %{march=mips64r5: -mips64r5} \ + %{march=mips64r6: -mips64r6} \ %{!march=*: -" MULTILIB_ISA_DEFAULT "}}" /* A spec that infers a -mhard-float or -msoft-float setting from an @@ -776,8 +754,11 @@ struct mips_cpu_info { /* Infer a -msynci setting from a -mips argument, on the assumption that -msynci is desired where possible. */ #define MIPS_ISA_SYNCI_SPEC \ - "%{msynci|mno-synci:;:%{mips32r2|mips32r3|mips32r5|mips64r2|mips64r3 \ - |mips64r5:-msynci;:-mno-synci}}" + "%{msynci|mno-synci:;:%{mips32r2|mips32r3|mips32r5|mips32r6|mips64r2 \ + |mips64r3|mips64r5|mips64r6:-msynci;:-mno-synci}}" + +#define MIPS_ISA_NAN2008_SPEC \ + "%{mnan*:;mips32r6|mips64r6:-mnan=2008}" #if (MIPS_ABI_DEFAULT == ABI_O64 \ || MIPS_ABI_DEFAULT == ABI_N32 \ @@ -827,11 +808,14 @@ struct mips_cpu_info { /* A spec that infers the -mdsp setting from an -march argument. */ #define BASE_DRIVER_SELF_SPECS \ + MIPS_ISA_NAN2008_SPEC, \ "%{!mno-dsp: \ %{march=24ke*|march=34kc*|march=34kf*|march=34kx*|march=1004k*: -mdsp} \ %{march=74k*|march=m14ke*: %{!mno-dspr2: -mdspr2 -mdsp}}}" -#define DRIVER_SELF_SPECS BASE_DRIVER_SELF_SPECS +#define DRIVER_SELF_SPECS \ + MIPS_ISA_LEVEL_SPEC, \ + BASE_DRIVER_SELF_SPECS #define GENERATE_DIVIDE_TRAPS (TARGET_DIVIDE_TRAPS \ && ISA_HAS_COND_TRAP) @@ -864,12 +848,15 @@ struct mips_cpu_info { || ISA_MIPS64 \ || ISA_MIPS64R2 \ || ISA_MIPS64R3 \ - || ISA_MIPS64R5) + || ISA_MIPS64R5 \ + || ISA_MIPS64R6) + +#define ISA_HAS_JR (mips_isa_rev <= 5) /* ISA has branch likely instructions (e.g. mips2). */ /* Disable branchlikely for tx39 until compare rewrite. They haven't been generated up to this point. */ -#define ISA_HAS_BRANCHLIKELY (!ISA_MIPS1) +#define ISA_HAS_BRANCHLIKELY (!ISA_MIPS1 && mips_isa_rev <= 5) /* ISA has 32 single-precision registers. */ #define ISA_HAS_ODD_SPREG ((mips_isa_rev >= 1 \ @@ -885,7 +872,8 @@ struct mips_cpu_info { || TARGET_MIPS7000 \ || TARGET_MIPS9000 \ || TARGET_MAD \ - || mips_isa_rev >= 1) \ + || (mips_isa_rev >= 1 \ + && mips_isa_rev <= 5)) \ && !TARGET_MIPS16) /* ISA has a three-operand multiplication instruction. */ @@ -893,30 +881,48 @@ struct mips_cpu_info { && TARGET_OCTEON \ && !TARGET_MIPS16) +/* ISA has HI and LO registers. */ +#define ISA_HAS_HILO (mips_isa_rev <= 5) + /* ISA supports instructions DMULT and DMULTU. */ -#define ISA_HAS_DMULT (TARGET_64BIT && !TARGET_MIPS5900) +#define ISA_HAS_DMULT (TARGET_64BIT \ + && !TARGET_MIPS5900 \ + && mips_isa_rev <= 5) -/* ISA supports instructions MULT and MULTU. - This is always true, but the macro is needed for ISA_HAS_MULT - in mips.md. */ -#define ISA_HAS_MULT (1) +/* ISA supports instructions MULT and MULTU. */ +#define ISA_HAS_MULT (mips_isa_rev <= 5) + +/* ISA supports instructions MUL, MULU, MUH, MUHU. */ +#define ISA_HAS_R6MUL (mips_isa_rev >= 6) + +/* ISA supports instructions DMUL, DMULU, DMUH, DMUHU. */ +#define ISA_HAS_R6DMUL (TARGET_64BIT && mips_isa_rev >= 6) /* ISA supports instructions DDIV and DDIVU. */ -#define ISA_HAS_DDIV (TARGET_64BIT && !TARGET_MIPS5900) +#define ISA_HAS_DDIV (TARGET_64BIT \ + && !TARGET_MIPS5900 \ + && mips_isa_rev <= 5) /* ISA supports instructions DIV and DIVU. This is always true, but the macro is needed for ISA_HAS_DIV in mips.md. */ -#define ISA_HAS_DIV (1) +#define ISA_HAS_DIV (mips_isa_rev <= 5) #define ISA_HAS_DIV3 ((TARGET_LOONGSON_2EF \ || TARGET_LOONGSON_3A) \ && !TARGET_MIPS16) +/* ISA supports instructions DIV, DIVU, MOD and MODU. */ +#define ISA_HAS_R6DIV (mips_isa_rev >= 6) + +/* ISA supports instructions DDIV, DDIVU, DMOD and DMODU. */ +#define ISA_HAS_R6DDIV (TARGET_64BIT && mips_isa_rev >= 6) + /* ISA has the floating-point conditional move instructions introduced in mips4. */ #define ISA_HAS_FP_CONDMOVE ((ISA_MIPS4 \ - || mips_isa_rev >= 1) \ + || (mips_isa_rev >= 1 \ + && mips_isa_rev <= 5)) \ && !TARGET_MIPS5500 \ && !TARGET_MIPS16) @@ -933,7 +939,15 @@ struct mips_cpu_info { /* ISA has the mips4 FP condition code instructions: FP-compare to CC, branch on CC, and move (both FP and non-FP) on CC. */ -#define ISA_HAS_8CC (ISA_MIPS4 || mips_isa_rev >= 1) +#define ISA_HAS_8CC (ISA_MIPS4 \ + || (mips_isa_rev >= 1 \ + && mips_isa_rev <= 5)) + +/* ISA has the FP condition code instructions that store the flag in an + FP register. */ +#define ISA_HAS_CCF (mips_isa_rev >= 6) + +#define ISA_HAS_SEL (mips_isa_rev >= 6) /* This is a catch all for other mips4 instructions: indexed load, the FP madd and msub instructions, and the FP recip and recip sqrt @@ -941,7 +955,8 @@ struct mips_cpu_info { ISA_HAS_* macros. */ #define ISA_HAS_FP4 ((ISA_MIPS4 \ || ISA_MIPS64 \ - || mips_isa_rev >= 2) \ + || (mips_isa_rev >= 2 \ + && mips_isa_rev <= 5)) \ && !TARGET_MIPS16) /* ISA has floating-point indexed load and store instructions @@ -949,14 +964,22 @@ struct mips_cpu_info { #define ISA_HAS_LXC1_SXC1 ISA_HAS_FP4 /* ISA has paired-single instructions. */ -#define ISA_HAS_PAIRED_SINGLE (ISA_MIPS64 || mips_isa_rev >= 2) +#define ISA_HAS_PAIRED_SINGLE (ISA_MIPS64 \ + || (mips_isa_rev >= 2 \ + && mips_isa_rev <= 5)) /* ISA has conditional trap instructions. */ #define ISA_HAS_COND_TRAP (!ISA_MIPS1 \ && !TARGET_MIPS16) +/* ISA has conditional trap with immediate instructions. */ +#define ISA_HAS_COND_TRAPI (!ISA_MIPS1 \ + && mips_isa_rev <= 5 \ + && !TARGET_MIPS16) + /* ISA has integer multiply-accumulate instructions, madd and msub. */ -#define ISA_HAS_MADD_MSUB (mips_isa_rev >= 1) +#define ISA_HAS_MADD_MSUB (mips_isa_rev >= 1 \ + && mips_isa_rev <= 5) /* Integer multiply-accumulate instructions should be generated. */ #define GENERATE_MADD_MSUB (TARGET_IMADD && !TARGET_MIPS16) @@ -964,6 +987,9 @@ struct mips_cpu_info { /* ISA has floating-point madd and msub instructions 'd = a * b [+-] c'. */ #define ISA_HAS_FP_MADD4_MSUB4 ISA_HAS_FP4 +/* ISA has floating-point MADDF and MSUBF instructions 'd = d [+-] a * b'. */ +#define ISA_HAS_FP_MADDF_MSUBF (mips_isa_rev >= 6) + /* ISA has floating-point madd and msub instructions 'c = a * b [+-] c'. */ #define ISA_HAS_FP_MADD3_MSUB3 TARGET_LOONGSON_2EF @@ -985,10 +1011,19 @@ struct mips_cpu_info { || ((TARGET_FLOAT64 \ || mips_isa_rev >= 2) \ && (MODE) == DFmode))) \ + || (((MODE) == SFmode \ + || (MODE) == DFmode) \ + && (mips_isa_rev >= 6)) \ || (TARGET_SB1 \ && (MODE) == V2SFmode)) \ && !TARGET_MIPS16) +#define ISA_HAS_LWL_LWR (mips_isa_rev <= 5 && !TARGET_MIPS16) + +#define ISA_HAS_IEEE_754_LEGACY (mips_isa_rev <= 5) + +#define ISA_HAS_IEEE_754_2008 (mips_isa_rev >= 2) + /* ISA has count leading zeroes/ones instruction (not implemented). */ #define ISA_HAS_CLZ_CLO (mips_isa_rev >= 1 && !TARGET_MIPS16) @@ -1046,6 +1081,9 @@ struct mips_cpu_info { || mips_isa_rev >= 1) \ && !TARGET_MIPS16) +/* ISA has data prefetch with limited 9-bit displacement. */ +#define ISA_HAS_PREFETCH_9BIT (mips_isa_rev >= 6) + /* ISA has data indexed prefetch instructions. This controls use of 'prefx', along with TARGET_HARD_FLOAT and TARGET_DOUBLE_FLOAT. (prefx is a cop1x instruction, so can only be used if FP is @@ -2133,6 +2171,7 @@ enum reg_class #define SMALL_INT_UNSIGNED(X) SMALL_OPERAND_UNSIGNED (INTVAL (X)) #define LUI_INT(X) LUI_OPERAND (INTVAL (X)) #define UMIPS_12BIT_OFFSET_P(OFFSET) (IN_RANGE (OFFSET, -2048, 2047)) +#define MIPS_9BIT_OFFSET_P(OFFSET) (IN_RANGE (OFFSET, -256, 255)) /* The HI and LO registers can only be reloaded via the general registers. Condition code registers can only be loaded to the diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index 65c0a3f18fe..bdcd694a894 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -67,6 +67,8 @@ xlr xlp p5600 + w32 + w64 ]) (define_c_enum "unspec" [ @@ -768,6 +770,11 @@ && !TARGET_LOONGSON_2EF && !TARGET_MIPS5900")]) +;; This mode iterator allows :FPCC to be used anywhere that an FP condition +;; is needed. +(define_mode_iterator FPCC [(CC "!ISA_HAS_CCF") + (CCF "ISA_HAS_CCF")]) + ;; 32-bit integer moves for which we provide move patterns. (define_mode_iterator IMOVE32 [SI @@ -857,7 +864,7 @@ ;; This attribute gives the best constraint to use for registers of ;; a given mode. -(define_mode_attr reg [(SI "d") (DI "d") (CC "z")]) +(define_mode_attr reg [(SI "d") (DI "d") (CC "z") (CCF "f")]) ;; This attribute gives the format suffix for floating-point operations. (define_mode_attr fmt [(SF "s") (DF "d") (V2SF "ps")]) @@ -897,6 +904,9 @@ (define_mode_attr sqrt_condition [(SF "!ISA_MIPS1") (DF "!ISA_MIPS1") (V2SF "TARGET_SB1")]) +;; This attribute provides the correct mnemonic for each FP condition mode. +(define_mode_attr fpcmp [(CC "c") (CCF "cmp")]) + ;; This code iterator allows signed and unsigned widening multiplications ;; to use the same template. (define_code_iterator any_extend [sign_extend zero_extend]) @@ -919,7 +929,10 @@ ;; This code iterator allows all native floating-point comparisons to be ;; generated from the same template. -(define_code_iterator fcond [unordered uneq unlt unle eq lt le]) +(define_code_iterator fcond [unordered uneq unlt unle eq lt le + (ordered "ISA_HAS_CCF") + (ltgt "ISA_HAS_CCF") + (ne "ISA_HAS_CCF")]) ;; This code iterator is used for comparisons that can be implemented ;; by swapping the operands. @@ -992,7 +1005,10 @@ (unle "ule") (eq "eq") (lt "lt") - (le "le")]) + (le "le") + (ordered "or") + (ltgt "ne") + (ne "une")]) ;; Similar, but for swapped conditions. (define_code_attr swapped_fcond [(ge "le") @@ -1006,6 +1022,10 @@ ;; This is the inverse value of bbv. (define_code_attr bbinv [(eq "1") (ne "0")]) + +;; The sel mnemonic to use depending on the condition test. +(define_code_attr sel [(eq "seleqz") (ne "selnez")]) +(define_code_attr selinv [(eq "selnez") (ne "seleqz")]) ;; ......................... ;; @@ -1114,18 +1134,27 @@ [(match_operand:GPR 1 "reg_or_0_operand") (match_operand:GPR 2 "arith_operand")]) (match_operand 3 "const_0_operand"))] - "ISA_HAS_COND_TRAP" + "ISA_HAS_COND_TRAPI || ISA_HAS_COND_TRAP" { mips_expand_conditional_trap (operands[0]); DONE; }) +(define_insn "*conditional_trap_reg" + [(trap_if (match_operator:GPR 0 "trap_comparison_operator" + [(match_operand:GPR 1 "reg_or_0_operand" "dJ") + (match_operand:GPR 2 "reg_or_0_operand" "dJ")]) + (const_int 0))] + "ISA_HAS_COND_TRAP && !ISA_HAS_COND_TRAPI" + "t%C0\t%z1,%2" + [(set_attr "type" "trap")]) + (define_insn "*conditional_trap" [(trap_if (match_operator:GPR 0 "trap_comparison_operator" [(match_operand:GPR 1 "reg_or_0_operand" "dJ") (match_operand:GPR 2 "arith_operand" "dI")]) (const_int 0))] - "ISA_HAS_COND_TRAP" + "ISA_HAS_COND_TRAPI" "t%C0\t%z1,%2" [(set_attr "type" "trap")]) @@ -1493,13 +1522,13 @@ [(set (match_operand:GPR 0 "register_operand") (mult:GPR (match_operand:GPR 1 "register_operand") (match_operand:GPR 2 "register_operand")))] - "ISA_HAS_MULT" + "ISA_HAS_MULT || ISA_HAS_R6MUL" { rtx lo; - if (TARGET_LOONGSON_2EF || TARGET_LOONGSON_3A) - emit_insn (gen_mul3_mul3_loongson (operands[0], operands[1], - operands[2])); + if (TARGET_LOONGSON_2EF || TARGET_LOONGSON_3A || ISA_HAS_R6MUL) + emit_insn (gen_mul3_mul3_nohilo (operands[0], operands[1], + operands[2])); else if (ISA_HAS_MUL3) emit_insn (gen_mul3_mul3 (operands[0], operands[1], operands[2])); else if (TARGET_MIPS16) @@ -1516,16 +1545,18 @@ DONE; }) -(define_insn "mul3_mul3_loongson" +(define_insn "mul3_mul3_nohilo" [(set (match_operand:GPR 0 "register_operand" "=d") (mult:GPR (match_operand:GPR 1 "register_operand" "d") (match_operand:GPR 2 "register_operand" "d")))] - "TARGET_LOONGSON_2EF || TARGET_LOONGSON_3A" + "TARGET_LOONGSON_2EF || TARGET_LOONGSON_3A || ISA_HAS_R6MUL" { if (TARGET_LOONGSON_2EF) return "multu.g\t%0,%1,%2"; - else + else if (TARGET_LOONGSON_3A) return "gsmultu\t%0,%1,%2"; + else + return "mul\t%0,%1,%2"; } [(set_attr "type" "imul3nc") (set_attr "mode" "")]) @@ -1961,6 +1992,24 @@ DONE; }) +(define_expand "mulsidi3_32bit_r6" + [(set (match_operand:DI 0 "register_operand") + (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand")) + (any_extend:DI (match_operand:SI 2 "register_operand"))))] + "!TARGET_64BIT && ISA_HAS_R6MUL" +{ + rtx dest = gen_reg_rtx (DImode); + rtx low = mips_subword (dest, 0); + rtx high = mips_subword (dest, 1); + + emit_insn (gen_mulsi3_mul3_nohilo (low, operands[1], operands[2])); + emit_insn (gen_mulsi3_highpart_r6 (high, operands[1], operands[2])); + + emit_move_insn (mips_subword (operands[0], 0), low); + emit_move_insn (mips_subword (operands[0], 1), high); + DONE; +}) + (define_expand "mulsidi3_32bit_mips16" [(set (match_operand:DI 0 "register_operand") (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand")) @@ -1982,7 +2031,7 @@ [(set (match_operand:DI 0 "muldiv_target_operand" "=ka") (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d")) (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))] - "!TARGET_64BIT && (!TARGET_FIX_R4000 || ISA_HAS_DSP)" + "!TARGET_64BIT && (!TARGET_FIX_R4000 || ISA_HAS_DSP) && ISA_HAS_MULT" { if (ISA_HAS_DSP_MULT) return "mult\t%q0,%1,%2"; @@ -1997,7 +2046,7 @@ (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d")) (any_extend:DI (match_operand:SI 2 "register_operand" "d")))) (clobber (match_scratch:DI 3 "=x"))] - "!TARGET_64BIT && TARGET_FIX_R4000 && !ISA_HAS_DSP" + "!TARGET_64BIT && TARGET_FIX_R4000 && !ISA_HAS_DSP && ISA_HAS_MULT" "mult\t%1,%2\;mflo\t%L0\;mfhi\t%M0" [(set_attr "type" "imul") (set_attr "mode" "SI") @@ -2009,7 +2058,8 @@ (any_extend:DI (match_operand:SI 2 "register_operand" "d")))) (clobber (match_scratch:TI 3 "=x")) (clobber (match_scratch:DI 4 "=d"))] - "TARGET_64BIT && !TARGET_FIX_R4000 && !ISA_HAS_DMUL3 && !TARGET_MIPS16" + "TARGET_64BIT && !TARGET_FIX_R4000 && !ISA_HAS_DMUL3 + && !TARGET_MIPS16 && ISA_HAS_MULT" "#" "&& reload_completed" [(const_int 0)] @@ -2092,6 +2142,15 @@ [(set_attr "type" "imul3") (set_attr "mode" "DI")]) +(define_insn "mulsidi3_64bit_r6dmul" + [(set (match_operand:DI 0 "register_operand" "=d") + (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d")) + (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))] + "ISA_HAS_R6DMUL" + "dmul\t%0,%1,%2" + [(set_attr "type" "imul3nc") + (set_attr "mode" "DI")]) + ;; Widening multiply with negation. (define_insn "*muls_di" [(set (match_operand:DI 0 "muldiv_target_operand" "=x") @@ -2149,12 +2208,27 @@ else if (TARGET_MIPS16) emit_insn (gen_mulsi3_highpart_split (operands[0], operands[1], operands[2])); + else if (ISA_HAS_R6MUL) + emit_insn (gen_mulsi3_highpart_r6 (operands[0], operands[1], + operands[2])); else emit_insn (gen_mulsi3_highpart_internal (operands[0], operands[1], operands[2])); DONE; }) +(define_insn "mulsi3_highpart_r6" + [(set (match_operand:SI 0 "register_operand" "=d") + (truncate:SI + (lshiftrt:DI + (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d")) + (any_extend:DI (match_operand:SI 2 "register_operand" "d"))) + (const_int 32))))] + "ISA_HAS_R6MUL" + "muh\t%0,%1,%2" + [(set_attr "type" "imul3nc") + (set_attr "mode" "SI")]) + (define_insn_and_split "mulsi3_highpart_internal" [(set (match_operand:SI 0 "register_operand" "=d") (truncate:SI @@ -2163,7 +2237,7 @@ (any_extend:DI (match_operand:SI 2 "register_operand" "d"))) (const_int 32)))) (clobber (match_scratch:SI 3 "=l"))] - "!ISA_HAS_MULHI && !TARGET_MIPS16" + "ISA_HAS_MULT && !ISA_HAS_MULHI && !TARGET_MIPS16" { return TARGET_FIX_R4000 ? "mult\t%1,%2\n\tmfhi\t%0" : "#"; } "&& reload_completed && !TARGET_FIX_R4000" [(const_int 0)] @@ -2241,17 +2315,34 @@ (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand")) (any_extend:TI (match_operand:DI 2 "register_operand"))) (const_int 64))))] - "ISA_HAS_DMULT && !( == ZERO_EXTEND && TARGET_FIX_VR4120)" + "ISA_HAS_R6DMUL + || (ISA_HAS_DMULT + && !( == ZERO_EXTEND && TARGET_FIX_VR4120))" { if (TARGET_MIPS16) emit_insn (gen_muldi3_highpart_split (operands[0], operands[1], operands[2])); + else if (ISA_HAS_R6DMUL) + emit_insn (gen_muldi3_highpart_r6 (operands[0], operands[1], + operands[2])); else emit_insn (gen_muldi3_highpart_internal (operands[0], operands[1], operands[2])); DONE; }) +(define_insn "muldi3_highpart_r6" + [(set (match_operand:DI 0 "register_operand" "=d") + (truncate:DI + (lshiftrt:TI + (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand" "d")) + (any_extend:TI (match_operand:DI 2 "register_operand" "d"))) + (const_int 64))))] + "ISA_HAS_R6DMUL" + "dmuh\t%0,%1,%2" + [(set_attr "type" "imul3nc") + (set_attr "mode" "DI")]) + (define_insn_and_split "muldi3_highpart_internal" [(set (match_operand:DI 0 "register_operand" "=d") (truncate:DI @@ -2390,6 +2481,16 @@ (set_attr "accum_in" "3") (set_attr "mode" "")]) +(define_insn "fma4" + [(set (match_operand:ANYF 0 "register_operand" "=f") + (fma:ANYF (match_operand:ANYF 1 "register_operand" "f") + (match_operand:ANYF 2 "register_operand" "f") + (match_operand:ANYF 3 "register_operand" "0")))] + "ISA_HAS_FP_MADDF_MSUBF" + "maddf.\t%0,%1,%2" + [(set_attr "type" "fmadd") + (set_attr "mode" "")]) + (define_insn "*madd3" [(set (match_operand:ANYF 0 "register_operand" "=f") (plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f") @@ -2773,6 +2874,40 @@ { return mips_output_division ("div\t%.,%1,%2", operands); } [(set_attr "type" "idiv") (set_attr "mode" "")]) + +;; Integer division and modulus. + +(define_insn "div3" + [(set (match_operand:GPR 0 "register_operand" "=&d") + (any_div:GPR (match_operand:GPR 1 "register_operand" "d") + (match_operand:GPR 2 "register_operand" "d")))] + "TARGET_LOONGSON_2EF || TARGET_LOONGSON_3A || ISA_HAS_R6DIV" + { + if (TARGET_LOONGSON_2EF) + return mips_output_division ("div.g\t%0,%1,%2", operands); + else if (TARGET_LOONGSON_3A) + return mips_output_division ("gsdiv\t%0,%1,%2", operands); + else + return mips_output_division ("div\t%0,%1,%2", operands); + } + [(set_attr "type" "idiv3") + (set_attr "mode" "")]) + +(define_insn "mod3" + [(set (match_operand:GPR 0 "register_operand" "=&d") + (any_mod:GPR (match_operand:GPR 1 "register_operand" "d") + (match_operand:GPR 2 "register_operand" "d")))] + "TARGET_LOONGSON_2EF || TARGET_LOONGSON_3A || ISA_HAS_R6DIV" + { + if (TARGET_LOONGSON_2EF) + return mips_output_division ("mod.g\t%0,%1,%2", operands); + else if (TARGET_LOONGSON_3A) + return mips_output_division ("gsmod\t%0,%1,%2", operands); + else + return mips_output_division ("mod\t%0,%1,%2", operands); + } + [(set_attr "type" "idiv3") + (set_attr "mode" "")]) ;; ;; .................... @@ -3918,7 +4053,7 @@ (sign_extract:GPR (match_operand:BLK 1 "memory_operand") (match_operand 2 "const_int_operand") (match_operand 3 "const_int_operand")))] - "!TARGET_MIPS16" + "ISA_HAS_LWL_LWR" { if (mips_expand_ext_as_unaligned_load (operands[0], operands[1], INTVAL (operands[2]), @@ -3955,7 +4090,7 @@ (zero_extract:GPR (match_operand:BLK 1 "memory_operand") (match_operand 2 "const_int_operand") (match_operand 3 "const_int_operand")))] - "!TARGET_MIPS16" + "ISA_HAS_LWL_LWR" { if (mips_expand_ext_as_unaligned_load (operands[0], operands[1], INTVAL (operands[2]), @@ -4006,7 +4141,7 @@ (match_operand 1 "const_int_operand") (match_operand 2 "const_int_operand")) (match_operand:GPR 3 "reg_or_0_operand"))] - "!TARGET_MIPS16" + "ISA_HAS_LWL_LWR" { if (mips_expand_ins_as_unaligned_store (operands[0], operands[3], INTVAL (operands[1]), @@ -4762,6 +4897,13 @@ DONE; }) +(define_insn "movccf" + [(set (match_operand:CCF 0 "nonimmediate_operand" "=f,f,m") + (match_operand:CCF 1 "nonimmediate_operand" "f,m,f"))] + "ISA_HAS_CCF" + { return mips_output_move (operands[0], operands[1]); } + [(set_attr "move_type" "fmove,fpload,fpstore")]) + (define_insn "*movsf_hardfloat" [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m") (match_operand:SF 1 "move_operand" "f,G,m,f,G,*d,*f,*G*d,*m,*d"))] @@ -5280,7 +5422,7 @@ (define_insn "mips_cache" [(set (mem:BLK (scratch)) (unspec:BLK [(match_operand:SI 0 "const_int_operand") - (match_operand:QI 1 "address_operand" "p")] + (match_operand:QI 1 "address_operand" "ZD")] UNSPEC_MIPS_CACHE))] "ISA_HAS_CACHE" "cache\t%X0,%a1") @@ -5557,11 +5699,11 @@ ;; Conditional branches on floating-point equality tests. -(define_insn "*branch_fp" +(define_insn "*branch_fp_" [(set (pc) (if_then_else (match_operator 1 "equality_operator" - [(match_operand:CC 2 "register_operand" "z") + [(match_operand:FPCC 2 "register_operand" "") (const_int 0)]) (label_ref (match_operand 0 "" "")) (pc)))] @@ -5573,11 +5715,11 @@ } [(set_attr "type" "branch")]) -(define_insn "*branch_fp_inverted" +(define_insn "*branch_fp_inverted_" [(set (pc) (if_then_else (match_operator 1 "equality_operator" - [(match_operand:CC 2 "register_operand" "z") + [(match_operand:FPCC 2 "register_operand" "") (const_int 0)]) (pc) (label_ref (match_operand 0 "" ""))))] @@ -5921,21 +6063,21 @@ ;; ;; .................... -(define_insn "s_" - [(set (match_operand:CC 0 "register_operand" "=z") - (fcond:CC (match_operand:SCALARF 1 "register_operand" "f") - (match_operand:SCALARF 2 "register_operand" "f")))] +(define_insn "s__using_" + [(set (match_operand:FPCC 0 "register_operand" "=") + (fcond:FPCC (match_operand:SCALARF 1 "register_operand" "f") + (match_operand:SCALARF 2 "register_operand" "f")))] "" - "c..\t%Z0%1,%2" + "..\t%Z0%1,%2" [(set_attr "type" "fcmp") (set_attr "mode" "FPSW")]) -(define_insn "s_" - [(set (match_operand:CC 0 "register_operand" "=z") - (swapped_fcond:CC (match_operand:SCALARF 1 "register_operand" "f") - (match_operand:SCALARF 2 "register_operand" "f")))] +(define_insn "s__using_" + [(set (match_operand:FPCC 0 "register_operand" "=") + (swapped_fcond:FPCC (match_operand:SCALARF 1 "register_operand" "f") + (match_operand:SCALARF 2 "register_operand" "f")))] "" - "c..\t%Z0%2,%1" + "..\t%Z0%2,%1" [(set_attr "type" "fcmp") (set_attr "mode" "FPSW")]) @@ -6953,6 +7095,41 @@ [(set_attr "type" "condmove") (set_attr "mode" "")]) +(define_insn "*sel_using_" + [(set (match_operand:GPR 0 "register_operand" "=d,d") + (if_then_else:GPR + (equality_op:GPR2 (match_operand:GPR2 1 "register_operand" "d,d") + (const_int 0)) + (match_operand:GPR 2 "reg_or_0_operand" "d,J") + (match_operand:GPR 3 "reg_or_0_operand" "J,d")))] + "ISA_HAS_SEL + && (register_operand (operands[2], mode) + != register_operand (operands[3], mode))" + "@ + \t%0,%2,%1 + \t%0,%3,%1" + [(set_attr "type" "condmove") + (set_attr "mode" "")]) + +;; sel.fmt copies the 3rd argument when the 1st is non-zero and the 2nd +;; argument if the 1st is zero. This means operand 2 and 3 are +;; inverted in the instruction. + +(define_insn "*sel" + [(set (match_operand:SCALARF 0 "register_operand" "=f,f,f") + (if_then_else:SCALARF + (ne:CCF (match_operand:CCF 1 "register_operand" "0,f,f") + (const_int 0)) + (match_operand:SCALARF 2 "reg_or_0_operand" "f,G,f") + (match_operand:SCALARF 3 "reg_or_0_operand" "f,f,G")))] + "ISA_HAS_SEL && ISA_HAS_CCF" + "@ + sel.\t%0,%3,%2 + seleqz.\t%0,%3,%1 + selnez.\t%0,%2,%1" + [(set_attr "type" "condmove") + (set_attr "mode" "")]) + ;; These are the main define_expand's used to make conditional moves. (define_expand "movcc" @@ -6961,8 +7138,11 @@ (if_then_else:GPR (match_dup 5) (match_operand:GPR 2 "reg_or_0_operand") (match_operand:GPR 3 "reg_or_0_operand")))] - "ISA_HAS_CONDMOVE" + "ISA_HAS_CONDMOVE || ISA_HAS_SEL" { + if (ISA_HAS_SEL && !INTEGRAL_MODE_P (GET_MODE (XEXP (operands[1], 0)))) + FAIL; + mips_expand_conditional_move (operands); DONE; }) @@ -6971,10 +7151,25 @@ [(set (match_dup 4) (match_operand 1 "comparison_operator")) (set (match_operand:SCALARF 0 "register_operand") (if_then_else:SCALARF (match_dup 5) - (match_operand:SCALARF 2 "register_operand") - (match_operand:SCALARF 3 "register_operand")))] - "ISA_HAS_FP_CONDMOVE" + (match_operand:SCALARF 2 "reg_or_0_operand") + (match_operand:SCALARF 3 "reg_or_0_operand")))] + "ISA_HAS_FP_CONDMOVE + || (ISA_HAS_SEL && ISA_HAS_CCF)" { + if (ISA_HAS_SEL && !FLOAT_MODE_P (GET_MODE (XEXP (operands[1], 0)))) + FAIL; + + /* Workaround an LRA bug which means that tied operands in the sel.fmt + pattern lead to the double precision destination of sel.d getting + reloaded with the full register file usable and the restrictions on + whether the CCFmode input can be used in odd-numbered single-precision + registers are ignored. For consistency reasons the CCF mode values + must be guaranteed to only exist in the even-registers because of + the unusual duality between single and double precision values. */ + if (ISA_HAS_SEL && mode == DFmode + && (!TARGET_ODD_SPREG || TARGET_FLOATXX)) + FAIL; + mips_expand_conditional_move (operands); DONE; }) @@ -7089,7 +7284,12 @@ [(set (reg:P TLS_GET_TP_REGNUM) (unspec:P [(const_int 0)] UNSPEC_TLS_GET_TP))] "HAVE_AS_TLS && !TARGET_MIPS16" - ".set\tpush\;.set\tmips32r2\t\;rdhwr\t$3,$29\;.set\tpop" + { + if (mips_isa_rev >= 2) + return "rdhwr\t$3,$29"; + + return ".set\tpush\;.set\tmips32r2\t\;rdhwr\t$3,$29\;.set\tpop"; + } [(set_attr "type" "unknown") ; Since rdhwr always generates a trap for now, putting it in a delay ; slot would make the kernel's emulation of it much slower. diff --git a/gcc/config/mips/netbsd.h b/gcc/config/mips/netbsd.h index efa28869b1b..ed41e0f837f 100644 --- a/gcc/config/mips/netbsd.h +++ b/gcc/config/mips/netbsd.h @@ -84,21 +84,13 @@ along with GCC; see the file COPYING3. If not see builtin_define ("__mips=3"); \ else if (ISA_MIPS4) \ builtin_define ("__mips=4"); \ - else if (ISA_MIPS32) \ - { \ - builtin_define ("__mips=32"); \ - builtin_define ("__mips_isa_rev=1"); \ - } \ - else if (ISA_MIPS32R2) \ - { \ - builtin_define ("__mips=32"); \ - builtin_define ("__mips_isa_rev=2"); \ - } \ - else if (ISA_MIPS64) \ - { \ - builtin_define ("__mips=64"); \ - builtin_define ("__mips_isa_rev=1"); \ - } \ + else if (mips_isa >= 32 && mips_isa < 64) \ + builtin_define ("__mips=32"); \ + else if (mips_isa >= 64) \ + builtin_define ("__mips=64"); \ + if (mips_isa_rev > 0) \ + builtin_define_with_int_value ("__mips_isa_rev", \ + mips_isa_rev); \ \ if (TARGET_HARD_FLOAT) \ builtin_define ("__mips_hard_float"); \ @@ -141,7 +133,8 @@ along with GCC; see the file COPYING3. If not see "%{EL:-m elf32lmip} \ %{EB:-m elf32bmip} \ %(endian_spec) \ - %{G*} %{mips1} %{mips2} %{mips3} %{mips4} %{mips32} %{mips32r2} %{mips64} \ + %{G*} %{mips1} %{mips2} %{mips3} %{mips4} %{mips32} %{mips32r2} \ + %{mips32r6} %{mips64} %{mips64r6} \ %(netbsd_link_spec)" #define NETBSD_ENTRY_POINT "__start" diff --git a/gcc/config/mips/t-isa3264 b/gcc/config/mips/t-isa3264 index 8fffdf8f6aa..8455745233e 100644 --- a/gcc/config/mips/t-isa3264 +++ b/gcc/config/mips/t-isa3264 @@ -22,10 +22,10 @@ ifneq ($(filter MIPS_ABI_DEFAULT=ABI_EABI,$(tm_defines)),) MULTILIB_OPTIONS = msoft-float EL/EB mips32/mips32r2/mips64/mips64r2 MULTILIB_DIRNAMES = soft-float el eb mips32 mips32r2 mips64 mips64r2 else -MULTILIB_OPTIONS = msoft-float/mfp64 EL/EB mips32/mips32r2/mips64/mips64r2 -MULTILIB_DIRNAMES = soft-float fp64 el eb mips32 mips32r2 mips64 mips64r2 +MULTILIB_OPTIONS = msoft-float/mfp64 EL/EB mips32/mips32r2/mips32r6/mips64/mips64r2/mips64r6 +MULTILIB_DIRNAMES = soft-float fp64 el eb mips32 mips32r2 mips32r6 mips64 mips64r2 mips64r6 ifneq ($(filter MIPS_ISA_DEFAULT=33,$(tm_defines)),) -MULTILIB_EXCLUSIONS = mips32/mfp64 mips64/mfp64 mips64r2/mfp64 +MULTILIB_EXCLUSIONS = mips32/mfp64 mips64/mfp64 mips64r2/mfp64 mips32r6/mfp64 mips64r6/mfp64 else MULTILIB_EXCLUSIONS = !mips32r2/mfp64 endif diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 45d4e2571c8..e37c777e895 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -785,7 +785,7 @@ Objective-C and Objective-C++ Dialects}. @emph{MIPS Options} @gccoptlist{-EL -EB -march=@var{arch} -mtune=@var{arch} @gol -mips1 -mips2 -mips3 -mips4 -mips32 -mips32r2 -mips32r3 -mips32r5 @gol --mips64 -mips64r2 -mips64r3 -mips64r5 @gol +-mips32r6 -mips64 -mips64r2 -mips64r3 -mips64r5 -mips64r6 @gol -mips16 -mno-mips16 -mflip-mips16 @gol -minterlink-compressed -mno-interlink-compressed @gol -minterlink-mips16 -mno-interlink-mips16 @gol @@ -17671,8 +17671,9 @@ Generate code that runs on @var{arch}, which can be the name of a generic MIPS ISA, or the name of a particular processor. The ISA names are: @samp{mips1}, @samp{mips2}, @samp{mips3}, @samp{mips4}, -@samp{mips32}, @samp{mips32r2}, @samp{mips32r3}, @samp{mips32r5}, -@samp{mips64}, @samp{mips64r2}, @samp{mips64r3} and @samp{mips64r5}. +@samp{mips32}, @samp{mips32r2}, @samp{mips32r3}, @samp{mips32r5}, +@samp{mips32r6}, @samp{mips64}, @samp{mips64r2}, @samp{mips64r3}, +@samp{mips64r5} and @samp{mips64r6}. The processor names are: @samp{4kc}, @samp{4km}, @samp{4kp}, @samp{4ksc}, @samp{4kec}, @samp{4kem}, @samp{4kep}, @samp{4ksd}, @@ -17779,6 +17780,10 @@ Equivalent to @option{-march=mips32r3}. @opindex mips32r5 Equivalent to @option{-march=mips32r5}. +@item -mips32r6 +@opindex mips32r6 +Equivalent to @option{-march=mips32r6}. + @item -mips64 @opindex mips64 Equivalent to @option{-march=mips64}. @@ -17795,6 +17800,10 @@ Equivalent to @option{-march=mips64r3}. @opindex mips64r5 Equivalent to @option{-march=mips64r5}. +@item -mips64r6 +@opindex mips64r6 +Equivalent to @option{-march=mips64r6}. + @item -mips16 @itemx -mno-mips16 @opindex mips16 diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index f2dcac95f98..7f0426c0bff 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -2994,10 +2994,8 @@ operands can be used for microMIPS instructions such as @code{ll} and equivalent to @code{R}. @item ZD -When compiling microMIPS code, this constraint matches an address operand -that is formed from a base register and a 12-bit offset. These operands -can be used for microMIPS instructions such as @code{prefetch}. When -not compiling for microMIPS code, @code{ZD} is equivalent to @code{p}. +An address suitable for a @code{prefetch} instruction, or for any other +instruction with the same addressing mode as @code{prefetch}. @end table @item Motorola 680x0---@file{config/m68k/constraints.md} diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 15096fdc3f3..8d2f41ca05f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,31 @@ +2014-12-19 Matthew Fortune + Steve Ellcey + + * gcc.dg/torture/mips-hilo-2.c: Unconditionally pass for R6 onwards. + * gcc.dg/torture/pr19683-1.c: Likewise. + * gcc.target/mips/branch-cost-2.c: Require MOVN. + * gcc.target/mips/movcc-1.c: Likewise. + * gcc.target/mips/movcc-2.c: Likewise. + * gcc.target/mips/movcc-3.c: Likewise. + * gcc.target/mips/call-saved-4.c: Require LDC. + * gcc.target/mips/dmult-1.c: Require R5 or earlier. + * gcc.target/mips/fpcmp-1.c: Likewise. + * gcc.target/mips/fpcmp-2.c: Likewise. + * gcc.target/mips/neg-abs-2.c: Likewise. + * gcc.target/mips/timode-1.c: Likewise. + * gcc.target/mips/unaligned-1.c: Likewise. + * gcc.target/mips/madd-3.c: Require MADD. + * gcc.target/mips/madd-9.c: Likewise. + * gcc.target/mips/maddu-3.c: Likewise. + * gcc.target/mips/msub-3.c: Likewise. + * gcc.target/mips/msubu-3.c: Likewise. + * gcc.target/mips/mult-1.c: Require INS and not DMUL. + * gcc.target/mips/mips-ps-type-2.c: Require MADD.PS. + * gcc.target/mips/mips.exp (mips_option_groups): Add ins, dmul, ldc, + movn, madd, maddps. + (mips-dg-options): INS available from R2. LDC available from MIPS II, + DMUL is present in octeon. Describe all features removed from R6. + 2014-12-19 Janus Weil PR fortran/64209 diff --git a/gcc/testsuite/gcc.dg/torture/mips-hilo-2.c b/gcc/testsuite/gcc.dg/torture/mips-hilo-2.c index dbe949307df..78f7710d67b 100644 --- a/gcc/testsuite/gcc.dg/torture/mips-hilo-2.c +++ b/gcc/testsuite/gcc.dg/torture/mips-hilo-2.c @@ -5,6 +5,7 @@ extern void abort (void); extern void exit (int); +#if __mips_isa_rev <= 5 unsigned int g; unsigned __attribute__ ((nomips16)) long long f (unsigned int x) @@ -15,13 +16,16 @@ unsigned __attribute__ ((nomips16)) long long f (unsigned int x) asm ("mflo\t%0" : "=r" (g) : "l" (u.parts[1])); return u.ll; } +#endif int __attribute__ ((nomips16)) main () { +#if __mips_isa_rev <= 5 union { unsigned long long ll; unsigned int parts[2]; } u; u.ll = f (0x12345678); if (g != u.parts[1]) abort (); +#endif exit (0); } diff --git a/gcc/testsuite/gcc.dg/torture/pr19683-1.c b/gcc/testsuite/gcc.dg/torture/pr19683-1.c index 05bf174183b..aa7205f7c6f 100644 --- a/gcc/testsuite/gcc.dg/torture/pr19683-1.c +++ b/gcc/testsuite/gcc.dg/torture/pr19683-1.c @@ -14,6 +14,7 @@ extern void exit (int); #define IN(X) unsigned int x##X = ptr[0] #define OUT(X) ptr[0] = x##X +#if __mips_isa_rev <= 5 union u { unsigned long long ll; unsigned int i[2]; }; unsigned int __attribute__ ((nomips16)) @@ -28,15 +29,18 @@ foo (volatile unsigned int *ptr) asm ("#" : "=l" (result) : "l" (u.i[1])); return result; } +#endif int __attribute__ ((nomips16)) main (void) { +#if __mips_isa_rev <= 5 unsigned int array[] = { 1000 * 1000 * 1000 }; union u u; u.ll = (unsigned long long) array[0] * array[0]; if (foo (array) != u.i[1]) abort (); +#endif exit (0); } diff --git a/gcc/testsuite/gcc.target/mips/args-3.c b/gcc/testsuite/gcc.target/mips/args-3.c index 6a79ce6745e..5eddabf8371 100644 --- a/gcc/testsuite/gcc.target/mips/args-3.c +++ b/gcc/testsuite/gcc.target/mips/args-3.c @@ -24,7 +24,7 @@ int foo (float inf, int64 in64, int32 in32) abort (); #endif -#if (__mips == 4 || __mips == 32 || __mips == 64) && !defined (__mips16) +#if (__mips == 4 || ((__mips == 32 || __mips == 64) && __mips_isa_rev < 6)) && !defined (__mips16) __asm__ ("move %0,%.\n\tmovn %0,%1,%2" : "=&r" (res32) : "r" (in32), "r" (in64 != 0)); if (res32 != 60) diff --git a/gcc/testsuite/gcc.target/mips/branch-cost-2.c b/gcc/testsuite/gcc.target/mips/branch-cost-2.c index 3b2c4a13e5e..5a422ae29b4 100644 --- a/gcc/testsuite/gcc.target/mips/branch-cost-2.c +++ b/gcc/testsuite/gcc.target/mips/branch-cost-2.c @@ -1,4 +1,4 @@ -/* { dg-options "-mbranch-cost=10 isa>=4" } */ +/* { dg-options "-mbranch-cost=10 (HAS_MOVN)" } */ /* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ NOMIPS16 int foo (int x, int y, int z, int k) diff --git a/gcc/testsuite/gcc.target/mips/call-saved-4.c b/gcc/testsuite/gcc.target/mips/call-saved-4.c index e12617558d9..846ea321e7c 100644 --- a/gcc/testsuite/gcc.target/mips/call-saved-4.c +++ b/gcc/testsuite/gcc.target/mips/call-saved-4.c @@ -1,5 +1,5 @@ /* Check that we save the correct call-saved GPRs and FPRs. */ -/* { dg-options "isa>=2 -mabi=32 -mfp32" } */ +/* { dg-options "(HAS_LDC) -mabi=32 -mfp32" } */ void bar (void); diff --git a/gcc/testsuite/gcc.target/mips/dmult-1.c b/gcc/testsuite/gcc.target/mips/dmult-1.c index f8c0b8b44f1..92573168d77 100644 --- a/gcc/testsuite/gcc.target/mips/dmult-1.c +++ b/gcc/testsuite/gcc.target/mips/dmult-1.c @@ -1,4 +1,4 @@ -/* { dg-options "forbid_cpu=octeon.* -mgp64" } */ +/* { dg-options "isa_rev<=5 forbid_cpu=octeon.* -mgp64" } */ /* { dg-final { scan-assembler "\tdmult\t" } } */ /* { dg-final { scan-assembler "\tmflo\t" } } */ /* { dg-final { scan-assembler-not "\tdmul\t" } } */ diff --git a/gcc/testsuite/gcc.target/mips/fpcmp-1.c b/gcc/testsuite/gcc.target/mips/fpcmp-1.c index c0594ff3562..03c2f792612 100644 --- a/gcc/testsuite/gcc.target/mips/fpcmp-1.c +++ b/gcc/testsuite/gcc.target/mips/fpcmp-1.c @@ -1,5 +1,5 @@ /* We used to use c.lt.fmt instead of c.ule.fmt here. */ -/* { dg-options "-mhard-float" } */ +/* { dg-options "isa_rev<=5 -mhard-float" } */ NOMIPS16 int f1 (float x, float y) { return __builtin_isless (x, y); } NOMIPS16 int f2 (double x, double y) { return __builtin_isless (x, y); } /* { dg-final { scan-assembler "\tc\\.ule\\.s\t" } } */ diff --git a/gcc/testsuite/gcc.target/mips/fpcmp-2.c b/gcc/testsuite/gcc.target/mips/fpcmp-2.c index 23d5cb0c4ca..6936b9009d3 100644 --- a/gcc/testsuite/gcc.target/mips/fpcmp-2.c +++ b/gcc/testsuite/gcc.target/mips/fpcmp-2.c @@ -1,5 +1,5 @@ /* We used to use c.le.fmt instead of c.ult.fmt here. */ -/* { dg-options "-mhard-float" } */ +/* { dg-options "isa_rev<=5 -mhard-float" } */ NOMIPS16 int f1 (float x, float y) { return __builtin_islessequal (x, y); } NOMIPS16 int f2 (double x, double y) { return __builtin_islessequal (x, y); } /* { dg-final { scan-assembler "\tc\\.ult\\.s\t" } } */ diff --git a/gcc/testsuite/gcc.target/mips/madd-3.c b/gcc/testsuite/gcc.target/mips/madd-3.c index 29f4c9b3768..b0771ad9920 100644 --- a/gcc/testsuite/gcc.target/mips/madd-3.c +++ b/gcc/testsuite/gcc.target/mips/madd-3.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "isa_rev>=1 -mgp32" } */ +/* { dg-options "(HAS_MADD) -mgp32" } */ /* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ /* { dg-final { scan-assembler-times "\tmadd\t" 3 } } */ diff --git a/gcc/testsuite/gcc.target/mips/madd-9.c b/gcc/testsuite/gcc.target/mips/madd-9.c index 28681a91002..acafc7a2be5 100644 --- a/gcc/testsuite/gcc.target/mips/madd-9.c +++ b/gcc/testsuite/gcc.target/mips/madd-9.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "isa_rev>=1 -mgp32 -mtune=4kc" } */ +/* { dg-options "(HAS_MADD) -mgp32 -mtune=4kc" } */ /* References to X within the loop need to have a higher frequency than references to X outside the loop, otherwise there is no reason to prefer multiply/accumulator registers over GPRs. */ diff --git a/gcc/testsuite/gcc.target/mips/maddu-3.c b/gcc/testsuite/gcc.target/mips/maddu-3.c index 27a7350f07b..e180fa74131 100644 --- a/gcc/testsuite/gcc.target/mips/maddu-3.c +++ b/gcc/testsuite/gcc.target/mips/maddu-3.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* This test requires widening_mul */ -/* { dg-options "isa_rev>=1 -mgp32 -fexpensive-optimizations" } */ +/* { dg-options "(HAS_MADD) -mgp32 -fexpensive-optimizations" } */ /* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ /* { dg-final { scan-assembler-times "\tmaddu\t" 3 } } */ diff --git a/gcc/testsuite/gcc.target/mips/mips-ps-type-2.c b/gcc/testsuite/gcc.target/mips/mips-ps-type-2.c index f52cf91e81b..a4dfbaea645 100644 --- a/gcc/testsuite/gcc.target/mips/mips-ps-type-2.c +++ b/gcc/testsuite/gcc.target/mips/mips-ps-type-2.c @@ -1,7 +1,7 @@ /* Test v2sf calculations. The nmadd and nmsub patterns need -ffinite-math-only. */ /* { dg-do compile } */ -/* { dg-options "isa_rev>=2 -mgp32 -mpaired-single -ffinite-math-only" } */ +/* { dg-options "(HAS_MADDPS) -mgp32 -mpaired-single -ffinite-math-only" } */ /* { dg-skip-if "nmadd and nmsub need combine" { *-*-* } { "-O0" } { "" } } */ /* { dg-final { scan-assembler "\tcvt.ps.s\t" } } */ /* { dg-final { scan-assembler "\tmov.ps\t" } } */ diff --git a/gcc/testsuite/gcc.target/mips/mips.exp b/gcc/testsuite/gcc.target/mips/mips.exp index e117a805f87..febc73a9389 100644 --- a/gcc/testsuite/gcc.target/mips/mips.exp +++ b/gcc/testsuite/gcc.target/mips/mips.exp @@ -247,6 +247,12 @@ set mips_option_groups { small-data "-G[0-9]+" warnings "-w" dump "-fdump-.*" + ins "HAS_INS" + dmul "NOT_HAS_DMUL" + ldc "HAS_LDC" + movn "HAS_MOVN" + madd "HAS_MADD" + maddps "HAS_MADDPS" } for { set option 0 } { $option < 32 } { incr option } { @@ -1063,6 +1069,9 @@ proc mips-dg-options { args } { && (($gp_size == 32 && [mips_have_test_option_p options "-mfp64"]) || [mips_have_test_option_p options "-msynci"] || [mips_have_test_option_p options "-mdsp"] + || [mips_have_test_option_p options "HAS_INS"] + || [mips_have_test_option_p options "HAS_MADD"] + || [mips_have_test_option_p options "HAS_MADDPS"] || [mips_have_test_option_p options "-mdspr2"]) } { if { $gp_size == 32 } { mips_make_test_option options "-mips32r2" @@ -1084,6 +1093,12 @@ proc mips-dg-options { args } { } else { mips_make_test_option options "-mips64" } + # We need MIPS IV or higher for: + # + # + } elseif { $isa < 3 + && [mips_have_test_option_p options "HAS_MOVN"] } { + mips_make_test_option options "-mips4" # We need MIPS III or higher for: # # - the "cache" instruction @@ -1102,8 +1117,38 @@ proc mips-dg-options { args } { && ([mips_have_test_option_p options "-mbranch-likely"] || [mips_have_test_option_p options "-mfix-r10000"] || ($gp_size == 32 - && [mips_have_test_option_p options "-mfpxx"])) } { + && ([mips_have_test_option_p options "-mfpxx"] + || [mips_have_test_option_p options "HAS_LDC"]))) } { mips_make_test_option options "-mips2" + # We need to use octeon's base ISA if a test must not run with an + # architecture that supports dmul. + } elseif { [regexp -- "^-march=octeon.*\$" $arch] + && [mips_have_test_option_p options "NOT_HAS_DMUL"] } { + mips_make_test_option options "-mips${isa}r${isa_rev}" + # Check whether we need to switch from mips*r6 down to mips*r5 due + # to options that are incompatible with mips*r6. If we do, use + # -mnan=2008 because r6 is nan2008 by default and without this flag + # tests that include stdlib.h will fail due to not finding + # stubs-o32_hard.h (r6 compilers only have stubs-o32_hard_2008.h) + } elseif { $isa_rev > 5 + && ([mips_have_test_option_p options "-mdsp"] + || [mips_have_test_option_p options "-mdspr2"] + || [mips_have_test_option_p options "-mips16"] + || [mips_have_test_option_p options "-mmicromips"] + || [mips_have_test_option_p options "-mfp32"] + || [mips_have_test_option_p options "-mfix-r10000"] + || [mips_have_test_option_p options "NOT_HAS_DMUL"] + || [mips_have_test_option_p options "HAS_MOVN"] + || [mips_have_test_option_p options "HAS_MADD"] + || [mips_have_test_option_p options "-mpaired-single"] + || [mips_have_test_option_p options "-mnan=legacy"] + || [mips_have_test_option_p options "-mabs=legacy"]) } { + if { $gp_size == 32 } { + mips_make_test_option options "-mips32r5" + } else { + mips_make_test_option options "-mips64r5" + } + mips_make_test_option options "-mnan=2008" # Check whether we need to switch from a 32-bit processor to the # "nearest" 64-bit processor. } elseif { $gp_size == 64 && [mips_32bit_arch_p $arch] } { @@ -1128,6 +1173,10 @@ proc mips-dg-options { args } { unset isa_rev } + # Re-calculate the isa_rev for use in the abi handling code below + set arch [mips_option options arch] + set isa_rev [mips_arch_info $arch isa_rev] + # Set an appropriate ABI, handling dependencies between the pre-abi # options and the abi options. This should mirror the abi and post-abi # code below. @@ -1192,8 +1241,8 @@ proc mips-dg-options { args } { if { $abi_test_option_p } { if { $eabi_p } { mips_make_test_option options "-mno-abicalls" - if { $gp_size == 32 } { - mips_make_test_option options "-mfp32" + if { $isa_rev < 6 && $gp_size == 32 } { + mips_make_test_option options "-mfp32" } } if { [mips_using_mips16_p options] @@ -1238,6 +1287,17 @@ proc mips-dg-options { args } { mips_make_test_option options "-mno-dsp" mips_make_test_option options "-mno-synci" } + if { $isa_rev > 5 } { + mips_make_test_option options "-mno-dsp" + mips_make_test_option options "-mno-mips16" + if { [mips_have_test_option_p options "-mdsp"] } { + mips_make_test_option options "-mfp64" + } + mips_make_test_option options "-mno-fix-r10000" + mips_make_test_option options "-mno-paired-single" + mips_make_test_option options "-mnan=2008" + mips_make_test_option options "-mabs=2008" + } unset arch unset isa unset isa_rev diff --git a/gcc/testsuite/gcc.target/mips/movcc-1.c b/gcc/testsuite/gcc.target/mips/movcc-1.c index b3fe188d2c0..7943fecbcef 100644 --- a/gcc/testsuite/gcc.target/mips/movcc-1.c +++ b/gcc/testsuite/gcc.target/mips/movcc-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "isa>=4" } */ +/* { dg-options "(HAS_MOVN)" } */ /* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ /* { dg-final { scan-assembler "\tmovz\t" } } */ /* { dg-final { scan-assembler "\tmovn\t" } } */ diff --git a/gcc/testsuite/gcc.target/mips/movcc-2.c b/gcc/testsuite/gcc.target/mips/movcc-2.c index 2638d51fd6c..1926e6460d1 100644 --- a/gcc/testsuite/gcc.target/mips/movcc-2.c +++ b/gcc/testsuite/gcc.target/mips/movcc-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "isa>=4" } */ +/* { dg-options "(HAS_MOVN)" } */ /* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ /* { dg-final { scan-assembler "\tmovz\t" } } */ /* { dg-final { scan-assembler "\tmovn\t" } } */ diff --git a/gcc/testsuite/gcc.target/mips/movcc-3.c b/gcc/testsuite/gcc.target/mips/movcc-3.c index f356465c887..55434b72c72 100644 --- a/gcc/testsuite/gcc.target/mips/movcc-3.c +++ b/gcc/testsuite/gcc.target/mips/movcc-3.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "isa>=4 -mhard-float" } */ +/* { dg-options "(HAS_MOVN) -mhard-float" } */ /* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ /* { dg-final { scan-assembler "\tmovt\t" } } */ /* { dg-final { scan-assembler "\tmovf\t" } } */ diff --git a/gcc/testsuite/gcc.target/mips/msub-3.c b/gcc/testsuite/gcc.target/mips/msub-3.c index aedd04302ac..132db857de8 100644 --- a/gcc/testsuite/gcc.target/mips/msub-3.c +++ b/gcc/testsuite/gcc.target/mips/msub-3.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* This test requires widening_mul */ -/* { dg-options "isa_rev>=1 -mgp32 -fexpensive-optimizations" } */ +/* { dg-options "(HAS_MADD) -mgp32 -fexpensive-optimizations" } */ /* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ /* { dg-final { scan-assembler-times "\tmsub\t" 2 } } */ diff --git a/gcc/testsuite/gcc.target/mips/msubu-3.c b/gcc/testsuite/gcc.target/mips/msubu-3.c index 2e936ebe03f..07cb7c714f6 100644 --- a/gcc/testsuite/gcc.target/mips/msubu-3.c +++ b/gcc/testsuite/gcc.target/mips/msubu-3.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* This test requires widening_mul */ -/* { dg-options "isa_rev>=1 -mgp32 -fexpensive-optimizations" } */ +/* { dg-options "(HAS_MADD) -mgp32 -fexpensive-optimizations" } */ /* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ /* { dg-final { scan-assembler-times "\tmsubu\t" 2 } } */ diff --git a/gcc/testsuite/gcc.target/mips/mult-1.c b/gcc/testsuite/gcc.target/mips/mult-1.c index 1038797f228..bd9757cc0ed 100644 --- a/gcc/testsuite/gcc.target/mips/mult-1.c +++ b/gcc/testsuite/gcc.target/mips/mult-1.c @@ -1,7 +1,7 @@ /* For SI->DI widening multiplication we should use DINS to combine the two halves. For Octeon use DMUL with explicit widening. */ /* This test requires widening_mul */ -/* { dg-options "-mgp64 isa_rev>=2 forbid_cpu=octeon.* -fexpensive-optimizations" } */ +/* { dg-options "-mgp64 (HAS_INS) (NOT_HAS_DMUL) -fexpensive-optimizations" } */ /* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ /* { dg-final { scan-assembler "\tdins\t" } } */ /* { dg-final { scan-assembler-not "\tdsll\t" } } */ diff --git a/gcc/testsuite/gcc.target/mips/neg-abs-2.c b/gcc/testsuite/gcc.target/mips/neg-abs-2.c index 435751e0cc4..59e797def1a 100644 --- a/gcc/testsuite/gcc.target/mips/neg-abs-2.c +++ b/gcc/testsuite/gcc.target/mips/neg-abs-2.c @@ -1,7 +1,7 @@ /* Make sure that we avoid abs.fmt and neg.fmt when the signs of NaNs matter. */ /* { dg-do compile } */ -/* { dg-options "-mhard-float -fno-finite-math-only" } */ +/* { dg-options "isa_rev<=5 -mhard-float -fno-finite-math-only -mabs=legacy" } */ /* { dg-final { scan-assembler-not "\tneg.s\t" } } */ /* { dg-final { scan-assembler-not "\tneg.d\t" } } */ /* { dg-final { scan-assembler-not "\tabs.s\t" } } */ diff --git a/gcc/testsuite/gcc.target/mips/timode-1.c b/gcc/testsuite/gcc.target/mips/timode-1.c index 606fee0cb1a..be3d317cb69 100644 --- a/gcc/testsuite/gcc.target/mips/timode-1.c +++ b/gcc/testsuite/gcc.target/mips/timode-1.c @@ -1,4 +1,4 @@ -/* { dg-options "-mgp64" } */ +/* { dg-options "isa_rev<=5 -mgp64" } */ /* { dg-skip-if "we deliberately use calls when optimizing for size" { *-*-* } { "-Os" } { "" } } */ typedef int int128_t __attribute__((mode(TI))); typedef unsigned int uint128_t __attribute__((mode(TI))); diff --git a/gcc/testsuite/gcc.target/mips/unaligned-1.c b/gcc/testsuite/gcc.target/mips/unaligned-1.c index 938f52d21f2..4888ca8b51f 100644 --- a/gcc/testsuite/gcc.target/mips/unaligned-1.c +++ b/gcc/testsuite/gcc.target/mips/unaligned-1.c @@ -1,4 +1,4 @@ -/* { dg-options "-mgp64" } */ +/* { dg-options "isa_rev<=5 -mgp64" } */ /* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ /* { dg-final { scan-assembler-times "\tsdl\t" 1 } } */ /* { dg-final { scan-assembler-times "\tsdr\t" 1 } } */ diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index ea0057f28fe..efd08c4fd14 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,8 @@ +2014-12-19 Matthew Fortune + + * config.host: Support mipsisa32r6 and mipsisa64r6. + * config/mips/mips16.S: Do not build for R6. + 2014-12-17 Oleg Endo * config/sh/crt.h: New. diff --git a/libgcc/config.host b/libgcc/config.host index 9903d153792..b10d7250e94 100644 --- a/libgcc/config.host +++ b/libgcc/config.host @@ -827,8 +827,10 @@ mips*-sde-elf*) ;; mipsisa32-*-elf* | mipsisa32el-*-elf* | \ mipsisa32r2-*-elf* | mipsisa32r2el-*-elf* | \ +mipsisa32r6-*-elf* | mipsisa32r6el-*-elf* | \ mipsisa64-*-elf* | mipsisa64el-*-elf* | \ -mipsisa64r2-*-elf* | mipsisa64r2el-*-elf*) +mipsisa64r2-*-elf* | mipsisa64r2el-*-elf* | \ +mipsisa64r6-*-elf* | mipsisa64r6el-*-elf*) tmake_file="$tmake_file mips/t-elf mips/t-crtstuff mips/t-mips16" extra_parts="$extra_parts crti.o crtn.o" ;; diff --git a/libgcc/config/mips/mips16.S b/libgcc/config/mips/mips16.S index c0c73ffac00..1783d1178dc 100644 --- a/libgcc/config/mips/mips16.S +++ b/libgcc/config/mips/mips16.S @@ -23,12 +23,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #include "auto-host.h" -#if defined(__mips_micromips) || defined(__mips_soft_float) +#if defined(__mips_micromips) || defined(__mips_soft_float) \ + || __mips_isa_rev >= 6 /* Do nothing because this code is only needed when linking against mips16 hard-float objects. Neither micromips code - nor soft-float code can be linked against mips16 hard-float - objects so we do not need these routines when building libgcc - for those cases. */ + nor soft-float nor MIPS R6 code can be linked against mips16 + hard-float objects so we do not need these routines when + building libgcc for those cases. */ #else #if defined(HAVE_AS_MODULE)