diff options
author | Steve Ellcey <Steve.Ellcey@imgtec.com> | 2015-03-19 15:09:08 -0700 |
---|---|---|
committer | Steve Ellcey <Steve.Ellcey@imgtec.com> | 2015-03-19 15:09:08 -0700 |
commit | 9f57376006c7afb1561fe3e7a8d8be64f3196acd (patch) | |
tree | 67be4e16ff59195e9a80737ebf6b262e2ab92911 /gcc-4.9/gcc/config | |
parent | 3951a3654b8197466bee3e6732b3bc94e4018f68 (diff) | |
download | toolchain_gcc-9f57376006c7afb1561fe3e7a8d8be64f3196acd.tar.gz toolchain_gcc-9f57376006c7afb1561fe3e7a8d8be64f3196acd.tar.bz2 toolchain_gcc-9f57376006c7afb1561fe3e7a8d8be64f3196acd.zip |
Update MSA Support in MIPS GCC.
Change-Id: Id87035be4552719dc05096bb98b49d4bed91a07a
Diffstat (limited to 'gcc-4.9/gcc/config')
24 files changed, 3648 insertions, 2253 deletions
diff --git a/gcc-4.9/gcc/config/mips/android.h b/gcc-4.9/gcc/config/mips/android.h index 00eac095d..e2bd6b338 100644 --- a/gcc-4.9/gcc/config/mips/android.h +++ b/gcc-4.9/gcc/config/mips/android.h @@ -24,7 +24,7 @@ along with GCC; see the file COPYING3. If not see to write. */ \ MIPS_ISA_LEVEL_SPEC, \ \ - /* Infer the default float setting (hard or soft) from -march. */ \ + /* Infer the default float setting from -march. */ \ MIPS_ARCH_FLOAT_SPEC, \ \ /* Infer the -msynci setting from -march if not explicitly set. */ \ @@ -34,12 +34,13 @@ along with GCC; see the file COPYING3. If not see or -mgp setting. */ \ "%{!mabi=*: %{" MIPS_32BIT_OPTION_SPEC ": -mabi=32;: -mabi=64}}", \ \ - /* If no FP option is specified, infer one from the ABI/ISA level. */\ - "%{!mfp*: %{mabi=32: \ - %{" MIPS_FPXX_OPTION_SPEC ": -mfpxx -mno-odd-spreg }}}", \ + /* If no FP ABI option is specified, infer one from the \ + ABI/ISA level unless there is a conflicting option. */ \ + "%{!msoft-float: %{!msingle-float: %{!mfp*: %{!mmsa: %{mabi=32: %{" \ + MIPS_FPXX_OPTION_SPEC ": -mfpxx}}}}}}", \ \ /* Base SPECs. */ \ - BASE_DRIVER_SELF_SPECS \ + BASE_DRIVER_SELF_SPECS, \ \ /* Use the standard linux specs for everything else. */ \ - LINUX64_DRIVER_SELF_SPECS + LINUX_DRIVER_SELF_SPECS diff --git a/gcc-4.9/gcc/config/mips/constraints.md b/gcc-4.9/gcc/config/mips/constraints.md index 92ab2dee5..7f5a63b4a 100644 --- a/gcc-4.9/gcc/config/mips/constraints.md +++ b/gcc-4.9/gcc/config/mips/constraints.md @@ -373,14 +373,16 @@ (if_then_else (match_test "TARGET_MICROMIPS") (match_test "umips_12bit_offset_address_p (XEXP (op, 0), mode)") - (match_test "mips_address_insns (XEXP (op, 0), mode, false)")))) + (if_then_else (match_test "ISA_HAS_PREF_LL_9BIT") + (match_test "mips_9bit_offset_address_p (XEXP (op, 0), mode)") + (match_test "mips_address_insns (XEXP (op, 0), mode, false)"))))) (define_address_constraint "ZD" "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)") - (if_then_else (match_test "ISA_HAS_PREFETCH_9BIT") + (if_then_else (match_test "ISA_HAS_PREF_LL_9BIT") (match_test "mips_9bit_offset_address_p (op, mode)") (match_test "mips_address_insns (op, mode, false)")))) diff --git a/gcc-4.9/gcc/config/mips/gnu-user.h b/gcc-4.9/gcc/config/mips/gnu-user.h index 02c6a3f0b..b0033e231 100644 --- a/gcc-4.9/gcc/config/mips/gnu-user.h +++ b/gcc-4.9/gcc/config/mips/gnu-user.h @@ -53,20 +53,23 @@ along with GCC; see the file COPYING3. If not see #undef MIPS_DEFAULT_GVALUE #define MIPS_DEFAULT_GVALUE 0 -/* Borrowed from sparc/linux.h */ #undef GNU_USER_TARGET_LINK_SPEC -#define GNU_USER_TARGET_LINK_SPEC \ - "%(endian_spec) \ - %{shared:-shared} \ - %{!EB:%{!meb:-m elf32ltsmip}} %{EB|meb:-m elf32btsmip} \ - %{!shared: \ - %{!static: \ - %{rdynamic:-export-dynamic} \ - -dynamic-linker " GNU_USER_DYNAMIC_LINKER "} \ - %{static:-static}}" +#define GNU_USER_TARGET_LINK_SPEC "\ + %{G*} %{EB} %{EL} %{mips*} %{shared} \ + %{!shared: \ + %{!static: \ + %{rdynamic:-export-dynamic} \ + %{mabi=n32: -dynamic-linker " GNU_USER_DYNAMIC_LINKERN32 "} \ + %{mabi=64: -dynamic-linker " GNU_USER_DYNAMIC_LINKER64 "} \ + %{mabi=32: -dynamic-linker " GNU_USER_DYNAMIC_LINKER32 "}} \ + %{static}} \ + %{mabi=n32:-m" GNU_USER_LINK_EMULATIONN32 "} \ + %{mabi=64:-m" GNU_USER_LINK_EMULATION64 "} \ + %{mabi=32:-m" GNU_USER_LINK_EMULATION32 "}" + #undef LINK_SPEC #define LINK_SPEC GNU_USER_TARGET_LINK_SPEC - + #undef SUBTARGET_ASM_SPEC #define SUBTARGET_ASM_SPEC \ "%{!mno-abicalls:%{mplt:-call_nonpic;:-KPIC}} " \ @@ -125,10 +128,13 @@ extern const char *host_detect_local_cpu (int argc, const char **argv); specs handling by removing a redundant option. */ \ "%{!mno-shared:%<mplt}", \ /* -mplt likewise has no effect for -mabi=64 without -msym32. */ \ - "%{mabi=64:%{!msym32:%<mplt}}" + "%{mabi=64:%{!msym32:%<mplt}}", \ + "%{!EB:%{!EL:%(endian_spec)}}", \ + "%{!mabi=*: -" MULTILIB_ABI_DEFAULT "}" #undef DRIVER_SELF_SPECS #define DRIVER_SELF_SPECS \ + MIPS_ISA_LEVEL_SPEC, \ BASE_DRIVER_SELF_SPECS, \ LINUX_DRIVER_SELF_SPECS @@ -140,3 +146,6 @@ extern const char *host_detect_local_cpu (int argc, const char **argv); #define ENDFILE_SPEC \ GNU_USER_TARGET_MATHFILE_SPEC " " \ GNU_USER_TARGET_ENDFILE_SPEC + +#undef LOCAL_LABEL_PREFIX +#define LOCAL_LABEL_PREFIX (TARGET_OLDABI ? "$" : ".") diff --git a/gcc-4.9/gcc/config/mips/gnu-user64.h b/gcc-4.9/gcc/config/mips/gnu-user64.h deleted file mode 100644 index b97b4a768..000000000 --- a/gcc-4.9/gcc/config/mips/gnu-user64.h +++ /dev/null @@ -1,52 +0,0 @@ -/* Definitions for MIPS systems using GNU userspace and n32/64 abi. - Copyright (C) 2002-2014 Free Software Foundation, Inc. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3, or (at your option) -any later version. - -GCC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - -/* Force the default endianness and ABI flags onto the command line - in order to make the other specs easier to write. */ - -#define LINUX64_DRIVER_SELF_SPECS \ - LINUX_DRIVER_SELF_SPECS \ - " %{!EB:%{!EL:%(endian_spec)}}" \ - " %{!mabi=*: -" MULTILIB_ABI_DEFAULT "}" - -#undef DRIVER_SELF_SPECS -#define DRIVER_SELF_SPECS \ - BASE_DRIVER_SELF_SPECS, \ - LINUX64_DRIVER_SELF_SPECS - -#undef GNU_USER_TARGET_LINK_SPEC -#define GNU_USER_TARGET_LINK_SPEC "\ -%{G*} %{EB} %{EL} %{mips1} %{mips2} %{mips3} %{mips4} \ -%{shared} \ - %(endian_spec) \ - %{!shared: \ - %{!static: \ - %{rdynamic:-export-dynamic} \ - %{mabi=n32: -dynamic-linker " GNU_USER_DYNAMIC_LINKERN32 "} \ - %{mabi=64: -dynamic-linker " GNU_USER_DYNAMIC_LINKER64 "} \ - %{mabi=32: -dynamic-linker " GNU_USER_DYNAMIC_LINKER32 "}} \ - %{static:-static}} \ -%{mabi=n32:-m" GNU_USER_LINK_EMULATIONN32 "} \ -%{mabi=64:-m" GNU_USER_LINK_EMULATION64 "} \ -%{mabi=32:-m" GNU_USER_LINK_EMULATION32 "}" -#undef LINK_SPEC -#define LINK_SPEC GNU_USER_TARGET_LINK_SPEC - -#undef LOCAL_LABEL_PREFIX -#define LOCAL_LABEL_PREFIX (TARGET_OLDABI ? "$" : ".") diff --git a/gcc-4.9/gcc/config/mips/i6400.md b/gcc-4.9/gcc/config/mips/i6400.md new file mode 100644 index 000000000..1950f3a7c --- /dev/null +++ b/gcc-4.9/gcc/config/mips/i6400.md @@ -0,0 +1,335 @@ +;; DFA-based pipeline description for i6400. + +;; Copyright (C) 2007-2014 Free Software Foundation, Inc. + +;; This file is part of GCC. + +;; GCC is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. + +;; GCC is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +;; License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; <http://www.gnu.org/licenses/>. + +(define_automaton "i6400_int_pipe, i6400_mdu_pipe, i6400_fpu_short_pipe, + i6400_fpu_long_pipe") + +(define_cpu_unit "i6400_gpmuldiv" "i6400_mdu_pipe") + +(define_cpu_unit "i6400_agen, i6400_alu1, i6400_lsu" "i6400_int_pipe") + +(define_cpu_unit "i6400_control, i6400_ctu, i6400_alu0" "i6400_int_pipe") + +;; The floating-point-unit queue (FPQ) has short and long pipes + +;; Short FPU pipeline. +(define_cpu_unit "i6400_fpu_short, i6400_fpu_intadd, i6400_fpu_logic, + i6400_fpu_div, i6400_fpu_cmp, i6400_fpu_float, i6400_fpu_store" + "i6400_fpu_short_pipe") + +;; Long FPU pipeline. +(define_cpu_unit "i6400_fpu_long, i6400_fpu_logic_l, i6400_fpu_float_l, + i6400_fpu_mult, i6400_fpu_apu" "i6400_fpu_long_pipe") + +(define_reservation "i6400_control_ctu" "i6400_control, i6400_ctu") +(define_reservation "i6400_control_alu0" "i6400_control, i6400_alu0") +(define_reservation "i6400_agen_lsu" "i6400_agen, i6400_lsu") +(define_reservation "i6400_agen_alu1" "i6400_agen, i6400_alu1") + +;; +;; FPU-MSA pipe +;; + +;; Short pipe + +;; addv, subv +(define_insn_reservation "i6400_msa_add_d" 1 + (and (eq_attr "cpu" "i6400") + (and (eq_attr "datafmt" "!d") + (and (eq_attr "alu_type" "add, sub") + (eq_attr "msa_execunit" "msa_eu_int_add")))) + "i6400_fpu_short, i6400_fpu_intadd") + +;; add, hadd, sub, hsub, average, min, max, compare +(define_insn_reservation "i6400_msa_int_add" 2 + (and (eq_attr "cpu" "i6400") + (eq_attr "msa_execunit" "msa_eu_int_add")) + "i6400_fpu_short, i6400_fpu_intadd") + +;; sat, pcnt +(define_insn_reservation "i6400_msa_short_logic3" 3 + (and (eq_attr "cpu" "i6400") + (eq_attr "msa_execunit" "msa_eu_logic3")) + "i6400_fpu_short, i6400_fpu_logic") + +;; shf.d +(define_insn_reservation "i6400_msa_shf_d" 1 + (and (eq_attr "cpu" "i6400") + (and (eq_attr "datafmt" "d") + (eq_attr "msa_execunit" "msa_eu_logic2"))) + "i6400_fpu_short, i6400_fpu_logic") + +;; shifts, nloc, nlzc, bneg, bclr, shf +(define_insn_reservation "i6400_msa_short_logic2" 2 + (and (eq_attr "cpu" "i6400") + (eq_attr "msa_execunit" "msa_eu_logic2")) + "i6400_fpu_short, i6400_fpu_logic") + +;; and, or, xor, ilv, pck, move.v, fill, splat +(define_insn_reservation "i6400_msa_short_logic" 1 + (and (eq_attr "cpu" "i6400") + (eq_attr "msa_execunit" "msa_eu_logic")) + "i6400_fpu_short, i6400_fpu_logic") + +;; move.v, ldi +(define_insn_reservation "i6400_msa_move" 1 + (and (eq_attr "cpu" "i6400") + (and (eq_attr "type" "fmove") + (eq_attr "mode" "TI"))) + "i6400_fpu_short, i6400_fpu_logic") + +;; Float compare New: CMP.cond.fmt +(define_insn_reservation "i6400_msa_cmp" 2 + (and (eq_attr "cpu" "i6400") + (eq_attr "msa_execunit" "msa_eu_cmp")) + "i6400_fpu_short, i6400_fpu_cmp") + +;; Float min, max, class +(define_insn_reservation "i6400_msa_short_float2" 2 + (and (eq_attr "cpu" "i6400") + (ior (and (eq_attr "msa_execunit" "msa_eu_float2") + (eq_attr "type" "!fmul")) + (and (eq_attr "msa_execunit" "msa_eu_float2_l") + (eq_attr "type" "fcmp")))) + "i6400_fpu_short, i6400_fpu_float") + +;; div.d, mod.d (non-pipelined) +(define_insn_reservation "i6400_msa_div_d" 36 + (and (eq_attr "cpu" "i6400") + (and (eq_attr "datafmt" "d") + (eq_attr "msa_execunit" "msa_eu_div"))) + "i6400_fpu_short+i6400_fpu_div*36") + +;; div.w, mod.w (non-pipelined) +(define_insn_reservation "i6400_msa_div_w" 20 + (and (eq_attr "cpu" "i6400") + (and (eq_attr "datafmt" "w") + (eq_attr "msa_execunit" "msa_eu_div"))) + "i6400_fpu_short+i6400_fpu_div*20") + +;; div.h, mod.h (non-pipelined) +(define_insn_reservation "i6400_msa_div_h" 12 + (and (eq_attr "cpu" "i6400") + (and (eq_attr "datafmt" "h") + (eq_attr "msa_execunit" "msa_eu_div"))) + "i6400_fpu_short+i6400_fpu_div*12") + +;; div.b, mod.b (non-pipelined) +(define_insn_reservation "i6400_msa_div_b" 8 + (and (eq_attr "cpu" "i6400") + (and (eq_attr "datafmt" "b") + (eq_attr "msa_execunit" "msa_eu_div"))) + "i6400_fpu_short+i6400_fpu_div*8") + +;; Vector copy +(define_insn_reservation "i6400_msa_copy" 1 + (and (eq_attr "cpu" "i6400") + (and (eq_attr "msa_execunit" "msa_eu_store4") + (eq_attr "type" "mfc, mtc"))) + "i6400_fpu_short, i6400_fpu_store") + +;; Vector bz, bnz +(define_insn_reservation "i6400_msa_branch" 1 + (and (eq_attr "cpu" "i6400") + (eq_attr "msa_execunit" "msa_eu_store4")) + "i6400_control_ctu") + +;; Vector store, sdc1, swc1 +(define_insn_reservation "i6400_fpu_msa_store" 1 + (and (eq_attr "cpu" "i6400") + (eq_attr "type" "fpstore")) + "i6400_agen_lsu") + +;; Vector load, ldc1, lwc1 +(define_insn_reservation "i6400_fpu_msa_load" 3 + (and (eq_attr "cpu" "i6400") + (eq_attr "type" "fpload")) + "i6400_agen_lsu") + +;; mfc, mtc +(define_insn_reservation "i6400_fpu_move" 1 + (and (eq_attr "cpu" "i6400") + (eq_attr "move_type" "mfc, mtc")) + "i6400_control_alu0 | i6400_agen_alu1") + +;; Long pipe + +;; bmz, bmnz, bsel, insert, insve +(define_insn_reservation "i6400_msa_long_logic1" 1 + (and (eq_attr "cpu" "i6400") + (eq_attr "msa_execunit" "msa_eu_logic_l")) + "i6400_fpu_long, i6400_fpu_logic_l") + +;; binsl, binsr, vshf, sld +(define_insn_reservation "i6400_msa_long_logic2" 2 + (and (eq_attr "cpu" "i6400") + (eq_attr "msa_execunit" "msa_eu_logic_l2")) + "i6400_fpu_long, i6400_fpu_logic_l") + +;; Vector mul, dotp, madd, msub +(define_insn_reservation "i6400_msa_mult" 5 + (and (eq_attr "cpu" "i6400") + (eq_attr "msa_execunit" "msa_eu_mult")) + "i6400_fpu_long, i6400_fpu_mult") + +;; Float flog2 +(define_insn_reservation "i6400_msa_long_float2" 2 + (and (eq_attr "cpu" "i6400") + (and (eq_attr "msa_execunit" "msa_eu_float2_l") + (eq_attr "type" "fmul"))) + "i6400_fpu_long, i6400_fpu_float_l") + +;; fadd, fsub +(define_insn_reservation "i6400_msa_long_float4" 4 + (and (eq_attr "cpu" "i6400") + (eq_attr "msa_execunit" "msa_eu_float4")) + "i6400_fpu_long, i6400_fpu_float_l") + +;; fmul, fexp2 +(define_insn_reservation "i6400_msa_long_float5" 5 + (and (eq_attr "cpu" "i6400") + (ior (eq_attr "msa_execunit" "msa_eu_float5") + (and (eq_attr "msa_execunit" "msa_eu_float2") + (eq_attr "type" "fmul")))) + "i6400_fpu_long, i6400_fpu_float_l") + +;; fmadd, fmsub +(define_insn_reservation "i6400_msa_long_float8" 8 + (and (eq_attr "cpu" "i6400") + (eq_attr "msa_execunit" "msa_eu_float8")) + "i6400_fpu_long, i6400_fpu_float_l") + +;; fdiv.d +(define_insn_reservation "i6400_msa_fdiv_df" 30 + (and (eq_attr "cpu" "i6400") + (and (eq_attr "mode" "DF") + (eq_attr "msa_execunit" "msa_eu_fdiv"))) + "i6400_fpu_long+i6400_fpu_float_l*30") + +;; fdiv.w +(define_insn_reservation "i6400_msa_fdiv_sf" 22 + (and (eq_attr "cpu" "i6400") + (eq_attr "msa_execunit" "msa_eu_fdiv")) + "i6400_fpu_long+i6400_fpu_float_l*22") + +;; +;; FPU pipe +;; + +;; fabs, fneg +(define_insn_reservation "i6400_fpu_fabs" 1 + (and (eq_attr "cpu" "i6400") + (eq_attr "type" "fabs,fneg,fmove")) + "i6400_fpu_short, i6400_fpu_apu") + +;; fadd, fsub, fcvt +(define_insn_reservation "i6400_fpu_fadd" 4 + (and (eq_attr "cpu" "i6400") + (eq_attr "type" "fadd, fcvt")) + "i6400_fpu_long, i6400_fpu_apu") + +;; fmul +(define_insn_reservation "i6400_fpu_fmul" 5 + (and (eq_attr "cpu" "i6400") + (eq_attr "type" "fmul")) + "i6400_fpu_long, i6400_fpu_apu") + +;; div, sqrt (Double Precision) +(define_insn_reservation "i6400_fpu_div_df" 30 + (and (eq_attr "cpu" "i6400") + (and (eq_attr "mode" "DF") + (eq_attr "type" "fdiv,frdiv,fsqrt,frsqrt"))) + "i6400_fpu_long+i6400_fpu_apu*30") + +;; div, sqrt (Single Precision) +(define_insn_reservation "i6400_fpu_div_sf" 22 + (and (eq_attr "cpu" "i6400") + (eq_attr "type" "fdiv,frdiv,fsqrt,frsqrt")) + "i6400_fpu_long+i6400_fpu_apu*22") + +;; +;; Integer pipe +;; + +;; and, lui, shifts, seb, seh +(define_insn_reservation "i6400_int_logical" 1 + (and (eq_attr "cpu" "i6400") + (eq_attr "move_type" "logical,const,andi,sll0,signext")) + "i6400_control_alu0 | i6400_agen_alu1") + +;; addi, addiu, ori, xori, add, addu, sub, nor +(define_insn_reservation "i6400_int_add" 1 + (and (eq_attr "cpu" "i6400") + (eq_attr "alu_type" "add,sub,or,xor,nor")) + "i6400_control_alu0 | i6400_agen_alu1") + +;; shifts, clo, clz, cond move, arith +(define_insn_reservation "i6400_int_arith" 1 + (and (eq_attr "cpu" "i6400") + (eq_attr "type" "shift,slt,move,clz,condmove,arith")) + "i6400_control_alu0 | i6400_agen_alu1") + +;; nop +(define_insn_reservation "i6400_int_nop" 0 + (and (eq_attr "cpu" "i6400") + (eq_attr "type" "nop")) + "nothing") + +;; mult, multu, mul +(define_insn_reservation "i6400_int_mult" 4 + (and (eq_attr "cpu" "i6400") + (eq_attr "type" "imul3,imul")) + "i6400_gpmuldiv") + +;; divide +(define_insn_reservation "i6400_int_div" 32 + (and (eq_attr "cpu" "i6400") + (eq_attr "type" "idiv")) + "i6400_gpmuldiv*32") + +;; Load lb, lbu, lh, lhu, lq, lw, lw_i2f, lwxs +(define_insn_reservation "i6400_int_load" 3 + (and (eq_attr "cpu" "i6400") + (eq_attr "move_type" "load")) + "i6400_agen_lsu") + +;; store +(define_insn_reservation "i6400_int_store" 1 + (and (eq_attr "cpu" "i6400") + (eq_attr "move_type" "store")) + "i6400_agen_lsu") + +;; prefetch +(define_insn_reservation "i6400_int_prefetch" 3 + (and (eq_attr "cpu" "i6400") + (eq_attr "type" "prefetch")) + "i6400_agen_lsu") + +;; branch and jump +(define_insn_reservation "i6400_int_branch" 1 + (and (eq_attr "cpu" "i6400") + (eq_attr "type" "branch,jump")) + "i6400_control_ctu") + +;; call +(define_insn_reservation "i6400_int_call" 1 + (and (eq_attr "cpu" "i6400") + (eq_attr "jal" "indirect,direct")) + "i6400_control_ctu") diff --git a/gcc-4.9/gcc/config/mips/linux.h b/gcc-4.9/gcc/config/mips/linux.h index d045089d8..a117f90fb 100644 --- a/gcc-4.9/gcc/config/mips/linux.h +++ b/gcc-4.9/gcc/config/mips/linux.h @@ -17,10 +17,27 @@ You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ -#define GLIBC_DYNAMIC_LINKER \ - "%{mnan=2008|mips32r6|mips64r6:/lib/ld-linux-mipsn8.so.1;:/lib/ld.so.1}" +#define GNU_USER_LINK_EMULATION32 "elf32%{EB:b}%{EL:l}tsmip" +#define GNU_USER_LINK_EMULATION64 "elf64%{EB:b}%{EL:l}tsmip" +#define GNU_USER_LINK_EMULATIONN32 "elf32%{EB:b}%{EL:l}tsmipn32" -#undef UCLIBC_DYNAMIC_LINKER -#define UCLIBC_DYNAMIC_LINKER \ - "%{mnan=2008|mips32r6|mips64r6:/lib/ld-uClibc-mipsn8.so.0;" \ - ":/lib/ld-uClibc.so.0}" +#define GLIBC_DYNAMIC_LINKER32 \ + "%{mnan=2008:/lib/ld-linux-mipsn8.so.1;:/lib/ld.so.1}" +#define GLIBC_DYNAMIC_LINKER64 \ + "%{mnan=2008:/lib64/ld-linux-mipsn8.so.1;:/lib64/ld.so.1}" +#define GLIBC_DYNAMIC_LINKERN32 \ + "%{mnan=2008:/lib32/ld-linux-mipsn8.so.1;:/lib32/ld.so.1}" + +#undef UCLIBC_DYNAMIC_LINKER32 +#define UCLIBC_DYNAMIC_LINKER32 \ + "%{mnan=2008:/lib/ld-uClibc-mipsn8.so.0;:/lib/ld-uClibc.so.0}" +#undef UCLIBC_DYNAMIC_LINKER64 +#define UCLIBC_DYNAMIC_LINKER64 \ + "%{mnan=2008:/lib/ld64-uClibc-mipsn8.so.0;:/lib/ld64-uClibc.so.0}" +#define UCLIBC_DYNAMIC_LINKERN32 \ + "%{mnan=2008:/lib32/ld-uClibc-mipsn8.so.0;:/lib32/ld-uClibc.so.0}" + +#define BIONIC_DYNAMIC_LINKERN32 "/system/bin/linker32" +#define GNU_USER_DYNAMIC_LINKERN32 \ + CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKERN32, UCLIBC_DYNAMIC_LINKERN32, \ + BIONIC_DYNAMIC_LINKERN32) diff --git a/gcc-4.9/gcc/config/mips/linux64.h b/gcc-4.9/gcc/config/mips/linux64.h deleted file mode 100644 index d09fe2367..000000000 --- a/gcc-4.9/gcc/config/mips/linux64.h +++ /dev/null @@ -1,47 +0,0 @@ -/* Definitions for MIPS running Linux-based GNU systems with ELF format - using n32/64 abi. - Copyright (C) 2002-2014 Free Software Foundation, Inc. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3, or (at your option) -any later version. - -GCC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - -#define GNU_USER_LINK_EMULATION32 "elf32%{EB:b}%{EL:l}tsmip" -#define GNU_USER_LINK_EMULATION64 "elf64%{EB:b}%{EL:l}tsmip" -#define GNU_USER_LINK_EMULATIONN32 "elf32%{EB:b}%{EL:l}tsmipn32" - -#define GLIBC_DYNAMIC_LINKER32 \ - "%{mnan=2008|mips32r6|mips64r6:/lib/ld-linux-mipsn8.so.1;:/lib/ld.so.1}" -#define GLIBC_DYNAMIC_LINKER64 \ - "%{mnan=2008|mips32r6|mips64r6:/lib64/ld-linux-mipsn8.so.1;:/lib64/ld.so.1}" -#define GLIBC_DYNAMIC_LINKERN32 \ - "%{mnan=2008|mips32r6|mips64r6:/lib32/ld-linux-mipsn8.so.1;:/lib32/ld.so.1}" - -#undef UCLIBC_DYNAMIC_LINKER32 -#define UCLIBC_DYNAMIC_LINKER32 \ - "%{mnan=2008|mips32r6|mips64r6:/lib/ld-uClibc-mipsn8.so.0;" \ - ":/lib/ld-uClibc.so.0}" -#undef UCLIBC_DYNAMIC_LINKER64 -#define UCLIBC_DYNAMIC_LINKER64 \ - "%{mnan=2008|mips32r6|mips64r6:/lib/ld64-uClibc-mipsn8.so.0;" \ - ":/lib/ld64-uClibc.so.0}" -#define UCLIBC_DYNAMIC_LINKERN32 \ - "%{mnan=2008|mips32r6|mips64r6:/lib32/ld-uClibc-mipsn8.so.0;" \ - ":/lib32/ld-uClibc.so.0}" - -#define BIONIC_DYNAMIC_LINKERN32 "/system/bin/linker32" -#define GNU_USER_DYNAMIC_LINKERN32 \ - CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKERN32, UCLIBC_DYNAMIC_LINKERN32, \ - BIONIC_DYNAMIC_LINKERN32) diff --git a/gcc-4.9/gcc/config/mips/mips-cpus.def b/gcc-4.9/gcc/config/mips/mips-cpus.def index 8f480772a..94e68873e 100644 --- a/gcc-4.9/gcc/config/mips/mips-cpus.def +++ b/gcc-4.9/gcc/config/mips/mips-cpus.def @@ -56,7 +56,7 @@ MIPS_CPU ("mips64", PROCESSOR_5KC, 64, PTF_AVOID_BRANCHLIKELY) 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_CPU ("mips64r6", PROCESSOR_I6400, 69, PTF_AVOID_BRANCHLIKELY) /* MIPS I processors. */ MIPS_CPU ("r3000", PROCESSOR_R3000, 1, 0) @@ -164,4 +164,8 @@ MIPS_CPU ("loongson3a", PROCESSOR_LOONGSON_3A, 65, PTF_AVOID_BRANCHLIKELY) MIPS_CPU ("octeon", PROCESSOR_OCTEON, 65, PTF_AVOID_BRANCHLIKELY) MIPS_CPU ("octeon+", PROCESSOR_OCTEON, 65, PTF_AVOID_BRANCHLIKELY) MIPS_CPU ("octeon2", PROCESSOR_OCTEON2, 65, PTF_AVOID_BRANCHLIKELY) +MIPS_CPU ("octeon3", PROCESSOR_OCTEON3, 65, PTF_AVOID_BRANCHLIKELY) MIPS_CPU ("xlp", PROCESSOR_XLP, 65, PTF_AVOID_BRANCHLIKELY) + +/* MIPS64 Release 6 processors. */ +MIPS_CPU ("i6400", PROCESSOR_I6400, 69, PTF_AVOID_BRANCHLIKELY) diff --git a/gcc-4.9/gcc/config/mips/mips-dsp.md b/gcc-4.9/gcc/config/mips/mips-dsp.md index 58c11fe9a..54d1b2a68 100644 --- a/gcc-4.9/gcc/config/mips/mips-dsp.md +++ b/gcc-4.9/gcc/config/mips/mips-dsp.md @@ -1185,8 +1185,21 @@ (label_ref (match_operand 0 "" "")) (pc)))] "ISA_HAS_DSP" - "%*bposge%1\t%0%/" - [(set_attr "type" "branch")]) +{ + if (TARGET_DSPR3 && TARGET_CB_MAYBE) + return "%*bposge%1%:\t%0"; + else + return "%*bposge%1\t%0%/"; +} + [(set_attr "type" "branch") + (set (attr "compact_form") (if_then_else (match_test "TARGET_DSPR3 + && TARGET_CB_MAYBE") + (const_string "maybe") + (const_string "never"))) + (set (attr "hazard") (if_then_else (match_test "TARGET_DSPR3 + && TARGET_CB_MAYBE") + (const_string "forbidden_slot") + (const_string "none")))]) (define_expand "mips_madd<u>" [(set (match_operand:DI 0 "register_operand") diff --git a/gcc-4.9/gcc/config/mips/mips-msa.md b/gcc-4.9/gcc/config/mips/mips-msa.md index 37f5fcab5..b2da26ddb 100644 --- a/gcc-4.9/gcc/config/mips/mips-msa.md +++ b/gcc-4.9/gcc/config/mips/mips-msa.md @@ -22,8 +22,6 @@ ;; (define_c_enum "unspec" [ - UNSPEC_MSA_ADDVI - UNSPEC_MSA_ANDI_B UNSPEC_MSA_ASUB_S UNSPEC_MSA_ASUB_U UNSPEC_MSA_AVE_S @@ -52,8 +50,6 @@ UNSPEC_MSA_BZ UNSPEC_MSA_CFCMSA UNSPEC_MSA_CMPI - UNSPEC_MSA_COPY_S - UNSPEC_MSA_COPY_U UNSPEC_MSA_CTCMSA UNSPEC_MSA_DOTP_S UNSPEC_MSA_DOTP_U @@ -72,11 +68,8 @@ UNSPEC_MSA_FFINT_U UNSPEC_MSA_FFQL UNSPEC_MSA_FFQR - UNSPEC_MSA_FILL UNSPEC_MSA_FLOG2 - UNSPEC_MSA_FMAX UNSPEC_MSA_FMAX_A - UNSPEC_MSA_FMIN UNSPEC_MSA_FMIN_A UNSPEC_MSA_FRCP UNSPEC_MSA_FRINT @@ -101,23 +94,12 @@ UNSPEC_MSA_HADD_U UNSPEC_MSA_HSUB_S UNSPEC_MSA_HSUB_U - UNSPEC_MSA_ILVEV - UNSPEC_MSA_ILVL - UNSPEC_MSA_ILVOD - UNSPEC_MSA_ILVR - UNSPEC_MSA_INSERT - UNSPEC_MSA_INSVE - UNSPEC_MSA_LD0 UNSPEC_MSA_MADD_Q UNSPEC_MSA_MADDR_Q UNSPEC_MSA_MAX_A - UNSPEC_MSA_MAX_S - UNSPEC_MSA_MAX_U UNSPEC_MSA_MAXI_S UNSPEC_MSA_MAXI_U UNSPEC_MSA_MIN_A - UNSPEC_MSA_MIN_S - UNSPEC_MSA_MIN_U UNSPEC_MSA_MINI_S UNSPEC_MSA_MINI_U UNSPEC_MSA_MSUB_Q @@ -161,11 +143,15 @@ ]) ;; Attributes to categorize MSA instructions based on execution units -(define_attr "msa_execunit" +(define_attr "msa_execunit" "unknown, msa_eu_div, msa_eu_float2, msa_eu_float2_l, - msa_eu_float4, msa_eu_float5, msa_eu_float8, msa_eu_logic, - msa_eu_logic3, msa_eu_logic_l, msa_eu_mult, msa_eu_cmp, - msa_eu_store4, msa_eu_int_add, msa_eu_fdiv" + msa_eu_float4, msa_eu_float5, msa_eu_float8, msa_eu_logic, + msa_eu_logic3, msa_eu_logic_l, msa_eu_mult, msa_eu_cmp, + msa_eu_store4, msa_eu_int_add, msa_eu_fdiv, msa_eu_logic_l2, msa_eu_logic2" + (const_string "unknown")) + +(define_attr "datafmt" + "unknown, d, w, h, b" (const_string "unknown")) ;; All vector modes with 128 bits. @@ -179,17 +165,16 @@ (define_mode_iterator IMSA [V2DI V4SI V8HI V16QI]) ;; mode that can combine a copy+insert into insve. -;; note V2DI is excluded because it split if !TARGET_64 -(define_mode_iterator INSVE [V4SI V8HI V16QI]) +(define_mode_iterator INSVE [V2DI V4SI]) -;; mode that can be combine copy+inset with subreg info insve. +;; mode that can be combine copy+insert with subreg info insve. (define_mode_iterator INSVE_2 [V8HI V16QI]) -;; As IMSA but excludeds V16QI. +;; As IMSA but excludes V16QI. (define_mode_iterator IMSA_X [V2DI V4SI V8HI]) -;; Only used with insert. -(define_mode_iterator MSA_3 [V16QI V8HI V2DF V4SF]) +;; As IMSA but excludes V2DI +(define_mode_iterator IMSA_X2 [V4SI V8HI V16QI]) ;; Only integer modes for fixed-point madd_q/maddr_q. (define_mode_iterator QMSA [V4SI V8HI]) @@ -203,18 +188,29 @@ ;; Only used in spliters (define_mode_iterator SPLIT [V2DI V2DF]) -;; Only used with SPILT iteraror +(define_mode_attr DMSA + [(V2DI "V4DI") + (V4SI "V8SI") + (V8HI "V16HI") + (V16QI "V32QI")]) + +;; Only used with SPLIT iterator (define_mode_attr predicate [(V2DI "reg_or_0") (V2DF "register")]) -(define_mode_attr VHALFMODE +(define_mode_attr VHALFMODE [(V8HI "V16QI") (V4SI "V8HI") (V2DI "V4SI") (V2DF "V4SF")]) -;; The attribute give the integer vector mode with same size. +(define_mode_attr VDMODE + [(V4SI "V2DI") + (V8HI "V4SI") + (V16QI "V8HI")]) + +;; The attribute gives the integer vector mode with same size. (define_mode_attr VIMODE [(V2DF "V2DI") (V4SF "V4SI") @@ -241,7 +237,7 @@ (V8HI "SI") (V16QI "SI")]) -;; This attribute qives suffix for MSA instructions. +;; This attribute gives suffix for MSA instructions. (define_mode_attr msafmt [(V2DF "d") (V4SF "w") @@ -255,8 +251,8 @@ [(V2DF "d") (V4SF "s")]) -;; This attribute qives define_insn suffix for MSA instructions -;; with need distinction between integer and floating point. +;; This attribute gives define_insn suffix for MSA instructions with need +;; distinction between integer and floating point. (define_mode_attr msafmt_f [(V2DF "d_f") (V4SF "w_f") @@ -272,8 +268,8 @@ (V8HI "15") (V16QI "7")]) -;; This is used to form an immediate operand constraint -;; using "const_<indeximm>_operand". +;; This is used to form an immediate operand constraint using +;; "const_<indeximm>_operand". (define_mode_attr indeximm [(V2DF "0_or_1") (V4SF "0_to_3") @@ -282,19 +278,27 @@ (V8HI "uimm3") (V16QI "uimm4")]) -;; This attribute is used to form the MODE for reg_or_0_operand -;; constraint. -(define_mode_attr REGOR0 - [(V2DF "DF") - (V4SF "SF") - (V2DI "DI") +;; To represent bitmask needed for vec_merge using "const_<bitmask>_operand". +(define_mode_attr bitmask + [(V2DF "exp_2") + (V4SF "exp_4") + (V2DI "exp_2") + (V4SI "exp_4") + (V8HI "exp_8") + (V16QI "exp_16")]) + +;; This attribute is used to form the MODE of an input operand +;; when some builtins (insert snd fill) take an input operand other than +;; UNITMODE mode. See the msa_insert and msa_fill for an examples. +(define_mode_attr EXCEPT + [(V2DI "DI") (V4SI "SI") (V8HI "SI") (V16QI "SI")]) -;; This attribute used to form an immediate operand constraint -;; using "const_<bitimm>_operand" -(define_mode_attr bitimm +;; This attribute used to form an immediate operand constraint using +;; "const_<bitimm>_operand". +(define_mode_attr bitimm [(V16QI "uimm3") (V8HI "uimm4") (V4SI "uimm5") @@ -310,6 +314,117 @@ DONE; }) +(define_mode_attr hmsafmt + [(V2DI "w") + (V4SI "h") + (V8HI "b")]) + +(define_expand "fixuns_trunc<FMSA:mode><mode_i>2" + [(set (match_operand:<VIMODE> 0 "register_operand" "=f") + (unsigned_fix:<VIMODE> (match_operand:FMSA 1 "register_operand" "f")))] + "ISA_HAS_MSA" + { + emit_insn (gen_msa_ftrunc_u_<msafmt> (operands[0], operands[1])); + DONE; + }) + +(define_expand "fix_trunc<FMSA:mode><mode_i>2" + [(set (match_operand:<VIMODE> 0 "register_operand" "=f") + (fix:<VIMODE> (match_operand:FMSA 1 "register_operand" "f")))] + "ISA_HAS_MSA" + { + emit_insn (gen_msa_ftrunc_s_<msafmt> (operands[0], operands[1])); + DONE; + }) + +(define_expand "vec_pack_trunc_v2df" + [(set (match_operand:V4SF 0 "register_operand") + (vec_concat:V4SF + (float_truncate:V2SF (match_operand:V2DF 1 "register_operand")) + (float_truncate:V2SF (match_operand:V2DF 2 "register_operand"))))] + "ISA_HAS_MSA" + "") + +;; pckev pattern with implicit type conversion. +(define_insn "vec_pack_trunc_<mode>" + [(set (match_operand:<VHALFMODE> 0 "register_operand" "=f") + (unspec:<VHALFMODE> [(match_operand:IMSA_X 1 "register_operand" "f") + (match_operand:IMSA_X 2 "register_operand" "f")] + UNSPEC_MSA_PCKEV))] + "ISA_HAS_MSA" + "pckev.<hmsafmt>\t%w0,%w2,%w1" + [(set_attr "alu_type" "add") + (set_attr "mode" "TI") + (set_attr "msa_execunit" "msa_eu_logic")]) + +(define_expand "vec_unpacks_hi_v4sf" + [(set (match_operand:V2DF 0 "register_operand" "=f") + (float_extend:V2DF + (vec_select:V2SF + (match_operand:V4SF 1 "register_operand" "f") + (parallel [(const_int 0) (const_int 1)]) + )))] + "ISA_HAS_MSA" + { + if (BYTES_BIG_ENDIAN) + emit_insn (gen_msa_fexupr_d (operands[0], operands[1])); + else + emit_insn (gen_msa_fexupl_d (operands[0], operands[1])); + DONE; + }) + +(define_expand "vec_unpacks_lo_v4sf" + [(set (match_operand:V2DF 0 "register_operand" "=f") + (float_extend:V2DF + (vec_select:V2SF + (match_operand:V4SF 1 "register_operand" "f") + (parallel [(const_int 0) (const_int 1)]) + )))] + "ISA_HAS_MSA" + { + if (BYTES_BIG_ENDIAN) + emit_insn (gen_msa_fexupl_d (operands[0], operands[1])); + else + emit_insn (gen_msa_fexupr_d (operands[0], operands[1])); + DONE; + }) + +(define_expand "vec_unpacks_hi_<mode>" + [(set (match_operand:<VDMODE> 0 "register_operand") + (match_operand:IMSA_X2 1 "register_operand"))] + "ISA_HAS_MSA" + { + mips_expand_vec_unpack (operands, false/*unsigned_p*/, true/*high_p*/); + DONE; + }) + +(define_expand "vec_unpacks_lo_<mode>" + [(set (match_operand:<VDMODE> 0 "register_operand") + (match_operand:IMSA_X2 1 "register_operand"))] + "ISA_HAS_MSA" + { + mips_expand_vec_unpack (operands, false/*unsigned_p*/, false/*high_p*/); + DONE; + }) + +(define_expand "vec_unpacku_hi_<mode>" + [(set (match_operand:<VDMODE> 0 "register_operand") + (match_operand:IMSA_X2 1 "register_operand"))] + "ISA_HAS_MSA" + { + mips_expand_vec_unpack (operands, true/*unsigned_p*/, true/*high_p*/); + DONE; + }) + +(define_expand "vec_unpacku_lo_<mode>" + [(set (match_operand:<VDMODE> 0 "register_operand") + (match_operand:IMSA_X2 1 "register_operand"))] + "ISA_HAS_MSA" + { + mips_expand_vec_unpack (operands, true/*unsigned_p*/, false/*high_p*/); + DONE; + }) + (define_expand "vec_extract<mode>" [(match_operand:<UNITMODE> 0 "register_operand") (match_operand:IMSA 1 "register_operand") @@ -358,12 +473,12 @@ (define_expand "vec_set<mode>" [(match_operand:IMSA 0 "register_operand") - (match_operand:<UNITMODE> 1 "register_operand") + (match_operand:<UNITMODE> 1 "reg_or_0_operand") (match_operand 2 "const_<indeximm>_operand")] "ISA_HAS_MSA" { - emit_insn (gen_msa_insert_<msafmt> (operands[0], operands[0], operands[2], - operands[1])); + emit_insn (gen_msa_insert_<msafmt>_insn (operands[0], operands[1], + operands[0], GEN_INT(1 << INTVAL (operands[2])))); DONE; }) @@ -373,8 +488,8 @@ (match_operand 2 "const_<indeximm>_operand")] "ISA_HAS_MSA" { - emit_insn (gen_msa_insve_<msafmt_f>_s (operands[0], operands[0], operands[2], - operands[1])); + emit_insn (gen_msa_insve_<msafmt_f>_s (operands[0], operands[0], + GEN_INT(1 << INTVAL (operands[2])), operands[1])); DONE; }) @@ -391,7 +506,7 @@ == GET_MODE_NUNITS (<IMSA:MODE>mode))" { mips_expand_vec_cond_expr (<MSA_2:MODE>mode, - <MSA_2:VIMODE>mode, + <MSA_2:VIMODE>mode, operands, gen_and<MSA_2:mode_i>3, gen_msa_nor_v_<MSA_2:msafmt>, @@ -420,58 +535,93 @@ DONE; }) -(define_insn "msa_insert_<msafmt>" +;; Note used directly by builtins but via the following define_expand. +(define_insn "msa_insert_<msafmt>_insn" [(set (match_operand:IMSA 0 "register_operand" "=f") - (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "0") - (match_operand 2 "const_<indeximm>_operand" "") - (match_operand:<REGOR0> 3 "reg_or_0_operand" "dJ")] - UNSPEC_MSA_INSERT))] + (vec_merge:IMSA (vec_duplicate:IMSA + (match_operand:<UNITMODE> 1 "reg_or_0_operand" "dJ")) + (match_operand:IMSA 2 "register_operand" "0") + (match_operand 3 "const_<bitmask>_operand" "")))] "ISA_HAS_MSA" - "insert.<msafmt>\t%w0[%2],%z3" - [(set_attr "type" "mtc") - (set_attr "mode" "TI") + "insert.<msafmt>\t%w0[%K3],%z1" + [(set_attr "type" "mtc") + (set_attr "mode" "TI") (set_attr "msa_execunit" "msa_eu_logic_l")]) -; Similar to msa_insert_<msafmt> but with <UNITMODE>mode for operand 3. -;; Note that insert.d and insert.d_f will be split later if !TARGET_64BIT. +;; Expand builtin catoring for HImode and QImode which take SImode. +(define_expand "msa_insert_<msafmt>" + [(match_operand:IMSA 0 "register_operand") + (match_operand:IMSA 1 "register_operand") + (match_operand 2 "const_<indeximm>_operand") + (match_operand:<EXCEPT> 3 "reg_or_0_operand")] + "ISA_HAS_MSA" +{ + if ((GET_MODE_SIZE (<UNITMODE>mode) < GET_MODE_SIZE (<EXCEPT>mode)) + && (REG_P (operands[3]) || (GET_CODE (operands[3]) == SUBREG + && REG_P (SUBREG_REG (operands[3]))))) + { + unsigned int offset = GET_MODE_SIZE (<EXCEPT>mode) + - GET_MODE_SIZE (<UNITMODE>mode); + operands[3] = simplify_gen_subreg (<UNITMODE>mode, operands[3], + GET_MODE (operands[3]), + BYTES_BIG_ENDIAN ? offset : 0); + } + emit_insn (gen_msa_insert_<msafmt>_insn (operands[0], operands[3], + operands[1], GEN_INT(1 << INTVAL (operands[2])))); + DONE; +}) + +(define_expand "msa_insert_<msafmt_f>" + [(match_operand:FMSA 0 "register_operand") + (match_operand:FMSA 1 "register_operand") + (match_operand 2 "const_<indeximm>_operand") + (match_operand:<UNITMODE> 3 "reg_or_0_operand")] + "ISA_HAS_MSA" +{ + emit_insn (gen_msa_insert_<msafmt_f>_insn (operands[0], operands[3], + operands[1], GEN_INT(1 << INTVAL (operands[2])))); + DONE; +}) -(define_insn "*msa_insert_<msafmt_f>" - [(set (match_operand:MSA_3 0 "register_operand" "=f") - (unspec:MSA_3 [(match_operand:MSA_3 1 "register_operand" "0") - (match_operand 2 "const_<indeximm>_operand" "") - (match_operand:<UNITMODE> 3 "reg_or_0_operand" "dJ")] - UNSPEC_MSA_INSERT))] +(define_insn "msa_insert_<msafmt_f>_insn" + [(set (match_operand:FMSA 0 "register_operand" "=f") + (vec_merge:FMSA (vec_duplicate:FMSA + (match_operand:<UNITMODE> 1 "register_operand" "d")) + (match_operand:FMSA 2 "register_operand" "0") + (match_operand 3 "const_<bitmask>_operand" "")))] "ISA_HAS_MSA" - "insert.<msafmt>\t%w0[%2],%z3" + "insert.<msafmt>\t%w0[%K3],%z1" [(set_attr "type" "mtc") (set_attr "mode" "TI") (set_attr "msa_execunit" "msa_eu_logic_l")]) (define_split [(set (match_operand:SPLIT 0 "register_operand") - (unspec:SPLIT [(match_operand:SPLIT 1 "register_operand") - (match_operand 2 "const_0_or_1_operand") - (match_operand:<UNITMODE> 3 "<SPLIT:predicate>_operand")] - UNSPEC_MSA_INSERT))] + (vec_merge:SPLIT + (vec_duplicate:SPLIT + (match_operand:<UNITMODE> 1 "<SPLIT:predicate>_operand")) + (match_operand:SPLIT 2 "register_operand") + (match_operand 3 "const_<bitmask>_operand")))] "reload_completed && TARGET_MSA && !TARGET_64BIT" [(const_int 0)] { - mips_split_msa_insert_d (operands[0], operands[1], operands[2], operands[3]); + mips_split_msa_insert_d (operands[0], operands[2], operands[3], operands[1]); DONE; }) ;; Used by combine to convert a copy_s + insert into an insve (define_insn "msa_insve_s_insn_<msafmt>" [(set (match_operand:INSVE 0 "register_operand" "=f") - (unspec:INSVE [(match_operand:INSVE 1 "register_operand" "0") - (match_operand 2 "const_<indeximm>_operand" "") - (unspec:<RES> - [(match_operand:INSVE 3 "register_operand" "f") - (match_operand 4 "const_0_operand" "") - ] UNSPEC_MSA_COPY_S) - ] UNSPEC_MSA_INSERT))] + (vec_merge:INSVE + (vec_duplicate:INSVE + (sign_extend:<UNITMODE> + (vec_select:<UNITMODE> + (match_operand:INSVE 3 "register_operand" "f") + (parallel [(match_operand 4 "const_0_operand" "")])))) + (match_operand:INSVE 1 "register_operand" "0") + (match_operand 2 "const_<bitmask>_operand" "")))] "ISA_HAS_MSA" - "insve.<msafmt>\t%w0[%2],%w3[0]" + "insve.<msafmt>\t%w0[%K2],%w3[0]" [(set_attr "type" "arith") (set_attr "mode" "TI") (set_attr "msa_execunit" "msa_eu_logic_l")]) @@ -479,15 +629,16 @@ ;; Used by combine to convert a copy_u + insert into an insve (define_insn "msa_insve_u_insn_<msafmt>" [(set (match_operand:INSVE 0 "register_operand" "=f") - (unspec:INSVE [(match_operand:INSVE 1 "register_operand" "0") - (match_operand 2 "const_<indeximm>_operand" "") - (unspec:<RES> - [(match_operand:INSVE 3 "register_operand" "f") - (match_operand 4 "const_0_operand" "") - ] UNSPEC_MSA_COPY_U) - ] UNSPEC_MSA_INSERT))] + (vec_merge:INSVE + (vec_duplicate:INSVE + (zero_extend:<UNITMODE> + (vec_select:<UNITMODE> + (match_operand:INSVE 3 "register_operand" "f") + (parallel [(match_operand 4 "const_0_operand" "")])))) + (match_operand:INSVE 1 "register_operand" "0") + (match_operand 2 "const_<bitmask>_operand" "")))] "ISA_HAS_MSA" - "insve.<msafmt>\t%w0[%2],%w3[0]" + "insve.<msafmt>\t%w0[%K2],%w3[0]" [(set_attr "type" "arith") (set_attr "mode" "TI") (set_attr "msa_execunit" "msa_eu_logic_l")]) @@ -495,16 +646,17 @@ ;; Used by combine to convert a copy_s + insert with subreg into an insve (define_insn "*msa_insve_sext_insn_<msafmt>" [(set (match_operand:INSVE_2 0 "register_operand" "=f") - (unspec:INSVE_2 [(match_operand:INSVE_2 1 "register_operand" "0") - (match_operand 2 "const_<indeximm>_operand" "") - (subreg:<UNITMODE> - (unspec:<RES> - [(match_operand:INSVE_2 3 "register_operand" "f") - (match_operand 4 "const_0_operand" "") - ] UNSPEC_MSA_COPY_S) 0) - ] UNSPEC_MSA_INSERT))] + (vec_merge:INSVE_2 + (vec_duplicate:INSVE_2 + (subreg:<UNITMODE> + (sign_extend:<RES> + (vec_select:<UNITMODE> + (match_operand:INSVE_2 3 "register_operand" "f") + (parallel [(match_operand 4 "const_0_operand" "")]))) 0)) + (match_operand:INSVE_2 1 "register_operand" "0") + (match_operand 2 "const_<bitmask>_operand" "")))] "ISA_HAS_MSA" - "insve.<msafmt>\t%w0[%2],%w3[0]" + "insve.<msafmt>\t%w0[%K2],%w3[0]" [(set_attr "type" "arith") (set_attr "mode" "TI") (set_attr "msa_execunit" "msa_eu_logic_l")]) @@ -512,28 +664,44 @@ ;; Used by combine to convert a copy_u + insert with subreg into an insve (define_insn "*msa_insve_zext_insn_<msafmt>" [(set (match_operand:INSVE_2 0 "register_operand" "=f") - (unspec:INSVE_2 [(match_operand:INSVE_2 1 "register_operand" "0") - (match_operand 2 "const_<indeximm>_operand" "") - (subreg:<UNITMODE> - (unspec:<RES> - [(match_operand:INSVE_2 3 "register_operand" "f") - (match_operand 4 "const_0_operand" "") - ] UNSPEC_MSA_COPY_U) 0) - ] UNSPEC_MSA_INSERT))] + (vec_merge:INSVE_2 + (vec_duplicate:INSVE_2 + (subreg:<UNITMODE> + (zero_extend:<RES> + (vec_select:<RES> + (match_operand:INSVE_2 3 "register_operand" "f") + (parallel [(match_operand 4 "const_0_operand" "")]))) 0)) + (match_operand:INSVE_2 1 "register_operand" "0") + (match_operand 2 "const_<bitmask>_operand" "")))] "ISA_HAS_MSA" - "insve.<msafmt>\t%w0[%2],%w3[%4]" + "insve.<msafmt>\t%w0[%K2],%w3[0]" [(set_attr "type" "arith") (set_attr "mode" "TI") (set_attr "msa_execunit" "msa_eu_logic_l")]) -(define_insn "msa_insve_<msafmt_f>" - [(set (match_operand:MSA 0 "register_operand" "=f") - (unspec:MSA [(match_operand:MSA 1 "register_operand" "0") - (match_operand 2 "const_<indeximm>_operand" "") - (match_operand:MSA 3 "register_operand" "f")] - UNSPEC_MSA_INSVE))] +(define_expand "msa_insve_<msafmt_f>" + [(set (match_operand:MSA 0 "register_operand") + (vec_merge:MSA (vec_duplicate:MSA + (vec_select:<UNITMODE> + (match_operand:MSA 3 "register_operand") + (parallel [(const_int 0)]))) + (match_operand:MSA 1 "register_operand") + (match_operand 2 "const_<indeximm>_operand")))] "ISA_HAS_MSA" - "insve.<msafmt>\t%w0[%2],%w3[0]" + { + operands[2] = GEN_INT ((1 << INTVAL (operands[2]))); + }) + +(define_insn "msa_insve_<msafmt_f>_insn" + [(set (match_operand:MSA 0 "register_operand" "=f") + (vec_merge:MSA (vec_duplicate:MSA + (vec_select:<UNITMODE> + (match_operand:MSA 3 "register_operand" "f") + (parallel [(const_int 0)]))) + (match_operand:MSA 1 "register_operand" "0") + (match_operand 2 "const_<bitmask>_operand" "")))] + "ISA_HAS_MSA" + "insve.<msafmt>\t%w0[%K2],%w3[0]" [(set_attr "type" "arith") (set_attr "mode" "TI") (set_attr "msa_execunit" "msa_eu_logic_l")]) @@ -541,12 +709,12 @@ ;; operand 3 is a scalar (define_insn "msa_insve_<msafmt>_f_s" [(set (match_operand:FMSA 0 "register_operand" "=f") - (unspec:FMSA [(match_operand:FMSA 1 "register_operand" "0") - (match_operand 2 "const_<indeximm>_operand" "") - (match_operand:<UNITMODE> 3 "register_operand" "f")] - UNSPEC_MSA_INSVE))] + (vec_merge:FMSA (vec_duplicate:FMSA + (match_operand:<UNITMODE> 3 "register_operand" "f")) + (match_operand:FMSA 1 "register_operand" "0") + (match_operand 2 "const_<bitmask>_operand" "")))] "ISA_HAS_MSA" - "insve.<msafmt>\t%w0[%2],%w3[0]" + "insve.<msafmt>\t%w0[%K2],%w3[0]" [(set_attr "type" "arith") (set_attr "mode" "TI") (set_attr "msa_execunit" "msa_eu_logic_l")]) @@ -554,9 +722,10 @@ ;; Note that copy_s.d and copy_s.d_f will be split later if !TARGET_64BIT. (define_insn "msa_copy_s_<msafmt_f>" [(set (match_operand:<RES> 0 "register_operand" "=d") - (unspec:<RES> [(match_operand:MSA 1 "register_operand" "f") - (match_operand 2 "const_<indeximm>_operand" "")] - UNSPEC_MSA_COPY_S))] + (sign_extend:<RES> + (vec_select:<UNITMODE> + (match_operand:MSA 1 "register_operand" "f") + (parallel [(match_operand 2 "const_<indeximm>_operand" "")]))))] "ISA_HAS_MSA" "copy_s.<msafmt>\t%0,%w1[%2]" [(set_attr "type" "mfc") @@ -565,9 +734,10 @@ (define_split [(set (match_operand:<UNITMODE> 0 "register_operand") - (unspec:<UNITMODE> [(match_operand:SPLIT 1 "register_operand") - (match_operand 2 "const_0_or_1_operand")] - UNSPEC_MSA_COPY_S))] + (sign_extend:<UNITMODE> + (vec_select:<UNITMODE> + (match_operand:SPLIT 1 "register_operand") + (parallel [(match_operand 2 "const_0_or_1_operand")]))))] "reload_completed && TARGET_MSA && !TARGET_64BIT" [(const_int 0)] { @@ -578,9 +748,10 @@ ;; Note that copy_u.d and copy_u.d_f will be split later if !TARGET_64BIT. (define_insn "msa_copy_u_<msafmt_f>" [(set (match_operand:<RES> 0 "register_operand" "=d") - (unspec:<RES> [(match_operand:MSA 1 "register_operand" "f") - (match_operand 2 "const_<indeximm>_operand" "")] - UNSPEC_MSA_COPY_U))] + (zero_extend:<RES> + (vec_select:<UNITMODE> + (match_operand:MSA 1 "register_operand" "f") + (parallel [(match_operand 2 "const_<indeximm>_operand" "")]))))] "ISA_HAS_MSA" "copy_u.<msafmt>\t%0,%w1[%2]" [(set_attr "type" "mfc") @@ -589,9 +760,10 @@ (define_split [(set (match_operand:<UNITMODE> 0 "register_operand") - (unspec:<UNITMODE> [(match_operand:SPLIT 1 "register_operand") - (match_operand 2 "const_0_or_1_operand")] - UNSPEC_MSA_COPY_U))] + (zero_extend:<UNITMODE> + (vec_select:<UNITMODE> + (match_operand:SPLIT 1 "register_operand") + (parallel [(match_operand 2 "const_0_or_1_operand")]))))] "reload_completed && TARGET_MSA && !TARGET_64BIT" [(const_int 0)] { @@ -608,14 +780,38 @@ { /* The optab semantics are that index 0 selects the first element of operands[1] and the highest index selects the last element - of operands[2]. This is the oppossite order from "vshf.df wd,rs,wt" - where index 0 selects the first elemnt of wt and the highest index - selects the last element of ws. We therefore swap the operands here. */ + of operands[2]. This is the oppossite order from "vshf.df wd,rs,wt" + where index 0 selects the first element of wt and the highest index + selects the last element of ws. We therefore swap the operands here. */ emit_insn (gen_msa_vshf<mode> (operands[0], operands[3], operands[2], operands[1])); DONE; }) +(define_expand "vec_perm_const<mode>" + [(match_operand:MSA 0 "register_operand") + (match_operand:MSA 1 "register_operand") + (match_operand:MSA 2 "register_operand") + (match_operand:<VIMODE> 3 "")] + "ISA_HAS_MSA" +{ + if (mips_expand_vec_perm_const (operands)) + DONE; + else + FAIL; +}) + +(define_expand "abs<mode>2" + [(set (match_operand:IMSA 0 "register_operand" "=f") + (abs:IMSA (match_operand:IMSA 1 "register_operand" "f")))] + "ISA_HAS_MSA" +{ + rtx reg = gen_reg_rtx (<MODE>mode); + emit_insn (gen_msa_ldi<mode> (reg, const0_rtx)); + emit_insn (gen_msa_add_a_<msafmt> (operands[0], operands[1], reg)); + DONE; +}) + (define_expand "neg<mode>2" [(match_operand:IMSA 0 "register_operand") (match_operand:IMSA 1 "register_operand")] @@ -633,23 +829,11 @@ "ISA_HAS_MSA" { rtx reg = gen_reg_rtx (<MODE>mode); - emit_insn (gen_msa_ld0<mode> (reg, const0_rtx)); + emit_move_insn (reg, CONST0_RTX (<MODE>mode)); emit_insn (gen_sub<mode>3 (operands[0], reg, operands[1])); DONE; }) -(define_insn "msa_ldi<mode>_insn" - [(set (match_operand:IMSA 0 "register_operand" "=f") - (match_operand:IMSA 1 "const_vector_same_simm10_operand" ""))] - "ISA_HAS_MSA" - { - operands[1] = CONST_VECTOR_ELT (operands[1], 0); - return "ldi.<msafmt>\t%w0,%d1"; - } - [(set_attr "type" "arith") - (set_attr "mode" "TI") - (set_attr "msa_execunit" "msa_eu_logic")]) - (define_expand "msa_ldi<mode>" [(match_operand:IMSA 0 "register_operand") (match_operand 1 "const_imm10_operand")] @@ -669,32 +853,12 @@ val = trunc_int_for_mode (val, <UNITMODE>mode); for (i = 0; i < n_elts; i++) - RTVEC_ELT (v, i) = GEN_INT (val); - emit_insn (gen_msa_ldi<mode>_insn (operands[0], - gen_rtx_CONST_VECTOR (<MODE>mode, v))); + RTVEC_ELT (v, i) = GEN_INT (val); + emit_move_insn (operands[0], + gen_rtx_CONST_VECTOR (<MODE>mode, v)); DONE; }) -(define_insn "msa_ld0<mode>" - [(set (match_operand:FMSA 0 "register_operand" "=f") - (unspec:FMSA [(match_operand 1 "const_0_operand" "")] - UNSPEC_MSA_LD0))] - "ISA_HAS_MSA" - "ldi.<msafmt>\t%w0,%d1" - [(set_attr "type" "arith") - (set_attr "mode" "TI") - (set_attr "msa_execunit" "msa_eu_logic")]) - -(define_insn "msa_lsa" - [(set (match_operand:SI 0 "register_operand" "=d") - (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d") - (match_operand:SI 2 "const_immlsa_operand" "")) - (match_operand:SI 3 "register_operand" "d")))] - "ISA_HAS_LSA" - "lsa\t%0,%1,%3,%y2" - [(set_attr "type" "arith") - (set_attr "mode" "SI")]) - (define_insn "msa_vshf<mode>" [(set (match_operand:MSA 0 "register_operand" "=f") (unspec:MSA [(match_operand:<VIMODE> 1 "register_operand" "0") @@ -705,83 +869,38 @@ "vshf.<msafmt>\t%w0,%w2,%w3" [(set_attr "type" "arith") (set_attr "mode" "TI") - (set_attr "msa_execunit" "msa_eu_logic_l")]) - -;; 128-bit integer/MSA vector registers moves -;; Note that we prefer floating-point loads, stores, and moves by adding * to -;; other register preferences. -;; Note that we combine f and J, so that move_type for J is fmove and its -;; instruction length can be 1. -(define_insn "movti_msa" - [(set (match_operand:TI 0 "nonimmediate_operand" "=*d,*d,*d,*R,*d,*f,f,R,f,*m,*d,*m,*f") - (match_operand:TI 1 "move_operand" "*d,*i,*R,*d*J,*f,*d,R,f,fJ,*d*J,*m,*f,*m"))] - "ISA_HAS_MSA - && !TARGET_64BIT - && (register_operand (operands[0], TImode) - || reg_or_0_operand (operands[1], TImode))" - { return mips_output_move (operands[0], operands[1]); } - [(set_attr "move_type" "move,const,load,store,mfc,mtc,fpload,fpstore,fmove,store,load,fpstore,fpload") - (set_attr "mode" "TI")]) - -;; Note that we prefer floating-point loads, stores, and moves by adding * to -;; other register preferences. -;; Note that we combine f and J, so that move_type for J is fmove and its -;; instruction length can be 1. -(define_insn "movti_msa_64bit" - [(set (match_operand:TI 0 "nonimmediate_operand" "=*d,*d,*d,*R,*a,*d,*d,*f,f,R,f,*m,*d,*m,*f") - (match_operand:TI 1 "move_operand" "*d,*i,*R,*d*J,*d*J,*a,*f,*d,R,f,fJ,*d*J,*m,*f,*m"))] - "ISA_HAS_MSA - && TARGET_64BIT - && (register_operand (operands[0], TImode) - || reg_or_0_operand (operands[1], TImode))" - { return mips_output_move (operands[0], operands[1]); } - [(set_attr "move_type" "move,const,load,store,mtlo,mflo,mfc,mtc,fpload,fpstore,fmove,store,load,fpstore,fpload") - (set_attr "mode" "TI")]) + (set (attr "msa_execunit") + (if_then_else (eq_attr "cpu" "i6400") + (const_string "msa_eu_logic_l2") + (const_string "msa_eu_logic_l")))]) (define_expand "mov<mode>" - [(set (match_operand:MODE128 0) - (match_operand:MODE128 1))] - "TARGET_64BIT || TARGET_MSA" + [(set (match_operand:MSA 0) + (match_operand:MSA 1))] + "TARGET_MSA" { if (mips_legitimize_move (<MODE>mode, operands[0], operands[1])) DONE; }) (define_expand "movmisalign<mode>" - [(set (match_operand:MODE128 0) - (match_operand:MODE128 1))] - "TARGET_64BIT || TARGET_MSA" + [(set (match_operand:MSA 0) + (match_operand:MSA 1))] + "TARGET_MSA" { if (mips_legitimize_move (<MODE>mode, operands[0], operands[1])) DONE; }) -;; 128bit MSA modes only in msa registers or memmory -;; an exception is allowing MSA modes for GP registers for arguments -;; and return values. +;; 128bit MSA modes only in msa registers or memory. An exception is allowing +;; MSA modes for GP registers for arguments and return values. (define_insn "mov<mode>_msa" - [(set (match_operand:MODE128 0 "nonimmediate_operand" "=f,f,R,!d,f") - (match_operand:MODE128 1 "move_operand" "fYG,R,f,f,!d"))] - "ISA_HAS_MSA - && (register_operand (operands[0], <MODE>mode) - || reg_or_0_operand (operands[1], <MODE>mode))" + [(set (match_operand:MSA 0 "nonimmediate_operand" "=f,f,R,*d,*f") + (match_operand:MSA 1 "move_operand" "fYGYI,R,f,*f,*d"))] + "TARGET_MSA" { return mips_output_move (operands[0], operands[1]); } - [(set_attr "move_type" "fmove,fpload,fpstore,fmove,fmove") - (set_attr "mode" "TI")]) - -(define_split - [(set (match_operand:TI 0 "nonimmediate_operand") - (match_operand:TI 1 "move_operand"))] - "reload_completed && TARGET_MSA - && mips_split_move_insn_p (operands[0], operands[1], insn)" - [(const_int 0)] -{ - /* Temporary sanity check */ - gcc_assert (mips_split_128bit_move_p (operands[0], operands[1])); - gcc_assert (mips_split_move_insn_p (operands[0], operands[1], curr_insn)); - mips_split_move_insn (operands[0], operands[1], curr_insn); - DONE; -}) + [(set_attr "move_type" "fmove,fpload,fpstore,mfc,mtc") + (set_attr "mode" "TI")]) (define_split [(set (match_operand:MSA 0 "nonimmediate_operand") @@ -790,8 +909,6 @@ && mips_split_move_insn_p (operands[0], operands[1], insn)" [(const_int 0)] { - /* Temporary sanity check */ - gcc_assert (mips_split_128bit_move_p (operands[0], operands[1])); mips_split_move_insn (operands[0], operands[1], curr_insn); DONE; }) @@ -851,8 +968,9 @@ gcc_unreachable (); } } - [(set_attr "alu_type" "add") + [(set_attr "alu_type" "add, unknown, unknown") (set_attr "mode" "TI") + (set_attr "datafmt" "<msafmt>") (set_attr "msa_execunit" "msa_eu_int_add")]) (define_insn "sub<mode>3" @@ -883,8 +1001,9 @@ gcc_unreachable (); } } - [(set_attr "alu_type" "sub") + [(set_attr "alu_type" "sub, unknown, unknown") (set_attr "mode" "TI") + (set_attr "datafmt" "<msafmt>") (set_attr "msa_execunit" "msa_eu_int_add")]) (define_insn "mul<mode>3" @@ -927,6 +1046,7 @@ { return mips_msa_output_division ("div_s.<msafmt>\t%w0,%w1,%w2", operands); } [(set_attr "type" "idiv3") (set_attr "mode" "TI") + (set_attr "datafmt" "<msafmt>") (set_attr "msa_execunit" "msa_eu_div")]) (define_insn "udiv<mode>3" @@ -937,6 +1057,7 @@ { return mips_msa_output_division ("div_u.<msafmt>\t%w0,%w1,%w2", operands); } [(set_attr "type" "idiv3") (set_attr "mode" "TI") + (set_attr "datafmt" "<msafmt>") (set_attr "msa_execunit" "msa_eu_div")]) (define_insn "mod<mode>3" @@ -947,6 +1068,7 @@ { return mips_msa_output_division ("mod_s.<msafmt>\t%w0,%w1,%w2", operands); } [(set_attr "type" "idiv3") (set_attr "mode" "TI") + (set_attr "datafmt" "<msafmt>") (set_attr "msa_execunit" "msa_eu_div")]) (define_insn "umod<mode>3" @@ -957,6 +1079,7 @@ { return mips_msa_output_division ("mod_u.<msafmt>\t%w0,%w1,%w2", operands); } [(set_attr "type" "idiv3") (set_attr "mode" "TI") + (set_attr "datafmt" "<msafmt>") (set_attr "msa_execunit" "msa_eu_div")]) (define_insn "xorv16qi3" @@ -996,7 +1119,11 @@ } [(set_attr "alu_type" "xor") (set_attr "mode" "TI") - (set_attr "msa_execunit" "msa_eu_logic")]) + (set (attr "msa_execunit") + (if_then_else (and (eq_attr "cpu" "i6400") + (eq_attr "alternative" "1")) + (const_string "msa_eu_logic2") + (const_string "msa_eu_logic")))]) (define_insn "iorv16qi3" [(set (match_operand:V16QI 0 "register_operand" "=f,f") @@ -1035,7 +1162,11 @@ } [(set_attr "alu_type" "or") (set_attr "mode" "TI") - (set_attr "msa_execunit" "msa_eu_logic")]) + (set (attr "msa_execunit") + (if_then_else (and (eq_attr "cpu" "i6400") + (eq_attr "alternative" "1")) + (const_string "msa_eu_logic2") + (const_string "msa_eu_logic")))]) (define_insn "andv16qi3" [(set (match_operand:V16QI 0 "register_operand" "=f,f") @@ -1046,7 +1177,7 @@ if (which_alternative == 1) { operands[2] = CONST_VECTOR_ELT (operands[2], 0); - return "andi.b\t%w0,%w0,%B2"; + return "andi.b\t%w0,%w1,%B2"; } else return "and.v\t%w0,%w1,%w2"; @@ -1074,7 +1205,11 @@ } [(set_attr "alu_type" "and") (set_attr "mode" "TI") - (set_attr "msa_execunit" "msa_eu_logic")]) + (set (attr "msa_execunit") + (if_then_else (and (eq_attr "cpu" "i6400") + (eq_attr "alternative" "1")) + (const_string "msa_eu_logic2") + (const_string "msa_eu_logic")))]) (define_insn "one_cmpl<mode>2" [(set (match_operand:IMSA 0 "register_operand" "=f") @@ -1087,8 +1222,8 @@ (define_insn "vlshr<mode>3" [(set (match_operand:IMSA 0 "register_operand" "=f,f") - (lshiftrt:<MODE> (match_operand:<MODE> 1 "register_operand" "f,f") - (match_operand:<MODE> 2 "reg_or_vector_same_uimm6_operand" "f,Uuv6")))] + (lshiftrt:IMSA (match_operand:IMSA 1 "register_operand" "f,f") + (match_operand:IMSA 2 "reg_or_vector_same_uimm6_operand" "f,Uuv6")))] "ISA_HAS_MSA" { if (which_alternative == 0) @@ -1100,7 +1235,10 @@ } [(set_attr "type" "shift") (set_attr "mode" "TI") - (set_attr "msa_execunit" "msa_eu_logic")]) + (set (attr "msa_execunit") + (if_then_else (eq_attr "cpu" "i6400") + (const_string "msa_eu_logic2") + (const_string "msa_eu_logic")))]) (define_insn "vashr<mode>3" [(set (match_operand:IMSA 0 "register_operand" "=f,f") @@ -1117,7 +1255,10 @@ } [(set_attr "type" "shift") (set_attr "mode" "TI") - (set_attr "msa_execunit" "msa_eu_logic")]) + (set (attr "msa_execunit") + (if_then_else (eq_attr "cpu" "i6400") + (const_string "msa_eu_logic2") + (const_string "msa_eu_logic")))]) (define_insn "vashl<mode>3" [(set (match_operand:IMSA 0 "register_operand" "=f,f") @@ -1134,7 +1275,10 @@ } [(set_attr "type" "shift") (set_attr "mode" "TI") - (set_attr "msa_execunit" "msa_eu_logic")]) + (set (attr "msa_execunit") + (if_then_else (eq_attr "cpu" "i6400") + (const_string "msa_eu_logic2") + (const_string "msa_eu_logic")))]) ;; Floating-point operations (define_insn "add<mode>3" @@ -1249,24 +1393,59 @@ (set_attr "mode" "TI") (set_attr "msa_execunit" "msa_eu_int_add")]) -(define_insn "msa_addvi_<msafmt>" +(define_expand "msa_addvi_<msafmt>" + [(set (match_operand:IMSA 0 "register_operand") + (plus:IMSA (match_operand:IMSA 1 "register_operand") + (match_operand 2 "const_uimm5_operand")))] + "ISA_HAS_MSA" + { + unsigned n_elts = GET_MODE_NUNITS (<MODE>mode); + rtvec v = rtvec_alloc (n_elts); + HOST_WIDE_INT val = INTVAL (operands[2]); + unsigned int i; + + for (i = 0; i < n_elts; i++) + RTVEC_ELT (v, i) = GEN_INT (val); + + emit_insn (gen_msa_addvi_<msafmt>_insn (operands[0], operands[1], + gen_rtx_CONST_VECTOR (<MODE>mode, v))); + DONE; + }) + +(define_expand "msa_andi_b" + [(set (match_operand:V16QI 0 "register_operand") + (and:V16QI (match_operand:V16QI 1 "register_operand") + (match_operand:QI 2 "const_uimm8_operand")))] + "ISA_HAS_MSA" + { + rtvec v = rtvec_alloc (16); + HOST_WIDE_INT val = INTVAL (operands[2]); + unsigned int i; + + for (i = 0; i < 16; i++) + RTVEC_ELT (v, i) = GEN_INT (val); + + emit_insn (gen_msa_andi_b_insn (operands[0], operands[1], + gen_rtx_CONST_VECTOR (V16QImode, v))); + DONE; + }) + +(define_insn "msa_addvi_<msafmt>_insn" [(set (match_operand:IMSA 0 "register_operand" "=f") - (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f") - (match_operand 2 "const_uimm5_operand" "")] - UNSPEC_MSA_ADDVI))] + (plus:IMSA (match_operand:IMSA 1 "register_operand" "f") + (match_operand:IMSA 2 "const_vector_same_uimm5_operand" "")))] "ISA_HAS_MSA" - "addvi.<msafmt>\t%w0,%w1,%2" + "addvi.<msafmt>\t%w0,%w1,%E2" [(set_attr "type" "arith") (set_attr "mode" "TI") (set_attr "msa_execunit" "msa_eu_int_add")]) -(define_insn "msa_andi_b" +(define_insn "msa_andi_b_insn" [(set (match_operand:V16QI 0 "register_operand" "=f") - (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "f") - (match_operand 2 "const_uimm8_operand" "")] - UNSPEC_MSA_ANDI_B))] + (and:V16QI (match_operand:V16QI 1 "register_operand" "f") + (match_operand:V16QI 2 "const_vector_same_uimm8_operand" "")))] "ISA_HAS_MSA" - "andi.b\t%w0,%w1,%2" + "andi.b\t%w0,%w1,%E2" [(set_attr "type" "arith") (set_attr "mode" "TI") (set_attr "msa_execunit" "msa_eu_logic")]) @@ -1346,7 +1525,10 @@ "bclr.<msafmt>\t%w0,%w1,%w2" [(set_attr "type" "arith") (set_attr "mode" "TI") - (set_attr "msa_execunit" "msa_eu_logic")]) + (set (attr "msa_execunit") + (if_then_else (eq_attr "cpu" "i6400") + (const_string "msa_eu_logic2") + (const_string "msa_eu_logic")))]) (define_insn "msa_bclri_<msafmt>" [(set (match_operand:IMSA 0 "register_operand" "=f") @@ -1357,7 +1539,10 @@ "bclri.<msafmt>\t%w0,%w1,%2" [(set_attr "type" "arith") (set_attr "mode" "TI") - (set_attr "msa_execunit" "msa_eu_logic")]) + (set (attr "msa_execunit") + (if_then_else (eq_attr "cpu" "i6400") + (const_string "msa_eu_logic2") + (const_string "msa_eu_logic")))]) (define_insn "msa_binsl_<msafmt>" [(set (match_operand:IMSA 0 "register_operand" "=f") @@ -1369,7 +1554,10 @@ "binsl.<msafmt>\t%w0,%w2,%w3" [(set_attr "type" "arith") (set_attr "mode" "TI") - (set_attr "msa_execunit" "msa_eu_logic_l")]) + (set (attr "msa_execunit") + (if_then_else (eq_attr "cpu" "i6400") + (const_string "msa_eu_logic_l2") + (const_string "msa_eu_logic_l")))]) (define_insn "msa_binsli_<msafmt>" [(set (match_operand:IMSA 0 "register_operand" "=f") @@ -1381,7 +1569,10 @@ "binsli.<msafmt>\t%w0,%w2,%3" [(set_attr "type" "arith") (set_attr "mode" "TI") - (set_attr "msa_execunit" "msa_eu_logic_l")]) + (set (attr "msa_execunit") + (if_then_else (eq_attr "cpu" "i6400") + (const_string "msa_eu_logic_l2") + (const_string "msa_eu_logic_l")))]) (define_insn "msa_binsr_<msafmt>" [(set (match_operand:IMSA 0 "register_operand" "=f") @@ -1393,7 +1584,10 @@ "binsr.<msafmt>\t%w0,%w2,%w3" [(set_attr "type" "arith") (set_attr "mode" "TI") - (set_attr "msa_execunit" "msa_eu_logic_l")]) + (set (attr "msa_execunit") + (if_then_else (eq_attr "cpu" "i6400") + (const_string "msa_eu_logic_l2") + (const_string "msa_eu_logic_l")))]) (define_insn "msa_binsri_<msafmt>" [(set (match_operand:IMSA 0 "register_operand" "=f") @@ -1405,7 +1599,10 @@ "binsri.<msafmt>\t%w0,%w2,%3" [(set_attr "type" "arith") (set_attr "mode" "TI") - (set_attr "msa_execunit" "msa_eu_logic_l")]) + (set (attr "msa_execunit") + (if_then_else (eq_attr "cpu" "i6400") + (const_string "msa_eu_logic_l2") + (const_string "msa_eu_logic_l")))]) (define_insn "msa_bmnz_v_<msafmt>" [(set (match_operand:IMSA 0 "register_operand" "=f") @@ -1464,18 +1661,24 @@ "bneg.<msafmt>\t%w0,%w1,%w2" [(set_attr "type" "arith") (set_attr "mode" "TI") - (set_attr "msa_execunit" "msa_eu_logic")]) + (set (attr "msa_execunit") + (if_then_else (eq_attr "cpu" "i6400") + (const_string "msa_eu_logic2") + (const_string "msa_eu_logic")))]) (define_insn "msa_bnegi_<msafmt>" [(set (match_operand:IMSA 0 "register_operand" "=f") (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f") (match_operand 2 "const_msa_branch_operand" "")] - UNSPEC_MSA_BNEGI))] + UNSPEC_MSA_BNEGI))] "ISA_HAS_MSA" "bnegi.<msafmt>\t%w0,%w1,%2" [(set_attr "type" "arith") (set_attr "mode" "TI") - (set_attr "msa_execunit" "msa_eu_logic")]) + (set (attr "msa_execunit") + (if_then_else (eq_attr "cpu" "i6400") + (const_string "msa_eu_logic2") + (const_string "msa_eu_logic")))]) (define_insn "msa_bsel_v_<msafmt>" [(set (match_operand:IMSA 0 "register_operand" "=f") @@ -1486,7 +1689,8 @@ "ISA_HAS_MSA" "bsel.v\t%w0,%w2,%w3" [(set_attr "type" "arith") - (set_attr "mode" "TI")]) + (set_attr "mode" "TI") + (set_attr "msa_execunit" "msa_eu_logic_l")]) (define_insn "msa_bseli_b" [(set (match_operand:V16QI 0 "register_operand" "=f") @@ -1509,7 +1713,10 @@ "bset.<msafmt>\t%w0,%w1,%w2" [(set_attr "type" "arith") (set_attr "mode" "TI") - (set_attr "msa_execunit" "msa_eu_logic")]) + (set (attr "msa_execunit") + (if_then_else (eq_attr "cpu" "i6400") + (const_string "msa_eu_logic2") + (const_string "msa_eu_logic")))]) (define_insn "msa_bseti_<msafmt>" [(set (match_operand:IMSA 0 "register_operand" "=f") @@ -1520,7 +1727,10 @@ "bseti.<msafmt>\t%w0,%w1,%2" [(set_attr "type" "arith") (set_attr "mode" "TI") - (set_attr "msa_execunit" "msa_eu_logic")]) + (set (attr "msa_execunit") + (if_then_else (eq_attr "cpu" "i6400") + (const_string "msa_eu_logic2") + (const_string "msa_eu_logic")))]) (define_code_iterator ICC [eq le leu lt ltu]) @@ -1560,10 +1770,7 @@ (ICC:IMSA (match_operand:IMSA 1 "register_operand" "f") (match_operand:IMSA 2 "const_vector_same_cmp<ICC:cmpi>imm4_operand" "")))] "ISA_HAS_MSA" - { - operands[2] = CONST_VECTOR_ELT (operands[2], 0); - return "c<ICC:icci>.<IMSA:msafmt>\t%w0,%w1,%d2"; - } + "c<ICC:icci>.<IMSA:msafmt>\t%w0,%w1,%E2" [(set_attr "type" "arith") (set_attr "mode" "TI") (set_attr "msa_execunit" "msa_eu_int_add")]) @@ -1581,9 +1788,9 @@ (define_insn "msa_dotp_s_<msafmt>" [(set (match_operand:IDOTP128 0 "register_operand" "=f") - (unspec:<MODE> [(match_operand:<VHALFMODE> 1 "register_operand" "f") - (match_operand:<VHALFMODE> 2 "register_operand" "f")] - UNSPEC_MSA_DOTP_S))] + (unspec:IDOTP128 [(match_operand:<VHALFMODE> 1 "register_operand" "f") + (match_operand:<VHALFMODE> 2 "register_operand" "f")] + UNSPEC_MSA_DOTP_S))] "ISA_HAS_MSA" "dotp_s.<msafmt>\t%w0,%w1,%w2" [(set_attr "type" "arith") @@ -1592,9 +1799,9 @@ (define_insn "msa_dotp_u_<msafmt>" [(set (match_operand:IDOTP128 0 "register_operand" "=f") - (unspec:<MODE> [(match_operand:<VHALFMODE> 1 "register_operand" "f") - (match_operand:<VHALFMODE> 2 "register_operand" "f")] - UNSPEC_MSA_DOTP_U))] + (unspec:IDOTP128 [(match_operand:<VHALFMODE> 1 "register_operand" "f") + (match_operand:<VHALFMODE> 2 "register_operand" "f")] + UNSPEC_MSA_DOTP_U))] "ISA_HAS_MSA" "dotp_u.<msafmt>\t%w0,%w1,%w2" [(set_attr "type" "arith") @@ -1603,10 +1810,10 @@ (define_insn "msa_dpadd_s_<msafmt>" [(set (match_operand:IDOTP128 0 "register_operand" "=f") - (unspec:<MODE> [(match_operand:<MODE> 1 "register_operand" "0") - (match_operand:<VHALFMODE> 2 "register_operand" "f") - (match_operand:<VHALFMODE> 3 "register_operand" "f")] - UNSPEC_MSA_DPADD_S))] + (unspec:IDOTP128 [(match_operand:IDOTP128 1 "register_operand" "0") + (match_operand:<VHALFMODE> 2 "register_operand" "f") + (match_operand:<VHALFMODE> 3 "register_operand" "f")] + UNSPEC_MSA_DPADD_S))] "ISA_HAS_MSA" "dpadd_s.<msafmt>\t%w0,%w2,%w3" [(set_attr "type" "arith") @@ -1615,10 +1822,10 @@ (define_insn "msa_dpadd_u_<msafmt>" [(set (match_operand:IDOTP128 0 "register_operand" "=f") - (unspec:<MODE> [(match_operand:<MODE> 1 "register_operand" "0") - (match_operand:<VHALFMODE> 2 "register_operand" "f") - (match_operand:<VHALFMODE> 3 "register_operand" "f")] - UNSPEC_MSA_DPADD_U))] + (unspec:IDOTP128 [(match_operand:IDOTP128 1 "register_operand" "0") + (match_operand:<VHALFMODE> 2 "register_operand" "f") + (match_operand:<VHALFMODE> 3 "register_operand" "f")] + UNSPEC_MSA_DPADD_U))] "ISA_HAS_MSA" "dpadd_u.<msafmt>\t%w0,%w2,%w3" [(set_attr "type" "arith") @@ -1627,10 +1834,10 @@ (define_insn "msa_dpsub_s_<msafmt>" [(set (match_operand:IDOTP128 0 "register_operand" "=f") - (unspec:<MODE> [(match_operand:<MODE> 1 "register_operand" "0") - (match_operand:<VHALFMODE> 2 "register_operand" "f") - (match_operand:<VHALFMODE> 3 "register_operand" "f")] - UNSPEC_MSA_DPSUB_S))] + (unspec:IDOTP128 [(match_operand:IDOTP128 1 "register_operand" "0") + (match_operand:<VHALFMODE> 2 "register_operand" "f") + (match_operand:<VHALFMODE> 3 "register_operand" "f")] + UNSPEC_MSA_DPSUB_S))] "ISA_HAS_MSA" "dpsub_s.<msafmt>\t%w0,%w2,%w3" [(set_attr "type" "arith") @@ -1639,10 +1846,10 @@ (define_insn "msa_dpsub_u_<msafmt>" [(set (match_operand:IDOTP128 0 "register_operand" "=f") - (unspec:<MODE> [(match_operand:<MODE> 1 "register_operand" "0") - (match_operand:<VHALFMODE> 2 "register_operand" "f") - (match_operand:<VHALFMODE> 3 "register_operand" "f")] - UNSPEC_MSA_DPSUB_U))] + (unspec:IDOTP128 [(match_operand:IDOTP128 1 "register_operand" "0") + (match_operand:<VHALFMODE> 2 "register_operand" "f") + (match_operand:<VHALFMODE> 3 "register_operand" "f")] + UNSPEC_MSA_DPSUB_U))] "ISA_HAS_MSA" "dpsub_u.<msafmt>\t%w0,%w2,%w3" [(set_attr "type" "arith") @@ -1694,6 +1901,24 @@ (le "fcle") (lt "fclt")]) +(define_int_iterator FSC_UNS [UNSPEC_MSA_FSAF UNSPEC_MSA_FSUN UNSPEC_MSA_FSOR + UNSPEC_MSA_FSEQ UNSPEC_MSA_FSNE UNSPEC_MSA_FSUEQ + UNSPEC_MSA_FSUNE UNSPEC_MSA_FSULE UNSPEC_MSA_FSULT + UNSPEC_MSA_FSLE UNSPEC_MSA_FSLT]) + +(define_int_attr fsc + [(UNSPEC_MSA_FSAF "fsaf") + (UNSPEC_MSA_FSUN "fsun") + (UNSPEC_MSA_FSOR "fsor") + (UNSPEC_MSA_FSEQ "fseq") + (UNSPEC_MSA_FSNE "fsne") + (UNSPEC_MSA_FSUEQ "fsueq") + (UNSPEC_MSA_FSUNE "fsune") + (UNSPEC_MSA_FSULE "fsule") + (UNSPEC_MSA_FSULT "fsult") + (UNSPEC_MSA_FSLE "fsle") + (UNSPEC_MSA_FSLT "fslt")]) + (define_insn "msa_<FCC:fcc>_<FMSA:msafmt>" [(set (match_operand:<VIMODE> 0 "register_operand" "=f") (FCC:<VIMODE> (match_operand:FMSA 1 "register_operand" "f") @@ -1704,123 +1929,13 @@ (set_attr "mode" "<UNITMODE>") (set_attr "msa_execunit" "msa_eu_cmp")]) -(define_insn "msa_fsaf_<FMSA:msafmt>" - [(set (match_operand:<VIMODE> 0 "register_operand" "=f") - (unspec:<VIMODE> [(match_operand:FMSA 1 "register_operand" "f") - (match_operand:FMSA 2 "register_operand" "f")] - UNSPEC_MSA_FSAF))] - "ISA_HAS_MSA" - "fsaf.<FMSA:msafmt>\t%w0,%w1,%w2" - [(set_attr "type" "fcmp") - (set_attr "mode" "<UNITMODE>") - (set_attr "msa_execunit" "msa_eu_cmp")]) - -(define_insn "msa_fsor_<FMSA:msafmt>" - [(set (match_operand:<VIMODE> 0 "register_operand" "=f") - (unspec:<VIMODE> [(match_operand:FMSA 1 "register_operand" "f") - (match_operand:FMSA 2 "register_operand" "f")] - UNSPEC_MSA_FSOR))] - "ISA_HAS_MSA" - "fsor.<FMSA:msafmt>\t%w0,%w1,%w2" - [(set_attr "type" "fcmp") - (set_attr "mode" "<UNITMODE>") - (set_attr "msa_execunit" "msa_eu_cmp")]) - -(define_insn "msa_fsun_<FMSA:msafmt>" - [(set (match_operand:<VIMODE> 0 "register_operand" "=f") - (unspec:<VIMODE> [(match_operand:FMSA 1 "register_operand" "f") - (match_operand:FMSA 2 "register_operand" "f")] - UNSPEC_MSA_FSUN))] - "ISA_HAS_MSA" - "fsun.<FMSA:msafmt>\t%w0,%w1,%w2" - [(set_attr "type" "fcmp") - (set_attr "mode" "<UNITMODE>") - (set_attr "msa_execunit" "msa_eu_cmp")]) - -(define_insn "msa_fsune_<msafmt>" - [(set (match_operand:<VIMODE> 0 "register_operand" "=f") - (unspec:<VIMODE> [(match_operand:FMSA 1 "register_operand" "f") - (match_operand:FMSA 2 "register_operand" "f")] - UNSPEC_MSA_FSUNE))] - "ISA_HAS_MSA" - "fsune.<msafmt>\t%w0,%w1,%w2" - [(set_attr "type" "fcmp") - (set_attr "mode" "<UNITMODE>") - (set_attr "msa_execunit" "msa_eu_cmp")]) - -(define_insn "msa_fsueq_<msafmt>" - [(set (match_operand:<VIMODE> 0 "register_operand" "=f") - (unspec:<VIMODE> [(match_operand:FMSA 1 "register_operand" "f") - (match_operand:FMSA 2 "register_operand" "f")] - UNSPEC_MSA_FSUEQ))] - "ISA_HAS_MSA" - "fsueq.<msafmt>\t%w0,%w1,%w2" - [(set_attr "type" "fcmp") - (set_attr "mode" "<UNITMODE>") - (set_attr "msa_execunit" "msa_eu_cmp")]) - -(define_insn "msa_fseq_<msafmt>" - [(set (match_operand:<VIMODE> 0 "register_operand" "=f") - (unspec:<VIMODE> [(match_operand:FMSA 1 "register_operand" "f") - (match_operand:FMSA 2 "register_operand" "f")] - UNSPEC_MSA_FSEQ))] - "ISA_HAS_MSA" - "fseq.<msafmt>\t%w0,%w1,%w2" - [(set_attr "type" "fcmp") - (set_attr "mode" "<UNITMODE>") - (set_attr "msa_execunit" "msa_eu_cmp")]) - -(define_insn "msa_fsne_<msafmt>" - [(set (match_operand:<VIMODE> 0 "register_operand" "=f") - (unspec:<VIMODE> [(match_operand:FMSA 1 "register_operand" "f") - (match_operand:FMSA 2 "register_operand" "f")] - UNSPEC_MSA_FSNE))] - "ISA_HAS_MSA" - "fsne.<msafmt>\t%w0,%w1,%w2" - [(set_attr "type" "fcmp") - (set_attr "mode" "<UNITMODE>") - (set_attr "msa_execunit" "msa_eu_cmp")]) - -(define_insn "msa_fslt_<msafmt>" - [(set (match_operand:<VIMODE> 0 "register_operand" "=f") - (unspec:<VIMODE> [(match_operand:FMSA 1 "register_operand" "f") - (match_operand:FMSA 2 "register_operand" "f")] - UNSPEC_MSA_FSLT))] - "ISA_HAS_MSA" - "fslt.<msafmt>\t%w0,%w1,%w2" - [(set_attr "type" "fcmp") - (set_attr "mode" "<UNITMODE>") - (set_attr "msa_execunit" "msa_eu_cmp")]) - -(define_insn "msa_fsult_<msafmt>" +(define_insn "msa_<fsc>_<FMSA:msafmt>" [(set (match_operand:<VIMODE> 0 "register_operand" "=f") (unspec:<VIMODE> [(match_operand:FMSA 1 "register_operand" "f") - (match_operand:FMSA 2 "register_operand" "f")] - UNSPEC_MSA_FSULT))] - "ISA_HAS_MSA" - "fsult.<msafmt>\t%w0,%w1,%w2" - [(set_attr "type" "fcmp") - (set_attr "mode" "<UNITMODE>") - (set_attr "msa_execunit" "msa_eu_cmp")]) - -(define_insn "msa_fsle_<msafmt>" - [(set (match_operand:<VIMODE> 0 "register_operand" "=f") - (unspec:<VIMODE> [(match_operand:FMSA 1 "register_operand" "f") - (match_operand:FMSA 2 "register_operand" "f")] - UNSPEC_MSA_FSLE))] + (match_operand:FMSA 2 "register_operand" "f")] + FSC_UNS))] "ISA_HAS_MSA" - "fsle.<msafmt>\t%w0,%w1,%w2" - [(set_attr "type" "fcmp") - (set_attr "mode" "<UNITMODE>") - (set_attr "msa_execunit" "msa_eu_cmp")]) - -(define_insn "msa_fsule_<msafmt>" - [(set (match_operand:<VIMODE> 0 "register_operand" "=f") - (unspec:<VIMODE> [(match_operand:FMSA 1 "register_operand" "f") - (match_operand:FMSA 2 "register_operand" "f")] - UNSPEC_MSA_FSULE))] - "ISA_HAS_MSA" - "fsule.<msafmt>\t%w0,%w1,%w2" + "<fsc>.<FMSA:msafmt>\t%w0,%w1,%w2" [(set_attr "type" "fcmp") (set_attr "mode" "<UNITMODE>") (set_attr "msa_execunit" "msa_eu_cmp")]) @@ -1844,6 +1959,10 @@ [(V4SF "v4si") (V2DF "v2di")]) +(define_mode_attr FQ + [(V4SF "V8HI") + (V2DF "V4SI")]) + (define_mode_attr FINTCNV [(V4SF "I2S") (V2DF "I2D")]) @@ -1852,9 +1971,9 @@ [(V4SF "S2I") (V2DF "D2I")]) -(define_insn "float<FMSA:mode><fint>2" +(define_insn "float<fint><FMSA:mode>2" [(set (match_operand:FMSA 0 "register_operand" "=f") - (float:<MODE> (match_operand:<FINT> 1 "register_operand" "f")))] + (float:FMSA (match_operand:<FINT> 1 "register_operand" "f")))] "ISA_HAS_MSA" "ffint_s.<msafmt>\t%w0,%w1" [(set_attr "type" "fcvt") @@ -1862,9 +1981,9 @@ (set_attr "mode" "<UNITMODE>") (set_attr "msa_execunit" "msa_eu_float4")]) -(define_insn "floatuns<FMSA:mode><fint>2" +(define_insn "floatuns<fint><FMSA:mode>2" [(set (match_operand:FMSA 0 "register_operand" "=f") - (unsigned_float:<MODE> (match_operand:<FINT> 1 "register_operand" "f")))] + (unsigned_float:FMSA (match_operand:<FINT> 1 "register_operand" "f")))] "ISA_HAS_MSA" "ffint_u.<msafmt>\t%w0,%w1" [(set_attr "type" "fcvt") @@ -1878,8 +1997,8 @@ (define_insn "msa_ffql_<msafmt>" [(set (match_operand:FMSA 0 "register_operand" "=f") - (unspec:<MODE> [(match_operand:<FINT> 1 "register_operand" "f")] - UNSPEC_MSA_FFQL))] + (unspec:FMSA [(match_operand:<FQ> 1 "register_operand" "f")] + UNSPEC_MSA_FFQL))] "ISA_HAS_MSA" "ffql.<msafmt>\t%w0,%w1" [(set_attr "type" "fcvt") @@ -1889,8 +2008,8 @@ (define_insn "msa_ffqr_<msafmt>" [(set (match_operand:FMSA 0 "register_operand" "=f") - (unspec:<MODE> [(match_operand:<FINT> 1 "register_operand" "f")] - UNSPEC_MSA_FFQR))] + (unspec:FMSA [(match_operand:<FQ> 1 "register_operand" "f")] + UNSPEC_MSA_FFQR))] "ISA_HAS_MSA" "ffqr.<msafmt>\t%w0,%w1" [(set_attr "type" "fcvt") @@ -1898,22 +2017,53 @@ (set_attr "mode" "<UNITMODE>") (set_attr "msa_execunit" "msa_eu_float4")]) -(define_insn "msa_fill_<msafmt_f>" - [(set (match_operand:MSA 0 "register_operand" "=f") - (unspec:<MODE> [(match_operand:<REGOR0> 1 "reg_or_0_operand" "dJ")] - UNSPEC_MSA_FILL))] +;; Note used directly by builtins but via the following define_expand. +(define_insn "msa_fill_<msafmt>_insn" + [(set (match_operand:IMSA 0 "register_operand" "=f") + (vec_duplicate:IMSA + (match_operand:<UNITMODE> 1 "reg_or_0_operand" "dJ")))] "ISA_HAS_MSA" "fill.<msafmt>\t%w0,%z1" [(set_attr "type" "arith") (set_attr "mode" "TI") (set_attr "msa_execunit" "msa_eu_logic")]) -;; Note that fill.d and fill_d_f will be split later if !TARGET_64BIT. +;; Expand builtin catoring for HImode and QImode which take SImode. +(define_expand "msa_fill_<msafmt>" + [(set (match_operand:IMSA 0 "register_operand") + (vec_duplicate:IMSA + (match_operand:<EXCEPT> 1 "reg_or_0_operand")))] + "ISA_HAS_MSA" +{ + if ((GET_MODE_SIZE (<UNITMODE>mode) < GET_MODE_SIZE (<EXCEPT>mode)) + && (REG_P (operands[1]) || (GET_CODE (operands[1]) == SUBREG + && REG_P (SUBREG_REG (operands[1]))))) + { + unsigned int offset = GET_MODE_SIZE (<EXCEPT>mode) + - GET_MODE_SIZE (<UNITMODE>mode); + operands[1] = simplify_gen_subreg (<UNITMODE>mode, operands[1], + GET_MODE (operands[1]), + BYTES_BIG_ENDIAN ? offset : 0); + } + emit_insn (gen_msa_fill_<msafmt>_insn (operands[0], operands[1])); + DONE; + }) + +(define_insn "msa_fill_<msafmt_f>" + [(set (match_operand:FMSA 0 "register_operand" "=f") + (vec_duplicate:FMSA + (match_operand:<UNITMODE> 1 "reg_or_0_operand" "dJ")))] + "ISA_HAS_MSA" + "fill.<msafmt>\t%w0,%z1" + [(set_attr "type" "arith") + (set_attr "mode" "TI") + (set_attr "msa_execunit" "msa_eu_logic")]) +;; Note that fill.d and fill.d_f will be split later if !TARGET_64BIT. (define_split [(set (match_operand:V2DI 0 "register_operand") - (unspec:V2DI [(match_operand:DI 1 "reg_or_0_operand")] - UNSPEC_MSA_FILL))] + (vec_duplicate:V2DI + (match_operand:DI 1 "reg_or_0_operand")))] "reload_completed && TARGET_MSA && !TARGET_64BIT" [(const_int 0)] { @@ -1923,8 +2073,8 @@ (define_split [(set (match_operand:V2DF 0 "register_operand") - (unspec:V2DF [(match_operand:DF 1 "register_operand")] - UNSPEC_MSA_FILL))] + (vec_duplicate:V2DF + (match_operand:DF 1 "register_operand")))] "reload_completed && TARGET_MSA && !TARGET_64BIT" [(const_int 0)] { @@ -1945,8 +2095,8 @@ ;;UNSPEC_MSA_FMAX (define_insn "smax<mode>3" [(set (match_operand:FMSA 0 "register_operand" "=f") - (smax:<MODE> (match_operand:<MODE> 1 "register_operand" "f") - (match_operand:<MODE> 2 "register_operand" "f")))] + (smax:FMSA (match_operand:FMSA 1 "register_operand" "f") + (match_operand:FMSA 2 "register_operand" "f")))] "ISA_HAS_MSA" "fmax.<msafmt>\t%w0,%w1,%w2" [(set_attr "type" "fadd") @@ -1956,8 +2106,8 @@ ;;UNSPEC_MSA_FMAX_A (define_insn "umax<mode>3" [(set (match_operand:FMSA 0 "register_operand" "=f") - (umax:<MODE> (match_operand:<MODE> 1 "register_operand" "f") - (match_operand:<MODE> 2 "register_operand" "f")))] + (umax:FMSA (match_operand:FMSA 1 "register_operand" "f") + (match_operand:FMSA 2 "register_operand" "f")))] "ISA_HAS_MSA" "fmax_a.<msafmt>\t%w0,%w1,%w2" [(set_attr "type" "fadd") @@ -1967,8 +2117,8 @@ ;;UNSPEC_MSA_FMIN (define_insn "smin<mode>3" [(set (match_operand:FMSA 0 "register_operand" "=f") - (smin:<MODE> (match_operand:<MODE> 1 "register_operand" "f") - (match_operand:<MODE> 2 "register_operand" "f")))] + (smin:FMSA (match_operand:FMSA 1 "register_operand" "f") + (match_operand:FMSA 2 "register_operand" "f")))] "ISA_HAS_MSA" "fmin.<msafmt>\t%w0,%w1,%w2" [(set_attr "type" "fadd") @@ -1978,8 +2128,8 @@ ;;UNSPEC_MSA_FMIN_A (define_insn "umin<mode>3" [(set (match_operand:FMSA 0 "register_operand" "=f") - (umin:<MODE> (match_operand:<MODE> 1 "register_operand" "f") - (match_operand:<MODE> 2 "register_operand" "f")))] + (umin:FMSA (match_operand:FMSA 1 "register_operand" "f") + (match_operand:FMSA 2 "register_operand" "f")))] "ISA_HAS_MSA" "fmin_a.<msafmt>\t%w0,%w1,%w2" [(set_attr "type" "fadd") @@ -1993,7 +2143,8 @@ "ISA_HAS_MSA" "frcp.<msafmt>\t%w0,%w1" [(set_attr "type" "frdiv") - (set_attr "mode" "<UNITMODE>")]) + (set_attr "mode" "<UNITMODE>") + (set_attr "msa_execunit" "msa_eu_fdiv")]) (define_insn "msa_frint_<msafmt>" [(set (match_operand:FMSA 0 "register_operand" "=f") @@ -2012,14 +2163,15 @@ "ISA_HAS_MSA" "frsqrt.<msafmt>\t%w0,%w1" [(set_attr "type" "frsqrt") - (set_attr "mode" "<UNITMODE>")]) + (set_attr "mode" "<UNITMODE>") + (set_attr "msa_execunit" "msa_eu_fdiv")]) (define_insn "msa_ftint_s_<msafmt>" [(set (match_operand:<FINT> 0 "register_operand" "=f") (unspec:<FINT> [(match_operand:FMSA 1 "register_operand" "f")] UNSPEC_MSA_FTINT_S))] "ISA_HAS_MSA" - "ftint_s.<>msafmt>\t%w0,%w1" + "ftint_s.<msafmt>\t%w0,%w1" [(set_attr "type" "fcvt") (set_attr "cnv_mode" "<FINTCNV_2>") (set_attr "mode" "<UNITMODE>") @@ -2083,14 +2235,14 @@ (set_attr "msa_execunit" "msa_eu_float4")]) (define_mode_iterator IZMODE [V8HI V4SI V2DI]) -(define_mode_attr IZDOUBLE +(define_mode_attr IZDOUBLE [(V8HI "V16QI") (V4SI "V8HI") (V2DI "V4SI")]) (define_insn "msa_hadd_s_<msafmt>" [(set (match_operand:IZMODE 0 "register_operand" "=f") - (unspec:<MODE> [(match_operand:<IZDOUBLE> 1 "register_operand" "f") + (unspec:IZMODE [(match_operand:<IZDOUBLE> 1 "register_operand" "f") (match_operand:<IZDOUBLE> 2 "register_operand" "f")] UNSPEC_MSA_HADD_S))] "ISA_HAS_MSA" @@ -2101,7 +2253,7 @@ (define_insn "msa_hadd_u_<msafmt>" [(set (match_operand:IZMODE 0 "register_operand" "=f") - (unspec:<MODE> [(match_operand:<IZDOUBLE> 1 "register_operand" "f") + (unspec:IZMODE [(match_operand:<IZDOUBLE> 1 "register_operand" "f") (match_operand:<IZDOUBLE> 2 "register_operand" "f")] UNSPEC_MSA_HADD_U))] "ISA_HAS_MSA" @@ -2112,7 +2264,7 @@ (define_insn "msa_hsub_s_<msafmt>" [(set (match_operand:IZMODE 0 "register_operand" "=f") - (unspec:<MODE> [(match_operand:<IZDOUBLE> 1 "register_operand" "f") + (unspec:IZMODE [(match_operand:<IZDOUBLE> 1 "register_operand" "f") (match_operand:<IZDOUBLE> 2 "register_operand" "f")] UNSPEC_MSA_HSUB_S))] "ISA_HAS_MSA" @@ -2123,7 +2275,7 @@ (define_insn "msa_hsub_u_<msafmt>" [(set (match_operand:IZMODE 0 "register_operand" "=f") - (unspec:<MODE> [(match_operand:<IZDOUBLE> 1 "register_operand" "f") + (unspec:IZMODE [(match_operand:<IZDOUBLE> 1 "register_operand" "f") (match_operand:<IZDOUBLE> 2 "register_operand" "f")] UNSPEC_MSA_HSUB_U))] "ISA_HAS_MSA" @@ -2132,46 +2284,214 @@ (set_attr "mode" "TI") (set_attr "msa_execunit" "msa_eu_int_add")]) -(define_insn "msa_ilvev_<msafmt>" - [(set (match_operand:IMSA 0 "register_operand" "=f") - (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f") - (match_operand:IMSA 2 "register_operand" "f")] - UNSPEC_MSA_ILVEV))] +(define_insn "msa_ilvev_b" + [(set (match_operand:V16QI 0 "register_operand" "=f") + (vec_select:V16QI (vec_concat:V32QI + (match_operand:V16QI 1 "register_operand" "f") + (match_operand:V16QI 2 "register_operand" "f")) + (parallel [(const_int 16) (const_int 0) + (const_int 18) (const_int 2) + (const_int 20) (const_int 4) + (const_int 22) (const_int 6) + (const_int 24) (const_int 8) + (const_int 26) (const_int 10) + (const_int 28) (const_int 12) + (const_int 30) (const_int 14)])))] + "ISA_HAS_MSA" + "ilvev.b\t%w0,%w1,%w2" + [(set_attr "alu_type" "add") + (set_attr "mode" "TI") + (set_attr "msa_execunit" "msa_eu_logic")]) + +(define_insn "msa_ilvev_h" + [(set (match_operand:V8HI 0 "register_operand" "=f") + (vec_select:V8HI (vec_concat:V16HI + (match_operand:V8HI 1 "register_operand" "f") + (match_operand:V8HI 2 "register_operand" "f")) + (parallel [(const_int 8) (const_int 0) + (const_int 10) (const_int 2) + (const_int 12) (const_int 4) + (const_int 14) (const_int 6)])))] + "ISA_HAS_MSA" + "ilvev.h\t%w0,%w1,%w2" + [(set_attr "alu_type" "add") + (set_attr "mode" "TI") + (set_attr "msa_execunit" "msa_eu_logic")]) + +(define_insn "msa_ilvev_w" + [(set (match_operand:V4SI 0 "register_operand" "=f") + (vec_select:V4SI (vec_concat:V8SI + (match_operand:V4SI 1 "register_operand" "f") + (match_operand:V4SI 2 "register_operand" "f")) + (parallel [(const_int 4) (const_int 0) + (const_int 6) (const_int 2)])))] "ISA_HAS_MSA" - "ilvev.<msafmt>\t%w0,%w1,%w2" + "ilvev.w\t%w0,%w1,%w2" [(set_attr "alu_type" "add") (set_attr "mode" "TI") (set_attr "msa_execunit" "msa_eu_logic")]) -(define_insn "msa_ilvl_<msafmt>" - [(set (match_operand:IMSA 0 "register_operand" "=f") - (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f") - (match_operand:IMSA 2 "register_operand" "f")] - UNSPEC_MSA_ILVL))] +(define_insn "msa_ilvl_b" + [(set (match_operand:V16QI 0 "register_operand" "=f") + (vec_select:V16QI (vec_concat:V32QI + (match_operand:V16QI 1 "register_operand" "f") + (match_operand:V16QI 2 "register_operand" "f")) + (parallel [(const_int 24) (const_int 8) + (const_int 25) (const_int 9) + (const_int 26) (const_int 10) + (const_int 27) (const_int 11) + (const_int 28) (const_int 12) + (const_int 29) (const_int 13) + (const_int 30) (const_int 14) + (const_int 31) (const_int 15)])))] + "ISA_HAS_MSA" + "ilvl.b\t%w0,%w1,%w2" + [(set_attr "alu_type" "add") + (set_attr "mode" "TI") + (set_attr "msa_execunit" "msa_eu_logic")]) + +(define_insn "msa_ilvl_h" + [(set (match_operand:V8HI 0 "register_operand" "=f") + (vec_select:V8HI (vec_concat:V16HI + (match_operand:V8HI 1 "register_operand" "f") + (match_operand:V8HI 2 "register_operand" "f")) + (parallel [(const_int 12) (const_int 4) + (const_int 13) (const_int 5) + (const_int 14) (const_int 6) + (const_int 15) (const_int 7)])))] + "ISA_HAS_MSA" + "ilvl.h\t%w0,%w1,%w2" + [(set_attr "alu_type" "add") + (set_attr "mode" "TI") + (set_attr "msa_execunit" "msa_eu_logic")]) + +(define_insn "msa_ilvl_w" + [(set (match_operand:V4SI 0 "register_operand" "=f") + (vec_select:V4SI (vec_concat:V8SI + (match_operand:V4SI 1 "register_operand" "f") + (match_operand:V4SI 2 "register_operand" "f")) + (parallel [(const_int 6) (const_int 2) + (const_int 7) (const_int 3)])))] "ISA_HAS_MSA" - "ilvl.<msafmt>\t%w0,%w1,%w2" + "ilvl.w\t%w0,%w1,%w2" [(set_attr "alu_type" "add") (set_attr "mode" "TI") (set_attr "msa_execunit" "msa_eu_logic")]) -(define_insn "msa_ilvod_<msafmt>" - [(set (match_operand:IMSA 0 "register_operand" "=f") - (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f") - (match_operand:IMSA 2 "register_operand" "f")] - UNSPEC_MSA_ILVOD))] +(define_insn "msa_ilvl_d" + [(set (match_operand:V2DI 0 "register_operand" "=f") + (vec_select:V2DI (vec_concat:V4DI + (match_operand:V2DI 1 "register_operand" "f") + (match_operand:V2DI 2 "register_operand" "f")) + (parallel [(const_int 3) (const_int 1)])))] "ISA_HAS_MSA" - "ilvod.<msafmt>\t%w0,%w1,%w2" + "ilvl.d\t%w0,%w1,%w2" [(set_attr "alu_type" "add") (set_attr "mode" "TI") (set_attr "msa_execunit" "msa_eu_logic")]) -(define_insn "msa_ilvr_<msafmt>" - [(set (match_operand:IMSA 0 "register_operand" "=f") - (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f") - (match_operand:IMSA 2 "register_operand" "f")] - UNSPEC_MSA_ILVR))] +(define_insn "msa_ilvod_b" + [(set (match_operand:V16QI 0 "register_operand" "=f") + (vec_select:V16QI (vec_concat:V32QI + (match_operand:V16QI 1 "register_operand" "f") + (match_operand:V16QI 2 "register_operand" "f")) + (parallel [(const_int 17) (const_int 1) + (const_int 19) (const_int 3) + (const_int 21) (const_int 5) + (const_int 23) (const_int 7) + (const_int 25) (const_int 9) + (const_int 27) (const_int 11) + (const_int 29) (const_int 13) + (const_int 31) (const_int 15)])))] + "ISA_HAS_MSA" + "ilvod.b\t%w0,%w1,%w2" + [(set_attr "alu_type" "add") + (set_attr "mode" "TI") + (set_attr "msa_execunit" "msa_eu_logic")]) + +(define_insn "msa_ilvod_h" + [(set (match_operand:V8HI 0 "register_operand" "=f") + (vec_select:V8HI (vec_concat:V16HI + (match_operand:V8HI 1 "register_operand" "f") + (match_operand:V8HI 2 "register_operand" "f")) + (parallel [(const_int 9) (const_int 1) + (const_int 11) (const_int 3) + (const_int 13) (const_int 5) + (const_int 15) (const_int 7)])))] + "ISA_HAS_MSA" + "ilvod.h\t%w0,%w1,%w2" + [(set_attr "alu_type" "add") + (set_attr "mode" "TI") + (set_attr "msa_execunit" "msa_eu_logic")]) + +(define_insn "msa_ilvod_w" + [(set (match_operand:V4SI 0 "register_operand" "=f") + (vec_select:V4SI (vec_concat:V8SI + (match_operand:V4SI 1 "register_operand" "f") + (match_operand:V4SI 2 "register_operand" "f")) + (parallel [(const_int 5) (const_int 1) + (const_int 7) (const_int 3)])))] + "ISA_HAS_MSA" + "ilvod.w\t%w0,%w1,%w2" + [(set_attr "alu_type" "add") + (set_attr "mode" "TI") + (set_attr "msa_execunit" "msa_eu_logic")]) + +(define_insn "msa_ilvr_b" + [(set (match_operand:V16QI 0 "register_operand" "=f") + (vec_select:V16QI (vec_concat:V32QI + (match_operand:V16QI 1 "register_operand" "f") + (match_operand:V16QI 2 "register_operand" "f")) + (parallel [(const_int 16) (const_int 0) + (const_int 17) (const_int 1) + (const_int 18) (const_int 2) + (const_int 19) (const_int 3) + (const_int 20) (const_int 4) + (const_int 21) (const_int 5) + (const_int 22) (const_int 6) + (const_int 23) (const_int 7)])))] + "ISA_HAS_MSA" + "ilvr.b\t%w0,%w1,%w2" + [(set_attr "alu_type" "add") + (set_attr "mode" "TI") + (set_attr "msa_execunit" "msa_eu_logic")]) + +(define_insn "msa_ilvr_h" + [(set (match_operand:V8HI 0 "register_operand" "=f") + (vec_select:V8HI (vec_concat:V16HI + (match_operand:V8HI 1 "register_operand" "f") + (match_operand:V8HI 2 "register_operand" "f")) + (parallel [(const_int 8) (const_int 0) + (const_int 9) (const_int 1) + (const_int 10) (const_int 2) + (const_int 11) (const_int 3)])))] + "ISA_HAS_MSA" + "ilvr.h\t%w0,%w1,%w2" + [(set_attr "alu_type" "add") + (set_attr "mode" "TI") + (set_attr "msa_execunit" "msa_eu_logic")]) + +(define_insn "msa_ilvr_w" + [(set (match_operand:V4SI 0 "register_operand" "=f") + (vec_select:V4SI (vec_concat:V8SI + (match_operand:V4SI 1 "register_operand" "f") + (match_operand:V4SI 2 "register_operand" "f")) + (parallel [(const_int 4) (const_int 0) + (const_int 5) (const_int 1)])))] "ISA_HAS_MSA" - "ilvr.<msafmt>\t%w0,%w1,%w2" + "ilvr.w\t%w0,%w1,%w2" + [(set_attr "alu_type" "add") + (set_attr "mode" "TI") + (set_attr "msa_execunit" "msa_eu_logic")]) + +(define_insn "msa_ilvr_d" + [(set (match_operand:V2DI 0 "register_operand" "=f") + (vec_select:V2DI (vec_concat:V4DI + (match_operand:V2DI 1 "register_operand" "f") + (match_operand:V2DI 2 "register_operand" "f")) + (parallel [(const_int 2) (const_int 0)])))] + "ISA_HAS_MSA" + "ilvr.d\t%w0,%w1,%w2" [(set_attr "alu_type" "add") (set_attr "mode" "TI") (set_attr "msa_execunit" "msa_eu_logic")]) @@ -2211,22 +2531,20 @@ (set_attr "mode" "TI") (set_attr "msa_execunit" "msa_eu_int_add")]) -(define_insn "msa_max_s_<msafmt>" +(define_insn "smax<mode>3" [(set (match_operand:IMSA 0 "register_operand" "=f") - (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f") - (match_operand:IMSA 2 "register_operand" "f")] - UNSPEC_MSA_MAX_S))] + (smax:IMSA (match_operand:IMSA 1 "register_operand" "f") + (match_operand:IMSA 2 "register_operand" "f")))] "ISA_HAS_MSA" "max_s.<msafmt>\t%w0,%w1,%w2" [(set_attr "type" "arith") (set_attr "mode" "TI") (set_attr "msa_execunit" "msa_eu_int_add")]) -(define_insn "msa_max_u_<msafmt>" +(define_insn "umax<mode>3" [(set (match_operand:IMSA 0 "register_operand" "=f") - (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f") - (match_operand:IMSA 2 "register_operand" "f")] - UNSPEC_MSA_MAX_U))] + (umax:IMSA (match_operand:IMSA 1 "register_operand" "f") + (match_operand:IMSA 2 "register_operand" "f")))] "ISA_HAS_MSA" "max_u.<msafmt>\t%w0,%w1,%w2" [(set_attr "type" "arith") @@ -2266,22 +2584,20 @@ (set_attr "mode" "TI") (set_attr "msa_execunit" "msa_eu_int_add")]) -(define_insn "msa_min_s_<msafmt>" +(define_insn "smin<mode>3" [(set (match_operand:IMSA 0 "register_operand" "=f") - (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f") - (match_operand:IMSA 2 "register_operand" "f")] - UNSPEC_MSA_MIN_S))] + (smin:IMSA (match_operand:IMSA 1 "register_operand" "f") + (match_operand:IMSA 2 "register_operand" "f")))] "ISA_HAS_MSA" "min_s.<msafmt>\t%w0,%w1,%w2" [(set_attr "type" "arith") (set_attr "mode" "TI") (set_attr "msa_execunit" "msa_eu_int_add")]) -(define_insn "msa_min_u_<msafmt>" +(define_insn "umin<mode>3" [(set (match_operand:IMSA 0 "register_operand" "=f") - (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f") - (match_operand:IMSA 2 "register_operand" "f")] - UNSPEC_MSA_MIN_U))] + (umin:IMSA (match_operand:IMSA 1 "register_operand" "f") + (match_operand:IMSA 2 "register_operand" "f")))] "ISA_HAS_MSA" "min_u.<msafmt>\t%w0,%w1,%w2" [(set_attr "type" "arith") @@ -2364,7 +2680,10 @@ "nloc.<msafmt>\t%w0,%w1" [(set_attr "type" "arith") (set_attr "mode" "TI") - (set_attr "msa_execunit" "msa_eu_logic")]) + (set (attr "msa_execunit") + (if_then_else (eq_attr "cpu" "i6400") + (const_string "msa_eu_logic2") + (const_string "msa_eu_logic")))]) (define_insn "clz<mode>2" [(set (match_operand:IMSA 0 "register_operand" "=f") @@ -2373,7 +2692,10 @@ "nlzc.<msafmt>\t%w0,%w1" [(set_attr "type" "arith") (set_attr "mode" "TI") - (set_attr "msa_execunit" "msa_eu_logic")]) + (set (attr "msa_execunit") + (if_then_else (eq_attr "cpu" "i6400") + (const_string "msa_eu_logic2") + (const_string "msa_eu_logic")))]) (define_insn "msa_nor_v_<msafmt>" [(set (match_operand:IMSA 0 "register_operand" "=f") @@ -2435,7 +2757,10 @@ "pcnt.<msafmt>\t%w0,%w1" [(set_attr "type" "arith") (set_attr "mode" "TI") - (set_attr "msa_execunit" "msa_eu_logic")]) + (set (attr "msa_execunit") + (if_then_else (eq_attr "cpu" "i6400") + (const_string "msa_eu_logic3") + (const_string "msa_eu_logic")))]) (define_insn "msa_sat_s_<msafmt>" [(set (match_operand:IMSA 0 "register_operand" "=f") @@ -2468,7 +2793,11 @@ "shf.<msafmt>\t%w0,%w1,%2" [(set_attr "type" "arith") (set_attr "mode" "TI") - (set_attr "msa_execunit" "msa_eu_logic")]) + (set_attr "datafmt" "<msafmt>") + (set (attr "msa_execunit") + (if_then_else (eq_attr "cpu" "i6400") + (const_string "msa_eu_logic2") + (const_string "msa_eu_logic")))]) (define_insn "msa_shf_w_f" [(set (match_operand:V4SF 0 "register_operand" "=f") @@ -2479,7 +2808,10 @@ "shf.w\t%w0,%w1,%2" [(set_attr "type" "arith") (set_attr "mode" "TI") - (set_attr "msa_execunit" "msa_eu_logic")]) + (set (attr "msa_execunit") + (if_then_else (eq_attr "cpu" "i6400") + (const_string "msa_eu_logic2") + (const_string "msa_eu_logic")))]) (define_insn "msa_slli_<msafmt>" [(set (match_operand:IMSA 0 "register_operand" "=f") @@ -2490,7 +2822,10 @@ "slli.<msafmt>\t%w0,%w1,%2" [(set_attr "type" "arith") (set_attr "mode" "TI") - (set_attr "msa_execunit" "msa_eu_logic")]) + (set (attr "msa_execunit") + (if_then_else (eq_attr "cpu" "i6400") + (const_string "msa_eu_logic2") + (const_string "msa_eu_logic")))]) (define_insn "msa_srai_<msafmt>" [(set (match_operand:IMSA 0 "register_operand" "=f") @@ -2501,7 +2836,10 @@ "srai.<msafmt>\t%w0,%w1,%2" [(set_attr "type" "arith") (set_attr "mode" "TI") - (set_attr "msa_execunit" "msa_eu_logic")]) + (set (attr "msa_execunit") + (if_then_else (eq_attr "cpu" "i6400") + (const_string "msa_eu_logic2") + (const_string "msa_eu_logic")))]) (define_insn "msa_srar_<msafmt>" [(set (match_operand:IMSA 0 "register_operand" "=f") @@ -2512,7 +2850,10 @@ "srar.<msafmt>\t%w0,%w1,%w2" [(set_attr "type" "arith") (set_attr "mode" "TI") - (set_attr "msa_execunit" "msa_eu_logic")]) + (set (attr "msa_execunit") + (if_then_else (eq_attr "cpu" "i6400") + (const_string "msa_eu_logic2") + (const_string "msa_eu_logic")))]) (define_insn "msa_srari_<msafmt>" [(set (match_operand:IMSA 0 "register_operand" "=f") @@ -2523,7 +2864,10 @@ "srari.<msafmt>\t%w0,%w1,%2" [(set_attr "type" "arith") (set_attr "mode" "TI") - (set_attr "msa_execunit" "msa_eu_logic")]) + (set (attr "msa_execunit") + (if_then_else (eq_attr "cpu" "i6400") + (const_string "msa_eu_logic2") + (const_string "msa_eu_logic")))]) (define_insn "msa_srli_<msafmt>" [(set (match_operand:IMSA 0 "register_operand" "=f") @@ -2534,7 +2878,10 @@ "srli.<msafmt>\t%w0,%w1,%2" [(set_attr "type" "arith") (set_attr "mode" "TI") - (set_attr "msa_execunit" "msa_eu_logic")]) + (set (attr "msa_execunit") + (if_then_else (eq_attr "cpu" "i6400") + (const_string "msa_eu_logic2") + (const_string "msa_eu_logic")))]) (define_insn "msa_srlr_<msafmt>" [(set (match_operand:IMSA 0 "register_operand" "=f") @@ -2545,7 +2892,10 @@ "srlr.<msafmt>\t%w0,%w1,%w2" [(set_attr "type" "arith") (set_attr "mode" "TI") - (set_attr "msa_execunit" "msa_eu_logic")]) + (set (attr "msa_execunit") + (if_then_else (eq_attr "cpu" "i6400") + (const_string "msa_eu_logic2") + (const_string "msa_eu_logic")))]) (define_insn "msa_srlri_<msafmt>" [(set (match_operand:IMSA 0 "register_operand" "=f") @@ -2556,7 +2906,10 @@ "srlri.<msafmt>\t%w0,%w1,%2" [(set_attr "type" "arith") (set_attr "mode" "TI") - (set_attr "msa_execunit" "msa_eu_logic")]) + (set (attr "msa_execunit") + (if_then_else (eq_attr "cpu" "i6400") + (const_string "msa_eu_logic2") + (const_string "msa_eu_logic")))]) (define_insn "msa_subs_s_<msafmt>" [(set (match_operand:IMSA 0 "register_operand" "=f") @@ -2634,7 +2987,10 @@ "sld.<msafmt>\t%w0,%w2[%z3]" [(set_attr "type" "arith") (set_attr "mode" "TI") - (set_attr "msa_execunit" "msa_eu_logic_l")]) + (set (attr "msa_execunit") + (if_then_else (eq_attr "cpu" "i6400") + (const_string "msa_eu_logic_l2") + (const_string "msa_eu_logic_l")))]) (define_insn "msa_sldi_<msafmt_f>" [(set (match_operand:MSA 0 "register_operand" "=f") @@ -2646,7 +3002,10 @@ "sldi.<msafmt>\t%w0,%w2[%3]" [(set_attr "type" "arith") (set_attr "mode" "TI") - (set_attr "msa_execunit" "msa_eu_logic_l")]) + (set (attr "msa_execunit") + (if_then_else (eq_attr "cpu" "i6400") + (const_string "msa_eu_logic_l2") + (const_string "msa_eu_logic_l")))]) (define_insn "msa_splat_<msafmt_f>" [(set (match_operand:MSA 0 "register_operand" "=f") @@ -2673,9 +3032,9 @@ ;; operand 1 is a scalar (define_insn "msa_splati_<msafmt_f>_s" [(set (match_operand:FMSA 0 "register_operand" "=f") - (unspec:<MODE> [(match_operand:<UNITMODE> 1 "register_operand" "f") - (match_operand 2 "const_<indeximm>_operand" "")] - UNSPEC_MSA_SPLATI))] + (unspec:FMSA [(match_operand:<UNITMODE> 1 "register_operand" "f") + (match_operand 2 "const_<indeximm>_operand" "")] + UNSPEC_MSA_SPLATI))] "ISA_HAS_MSA" "splati.<msafmt>\t%w0,%w1[%2]" [(set_attr "type" "arith") @@ -2715,11 +3074,11 @@ (define_insn "msa_fexdo_w" [(set (match_operand:V4SF 0 "register_operand" "=f") - (unspec:V4SF [(match_operand:V2DF 1 "register_operand" "f") - (match_operand:V2DF 2 "register_operand" "f")] - UNSPEC_MSA_FEXDO))] + (vec_concat:V4SF + (float_truncate:V2SF (match_operand:V2DF 1 "register_operand" "f")) + (float_truncate:V2SF (match_operand:V2DF 2 "register_operand" "f"))))] "ISA_HAS_MSA" - "fexdo.w\t%w0,%w1,%w2" + "fexdo.w\t%w0,%w2,%w1" [(set_attr "type" "arith") (set_attr "mode" "TI") (set_attr "msa_execunit" "msa_eu_float4")]) @@ -2746,8 +3105,8 @@ (define_insn "msa_fexupr_w" [(set (match_operand:V4SF 0 "register_operand" "=f") - (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "f")] - UNSPEC_MSA_FEXUPR))] + (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "f")] + UNSPEC_MSA_FEXUPR))] "ISA_HAS_MSA" "fexupr.w\t%w0,%w1" [(set_attr "type" "arith") @@ -2756,15 +3115,15 @@ (define_insn "msa_fexupr_d" [(set (match_operand:V2DF 0 "register_operand" "=f") - (unspec:V2DF [(match_operand:V4SF 1 "register_operand" "f")] - UNSPEC_MSA_FEXUPR))] + (unspec:V2DF [(match_operand:V4SF 1 "register_operand" "f")] + UNSPEC_MSA_FEXUPR))] "ISA_HAS_MSA" "fexupr.d\t%w0,%w1" [(set_attr "type" "arith") (set_attr "mode" "TI") (set_attr "msa_execunit" "msa_eu_float4")]) -(define_insn "msa_branch_nz_v_<msafmt_f>" +(define_insn "msa_branch_nz_v_<msafmt_f>" [(set (pc) (if_then_else (ne (unspec:SI [(match_operand:MSA 1 "register_operand" "f")] UNSPEC_MSA_BNZ_V) @@ -2830,7 +3189,7 @@ return mips_output_conditional_branch (insn, operands, MIPS_BRANCH ("bnz.<msafmt>", "%w1,%0"), MIPS_BRANCH ("bz.<msafmt>", "%w1,%0")); - + } [(set_attr "type" "branch") diff --git a/gcc-4.9/gcc/config/mips/mips-opts.h b/gcc-4.9/gcc/config/mips/mips-opts.h index 51375ff3a..9d0de4921 100644 --- a/gcc-4.9/gcc/config/mips/mips-opts.h +++ b/gcc-4.9/gcc/config/mips/mips-opts.h @@ -47,11 +47,10 @@ enum mips_r10k_cache_barrier_setting { #define MIPS_ARCH_OPTION_FROM_ABI -1 #define MIPS_ARCH_OPTION_NATIVE -2 -/* Enumerates the setting of the -mclib= option. */ -enum mips_lib_setting { - MIPS_LIB_NEWLIB, - MIPS_LIB_SMALL, - MIPS_LIB_TINY +/* Enumerates the setting of the -mcompact-branches= option. */ +enum mips_cb_setting { + MIPS_CB_NEVER, + MIPS_CB_OPTIMAL, + MIPS_CB_ALWAYS }; - #endif diff --git a/gcc-4.9/gcc/config/mips/mips-protos.h b/gcc-4.9/gcc/config/mips/mips-protos.h index 73d627719..6ce3d70e6 100644 --- a/gcc-4.9/gcc/config/mips/mips-protos.h +++ b/gcc-4.9/gcc/config/mips/mips-protos.h @@ -192,9 +192,9 @@ enum mips_split_type { extern bool mips_symbolic_constant_p (rtx, enum mips_symbol_context, enum mips_symbol_type *); -extern int mips_regno_mode_ok_for_base_p (int, enum machine_mode, bool); -extern bool mips_stack_address_p (rtx, enum machine_mode); -extern int mips_address_insns (rtx, enum machine_mode, bool); +extern int mips_regno_mode_ok_for_base_p (int, machine_mode, bool); +extern bool mips_stack_address_p (rtx, machine_mode); +extern int mips_address_insns (rtx, machine_mode, bool); extern int mips_const_insns (rtx); extern int mips_split_const_insns (rtx); extern int mips_split_128bit_const_insns (rtx); @@ -207,20 +207,19 @@ extern void mips_emit_binary (enum rtx_code, rtx, rtx, rtx); #endif extern rtx mips_pic_base_register (rtx); extern rtx mips_got_load (rtx, rtx, enum mips_symbol_type); -extern bool mips_split_symbol (rtx, rtx, enum machine_mode, rtx *); +extern bool mips_split_symbol (rtx, rtx, machine_mode, rtx *); extern rtx mips_unspec_address (rtx, enum mips_symbol_type); extern rtx mips_strip_unspec_address (rtx); extern void mips_move_integer (rtx, rtx, unsigned HOST_WIDE_INT); -extern bool mips_legitimize_move (enum machine_mode, rtx, rtx); +extern bool mips_legitimize_move (machine_mode, rtx, rtx); extern rtx mips_subword (rtx, bool); -extern rtx mips_subword_at_byte (rtx, unsigned int); extern bool mips_split_move_p (rtx, rtx, enum mips_split_type); -extern bool mips_split_128bit_move_p (rtx, rtx); -extern bool mips_split_move_insn_p (rtx, rtx, rtx); extern void mips_split_move (rtx, rtx, enum mips_split_type); +extern bool mips_split_move_insn_p (rtx, rtx, rtx); extern void mips_split_move_insn (rtx, rtx, rtx); extern void mips_split_128bit_move (rtx, rtx); +extern bool mips_split_128bit_move_p (rtx, rtx); extern void mips_split_msa_copy_d (rtx, rtx, rtx, rtx (*)(rtx, rtx, rtx)); extern void mips_split_msa_insert_d (rtx, rtx, rtx, rtx); extern void mips_split_msa_fill_d (rtx, rtx); @@ -248,15 +247,14 @@ extern bool mips_expand_block_move (rtx, rtx, rtx); extern void mips_expand_synci_loop (rtx, rtx); extern void mips_init_cumulative_args (CUMULATIVE_ARGS *, tree); -extern bool mips_pad_arg_upward (enum machine_mode, const_tree); -extern bool mips_pad_reg_upward (enum machine_mode, tree); +extern bool mips_pad_arg_upward (machine_mode, const_tree); +extern bool mips_pad_reg_upward (machine_mode, tree); extern bool mips_expand_ext_as_unaligned_load (rtx, rtx, HOST_WIDE_INT, HOST_WIDE_INT, bool); extern bool mips_expand_ins_as_unaligned_store (rtx, rtx, HOST_WIDE_INT, HOST_WIDE_INT); -extern bool mips_mem_fits_mode_p (enum machine_mode mode, rtx x); -extern void mips_order_regs_for_local_alloc (void); +extern bool mips_mem_fits_mode_p (machine_mode mode, rtx x); extern HOST_WIDE_INT mips_debugger_offset (rtx, HOST_WIDE_INT); extern void mips_push_asm_switch (struct mips_asm_switch *); @@ -286,29 +284,32 @@ extern void mips_expand_prologue (void); extern void mips_expand_before_return (void); extern void mips_expand_epilogue (bool); extern bool mips_can_use_return_insn (void); - +extern bool mips_const_vector_same_val_p (rtx, machine_mode); +extern bool mips_const_vector_same_byte_p (rtx, machine_mode); +extern bool mips_const_vector_same_int_p (rtx, machine_mode, HOST_WIDE_INT, + HOST_WIDE_INT); +extern bool mips_const_vector_bitimm_set_p (rtx, machine_mode); +extern bool mips_const_vector_bitimm_clr_p (rtx, machine_mode); extern bool mips_secondary_memory_needed (enum reg_class, enum reg_class, - enum machine_mode); -extern bool mips_const_vector_same_val_p (rtx, enum machine_mode); -extern bool mips_const_vector_same_byte_p (rtx, enum machine_mode); -extern bool mips_const_vector_same_int_p (rtx, enum machine_mode, HOST_WIDE_INT, HOST_WIDE_INT); -extern bool mips_const_vector_bitimm_set_p (rtx, enum machine_mode); -extern bool mips_const_vector_bitimm_clr_p (rtx, enum machine_mode); -extern bool mips_cannot_change_mode_class (enum machine_mode, - enum machine_mode, enum reg_class); + machine_mode); +extern bool mips_cannot_change_mode_class (machine_mode, + machine_mode, enum reg_class); extern bool mips_dangerous_for_la25_p (rtx); -extern bool mips_modes_tieable_p (enum machine_mode, enum machine_mode); +extern bool mips_modes_tieable_p (machine_mode, machine_mode); extern enum reg_class mips_secondary_reload_class (enum reg_class, - enum machine_mode, + machine_mode, rtx, bool); -extern int mips_class_max_nregs (enum reg_class, enum machine_mode); -extern enum machine_mode mips_hard_regno_caller_save_mode (unsigned int, - unsigned int, - enum machine_mode); +extern int mips_class_max_nregs (enum reg_class, machine_mode); + +extern machine_mode mips_hard_regno_caller_save_mode (unsigned int, + unsigned int, + machine_mode); extern int mips_adjust_insn_length (rtx, int); extern void mips_output_load_label (rtx); extern const char *mips_output_conditional_branch (rtx, rtx *, const char *, const char *); +extern const char *mips_output_jump (rtx *, int, int, bool); +extern const char *mips_output_equal_conditional_branch (rtx, rtx *, bool); extern const char *mips_output_order_conditional_branch (rtx, rtx *, bool); extern const char *mips_output_sync (void); extern const char *mips_output_sync_loop (rtx, rtx *); @@ -316,7 +317,7 @@ extern unsigned int mips_sync_loop_insns (rtx, rtx *); extern const char *mips_output_division (const char *, rtx *); extern const char *mips_msa_output_division (const char *, rtx *); extern const char *mips_output_probe_stack_range (rtx, rtx); -extern unsigned int mips_hard_regno_nregs (int, enum machine_mode); +extern unsigned int mips_hard_regno_nregs (int, machine_mode); extern bool mips_linked_madd_p (rtx, rtx); extern bool mips_store_data_bypass_p (rtx, rtx); extern int mips_dspalu_bypass_p (rtx, rtx); @@ -330,9 +331,9 @@ extern const char *mips16e_output_save_restore (rtx, HOST_WIDE_INT); extern bool mips16e_save_restore_pattern_p (rtx, HOST_WIDE_INT, struct mips16e_save_restore_info *); -extern bool mask_low_and_shift_p (enum machine_mode, rtx, rtx, int); -extern int mask_low_and_shift_len (enum machine_mode, rtx, rtx); -extern bool and_operands_ok (enum machine_mode, rtx, rtx); +extern bool mask_low_and_shift_p (machine_mode, rtx, rtx, int); +extern int mask_low_and_shift_len (machine_mode, rtx, rtx); +extern bool and_operands_ok (machine_mode, rtx, rtx); extern bool mips_fmadd_bypass (rtx, rtx); union mips_gen_fn_ptrs @@ -352,7 +353,7 @@ extern void mips_expand_vec_reduc (rtx, rtx, rtx (*)(rtx, rtx, rtx)); extern void mips_expand_vec_minmax (rtx, rtx, rtx, rtx (*) (rtx, rtx, rtx), bool); -extern int mips_ldst_scaled_shift (enum machine_mode); +extern int mips_ldst_scaled_shift (machine_mode); extern bool mips_signed_immediate_p (unsigned HOST_WIDE_INT, int, int); extern bool mips_unsigned_immediate_p (unsigned HOST_WIDE_INT, int, int); extern const char *umips_output_save_restore (bool, rtx); @@ -360,11 +361,11 @@ extern bool umips_save_restore_pattern_p (bool, rtx); 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, enum machine_mode); -extern bool mips_9bit_offset_address_p (rtx, enum machine_mode); -extern bool lwsp_swsp_address_p (rtx, enum machine_mode); -extern bool m16_based_address_p (rtx, enum machine_mode, - int (*)(rtx_def*, machine_mode)); +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)); extern rtx mips_expand_thread_pointer (rtx); extern void mips16_expand_get_fcsr (rtx); extern void mips16_expand_set_fcsr (rtx); @@ -374,14 +375,15 @@ extern bool mips_epilogue_uses (unsigned int); extern void mips_final_prescan_insn (rtx, rtx *, int); extern int mips_trampoline_code_size (void); extern void mips_function_profiler (FILE *); +extern bool mips_load_store_bonding_p (rtx *, machine_mode, bool); typedef rtx (*mulsidi3_gen_fn) (rtx, rtx, rtx); #ifdef RTX_CODE extern mulsidi3_gen_fn mips_mulsidi3_gen_fn (enum rtx_code); #endif -extern void mips_expand_vec_cond_expr (enum machine_mode, - enum machine_mode, +extern void mips_expand_vec_cond_expr (machine_mode, + machine_mode, rtx *, rtx (*)(rtx, rtx, rtx), rtx (*)(rtx, rtx, rtx), diff --git a/gcc-4.9/gcc/config/mips/mips-tables.opt b/gcc-4.9/gcc/config/mips/mips-tables.opt index f963c48ff..36156fd60 100644 --- a/gcc-4.9/gcc/config/mips/mips-tables.opt +++ b/gcc-4.9/gcc/config/mips/mips-tables.opt @@ -679,5 +679,11 @@ EnumValue Enum(mips_arch_opt_value) String(octeon2) Value(96) Canonical EnumValue -Enum(mips_arch_opt_value) String(xlp) Value(97) Canonical +Enum(mips_arch_opt_value) String(octeon3) Value(97) Canonical + +EnumValue +Enum(mips_arch_opt_value) String(xlp) Value(98) Canonical + +EnumValue +Enum(mips_arch_opt_value) String(i6400) Value(99) Canonical diff --git a/gcc-4.9/gcc/config/mips/mips.c b/gcc-4.9/gcc/config/mips/mips.c index cf3894a8e..524c6d52d 100644 --- a/gcc-4.9/gcc/config/mips/mips.c +++ b/gcc-4.9/gcc/config/mips/mips.c @@ -74,36 +74,14 @@ along with GCC; see the file COPYING3. If not see /* Definitions used in ready queue reordering for first scheduling pass. */ -/* Register types. */ -#define GPREG 0 -#define VECREG 1 - -/* Information about GP and vector register weights - indexed by instruction UID. */ -struct msched_weight_info { - int reg_weight_gp; - int reg_weight_vec; -}; - -static msched_weight_info *regtype_weight = NULL; - -/* Current vector and GP register weights of scheduled instructions. */ -static int curr_regtype_pressure[2]; - -/* Return GP register weight for INSN. */ -#define INSN_GPREG_WEIGHT(INSN) \ - regtype_weight[INSN_UID ((INSN))].reg_weight_gp - -/* Return vector register weight for INSN. */ -#define INSN_VECREG_WEIGHT(INSN) \ - regtype_weight[INSN_UID ((INSN))].reg_weight_vec +static int *level = NULL; +static int *consumer_luid = NULL; -/* Return current register pressure for REG_TYPE. */ -#define CURR_REGTYPE_PRESSURE(REG_TYPE) \ - curr_regtype_pressure[(REG_TYPE)] +#define LEVEL(INSN) \ + level[INSN_UID ((INSN))] -#define PROMOTE_HIGH_PRIORITY_PRESSURE 25 -#define PROMOTE_MAX_DEP_PRESSURE 15 +#define CONSUMER_LUID(INSN) \ + consumer_luid[INSN_UID ((INSN))] /* True if X is an UNSPEC wrapper around a SYMBOL_REF or LABEL_REF. */ #define UNSPEC_ADDRESS_P(X) \ @@ -198,7 +176,8 @@ static int curr_regtype_pressure[2]; /* 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) | (ISA_HAS_JR ? 0x8 : 0x9)) + (TARGET_CB_ALWAYS ? ((0x1b << 27) | ((DEST) << 16)) \ + : (((DEST) << 21) | (ISA_HAS_JR ? 0x8 : 0x9))) /* Return the opcode for: @@ -802,8 +781,8 @@ static const struct mips_rtx_cost_data mips_rtx_cost_optimize_size = { COSTS_N_INSNS (1), /* int_mult_di */ COSTS_N_INSNS (1), /* int_div_si */ COSTS_N_INSNS (1), /* int_div_di */ - 2, /* branch_cost */ - 4 /* memory_latency */ + 2, /* branch_cost */ + 4 /* memory_latency */ }; /* Costs to use when optimizing for speed, indexed by processor. */ @@ -990,6 +969,20 @@ static const struct mips_rtx_cost_data 4, /* branch_cost */ 4 /* memory_latency */ }, + /* Octeon III */ + { + COSTS_N_INSNS (6), /* fp_add */ + COSTS_N_INSNS (6), /* fp_mult_sf */ + COSTS_N_INSNS (7), /* fp_mult_df */ + COSTS_N_INSNS (25), /* fp_div_sf */ + COSTS_N_INSNS (48), /* fp_div_df */ + COSTS_N_INSNS (6), /* int_mult_si */ + COSTS_N_INSNS (6), /* int_mult_di */ + COSTS_N_INSNS (18), /* int_div_si */ + COSTS_N_INSNS (35), /* int_div_di */ + 4, /* branch_cost */ + 4 /* memory_latency */ + }, { /* R3900 */ COSTS_N_INSNS (2), /* fp_add */ COSTS_N_INSNS (4), /* fp_mult_sf */ @@ -1224,7 +1217,7 @@ static const struct mips_rtx_cost_data COSTS_N_INSNS (8), /* int_div_si */ COSTS_N_INSNS (8), /* int_div_di */ 2, /* branch_cost */ - 10 /* memory_latency */ + 4 /* memory_latency */ }, { /* W32 */ COSTS_N_INSNS (4), /* fp_add */ @@ -1251,14 +1244,27 @@ static const struct mips_rtx_cost_data COSTS_N_INSNS (41), /* int_div_di */ 1, /* branch_cost */ 4 /* memory_latency */ + }, + { /* I6400 */ + COSTS_N_INSNS (4), /* fp_add */ + COSTS_N_INSNS (5), /* fp_mult_sf */ + COSTS_N_INSNS (5), /* fp_mult_df */ + COSTS_N_INSNS (32), /* 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 (36), /* int_div_si */ + COSTS_N_INSNS (36), /* int_div_di */ + 2, /* branch_cost */ + 4 /* memory_latency */ } }; static rtx mips_find_pic_call_symbol (rtx, rtx, bool); -static int mips_register_move_cost (enum machine_mode, reg_class_t, +static int mips_register_move_cost (machine_mode, reg_class_t, reg_class_t); -static unsigned int mips_function_arg_boundary (enum machine_mode, const_tree); -static enum machine_mode mips_get_reg_raw_mode (int regno); +static unsigned int mips_function_arg_boundary (machine_mode, const_tree); +static machine_mode mips_get_reg_raw_mode (int regno); /* This hash table keeps track of implicit "mips16" and "nomips16" attributes for -mflip_mips16. It maps decl names onto a boolean mode setting. */ @@ -1686,7 +1692,7 @@ mips_build_integer (struct mips_integer_op *codes, /* Implement TARGET_LEGITIMATE_CONSTANT_P. */ static bool -mips_legitimate_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x) +mips_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x) { return mips_const_insns (x) > 0; } @@ -1857,7 +1863,7 @@ mips_symbol_binds_local_p (const_rtx x) } bool -mips_const_vector_bitimm_set_p (rtx op, enum machine_mode mode) +mips_const_vector_bitimm_set_p (rtx op, machine_mode mode) { if (GET_CODE (op) == CONST_VECTOR && op != const0_rtx) { @@ -1879,7 +1885,7 @@ mips_const_vector_bitimm_set_p (rtx op, enum machine_mode mode) } bool -mips_const_vector_bitimm_clr_p (rtx op, enum machine_mode mode) +mips_const_vector_bitimm_clr_p (rtx op, machine_mode mode) { if (GET_CODE (op) == CONST_VECTOR && op != constm1_rtx) { @@ -1901,10 +1907,10 @@ mips_const_vector_bitimm_clr_p (rtx op, enum machine_mode mode) } /* Return true if OP is a constant vector with the number of units in MODE, - and each unit has the same value. */ + and each unit has the same value. */ bool -mips_const_vector_same_val_p (rtx op, enum machine_mode mode) +mips_const_vector_same_val_p (rtx op, machine_mode mode) { int i, nunits = GET_MODE_NUNITS (mode); rtx first; @@ -1921,10 +1927,10 @@ mips_const_vector_same_val_p (rtx op, enum machine_mode mode) } /* Return true if OP is a constant vector with the number of units in MODE, - and each unit has the same value. */ + and each unit has the same value. */ bool -mips_const_vector_same_byte_p (rtx op, enum machine_mode mode) +mips_const_vector_same_byte_p (rtx op, machine_mode mode) { int i, nunits = GET_MODE_NUNITS (mode); rtx first; @@ -1939,7 +1945,7 @@ mips_const_vector_same_byte_p (rtx op, enum machine_mode mode) if (!rtx_equal_p (first, CONST_VECTOR_ELT (op, i))) return false; - /* it's a 8-bit mode don't care if signed or unsigned */ + /* It's an 8-bit mode don't care if signed or unsigned. */ return true; } @@ -1947,7 +1953,7 @@ mips_const_vector_same_byte_p (rtx op, enum machine_mode mode) and each unit has the same integer value in the range [LOW, HIGH]. */ bool -mips_const_vector_same_int_p (rtx op, enum machine_mode mode, HOST_WIDE_INT low, +mips_const_vector_same_int_p (rtx op, machine_mode mode, HOST_WIDE_INT low, HOST_WIDE_INT high) { HOST_WIDE_INT value; @@ -1968,7 +1974,7 @@ mips_const_vector_same_int_p (rtx op, enum machine_mode mode, HOST_WIDE_INT low, data section. */ static bool -mips_rtx_constant_in_small_data_p (enum machine_mode mode) +mips_rtx_constant_in_small_data_p (machine_mode mode) { return (!TARGET_EMBEDDED_DATA && TARGET_LOCAL_SDATA @@ -2221,7 +2227,7 @@ mips_symbolic_constant_p (rtx x, enum mips_symbol_context context, extended ones. */ static int -mips_symbol_insns_1 (enum mips_symbol_type type, enum machine_mode mode) +mips_symbol_insns_1 (enum mips_symbol_type type, machine_mode mode) { if (mips_use_pcrel_pool_p[(int) type]) { @@ -2333,7 +2339,7 @@ mips_symbol_insns_1 (enum mips_symbol_type type, enum machine_mode mode) In both cases, instruction counts are based off BASE_INSN_LENGTH. */ static int -mips_symbol_insns (enum mips_symbol_type type, enum machine_mode mode) +mips_symbol_insns (enum mips_symbol_type type, machine_mode mode) { /* MSA LD.* and ST.* cannot support loading symbols via an immediate operand. */ @@ -2355,7 +2361,7 @@ mips_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED) /* Implement TARGET_CANNOT_FORCE_CONST_MEM. */ static bool -mips_cannot_force_const_mem (enum machine_mode mode, rtx x) +mips_cannot_force_const_mem (machine_mode mode, rtx x) { enum mips_symbol_type type; rtx base, offset; @@ -2405,7 +2411,7 @@ mips_cannot_force_const_mem (enum machine_mode mode, rtx x) constants when we're using a per-function constant pool. */ static bool -mips_use_blocks_for_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED, +mips_use_blocks_for_constant_p (machine_mode mode ATTRIBUTE_UNUSED, const_rtx x ATTRIBUTE_UNUSED) { return !TARGET_MIPS16_PCREL_LOADS; @@ -2415,7 +2421,7 @@ mips_use_blocks_for_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED, STRICT_P is true if REG_OK_STRICT is in effect. */ int -mips_regno_mode_ok_for_base_p (int regno, enum machine_mode mode, +mips_regno_mode_ok_for_base_p (int regno, machine_mode mode, bool strict_p) { if (!HARD_REGISTER_NUM_P (regno)) @@ -2443,7 +2449,7 @@ mips_regno_mode_ok_for_base_p (int regno, enum machine_mode mode, STRICT_P is true if REG_OK_STRICT is in effect. */ static bool -mips_valid_base_register_p (rtx x, enum machine_mode mode, bool strict_p) +mips_valid_base_register_p (rtx x, machine_mode mode, bool strict_p) { if (!strict_p && GET_CODE (x) == SUBREG) x = SUBREG_REG (x); @@ -2456,7 +2462,7 @@ mips_valid_base_register_p (rtx x, enum machine_mode mode, bool strict_p) can address a value of mode MODE. */ static bool -mips_valid_offset_p (rtx x, enum machine_mode mode) +mips_valid_offset_p (rtx x, machine_mode mode) { /* Check that X is a signed 16-bit number. */ if (!const_arith_operand (x, Pmode)) @@ -2469,7 +2475,7 @@ mips_valid_offset_p (rtx x, enum machine_mode mode) return false; /* MSA LD.* and ST.* supports 10-bit signed offsets. */ - if (MSA_SUPPORTED_VECTOR_MODE_P (mode) + if (MSA_SUPPORTED_MODE_P (mode) && !mips_signed_immediate_p (INTVAL (x), 10, mips_ldst_scaled_shift (mode))) return false; @@ -2481,7 +2487,7 @@ mips_valid_offset_p (rtx x, enum machine_mode mode) LO_SUM symbol has type SYMBOL_TYPE. */ static bool -mips_valid_lo_sum_p (enum mips_symbol_type symbol_type, enum machine_mode mode) +mips_valid_lo_sum_p (enum mips_symbol_type symbol_type, machine_mode mode) { /* Check that symbols of type SYMBOL_TYPE can be used to access values of mode MODE. */ @@ -2513,7 +2519,7 @@ mips_valid_lo_sum_p (enum mips_symbol_type symbol_type, enum machine_mode mode) static bool mips_classify_address (struct mips_address_info *info, rtx x, - enum machine_mode mode, bool strict_p) + machine_mode mode, bool strict_p) { switch (GET_CODE (x)) { @@ -2572,7 +2578,7 @@ mips_classify_address (struct mips_address_info *info, rtx x, /* Implement TARGET_LEGITIMATE_ADDRESS_P. */ static bool -mips_legitimate_address_p (enum machine_mode mode, rtx x, bool strict_p) +mips_legitimate_address_p (machine_mode mode, rtx x, bool strict_p) { struct mips_address_info addr; @@ -2582,7 +2588,7 @@ mips_legitimate_address_p (enum machine_mode mode, rtx x, bool strict_p) /* Return true if X is a legitimate $sp-based address for mode MDOE. */ bool -mips_stack_address_p (rtx x, enum machine_mode mode) +mips_stack_address_p (rtx x, machine_mode mode) { struct mips_address_info addr; @@ -2619,7 +2625,7 @@ mips_lwxs_address_p (rtx addr) sense, because their use is so restricted. */ static bool -mips_lx_address_p (rtx addr, enum machine_mode mode) +mips_lx_address_p (rtx addr, machine_mode mode) { if (GET_CODE (addr) != PLUS || !REG_P (XEXP (addr, 0)) @@ -2633,7 +2639,7 @@ mips_lx_address_p (rtx addr, enum machine_mode mode) return true; if (ISA_HAS_LDX && mode == DImode) return true; - if (ISA_HAS_MSA && MSA_SUPPORTED_MODE_P (mode)) + if (MSA_SUPPORTED_MODE_P (mode)) return true; return false; } @@ -2648,7 +2654,7 @@ mips_lx_address_p (rtx addr, enum machine_mode mode) an 8-bit immediate field that's shifted left twice. */ static bool -mips16_unextended_reference_p (enum machine_mode mode, rtx base, +mips16_unextended_reference_p (machine_mode mode, rtx base, unsigned HOST_WIDE_INT offset) { if (mode != BLKmode && offset % GET_MODE_SIZE (mode) == 0) @@ -2668,11 +2674,11 @@ mips16_unextended_reference_p (enum machine_mode mode, rtx base, enough. */ int -mips_address_insns (rtx x, enum machine_mode mode, bool might_split_p) +mips_address_insns (rtx x, machine_mode mode, bool might_split_p) { struct mips_address_info addr; int factor; - bool msa_p = (TARGET_MSA && !might_split_p && MSA_SUPPORTED_MODE_P (mode)); + bool msa_p = (!might_split_p && MSA_SUPPORTED_MODE_P (mode)); /* BLKmode is used for single unaligned loads and stores and should not count as a multiword mode. (GET_MODE_SIZE (BLKmode) is pretty @@ -2690,9 +2696,8 @@ mips_address_insns (rtx x, enum machine_mode mode, bool might_split_p) if (msa_p) { /* MSA LD.* and ST.* supports 10-bit signed offsets. */ - if (MSA_SUPPORTED_VECTOR_MODE_P (mode) - && mips_signed_immediate_p (INTVAL (addr.offset), 10, - mips_ldst_scaled_shift (mode))) + if (mips_signed_immediate_p (INTVAL (addr.offset), 10, + mips_ldst_scaled_shift (mode))) return 1; else return 0; @@ -2734,10 +2739,10 @@ mips_signed_immediate_p (unsigned HOST_WIDE_INT x, int bits, int shift = 0) return mips_unsigned_immediate_p (x, bits, shift); } -/* Return the scale shift that applied to MSA LD/ST address offset */ +/* Return the scale shift that applied to MSA LD/ST address offset. */ int -mips_ldst_scaled_shift (enum machine_mode mode) +mips_ldst_scaled_shift (machine_mode mode) { int shift = exact_log2 (GET_MODE_UNIT_SIZE (mode)); @@ -2752,7 +2757,7 @@ mips_ldst_scaled_shift (enum machine_mode mode) OFFSET_PREDICATE. */ bool -m16_based_address_p (rtx x, enum machine_mode mode, +m16_based_address_p (rtx x, machine_mode mode, insn_operand_predicate_fn offset_predicate) { struct mips_address_info addr; @@ -2767,7 +2772,7 @@ m16_based_address_p (rtx x, enum machine_mode mode, for a microMIPS LWSP or SWSP insn. */ bool -lwsp_swsp_address_p (rtx x, enum machine_mode mode) +lwsp_swsp_address_p (rtx x, machine_mode mode) { struct mips_address_info addr; @@ -2781,7 +2786,7 @@ lwsp_swsp_address_p (rtx x, enum machine_mode mode) MODE is the mode of the value being accessed. */ bool -umips_12bit_offset_address_p (rtx x, enum machine_mode mode) +umips_12bit_offset_address_p (rtx x, machine_mode mode) { struct mips_address_info addr; @@ -2795,7 +2800,7 @@ umips_12bit_offset_address_p (rtx x, enum machine_mode mode) MODE is the mode of the value being accessed. */ bool -mips_9bit_offset_address_p (rtx x, enum machine_mode mode) +mips_9bit_offset_address_p (rtx x, machine_mode mode) { struct mips_address_info addr; @@ -2846,7 +2851,7 @@ mips_const_insns (rtx x) if (TARGET_MSA && mips_const_vector_same_int_p (x, GET_MODE (x), -512, 511)) return 1; - /* fall through. */ + /* Fall through. */ case CONST_DOUBLE: /* Allow zeros for normal mode, where we can use $0. */ return !TARGET_MIPS16 && x == CONST0_RTX (GET_MODE (x)) ? 1 : 0; @@ -2907,23 +2912,24 @@ mips_split_const_insns (rtx x) return low + high; } -/* X is a 128-bit constant that can be handled by splitting it into - two or four words and loading each word separately. Return the number of - instructions required to do this. */ +/* Return one word of 128-bit value OP, taking into account the fixed + endianness of certain registers. BYTE selects from the byte address. */ -int -mips_split_128bit_const_insns (rtx x) +rtx +mips_subword_at_byte (rtx op, unsigned int byte) { - int byte; - unsigned int elem, total = 0; + machine_mode mode; - for (byte = 0; byte < GET_MODE_SIZE (TImode); byte += UNITS_PER_WORD) - { - elem = mips_const_insns (mips_subword_at_byte (x, byte)); - gcc_assert (elem > 0); - total += elem; - } - return total; + mode = GET_MODE (op); + if (mode == VOIDmode) + mode = TImode; + + gcc_assert (!FP_REG_RTX_P (op)); + + if (MEM_P (op)) + return mips_rewrite_small_data (adjust_address (op, word_mode, byte)); + + return simplify_gen_subreg (word_mode, op, mode, byte); } /* Return the number of instructions needed to implement INSN, @@ -2933,7 +2939,7 @@ mips_split_128bit_const_insns (rtx x) int mips_load_store_insns (rtx mem, rtx insn) { - enum machine_mode mode; + machine_mode mode; bool might_split_p; rtx set; @@ -2948,12 +2954,6 @@ mips_load_store_insns (rtx mem, rtx insn) if (set && !mips_split_move_insn_p (SET_DEST (set), SET_SRC (set), insn)) might_split_p = false; } - else if (GET_MODE_BITSIZE (mode) == 128) - { - set = single_set (insn); - if (set && !mips_split_128bit_move_p (SET_DEST (set), SET_SRC (set))) - might_split_p = false; - } return mips_address_insns (XEXP (mem, 0), mode, might_split_p); } @@ -3030,7 +3030,7 @@ mips_emit_unary (enum rtx_code code, rtx target, rtx op0) Return that new register. */ static rtx -mips_force_unary (enum machine_mode mode, enum rtx_code code, rtx op0) +mips_force_unary (machine_mode mode, enum rtx_code code, rtx op0) { rtx reg; @@ -3052,7 +3052,7 @@ mips_emit_binary (enum rtx_code code, rtx target, rtx op0, rtx op1) of mode MODE. Return that new register. */ static rtx -mips_force_binary (enum machine_mode mode, enum rtx_code code, rtx op0, rtx op1) +mips_force_binary (machine_mode mode, enum rtx_code code, rtx op0, rtx op1) { rtx reg; @@ -3300,7 +3300,7 @@ mips_got_load (rtx temp, rtx addr, enum mips_symbol_type type) is guaranteed to be a legitimate address for mode MODE. */ bool -mips_split_symbol (rtx temp, rtx addr, enum machine_mode mode, rtx *low_out) +mips_split_symbol (rtx temp, rtx addr, machine_mode mode, rtx *low_out) { enum mips_symbol_context context; enum mips_symbol_type symbol_type; @@ -3560,7 +3560,7 @@ mips16_expand_set_fcsr (rtx newval) /* If X is not a valid address for mode MODE, force it into a register. */ static rtx -mips_force_address (rtx x, enum machine_mode mode) +mips_force_address (rtx x, machine_mode mode) { if (!mips_legitimate_address_p (mode, x, false)) x = force_reg (Pmode, x); @@ -3574,7 +3574,7 @@ mips_force_address (rtx x, enum machine_mode mode) static rtx mips_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, - enum machine_mode mode) + machine_mode mode) { rtx base, addr; HOST_WIDE_INT offset; @@ -3605,7 +3605,7 @@ void mips_move_integer (rtx temp, rtx dest, unsigned HOST_WIDE_INT value) { struct mips_integer_op codes[MIPS_MAX_INTEGER_OPS]; - enum machine_mode mode; + machine_mode mode; unsigned int i, num_ops; rtx x; @@ -3635,7 +3635,7 @@ mips_move_integer (rtx temp, rtx dest, unsigned HOST_WIDE_INT value) move_operand. */ static void -mips_legitimize_const_move (enum machine_mode mode, rtx dest, rtx src) +mips_legitimize_const_move (machine_mode mode, rtx dest, rtx src) { rtx base, offset; @@ -3686,12 +3686,16 @@ mips_legitimize_const_move (enum machine_mode mode, rtx dest, rtx src) sequence that is valid. */ bool -mips_legitimize_move (enum machine_mode mode, rtx dest, rtx src) +mips_legitimize_move (machine_mode mode, rtx dest, rtx src) { - if (!register_operand (dest, mode) && !reg_or_0_operand (src, mode)) + if (!register_operand (dest, mode) && !register_operand (src, mode)) { - mips_emit_move (dest, force_reg (mode, src)); - return true; + if (TARGET_MIPS16 || !const_0_operand (src, mode) + || MSA_SUPPORTED_MODE_P (mode)) + { + mips_emit_move (dest, force_reg (mode, src)); + return true; + } } /* We need to deal with constants that would be legitimate @@ -3932,7 +3936,7 @@ mips_binary_cost (rtx x, int single_cost, int double_cost, bool speed) /* Return the cost of floating-point multiplications of mode MODE. */ static int -mips_fp_mult_cost (enum machine_mode mode) +mips_fp_mult_cost (machine_mode mode) { return mode == DFmode ? mips_cost->fp_mult_df : mips_cost->fp_mult_sf; } @@ -3940,7 +3944,7 @@ mips_fp_mult_cost (enum machine_mode mode) /* Return the cost of floating-point divisions of mode MODE. */ static int -mips_fp_div_cost (enum machine_mode mode) +mips_fp_div_cost (machine_mode mode) { return mode == DFmode ? mips_cost->fp_div_df : mips_cost->fp_div_sf; } @@ -3949,7 +3953,7 @@ mips_fp_div_cost (enum machine_mode mode) cost of OP itself. */ static int -mips_sign_extend_cost (enum machine_mode mode, rtx op) +mips_sign_extend_cost (machine_mode mode, rtx op) { if (MEM_P (op)) /* Extended loads are as cheap as unextended ones. */ @@ -3971,7 +3975,7 @@ mips_sign_extend_cost (enum machine_mode mode, rtx op) cost of OP itself. */ static int -mips_zero_extend_cost (enum machine_mode mode, rtx op) +mips_zero_extend_cost (machine_mode mode, rtx op) { if (MEM_P (op)) /* Extended loads are as cheap as unextended ones. */ @@ -3997,7 +4001,7 @@ mips_zero_extend_cost (enum machine_mode mode, rtx op) assuming that the move will be in pieces of at most UNITS bytes. */ static int -mips_set_reg_reg_piece_cost (enum machine_mode mode, unsigned int units) +mips_set_reg_reg_piece_cost (machine_mode mode, unsigned int units) { return COSTS_N_INSNS ((GET_MODE_SIZE (mode) + units - 1) / units); } @@ -4005,7 +4009,7 @@ mips_set_reg_reg_piece_cost (enum machine_mode mode, unsigned int units) /* Return the cost of moving between two registers of mode MODE. */ static int -mips_set_reg_reg_cost (enum machine_mode mode) +mips_set_reg_reg_cost (machine_mode mode) { switch (GET_MODE_CLASS (mode)) { @@ -4030,7 +4034,7 @@ static bool mips_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED, int *total, bool speed) { - enum machine_mode mode = GET_MODE (x); + machine_mode mode = GET_MODE (x); bool float_mode_p = FLOAT_MODE_P (mode); int cost; rtx addr; @@ -4309,17 +4313,18 @@ mips_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED, return false; } - /* If it's an add + mult (which is equivalent to shift left) - * and it's immediate operand satisfies const_immlsa_operand - * predicate. */ - if (ISA_HAS_LSA - && mode == SImode + /* If it's an add + mult (which is equivalent to shift left) and + it's immediate operand satisfies const_immlsa_operand predicate. */ + if (((ISA_HAS_LSA && mode == SImode) + || (ISA_HAS_DLSA && mode == DImode)) && GET_CODE (XEXP (x, 0)) == MULT) { rtx op2 = XEXP (XEXP (x, 0), 1); if (const_immlsa_operand (op2, mode)) { - *total = 0; + *total = (COSTS_N_INSNS (1) + + set_src_cost (XEXP (XEXP (x, 0), 0), speed) + + set_src_cost (XEXP (x, 1), speed)); return true; } } @@ -4359,11 +4364,15 @@ 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); else if (mode == DImode && !TARGET_64BIT) - /* R6 impact ??? */ /* Synthesized from 2 mulsi3s, 1 mulsidi3 and two additions, where the mulsidi3 always includes an MFHI and an MFLO. */ *total = (speed @@ -4522,7 +4531,7 @@ mips_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED, /* Implement TARGET_ADDRESS_COST. */ static int -mips_address_cost (rtx addr, enum machine_mode mode, +mips_address_cost (rtx addr, machine_mode mode, addr_space_t as ATTRIBUTE_UNUSED, bool speed ATTRIBUTE_UNUSED) { @@ -4657,7 +4666,7 @@ rtx mips_subword (rtx op, bool high_p) { unsigned int byte, offset; - enum machine_mode mode; + machine_mode mode; mode = GET_MODE (op); if (mode == VOIDmode) @@ -4681,26 +4690,6 @@ mips_subword (rtx op, bool high_p) return simplify_gen_subreg (word_mode, op, mode, byte); } -/* Return one word of 128-bit value OP, taking into account the fixed - endianness of certain registers. BYTE selects from the byte address. */ - -rtx -mips_subword_at_byte (rtx op, unsigned int byte) -{ - enum machine_mode mode; - - mode = GET_MODE (op); - if (mode == VOIDmode) - mode = TImode; - - gcc_assert (!FP_REG_RTX_P (op)); - - if (MEM_P (op)) - return mips_rewrite_small_data (adjust_address (op, word_mode, byte)); - - return simplify_gen_subreg (word_mode, op, mode, byte); -} - /* Return true if SRC should be moved into DEST using "MULT $0, $0". SPLIT_TYPE is the condition under which moves should be split. */ @@ -4742,19 +4731,14 @@ mips_split_move_p (rtx dest, rtx src, enum mips_split_type split_type) return false; } - /* Check if MSA moves need splitting. */ - if (MSA_SUPPORTED_MODE_P (GET_MODE (dest)) - || MSA_SUPPORTED_MODE_P (GET_MODE (src))) + /* Check if MSA moves need splitting. */ + if (MSA_SUPPORTED_MODE_P (GET_MODE (dest))) return mips_split_128bit_move_p (dest, src); /* Otherwise split all multiword moves. */ return size > UNITS_PER_WORD; } -/* Determine if the DEST,SRC move insn applies to MSA. */ -#define MSA_SPLIT_P(DEST, SRC) \ - (MSA_SUPPORTED_MODE_P (GET_MODE (DEST)) && MSA_SUPPORTED_MODE_P (GET_MODE (SRC))) - /* Split a move from SRC to DEST, given that mips_split_move_p holds. SPLIT_TYPE describes the split condition. */ @@ -4764,8 +4748,9 @@ mips_split_move (rtx dest, rtx src, enum mips_split_type split_type) rtx low_dest; gcc_checking_assert (mips_split_move_p (dest, src, split_type)); - if (!MSA_SPLIT_P (dest, src) - && (FP_REG_RTX_P (dest)|| FP_REG_RTX_P (src))) + if (MSA_SUPPORTED_MODE_P (GET_MODE (dest))) + mips_split_128bit_move (dest, src); + else if (FP_REG_RTX_P (dest) || FP_REG_RTX_P (src)) { if (!TARGET_64BIT && GET_MODE (dest) == DImode) emit_insn (gen_move_doubleword_fprdi (dest, src)); @@ -4801,13 +4786,6 @@ mips_split_move (rtx dest, rtx src, enum mips_split_type split_type) else emit_insn (gen_mfhisi_di (mips_subword (dest, true), src)); } - else if (MSA_SPLIT_P (dest, src)) - { - /* Temporary sanity check should only get here if - * a 128bit move needed spliting. */ - gcc_assert (mips_split_128bit_move_p (dest, src)); - mips_split_128bit_move (dest, src); - } else { /* The operation can be split into two normal moves. Decide in @@ -4845,8 +4823,8 @@ mips_insn_split_type (rtx insn) return SPLIT_IF_NECESSARY; } -/* Return true if a 128-bit move from SRC to DEST should be split into two - or four. */ +/* Return true if a 128-bit move from SRC to DEST should be split. */ + bool mips_split_128bit_move_p (rtx dest, rtx src) { @@ -4860,7 +4838,8 @@ mips_split_128bit_move_p (rtx dest, rtx src) if (FP_REG_RTX_P (src) && MEM_P (dest)) return false; - /* Check for MSA set to an immediate const vector with valid replicated element. */ + /* Check for MSA set to an immediate const vector with valid replicated + element. */ if (FP_REG_RTX_P (dest) && mips_const_vector_same_int_p (src, GET_MODE (src), -512, 511)) return false; @@ -4874,7 +4853,7 @@ void mips_split_128bit_move (rtx dest, rtx src) { int byte, index; - rtx low_dest, low_src, d, s, last_d, last_s; + rtx low_dest, low_src, d, s; if (FP_REG_RTX_P (dest)) { @@ -4930,74 +4909,37 @@ mips_split_128bit_move (rtx dest, rtx src) emit_insn (gen_msa_copy_s_d (d, new_src, GEN_INT (index))); } } - else if (REG_P (dest) && REGNO (dest) == MD_REG_FIRST) - { - gcc_assert (TARGET_64BIT); - - low_dest = mips_subword (dest, false); - mips_emit_move (low_dest, mips_subword (src, false)); - emit_insn (gen_mthidi_ti (dest, mips_subword (src, true), low_dest)); - } - else if (REG_P (src) && REGNO (src) == MD_REG_FIRST) - { - gcc_assert (TARGET_64BIT); - - mips_emit_move (mips_subword (dest, false), mips_subword (src, false)); - emit_insn (gen_mfhidi_ti (mips_subword (dest, true), src)); - } else { - low_dest = mips_subword_at_byte (dest, false); - low_src = mips_subword_at_byte (src, false); - last_d = NULL; - last_s = NULL; - if (REG_P (low_dest) && REG_P (low_src)) + low_dest = mips_subword_at_byte (dest, 0); + low_src = mips_subword_at_byte (src, 0); + gcc_assert (REG_P (low_dest) && REG_P (low_src)); + /* Make sure the source register is not written before reading. */ + if (REGNO (low_dest) <= REGNO (low_src)) { - /* Make sure the source register is not written before reading. */ - if (REGNO (low_dest) <= REGNO (low_src)) + for (byte = 0; byte < GET_MODE_SIZE (TImode); + byte += UNITS_PER_WORD) { - for (byte = 0; byte < GET_MODE_SIZE (TImode); - byte += UNITS_PER_WORD) - { - d = mips_subword_at_byte (dest, byte); - s = mips_subword_at_byte (src, byte); - mips_emit_move (d, s); - } - } - else - { - for (byte = GET_MODE_SIZE (TImode) - UNITS_PER_WORD; byte >= 0; - byte -= UNITS_PER_WORD) - { - d = mips_subword_at_byte (dest, byte); - s = mips_subword_at_byte (src, byte); - mips_emit_move (d, s); - } + d = mips_subword_at_byte (dest, byte); + s = mips_subword_at_byte (src, byte); + mips_emit_move (d, s); } } else { - for (byte = 0; byte < GET_MODE_SIZE (TImode); byte += UNITS_PER_WORD) + for (byte = GET_MODE_SIZE (TImode) - UNITS_PER_WORD; byte >= 0; + byte -= UNITS_PER_WORD) { d = mips_subword_at_byte (dest, byte); s = mips_subword_at_byte (src, byte); - if (REG_P (low_dest) && reg_overlap_mentioned_p (d, src)) - { - gcc_assert (last_d == NULL && last_s == NULL); - last_d = d; - last_s = s; - } - else - mips_emit_move (d, s); + mips_emit_move (d, s); } - if (last_d != NULL && last_s != NULL) - mips_emit_move (last_d, last_s); } } } -/* Split a COPY_S.D with operands DEST, SRC and INDEX. GEN is a function - * used to generate subregs. */ +/* Split a COPY_S.D with operands DEST, SRC and INDEX. GEN is a function + used to generate subregs. */ void mips_split_msa_copy_d (rtx dest, rtx src, rtx index, @@ -5016,11 +4958,12 @@ mips_split_msa_copy_d (rtx dest, rtx src, rtx index, emit_insn (gen_fn (high, new_src, GEN_INT (INTVAL (index) * 2 + 1))); } -/* Split a INSERT.D with operand DEST, SRC1.INDEX and SRC2. */ +/* Split a INSERT.D with operand DEST, SRC1.INDEX and SRC2. */ void mips_split_msa_insert_d (rtx dest, rtx src1, rtx index, rtx src2) { + int i; gcc_assert (GET_MODE (dest) == GET_MODE (src1)); gcc_assert ((GET_MODE (dest) == V2DImode && (GET_MODE (src2) == DImode || src2 == const0_rtx)) @@ -5032,10 +4975,13 @@ mips_split_msa_insert_d (rtx dest, rtx src1, rtx index, rtx src2) rtx high = mips_subword (src2, true); rtx new_dest = simplify_gen_subreg (V4SImode, dest, GET_MODE (dest), 0); rtx new_src1 = simplify_gen_subreg (V4SImode, src1, GET_MODE (src1), 0); + i = exact_log2 (INTVAL (index)); + gcc_assert (i != -1); + emit_insn (gen_msa_insert_w (new_dest, new_src1, - GEN_INT (INTVAL (index) * 2), low)); + GEN_INT (i * 2), low)); emit_insn (gen_msa_insert_w (new_dest, new_dest, - GEN_INT (INTVAL (index) * 2 + 1), high)); + GEN_INT (i * 2 + 1), high)); } /* Split fill.d. */ @@ -5089,20 +5035,25 @@ mips_split_move_insn (rtx dest, rtx src, rtx insn) const char * mips_output_move (rtx dest, rtx src) { - enum rtx_code dest_code, src_code; - enum machine_mode mode; + enum rtx_code dest_code = GET_CODE (dest); + enum rtx_code src_code = GET_CODE (src); + machine_mode mode = GET_MODE (dest); + bool dbl_p = (GET_MODE_SIZE (mode) == 8); + bool msa_p = MSA_SUPPORTED_MODE_P (mode); enum mips_symbol_type symbol_type; - bool dbl_p, msa_p; - - dest_code = GET_CODE (dest); - src_code = GET_CODE (src); - mode = GET_MODE (dest); - dbl_p = (GET_MODE_SIZE (mode) == 8); - msa_p = MSA_SUPPORTED_MODE_P (mode); if (mips_split_move_p (dest, src, SPLIT_IF_NECESSARY)) return "#"; + if (msa_p + && dest_code == REG && FP_REG_P (REGNO (dest)) + && src_code == CONST_VECTOR + && CONST_INT_P (CONST_VECTOR_ELT (src, 0))) + { + gcc_assert (const_yi_operand (src, mode)); + return "ldi.%v0\t%w0,%E1"; + } + if ((src_code == REG && GP_REG_P (REGNO (src))) || (!TARGET_MIPS16 && src == CONST0_RTX (mode))) { @@ -5121,7 +5072,12 @@ mips_output_move (rtx dest, rtx src) /* Moves to HI are handled by special .md insns. */ if (REGNO (dest) == LO_REGNUM) - return "mtlo\t%z1"; + { + if (ISA_HAS_MULT) + return "mtlo\t%z1"; + else + return "mtlo\t%z1,$ac0"; + } if (DSP_ACC_REG_P (REGNO (dest))) { @@ -5136,17 +5092,8 @@ mips_output_move (rtx dest, rtx src) { if (msa_p) { - enum machine_mode dstmode = GET_MODE (dest); - gcc_assert (src == CONST0_RTX (GET_MODE (src))); - - if (MSA_SUPPORTED_MODE_P (dstmode)) - { - if (dstmode == TImode) - return "ldi.b\t%w0,0"; - else - return "ldi.%v0\t%w0,0"; - } + return "ldi.%v0\t%w0,0"; } return dbl_p ? "dmtc1\t%z1,%0" : "mtc1\t%z1,%0"; @@ -5183,7 +5130,10 @@ mips_output_move (rtx dest, rtx src) -mfix-vr4130. */ if (ISA_HAS_MACCHI) return dbl_p ? "dmacc\t%0,%.,%." : "macc\t%0,%.,%."; - return "mflo\t%0"; + if (ISA_HAS_MULT) + return "mflo\t%0"; + else + return "mflo\t%0,$ac0"; } if (DSP_ACC_REG_P (REGNO (src))) @@ -5272,16 +5222,8 @@ mips_output_move (rtx dest, rtx src) if (dest_code == MEM) { - if (MSA_SUPPORTED_MODE_P (mode)) - { - if (mode == TImode) - { - /* Just use st.d/st.w to store. */ - return TARGET_64BIT ? "st.d\t%w1,%0" : "st.w\t%w1,%0"; - } - else - return "st.%v1\t%w1,%0"; - } + if (msa_p) + return "st.%v1\t%w1,%0"; return dbl_p ? "sdc1\t%1,%0" : "swc1\t%1,%0"; } @@ -5290,16 +5232,8 @@ mips_output_move (rtx dest, rtx src) { if (src_code == MEM) { - if (MSA_SUPPORTED_MODE_P (mode)) - { - if (mode == TImode) - { - /* Just use ld.d/ld.w to load. */ - return TARGET_64BIT ? "ld.d\t%w0,%1" : "ld.w\t%w0,%1"; - } - else - return "ld.%v0\t%w0,%1"; - } + if (msa_p) + return "ld.%v0\t%w0,%1"; return dbl_p ? "ldc1\t%0,%1" : "lwc1\t%0,%1"; } @@ -5362,7 +5296,7 @@ mips_int_order_operand_ok_p (enum rtx_code code, rtx cmp1) static bool mips_canonicalize_int_order_test (enum rtx_code *code, rtx *cmp1, - enum machine_mode mode) + machine_mode mode) { HOST_WIDE_INT plus_one; @@ -5407,7 +5341,7 @@ static void mips_emit_int_order_test (enum rtx_code code, bool *invert_ptr, rtx target, rtx cmp0, rtx cmp1) { - enum machine_mode mode; + machine_mode mode; /* First see if there is a MIPS instruction that can do this operation. If not, try doing the same for the inverse operation. If that also @@ -5511,7 +5445,7 @@ mips_reversed_fp_cond (enum rtx_code *code) a simple round-robin allocation scheme. */ static rtx -mips_allocate_fcc (enum machine_mode mode) +mips_allocate_fcc (machine_mode mode) { unsigned int regno, count; @@ -5544,7 +5478,8 @@ mips_allocate_fcc (enum machine_mode mode) conditions are: - EQ or NE between two registers. - - any comparison between a register and zero. */ + - any comparison between a register and zero. + - if mips R6 then any of the conditional branches are valid. */ static void mips_emit_compare (enum rtx_code *code, rtx *op0, rtx *op1, bool need_eq_ne_p) @@ -5566,6 +5501,44 @@ mips_emit_compare (enum rtx_code *code, rtx *op0, rtx *op1, bool need_eq_ne_p) else *op1 = force_reg (GET_MODE (cmp_op0), cmp_op1); } + else if (!need_eq_ne_p && TARGET_CB_MAYBE) + { + bool swap = false; + switch (*code) + { + case LE: + swap = true; + *code = GE; + break; + case GT: + swap = true; + *code = LT; + break; + case LEU: + swap = true; + *code = GEU; + break; + case GTU: + swap = true; + *code = LTU; + break; + case GE: + case LT: + case GEU: + case LTU: + /* Do nothing. */ + break; + default: + gcc_unreachable (); + } + *op1 = force_reg (GET_MODE (cmp_op0), cmp_op1); + if (swap) + { + rtx tmp = *op1; + *op1 = *op0; + *op0 = tmp; + } + } else { /* The comparison needs a separate scc instruction. Store the @@ -5596,7 +5569,7 @@ mips_emit_compare (enum rtx_code *code, rtx *op0, rtx *op1, bool need_eq_ne_p) *CODE to the code that the branch or move should use. */ cmp_code = *code; if (ISA_HAS_CCF) - { + { /* All FP conditions can be implemented directly with CMP.cond.fmt or by reversing the operands. */ *code = NE; @@ -5666,9 +5639,9 @@ mips_expand_conditional_branch (rtx *operands) emit_jump_insn (gen_condjump (condition, operands[3])); } -/* Generate RTL to test OPERAND[1] the test is specified by GEN_FUN - * then set OPERANDS[0] to 1 or 0 if test is true/false repectiveltyi - * according to GEN_FN. */ +/* Generate RTL to test OPERAND[1]. The test is specified by GEN_FN, + then sets OPERANDS[0] to 1 or 0 if the test is true/false respectively + according to GEN_FN. */ void mips_expand_msa_branch (rtx *operands, rtx (*gen_fn)(rtx, rtx, rtx)) @@ -5735,7 +5708,7 @@ mips_expand_conditional_move (rtx *operands) && register_operand (operands[2], VOIDmode) && register_operand (operands[3], VOIDmode)) { - enum machine_mode mode = GET_MODE (operands[0]); + machine_mode mode = GET_MODE (operands[0]); rtx temp = gen_reg_rtx (mode); rtx temp2 = gen_reg_rtx (mode); @@ -5774,7 +5747,7 @@ void mips_expand_conditional_trap (rtx comparison) { rtx op0, op1; - enum machine_mode mode; + machine_mode mode; enum rtx_code code; /* MIPS conditional trap instructions don't have GT or LE flavors, @@ -5826,7 +5799,7 @@ mips_init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype) static void mips_get_arg_info (struct mips_arg_info *info, const CUMULATIVE_ARGS *cum, - enum machine_mode mode, const_tree type, bool named) + machine_mode mode, const_tree type, bool named) { bool doubleword_aligned_p; unsigned int num_bytes, num_words, max_regs; @@ -5873,7 +5846,6 @@ mips_get_arg_info (struct mips_arg_info *info, const CUMULATIVE_ARGS *cum, than a variable argument. */ gcc_assert (TARGET_PAIRED_SINGLE_FLOAT || mode != V2SFmode); info->fpr_p = (named - && named && (type == 0 || FLOAT_TYPE_P (type)) && (GET_MODE_CLASS (mode) == MODE_FLOAT || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT @@ -5966,7 +5938,7 @@ mips_strict_argument_naming (cumulative_args_t ca ATTRIBUTE_UNUSED) /* Implement TARGET_FUNCTION_ARG. */ static rtx -mips_function_arg (cumulative_args_t cum_v, enum machine_mode mode, +mips_function_arg (cumulative_args_t cum_v, machine_mode mode, const_tree type, bool named) { CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); @@ -5979,7 +5951,7 @@ mips_function_arg (cumulative_args_t cum_v, enum machine_mode mode, if (mode == VOIDmode) { if (TARGET_MIPS16 && cum->fp_code != 0) - return gen_rtx_REG ((enum machine_mode) cum->fp_code, 0); + return gen_rtx_REG ((machine_mode) cum->fp_code, 0); else return NULL; } @@ -6062,7 +6034,7 @@ mips_function_arg (cumulative_args_t cum_v, enum machine_mode mode, && GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT) { rtx real, imag; - enum machine_mode inner; + machine_mode inner; unsigned int regno; inner = GET_MODE_INNER (mode); @@ -6093,7 +6065,7 @@ mips_function_arg (cumulative_args_t cum_v, enum machine_mode mode, /* Implement TARGET_FUNCTION_ARG_ADVANCE. */ static void -mips_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode, +mips_function_arg_advance (cumulative_args_t cum_v, machine_mode mode, const_tree type, bool named) { CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); @@ -6131,7 +6103,7 @@ mips_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode, static int mips_arg_partial_bytes (cumulative_args_t cum, - enum machine_mode mode, tree type, bool named) + machine_mode mode, tree type, bool named) { struct mips_arg_info info; @@ -6144,7 +6116,7 @@ mips_arg_partial_bytes (cumulative_args_t cum, to STACK_BOUNDARY bits if the type requires it. */ static unsigned int -mips_function_arg_boundary (enum machine_mode mode, const_tree type) +mips_function_arg_boundary (machine_mode mode, const_tree type) { unsigned int alignment; @@ -6156,15 +6128,14 @@ mips_function_arg_boundary (enum machine_mode mode, const_tree type) return alignment; } -/* Implement TARGET_GET_RAW_*_MODE. */ +/* Implement TARGET_GET_RAW_RESULT_MODE and TARGET_GET_RAW_ARG_MODE. */ -static enum machine_mode +static machine_mode mips_get_reg_raw_mode (int regno) { - if ((mips_abi == ABI_32 && !TARGET_FLOAT32) - && FP_REG_P (regno)) + if (TARGET_FLOATXX && FP_REG_P (regno)) return DFmode; - return default_get_reg_raw_mode(regno); + return default_get_reg_raw_mode (regno); } /* Return true if FUNCTION_ARG_PADDING (MODE, TYPE) should return @@ -6173,7 +6144,7 @@ mips_get_reg_raw_mode (int regno) byte does. */ bool -mips_pad_arg_upward (enum machine_mode mode, const_tree type) +mips_pad_arg_upward (machine_mode mode, const_tree type) { /* On little-endian targets, the first byte of every stack argument is passed in the first byte of the stack slot. */ @@ -6211,7 +6182,7 @@ mips_pad_arg_upward (enum machine_mode mode, const_tree type) the opposite if the most significant byte does. */ bool -mips_pad_reg_upward (enum machine_mode mode, tree type) +mips_pad_reg_upward (machine_mode mode, tree type) { /* No shifting is required for floating-point arguments. */ if (type != 0 ? FLOAT_TYPE_P (type) : GET_MODE_CLASS (mode) == MODE_FLOAT) @@ -6226,7 +6197,7 @@ mips_pad_reg_upward (enum machine_mode mode, tree type) static bool mips_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, - enum machine_mode mode, const_tree type, + machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { if (mips_abi == ABI_EABI) @@ -6253,7 +6224,7 @@ mips_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, static bool mips_callee_copies (cumulative_args_t cum ATTRIBUTE_UNUSED, - enum machine_mode mode ATTRIBUTE_UNUSED, + machine_mode mode ATTRIBUTE_UNUSED, const_tree type ATTRIBUTE_UNUSED, bool named) { return mips_abi == ABI_EABI && named; @@ -6322,7 +6293,7 @@ mips_return_in_msb (const_tree valtype) floating-point register. */ static bool -mips_return_mode_in_fpr_p (enum machine_mode mode) +mips_return_mode_in_fpr_p (machine_mode mode) { gcc_assert (TARGET_PAIRED_SINGLE_FLOAT || mode != V2SFmode); return ((GET_MODE_CLASS (mode) == MODE_FLOAT @@ -6342,8 +6313,8 @@ mips_return_mode_in_fpr_p (enum machine_mode mode) the structure itself has mode BLKmode. */ static rtx -mips_return_fpr_single (enum machine_mode type_mode, - enum machine_mode value_mode) +mips_return_fpr_single (machine_mode type_mode, + machine_mode value_mode) { rtx x; @@ -6365,9 +6336,9 @@ mips_return_fpr_single (enum machine_mode type_mode, Otherwise the values are packed together as closely as possible. */ static rtx -mips_return_fpr_pair (enum machine_mode mode, - enum machine_mode mode1, HOST_WIDE_INT offset1, - enum machine_mode mode2, HOST_WIDE_INT offset2) +mips_return_fpr_pair (machine_mode mode, + machine_mode mode1, HOST_WIDE_INT offset1, + machine_mode mode2, HOST_WIDE_INT offset2) { int inc; @@ -6390,7 +6361,7 @@ mips_return_fpr_pair (enum machine_mode mode, static rtx mips_function_value_1 (const_tree valtype, const_tree fn_decl_or_type, - enum machine_mode mode) + machine_mode mode) { if (valtype) { @@ -6480,7 +6451,7 @@ mips_function_value (const_tree valtype, const_tree fn_decl_or_type, /* Implement TARGET_LIBCALL_VALUE. */ static rtx -mips_libcall_value (enum machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED) +mips_libcall_value (machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED) { return mips_function_value_1 (NULL_TREE, NULL_TREE, mode); } @@ -6492,19 +6463,24 @@ mips_libcall_value (enum machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED) static bool mips_function_value_regno_p (const unsigned int regno) { + /* Most types only require one GPR or one FPR for return values but for + hard-float two FPRs can be used for _Complex types (for all ABIs) + and long doubles (for n64). */ if (regno == GP_RETURN || regno == FP_RETURN - || regno == FP_RETURN + 2 - || (LONG_DOUBLE_TYPE_SIZE == 128 - && FP_RETURN != GP_RETURN + || (FP_RETURN != GP_RETURN && regno == FP_RETURN + 2)) return true; - if ((regno == FP_RETURN + 1 - || regno == FP_RETURN + 3) + /* For o32 FP32, _Complex double will be returned in four 32-bit registers. + This does not apply to o32 FPXX as floating-point function argument and + return registers are described as 64-bit even though floating-point + registers are primarily described as 32-bit internally. + See: mips_get_reg_raw_mode. */ + if ((mips_abi == ABI_32 && TARGET_FLOAT32) && FP_RETURN != GP_RETURN - && (mips_abi == ABI_32 && TARGET_FLOAT32) - && FP_REG_P (regno)) + && (regno == FP_RETURN + 1 + || regno == FP_RETURN + 3)) return true; return false; @@ -6527,7 +6503,7 @@ mips_return_in_memory (const_tree type, const_tree fndecl ATTRIBUTE_UNUSED) /* Implement TARGET_SETUP_INCOMING_VARARGS. */ static void -mips_setup_incoming_varargs (cumulative_args_t cum, enum machine_mode mode, +mips_setup_incoming_varargs (cumulative_args_t cum, machine_mode mode, tree type, int *pretend_size ATTRIBUTE_UNUSED, int no_rtl) { @@ -6566,7 +6542,7 @@ mips_setup_incoming_varargs (cumulative_args_t cum, enum machine_mode mode, { /* We can't use move_block_from_reg, because it will use the wrong mode. */ - enum machine_mode mode; + machine_mode mode; int off, i; /* Set OFF to the offset from virtual_incoming_args_rtx of @@ -7215,7 +7191,7 @@ static struct mips16_stub *mips16_stubs; return mode MODE in the name of a MIPS16 function stub. */ static const char * -mips16_call_stub_mode_suffix (enum machine_mode mode) +mips16_call_stub_mode_suffix (machine_mode mode) { if (mode == SFmode) return "sf"; @@ -7303,7 +7279,7 @@ mips_output_args_xfer (int fp_code, char direction) for (f = (unsigned int) fp_code; f != 0; f >>= 2) { - enum machine_mode mode; + machine_mode mode; struct mips_arg_info info; if ((f & 3) == 1) @@ -7428,7 +7404,7 @@ mips16_copy_fpr_return_value (void) { rtx fn, insn, retval; tree return_type; - enum machine_mode return_mode; + machine_mode return_mode; const char *name; return_type = DECL_RESULT (current_function_decl); @@ -7669,7 +7645,7 @@ mips16_build_call_stub (rtx retval, rtx *fn_ptr, rtx args_size, int fp_code) $18 is usually a call-saved register. */ fprintf (asm_out_file, "\tmove\t%s,%s\n", reg_names[GP_REG_FIRST + 18], reg_names[RETURN_ADDR_REGNUM]); - output_asm_insn (MIPS_CALL ("jal", &fn, 0, -1), &fn); + output_asm_insn (mips_output_jump (&fn, 0, -1, true), &fn); fprintf (asm_out_file, "\t.cfi_register 31,18\n"); /* Move the result from floating-point registers to @@ -7982,7 +7958,7 @@ mips_store_by_pieces_p (unsigned HOST_WIDE_INT size, unsigned int align) LW/SWL/SWR sequence. This is often better than the 4 LIs and 4 SBs that we would generate when storing by pieces. */ if (align <= BITS_PER_UNIT) - return size < 4; + return size < 4 || !ISA_HAS_LWL_LWR; /* If the data is 2-byte aligned, then: @@ -8017,7 +7993,9 @@ mips_store_by_pieces_p (unsigned HOST_WIDE_INT size, unsigned int align) (c4) A block move of 8 bytes can use two LW/SW sequences or a single LD/SD sequence, and in these cases we've traditionally preferred the memory copy over the more bulky constant moves. */ - return size < 8; + return (size < 8 + || (align < 4 * BITS_PER_UNIT + && !ISA_HAS_LWL_LWR)); } /* Emit straight-line code to move LENGTH bytes from SRC to DEST. @@ -8029,7 +8007,7 @@ mips_block_move_straight (rtx dest, rtx src, HOST_WIDE_INT length) HOST_WIDE_INT offset, delta; unsigned HOST_WIDE_INT bits; int i; - enum machine_mode mode; + machine_mode mode; rtx *regs; /* Work out how many bits to move at a time. If both operands have @@ -8159,8 +8137,9 @@ 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) + if (!ISA_HAS_LWL_LWR + && (MEM_ALIGN (src) < BITS_PER_WORD + || MEM_ALIGN (dest) < BITS_PER_WORD)) return false; if (CONST_INT_P (length)) @@ -8253,7 +8232,7 @@ mips_expand_atomic_qihi (union mips_gen_fn_ptrs generator, rtx orig_addr, memsi_addr, memsi, shift, shiftsi, unshifted_mask; rtx unshifted_mask_reg, mask, inverted_mask, si_op; rtx res = NULL; - enum machine_mode mode; + machine_mode mode; mode = GET_MODE (mem); @@ -8438,7 +8417,7 @@ mips_expand_ins_as_unaligned_store (rtx dest, rtx src, HOST_WIDE_INT width, HOST_WIDE_INT bitpos) { rtx left, right; - enum machine_mode mode; + machine_mode mode; if (!mips_get_unaligned_mem (dest, width, bitpos, &left, &right)) return false; @@ -8461,7 +8440,7 @@ mips_expand_ins_as_unaligned_store (rtx dest, rtx src, HOST_WIDE_INT width, /* Return true if X is a MEM with the same size as MODE. */ bool -mips_mem_fits_mode_p (enum machine_mode mode, rtx x) +mips_mem_fits_mode_p (machine_mode mode, rtx x) { return (MEM_P (x) && MEM_SIZE_KNOWN_P (x) @@ -8503,7 +8482,7 @@ mips_use_ins_ext_p (rtx op, HOST_WIDE_INT width, HOST_WIDE_INT bitpos) mask_low_and_shift_len for the actual definition. */ bool -mask_low_and_shift_p (enum machine_mode mode, rtx mask, rtx shift, int maxlen) +mask_low_and_shift_p (machine_mode mode, rtx mask, rtx shift, int maxlen) { return IN_RANGE (mask_low_and_shift_len (mode, mask, shift), 1, maxlen); } @@ -8513,7 +8492,7 @@ mask_low_and_shift_p (enum machine_mode mode, rtx mask, rtx shift, int maxlen) see the table in the comment before the pattern. */ bool -and_operands_ok (enum machine_mode mode, rtx op1, rtx op2) +and_operands_ok (machine_mode mode, rtx op1, rtx op2) { return (memory_operand (op1, mode) ? and_load_operand (op2, mode) @@ -8527,7 +8506,7 @@ and_operands_ok (enum machine_mode mode, rtx op1, rtx op2) return the length of the mask, otherwise return -1. */ int -mask_low_and_shift_len (enum machine_mode mode, rtx mask, rtx shift) +mask_low_and_shift_len (machine_mode mode, rtx mask, rtx shift) { HOST_WIDE_INT shval; @@ -8772,7 +8751,7 @@ mips_pop_asm_switch (struct mips_asm_switch *asm_switch) '!' Print "s" to use the short version if the delay slot contains a 16-bit instruction. - See also mips_init_print_operand_pucnt. */ + See also mips_init_print_operand_punct. */ static void mips_print_operand_punctuation (FILE *file, int ch) @@ -8856,7 +8835,8 @@ mips_print_operand_punctuation (FILE *file, int ch) case ':': /* When final_sequence is 0, the delay slot will be a nop. We can - use the compact version for microMIPS. */ + use the compact version where available. The %: formatter will + only be present if a compact form of the branch is available. */ if (final_sequence == 0) putc ('c', file); break; @@ -8864,8 +8844,9 @@ mips_print_operand_punctuation (FILE *file, int ch) case '!': /* If the delay slot instruction is short, then use the compact version. */ - if (final_sequence == 0 - || get_attr_length (XVECEXP (final_sequence, 0, 1)) == 2) + if (TARGET_MICROMIPS && !TARGET_INTERLINK_COMPRESSED && mips_isa_rev <= 5 + && (final_sequence == 0 + || get_attr_length (XVECEXP (final_sequence, 0, 1)) == 2)) putc ('s', file); break; @@ -8953,11 +8934,13 @@ mips_print_operand_punct_valid_p (unsigned char code) /* Implement TARGET_PRINT_OPERAND. The MIPS-specific operand codes are: + 'E' Print CONST_INT_OP element 0 of a replicated CONST_VECTOR in decimal. 'X' Print CONST_INT OP in hexadecimal format. 'x' Print the low 16 bits of CONST_INT OP in hexadecimal format. 'd' Print CONST_INT OP in decimal. 'B' Print CONST_INT as an unsigned byte [0..255]. 'm' Print one less than CONST_INT OP in decimal. + 'y' Print exact log2 of CONST_INT OP in decimal. 'h' Print the high-part relocation associated with OP, after stripping any outermost HIGH. 'R' Print the low-part relocation associated with OP. @@ -8976,7 +8959,6 @@ mips_print_operand_punct_valid_p (unsigned char code) 'L' Print the low-order register in a double-word register operand. 'M' Print high-order register in a double-word register operand. 'z' Print $0 if OP is zero, otherwise print OP normally. - 'y' Print exact log2 of CONST_INT OP in decimal. 'b' Print the address of a memory operand, without offset. 'v' Print the insn size suffix b,h,w,d,f or d for vector modes V16QI,V8HI,V4SI, V2SI,V4DF and V2DF. */ @@ -8997,6 +8979,18 @@ mips_print_operand (FILE *file, rtx op, int letter) switch (letter) { + case 'E': + if (GET_CODE (op) == CONST_VECTOR) + { + gcc_assert (mips_const_vector_same_val_p (op, GET_MODE (op))); + op = CONST_VECTOR_ELT (op, 0); + gcc_assert (CONST_INT_P (op)); + fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (op)); + } + else + output_operand_lossage ("invalid use of '%%%c'", letter); + break; + case 'X': if (CONST_INT_P (op)) fprintf (file, HOST_WIDE_INT_PRINT_HEX, INTVAL (op)); @@ -9038,6 +9032,26 @@ mips_print_operand (FILE *file, rtx op, int letter) output_operand_lossage ("invalid use of '%%%c'", letter); break; + case 'K': + if (CONST_INT_P (op)) + { + int val = INTVAL (op); + int i; + for (i = 0; i < 16; i++) + { + if ((val & (1 << i)) == val) + { + fprintf (file, "%d", i); + break; + } + } + if (i == 16) + output_operand_lossage ("invalid use of '%%%c' - Mask inappropriate", letter); + } + else + output_operand_lossage ("invalid use of '%%%c'", letter); + break; + case 'm': if (CONST_INT_P (op)) fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (op) - 1); @@ -9254,7 +9268,7 @@ mips_encode_section_info (tree decl, rtx rtl, int first) /* Implement TARGET_SELECT_RTX_SECTION. */ static section * -mips_select_rtx_section (enum machine_mode mode, rtx x, +mips_select_rtx_section (machine_mode mode, rtx x, unsigned HOST_WIDE_INT align) { /* ??? Consider using mergeable small data sections. */ @@ -9502,17 +9516,16 @@ static rtx mips_dwarf_register_span (rtx reg) { rtx high, low; - enum machine_mode mode; + machine_mode mode; /* TARGET_FLOATXX is implemented as 32-bit floating-point registers but - ensures that double precision registers are treated as if they were + ensures that double-precision registers are treated as if they were 64-bit physical registers. The code will run correctly with 32-bit or - 64-bit registers which means that dwarf information cannot be precisely - correct for all scenarios. We choose to state that the 64-bit values - are stored in a single 64-bit 'piece'. This slightly unusual - construct can then be interpreted as either a pair of registers if the - registers are 32-bit or a single 64-bit register depending on - hardware. */ + 64-bit registers which means that dwarf information cannot be precise + for all scenarios. We choose to state that the 64-bit values are stored + in a single 64-bit 'piece'. This slightly unusual construct can then be + interpreted as either a pair of registers if the registers are 32-bit or + a single 64-bit register depending on hardware. */ mode = GET_MODE (reg); if (FP_REG_P (REGNO (reg)) && TARGET_FLOATXX @@ -9537,6 +9550,19 @@ mips_dwarf_register_span (rtx reg) return NULL_RTX; } +/* Implement TARGET_DWARF_FRAME_REG_MODE. */ + +static machine_mode +mips_dwarf_frame_reg_mode (int regno) +{ + machine_mode mode = default_dwarf_frame_reg_mode (regno); + + if (FP_REG_P (regno) && mips_abi == ABI_32 && TARGET_FLOAT64) + mode = SImode; + + return mode; +} + /* DSP ALU can bypass data with no delays for the following pairs. */ enum insn_code dspalu_bypass_table[][2] = { @@ -9816,7 +9842,7 @@ mips_file_start (void) fprintf (asm_out_file, "\t.nan\t%s\n", mips_nan == MIPS_IEEE_754_2008 ? "2008" : "legacy"); -#ifdef HAVE_AS_MODULE +#ifdef HAVE_AS_DOT_MODULE /* Record the FP ABI. See below for comments. */ if (TARGET_NO_FLOAT) #ifdef HAVE_AS_GNU_ATTRIBUTE @@ -9856,7 +9882,7 @@ mips_file_start (void) attr = 2; /* 64-bit FP registers on a 32-bit target, -mips32r2 -mfp64. Reserved attr=4. - This case used 12 callee save double precision registers + This case used 12 callee-saved double-precision registers and is deprecated. */ /* 64-bit or 32-bit FP registers on a 32-bit target, -mfpxx. */ else if (TARGET_FLOATXX) @@ -11323,7 +11349,7 @@ typedef void (*mips_save_restore_fn) (rtx, rtx); stack pointer. */ static void -mips_save_restore_reg (enum machine_mode mode, int regno, +mips_save_restore_reg (machine_mode mode, int regno, HOST_WIDE_INT offset, mips_save_restore_fn fn) { rtx mem; @@ -11491,7 +11517,7 @@ static void mips_for_each_saved_gpr_and_fpr (HOST_WIDE_INT sp_offset, mips_save_restore_fn fn) { - enum machine_mode fpr_mode; + machine_mode fpr_mode; int regno; const struct mips_frame_info *frame = &cfun->machine->frame; HOST_WIDE_INT offset; @@ -11526,7 +11552,16 @@ mips_for_each_saved_gpr_and_fpr (HOST_WIDE_INT sp_offset, regno -= MAX_FPRS_PER_FMT) if (BITSET_P (cfun->machine->frame.fmask, regno - FP_REG_FIRST)) { - mips_save_restore_reg (fpr_mode, regno, offset, fn); + if (!TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT + && (fixed_regs[regno] || fixed_regs[regno + 1])) + { + if (fixed_regs[regno]) + mips_save_restore_reg (SFmode, regno + 1, offset, fn); + else + mips_save_restore_reg (SFmode, regno, offset, fn); + } + else + mips_save_restore_reg (fpr_mode, regno, offset, fn); offset -= GET_MODE_SIZE (fpr_mode); } } @@ -12624,7 +12659,7 @@ mips_can_use_return_insn (void) The result of this function is cached in mips_hard_regno_mode_ok. */ static bool -mips_hard_regno_mode_ok_p (unsigned int regno, enum machine_mode mode) +mips_hard_regno_mode_ok_p (unsigned int regno, machine_mode mode) { unsigned int size; enum mode_class mclass; @@ -12645,7 +12680,7 @@ mips_hard_regno_mode_ok_p (unsigned int regno, enum machine_mode mode) size = GET_MODE_SIZE (mode); mclass = GET_MODE_CLASS (mode); - if (GP_REG_P (regno) && mode != CCFmode) + if (GP_REG_P (regno) && mode != CCFmode && !MSA_SUPPORTED_MODE_P (mode)) return ((regno - GP_REG_FIRST) & 1) == 0 || size <= UNITS_PER_WORD; /* For MSA, allow TImode and 128-bit vector modes in all FPR. */ @@ -12657,13 +12692,12 @@ mips_hard_regno_mode_ok_p (unsigned int regno, enum machine_mode mode) || (MIN_FPRS_PER_FMT == 1 && size <= UNITS_PER_FPREG))) { /* Deny use of odd-numbered registers for 32-bit data for - the O32 FP64A ABI. */ - if (mips_abi == ABI_32 && TARGET_FLOAT64 && !TARGET_ODD_SPREG - && size <= 4 && (regno & 1) != 0) + the o32 FP64A ABI. */ + if (TARGET_O32_FP64A_ABI && size <= 4 && (regno & 1) != 0) return false; /* Prevent the use of odd-numbered registers for CCFmode with the - O32-FPXX ABI, otherwise allow them. + o32 FPXX ABI, otherwise allow them. The FPXX ABI does not permit double-precision data to be placed in odd-numbered registers and double-precision compares write them as 64-bit values. Without this restriction the R6 FPXX @@ -12694,7 +12728,7 @@ mips_hard_regno_mode_ok_p (unsigned int regno, enum machine_mode mode) /* Don't allow MSA vector modes in accumulators. */ if (ACC_REG_P (regno) - && !MSA_SUPPORTED_VECTOR_MODE_P (mode) + && !MSA_SUPPORTED_MODE_P (mode) && (INTEGRAL_MODE_P (mode) || ALL_FIXED_POINT_MODE_P (mode))) { if (MD_REG_P (regno)) @@ -12735,7 +12769,7 @@ mips_hard_regno_mode_ok_p (unsigned int regno, enum machine_mode mode) /* Implement HARD_REGNO_NREGS. */ unsigned int -mips_hard_regno_nregs (int regno, enum machine_mode mode) +mips_hard_regno_nregs (int regno, machine_mode mode) { if (ST_REG_P (regno)) /* The size of FP status registers is always 4, because they only hold @@ -12758,7 +12792,7 @@ mips_hard_regno_nregs (int regno, enum machine_mode mode) in mips_hard_regno_nregs. */ int -mips_class_max_nregs (enum reg_class rclass, enum machine_mode mode) +mips_class_max_nregs (enum reg_class rclass, machine_mode mode) { int size; HARD_REG_SET left; @@ -12797,8 +12831,8 @@ mips_class_max_nregs (enum reg_class rclass, enum machine_mode mode) /* Implement CANNOT_CHANGE_MODE_CLASS. */ bool -mips_cannot_change_mode_class (enum machine_mode from, - enum machine_mode to, +mips_cannot_change_mode_class (machine_mode from, + machine_mode to, enum reg_class rclass) { /* Allow conversions between different Loongson integer vectors, @@ -12840,7 +12874,7 @@ mips_cannot_change_mode_class (enum machine_mode from, /* Implement target hook small_register_classes_for_mode_p. */ static bool -mips_small_register_classes_for_mode_p (enum machine_mode mode +mips_small_register_classes_for_mode_p (machine_mode mode ATTRIBUTE_UNUSED) { return TARGET_MIPS16; @@ -12850,7 +12884,7 @@ mips_small_register_classes_for_mode_p (enum machine_mode mode or use the MSA's move.v instruction. */ static bool -mips_mode_ok_for_mov_fmt_p (enum machine_mode mode) +mips_mode_ok_for_mov_fmt_p (machine_mode mode) { switch (mode) { @@ -12862,7 +12896,7 @@ mips_mode_ok_for_mov_fmt_p (enum machine_mode mode) return TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT; case V2SFmode: - return TARGET_HARD_FLOAT; + return TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT; default: return MSA_SUPPORTED_MODE_P (mode); @@ -12872,7 +12906,7 @@ mips_mode_ok_for_mov_fmt_p (enum machine_mode mode) /* Implement MODES_TIEABLE_P. */ bool -mips_modes_tieable_p (enum machine_mode mode1, enum machine_mode mode2) +mips_modes_tieable_p (machine_mode mode1, machine_mode mode2) { /* FPRs allow no mode punning, so it's not worth tying modes if we'd prefer to put one of them in FPRs. */ @@ -12922,21 +12956,17 @@ mips_canonicalize_move_class (reg_class_t rclass) return rclass; } -/* Return the cost of moving a value of mode MODE from a register of - class FROM to a GPR. Return 0 for classes that are unions of other - classes handled by this function. */ +/* Return the cost of moving a value from a register of class FROM to a GPR. + Return 0 for classes that are unions of other classes handled by this + function. */ static int -mips_move_to_gpr_cost (enum machine_mode mode, reg_class_t from) +mips_move_to_gpr_cost (machine_mode mode, reg_class_t from) { switch (from) { case M16_REGS: case GENERAL_REGS: - /* Two or four move. */ - if (MSA_SUPPORTED_MODE_P (mode)) - return TARGET_64BIT ? 4 : 8; - /* A MIPS16 MOVE instruction, or a non-MIPS16 MOVE macro. */ return 2; @@ -12945,17 +12975,9 @@ mips_move_to_gpr_cost (enum machine_mode mode, reg_class_t from) return 6; case FP_REGS: - /* Two or four copy_s.*. */ - if (MSA_SUPPORTED_MODE_P (mode)) - return TARGET_64BIT ? 8 : 16; - /* MFC1, etc. */ return 4; - case ST_REGS: - /* Not possible. ST_REGS are never moved. */ - return 0; - case COP0_REGS: case COP2_REGS: case COP3_REGS: @@ -12967,21 +12989,17 @@ mips_move_to_gpr_cost (enum machine_mode mode, reg_class_t from) } } -/* Return the cost of moving a value of mode MODE from a GPR to a - register of class TO. Return 0 for classes that are unions of - other classes handled by this function. */ +/* Return the cost of moving a value from a GPR to a register of class TO. + Return 0 for classes that are unions of other classes handled by this + function. */ static int -mips_move_from_gpr_cost (enum machine_mode mode, reg_class_t to) +mips_move_from_gpr_cost (machine_mode mode, reg_class_t to) { switch (to) { case M16_REGS: case GENERAL_REGS: - /* Two or four move. */ - if (MSA_SUPPORTED_MODE_P (mode)) - return TARGET_64BIT ? 4: 8; - /* A MIPS16 MOVE instruction, or a non-MIPS16 MOVE macro. */ return 2; @@ -12990,17 +13008,9 @@ mips_move_from_gpr_cost (enum machine_mode mode, reg_class_t to) return 6; case FP_REGS: - /* Two or four insv.*. */ - if (MSA_SUPPORTED_MODE_P (mode)) - return TARGET_64BIT ? 8: 16; - /* MTC1, etc. */ return 4; - case ST_REGS: - /* Not possible. ST_REGS are never moved. */ - return 0; - case COP0_REGS: case COP2_REGS: case COP3_REGS: @@ -13017,7 +13027,7 @@ mips_move_from_gpr_cost (enum machine_mode mode, reg_class_t to) the maximum for us. */ static int -mips_register_move_cost (enum machine_mode mode, +mips_register_move_cost (machine_mode mode, reg_class_t from, reg_class_t to) { reg_class_t dregs; @@ -13068,15 +13078,9 @@ mips_register_priority (int hard_regno) /* Implement TARGET_MEMORY_MOVE_COST. */ static int -mips_memory_move_cost (enum machine_mode mode, reg_class_t rclass, bool in) +mips_memory_move_cost (machine_mode mode, reg_class_t rclass, bool in) { - int multiplier = 1; - /* Acount for the numder of losds md nd stores that are needed to - * handle MSA type in GPRs. */ - if (MSA_SUPPORTED_MODE_P (mode) && rclass != FP_REGS) - multiplier = GET_MODE_SIZE (mode) / UNITS_PER_WORD; - - return (mips_cost->memory_latency * multiplier + return (mips_cost->memory_latency + memory_move_secondary_cost (mode, rclass, in)); } @@ -13084,7 +13088,7 @@ mips_memory_move_cost (enum machine_mode mode, reg_class_t rclass, bool in) bool mips_secondary_memory_needed (enum reg_class class1, enum reg_class class2, - enum machine_mode mode) + machine_mode mode) { /* Ignore spilled pseudos. */ if (lra_in_progress && (class1 == NO_REGS || class2 == NO_REGS)) @@ -13092,7 +13096,7 @@ mips_secondary_memory_needed (enum reg_class class1, enum reg_class class2, if (((class1 == FP_REGS) != (class2 == FP_REGS)) && ((TARGET_FLOATXX && !ISA_HAS_MXHC1) - || (mips_abi == ABI_32 && TARGET_FLOAT64 && !TARGET_ODD_SPREG)) + || TARGET_O32_FP64A_ABI) && GET_MODE_SIZE (mode) >= 8) return true; @@ -13107,7 +13111,7 @@ mips_secondary_memory_needed (enum reg_class class1, enum reg_class class2, enum reg_class mips_secondary_reload_class (enum reg_class rclass, - enum machine_mode mode, rtx x, bool in_p) + machine_mode mode, rtx x, bool) { int regno; @@ -13133,28 +13137,11 @@ mips_secondary_reload_class (enum reg_class rclass, if (ACC_REG_P (regno)) return reg_class_subset_p (rclass, GR_REGS) ? NO_REGS : GR_REGS; - /* We can only copy a value to a condition code register from a - floating-point register, and even then we require a scratch - floating-point register. We can only copy a value out of a - condition-code register into a general register. */ - if (reg_class_subset_p (rclass, ST_REGS)) - { - if (in_p) - return FP_REGS; - return GP_REG_P (regno) ? NO_REGS : GR_REGS; - } - if (ST_REG_P (regno)) - { - if (!in_p) - return FP_REGS; - return reg_class_subset_p (rclass, GR_REGS) ? NO_REGS : GR_REGS; - } - if (reg_class_subset_p (rclass, FP_REGS)) { - /* We don't need a reload if the pseudo is in memory. */ - if ((MEM_P (x) || regno == -1) - && (GET_MODE_SIZE (mode) == 4 || GET_MODE_SIZE (mode) == 8)) + if (regno < 0 + || (MEM_P (x) + && (GET_MODE_SIZE (mode) == 4 || GET_MODE_SIZE (mode) == 8))) /* In this case we can use lwc1, swc1, ldc1 or sdc1. We'll use pairs of lwc1s and swc1s if ldc1 and sdc1 are not supported. */ return NO_REGS; @@ -13178,8 +13165,7 @@ mips_secondary_reload_class (enum reg_class rclass, return NO_REGS; /* Otherwise, we need to reload through an integer register. */ - if (regno >= 0) - return GR_REGS; + return GR_REGS; } if (FP_REG_P (regno)) return reg_class_subset_p (rclass, GR_REGS) ? NO_REGS : GR_REGS; @@ -13190,7 +13176,7 @@ mips_secondary_reload_class (enum reg_class rclass, /* Implement TARGET_MODE_REP_EXTENDED. */ static int -mips_mode_rep_extended (enum machine_mode mode, enum machine_mode mode_rep) +mips_mode_rep_extended (machine_mode mode, machine_mode mode_rep) { /* On 64-bit targets, SImode register values are sign-extended to DImode. */ if (TARGET_64BIT && mode == SImode && mode_rep == DImode) @@ -13202,7 +13188,7 @@ mips_mode_rep_extended (enum machine_mode mode, enum machine_mode mode_rep) /* Implement TARGET_VALID_POINTER_MODE. */ static bool -mips_valid_pointer_mode (enum machine_mode mode) +mips_valid_pointer_mode (machine_mode mode) { return mode == SImode || (TARGET_64BIT && mode == DImode); } @@ -13210,7 +13196,7 @@ mips_valid_pointer_mode (enum machine_mode mode) /* Implement TARGET_VECTOR_MODE_SUPPORTED_P. */ static bool -mips_vector_mode_supported_p (enum machine_mode mode) +mips_vector_mode_supported_p (machine_mode mode) { switch (mode) { @@ -13233,14 +13219,14 @@ mips_vector_mode_supported_p (enum machine_mode mode) return TARGET_LOONGSON_VECTORS; default: - return TARGET_MSA && MSA_SUPPORTED_VECTOR_MODE_P (mode); + return MSA_SUPPORTED_MODE_P (mode); } } /* Implement TARGET_SCALAR_MODE_SUPPORTED_P. */ static bool -mips_scalar_mode_supported_p (enum machine_mode mode) +mips_scalar_mode_supported_p (machine_mode mode) { if (ALL_FIXED_POINT_MODE_P (mode) && GET_MODE_PRECISION (mode) <= 2 * BITS_PER_WORD) @@ -13251,8 +13237,8 @@ mips_scalar_mode_supported_p (enum machine_mode mode) /* Implement TARGET_VECTORIZE_PREFERRED_SIMD_MODE. */ -static enum machine_mode -mips_preferred_simd_mode (enum machine_mode mode) +static machine_mode +mips_preferred_simd_mode (machine_mode mode) { if (TARGET_PAIRED_SINGLE_FLOAT && mode == SFmode) @@ -13486,6 +13472,7 @@ mips_adjust_insn_length (rtx insn, int length) break; case HAZARD_DELAY: + case HAZARD_FORBIDDEN_SLOT: length += NOP_INSN_LENGTH; break; @@ -13497,6 +13484,78 @@ mips_adjust_insn_length (rtx insn, int length) return length; } +/* Return the asm template for a call. OPERANDS are the operands, TARGET_OPNO + is the operand number of the target. SIZE_OPNO is the operand number of + the argument size operand that can optionally hold the call attributes. If + SIZE_OPNO is not -1 and the call is indirect, use the function symbol from + the call attributes to attach a R_MIPS_JALR relocation to the call. + + When generating GOT code without explicit relocation operators, all calls + should use assembly macros. Otherwise, all indirect calls should use "jr" + or "jalr"; we will arrange to restore $gp afterwards if necessary. Finally, + we can only generate direct calls for -mabicalls by temporarily switching + to non-PIC mode. + + For microMIPS jal(r), we try to generate jal(r)s when a 16-bit + instruction is in the delay slot of jal(r). + + Where compact branches are available, we try to use them if the delay slot + has a NOP (or equivalently delay slots were not enabled for the instruction + anyway). */ + +const char * +mips_output_jump (rtx *operands, int target_opno, int size_opno, bool link_p) +{ + static char buffer[300]; + char *s = buffer; + bool reg_p = REG_P (operands[target_opno]); + + const char *and_link = link_p ? "al" : ""; + const char *reg = reg_p ? "r" : ""; + const char *compact = ""; + const char *nop = "%/"; + const char *short_delay = link_p ? "%!" : ""; + const char *insn_name = TARGET_CB_NEVER || reg_p ? "j" : "b"; + + /* Compact branches can only be described when the ISA has support for them + as both the compact formatter '%:' and the delay slot NOP formatter '%/' + work as a mutually exclusive pair. I.e. a NOP is never required if a + compact form is available. */ + if (!final_sequence + && (TARGET_CB_MAYBE + || (ISA_HAS_JRC && !link_p && reg_p))) + { + compact = "c"; + nop = ""; + } + + + if (TARGET_USE_GOT && !TARGET_EXPLICIT_RELOCS) + sprintf (s, "%%*%s%s\t%%%d%%/", insn_name, link_p ? "al" : "", target_opno); + else + { + if (!reg_p && TARGET_ABICALLS_PIC2) + s += sprintf (s, ".option\tpic0\n\t"); + + if (reg_p && mips_get_pic_call_symbol (operands, size_opno)) + { + s += sprintf (s, "%%*.reloc\t1f,R_MIPS_JALR,%%%d\n1:\t", size_opno); + /* Not sure why this shouldn't permit a short delay but it did not + allow it before so we still don't allow it. */ + short_delay = ""; + } + else + s += sprintf (s, "%%*"); + + s += sprintf (s, "%s%s%s%s%s\t%%%d%s", insn_name, and_link, reg, compact, short_delay, + target_opno, nop); + + if (!reg_p && TARGET_ABICALLS_PIC2) + s += sprintf (s, "\n\t.option\tpic2"); + } + return buffer; +} + /* Return the assembly code for INSN, which has the operands given by OPERANDS, and which branches to OPERANDS[0] if some condition is true. BRANCH_IF_TRUE is the asm template that should be used if OPERANDS[0] @@ -13517,7 +13576,7 @@ mips_output_conditional_branch (rtx insn, rtx *operands, if (length <= 8) { /* Just a simple conditional branch. */ - mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn)); + mips_branch_likely = final_sequence && INSN_ANNULLED_BRANCH_P (insn); return branch_if_true; } @@ -13550,12 +13609,25 @@ mips_output_conditional_branch (rtx insn, rtx *operands, } /* Output the unconditional branch to TAKEN. */ - if (TARGET_ABSOLUTE_JUMPS) + if (TARGET_ABSOLUTE_JUMPS && TARGET_CB_MAYBE) + { + /* Add a hazard nop. */ + if (!final_sequence) + { + output_asm_insn ("nop\t\t# hazard nop", 0); + fprintf (asm_out_file, "\n"); + } + output_asm_insn (MIPS_ABSOLUTE_JUMP ("bc\t%0"), &taken); + } + else if (TARGET_ABSOLUTE_JUMPS) output_asm_insn (MIPS_ABSOLUTE_JUMP ("j\t%0%/"), &taken); else { mips_output_load_label (taken); - output_asm_insn ("jr\t%@%]%/", 0); + if (TARGET_CB_MAYBE) + output_asm_insn ("jrc\t%@%]", 0); + else + output_asm_insn ("jr\t%@%]%/", 0); } /* Now deal with its delay slot; see above. */ @@ -13569,7 +13641,7 @@ mips_output_conditional_branch (rtx insn, rtx *operands, asm_out_file, optimize, 1, NULL); INSN_DELETED_P (XVECEXP (final_sequence, 0, 1)) = 1; } - else + else if (TARGET_CB_NEVER) output_asm_insn ("nop", 0); fprintf (asm_out_file, "\n"); } @@ -13580,6 +13652,58 @@ mips_output_conditional_branch (rtx insn, rtx *operands, return ""; } +const char * +mips_output_equal_conditional_branch (rtx insn, rtx *operands, bool inverted_p) +{ + const char *branch[2]; + /* For a simple BNEZ or BEQZ microMIPSr3 branch. */ + if (TARGET_MICROMIPS + && mips_isa_rev <= 5 + && operands[3] == const0_rtx + && get_attr_length (insn) <= 8) + { + if (mips_cb == MIPS_CB_OPTIMAL) + { + branch[!inverted_p] = "%*b%C1z%:\t%2,%0"; + branch[inverted_p] = "%*b%N1z%:\t%2,%0"; + } + else + { + branch[!inverted_p] = "%*b%C1z\t%2,%0%/"; + branch[inverted_p] = "%*b%N1z\t%2,%0%/"; + } + } + else if (TARGET_CB_MAYBE) + { + if (operands[3] == const0_rtx) + { + branch[!inverted_p] = MIPS_BRANCH_C ("b%C1z", "%2,%0"); + branch[inverted_p] = MIPS_BRANCH_C ("b%N1z", "%2,%0"); + } + else if (REGNO (operands[2]) != REGNO (operands[3])) + { + branch[!inverted_p] = MIPS_BRANCH_C ("b%C1", "%2,%3,%0"); + branch[inverted_p] = MIPS_BRANCH_C ("b%N1", "%2,%3,%0"); + } + else + { + /* This case is stupid. Fix me. */ + if (GET_CODE (operands[1]) == NE) + inverted_p = !inverted_p; + + branch[!inverted_p] = MIPS_BRANCH_C ("b", "%0"); + branch[inverted_p] = "%*\t\t# branch never"; + } + } + else + { + branch[!inverted_p] = MIPS_BRANCH ("b%C1", "%2,%z3,%0"); + branch[inverted_p] = MIPS_BRANCH ("b%N1", "%2,%z3,%0"); + } + + return mips_output_conditional_branch (insn, operands, branch[1], branch[0]); +} + /* Return the assembly code for INSN, which branches to OPERANDS[0] if some ordering condition is true. The condition is given by OPERANDS[1] if !INVERTED_P, otherwise it is the inverse of @@ -13591,32 +13715,84 @@ mips_output_order_conditional_branch (rtx insn, rtx *operands, bool inverted_p) { const char *branch[2]; - /* Make BRANCH[1] branch to OPERANDS[0] when the condition is true. - Make BRANCH[0] branch on the inverse condition. */ - switch (GET_CODE (operands[1])) + if (operands[3] != const0_rtx) { - /* These cases are equivalent to comparisons against zero. */ - case LEU: - inverted_p = !inverted_p; - /* Fall through. */ - case GTU: - branch[!inverted_p] = MIPS_BRANCH ("bne", "%2,%.,%0"); - branch[inverted_p] = MIPS_BRANCH ("beq", "%2,%.,%0"); - break; + if (REGNO (operands[2]) == REGNO (operands[3])) + { + switch (GET_CODE (operands[1])) + { + case LT: + case LTU: + inverted_p = !inverted_p; + /* Fall through. */ + case GE: + case GEU: + branch[!inverted_p] = MIPS_BRANCH_C ("b", "%0"); + branch[inverted_p] = "%*\t\t# branch never"; + break; + default: + gcc_unreachable (); + } + } + else + { + branch[!inverted_p] = MIPS_BRANCH_C ("b%C1", "%2,%3,%0"); + branch[inverted_p] = MIPS_BRANCH_C ("b%N1", "%2,%3,%0"); + } + } + else + { + /* Make BRANCH[1] branch to OPERANDS[0] when the condition is true. + Make BRANCH[0] branch on the inverse condition. */ + switch (GET_CODE (operands[1])) + { + /* These cases are equivalent to comparisons against zero. */ + case LEU: + inverted_p = !inverted_p; + /* Fall through. */ + case GTU: + if (TARGET_CB_MAYBE) + { + branch[!inverted_p] = MIPS_BRANCH_C ("bnez", "%2,%0"); + branch[inverted_p] = MIPS_BRANCH_C ("beqz", "%2,%0"); + } + else + { + branch[!inverted_p] = MIPS_BRANCH ("bne", "%2,%.,%0"); + branch[inverted_p] = MIPS_BRANCH ("beq", "%2,%.,%0"); + } + break; - /* These cases are always true or always false. */ - case LTU: - inverted_p = !inverted_p; - /* Fall through. */ - case GEU: - branch[!inverted_p] = MIPS_BRANCH ("beq", "%.,%.,%0"); - branch[inverted_p] = MIPS_BRANCH ("bne", "%.,%.,%0"); - break; + /* These cases are always true or always false. */ + case LTU: + inverted_p = !inverted_p; + /* Fall through. */ + case GEU: + if (TARGET_CB_MAYBE) + { + branch[!inverted_p] = MIPS_BRANCH_C ("b", "%0"); + branch[inverted_p] = "%*\t\t# branch never"; + } + else + { + branch[!inverted_p] = MIPS_BRANCH ("beq", "%.,%.,%0"); + branch[inverted_p] = MIPS_BRANCH ("bne", "%.,%.,%0"); + } + break; - default: - branch[!inverted_p] = MIPS_BRANCH ("b%C1z", "%2,%0"); - branch[inverted_p] = MIPS_BRANCH ("b%N1z", "%2,%0"); - break; + default: + if (TARGET_CB_MAYBE) + { + branch[!inverted_p] = MIPS_BRANCH_C ("b%C1z", "%2,%0"); + branch[inverted_p] = MIPS_BRANCH_C ("b%N1z", "%2,%0"); + } + else + { + branch[!inverted_p] = MIPS_BRANCH ("b%C1z", "%2,%0"); + branch[inverted_p] = MIPS_BRANCH ("b%N1z", "%2,%0"); + } + break; + } } return mips_output_conditional_branch (insn, operands, branch[1], branch[0]); } @@ -13819,11 +13995,18 @@ mips_process_sync_loop (rtx insn, rtx *operands) at, oldval, inclusive_mask, NULL); tmp1 = at; } - mips_multi_add_insn ("bne\t%0,%z1,2f", tmp1, required_oldval, NULL); + if (TARGET_CB_NEVER) + mips_multi_add_insn ("bne\t%0,%z1,2f", tmp1, required_oldval, NULL); /* CMP = 0 [delay slot]. */ if (cmp) mips_multi_add_insn ("li\t%0,0", cmp, NULL); + + if (TARGET_CB_MAYBE && required_oldval == const0_rtx) + mips_multi_add_insn ("bnezc\t%0,2f", tmp1, NULL); + else if (TARGET_CB_MAYBE) + mips_multi_add_insn ("bnec\t%0,%1,2f", tmp1, required_oldval, NULL); + } /* $TMP1 = OLDVAL & EXCLUSIVE_MASK. */ @@ -13879,7 +14062,17 @@ mips_process_sync_loop (rtx insn, rtx *operands) This will sometimes be a delayed branch; see the write code below for details. */ mips_multi_add_insn (is_64bit_p ? "scd\t%0,%1" : "sc\t%0,%1", at, mem, NULL); - mips_multi_add_insn ("beq%?\t%0,%.,1b", at, NULL); + + /* When using branch likely (-mfix-r10000), the delay slot instruction + will be annulled on false. The normal delay slot instructions + calculate the overall result of the atomic operation and must not + be annulled. To ensure this behaviour unconditionally use a NOP + in the delay slot for the branch likely case. */ + + if (TARGET_CB_MAYBE) + mips_multi_add_insn ("beqzc\t%0,1b", at, NULL); + else + mips_multi_add_insn ("beq%?\t%0,%.,1b%~", at, NULL); /* if (INSN1 != MOVE && INSN1 != LI) NEWVAL = $TMP3 [delay slot]. */ if (insn1 != SYNC_INSN1_MOVE && insn1 != SYNC_INSN1_LI && tmp3 != newval) @@ -13887,7 +14080,7 @@ mips_process_sync_loop (rtx insn, rtx *operands) mips_multi_copy_insn (tmp3_insn); mips_multi_set_operand (mips_multi_last_index (), 0, newval); } - else if (!(required_oldval && cmp)) + else if (!(required_oldval && cmp) && !mips_branch_likely) mips_multi_add_insn ("nop", NULL); /* CMP = 1 -- either standalone or in a delay slot. */ @@ -13911,12 +14104,12 @@ mips_process_sync_loop (rtx insn, rtx *operands) const char * mips_output_sync_loop (rtx insn, rtx *operands) { - mips_process_sync_loop (insn, operands); - /* Use branch-likely instructions to work around the LL/SC R10000 errata. */ mips_branch_likely = TARGET_FIX_R10000; + mips_process_sync_loop (insn, operands); + mips_push_asm_switch (&mips_noreorder); mips_push_asm_switch (&mips_nomacro); mips_push_asm_switch (&mips_noat); @@ -13938,6 +14131,9 @@ mips_output_sync_loop (rtx insn, rtx *operands) unsigned int mips_sync_loop_insns (rtx insn, rtx *operands) { + /* Use branch-likely instructions to work around the LL/SC R10000 + errata. */ + mips_branch_likely = TARGET_FIX_R10000; mips_process_sync_loop (insn, operands); return mips_multi_num_insns; } @@ -14062,11 +14258,11 @@ mips_output_division (const char *division, rtx *operands) } } else - { + { output_asm_insn ("%(bne\t%2,%.,1f", operands); output_asm_insn (s, operands); s = "break\t7%)\n1:"; - } + } } return s; } @@ -14095,7 +14291,7 @@ bool mips_fmadd_bypass (rtx out_insn, rtx in_insn) { int dst_reg, src_reg; - + gcc_assert (get_attr_type (in_insn) == TYPE_FMADD); gcc_assert (get_attr_type (out_insn) == TYPE_FMADD); @@ -14233,6 +14429,8 @@ mips_issue_rate (void) case PROCESSOR_R9000: case PROCESSOR_OCTEON: case PROCESSOR_OCTEON2: + case PROCESSOR_OCTEON3: + case PROCESSOR_I6400: return 2; case PROCESSOR_SB1: @@ -14382,7 +14580,7 @@ mips_multipass_dfa_lookahead (void) if (TUNE_OCTEON) return 2; - if (TUNE_P5600) + if (TUNE_P5600 || TUNE_I6400) return 4; return 0; @@ -14636,82 +14834,68 @@ mips_74k_agen_reorder (rtx *ready, int nready) } } -/* These functions are called when -msched-weight is set. - They calculate register weight for given register type. */ +/* These functions are called when -msched-weight is set. */ -/* Find GP and vector register weight for given X. */ +/* Find register born in given X if any. */ -static void -find_regtype_weight (rtx x, int insn_uid) +static int +find_reg_born (rtx x) { if (GET_CODE (x) == CLOBBER) - { - if (GET_MODE_SIZE (GET_MODE (SET_DEST (x))) <= GET_MODE_SIZE (DImode)) - regtype_weight[insn_uid].reg_weight_gp++; - else - regtype_weight[insn_uid].reg_weight_vec++; - } + return 1; if (GET_CODE (x) == SET) { if (REG_P (SET_DEST (x)) && reg_mentioned_p (SET_DEST (x), SET_SRC (x))) - return; - - if (GET_MODE_SIZE (GET_MODE (SET_DEST (x))) <= GET_MODE_SIZE (DImode)) - regtype_weight[insn_uid].reg_weight_gp++; - else - regtype_weight[insn_uid].reg_weight_vec++; + return 0; + return 1; } + return 0; } -/* Calculate register weights for all instructions and modes - of all basic blocks. */ +/* Calculate register weight for given INSN. */ -static void -mips_weight_init_global (int old_max_uid) +static int +get_weight (rtx insn) { - rtx x, insn; - basic_block b; + int weight = 0; + rtx x; - regtype_weight = XCNEWVEC (struct msched_weight_info, old_max_uid); + /* Increment weight for each register born here. */ + x = PATTERN (insn); + weight = find_reg_born (x); - FOR_EACH_BB_REVERSE_FN (b, cfun) - FOR_BB_INSNS (b, insn) - if (NONDEBUG_INSN_P (insn)) + if (GET_CODE (x) == PARALLEL) + { + int i; + for (i = XVECLEN (x, 0) - 1; i >= 0; i--) { - /* Increment weight for each register born here. */ - x = PATTERN (insn); - find_regtype_weight (x, INSN_UID (insn)); - - if (GET_CODE (x) == PARALLEL) - { - int i; - for (i = XVECLEN (x, 0) - 1; i >= 0; i--) - { - x = XVECEXP (PATTERN (insn), 0, i); - find_regtype_weight (x, INSN_UID (insn)); - } - } + x = XVECEXP (PATTERN (insn), 0, i); + weight += find_reg_born (x); + } + } - /* Decrement weight for each register that dies here. */ - for (x = REG_NOTES (insn); x; x = XEXP (x, 1)) - if (REG_NOTE_KIND (x) == REG_DEAD - || REG_NOTE_KIND (x) == REG_UNUSED) - { - rtx note = XEXP (x, 0); - if (REG_P (note)) - { - if (GET_MODE_SIZE (GET_MODE (note)) - <= GET_MODE_SIZE (DImode)) - regtype_weight[INSN_UID (insn)].reg_weight_gp--; - else - regtype_weight[INSN_UID (insn)].reg_weight_vec--; - } - } + /* Decrement weight for each register that dies here. */ + for (x = REG_NOTES (insn); x; x = XEXP (x, 1)) + { + if (REG_NOTE_KIND (x) == REG_DEAD || REG_NOTE_KIND (x) == REG_UNUSED) + { + rtx note = XEXP (x, 0); + if (REG_P (note)) + weight--; } + } + return weight; +} - CURR_REGTYPE_PRESSURE (GPREG) = 0; - CURR_REGTYPE_PRESSURE (VECREG) = 0; +/* TARGET_SCHED_WEIGHT helper function. + Allocate and initialize global data. */ + +static void +mips_weight_init_global (int old_max_uid) +{ + level = (int *) xcalloc (old_max_uid, sizeof (int)); + consumer_luid = (int *) xcalloc (old_max_uid, sizeof (int)); } /* Implement TARGET_SCHED_INIT_GLOBAL. */ @@ -14721,15 +14905,72 @@ mips_sched_init_global (FILE *dump ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED, int old_max_uid) { - if (TARGET_SCHED_WEIGHT) + if (!reload_completed && TARGET_SCHED_WEIGHT) mips_weight_init_global (old_max_uid); } +/* TARGET_SCHED_WEIGHT helper function. Called for each basic block + with dependency chain information in HEAD and TAIL. + Calculates LEVEL for each INSN from its forward dependencies + and finds out UID of first consumer instruction (CONSUMER_LUID) of INSN. */ + +static void +mips_weight_evaluation (rtx head, rtx tail) +{ + sd_iterator_def sd_it; + dep_t dep; + rtx prev_head, insn, x; + prev_head = PREV_INSN (head); + + for (insn = tail; insn != prev_head; insn = PREV_INSN (insn)) + if (INSN_P (insn)) + { + FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep) + { + x = DEP_CON (dep); + if (! DEBUG_INSN_P (x)) + { + if (LEVEL (x) > LEVEL (insn)) + LEVEL (insn) = LEVEL (x); + CONSUMER_LUID (insn) = INSN_LUID (x); + } + } + LEVEL (insn)++; + } +} + +/* Implement TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK. */ + +static void +mips_evaluation_hook (rtx head, rtx tail) +{ + if (!reload_completed && TARGET_SCHED_WEIGHT) + mips_weight_evaluation (head, tail); +} + +/* Implement TARGET_SCHED_SET_SCHED_FLAGS. + Enables DONT_BREAK_DEPENDENCIES for the first scheduling pass. + It prevents breaking of dependencies on mem/inc pair in the first pass + which would otherwise increase stalls. */ + +static void +mips_set_sched_flags (spec_info_t spec_info ATTRIBUTE_UNUSED) +{ + if (!reload_completed && TARGET_SCHED_WEIGHT) + { + unsigned int *flags = &(current_sched_info->flags); + *flags |= DONT_BREAK_DEPENDENCIES; + } +} + static void mips_weight_finish_global () { - if (regtype_weight != NULL) - XDELETEVEC (regtype_weight); + if (level != NULL) + free (level); + + if (consumer_luid != NULL) + free (consumer_luid); } /* Implement TARGET_SCHED_FINISH_GLOBAL. */ @@ -14738,80 +14979,61 @@ static void mips_sched_finish_global (FILE *dump ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED) { - if (TARGET_SCHED_WEIGHT) + if (!reload_completed && TARGET_SCHED_WEIGHT) mips_weight_finish_global (); } -/* This is a TARGET_SCHED_WEIGHT (option -msched-weight) helper - function which is called during reordering of instructions in - the first pass of the scheduler. The function swaps the instruction - at the bottom (NREADY - 1) of the READY list with another instruction - in READY list as per following algorithm. The scheduler then picks the - instruction at READY[NREADY - 1] and schedules it. - When an instruction is scheduled its register weight is accumulated - in CURR_REGTYPE_PRESSURE (mode). Which is number of live registers - at that instruction. +/* This is a TARGET_SCHED_WEIGHT (option -msched-weight) helper function + which is called during reordering of instructions in the first pass + of the scheduler. The function swaps the instruction at (NREADY - 1) + of the READY list with another instruction in READY list as per + the following algorithm. The scheduler then picks the instruction + at READY[NREADY - 1] and schedules it. - If the current register pressure (CURR_REGTYPE_PRESSURE) is - more than PROMOTE_HIGH_PRIORITY_PRESSURE (25 registers) and if the - priority of the consumer of the instruction in question (INSN) is - more than the priority of READY[NREADY - 1] then INSN is swapped - with READY[NREADY - 1]. + Every instruction is assigned with a value LEVEL. + [See: mips_weight_evaluation().] - If the current register pressure (CURR_REGTYPE_PRESSURE) is - more than PROMOTE_MAX_DEP_PRESSURE (15 registers) then INSN - with maximum forward dependencies is swapped with the - READY[NREADY - 1]. */ + 1. INSN with highest LEVEL is chosen to be scheduled next, ties broken by + 1a. Choosing INSN that is used early in the flow or + 1b. Choosing INSN with greater INSN_TICK. + + 2. Choose INSN having less LEVEL number iff, + 2a. It is used early and + 2b. Has greater INSN_TICK and + 2c. Contributes less to the register pressure. */ static void mips_sched_weight (rtx *ready, int nready) { - int mode, toswap, i; - int max_forw_dependency = 0; - - toswap = nready - 1; - + int max_level = LEVEL (ready[nready-1]), toswap = nready-1; + int i; #define INSN_TICK(INSN) (HID (INSN)->tick) - mode = CURR_REGTYPE_PRESSURE (GPREG) > CURR_REGTYPE_PRESSURE (VECREG) - ? GPREG : VECREG; - - for (i = nready - 1; i >= 0; i--) + for (i = nready - 2; i >= 0; i--) { - rtx insn = ready[i], consumer_insn = NULL_RTX; - sd_iterator_def sd_it; - dep_t dep; - int forw_dependency_count = 0; - - FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep) - { - if (! DEBUG_INSN_P (DEP_CON (dep))) - forw_dependency_count++; - consumer_insn = DEP_CON (dep); - } - - if (CURR_REGTYPE_PRESSURE (mode) > PROMOTE_HIGH_PRIORITY_PRESSURE) + rtx insn = ready[i]; + if (LEVEL (insn) == max_level) { - if (consumer_insn != NULL_RTX - && INSN_PRIORITY_KNOWN (consumer_insn) - && (INSN_PRIORITY (consumer_insn) - > INSN_PRIORITY (ready[toswap]))) + if (INSN_PRIORITY (insn) >= INSN_PRIORITY (ready[toswap])) { - max_forw_dependency = forw_dependency_count; - toswap = i; + if (CONSUMER_LUID (insn) < CONSUMER_LUID (ready[toswap])) + toswap = i; } + else if (INSN_TICK (insn) > INSN_TICK(ready[toswap])) + toswap = i; } - else if (CURR_REGTYPE_PRESSURE (mode) > PROMOTE_MAX_DEP_PRESSURE) + if (LEVEL (insn) > max_level) { - if (forw_dependency_count > max_forw_dependency - || ((forw_dependency_count == max_forw_dependency) - && (INSN_TICK (insn) >= INSN_TICK (ready[toswap])) - && (INSN_UID (insn) < INSN_UID (ready[toswap])))) - { - max_forw_dependency = forw_dependency_count; - toswap = i; - } + max_level = LEVEL (insn); + toswap = i; + } + if (LEVEL (insn) < max_level) + { + if (CONSUMER_LUID (insn) < CONSUMER_LUID (ready[toswap]) + && INSN_TICK (insn) > INSN_TICK(ready[toswap]) + && get_weight (insn) < get_weight (ready[toswap])) + toswap = i; } } @@ -14823,6 +15045,7 @@ mips_sched_weight (rtx *ready, int nready) } #undef INSN_TICK } + /* Implement TARGET_SCHED_INIT. */ @@ -14839,12 +15062,6 @@ mips_sched_init (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED, pointed to ALU2. */ mips_ls2.alu1_turn_p = false; mips_ls2.falu1_turn_p = true; - - if (TARGET_SCHED_WEIGHT) - { - CURR_REGTYPE_PRESSURE (GPREG) = 0; - CURR_REGTYPE_PRESSURE (VECREG) = 0; - } } /* Subroutine used by TARGET_SCHED_REORDER and TARGET_SCHED_REORDER2. */ @@ -14942,16 +15159,6 @@ mips_variable_issue (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED, mips_74k_agen_init (insn); else if (TUNE_LOONGSON_2EF) mips_ls2_variable_issue (insn); - else if (TARGET_SCHED_WEIGHT) - { - if (regtype_weight != NULL) - { - CURR_REGTYPE_PRESSURE (GPREG) - += INSN_GPREG_WEIGHT (insn); - CURR_REGTYPE_PRESSURE (VECREG) - += INSN_VECREG_WEIGHT (insn); - } - } } /* Instructions of type 'multi' should all be split before @@ -15246,10 +15453,10 @@ AVAIL_NON_MIPS16 (msa, TARGET_MSA) #define CODE_FOR_msa_div_u_d CODE_FOR_udivv2di3 #define CODE_FOR_msa_fadd_w CODE_FOR_addv4sf3 #define CODE_FOR_msa_fadd_d CODE_FOR_addv2df3 -#define CODE_FOR_msa_ffint_s_w CODE_FOR_floatv4sfv4si2 -#define CODE_FOR_msa_ffint_s_d CODE_FOR_floatv2dfv2di2 -#define CODE_FOR_msa_ffint_u_w CODE_FOR_floatunsv4sfv4si2 -#define CODE_FOR_msa_ffint_u_d CODE_FOR_floatunsv2dfv2di2 +#define CODE_FOR_msa_ffint_s_w CODE_FOR_floatv4siv4sf2 +#define CODE_FOR_msa_ffint_s_d CODE_FOR_floatv2div2df2 +#define CODE_FOR_msa_ffint_u_w CODE_FOR_floatunsv4siv4sf2 +#define CODE_FOR_msa_ffint_u_d CODE_FOR_floatunsv2div2df2 #define CODE_FOR_msa_fsub_w CODE_FOR_subv4sf3 #define CODE_FOR_msa_fsub_d CODE_FOR_subv2df3 #define CODE_FOR_msa_fmul_w CODE_FOR_mulv4sf3 @@ -15258,14 +15465,30 @@ AVAIL_NON_MIPS16 (msa, TARGET_MSA) #define CODE_FOR_msa_fdiv_d CODE_FOR_divv2df3 #define CODE_FOR_msa_fmax_w CODE_FOR_smaxv4sf3 #define CODE_FOR_msa_fmax_d CODE_FOR_smaxv2df3 -#define CODE_FOR_msa_fmax_a_w CODE_FOR_smaxv4sf3 -#define CODE_FOR_msa_fmax_a_d CODE_FOR_smaxv2sf3 +#define CODE_FOR_msa_fmax_a_w CODE_FOR_umaxv4sf3 +#define CODE_FOR_msa_fmax_a_d CODE_FOR_umaxv2df3 #define CODE_FOR_msa_fmin_w CODE_FOR_sminv4sf3 #define CODE_FOR_msa_fmin_d CODE_FOR_sminv2df3 -#define CODE_FOR_msa_fmin_a_w CODE_FOR_sminv4sf3 -#define CODE_FOR_msa_fmin_a_d CODE_FOR_sminv2df3 +#define CODE_FOR_msa_fmin_a_w CODE_FOR_uminv4sf3 +#define CODE_FOR_msa_fmin_a_d CODE_FOR_uminv2df3 #define CODE_FOR_msa_fsqrt_w CODE_FOR_sqrtv4sf2 #define CODE_FOR_msa_fsqrt_d CODE_FOR_sqrtv2df2 +#define CODE_FOR_msa_max_s_b CODE_FOR_smaxv16qi3 +#define CODE_FOR_msa_max_s_h CODE_FOR_smaxv8hi3 +#define CODE_FOR_msa_max_s_w CODE_FOR_smaxv4si3 +#define CODE_FOR_msa_max_s_d CODE_FOR_smaxv2di3 +#define CODE_FOR_msa_max_u_b CODE_FOR_umaxv16qi3 +#define CODE_FOR_msa_max_u_h CODE_FOR_umaxv8hi3 +#define CODE_FOR_msa_max_u_w CODE_FOR_umaxv4si3 +#define CODE_FOR_msa_max_u_d CODE_FOR_umaxv2di3 +#define CODE_FOR_msa_min_s_b CODE_FOR_sminv16qi3 +#define CODE_FOR_msa_min_s_h CODE_FOR_sminv8hi3 +#define CODE_FOR_msa_min_s_w CODE_FOR_sminv4si3 +#define CODE_FOR_msa_min_s_d CODE_FOR_sminv2di3 +#define CODE_FOR_msa_min_u_b CODE_FOR_uminv16qi3 +#define CODE_FOR_msa_min_u_h CODE_FOR_uminv8hi3 +#define CODE_FOR_msa_min_u_w CODE_FOR_uminv4si3 +#define CODE_FOR_msa_min_u_d CODE_FOR_uminv2di3 #define CODE_FOR_msa_mod_s_b CODE_FOR_modv16qi3 #define CODE_FOR_msa_mod_s_h CODE_FOR_modv8hi3 #define CODE_FOR_msa_mod_s_w CODE_FOR_modv4si3 @@ -15321,6 +15544,9 @@ AVAIL_NON_MIPS16 (msa, TARGET_MSA) #define CODE_FOR_msa_vshf_w CODE_FOR_msa_vshfv4si #define CODE_FOR_msa_vshf_d CODE_FOR_msa_vshfv2di +#define CODE_FOR_msa_ilvod_d CODE_FOR_msa_ilvl_d +#define CODE_FOR_msa_ilvev_d CODE_FOR_msa_ilvr_d + #define CODE_FOR_msa_ldi_b CODE_FOR_msa_ldiv16qi #define CODE_FOR_msa_ldi_h CODE_FOR_msa_ldiv8hi #define CODE_FOR_msa_ldi_w CODE_FOR_msa_ldiv4si @@ -16161,12 +16387,15 @@ static const struct mips_builtin_description mips_builtins[] = { /* Index I is the function declaration for mips_builtins[I], or null if the function isn't defined on this target. */ static GTY(()) tree mips_builtin_decls[ARRAY_SIZE (mips_builtins)]; +/* Get the index I of the function declaration for mips_builtin_decls[I] + using the instruction code or return null if not defined for the target. */ +static GTY(()) int mips_get_builtin_decl_index[LAST_INSN_CODE]; /* MODE is a vector mode whose elements have type TYPE. Return the type of the vector itself. */ static tree -mips_builtin_vector_type (tree type, enum machine_mode mode) +mips_builtin_vector_type (tree type, machine_mode mode) { static tree types[2 * (int) MAX_MACHINE_MODE]; int mode_index; @@ -16292,10 +16521,13 @@ mips_init_builtins (void) { d = &mips_builtins[i]; if (d->avail ()) - mips_builtin_decls[i] - = add_builtin_function (d->name, - mips_build_function_type (d->function_type), - i, BUILT_IN_MD, NULL, NULL); + { + mips_builtin_decls[i] + = add_builtin_function (d->name, + mips_build_function_type (d->function_type), + i, BUILT_IN_MD, NULL, NULL); + mips_get_builtin_decl_index[d->icode] = i; + } } } @@ -16309,6 +16541,51 @@ mips_builtin_decl (unsigned int code, bool initialize_p ATTRIBUTE_UNUSED) return mips_builtin_decls[code]; } +/* Implement TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION. */ + +static tree +mips_builtin_vectorized_function (tree fndecl, tree type_out, + tree type_in) +{ + machine_mode in_mode, out_mode; + enum built_in_function fn = DECL_FUNCTION_CODE (fndecl); + int in_n, out_n; + + if (TREE_CODE (type_out) != VECTOR_TYPE + || TREE_CODE (type_in) != VECTOR_TYPE + || DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL + || !ISA_HAS_MSA) + return NULL_TREE; + + out_mode = TYPE_MODE (TREE_TYPE (type_out)); + out_n = TYPE_VECTOR_SUBPARTS (type_out); + in_mode = TYPE_MODE (TREE_TYPE (type_in)); + in_n = TYPE_VECTOR_SUBPARTS (type_in); + + /* INSN is the name of the associated instruction pattern, without + the leading CODE_FOR_. */ +#define MIPS_GET_BUILTIN(INSN) \ + mips_builtin_decls[mips_get_builtin_decl_index[CODE_FOR_##INSN]] + + switch (fn) + { + case BUILT_IN_SQRT: + if (out_mode == DFmode && out_n == 2 + && in_mode == DFmode && in_n == 2) + return MIPS_GET_BUILTIN (msa_fsqrt_d); + break; + case BUILT_IN_SQRTF: + if (out_mode == SFmode && out_n == 4 + && in_mode == SFmode && in_n == 4) + return MIPS_GET_BUILTIN (msa_fsqrt_w); + break; + default: + break; + } + + return NULL_TREE; +} + /* Take argument ARGNO from EXP's argument list and convert it into an expand operand. Store the operand in *OP. */ @@ -16524,7 +16801,7 @@ mips_expand_builtin_bposge (enum mips_builtin_type builtin_type, rtx target) static rtx mips_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED, - enum machine_mode mode, int ignore) + machine_mode mode, int ignore) { tree fndecl; unsigned int fcode, avail; @@ -16575,7 +16852,7 @@ struct mips16_constant { struct mips16_constant *next; rtx value; rtx label; - enum machine_mode mode; + machine_mode mode; }; /* Information about an incomplete MIPS16 constant pool. FIRST is the @@ -16593,7 +16870,7 @@ struct mips16_constant_pool { static rtx mips16_add_constant (struct mips16_constant_pool *pool, - rtx value, enum machine_mode mode) + rtx value, machine_mode mode) { struct mips16_constant **p, *c; bool first_of_size_p; @@ -16649,7 +16926,7 @@ mips16_add_constant (struct mips16_constant_pool *pool, instruction emitted. MODE is the mode of the constant. */ static rtx -mips16_emit_constants_1 (enum machine_mode mode, rtx value, rtx insn) +mips16_emit_constants_1 (machine_mode mode, rtx value, rtx insn) { if (SCALAR_INT_MODE_P (mode) || ALL_SCALAR_FIXED_POINT_MODE_P (mode)) { @@ -17019,7 +17296,7 @@ r10k_safe_mem_expr_p (tree expr, unsigned HOST_WIDE_INT offset) { HOST_WIDE_INT bitoffset, bitsize; tree inner, var_offset; - enum machine_mode mode; + machine_mode mode; int unsigned_p, volatile_p; inner = get_inner_reference (expr, &bitsize, &bitoffset, &var_offset, &mode, @@ -17687,7 +17964,7 @@ mips_mult_zero_zero_cost (struct mips_sim *state, bool setting) mips_tuning_info.fast_mult_zero_zero_p = setting; start_sequence (); - enum machine_mode dword_mode = TARGET_64BIT ? TImode : DImode; + machine_mode dword_mode = TARGET_64BIT ? TImode : DImode; rtx hilo = gen_rtx_REG (dword_mode, MD_REG_FIRST); mips_emit_move_or_split (hilo, const0_rtx, SPLIT_FOR_SPEED); @@ -17711,7 +17988,7 @@ 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 || !ISA_HAS_HILO) + if (TARGET_MIPS16 || (!ISA_HAS_HILO && !TARGET_DSP)) /* 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. */ @@ -18071,7 +18348,7 @@ mips_orphaned_high_part_p (mips_offset_table htab, rtx insn) static void mips_avoid_hazard (rtx after, rtx insn, int *hilo_delay, - rtx *delayed_reg, rtx lo_reg) + rtx *delayed_reg, rtx lo_reg, bool *fs_delay) { rtx pattern, set; int nops, ninsns; @@ -18097,6 +18374,15 @@ mips_avoid_hazard (rtx after, rtx insn, int *hilo_delay, nops = 2 - *hilo_delay; else if (*delayed_reg != 0 && reg_referenced_p (*delayed_reg, pattern)) nops = 1; + /* If processing a forbidden slot hazard then a NOP is required if the + branch instruction was not in a sequence (as the sequence would + imply it is not actually a compact branch anyway) and the current + insn is not an inline asm, and can't go in a delay slot. */ + else if (*fs_delay && get_attr_can_delay (insn) == CAN_DELAY_NO + && GET_CODE (PATTERN (after)) != SEQUENCE + && GET_CODE (pattern) != ASM_INPUT + && asm_noperands (pattern) < 0) + nops = 1; else nops = 0; @@ -18109,12 +18395,18 @@ mips_avoid_hazard (rtx after, rtx insn, int *hilo_delay, /* Set up the state for the next instruction. */ *hilo_delay += ninsns; *delayed_reg = 0; + *fs_delay = false; if (INSN_CODE (insn) >= 0) switch (get_attr_hazard (insn)) { case HAZARD_NONE: break; + case HAZARD_FORBIDDEN_SLOT: + if (TARGET_CB_MAYBE) + *fs_delay = true; + break; + case HAZARD_HILO: *hilo_delay = 0; break; @@ -18138,6 +18430,7 @@ mips_reorg_process_insns (void) rtx insn, last_insn, subinsn, next_insn, lo_reg, delayed_reg; int hilo_delay; mips_offset_table htab; + bool fs_delay; /* Force all instructions to be split into their final form. */ split_all_insns_noflow (); @@ -18206,6 +18499,7 @@ mips_reorg_process_insns (void) hilo_delay = 2; delayed_reg = 0; lo_reg = gen_rtx_REG (SImode, LO_REGNUM); + fs_delay = false; /* Make a second pass over the instructions. Delete orphaned high-part relocations or turn them into NOPs. Avoid hazards @@ -18229,7 +18523,7 @@ mips_reorg_process_insns (void) INSN_CODE (subinsn) = CODE_FOR_nop; } mips_avoid_hazard (last_insn, subinsn, &hilo_delay, - &delayed_reg, lo_reg); + &delayed_reg, lo_reg, &fs_delay); } last_insn = insn; } @@ -18250,7 +18544,7 @@ mips_reorg_process_insns (void) else { mips_avoid_hazard (last_insn, insn, &hilo_delay, - &delayed_reg, lo_reg); + &delayed_reg, lo_reg, &fs_delay); last_insn = insn; } } @@ -18983,7 +19277,7 @@ mips_option_override (void) else { /* -msingle-float selects 32-bit float registers. On r6 and later, - -mdouble-float selects 64-bit float registers, since the old paired + -mdouble-float selects 64-bit float registers, since the old paired register model is not supported. -mmsa selects 64-bit registers for O32. In other cases the float registers should be the same size as the integer ones. */ @@ -19094,15 +19388,11 @@ mips_option_override (void) " instructions", mips_arch_info->name); /* If neither -modd-spreg nor -mno-odd-spreg was given on the command - line, set MASK_ODD_SPREG based on the ISA. */ + line, set MASK_ODD_SPREG based on the ISA and ABI. */ if ((target_flags_explicit & MASK_ODD_SPREG) == 0) { - /* Disable TARGET_ODD_SPREG for generic architectures when using the - O32 FPXX ABI to make them compatible with those implementations - which are !ISA_HAS_ODD_SPREG. */ - if (!ISA_HAS_ODD_SPREG - || (TARGET_FLOATXX - && (strncmp (mips_arch_info->name, "mips", 4) == 0))) + /* Disable TARGET_ODD_SPREG when using the o32 FPXX ABI. */ + if (!ISA_HAS_ODD_SPREG || TARGET_FLOATXX) target_flags &= ~MASK_ODD_SPREG; else target_flags |= MASK_ODD_SPREG; @@ -19111,6 +19401,35 @@ mips_option_override (void) warning (0, "the %qs architecture does not support odd single-precision" " registers", mips_arch_info->name); + if (!TARGET_ODD_SPREG && TARGET_64BIT) + { + error ("unsupported combination: %s", "-mgp64 -mno-odd-spreg"); + /* Allow compilation to continue further even though invalid output + will be produced. */ + target_flags |= MASK_ODD_SPREG; + } + + if (!ISA_HAS_COMPACT_BRANCHES && mips_cb == MIPS_CB_ALWAYS) + { + error ("unsupported combination: %qs%s %s", + mips_arch_info->name, TARGET_MICROMIPS ? " -mmicromips" : "", + "-mcompact-branches=always"); + } + else if (!ISA_HAS_DELAY_SLOTS && mips_cb == MIPS_CB_NEVER) + { + error ("unsupported combination: %qs%s %s", + mips_arch_info->name, TARGET_MICROMIPS ? " -mmicromips" : "", + "-mcompact-branches=never"); + } + + /* Require explicit relocs for MIPS R6 onwards. This enables simplification + of the compact branch and jump support through the backend. */ + if (!TARGET_EXPLICIT_RELOCS && mips_isa_rev >= 6) + { + error ("unsupported combination: %qs %s", + mips_arch_info->name, "-mno-explicit-relocs"); + } + /* The effect of -mabicalls isn't defined for the EABI. */ if (mips_abi == ABI_EABI && TARGET_ABICALLS) { @@ -19254,14 +19573,14 @@ mips_option_override (void) if (TARGET_DSPR2) TARGET_DSP = true; - if (TARGET_DSP && mips_isa_rev >= 6) + if (TARGET_DSPR3) { - error ("the %qs architecture does not support DSP instructions", - mips_arch_info->name); - TARGET_DSP = false; - TARGET_DSPR2 = false; + TARGET_DSP = true; + TARGET_DSPR2 = true; } + + /* .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. @@ -19325,7 +19644,7 @@ mips_option_override (void) for (mode = 0; mode < MAX_MACHINE_MODE; mode++) for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) mips_hard_regno_mode_ok[mode][regno] - = mips_hard_regno_mode_ok_p (regno, (enum machine_mode) mode); + = mips_hard_regno_mode_ok_p (regno, (machine_mode) mode); /* Function to allocate machine-dependent function status. */ init_machine_status = &mips_init_machine_status; @@ -19442,7 +19761,7 @@ mips_conditional_register_usage (void) AND_COMPL_HARD_REG_SET (accessible_reg_set, reg_class_contents[(int) DSP_ACC_REGS]); - if (!ISA_HAS_HILO) + if (!ISA_HAS_HILO && !ISA_HAS_DSP) AND_COMPL_HARD_REG_SET (accessible_reg_set, reg_class_contents[(int) MD_REGS]); @@ -19533,28 +19852,6 @@ mips_conditional_register_usage (void) } } -/* When generating MIPS16 code, we want to allocate $24 (T_REG) before - other registers for instructions for which it is possible. This - encourages the compiler to use CMP in cases where an XOR would - require some register shuffling. */ - -void -mips_order_regs_for_local_alloc (void) -{ - int i; - - for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - reg_alloc_order[i] = i; - - if (TARGET_MIPS16) - { - /* It really doesn't matter where we put register 0, since it is - a fixed register anyhow. */ - reg_alloc_order[0] = 24; - reg_alloc_order[24] = 0; - } -} - /* Implement EH_USES. */ bool @@ -19845,6 +20142,64 @@ umips_load_store_pair_p_1 (bool load_p, bool swap_p, return true; } +bool +mips_load_store_bonding_p (rtx *operands, machine_mode mode, bool load_p) +{ + rtx reg1, reg2, mem1, mem2, base1, base2; + enum reg_class rc1, rc2; + HOST_WIDE_INT offset1, offset2; + + if (load_p) + { + reg1 = operands[0]; + reg2 = operands[2]; + mem1 = operands[1]; + mem2 = operands[3]; + } + else + { + reg1 = operands[1]; + reg2 = operands[3]; + mem1 = operands[0]; + mem2 = operands[2]; + } + + if (!mips_address_insns (XEXP (mem1, 0), mode, false) + || !mips_address_insns (XEXP (mem2, 0), mode, false)) + return false; + + mips_split_plus (XEXP (mem1, 0), &base1, &offset1); + mips_split_plus (XEXP (mem2, 0), &base2, &offset2); + + /* Base regs do not match. */ + if (!REG_P (base1) || !rtx_equal_p (base1, base2)) + return false; + + /* Either of the loads is clobbering base register. */ + if (load_p + && (REGNO (reg1) == REGNO (base1) + || (REGNO (reg2) == REGNO (base1)))) + return false; + + /* Loading in same registers. */ + if (load_p + && REGNO (reg1) == REGNO (reg2)) + return false; + + /* The loads/stores are not of same type. */ + rc1 = REGNO_REG_CLASS (REGNO (reg1)); + rc2 = REGNO_REG_CLASS (REGNO (reg2)); + if (rc1 != rc2 + && !reg_class_subset_p (rc1, rc2) + && !reg_class_subset_p (rc2, rc1)) + return false; + + if (abs(offset1 - offset2) != GET_MODE_SIZE (mode)) + return false; + + return true; +} + /* OPERANDS describes the operands to a pair of SETs, in the order dest1, src1, dest2, src2. Return true if the operands can be used in an LWP or SWP instruction; LOAD_P says which. */ @@ -20103,6 +20458,18 @@ mips_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) #undef OP + /* If we are using compact branches we don't have delay slots so + place the instruction that was in the delay slot before the JRC + instruction. */ + + if (TARGET_CB_ALWAYS) + { + rtx temp; + temp = trampoline[i-2]; + trampoline[i-2] = trampoline[i-1]; + trampoline[i-1] = temp; + } + /* Copy the trampoline code. Leave any padding uninitialized. */ for (j = 0; j < i; j++) { @@ -20181,7 +20548,7 @@ void mips_function_profiler (FILE *file) when TARGET_LOONGSON_VECTORS is true. */ static unsigned HOST_WIDE_INT -mips_shift_truncation_mask (enum machine_mode mode) +mips_shift_truncation_mask (machine_mode mode) { if (TARGET_LOONGSON_VECTORS && VECTOR_MODE_P (mode)) return 0; @@ -20220,13 +20587,13 @@ mips_prepare_pch_save (void) /* Generate or test for an insn that supports a constant permutation. */ -#define MAX_VECT_LEN 8 +#define MAX_VECT_LEN 16 struct expand_vec_perm_d { rtx target, op0, op1; unsigned char perm[MAX_VECT_LEN]; - enum machine_mode vmode; + machine_mode vmode; unsigned char nelt; bool one_vector_p; bool testing_p; @@ -20264,7 +20631,7 @@ static bool mips_expand_vselect_vconcat (rtx target, rtx op0, rtx op1, const unsigned char *perm, unsigned nelt) { - enum machine_mode v2mode; + machine_mode v2mode; rtx x; v2mode = GET_MODE_2XWIDER_MODE (GET_MODE (op0)); @@ -20535,10 +20902,21 @@ mips_expand_vec_perm_const (rtx operands[4]) return ok; } +/* Implement TARGET_SCHED_REASSOCIATION_WIDTH. */ + +static int +mips_sched_reassociation_width (unsigned int opc ATTRIBUTE_UNUSED, + machine_mode mode) +{ + if (MSA_SUPPORTED_MODE_P (mode)) + return 2; + return 1; +} + /* Implement TARGET_VECTORIZE_VEC_PERM_CONST_OK. */ static bool -mips_vectorize_vec_perm_const_ok (enum machine_mode vmode, +mips_vectorize_vec_perm_const_ok (machine_mode vmode, const unsigned char *sel) { struct expand_vec_perm_d d; @@ -20583,11 +20961,66 @@ mips_vectorize_vec_perm_const_ok (enum machine_mode vmode, void mips_expand_vec_unpack (rtx operands[2], bool unsigned_p, bool high_p) { - enum machine_mode imode = GET_MODE (operands[1]); + machine_mode imode = GET_MODE (operands[1]); rtx (*unpack) (rtx, rtx, rtx); - rtx (*cmpgt) (rtx, rtx, rtx); + rtx (*cmpFunc) (rtx, rtx, rtx); rtx tmp, dest, zero; + if (ISA_HAS_MSA) + { + switch (imode) + { + case V4SImode: + if (BYTES_BIG_ENDIAN != high_p) + unpack = gen_msa_ilvl_w; + else + unpack = gen_msa_ilvr_w; + + cmpFunc = gen_msa_clti_si_w; + break; + + case V8HImode: + if (BYTES_BIG_ENDIAN != high_p) + unpack = gen_msa_ilvl_h; + else + unpack = gen_msa_ilvr_h; + + cmpFunc = gen_msa_clti_si_h; + break; + + case V16QImode: + if (BYTES_BIG_ENDIAN != high_p) + unpack = gen_msa_ilvl_b; + else + unpack = gen_msa_ilvr_b; + + cmpFunc = gen_msa_clti_si_b; + break; + + default: + gcc_unreachable (); + break; + } + + if (!unsigned_p) + { + /* Extract sign extention for each element comparing each element with + immediate zero. */ + tmp = gen_reg_rtx (imode); + emit_insn (cmpFunc (tmp, operands[1], CONST0_RTX (imode))); + } + else + { + tmp = force_reg (imode, CONST0_RTX (imode)); + } + + dest = gen_reg_rtx (imode); + + emit_insn (unpack (dest, tmp, operands[1])); + emit_move_insn (operands[0], gen_lowpart (GET_MODE (operands[0]), dest)); + return; + } + switch (imode) { case V8QImode: @@ -20595,14 +21028,14 @@ mips_expand_vec_unpack (rtx operands[2], bool unsigned_p, bool high_p) unpack = gen_loongson_punpckhbh; else unpack = gen_loongson_punpcklbh; - cmpgt = gen_loongson_pcmpgtb; + cmpFunc = gen_loongson_pcmpgtb; break; case V4HImode: if (high_p) unpack = gen_loongson_punpckhhw; else unpack = gen_loongson_punpcklhw; - cmpgt = gen_loongson_pcmpgth; + cmpFunc = gen_loongson_pcmpgth; break; default: gcc_unreachable (); @@ -20614,7 +21047,7 @@ mips_expand_vec_unpack (rtx operands[2], bool unsigned_p, bool high_p) else { tmp = gen_reg_rtx (imode); - emit_insn (cmpgt (tmp, zero, operands[1])); + emit_insn (cmpFunc (tmp, zero, operands[1])); } dest = gen_reg_rtx (imode); @@ -20634,7 +21067,7 @@ mips_constant_elt_p (rtx x) /* A subroutine of mips_expand_vec_init, expand via broadcast. */ static void -mips_expand_vi_broadcast (enum machine_mode vmode, rtx target, rtx elt) +mips_expand_vi_broadcast (machine_mode vmode, rtx target, rtx elt) { struct expand_vec_perm_d d; rtx t1; @@ -20674,7 +21107,7 @@ mips_expand_vi_broadcast (enum machine_mode vmode, rtx target, rtx elt) elements of VALS with zeros, copy the constant vector to TARGET. */ static void -mips_expand_vi_constant (enum machine_mode vmode, unsigned nelt, +mips_expand_vi_constant (machine_mode vmode, unsigned nelt, rtx target, rtx vals) { rtvec vec = shallow_copy_rtvec (XVEC (vals, 0)); @@ -20705,7 +21138,7 @@ mips_expand_vi_loongson_one_pinsrh (rtx target, rtx vals, unsigned one_var) /* A subroutine of mips_expand_vec_init, expand anything via memory. */ static void -mips_expand_vi_general (enum machine_mode vmode, enum machine_mode imode, +mips_expand_vi_general (machine_mode vmode, machine_mode imode, unsigned nelt, unsigned nvar, rtx target, rtx vals) { rtx mem = assign_stack_temp (vmode, GET_MODE_SIZE (vmode)); @@ -20729,8 +21162,8 @@ mips_expand_vi_general (enum machine_mode vmode, enum machine_mode imode, void mips_expand_vector_init (rtx target, rtx vals) { - enum machine_mode vmode = GET_MODE (target); - enum machine_mode imode = GET_MODE_INNER (vmode); + machine_mode vmode = GET_MODE (target); + machine_mode imode = GET_MODE_INNER (vmode); unsigned i, nelt = GET_MODE_NUNITS (vmode); unsigned nvar = 0, one_var = -1u; bool all_same = true; @@ -20750,8 +21183,7 @@ mips_expand_vector_init (rtx target, rtx vals) if (all_same) { rtx same = XVECEXP (vals, 0, 0); - rtx temp; - rtx temp2; + rtx temp, temp2; if (CONST_INT_P (same) && nvar == 0 && mips_signed_immediate_p (INTVAL (same), 10, 0)) { @@ -20779,19 +21211,27 @@ mips_expand_vector_init (rtx target, rtx vals) } temp = gen_reg_rtx (imode); if (imode == GET_MODE (same)) - emit_move_insn (temp, same); + temp2 = same; + else if (GET_MODE_SIZE (imode) >= UNITS_PER_WORD) + temp2 = simplify_gen_subreg (imode, same, GET_MODE (same), 0); else - emit_move_insn (temp, simplify_gen_subreg (imode, same, GET_MODE (same), 0)); + { + unsigned offset = 0; + + if (TARGET_BIG_ENDIAN) + offset = GET_MODE_SIZE (GET_MODE (same)) - GET_MODE_SIZE (imode); + temp2 = simplify_gen_subreg (imode, same, GET_MODE (same), offset); + } + emit_move_insn (temp, temp2); + switch (vmode) { case V16QImode: - temp2 = simplify_gen_subreg (SImode, temp, imode, 0); - emit_insn (gen_msa_fill_b (target, temp2)); + emit_insn (gen_msa_fill_b_insn (target, temp)); break; case V8HImode: - temp2 = simplify_gen_subreg (SImode, temp, imode, 0); - emit_insn (gen_msa_fill_h (target, temp2)); + emit_insn (gen_msa_fill_h_insn (target, temp)); break; case V4SImode: @@ -20816,7 +21256,6 @@ mips_expand_vector_init (rtx target, rtx vals) return; } - rtvec vec = shallow_copy_rtvec (XVEC (vals, 0)); for (i = 0; i < nelt; ++i) @@ -20904,7 +21343,7 @@ mips_expand_vector_init (rtx target, rtx vals) void mips_expand_vec_reduc (rtx target, rtx in, rtx (*gen)(rtx, rtx, rtx)) { - enum machine_mode vmode = GET_MODE (in); + machine_mode vmode = GET_MODE (in); unsigned char perm2[2]; rtx last, next, fold, x; bool ok; @@ -20976,7 +21415,7 @@ void mips_expand_vec_minmax (rtx target, rtx op0, rtx op1, rtx (*cmp) (rtx, rtx, rtx), bool min_p) { - enum machine_mode vmode = GET_MODE (target); + machine_mode vmode = GET_MODE (target); rtx tc, t0, t1, x; tc = gen_reg_rtx (vmode); @@ -20997,10 +21436,25 @@ mips_expand_vec_minmax (rtx target, rtx op0, rtx op1, emit_insn (gen_rtx_SET (VOIDmode, target, x)); } +/* Implement HARD_REGNO_CALLER_SAVE_MODE. */ + +machine_mode +mips_hard_regno_caller_save_mode (unsigned int regno, + unsigned int nregs, + machine_mode mode) +{ + /* For performance, avoid saving/restoring upper parts of a register + by returning MODE as save mode when the mode is known. */ + if (mode == VOIDmode) + return choose_hard_reg_mode (regno, nregs, false); + else + return mode; +} + static void mips_expand_msa_one_cmpl (rtx dest, rtx src) { - enum machine_mode mode = GET_MODE (dest); + machine_mode mode = GET_MODE (dest); switch (mode) { case V16QImode: @@ -21023,7 +21477,7 @@ mips_expand_msa_one_cmpl (rtx dest, rtx src) static void mips_expand_msa_cmp (rtx dest, enum rtx_code cond, rtx op0, rtx op1) { - enum machine_mode cmp_mode = GET_MODE (op0); + machine_mode cmp_mode = GET_MODE (op0); switch (cmp_mode) { @@ -21046,13 +21500,13 @@ mips_expand_msa_cmp (rtx dest, enum rtx_code cond, rtx op0, rtx op1) emit_insn (gen_msa_cle_u_b (dest, op0, op1)); break; case GE: // swap - emit_insn (gen_msa_clt_s_b (dest, op1, op0)); + emit_insn (gen_msa_cle_s_b (dest, op1, op0)); break; case GT: // swap emit_insn (gen_msa_clt_s_b (dest, op1, op0)); break; case GEU: // swap - emit_insn (gen_msa_clt_u_b (dest, op1, op0)); + emit_insn (gen_msa_cle_u_b (dest, op1, op0)); break; case GTU: // swap emit_insn (gen_msa_clt_u_b (dest, op1, op0)); @@ -21081,13 +21535,13 @@ mips_expand_msa_cmp (rtx dest, enum rtx_code cond, rtx op0, rtx op1) emit_insn (gen_msa_cle_u_h (dest, op0, op1)); break; case GE: // swap - emit_insn (gen_msa_clt_s_h (dest, op1, op0)); + emit_insn (gen_msa_cle_s_h (dest, op1, op0)); break; case GT: // swap emit_insn (gen_msa_clt_s_h (dest, op1, op0)); break; case GEU: // swap - emit_insn (gen_msa_clt_u_h (dest, op1, op0)); + emit_insn (gen_msa_cle_u_h (dest, op1, op0)); break; case GTU: // swap emit_insn (gen_msa_clt_u_h (dest, op1, op0)); @@ -21116,13 +21570,13 @@ mips_expand_msa_cmp (rtx dest, enum rtx_code cond, rtx op0, rtx op1) emit_insn (gen_msa_cle_u_w (dest, op0, op1)); break; case GE: // swap - emit_insn (gen_msa_clt_s_w (dest, op1, op0)); + emit_insn (gen_msa_cle_s_w (dest, op1, op0)); break; case GT: // swap emit_insn (gen_msa_clt_s_w (dest, op1, op0)); break; case GEU: // swap - emit_insn (gen_msa_clt_u_w (dest, op1, op0)); + emit_insn (gen_msa_cle_u_w (dest, op1, op0)); break; case GTU: // swap emit_insn (gen_msa_clt_u_w (dest, op1, op0)); @@ -21151,13 +21605,13 @@ mips_expand_msa_cmp (rtx dest, enum rtx_code cond, rtx op0, rtx op1) emit_insn (gen_msa_cle_u_d (dest, op0, op1)); break; case GE: // swap - emit_insn (gen_msa_clt_s_d (dest, op1, op0)); + emit_insn (gen_msa_cle_s_d (dest, op1, op0)); break; case GT: // swap emit_insn (gen_msa_clt_s_d (dest, op1, op0)); break; case GEU: // swap - emit_insn (gen_msa_clt_u_d (dest, op1, op0)); + emit_insn (gen_msa_cle_u_d (dest, op1, op0)); break; case GTU: // swap emit_insn (gen_msa_clt_u_d (dest, op1, op0)); @@ -21176,6 +21630,9 @@ mips_expand_msa_cmp (rtx dest, enum rtx_code cond, rtx op0, rtx op1) case EQ: emit_insn (gen_msa_fceq_w (dest, op0, op1)); break; + case NE: + emit_insn (gen_msa_fcne_w (dest, op0, op1)); + break; case LTGT: emit_insn (gen_msa_fcne_w (dest, op0, op1)); break; @@ -21217,6 +21674,9 @@ mips_expand_msa_cmp (rtx dest, enum rtx_code cond, rtx op0, rtx op1) case EQ: emit_insn (gen_msa_fceq_d (dest, op0, op1)); break; + case NE: + emit_insn (gen_msa_fcne_d (dest, op0, op1)); + break; case LTGT: emit_insn (gen_msa_fcne_d (dest, op0, op1)); break; @@ -21274,7 +21734,6 @@ mips_msa_reversed_fp_cond (enum rtx_code *code) { switch (*code) { - case NE: case ORDERED: case UNEQ: *code = reverse_condition_maybe_unordered (*code); @@ -21285,12 +21744,16 @@ mips_msa_reversed_fp_cond (enum rtx_code *code) } } +/* Generate RTL for comparing CMP_OP0, CMP_ OP1 using condition COND + and store the result -1 or 0 in DEST TRUE_SRC and DEST_SRC + must be -1 and 0 respectively. */ + static void mips_expand_msa_vcond (rtx dest, rtx true_src, rtx false_src, enum rtx_code cond, rtx cmp_op0, rtx cmp_op1) { - enum machine_mode dest_mode = GET_MODE (dest); - enum machine_mode cmp_mode = GET_MODE (cmp_op0); + machine_mode dest_mode = GET_MODE (dest); + machine_mode cmp_mode = GET_MODE (cmp_op0); bool reversed_p; if (FLOAT_MODE_P (cmp_mode)) @@ -21307,18 +21770,17 @@ mips_expand_msa_vcond (rtx dest, rtx true_src, rtx false_src, && (false_src == CONST0_RTX (dest_mode))); } -/* Expand VEC_COND_EXPR - * MODE of result - * VIMODE equivalent integer mode - * OPERANDS operands of VEC_COND_EXPR - * gen_msa_and_fn used to generate a VIMODE vector msa AND - * gen_msa_nor_fn used to generate a VIMODE vector msa NOR - * gen_msa_ior_fn used to generate a VIMODE vector msa AND. - */ +/* Expand VEC_COND_EXPR, where: + MODE is mode of the result + VIMODE equivalent integer mode + OPERANDS operands of VEC_COND_EXPR + gen_msa_and_fn used to generate a VIMODE vector msa AND + gen_msa_nor_fn used to generate a VIMODE vector msa NOR + gen_msa_ior_fn used to generate a VIMODE vector msa AND. */ void -mips_expand_vec_cond_expr (enum machine_mode mode, - enum machine_mode vimode, +mips_expand_vec_cond_expr (machine_mode mode, + machine_mode vimode, rtx *operands, rtx (*gen_msa_and_fn)(rtx, rtx, rtx), rtx (*gen_msa_nor_fn)(rtx, rtx, rtx), @@ -21340,15 +21802,15 @@ mips_expand_vec_cond_expr (enum machine_mode mode, mips_expand_msa_vcond (res, true_val, false_val, GET_CODE (operands[3]), operands[4], operands[5]); - // This results in a vector result with whose T/F elements having - // the value -1 or 0 for (T/F repectively). This result may need - // adjusting if needed results operands[]/operands[1] are different. + /* This results in a vector result with whose T/F elements having + the value -1 or 0 for (T/F repectively). This result may need + adjusting if needed results operands[]/operands[1] are different. */ - // Adjust True elements to be operand[1]. + /* Adjust True elements to be operand[1]. */ emit_move_insn (xres, res); if (operands[1] != true_val) { - rtx xop1 = operands[1]; /* Assume we can use operands[1] */ + rtx xop1 = operands[1]; /* Assume we can use operands[1]. */ if (mode != vimode) { @@ -21375,11 +21837,11 @@ mips_expand_vec_cond_expr (enum machine_mode mode, else emit_move_insn (temp1, xres); - // Adjust False elements to be operand[0]. + /* Adjust False elements to be operand[0]. */ emit_insn (gen_msa_nor_fn (temp2, xres, xres)); if (operands[2] != false_val) { - rtx xop2 = operands[2]; ; /* Assume we can use operands[2] */ + rtx xop2 = operands[2]; ; /* Assume we can use operands[2]. */ if (mode != vimode) { @@ -21406,28 +21868,13 @@ mips_expand_vec_cond_expr (enum machine_mode mode, else emit_insn (gen_msa_and_fn (temp2, temp2, xres)); - // Combine together into result. + /* Combine together into result. */ emit_insn (gen_msa_ior_fn (xres, temp1, temp2)); emit_move_insn (operands[0], gen_rtx_SUBREG (mode, xres, 0)); } } -/* Implement HARD_REGNO_CALLER_SAVE_MODE. */ - -enum machine_mode -mips_hard_regno_caller_save_mode (unsigned int regno, - unsigned int nregs, - enum machine_mode mode) -{ - /* For performance, to avoid saving/restoring upper parts of a register, - we return MODE as save mode when MODE is not VOIDmode. */ - if (mode == VOIDmode) - return choose_hard_reg_mode (regno, nregs, false); - else - return mode; -} - /* Implement TARGET_CASE_VALUES_THRESHOLD. */ unsigned int @@ -21487,7 +21934,7 @@ mips_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update) static reg_class_t mips_spill_class (reg_class_t rclass ATTRIBUTE_UNUSED, - enum machine_mode mode ATTRIBUTE_UNUSED) + machine_mode mode ATTRIBUTE_UNUSED) { if (TARGET_MIPS16) return SPILL_REGS; @@ -21655,6 +22102,9 @@ mips_lra_p (void) #undef TARGET_MODE_REP_EXTENDED #define TARGET_MODE_REP_EXTENDED mips_mode_rep_extended +#undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION +#define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \ + mips_builtin_vectorized_function #undef TARGET_VECTOR_MODE_SUPPORTED_P #define TARGET_VECTOR_MODE_SUPPORTED_P mips_vector_mode_supported_p @@ -21710,6 +22160,8 @@ mips_lra_p (void) #endif #undef TARGET_DWARF_REGISTER_SPAN #define TARGET_DWARF_REGISTER_SPAN mips_dwarf_register_span +#undef TARGET_DWARF_FRAME_REG_MODE +#define TARGET_DWARF_FRAME_REG_MODE mips_dwarf_frame_reg_mode #undef TARGET_ASM_FINAL_POSTSCAN_INSN #define TARGET_ASM_FINAL_POSTSCAN_INSN mips_final_postscan_insn @@ -21741,6 +22193,9 @@ mips_lra_p (void) #undef TARGET_VECTORIZE_VEC_PERM_CONST_OK #define TARGET_VECTORIZE_VEC_PERM_CONST_OK mips_vectorize_vec_perm_const_ok +#undef TARGET_SCHED_REASSOCIATION_WIDTH +#define TARGET_SCHED_REASSOCIATION_WIDTH mips_sched_reassociation_width + #undef TARGET_CASE_VALUES_THRESHOLD #define TARGET_CASE_VALUES_THRESHOLD mips_case_values_threshold @@ -21758,6 +22213,12 @@ mips_lra_p (void) #undef TARGET_SCHED_FINISH_GLOBAL #define TARGET_SCHED_FINISH_GLOBAL mips_sched_finish_global +#undef TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK +#define TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK mips_evaluation_hook + +#undef TARGET_SCHED_SET_SCHED_FLAGS +#define TARGET_SCHED_SET_SCHED_FLAGS mips_set_sched_flags + struct gcc_target targetm = TARGET_INITIALIZER; #include "gt-mips.h" diff --git a/gcc-4.9/gcc/config/mips/mips.h b/gcc-4.9/gcc/config/mips/mips.h index a4c70480b..f46fec5f7 100644 --- a/gcc-4.9/gcc/config/mips/mips.h +++ b/gcc-4.9/gcc/config/mips/mips.h @@ -92,6 +92,21 @@ struct mips_cpu_info { /* True if we are generating position-independent VxWorks RTP code. */ #define TARGET_RTP_PIC (TARGET_VXWORKS_RTP && flag_pic) +/* True depending on the compact branch policy. */ +#define TARGET_CB_NEVER (mips_cb == MIPS_CB_NEVER \ + || (mips_cb == MIPS_CB_OPTIMAL \ + && !ISA_HAS_COMPACT_BRANCHES)) +#define TARGET_CB_MAYBE (TARGET_CB_ALWAYS \ + || (mips_cb == MIPS_CB_OPTIMAL \ + && ISA_HAS_COMPACT_BRANCHES)) +#define TARGET_CB_ALWAYS (mips_cb == MIPS_CB_ALWAYS \ + || (mips_cb == MIPS_CB_OPTIMAL \ + && !ISA_HAS_DELAY_SLOTS)) + +#define ISA_HAS_JRC (ISA_HAS_COMPACT_BRANCHES \ + || (TARGET_MICROMIPS \ + && mips_cb == MIPS_CB_OPTIMAL)) + /* True if the output file is marked as ".abicalls; .option pic0" (-call_nonpic). */ #define TARGET_ABICALLS_PIC0 \ @@ -181,6 +196,14 @@ struct mips_cpu_info { #define ISA_HAS_DSP_MULT ISA_HAS_DSPR2 #endif +/* ISA has LSA available. */ +#define ISA_HAS_LSA (mips_isa_rev >= 6 || ISA_HAS_MSA) + +/* ISA has DLSA available. */ +#define ISA_HAS_DLSA (TARGET_64BIT \ + && (mips_isa_rev >= 6 \ + || ISA_HAS_MSA)) + /* The ISA compression flags that are currently in effect. */ #define TARGET_COMPRESSION (target_flags & (MASK_MIPS16 | MASK_MICROMIPS)) @@ -232,8 +255,10 @@ struct mips_cpu_info { #define TARGET_MIPS7000 (mips_arch == PROCESSOR_R7000) #define TARGET_MIPS9000 (mips_arch == PROCESSOR_R9000) #define TARGET_OCTEON (mips_arch == PROCESSOR_OCTEON \ - || mips_arch == PROCESSOR_OCTEON2) -#define TARGET_OCTEON2 (mips_arch == PROCESSOR_OCTEON2) + || mips_arch == PROCESSOR_OCTEON2 \ + || mips_arch == PROCESSOR_OCTEON3) +#define TARGET_OCTEON2 (mips_arch == PROCESSOR_OCTEON2 \ + || mips_arch == PROCESSOR_OCTEON3) #define TARGET_SB1 (mips_arch == PROCESSOR_SB1 \ || mips_arch == PROCESSOR_SB1A) #define TARGET_SR71K (mips_arch == PROCESSOR_SR71000) @@ -263,10 +288,12 @@ struct mips_cpu_info { #define TUNE_MIPS7000 (mips_tune == PROCESSOR_R7000) #define TUNE_MIPS9000 (mips_tune == PROCESSOR_R9000) #define TUNE_OCTEON (mips_tune == PROCESSOR_OCTEON \ - || mips_tune == PROCESSOR_OCTEON2) + || mips_tune == PROCESSOR_OCTEON2 \ + || mips_tune == PROCESSOR_OCTEON3) #define TUNE_SB1 (mips_tune == PROCESSOR_SB1 \ || mips_tune == PROCESSOR_SB1A) #define TUNE_P5600 (mips_tune == PROCESSOR_P5600) +#define TUNE_I6400 (mips_tune == PROCESSOR_I6400) /* Whether vector modes and intrinsics for ST Microelectronics Loongson-2E/2F processors should be enabled. In o32 pairs of @@ -326,6 +353,11 @@ struct mips_cpu_info { -mfpxx, derive TARGET_FLOAT32 to represent -mfp32. */ #define TARGET_FLOAT32 (!TARGET_FLOAT64 && !TARGET_FLOATXX) +/* TARGET_O32_FP64A_ABI represents all the conditions that form the + o32 FP64A ABI extension (-mabi=32 -mfp64 -mno-odd-spreg). */ +#define TARGET_O32_FP64A_ABI (mips_abi == ABI_32 && TARGET_FLOAT64 \ + && !TARGET_ODD_SPREG) + /* False if SC acts as a memory barrier with respect to itself, otherwise a SYNC will be emitted after SC for atomic operations that require ordering between the SC and following loads and @@ -425,6 +457,11 @@ struct mips_cpu_info { builtin_define ("__mips_dspr2"); \ builtin_define ("__mips_dsp_rev=2"); \ } \ + else if (TARGET_DSPR3) \ + { \ + builtin_define ("__mips_dspr3"); \ + builtin_define ("__mips_dsp_rev=3"); \ + } \ else \ builtin_define ("__mips_dsp_rev=1"); \ } \ @@ -524,12 +561,6 @@ struct mips_cpu_info { if (mips_nan == MIPS_IEEE_754_2008) \ builtin_define ("__mips_nan2008"); \ \ - if (mips_c_lib == MIPS_LIB_SMALL) \ - builtin_define ("__mips_clib_small"); \ - \ - if (mips_c_lib == MIPS_LIB_TINY) \ - builtin_define ("__mips_clib_tiny"); \ - \ if (TARGET_BIG_ENDIAN) \ { \ builtin_define_std ("MIPSEB"); \ @@ -729,7 +760,7 @@ struct mips_cpu_info { %{march=mips64r2|march=loongson3a|march=octeon|march=xlp: -mips64r2} \ %{march=mips64r3: -mips64r3} \ %{march=mips64r5: -mips64r5} \ - %{march=mips64r6: -mips64r6} \ + %{march=mips64r6|march=i6400: -mips64r6} \ %{!march=*: -" MULTILIB_ISA_DEFAULT "}}" /* A spec that infers a -mhard-float or -msoft-float setting from an @@ -749,8 +780,8 @@ struct mips_cpu_info { #define MIPS_32BIT_OPTION_SPEC \ "mips1|mips2|mips32*|mgp32" -/* A spec condition that matches architectures should be targetted with - O32 FPXX for compatibility reasons. */ +/* A spec condition that matches architectures should be targeted with + o32 FPXX for compatibility reasons. */ #define MIPS_FPXX_OPTION_SPEC \ "mips2|mips3|mips4|mips5|mips32|mips32r2|mips32r3|mips32r5| \ mips64|mips64r2|mips64r3|mips64r5" @@ -761,6 +792,9 @@ struct mips_cpu_info { "%{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 \ || MIPS_ABI_DEFAULT == ABI_64) @@ -779,9 +813,13 @@ struct mips_cpu_info { --with-abi is ignored if -mabi is specified. --with-float is ignored if -mhard-float or -msoft-float are specified. + --with-fpu is ignored if -msoft-float, -msingle-float or -mdouble-float are + specified. --with-nan is ignored if -mnan is specified. - --with-fp is ignored if -mfp is specified. - --with-odd-spreg is ignored if -modd-spreg or -mno-odd-spreg are specified. + --with-fp-32 is ignored if -msoft-float, -msingle-float, -mmsa or -mfp are + specified. + --with-odd-spreg-32 is ignored if -msoft-float, -msingle-float, -modd-spreg + or -mno-odd-spreg are specified. --with-divide is ignored if -mdivide-traps or -mdivide-breaks are specified. */ #define OPTION_DEFAULT_SPECS \ @@ -793,10 +831,12 @@ struct mips_cpu_info { {"tune_64", "%{" OPT_ARCH64 ":%{!mtune=*:-mtune=%(VALUE)}}" }, \ {"abi", "%{!mabi=*:-mabi=%(VALUE)}" }, \ {"float", "%{!msoft-float:%{!mhard-float:-m%(VALUE)-float}}" }, \ - {"fpu", "%{!msingle-float:%{!mdouble-float:-m%(VALUE)-float}}" }, \ + {"fpu", "%{!msoft-float:%{!msingle-float:%{!mdouble-float:-m%(VALUE)-float}}}" }, \ {"nan", "%{!mnan=*:-mnan=%(VALUE)}" }, \ - {"fp_32", "%{" OPT_ARCH32 ":%{!mfp*:-mfp%(VALUE)}}" }, \ - {"odd_spreg_32", "%{" OPT_ARCH32 ":%{!modd-spreg:%{!mno-odd-spreg:-m%(VALUE)}}}" }, \ + {"fp_32", "%{" OPT_ARCH32 \ + ":%{!msoft-float:%{!msingle-float:%{!mfp*:%{!mmsa:-mfp%(VALUE)}}}}}" }, \ + {"odd_spreg_32", "%{" OPT_ARCH32 ":%{!msoft-float:%{!msingle-float:" \ + "%{!modd-spreg:%{!mno-odd-spreg:-m%(VALUE)}}}}}" }, \ {"divide", "%{!mdivide-traps:%{!mdivide-breaks:-mdivide-%(VALUE)}}" }, \ {"llsc", "%{!mllsc:%{!mno-llsc:-m%(VALUE)}}" }, \ {"mips-plt", "%{!mplt:%{!mno-plt:-m%(VALUE)}}" }, \ @@ -804,11 +844,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) @@ -846,6 +889,10 @@ struct mips_cpu_info { #define ISA_HAS_JR (mips_isa_rev <= 5) +#define ISA_HAS_DELAY_SLOTS 1 + +#define ISA_HAS_COMPACT_BRANCHES (mips_isa_rev >= 6) + /* ISA has branch likely instructions (e.g. mips2). */ /* Disable branchlikely for tx39 until compare rewrite. They haven't been generated up to this point. */ @@ -854,7 +901,8 @@ struct mips_cpu_info { /* ISA has 32 single-precision registers. */ #define ISA_HAS_ODD_SPREG ((mips_isa_rev >= 1 \ && !TARGET_LOONGSON_3A) \ - || TARGET_FLOAT64) + || TARGET_FLOAT64 \ + || TARGET_MIPS5900) /* ISA has a three-operand multiplication instruction (usually spelt "mul"). */ #define ISA_HAS_MUL3 ((TARGET_MIPS3900 \ @@ -876,7 +924,6 @@ struct mips_cpu_info { /* 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 \ @@ -885,7 +932,10 @@ struct mips_cpu_info { /* ISA supports instructions MULT and MULTU. */ #define ISA_HAS_MULT ISA_HAS_HILO +/* 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. */ @@ -902,7 +952,10 @@ struct mips_cpu_info { || 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 @@ -974,7 +1027,7 @@ 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'. */ +/* 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'. */ @@ -1069,7 +1122,7 @@ struct mips_cpu_info { && !TARGET_MIPS16) /* ISA has data prefetch with limited 9-bit displacement. */ -#define ISA_HAS_PREFETCH_9BIT (mips_isa_rev >= 6) +#define ISA_HAS_PREF_LL_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. @@ -1115,9 +1168,6 @@ struct mips_cpu_info { /* The MSA ASE is available. */ #define ISA_HAS_MSA (TARGET_MSA && !TARGET_MIPS16) -/* ISA has LSA available */ -#define ISA_HAS_LSA (TARGET_MSA && !TARGET_MIPS16) - /* True if the result of a load is not available to the next instruction. A nop will then be needed between instructions like "lw $4,..." and "addiu $4,$4,1". */ @@ -1239,6 +1289,7 @@ struct mips_cpu_info { %{mdmx} %{mno-mdmx:-no-mdmx} \ %{mdsp} %{mno-dsp} \ %{mdspr2} %{mno-dspr2} \ +%{mdspr3} %{mno-dspr3} \ %{mmcu} %{mno-mcu} \ %{meva} %{mno-eva} \ %{mvirt} %{mno-virt} \ @@ -1255,12 +1306,12 @@ struct mips_cpu_info { %{mabi=*} %{!mabi=*: %(asm_abi_default_spec)} \ %{mgp32} %{mgp64} %{march=*} %{mxgot:-xgot} \ %{mfp32} %{mfpxx} %{mfp64} %{mnan=*} \ -%{mhard-float} %{msoft-float} \ -%{mdouble-float} %{msingle-float} \ %{modd-spreg} %{mno-odd-spreg} \ %{mshared} %{mno-shared} \ %{msym32} %{mno-sym32} \ %{mtune=*} \ +%{mhard-float} %{msoft-float} \ +%{msingle-float} %{mdouble-float} \ %(subtarget_asm_spec)" /* Extra switches sometimes passed to the linker. */ @@ -1375,11 +1426,6 @@ struct mips_cpu_info { /* The DWARF 2 CFA column which tracks the return address. */ #define DWARF_FRAME_RETURN_COLUMN RETURN_ADDR_REGNUM -/* The mode to use to calculate the size of a DWARF 2 CFA column. */ -#define DWARF_REG_MODE(REGNO, MODE) \ - (FP_REG_P (REGNO) && mips_abi == ABI_32 && TARGET_FLOAT64 \ - ? SImode : (MODE)) - /* Before the prologue, RA lives in r31. */ #define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (VOIDmode, RETURN_ADDR_REGNUM) @@ -1712,7 +1758,7 @@ struct mips_cpu_info { { /* General registers. */ \ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, \ - /* Floating-point registers. */ \ + /* Floating-point registers. */ \ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ /* Others. */ \ @@ -1841,7 +1887,7 @@ struct mips_cpu_info { /* Test if REGNO is hi, lo, or one of the 6 new DSP accumulators. */ #define ACC_REG_P(REGNO) \ (MD_REG_P (REGNO) || DSP_ACC_REG_P (REGNO)) -#define MSA_REG_P(REGNO) \ +#define MSA_REG_P(REGNO) \ ((unsigned int) ((int) (REGNO) - MSA_REG_FIRST) < MSA_REG_NUM) #define FP_REG_RTX_P(X) (REG_P (X) && FP_REG_P (REGNO (X))) @@ -1870,13 +1916,12 @@ struct mips_cpu_info { #define HARD_REGNO_CALLER_SAVE_MODE(REGNO, NREGS, MODE) \ mips_hard_regno_caller_save_mode (REGNO, NREGS, MODE) -/* Odd-numbered single-precision registers are not considered call saved - for O32 FPXX as they will be clobbered when run on an FR=1 FPU. */ -/* MIPS ABIs can only save 32-bit/64-bit (single/double) FP registers. - Thus, MSA vector registers with MODE > 64 bits are part clobbered. */ +/* Odd-numbered single-precision registers are not considered callee-saved + for o32 FPXX as they will be clobbered when run on an FR=1 FPU. + MSA vector registers with MODE > 64 bits are part clobbered too. */ #define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) \ ((TARGET_FLOATXX && hard_regno_nregs[REGNO][MODE] == 1 \ - && FP_REG_P (REGNO) && (REGNO & 1)) \ + && FP_REG_P (REGNO) && ((REGNO) & 1)) \ || (TARGET_MSA && FP_REG_P (REGNO) && GET_MODE_SIZE (MODE) > 8)) #define MODES_TIEABLE_P mips_modes_tieable_p @@ -2163,13 +2208,6 @@ enum reg_class 182,183,184,185,186,187 \ } -/* ADJUST_REG_ALLOC_ORDER is a macro which permits reg_alloc_order - to be rearranged based on a particular function. On the mips16, we - want to allocate $24 (T_REG) before other registers for - instructions for which it is possible. */ - -#define ADJUST_REG_ALLOC_ORDER mips_order_regs_for_local_alloc () - /* True if VALUE is an unsigned 6-bit number. */ #define UIMM6_OPERAND(VALUE) \ @@ -2220,19 +2258,16 @@ enum reg_class #define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, X) \ mips_secondary_reload_class (CLASS, MODE, X, false) -/* When targetting the O32 FPXX ABI then all doubleword or greater moves - to/from FP registers must be performed by FR-mode-aware instructions. - This can be achieved using mfhc1/mthc1 when these instructions are +/* When targeting the o32 FPXX ABI, all moves with a length of doubleword + or greater must be performed by FR-mode-aware instructions. + This can be achieved using MFHC1/MTHC1 when these instructions are available but otherwise moves must go via memory. - For the O32 FP64A ABI then all odd-numbered doubleword or greater - moves to/from FP registers must move via memory as it is not permitted - to access the lower-half of these registers with mtc1/mfc1 since that - constitutes a single-precision access (which is forbidden). This is - implemented by requiring all double-word moves to move via memory - as this check is register class based and not register based. - Splitting the FP_REGS into even and odd classes would allow the - precise restriction to be represented but this would have a - significant affect on other areas of the backend. */ + For the o32 FP64A ABI, all odd-numbered moves with a length of + doubleword or greater are required to use memory. Using MTC1/MFC1 + to access the lower-half of these registers would require a forbidden + single-precision access. We require all double-word moves to use + memory because adding even and odd floating-point registers classes + would have a significant impact on the backend. */ #define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \ mips_secondary_memory_needed ((CLASS1), (CLASS2), (MODE)) @@ -2350,15 +2385,12 @@ enum reg_class #define FP_ARG_LAST (FP_ARG_FIRST + MAX_ARGS_IN_REGISTERS - 1) /* True if MODE is vector and supported in a MSA vector register. */ -#define MSA_SUPPORTED_VECTOR_MODE_P(MODE) \ - (GET_MODE_SIZE (MODE) == UNITS_PER_MSA_REG \ +#define MSA_SUPPORTED_MODE_P(MODE) \ + (TARGET_MSA \ + && GET_MODE_SIZE (MODE) == UNITS_PER_MSA_REG \ && (GET_MODE_CLASS (MODE) == MODE_VECTOR_INT \ || GET_MODE_CLASS (MODE) == MODE_VECTOR_FLOAT)) -/* True if MODE is supported in a MSA vector register. */ -#define MSA_SUPPORTED_MODE_P(MODE) \ - (TARGET_MSA && ((MODE) == TImode || MSA_SUPPORTED_VECTOR_MODE_P (MODE))) - /* Temporary register that is used when restoring $gp after a call. $4 and $5 are used for returning complex double values in soft-float code, so $6 is the first suitable candidate for TARGET_MIPS16. For !TARGET_MIPS16 we can use @@ -2367,9 +2399,9 @@ enum reg_class (TARGET_MIPS16 ? GP_ARG_FIRST + 2 : PIC_OFFSET_TABLE_REGNUM) /* 1 if N is a possible register number for function argument passing. - We have no FP argument registers when soft-float. When FP registers - are 32 bits, we can't directly reference the odd numbered ones. */ -/* Ignore odd numbered registers for O32 FPXX and O32 FP64. */ + We have no FP argument registers when soft-float. Special handling + is required for O32 where only even numbered registers are used for + O32-FPXX and O32-FP64. */ #define FUNCTION_ARG_REGNO_P(N) \ ((IN_RANGE((N), GP_ARG_FIRST, GP_ARG_LAST) \ @@ -2466,6 +2498,7 @@ typedef struct mips_args { to the next fully-aligned offset. */ #define MIPS_STACK_ALIGN(LOC) \ (TARGET_NEWABI ? ((LOC) + 15) & -16 : ((LOC) + 7) & -8) + /* Output assembler code to FILE to increment profiler label # LABELNO for profiling a function entry. */ @@ -2656,6 +2689,9 @@ typedef struct mips_args { #define MIPS_BRANCH(OPCODE, OPERANDS) \ "%*" OPCODE "%?\t" OPERANDS "%/" +#define MIPS_BRANCH_C(OPCODE, OPERANDS) \ + "%*" OPCODE "%:\t" OPERANDS + /* Return an asm string that forces INSN to be treated as an absolute J or JAL instruction instead of an assembler macro. */ #define MIPS_ABSOLUTE_JUMP(INSN) \ @@ -2663,45 +2699,6 @@ typedef struct mips_args { ? ".option\tpic0\n\t" INSN "\n\t.option\tpic2" \ : INSN) -/* Return the asm template for a call. INSN is the instruction's mnemonic - ("j" or "jal"), OPERANDS are its operands, TARGET_OPNO is the operand - number of the target. SIZE_OPNO is the operand number of the argument size - operand that can optionally hold the call attributes. If SIZE_OPNO is not - -1 and the call is indirect, use the function symbol from the call - attributes to attach a R_MIPS_JALR relocation to the call. - - When generating GOT code without explicit relocation operators, - all calls should use assembly macros. Otherwise, all indirect - calls should use "jr" or "jalr"; we will arrange to restore $gp - afterwards if necessary. Finally, we can only generate direct - calls for -mabicalls by temporarily switching to non-PIC mode. - - For microMIPS jal(r), we try to generate jal(r)s when a 16-bit - instruction is in the delay slot of jal(r). */ -#define MIPS_CALL(INSN, OPERANDS, TARGET_OPNO, SIZE_OPNO) \ - (TARGET_USE_GOT && !TARGET_EXPLICIT_RELOCS \ - ? "%*" INSN "\t%" #TARGET_OPNO "%/" \ - : REG_P (OPERANDS[TARGET_OPNO]) \ - ? (mips_get_pic_call_symbol (OPERANDS, SIZE_OPNO) \ - ? ("%*.reloc\t1f,R_MIPS_JALR,%" #SIZE_OPNO "\n" \ - "1:\t" INSN "r\t%" #TARGET_OPNO "%/") \ - : TARGET_MICROMIPS && !TARGET_INTERLINK_COMPRESSED \ - ? "%*" INSN "r%!\t%" #TARGET_OPNO "%/" \ - : "%*" INSN "r\t%" #TARGET_OPNO "%/") \ - : TARGET_MICROMIPS && !TARGET_INTERLINK_COMPRESSED \ - ? MIPS_ABSOLUTE_JUMP ("%*" INSN "%!\t%" #TARGET_OPNO "%/") \ - : MIPS_ABSOLUTE_JUMP ("%*" INSN "\t%" #TARGET_OPNO "%/")) \ - -/* Similar to MIPS_CALL, but this is for MICROMIPS "j" to generate - "jrc" when nop is in the delay slot of "jr". */ - -#define MICROMIPS_J(INSN, OPERANDS, OPNO) \ - (TARGET_USE_GOT && !TARGET_EXPLICIT_RELOCS \ - ? "%*j\t%" #OPNO "%/" \ - : REG_P (OPERANDS[OPNO]) \ - ? "%*jr%:\t%" #OPNO \ - : MIPS_ABSOLUTE_JUMP ("%*" INSN "\t%" #OPNO "%/")) - /* Control the assembler format that we output. */ @@ -3198,3 +3195,17 @@ extern GTY(()) struct target_globals *mips16_globals; with arguments ARGS. */ #define PMODE_INSN(NAME, ARGS) \ (Pmode == SImode ? NAME ## _si ARGS : NAME ## _di ARGS) + +/* If we are *not* using multilibs and the default ABI is not ABI_32 we + need to change these from /lib and /usr/lib. */ +#if MIPS_ABI_DEFAULT == ABI_N32 +#define STANDARD_STARTFILE_PREFIX_1 "/lib32/" +#define STANDARD_STARTFILE_PREFIX_2 "/usr/lib32/" +#elif MIPS_ABI_DEFAULT == ABI_64 +#define STANDARD_STARTFILE_PREFIX_1 "/lib64/" +#define STANDARD_STARTFILE_PREFIX_2 "/usr/lib64/" +#endif + +#define ENABLE_LD_ST_PAIRS \ + (TARGET_LOAD_STORE_PAIRS && (TUNE_P5600 || TUNE_I6400)\ + && !TARGET_MICROMIPS && !TARGET_FIX_24K) diff --git a/gcc-4.9/gcc/config/mips/mips.md b/gcc-4.9/gcc/config/mips/mips.md index 1366362f3..4f4697c4e 100644 --- a/gcc-4.9/gcc/config/mips/mips.md +++ b/gcc-4.9/gcc/config/mips/mips.md @@ -41,6 +41,7 @@ m4k octeon octeon2 + octeon3 r3900 r6000 r4000 @@ -68,6 +69,7 @@ p5600 w32 w64 + i6400 ]) (define_c_enum "unspec" [ @@ -420,6 +422,15 @@ (eq_attr "sync_mem" "!none") (const_string "syncloop")] (const_string "unknown"))) +(define_attr "compact_form" "always,maybe,never" + (cond [(eq_attr "jal" "direct") + (const_string "always") + (eq_attr "jal" "indirect") + (const_string "maybe") + (eq_attr "type" "jump") + (const_string "maybe")] + (const_string "never"))) + ;; Mode for conversion types (fcvt) ;; I2S integer to float single (SI/DI to SF) ;; I2D integer to float double (SI/DI to DF) @@ -442,22 +453,18 @@ (const_string "yes") (const_string "no"))) -(define_attr "compression" "none,all,micromips" +(define_attr "compression" "none,all,micromips32,micromips" (const_string "none")) (define_attr "enabled" "no,yes" - (cond [;; The O32 FPXX ABI prohibits direct moves between GR_REG and FR_REG - ;; for 64-bit values. + (cond [;; The o32 FPXX and FP64A ABI extensions prohibit direct moves between + ;; GR_REG and FR_REG for 64-bit values. (and (eq_attr "move_type" "mtc,mfc") (match_test "(TARGET_FLOATXX && !ISA_HAS_MXHC1) - || (mips_abi == ABI_32 - && TARGET_FLOAT64 && !TARGET_ODD_SPREG)") + || TARGET_O32_FP64A_ABI") (eq_attr "dword_mode" "yes")) (const_string "no") - - ;; The micromips compressed instruction alternatives should only be - ;; considered when targetting micromips. - (and (eq_attr "compression" "micromips") + (and (eq_attr "compression" "micromips32,micromips") (match_test "!TARGET_MICROMIPS")) (const_string "no")] (const_string "yes"))) @@ -496,13 +503,7 @@ ;; instructions. (and (eq_attr "move_type" "mtc,mfc,move") (eq_attr "qword_mode" "yes")) - (const_int 16) - - ;; Quadword CONST moves are split into four word - ;; CONST moves. - (and (eq_attr "move_type" "const") - (eq_attr "qword_mode" "yes")) - (symbol_ref "mips_split_128bit_const_insns (operands[1]) * 4") + (const_int 4) ;; Constants, loads and stores are handled by external routines. (and (eq_attr "move_type" "const,constN") @@ -557,7 +558,9 @@ ;; but there are special cases for branches (which must be handled here) ;; and for compressed single instructions. (define_attr "length" "" - (cond [(and (eq_attr "compression" "micromips,all") + (cond [(and (ior (eq_attr "compression" "micromips,all") + (and (eq_attr "compression" "micromips32") + (eq_attr "mode" "SI,SF"))) (eq_attr "dword_mode" "no") (match_test "TARGET_MICROMIPS")) (const_int 2) @@ -721,7 +724,7 @@ ;; DELAY means that the next instruction cannot read the result ;; of this one. HILO means that the next two instructions cannot ;; write to HI or LO. -(define_attr "hazard" "none,delay,hilo" +(define_attr "hazard" "none,delay,hilo,forbidden_slot" (cond [(and (eq_attr "type" "load,fpload,fpidxload") (match_test "ISA_HAS_LOAD_DELAY")) (const_string "delay") @@ -781,6 +784,11 @@ (define_mode_iterator MOVEP1 [SI SF]) (define_mode_iterator MOVEP2 [SI SF]) +(define_mode_iterator JOIN_MODE [ + HI + SI + (SF "TARGET_HARD_FLOAT") + (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")]) ;; This mode iterator allows :HILO to be used as the mode of the ;; concatenated HI and LO registers. @@ -899,8 +907,8 @@ ;; This attribute gives the upper-case mode name for one unit of a ;; floating-point mode or vector mode. (define_mode_attr UNITMODE [(SF "SF") (DF "DF") (V2SF "SF") (V4SF "SF") - (V16QI "QI") (V8HI "HI") (V4SI "SI") (V2DI "DI") - (V2DF "DF")]) + (V16QI "QI") (V8HI "HI") (V4SI "SI") (V2DI "DI") + (V2DF "DF")]) ;; This attribute gives the integer mode that has the same size as a ;; fixed-point mode. @@ -933,7 +941,7 @@ (define_mode_attr sqrt_condition [(SF "!ISA_MIPS1") (DF "!ISA_MIPS1") (V2SF "TARGET_SB1")]) -;; This attribute provides the correct nmemonic for each FP condition mode. +;; 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 @@ -1023,8 +1031,8 @@ (xor "xori") (and "andi")]) -(define_code_attr shift_compression [(ashift "micromips") - (lshiftrt "micromips") +(define_code_attr shift_compression [(ashift "micromips32") + (lshiftrt "micromips32") (ashiftrt "none")]) ;; <fcond> is the c.cond.fmt condition associated with a particular code. @@ -1052,7 +1060,7 @@ ;; This is the inverse value of bbv. (define_code_attr bbinv [(eq "1") (ne "0")]) -;; The sel nmemonic to use depending on the condition test. +;; 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")]) @@ -1069,21 +1077,36 @@ (nil) (eq_attr "can_delay" "yes")]) -;; Branches that don't have likely variants do not annul on false. +;; Branches that have delay slots and don't have likely variants do +;; not annul on false. (define_delay (and (eq_attr "type" "branch") (not (match_test "TARGET_MIPS16")) + (ior (match_test "TARGET_CB_NEVER") + (and (eq_attr "compact_form" "maybe") + (not (match_test "TARGET_CB_ALWAYS"))) + (eq_attr "compact_form" "never")) (eq_attr "branch_likely" "no")) [(eq_attr "can_delay" "yes") (nil) (nil)]) -(define_delay (eq_attr "type" "jump") +(define_delay (and (eq_attr "type" "jump") + (ior (match_test "TARGET_CB_NEVER") + (and (eq_attr "compact_form" "maybe") + (not (match_test "TARGET_CB_ALWAYS"))) + (eq_attr "compact_form" "never"))) [(eq_attr "can_delay" "yes") (nil) (nil)]) +;; Call type instructions will never have a compact form as the +;; type is only used for MIPS16 patterns (define_delay (and (eq_attr "type" "call") - (eq_attr "jal_macro" "no")) + (eq_attr "jal_macro" "no") + (ior (match_test "TARGET_CB_NEVER") + (and (eq_attr "compact_form" "maybe") + (not (match_test "TARGET_CB_ALWAYS"))) + (eq_attr "compact_form" "never"))) [(eq_attr "can_delay" "yes") (nil) (nil)]) @@ -1109,6 +1132,7 @@ (eq_attr "type" "ghost") "nothing") +(include "i6400.md") (include "p5600.md") (include "4k.md") (include "5k.md") @@ -1223,7 +1247,7 @@ return "<d>addiu\t%0,%1,%2"; } [(set_attr "alu_type" "add") - (set_attr "compression" "micromips,*,micromips,micromips,micromips,micromips,*") + (set_attr "compression" "micromips32,*,micromips32,micromips32,micromips32,micromips32,*") (set_attr "mode" "<MODE>")]) (define_insn "*add<mode>3_mips16" @@ -1441,7 +1465,7 @@ "" "<d>subu\t%0,%1,%2" [(set_attr "alu_type" "sub") - (set_attr "compression" "micromips,*") + (set_attr "compression" "micromips32,*") (set_attr "mode" "<MODE>")]) (define_insn "*subsi3_extended" @@ -2060,7 +2084,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) && ISA_HAS_MULT" + "!TARGET_64BIT && ((!TARGET_FIX_R4000 && ISA_HAS_MULT) || ISA_HAS_DSP)" { if (ISA_HAS_DSP_MULT) return "mult<u>\t%q0,%1,%2"; @@ -2510,13 +2534,13 @@ (set_attr "accum_in" "3") (set_attr "mode" "<UNITMODE>")]) -(define_insn "*maddf<mode>" +(define_insn "fma<mode>4" [(set (match_operand:ANYF 0 "register_operand" "=f") - (plus:ANYF (match_operand:ANYF 1 "register_operand" "0") - (mult:ANYF (match_operand:ANYF 2 "register_operand" "f") - (match_operand:ANYF 3 "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.<fmt>\t%0,%2,%3" + "maddf.<fmt>\t%0,%1,%2" [(set_attr "type" "fmadd") (set_attr "mode" "<UNITMODE>")]) @@ -2542,16 +2566,6 @@ (set_attr "accum_in" "3") (set_attr "mode" "<UNITMODE>")]) -(define_insn "*msubf<mode>" - [(set (match_operand:ANYF 0 "register_operand" "=f") - (minus:ANYF (match_operand:ANYF 1 "register_operand" "0") - (mult:ANYF (match_operand:ANYF 2 "register_operand" "f") - (match_operand:ANYF 3 "register_operand" "f"))))] - "ISA_HAS_FP_MADDF_MSUBF" - "msubf.<fmt>\t%0,%2,%3" - [(set_attr "type" "fmadd") - (set_attr "mode" "<UNITMODE>")]) - (define_insn "*msub3<mode>" [(set (match_operand:ANYF 0 "register_operand" "=f") (minus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f") @@ -5019,7 +5033,7 @@ (define_expand "movti" [(set (match_operand:TI 0) (match_operand:TI 1))] - "TARGET_64BIT || TARGET_MSA" + "TARGET_64BIT" { if (mips_legitimize_move (TImode, operands[0], operands[1])) DONE; @@ -5029,7 +5043,6 @@ [(set (match_operand:TI 0 "nonimmediate_operand" "=d,d,d,m,*a,*a,*d") (match_operand:TI 1 "move_operand" "d,i,m,dJ,*J,*d,*a"))] "TARGET_64BIT - && !TARGET_MSA && !TARGET_MIPS16 && (register_operand (operands[0], TImode) || reg_or_0_operand (operands[1], TImode))" @@ -5098,7 +5111,7 @@ (define_split [(set (match_operand:MOVE128 0 "nonimmediate_operand") (match_operand:MOVE128 1 "move_operand"))] - "reload_completed && !TARGET_MSA && mips_split_move_insn_p (operands[0], operands[1], insn)" + "reload_completed && mips_split_move_insn_p (operands[0], operands[1], insn)" [(const_int 0)] { mips_split_move_insn (operands[0], operands[1], curr_insn); @@ -5153,7 +5166,8 @@ (unspec:GPR [(match_operand:HILO 1 "hilo_operand" "x")] UNSPEC_MFHI))] "" - { return ISA_HAS_MACCHI ? "<GPR:d>macchi\t%0,%.,%." : "mfhi\t%0"; } + { return ISA_HAS_MACCHI ? "<GPR:d>macchi\t%0,%.,%." : + ISA_HAS_MULT ? "mfhi\t%0" : "mfhi\t%0,$ac0"; } [(set_attr "type" "mfhi") (set_attr "mode" "<GPR:MODE>")]) @@ -5166,7 +5180,12 @@ (match_operand:GPR 2 "register_operand" "l")] UNSPEC_MTHI))] "" - "mthi\t%z1" + { + if (ISA_HAS_MULT) + return "mthi\t%z1"; + else + return "mthi\t%z1, $ac0"; + } [(set_attr "type" "mthi") (set_attr "mode" "SI")]) @@ -5581,6 +5600,16 @@ (set_attr "mode" "SI") (set_attr "extended_mips16" "no,no,yes")]) +(define_insn "<GPR:d>lsa" + [(set (match_operand:GPR 0 "register_operand" "=d") + (plus:GPR (mult:GPR (match_operand:GPR 1 "register_operand" "d") + (match_operand 2 "const_immlsa_operand" "")) + (match_operand:GPR 3 "register_operand" "d")))] + "ISA_HAS_<GPR:D>LSA" + "<GPR:d>lsa\t%0,%1,%3,%y2" + [(set_attr "type" "arith") + (set_attr "mode" "<GPR:MODE>")]) + ;; We need separate DImode MIPS16 patterns because of the irregularity ;; of right shifts. (define_insn "*ashldi3_mips16" @@ -5777,25 +5806,29 @@ [(set (pc) (if_then_else (match_operator 1 "order_operator" - [(match_operand:GPR 2 "register_operand" "d") - (const_int 0)]) + [(match_operand:GPR 2 "register_operand" "d,d") + (match_operand:GPR 3 "reg_or_0_operand" "J,d")]) (label_ref (match_operand 0 "" "")) (pc)))] "!TARGET_MIPS16" { return mips_output_order_conditional_branch (insn, operands, false); } - [(set_attr "type" "branch")]) + [(set_attr "type" "branch") + (set_attr "compact_form" "maybe,always") + (set_attr "hazard" "forbidden_slot")]) (define_insn "*branch_order<mode>_inverted" [(set (pc) (if_then_else (match_operator 1 "order_operator" - [(match_operand:GPR 2 "register_operand" "d") - (const_int 0)]) + [(match_operand:GPR 2 "register_operand" "d,d") + (match_operand:GPR 3 "reg_or_0_operand" "J,d")]) (pc) (label_ref (match_operand 0 "" ""))))] "!TARGET_MIPS16" { return mips_output_order_conditional_branch (insn, operands, true); } - [(set_attr "type" "branch")]) + [(set_attr "type" "branch") + (set_attr "compact_form" "maybe,always") + (set_attr "hazard" "forbidden_slot")]) ;; Conditional branch on equality comparison. @@ -5808,20 +5841,10 @@ (label_ref (match_operand 0 "" "")) (pc)))] "!TARGET_MIPS16" -{ - /* For a simple BNEZ or BEQZ microMIPS branch. */ - if (TARGET_MICROMIPS - && operands[3] == const0_rtx - && get_attr_length (insn) <= 8) - return mips_output_conditional_branch (insn, operands, - "%*b%C1z%:\t%2,%0", - "%*b%N1z%:\t%2,%0"); - - return mips_output_conditional_branch (insn, operands, - MIPS_BRANCH ("b%C1", "%2,%z3,%0"), - MIPS_BRANCH ("b%N1", "%2,%z3,%0")); -} - [(set_attr "type" "branch")]) + { return mips_output_equal_conditional_branch (insn, operands, false); } + [(set_attr "type" "branch") + (set_attr "compact_form" "maybe") + (set_attr "hazard" "forbidden_slot")]) (define_insn "*branch_equality<mode>_inverted" [(set (pc) @@ -5832,20 +5855,10 @@ (pc) (label_ref (match_operand 0 "" ""))))] "!TARGET_MIPS16" -{ - /* For a simple BNEZ or BEQZ microMIPS branch. */ - if (TARGET_MICROMIPS - && operands[3] == const0_rtx - && get_attr_length (insn) <= 8) - return mips_output_conditional_branch (insn, operands, - "%*b%N0z%:\t%2,%1", - "%*b%C0z%:\t%2,%1"); - - return mips_output_conditional_branch (insn, operands, - MIPS_BRANCH ("b%N1", "%2,%z3,%0"), - MIPS_BRANCH ("b%C1", "%2,%z3,%0")); -} - [(set_attr "type" "branch")]) + { return mips_output_equal_conditional_branch (insn, operands, true); } + [(set_attr "type" "branch") + (set_attr "compact_form" "maybe") + (set_attr "hazard" "forbidden_slot")]) ;; MIPS16 branches @@ -6115,7 +6128,7 @@ (define_insn "s<code>_<SCALARF:mode>_using_<FPCC:mode>" [(set (match_operand:FPCC 0 "register_operand" "=<reg>") (swapped_fcond:FPCC (match_operand:SCALARF 1 "register_operand" "f") - (match_operand:SCALARF 2 "register_operand" "f")))] + (match_operand:SCALARF 2 "register_operand" "f")))] "" "<fpcmp>.<swapped_fcond>.<fmt>\t%Z0%2,%1" [(set_attr "type" "fcmp") @@ -6139,14 +6152,23 @@ (label_ref (match_operand 0)))] "!TARGET_MIPS16 && TARGET_ABSOLUTE_JUMPS" { - /* Use a branch for microMIPS. The assembler will choose - a 16-bit branch, a 32-bit branch, or a 32-bit jump. */ - if (TARGET_MICROMIPS && !TARGET_ABICALLS_PIC2) - return "%*b\t%l0%/"; + if (get_attr_length (insn) <= 8) + { + if (TARGET_CB_MAYBE) + return MIPS_ABSOLUTE_JUMP ("%*b%:\t%l0"); + else + return MIPS_ABSOLUTE_JUMP ("%*b\t%l0%/"); + } else - return MIPS_ABSOLUTE_JUMP ("%*j\t%l0%/"); + { + if (TARGET_CB_MAYBE && !final_sequence) + return MIPS_ABSOLUTE_JUMP ("%*bc\t%l0"); + else + return MIPS_ABSOLUTE_JUMP ("%*j\t%l0%/"); + } } - [(set_attr "type" "jump")]) + [(set_attr "type" "branch") + (set_attr "compact_form" "maybe")]) (define_insn "*jump_pic" [(set (pc) @@ -6154,14 +6176,23 @@ "!TARGET_MIPS16 && !TARGET_ABSOLUTE_JUMPS" { if (get_attr_length (insn) <= 8) - return "%*b\t%l0%/"; + { + if (TARGET_CB_MAYBE) + return "%*b%:\t%l0"; + else + return "%*b\t%l0%/"; + } else { mips_output_load_label (operands[0]); - return "%*jr\t%@%/%]"; + if (TARGET_CB_MAYBE) + return "%*jr%:\t%@%]"; + else + return "%*jr\t%@%/%]"; } } - [(set_attr "type" "branch")]) + [(set_attr "type" "branch") + (set_attr "compact_form" "maybe")]) ;; We need a different insn for the mips16, because a mips16 branch ;; does not have a delay slot. @@ -6208,12 +6239,9 @@ (define_insn "indirect_jump_<mode>" [(set (pc) (match_operand:P 0 "register_operand" "d"))] "" -{ - if (TARGET_MICROMIPS) - return "%*jr%:\t%0"; - else - return "%*j\t%0%/"; -} + { + return mips_output_jump (operands, 0, -1, false); + } [(set_attr "type" "jump") (set_attr "mode" "none")]) @@ -6257,12 +6285,9 @@ (match_operand:P 0 "register_operand" "d")) (use (label_ref (match_operand 1 "" "")))] "" -{ - if (TARGET_MICROMIPS) - return "%*jr%:\t%0"; - else - return "%*j\t%0%/"; -} + { + return mips_output_jump (operands, 0, -1, false); + } [(set_attr "type" "jump") (set_attr "mode" "none")]) @@ -6474,10 +6499,8 @@ [(any_return)] "" { - if (TARGET_MICROMIPS) - return "%*jr%:\t$31"; - else - return "%*j\t$31%/"; + operands[0] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM); + return mips_output_jump (operands, 0, -1, false); } [(set_attr "type" "jump") (set_attr "mode" "none")]) @@ -6488,12 +6511,10 @@ [(any_return) (use (match_operand 0 "pmode_register_operand" ""))] "" -{ - if (TARGET_MICROMIPS) - return "%*jr%:\t%0"; - else - return "%*j\t%0%/"; -} + { + operands[0] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM); + return mips_output_jump (operands, 0, -1, false); + } [(set_attr "type" "jump") (set_attr "mode" "none")]) @@ -6749,12 +6770,7 @@ [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S")) (match_operand 1 "" ""))] "TARGET_SIBCALLS && SIBLING_CALL_P (insn)" -{ - if (TARGET_MICROMIPS) - return MICROMIPS_J ("j", operands, 0); - else - return MIPS_CALL ("j", operands, 0, 1); -} + { return mips_output_jump (operands, 0, 1, false); } [(set_attr "jal" "indirect,direct") (set_attr "jal_macro" "no")]) @@ -6775,12 +6791,7 @@ (call (mem:SI (match_operand 1 "call_insn_operand" "j,S")) (match_operand 2 "" "")))] "TARGET_SIBCALLS && SIBLING_CALL_P (insn)" -{ - if (TARGET_MICROMIPS) - return MICROMIPS_J ("j", operands, 1); - else - return MIPS_CALL ("j", operands, 1, 2); -} + { return mips_output_jump (operands, 1, 2, false); } [(set_attr "jal" "indirect,direct") (set_attr "jal_macro" "no")]) @@ -6792,12 +6803,7 @@ (call (mem:SI (match_dup 1)) (match_dup 2)))] "TARGET_SIBCALLS && SIBLING_CALL_P (insn)" -{ - if (TARGET_MICROMIPS) - return MICROMIPS_J ("j", operands, 1); - else - return MIPS_CALL ("j", operands, 1, 2); -} + { return mips_output_jump (operands, 1, 2, false); } [(set_attr "jal" "indirect,direct") (set_attr "jal_macro" "no")]) @@ -6853,7 +6859,10 @@ (match_operand 1 "" "")) (clobber (reg:SI RETURN_ADDR_REGNUM))] "" - { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 0, 1); } + { + return (TARGET_SPLIT_CALLS ? "#" + : mips_output_jump (operands, 0, 1, true)); + } "reload_completed && TARGET_SPLIT_CALLS" [(const_int 0)] { @@ -6868,7 +6877,7 @@ (clobber (reg:SI RETURN_ADDR_REGNUM)) (clobber (reg:SI 28))] "TARGET_SPLIT_CALLS" - { return MIPS_CALL ("jal", operands, 0, 1); } + { return mips_output_jump (operands, 0, 1, true); } [(set_attr "jal" "indirect,direct") (set_attr "jal_macro" "no")]) @@ -6882,7 +6891,10 @@ (const_int 1) (clobber (reg:SI RETURN_ADDR_REGNUM))] "" - { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 0, -1); } + { + return (TARGET_SPLIT_CALLS ? "#" + : mips_output_jump (operands, 0, -1, true)); + } "reload_completed && TARGET_SPLIT_CALLS" [(const_int 0)] { @@ -6899,7 +6911,7 @@ (clobber (reg:SI RETURN_ADDR_REGNUM)) (clobber (reg:SI 28))] "TARGET_SPLIT_CALLS" - { return MIPS_CALL ("jal", operands, 0, -1); } + { return mips_output_jump (operands, 0, -1, true); } [(set_attr "jal" "direct") (set_attr "jal_macro" "no")]) @@ -6922,7 +6934,10 @@ (match_operand 2 "" ""))) (clobber (reg:SI RETURN_ADDR_REGNUM))] "" - { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1, 2); } + { + return (TARGET_SPLIT_CALLS ? "#" + : mips_output_jump (operands, 1, 2, true)); + } "reload_completed && TARGET_SPLIT_CALLS" [(const_int 0)] { @@ -6940,7 +6955,7 @@ (clobber (reg:SI RETURN_ADDR_REGNUM)) (clobber (reg:SI 28))] "TARGET_SPLIT_CALLS" - { return MIPS_CALL ("jal", operands, 1, 2); } + { return mips_output_jump (operands, 1, 2, true); } [(set_attr "jal" "indirect,direct") (set_attr "jal_macro" "no")]) @@ -6952,7 +6967,10 @@ (const_int 1) (clobber (reg:SI RETURN_ADDR_REGNUM))] "" - { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1, -1); } + { + return (TARGET_SPLIT_CALLS ? "#" + : mips_output_jump (operands, 1, -1, true)); + } "reload_completed && TARGET_SPLIT_CALLS" [(const_int 0)] { @@ -6971,7 +6989,7 @@ (clobber (reg:SI RETURN_ADDR_REGNUM)) (clobber (reg:SI 28))] "TARGET_SPLIT_CALLS" - { return MIPS_CALL ("jal", operands, 1, -1); } + { return mips_output_jump (operands, 1, -1, true); } [(set_attr "jal" "direct") (set_attr "jal_macro" "no")]) @@ -6985,7 +7003,10 @@ (match_dup 2))) (clobber (reg:SI RETURN_ADDR_REGNUM))] "" - { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1, 2); } + { + return (TARGET_SPLIT_CALLS ? "#" + : mips_output_jump (operands, 1, 2, true)); + } "reload_completed && TARGET_SPLIT_CALLS" [(const_int 0)] { @@ -7006,7 +7027,7 @@ (clobber (reg:SI RETURN_ADDR_REGNUM)) (clobber (reg:SI 28))] "TARGET_SPLIT_CALLS" - { return MIPS_CALL ("jal", operands, 1, 2); } + { return mips_output_jump (operands, 1, 2, true); } [(set_attr "jal" "indirect,direct") (set_attr "jal_macro" "no")]) @@ -7141,7 +7162,7 @@ [(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)) + (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 @@ -7205,9 +7226,9 @@ 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 + 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. */ + the unusual duality between single and double precision values. */ if (ISA_HAS_SEL && <MODE>mode == DFmode && (!TARGET_ODD_SPREG || TARGET_FLOATXX)) FAIL; @@ -7376,7 +7397,7 @@ (clobber (reg:P PIC_FUNCTION_ADDR_REGNUM)) (clobber (reg:P RETURN_ADDR_REGNUM))] "HAVE_AS_TLS && TARGET_MIPS16" - { return MIPS_CALL ("jal", operands, 0, -1); } + { return mips_output_jump (operands, 0, -1, true); } [(set_attr "type" "call") (set_attr "insn_count" "3") (set_attr "mode" "<MODE>")]) @@ -7417,7 +7438,7 @@ (clobber (reg:P PIC_FUNCTION_ADDR_REGNUM)) (clobber (reg:P RETURN_ADDR_REGNUM))] "TARGET_HARD_FLOAT_ABI && TARGET_MIPS16" - { return MIPS_CALL ("jal", operands, 0, -1); } + { return mips_output_jump (operands, 0, -1, true); } [(set_attr "type" "call") (set_attr "insn_count" "3")]) @@ -7447,9 +7468,101 @@ (clobber (reg:P PIC_FUNCTION_ADDR_REGNUM)) (clobber (reg:P RETURN_ADDR_REGNUM))] "TARGET_HARD_FLOAT_ABI && TARGET_MIPS16" - { return MIPS_CALL ("jal", operands, 0, -1); } + { return mips_output_jump (operands, 0, -1, true); } [(set_attr "type" "call") (set_attr "insn_count" "3")]) + +(define_insn "*join2_load_store<JOIN_MODE:mode>" + [(set (match_operand:JOIN_MODE 0 "nonimmediate_operand" "=d,f,m,m") + (match_operand:JOIN_MODE 1 "nonimmediate_operand" "m,m,d,f")) + (set (match_operand:JOIN_MODE 2 "nonimmediate_operand" "=d,f,m,m") + (match_operand:JOIN_MODE 3 "nonimmediate_operand" "m,m,d,f"))] + "ENABLE_LD_ST_PAIRS && reload_completed" + { + bool load_p = (which_alternative == 0 || which_alternative == 1); + if (!load_p || !reg_overlap_mentioned_p (operands[0], operands[1])) + { + output_asm_insn (mips_output_move (operands[0], operands[1]), operands); + output_asm_insn (mips_output_move (operands[2], operands[3]), &operands[2]); + } + else + { + output_asm_insn (mips_output_move (operands[2], operands[3]), &operands[2]); + output_asm_insn (mips_output_move (operands[0], operands[1]), operands); + } + return ""; + } + [(set_attr "move_type" "load,fpload,store,fpstore") + (set_attr "insn_count" "2,2,2,2")]) + +;; 2 HI/SI/SF/DF loads are joined. +;; P5600 does not support bonding of two LBs, hence QI mode is not included. +(define_peephole2 + [(set (match_operand:JOIN_MODE 0 "register_operand") + (match_operand:JOIN_MODE 1 "non_volatile_mem_operand")) + (set (match_operand:JOIN_MODE 2 "register_operand") + (match_operand:JOIN_MODE 3 "non_volatile_mem_operand"))] + "ENABLE_LD_ST_PAIRS && + mips_load_store_bonding_p (operands, <JOIN_MODE:MODE>mode, true)" + [(parallel [(set (match_dup 0) + (match_dup 1)) + (set (match_dup 2) + (match_dup 3))])] + "") + +;; 2 HI/SI/SF/DF stores are joined. +;; P5600 does not support bonding of two SBs, hence QI mode is not included. +(define_peephole2 + [(set (match_operand:JOIN_MODE 0 "memory_operand") + (match_operand:JOIN_MODE 1 "register_operand")) + (set (match_operand:JOIN_MODE 2 "memory_operand") + (match_operand:JOIN_MODE 3 "register_operand"))] + "ENABLE_LD_ST_PAIRS && + mips_load_store_bonding_p (operands, <JOIN_MODE:MODE>mode, false)" + [(parallel [(set (match_dup 0) + (match_dup 1)) + (set (match_dup 2) + (match_dup 3))])] + "") + +(define_insn "*join2_loadhi" + [(set (match_operand:SI 0 "register_operand" "=r") + (any_extend:SI (match_operand:HI 1 "memory_operand" "m"))) + (set (match_operand:SI 2 "register_operand" "=r") + (any_extend:SI (match_operand:HI 3 "memory_operand" "m")))] + "ENABLE_LD_ST_PAIRS && reload_completed" + { + if (!reg_overlap_mentioned_p (operands[0], operands[1])) + { + output_asm_insn ("lh<u>\t%0,%1", operands); + output_asm_insn ("lh<u>\t%2,%3", operands); + } + else + { + output_asm_insn ("lh<u>\t%2,%3", operands); + output_asm_insn ("lh<u>\t%0,%1", operands); + } + + return ""; + } + [(set_attr "move_type" "load") + (set_attr "insn_count" "2")]) + + +;; 2 16 bit integer loads are joined. +(define_peephole2 + [(set (match_operand:SI 0 "register_operand") + (any_extend:SI (match_operand:HI 1 "non_volatile_mem_operand"))) + (set (match_operand:SI 2 "register_operand") + (any_extend:SI (match_operand:HI 3 "non_volatile_mem_operand")))] + "ENABLE_LD_ST_PAIRS && + mips_load_store_bonding_p (operands, HImode, true)" + [(parallel [(set (match_dup 0) + (any_extend:SI (match_dup 1))) + (set (match_dup 2) + (any_extend:SI (match_dup 3)))])] + "") + ;; Synchronization instructions. diff --git a/gcc-4.9/gcc/config/mips/mips.opt b/gcc-4.9/gcc/config/mips/mips.opt index 740fdd6d8..88a08f5fc 100644 --- a/gcc-4.9/gcc/config/mips/mips.opt +++ b/gcc-4.9/gcc/config/mips/mips.opt @@ -123,6 +123,10 @@ mdspr2 Target Report Var(TARGET_DSPR2) Use MIPS-DSP REV 2 instructions +mdspr3 +Target Report Var(TARGET_DSPR3) +Use MIPS-DSP Rev 3 instructions + mdebug Target Var(TARGET_DEBUG_MODE) Undocumented @@ -199,7 +203,7 @@ Use 32-bit floating-point registers mfpxx Target Report RejectNegative Mask(FLOATXX) -Follow the O32 FPXX ABI +Conform to the o32 FPXX ABI mfp64 Target Report RejectNegative Mask(FLOAT64) @@ -431,25 +435,29 @@ Enable use of odd-numbered single-precision registers noasmopt Driver -mclib= -Target RejectNegative Joined Var(mips_c_lib) ToLower Enum(mips_lib_setting) Init(MIPS_LIB_NEWLIB) -Specify the C library to use with this application -newlib Use newlib -small Use SmallLib -tiny Use SmallLib optimised for size +mload-store-pairs +Target Report Var(TARGET_LOAD_STORE_PAIRS) Undocumented +Enable load/store bonding. + +msched-weight +Target Report Var(TARGET_SCHED_WEIGHT) Undocumented + +mcompact-branches= +Target RejectNegative JoinedOrMissing Var(mips_cb) Report Enum(mips_cb_setting) Init(MIPS_CB_OPTIMAL) +Specify the compact branch usage policy +never Only use delay slot branches +optimal Use compact branches where beneficial +always Only use compact branches Enum -Name(mips_lib_setting) Type(enum mips_lib_setting) -Known MIPS C libraries (for use with the -mclib= option): +Name(mips_cb_setting) Type(enum mips_cb_setting) +Policies available for use with -mcompact-branches= EnumValue -Enum(mips_lib_setting) String(newlib) Value(MIPS_LIB_NEWLIB) +Enum(mips_cb_setting) String(never) Value(MIPS_CB_NEVER) EnumValue -Enum(mips_lib_setting) String(small) Value(MIPS_LIB_SMALL) +Enum(mips_cb_setting) String(optimal) Value(MIPS_CB_OPTIMAL) EnumValue -Enum(mips_lib_setting) String(tiny) Value(MIPS_LIB_TINY) - -msched-weight -Target Report Var(TARGET_SCHED_WEIGHT) Undocumented +Enum(mips_cb_setting) String(always) Value(MIPS_CB_ALWAYS) diff --git a/gcc-4.9/gcc/config/mips/msa.h b/gcc-4.9/gcc/config/mips/msa.h index 64fa42c71..fe2eaa1ac 100644 --- a/gcc-4.9/gcc/config/mips/msa.h +++ b/gcc-4.9/gcc/config/mips/msa.h @@ -51,1063 +51,1071 @@ typedef double v2f64_d __attribute__ ((vector_size(16), aligned(8))); #ifndef __clang__ extern v16i8 __builtin_msa_sll_b(v16i8, v16i8); -#define __msa_sll_b __builtin_msa_sll_b extern v8i16 __builtin_msa_sll_h(v8i16, v8i16); -#define __msa_sll_h __builtin_msa_sll_h extern v4i32 __builtin_msa_sll_w(v4i32, v4i32); -#define __msa_sll_w __builtin_msa_sll_w extern v2i64 __builtin_msa_sll_d(v2i64, v2i64); -#define __msa_sll_d __builtin_msa_sll_d extern v16i8 __builtin_msa_slli_b(v16i8, unsigned char); -#define __msa_slli_b __builtin_msa_slli_b extern v8i16 __builtin_msa_slli_h(v8i16, unsigned char); -#define __msa_slli_h __builtin_msa_slli_h extern v4i32 __builtin_msa_slli_w(v4i32, unsigned char); -#define __msa_slli_w __builtin_msa_slli_w extern v2i64 __builtin_msa_slli_d(v2i64, unsigned char); -#define __msa_slli_d __builtin_msa_slli_d extern v16i8 __builtin_msa_sra_b(v16i8, v16i8); -#define __msa_sra_b __builtin_msa_sra_b extern v8i16 __builtin_msa_sra_h(v8i16, v8i16); -#define __msa_sra_h __builtin_msa_sra_h extern v4i32 __builtin_msa_sra_w(v4i32, v4i32); -#define __msa_sra_w __builtin_msa_sra_w extern v2i64 __builtin_msa_sra_d(v2i64, v2i64); -#define __msa_sra_d __builtin_msa_sra_d extern v16i8 __builtin_msa_srai_b(v16i8, unsigned char); -#define __msa_srai_b __builtin_msa_srai_b extern v8i16 __builtin_msa_srai_h(v8i16, unsigned char); -#define __msa_srai_h __builtin_msa_srai_h extern v4i32 __builtin_msa_srai_w(v4i32, unsigned char); -#define __msa_srai_w __builtin_msa_srai_w extern v2i64 __builtin_msa_srai_d(v2i64, unsigned char); -#define __msa_srai_d __builtin_msa_srai_d extern v16i8 __builtin_msa_srar_b(v16i8, v16i8); -#define __msa_srar_b __builtin_msa_srar_b extern v8i16 __builtin_msa_srar_h(v8i16, v8i16); -#define __msa_srar_h __builtin_msa_srar_h extern v4i32 __builtin_msa_srar_w(v4i32, v4i32); -#define __msa_srar_w __builtin_msa_srar_w extern v2i64 __builtin_msa_srar_d(v2i64, v2i64); -#define __msa_srar_d __builtin_msa_srar_d extern v16i8 __builtin_msa_srari_b(v16i8, unsigned char); -#define __msa_srari_b __builtin_msa_srari_b extern v8i16 __builtin_msa_srari_h(v8i16, unsigned char); -#define __msa_srari_h __builtin_msa_srari_h extern v4i32 __builtin_msa_srari_w(v4i32, unsigned char); -#define __msa_srari_w __builtin_msa_srari_w extern v2i64 __builtin_msa_srari_d(v2i64, unsigned char); -#define __msa_srari_d __builtin_msa_srari_d extern v16i8 __builtin_msa_srl_b(v16i8, v16i8); -#define __msa_srl_b __builtin_msa_srl_b extern v8i16 __builtin_msa_srl_h(v8i16, v8i16); -#define __msa_srl_h __builtin_msa_srl_h extern v4i32 __builtin_msa_srl_w(v4i32, v4i32); -#define __msa_srl_w __builtin_msa_srl_w extern v2i64 __builtin_msa_srl_d(v2i64, v2i64); -#define __msa_srl_d __builtin_msa_srl_d extern v16i8 __builtin_msa_srli_b(v16i8, unsigned char); -#define __msa_srli_b __builtin_msa_srli_b extern v8i16 __builtin_msa_srli_h(v8i16, unsigned char); -#define __msa_srli_h __builtin_msa_srli_h extern v4i32 __builtin_msa_srli_w(v4i32, unsigned char); -#define __msa_srli_w __builtin_msa_srli_w extern v2i64 __builtin_msa_srli_d(v2i64, unsigned char); -#define __msa_srli_d __builtin_msa_srli_d extern v16i8 __builtin_msa_srlr_b(v16i8, v16i8); -#define __msa_srlr_b __builtin_msa_srlr_b extern v8i16 __builtin_msa_srlr_h(v8i16, v8i16); -#define __msa_srlr_h __builtin_msa_srlr_h extern v4i32 __builtin_msa_srlr_w(v4i32, v4i32); -#define __msa_srlr_w __builtin_msa_srlr_w extern v2i64 __builtin_msa_srlr_d(v2i64, v2i64); -#define __msa_srlr_d __builtin_msa_srlr_d extern v16i8 __builtin_msa_srlri_b(v16i8, unsigned char); -#define __msa_srlri_b __builtin_msa_srlri_b extern v8i16 __builtin_msa_srlri_h(v8i16, unsigned char); -#define __msa_srlri_h __builtin_msa_srlri_h extern v4i32 __builtin_msa_srlri_w(v4i32, unsigned char); -#define __msa_srlri_w __builtin_msa_srlri_w extern v2i64 __builtin_msa_srlri_d(v2i64, unsigned char); -#define __msa_srlri_d __builtin_msa_srlri_d extern v16u8 __builtin_msa_bclr_b(v16u8, v16u8); -#define __msa_bclr_b __builtin_msa_bclr_b extern v8u16 __builtin_msa_bclr_h(v8u16, v8u16); -#define __msa_bclr_h __builtin_msa_bclr_h extern v4u32 __builtin_msa_bclr_w(v4u32, v4u32); -#define __msa_bclr_w __builtin_msa_bclr_w extern v2u64 __builtin_msa_bclr_d(v2u64, v2u64); -#define __msa_bclr_d __builtin_msa_bclr_d extern v16u8 __builtin_msa_bclri_b(v16u8, unsigned char); -#define __msa_bclri_b __builtin_msa_bclri_b extern v8u16 __builtin_msa_bclri_h(v8u16, unsigned char); -#define __msa_bclri_h __builtin_msa_bclri_h extern v4u32 __builtin_msa_bclri_w(v4u32, unsigned char); -#define __msa_bclri_w __builtin_msa_bclri_w extern v2u64 __builtin_msa_bclri_d(v2u64, unsigned char); -#define __msa_bclri_d __builtin_msa_bclri_d extern v16u8 __builtin_msa_bset_b(v16u8, v16u8); -#define __msa_bset_b __builtin_msa_bset_b extern v8u16 __builtin_msa_bset_h(v8u16, v8u16); -#define __msa_bset_h __builtin_msa_bset_h extern v4u32 __builtin_msa_bset_w(v4u32, v4u32); -#define __msa_bset_w __builtin_msa_bset_w extern v2u64 __builtin_msa_bset_d(v2u64, v2u64); -#define __msa_bset_d __builtin_msa_bset_d extern v16u8 __builtin_msa_bseti_b(v16u8, unsigned char); -#define __msa_bseti_b __builtin_msa_bseti_b extern v8u16 __builtin_msa_bseti_h(v8u16, unsigned char); -#define __msa_bseti_h __builtin_msa_bseti_h extern v4u32 __builtin_msa_bseti_w(v4u32, unsigned char); -#define __msa_bseti_w __builtin_msa_bseti_w extern v2u64 __builtin_msa_bseti_d(v2u64, unsigned char); -#define __msa_bseti_d __builtin_msa_bseti_d extern v16u8 __builtin_msa_bneg_b(v16u8, v16u8); -#define __msa_bneg_b __builtin_msa_bneg_b extern v8u16 __builtin_msa_bneg_h(v8u16, v8u16); -#define __msa_bneg_h __builtin_msa_bneg_h extern v4u32 __builtin_msa_bneg_w(v4u32, v4u32); -#define __msa_bneg_w __builtin_msa_bneg_w extern v2u64 __builtin_msa_bneg_d(v2u64, v2u64); -#define __msa_bneg_d __builtin_msa_bneg_d extern v16u8 __builtin_msa_bnegi_b(v16u8, unsigned char); -#define __msa_bnegi_b __builtin_msa_bnegi_b extern v8u16 __builtin_msa_bnegi_h(v8u16, unsigned char); -#define __msa_bnegi_h __builtin_msa_bnegi_h extern v4u32 __builtin_msa_bnegi_w(v4u32, unsigned char); -#define __msa_bnegi_w __builtin_msa_bnegi_w extern v2u64 __builtin_msa_bnegi_d(v2u64, unsigned char); -#define __msa_bnegi_d __builtin_msa_bnegi_d extern v16u8 __builtin_msa_binsl_b(v16u8, v16u8, v16u8); -#define __msa_binsl_b __builtin_msa_binsl_b extern v8u16 __builtin_msa_binsl_h(v8u16, v8u16, v8u16); -#define __msa_binsl_h __builtin_msa_binsl_h extern v4u32 __builtin_msa_binsl_w(v4u32, v4u32, v4u32); -#define __msa_binsl_w __builtin_msa_binsl_w extern v2u64 __builtin_msa_binsl_d(v2u64, v2u64, v2u64); -#define __msa_binsl_d __builtin_msa_binsl_d extern v16u8 __builtin_msa_binsli_b(v16u8, v16u8, unsigned char); -#define __msa_binsli_b __builtin_msa_binsli_b extern v8u16 __builtin_msa_binsli_h(v8u16, v8u16, unsigned char); -#define __msa_binsli_h __builtin_msa_binsli_h extern v4u32 __builtin_msa_binsli_w(v4u32, v4u32, unsigned char); -#define __msa_binsli_w __builtin_msa_binsli_w extern v2u64 __builtin_msa_binsli_d(v2u64, v2u64, unsigned char); -#define __msa_binsli_d __builtin_msa_binsli_d extern v16u8 __builtin_msa_binsr_b(v16u8, v16u8, v16u8); -#define __msa_binsr_b __builtin_msa_binsr_b extern v8u16 __builtin_msa_binsr_h(v8u16, v8u16, v8u16); -#define __msa_binsr_h __builtin_msa_binsr_h extern v4u32 __builtin_msa_binsr_w(v4u32, v4u32, v4u32); -#define __msa_binsr_w __builtin_msa_binsr_w extern v2u64 __builtin_msa_binsr_d(v2u64, v2u64, v2u64); -#define __msa_binsr_d __builtin_msa_binsr_d extern v16u8 __builtin_msa_binsri_b(v16u8, v16u8, unsigned char); -#define __msa_binsri_b __builtin_msa_binsri_b extern v8u16 __builtin_msa_binsri_h(v8u16, v8u16, unsigned char); -#define __msa_binsri_h __builtin_msa_binsri_h extern v4u32 __builtin_msa_binsri_w(v4u32, v4u32, unsigned char); -#define __msa_binsri_w __builtin_msa_binsri_w extern v2u64 __builtin_msa_binsri_d(v2u64, v2u64, unsigned char); -#define __msa_binsri_d __builtin_msa_binsri_d extern v16i8 __builtin_msa_addv_b(v16i8, v16i8); -#define __msa_addv_b __builtin_msa_addv_b extern v8i16 __builtin_msa_addv_h(v8i16, v8i16); -#define __msa_addv_h __builtin_msa_addv_h extern v4i32 __builtin_msa_addv_w(v4i32, v4i32); -#define __msa_addv_w __builtin_msa_addv_w extern v2i64 __builtin_msa_addv_d(v2i64, v2i64); -#define __msa_addv_d __builtin_msa_addv_d extern v16i8 __builtin_msa_addvi_b(v16i8, unsigned char); -#define __msa_addvi_b __builtin_msa_addvi_b extern v8i16 __builtin_msa_addvi_h(v8i16, unsigned char); -#define __msa_addvi_h __builtin_msa_addvi_h extern v4i32 __builtin_msa_addvi_w(v4i32, unsigned char); -#define __msa_addvi_w __builtin_msa_addvi_w extern v2i64 __builtin_msa_addvi_d(v2i64, unsigned char); -#define __msa_addvi_d __builtin_msa_addvi_d extern v16i8 __builtin_msa_subv_b(v16i8, v16i8); -#define __msa_subv_b __builtin_msa_subv_b extern v8i16 __builtin_msa_subv_h(v8i16, v8i16); -#define __msa_subv_h __builtin_msa_subv_h extern v4i32 __builtin_msa_subv_w(v4i32, v4i32); -#define __msa_subv_w __builtin_msa_subv_w extern v2i64 __builtin_msa_subv_d(v2i64, v2i64); -#define __msa_subv_d __builtin_msa_subv_d extern v16i8 __builtin_msa_subvi_b(v16i8, unsigned char); -#define __msa_subvi_b __builtin_msa_subvi_b extern v8i16 __builtin_msa_subvi_h(v8i16, unsigned char); -#define __msa_subvi_h __builtin_msa_subvi_h extern v4i32 __builtin_msa_subvi_w(v4i32, unsigned char); -#define __msa_subvi_w __builtin_msa_subvi_w extern v2i64 __builtin_msa_subvi_d(v2i64, unsigned char); -#define __msa_subvi_d __builtin_msa_subvi_d extern v16i8 __builtin_msa_max_s_b(v16i8, v16i8); -#define __msa_max_s_b __builtin_msa_max_s_b extern v8i16 __builtin_msa_max_s_h(v8i16, v8i16); -#define __msa_max_s_h __builtin_msa_max_s_h extern v4i32 __builtin_msa_max_s_w(v4i32, v4i32); -#define __msa_max_s_w __builtin_msa_max_s_w extern v2i64 __builtin_msa_max_s_d(v2i64, v2i64); -#define __msa_max_s_d __builtin_msa_max_s_d extern v16i8 __builtin_msa_maxi_s_b(v16i8, char); -#define __msa_maxi_s_b __builtin_msa_maxi_s_b extern v8i16 __builtin_msa_maxi_s_h(v8i16, char); -#define __msa_maxi_s_h __builtin_msa_maxi_s_h extern v4i32 __builtin_msa_maxi_s_w(v4i32, char); -#define __msa_maxi_s_w __builtin_msa_maxi_s_w extern v2i64 __builtin_msa_maxi_s_d(v2i64, char); -#define __msa_maxi_s_d __builtin_msa_maxi_s_d extern v16u8 __builtin_msa_max_u_b(v16u8, v16u8); -#define __msa_max_u_b __builtin_msa_max_u_b extern v8u16 __builtin_msa_max_u_h(v8u16, v8u16); -#define __msa_max_u_h __builtin_msa_max_u_h extern v4u32 __builtin_msa_max_u_w(v4u32, v4u32); -#define __msa_max_u_w __builtin_msa_max_u_w extern v2u64 __builtin_msa_max_u_d(v2u64, v2u64); -#define __msa_max_u_d __builtin_msa_max_u_d extern v16u8 __builtin_msa_maxi_u_b(v16u8, unsigned char); -#define __msa_maxi_u_b __builtin_msa_maxi_u_b extern v8u16 __builtin_msa_maxi_u_h(v8u16, unsigned char); -#define __msa_maxi_u_h __builtin_msa_maxi_u_h extern v4u32 __builtin_msa_maxi_u_w(v4u32, unsigned char); -#define __msa_maxi_u_w __builtin_msa_maxi_u_w extern v2u64 __builtin_msa_maxi_u_d(v2u64, unsigned char); -#define __msa_maxi_u_d __builtin_msa_maxi_u_d extern v16i8 __builtin_msa_min_s_b(v16i8, v16i8); -#define __msa_min_s_b __builtin_msa_min_s_b extern v8i16 __builtin_msa_min_s_h(v8i16, v8i16); -#define __msa_min_s_h __builtin_msa_min_s_h extern v4i32 __builtin_msa_min_s_w(v4i32, v4i32); -#define __msa_min_s_w __builtin_msa_min_s_w extern v2i64 __builtin_msa_min_s_d(v2i64, v2i64); -#define __msa_min_s_d __builtin_msa_min_s_d extern v16i8 __builtin_msa_mini_s_b(v16i8, char); -#define __msa_mini_s_b __builtin_msa_mini_s_b extern v8i16 __builtin_msa_mini_s_h(v8i16, char); -#define __msa_mini_s_h __builtin_msa_mini_s_h extern v4i32 __builtin_msa_mini_s_w(v4i32, char); -#define __msa_mini_s_w __builtin_msa_mini_s_w extern v2i64 __builtin_msa_mini_s_d(v2i64, char); -#define __msa_mini_s_d __builtin_msa_mini_s_d extern v16u8 __builtin_msa_min_u_b(v16u8, v16u8); -#define __msa_min_u_b __builtin_msa_min_u_b extern v8u16 __builtin_msa_min_u_h(v8u16, v8u16); -#define __msa_min_u_h __builtin_msa_min_u_h extern v4u32 __builtin_msa_min_u_w(v4u32, v4u32); -#define __msa_min_u_w __builtin_msa_min_u_w extern v2u64 __builtin_msa_min_u_d(v2u64, v2u64); -#define __msa_min_u_d __builtin_msa_min_u_d extern v16u8 __builtin_msa_mini_u_b(v16u8, unsigned char); -#define __msa_mini_u_b __builtin_msa_mini_u_b extern v8u16 __builtin_msa_mini_u_h(v8u16, unsigned char); -#define __msa_mini_u_h __builtin_msa_mini_u_h extern v4u32 __builtin_msa_mini_u_w(v4u32, unsigned char); -#define __msa_mini_u_w __builtin_msa_mini_u_w extern v2u64 __builtin_msa_mini_u_d(v2u64, unsigned char); -#define __msa_mini_u_d __builtin_msa_mini_u_d extern v16i8 __builtin_msa_max_a_b(v16i8, v16i8); -#define __msa_max_a_b __builtin_msa_max_a_b extern v8i16 __builtin_msa_max_a_h(v8i16, v8i16); -#define __msa_max_a_h __builtin_msa_max_a_h extern v4i32 __builtin_msa_max_a_w(v4i32, v4i32); -#define __msa_max_a_w __builtin_msa_max_a_w extern v2i64 __builtin_msa_max_a_d(v2i64, v2i64); -#define __msa_max_a_d __builtin_msa_max_a_d extern v16i8 __builtin_msa_min_a_b(v16i8, v16i8); -#define __msa_min_a_b __builtin_msa_min_a_b extern v8i16 __builtin_msa_min_a_h(v8i16, v8i16); -#define __msa_min_a_h __builtin_msa_min_a_h extern v4i32 __builtin_msa_min_a_w(v4i32, v4i32); -#define __msa_min_a_w __builtin_msa_min_a_w extern v2i64 __builtin_msa_min_a_d(v2i64, v2i64); -#define __msa_min_a_d __builtin_msa_min_a_d extern v16i8 __builtin_msa_ceq_b(v16i8, v16i8); -#define __msa_ceq_b __builtin_msa_ceq_b extern v8i16 __builtin_msa_ceq_h(v8i16, v8i16); -#define __msa_ceq_h __builtin_msa_ceq_h extern v4i32 __builtin_msa_ceq_w(v4i32, v4i32); -#define __msa_ceq_w __builtin_msa_ceq_w extern v2i64 __builtin_msa_ceq_d(v2i64, v2i64); -#define __msa_ceq_d __builtin_msa_ceq_d extern v16i8 __builtin_msa_ceqi_b(v16i8, char); -#define __msa_ceqi_b __builtin_msa_ceqi_b extern v8i16 __builtin_msa_ceqi_h(v8i16, char); -#define __msa_ceqi_h __builtin_msa_ceqi_h extern v4i32 __builtin_msa_ceqi_w(v4i32, char); -#define __msa_ceqi_w __builtin_msa_ceqi_w extern v2i64 __builtin_msa_ceqi_d(v2i64, char); -#define __msa_ceqi_d __builtin_msa_ceqi_d extern v16i8 __builtin_msa_clt_s_b(v16i8, v16i8); -#define __msa_clt_s_b __builtin_msa_clt_s_b extern v8i16 __builtin_msa_clt_s_h(v8i16, v8i16); -#define __msa_clt_s_h __builtin_msa_clt_s_h extern v4i32 __builtin_msa_clt_s_w(v4i32, v4i32); -#define __msa_clt_s_w __builtin_msa_clt_s_w extern v2i64 __builtin_msa_clt_s_d(v2i64, v2i64); -#define __msa_clt_s_d __builtin_msa_clt_s_d extern v16i8 __builtin_msa_clti_s_b(v16i8, char); -#define __msa_clti_s_b __builtin_msa_clti_s_b extern v8i16 __builtin_msa_clti_s_h(v8i16, char); -#define __msa_clti_s_h __builtin_msa_clti_s_h extern v4i32 __builtin_msa_clti_s_w(v4i32, char); -#define __msa_clti_s_w __builtin_msa_clti_s_w extern v2i64 __builtin_msa_clti_s_d(v2i64, char); -#define __msa_clti_s_d __builtin_msa_clti_s_d extern v16i8 __builtin_msa_clt_u_b(v16u8, v16u8); -#define __msa_clt_u_b __builtin_msa_clt_u_b extern v8i16 __builtin_msa_clt_u_h(v8u16, v8u16); -#define __msa_clt_u_h __builtin_msa_clt_u_h extern v4i32 __builtin_msa_clt_u_w(v4u32, v4u32); -#define __msa_clt_u_w __builtin_msa_clt_u_w extern v2i64 __builtin_msa_clt_u_d(v2u64, v2u64); -#define __msa_clt_u_d __builtin_msa_clt_u_d extern v16i8 __builtin_msa_clti_u_b(v16u8, unsigned char); -#define __msa_clti_u_b __builtin_msa_clti_u_b extern v8i16 __builtin_msa_clti_u_h(v8u16, unsigned char); -#define __msa_clti_u_h __builtin_msa_clti_u_h extern v4i32 __builtin_msa_clti_u_w(v4u32, unsigned char); -#define __msa_clti_u_w __builtin_msa_clti_u_w extern v2i64 __builtin_msa_clti_u_d(v2u64, unsigned char); -#define __msa_clti_u_d __builtin_msa_clti_u_d extern v16i8 __builtin_msa_cle_s_b(v16i8, v16i8); -#define __msa_cle_s_b __builtin_msa_cle_s_b extern v8i16 __builtin_msa_cle_s_h(v8i16, v8i16); -#define __msa_cle_s_h __builtin_msa_cle_s_h extern v4i32 __builtin_msa_cle_s_w(v4i32, v4i32); -#define __msa_cle_s_w __builtin_msa_cle_s_w extern v2i64 __builtin_msa_cle_s_d(v2i64, v2i64); -#define __msa_cle_s_d __builtin_msa_cle_s_d extern v16i8 __builtin_msa_clei_s_b(v16i8, char); -#define __msa_clei_s_b __builtin_msa_clei_s_b extern v8i16 __builtin_msa_clei_s_h(v8i16, char); -#define __msa_clei_s_h __builtin_msa_clei_s_h extern v4i32 __builtin_msa_clei_s_w(v4i32, char); -#define __msa_clei_s_w __builtin_msa_clei_s_w extern v2i64 __builtin_msa_clei_s_d(v2i64, char); -#define __msa_clei_s_d __builtin_msa_clei_s_d extern v16i8 __builtin_msa_cle_u_b(v16u8, v16u8); -#define __msa_cle_u_b __builtin_msa_cle_u_b extern v8i16 __builtin_msa_cle_u_h(v8u16, v8u16); -#define __msa_cle_u_h __builtin_msa_cle_u_h extern v4i32 __builtin_msa_cle_u_w(v4u32, v4u32); -#define __msa_cle_u_w __builtin_msa_cle_u_w extern v2i64 __builtin_msa_cle_u_d(v2u64, v2u64); -#define __msa_cle_u_d __builtin_msa_cle_u_d extern v16i8 __builtin_msa_clei_u_b(v16u8, unsigned char); -#define __msa_clei_u_b __builtin_msa_clei_u_b extern v8i16 __builtin_msa_clei_u_h(v8u16, unsigned char); -#define __msa_clei_u_h __builtin_msa_clei_u_h extern v4i32 __builtin_msa_clei_u_w(v4u32, unsigned char); -#define __msa_clei_u_w __builtin_msa_clei_u_w extern v2i64 __builtin_msa_clei_u_d(v2u64, unsigned char); -#define __msa_clei_u_d __builtin_msa_clei_u_d extern v16i8 __builtin_msa_ld_b(void *, int); -#define __msa_ld_b __builtin_msa_ld_b extern v8i16 __builtin_msa_ld_h(void *, int); -#define __msa_ld_h __builtin_msa_ld_h extern v4i32 __builtin_msa_ld_w(void *, int); -#define __msa_ld_w __builtin_msa_ld_w extern v2i64 __builtin_msa_ld_d(void *, int); -#define __msa_ld_d __builtin_msa_ld_d +extern void __builtin_msa_st_b(v16i8, char *, int); +extern void __builtin_msa_st_h(v8i16, char *, int); +extern void __builtin_msa_st_w(v4i32, char *, int); +extern void __builtin_msa_st_d(v2i64, char *, int); extern v16i8 __builtin_msa_sat_s_b(v16i8, unsigned char); -#define __msa_sat_s_b __builtin_msa_sat_s_b extern v8i16 __builtin_msa_sat_s_h(v8i16, unsigned char); -#define __msa_sat_s_h __builtin_msa_sat_s_h extern v4i32 __builtin_msa_sat_s_w(v4i32, unsigned char); -#define __msa_sat_s_w __builtin_msa_sat_s_w extern v2i64 __builtin_msa_sat_s_d(v2i64, unsigned char); -#define __msa_sat_s_d __builtin_msa_sat_s_d extern v16u8 __builtin_msa_sat_u_b(v16u8, unsigned char); -#define __msa_sat_u_b __builtin_msa_sat_u_b extern v8u16 __builtin_msa_sat_u_h(v8u16, unsigned char); -#define __msa_sat_u_h __builtin_msa_sat_u_h extern v4u32 __builtin_msa_sat_u_w(v4u32, unsigned char); -#define __msa_sat_u_w __builtin_msa_sat_u_w extern v2u64 __builtin_msa_sat_u_d(v2u64, unsigned char); -#define __msa_sat_u_d __builtin_msa_sat_u_d extern v16i8 __builtin_msa_add_a_b(v16i8, v16i8); -#define __msa_add_a_b __builtin_msa_add_a_b extern v8i16 __builtin_msa_add_a_h(v8i16, v8i16); -#define __msa_add_a_h __builtin_msa_add_a_h extern v4i32 __builtin_msa_add_a_w(v4i32, v4i32); -#define __msa_add_a_w __builtin_msa_add_a_w extern v2i64 __builtin_msa_add_a_d(v2i64, v2i64); -#define __msa_add_a_d __builtin_msa_add_a_d extern v16i8 __builtin_msa_adds_a_b(v16i8, v16i8); -#define __msa_adds_a_b __builtin_msa_adds_a_b extern v8i16 __builtin_msa_adds_a_h(v8i16, v8i16); -#define __msa_adds_a_h __builtin_msa_adds_a_h extern v4i32 __builtin_msa_adds_a_w(v4i32, v4i32); -#define __msa_adds_a_w __builtin_msa_adds_a_w extern v2i64 __builtin_msa_adds_a_d(v2i64, v2i64); -#define __msa_adds_a_d __builtin_msa_adds_a_d extern v16i8 __builtin_msa_adds_s_b(v16i8, v16i8); -#define __msa_adds_s_b __builtin_msa_adds_s_b extern v8i16 __builtin_msa_adds_s_h(v8i16, v8i16); -#define __msa_adds_s_h __builtin_msa_adds_s_h extern v4i32 __builtin_msa_adds_s_w(v4i32, v4i32); -#define __msa_adds_s_w __builtin_msa_adds_s_w extern v2i64 __builtin_msa_adds_s_d(v2i64, v2i64); -#define __msa_adds_s_d __builtin_msa_adds_s_d extern v16u8 __builtin_msa_adds_u_b(v16u8, v16u8); -#define __msa_adds_u_b __builtin_msa_adds_u_b extern v8u16 __builtin_msa_adds_u_h(v8u16, v8u16); -#define __msa_adds_u_h __builtin_msa_adds_u_h extern v4u32 __builtin_msa_adds_u_w(v4u32, v4u32); -#define __msa_adds_u_w __builtin_msa_adds_u_w extern v2u64 __builtin_msa_adds_u_d(v2u64, v2u64); -#define __msa_adds_u_d __builtin_msa_adds_u_d extern v16i8 __builtin_msa_ave_s_b(v16i8, v16i8); -#define __msa_ave_s_b __builtin_msa_ave_s_b extern v8i16 __builtin_msa_ave_s_h(v8i16, v8i16); -#define __msa_ave_s_h __builtin_msa_ave_s_h extern v4i32 __builtin_msa_ave_s_w(v4i32, v4i32); -#define __msa_ave_s_w __builtin_msa_ave_s_w extern v2i64 __builtin_msa_ave_s_d(v2i64, v2i64); -#define __msa_ave_s_d __builtin_msa_ave_s_d extern v16u8 __builtin_msa_ave_u_b(v16u8, v16u8); -#define __msa_ave_u_b __builtin_msa_ave_u_b extern v8u16 __builtin_msa_ave_u_h(v8u16, v8u16); -#define __msa_ave_u_h __builtin_msa_ave_u_h extern v4u32 __builtin_msa_ave_u_w(v4u32, v4u32); -#define __msa_ave_u_w __builtin_msa_ave_u_w extern v2u64 __builtin_msa_ave_u_d(v2u64, v2u64); -#define __msa_ave_u_d __builtin_msa_ave_u_d extern v16i8 __builtin_msa_aver_s_b(v16i8, v16i8); -#define __msa_aver_s_b __builtin_msa_aver_s_b extern v8i16 __builtin_msa_aver_s_h(v8i16, v8i16); -#define __msa_aver_s_h __builtin_msa_aver_s_h extern v4i32 __builtin_msa_aver_s_w(v4i32, v4i32); -#define __msa_aver_s_w __builtin_msa_aver_s_w extern v2i64 __builtin_msa_aver_s_d(v2i64, v2i64); -#define __msa_aver_s_d __builtin_msa_aver_s_d extern v16u8 __builtin_msa_aver_u_b(v16u8, v16u8); -#define __msa_aver_u_b __builtin_msa_aver_u_b extern v8u16 __builtin_msa_aver_u_h(v8u16, v8u16); -#define __msa_aver_u_h __builtin_msa_aver_u_h extern v4u32 __builtin_msa_aver_u_w(v4u32, v4u32); -#define __msa_aver_u_w __builtin_msa_aver_u_w extern v2u64 __builtin_msa_aver_u_d(v2u64, v2u64); -#define __msa_aver_u_d __builtin_msa_aver_u_d extern v16i8 __builtin_msa_subs_s_b(v16i8, v16i8); -#define __msa_subs_s_b __builtin_msa_subs_s_b extern v8i16 __builtin_msa_subs_s_h(v8i16, v8i16); -#define __msa_subs_s_h __builtin_msa_subs_s_h extern v4i32 __builtin_msa_subs_s_w(v4i32, v4i32); -#define __msa_subs_s_w __builtin_msa_subs_s_w extern v2i64 __builtin_msa_subs_s_d(v2i64, v2i64); -#define __msa_subs_s_d __builtin_msa_subs_s_d extern v16u8 __builtin_msa_subs_u_b(v16u8, v16u8); -#define __msa_subs_u_b __builtin_msa_subs_u_b extern v8u16 __builtin_msa_subs_u_h(v8u16, v8u16); -#define __msa_subs_u_h __builtin_msa_subs_u_h extern v4u32 __builtin_msa_subs_u_w(v4u32, v4u32); -#define __msa_subs_u_w __builtin_msa_subs_u_w extern v2u64 __builtin_msa_subs_u_d(v2u64, v2u64); -#define __msa_subs_u_d __builtin_msa_subs_u_d extern v16i8 __builtin_msa_subsuu_s_b(v16u8, v16u8); -#define __msa_subsuu_s_b __builtin_msa_subsuu_s_b extern v8i16 __builtin_msa_subsuu_s_h(v8u16, v8u16); -#define __msa_subsuu_s_h __builtin_msa_subsuu_s_h extern v4i32 __builtin_msa_subsuu_s_w(v4u32, v4u32); -#define __msa_subsuu_s_w __builtin_msa_subsuu_s_w extern v2i64 __builtin_msa_subsuu_s_d(v2u64, v2u64); -#define __msa_subsuu_s_d __builtin_msa_subsuu_s_d extern v16u8 __builtin_msa_subsus_u_b(v16u8, v16i8); -#define __msa_subsus_u_b __builtin_msa_subsus_u_b extern v8u16 __builtin_msa_subsus_u_h(v8u16, v8i16); -#define __msa_subsus_u_h __builtin_msa_subsus_u_h extern v4u32 __builtin_msa_subsus_u_w(v4u32, v4i32); -#define __msa_subsus_u_w __builtin_msa_subsus_u_w extern v2u64 __builtin_msa_subsus_u_d(v2u64, v2i64); -#define __msa_subsus_u_d __builtin_msa_subsus_u_d extern v16i8 __builtin_msa_asub_s_b(v16i8, v16i8); -#define __msa_asub_s_b __builtin_msa_asub_s_b extern v8i16 __builtin_msa_asub_s_h(v8i16, v8i16); -#define __msa_asub_s_h __builtin_msa_asub_s_h extern v4i32 __builtin_msa_asub_s_w(v4i32, v4i32); -#define __msa_asub_s_w __builtin_msa_asub_s_w extern v2i64 __builtin_msa_asub_s_d(v2i64, v2i64); -#define __msa_asub_s_d __builtin_msa_asub_s_d extern v16u8 __builtin_msa_asub_u_b(v16u8, v16u8); -#define __msa_asub_u_b __builtin_msa_asub_u_b extern v8u16 __builtin_msa_asub_u_h(v8u16, v8u16); -#define __msa_asub_u_h __builtin_msa_asub_u_h extern v4u32 __builtin_msa_asub_u_w(v4u32, v4u32); -#define __msa_asub_u_w __builtin_msa_asub_u_w extern v2u64 __builtin_msa_asub_u_d(v2u64, v2u64); -#define __msa_asub_u_d __builtin_msa_asub_u_d extern v16i8 __builtin_msa_mulv_b(v16i8, v16i8); -#define __msa_mulv_b __builtin_msa_mulv_b extern v8i16 __builtin_msa_mulv_h(v8i16, v8i16); -#define __msa_mulv_h __builtin_msa_mulv_h extern v4i32 __builtin_msa_mulv_w(v4i32, v4i32); -#define __msa_mulv_w __builtin_msa_mulv_w extern v2i64 __builtin_msa_mulv_d(v2i64, v2i64); -#define __msa_mulv_d __builtin_msa_mulv_d extern v16i8 __builtin_msa_maddv_b(v16i8, v16i8, v16i8); -#define __msa_maddv_b __builtin_msa_maddv_b extern v8i16 __builtin_msa_maddv_h(v8i16, v8i16, v8i16); -#define __msa_maddv_h __builtin_msa_maddv_h extern v4i32 __builtin_msa_maddv_w(v4i32, v4i32, v4i32); -#define __msa_maddv_w __builtin_msa_maddv_w extern v2i64 __builtin_msa_maddv_d(v2i64, v2i64, v2i64); -#define __msa_maddv_d __builtin_msa_maddv_d extern v16i8 __builtin_msa_msubv_b(v16i8, v16i8, v16i8); -#define __msa_msubv_b __builtin_msa_msubv_b extern v8i16 __builtin_msa_msubv_h(v8i16, v8i16, v8i16); -#define __msa_msubv_h __builtin_msa_msubv_h extern v4i32 __builtin_msa_msubv_w(v4i32, v4i32, v4i32); -#define __msa_msubv_w __builtin_msa_msubv_w extern v2i64 __builtin_msa_msubv_d(v2i64, v2i64, v2i64); -#define __msa_msubv_d __builtin_msa_msubv_d extern v16i8 __builtin_msa_div_s_b(v16i8, v16i8); -#define __msa_div_s_b __builtin_msa_div_s_b extern v8i16 __builtin_msa_div_s_h(v8i16, v8i16); -#define __msa_div_s_h __builtin_msa_div_s_h extern v4i32 __builtin_msa_div_s_w(v4i32, v4i32); -#define __msa_div_s_w __builtin_msa_div_s_w extern v2i64 __builtin_msa_div_s_d(v2i64, v2i64); -#define __msa_div_s_d __builtin_msa_div_s_d extern v16u8 __builtin_msa_div_u_b(v16u8, v16u8); -#define __msa_div_u_b __builtin_msa_div_u_b extern v8u16 __builtin_msa_div_u_h(v8u16, v8u16); -#define __msa_div_u_h __builtin_msa_div_u_h extern v4u32 __builtin_msa_div_u_w(v4u32, v4u32); -#define __msa_div_u_w __builtin_msa_div_u_w extern v2u64 __builtin_msa_div_u_d(v2u64, v2u64); -#define __msa_div_u_d __builtin_msa_div_u_d extern v8i16 __builtin_msa_hadd_s_h(v16i8, v16i8); -#define __msa_hadd_s_h __builtin_msa_hadd_s_h extern v4i32 __builtin_msa_hadd_s_w(v8i16, v8i16); -#define __msa_hadd_s_w __builtin_msa_hadd_s_w extern v2i64 __builtin_msa_hadd_s_d(v4i32, v4i32); -#define __msa_hadd_s_d __builtin_msa_hadd_s_d extern v8u16 __builtin_msa_hadd_u_h(v16u8, v16u8); -#define __msa_hadd_u_h __builtin_msa_hadd_u_h extern v4u32 __builtin_msa_hadd_u_w(v8u16, v8u16); -#define __msa_hadd_u_w __builtin_msa_hadd_u_w extern v2u64 __builtin_msa_hadd_u_d(v4u32, v4u32); -#define __msa_hadd_u_d __builtin_msa_hadd_u_d extern v8i16 __builtin_msa_hsub_s_h(v16i8, v16i8); -#define __msa_hsub_s_h __builtin_msa_hsub_s_h extern v4i32 __builtin_msa_hsub_s_w(v8i16, v8i16); -#define __msa_hsub_s_w __builtin_msa_hsub_s_w extern v2i64 __builtin_msa_hsub_s_d(v4i32, v4i32); -#define __msa_hsub_s_d __builtin_msa_hsub_s_d extern v8i16 __builtin_msa_hsub_u_h(v16u8, v16u8); -#define __msa_hsub_u_h __builtin_msa_hsub_u_h extern v4i32 __builtin_msa_hsub_u_w(v8u16, v8u16); -#define __msa_hsub_u_w __builtin_msa_hsub_u_w extern v2i64 __builtin_msa_hsub_u_d(v4u32, v4u32); -#define __msa_hsub_u_d __builtin_msa_hsub_u_d extern v16i8 __builtin_msa_mod_s_b(v16i8, v16i8); -#define __msa_mod_s_b __builtin_msa_mod_s_b extern v8i16 __builtin_msa_mod_s_h(v8i16, v8i16); -#define __msa_mod_s_h __builtin_msa_mod_s_h extern v4i32 __builtin_msa_mod_s_w(v4i32, v4i32); -#define __msa_mod_s_w __builtin_msa_mod_s_w extern v2i64 __builtin_msa_mod_s_d(v2i64, v2i64); -#define __msa_mod_s_d __builtin_msa_mod_s_d extern v16u8 __builtin_msa_mod_u_b(v16u8, v16u8); -#define __msa_mod_u_b __builtin_msa_mod_u_b extern v8u16 __builtin_msa_mod_u_h(v8u16, v8u16); -#define __msa_mod_u_h __builtin_msa_mod_u_h extern v4u32 __builtin_msa_mod_u_w(v4u32, v4u32); -#define __msa_mod_u_w __builtin_msa_mod_u_w extern v2u64 __builtin_msa_mod_u_d(v2u64, v2u64); -#define __msa_mod_u_d __builtin_msa_mod_u_d extern v8i16 __builtin_msa_dotp_s_h(v16i8, v16i8); -#define __msa_dotp_s_h __builtin_msa_dotp_s_h extern v4i32 __builtin_msa_dotp_s_w(v8i16, v8i16); -#define __msa_dotp_s_w __builtin_msa_dotp_s_w extern v2i64 __builtin_msa_dotp_s_d(v4i32, v4i32); -#define __msa_dotp_s_d __builtin_msa_dotp_s_d extern v8u16 __builtin_msa_dotp_u_h(v16u8, v16u8); -#define __msa_dotp_u_h __builtin_msa_dotp_u_h extern v4u32 __builtin_msa_dotp_u_w(v8u16, v8u16); -#define __msa_dotp_u_w __builtin_msa_dotp_u_w extern v2u64 __builtin_msa_dotp_u_d(v4u32, v4u32); -#define __msa_dotp_u_d __builtin_msa_dotp_u_d extern v8i16 __builtin_msa_dpadd_s_h(v8i16, v16i8, v16i8); -#define __msa_dpadd_s_h __builtin_msa_dpadd_s_h extern v4i32 __builtin_msa_dpadd_s_w(v4i32, v8i16, v8i16); -#define __msa_dpadd_s_w __builtin_msa_dpadd_s_w extern v2i64 __builtin_msa_dpadd_s_d(v2i64, v4i32, v4i32); -#define __msa_dpadd_s_d __builtin_msa_dpadd_s_d extern v8u16 __builtin_msa_dpadd_u_h(v8u16, v16u8, v16u8); -#define __msa_dpadd_u_h __builtin_msa_dpadd_u_h extern v4u32 __builtin_msa_dpadd_u_w(v4u32, v8u16, v8u16); -#define __msa_dpadd_u_w __builtin_msa_dpadd_u_w extern v2u64 __builtin_msa_dpadd_u_d(v2u64, v4u32, v4u32); -#define __msa_dpadd_u_d __builtin_msa_dpadd_u_d extern v8i16 __builtin_msa_dpsub_s_h(v8i16, v16i8, v16i8); -#define __msa_dpsub_s_h __builtin_msa_dpsub_s_h extern v4i32 __builtin_msa_dpsub_s_w(v4i32, v8i16, v8i16); -#define __msa_dpsub_s_w __builtin_msa_dpsub_s_w extern v2i64 __builtin_msa_dpsub_s_d(v2i64, v4i32, v4i32); -#define __msa_dpsub_s_d __builtin_msa_dpsub_s_d extern v8i16 __builtin_msa_dpsub_u_h(v8i16, v16u8, v16u8); -#define __msa_dpsub_u_h __builtin_msa_dpsub_u_h extern v4i32 __builtin_msa_dpsub_u_w(v4i32, v8u16, v8u16); -#define __msa_dpsub_u_w __builtin_msa_dpsub_u_w extern v2i64 __builtin_msa_dpsub_u_d(v2i64, v4u32, v4u32); -#define __msa_dpsub_u_d __builtin_msa_dpsub_u_d extern v16i8 __builtin_msa_sld_b(v16i8, v16i8, int); -#define __msa_sld_b __builtin_msa_sld_b extern v8i16 __builtin_msa_sld_h(v8i16, v8i16, int); -#define __msa_sld_h __builtin_msa_sld_h extern v4i32 __builtin_msa_sld_w(v4i32, v4i32, int); -#define __msa_sld_w __builtin_msa_sld_w extern v2i64 __builtin_msa_sld_d(v2i64, v2i64, int); -#define __msa_sld_d __builtin_msa_sld_d extern v16i8 __builtin_msa_sldi_b(v16i8, v16i8, unsigned char); -#define __msa_sldi_b __builtin_msa_sldi_b extern v8i16 __builtin_msa_sldi_h(v8i16, v8i16, unsigned char); -#define __msa_sldi_h __builtin_msa_sldi_h extern v4i32 __builtin_msa_sldi_w(v4i32, v4i32, unsigned char); -#define __msa_sldi_w __builtin_msa_sldi_w extern v2i64 __builtin_msa_sldi_d(v2i64, v2i64, unsigned char); -#define __msa_sldi_d __builtin_msa_sldi_d extern v16i8 __builtin_msa_splat_b(v16i8, int); -#define __msa_splat_b __builtin_msa_splat_b extern v8i16 __builtin_msa_splat_h(v8i16, int); -#define __msa_splat_h __builtin_msa_splat_h extern v4i32 __builtin_msa_splat_w(v4i32, int); -#define __msa_splat_w __builtin_msa_splat_w extern v2i64 __builtin_msa_splat_d(v2i64, int); -#define __msa_splat_d __builtin_msa_splat_d extern v16i8 __builtin_msa_splati_b(v16i8, unsigned char); -#define __msa_splati_b __builtin_msa_splati_b extern v8i16 __builtin_msa_splati_h(v8i16, unsigned char); -#define __msa_splati_h __builtin_msa_splati_h extern v4i32 __builtin_msa_splati_w(v4i32, unsigned char); -#define __msa_splati_w __builtin_msa_splati_w extern v2i64 __builtin_msa_splati_d(v2i64, unsigned char); -#define __msa_splati_d __builtin_msa_splati_d extern v16i8 __builtin_msa_pckev_b(v16i8, v16i8); -#define __msa_pckev_b __builtin_msa_pckev_b extern v8i16 __builtin_msa_pckev_h(v8i16, v8i16); -#define __msa_pckev_h __builtin_msa_pckev_h extern v4i32 __builtin_msa_pckev_w(v4i32, v4i32); -#define __msa_pckev_w __builtin_msa_pckev_w extern v2i64 __builtin_msa_pckev_d(v2i64, v2i64); -#define __msa_pckev_d __builtin_msa_pckev_d extern v16i8 __builtin_msa_pckod_b(v16i8, v16i8); -#define __msa_pckod_b __builtin_msa_pckod_b extern v8i16 __builtin_msa_pckod_h(v8i16, v8i16); -#define __msa_pckod_h __builtin_msa_pckod_h extern v4i32 __builtin_msa_pckod_w(v4i32, v4i32); -#define __msa_pckod_w __builtin_msa_pckod_w extern v2i64 __builtin_msa_pckod_d(v2i64, v2i64); -#define __msa_pckod_d __builtin_msa_pckod_d extern v16i8 __builtin_msa_ilvl_b(v16i8, v16i8); -#define __msa_ilvl_b __builtin_msa_ilvl_b extern v8i16 __builtin_msa_ilvl_h(v8i16, v8i16); -#define __msa_ilvl_h __builtin_msa_ilvl_h extern v4i32 __builtin_msa_ilvl_w(v4i32, v4i32); -#define __msa_ilvl_w __builtin_msa_ilvl_w extern v2i64 __builtin_msa_ilvl_d(v2i64, v2i64); -#define __msa_ilvl_d __builtin_msa_ilvl_d extern v16i8 __builtin_msa_ilvr_b(v16i8, v16i8); -#define __msa_ilvr_b __builtin_msa_ilvr_b extern v8i16 __builtin_msa_ilvr_h(v8i16, v8i16); -#define __msa_ilvr_h __builtin_msa_ilvr_h extern v4i32 __builtin_msa_ilvr_w(v4i32, v4i32); -#define __msa_ilvr_w __builtin_msa_ilvr_w extern v2i64 __builtin_msa_ilvr_d(v2i64, v2i64); -#define __msa_ilvr_d __builtin_msa_ilvr_d extern v16i8 __builtin_msa_ilvev_b(v16i8, v16i8); -#define __msa_ilvev_b __builtin_msa_ilvev_b extern v8i16 __builtin_msa_ilvev_h(v8i16, v8i16); -#define __msa_ilvev_h __builtin_msa_ilvev_h extern v4i32 __builtin_msa_ilvev_w(v4i32, v4i32); -#define __msa_ilvev_w __builtin_msa_ilvev_w extern v2i64 __builtin_msa_ilvev_d(v2i64, v2i64); -#define __msa_ilvev_d __builtin_msa_ilvev_d extern v16i8 __builtin_msa_ilvod_b(v16i8, v16i8); -#define __msa_ilvod_b __builtin_msa_ilvod_b extern v8i16 __builtin_msa_ilvod_h(v8i16, v8i16); -#define __msa_ilvod_h __builtin_msa_ilvod_h extern v4i32 __builtin_msa_ilvod_w(v4i32, v4i32); -#define __msa_ilvod_w __builtin_msa_ilvod_w extern v2i64 __builtin_msa_ilvod_d(v2i64, v2i64); -#define __msa_ilvod_d __builtin_msa_ilvod_d extern v16i8 __builtin_msa_vshf_b(v16i8, v16i8, v16i8); -#define __msa_vshf_b __builtin_msa_vshf_b extern v8i16 __builtin_msa_vshf_h(v8i16, v8i16, v8i16); -#define __msa_vshf_h __builtin_msa_vshf_h extern v4i32 __builtin_msa_vshf_w(v4i32, v4i32, v4i32); -#define __msa_vshf_w __builtin_msa_vshf_w extern v2i64 __builtin_msa_vshf_d(v2i64, v2i64, v2i64); -#define __msa_vshf_d __builtin_msa_vshf_d extern v16u8 __builtin_msa_and_v(v16u8, v16u8); -#define __msa_and_v __builtin_msa_and_v extern v16u8 __builtin_msa_andi_b(v16u8, unsigned char); -#define __msa_andi_b __builtin_msa_andi_b extern v16u8 __builtin_msa_or_v(v16u8, v16u8); -#define __msa_or_v __builtin_msa_or_v extern v16u8 __builtin_msa_ori_b(v16u8, unsigned char); -#define __msa_ori_b __builtin_msa_ori_b extern v16u8 __builtin_msa_nor_v(v16u8, v16u8); -#define __msa_nor_v __builtin_msa_nor_v extern v16u8 __builtin_msa_nori_b(v16u8, unsigned char); -#define __msa_nori_b __builtin_msa_nori_b extern v16u8 __builtin_msa_xor_v(v16u8, v16u8); -#define __msa_xor_v __builtin_msa_xor_v extern v16u8 __builtin_msa_xori_b(v16u8, unsigned char); -#define __msa_xori_b __builtin_msa_xori_b extern v16u8 __builtin_msa_bmnz_v(v16u8, v16u8, v16u8); -#define __msa_bmnz_v __builtin_msa_bmnz_v extern v16u8 __builtin_msa_bmnzi_b(v16u8, v16u8, unsigned char); -#define __msa_bmnzi_b __builtin_msa_bmnzi_b extern v16u8 __builtin_msa_bmz_v(v16u8, v16u8, v16u8); -#define __msa_bmz_v __builtin_msa_bmz_v extern v16u8 __builtin_msa_bmzi_b(v16u8, v16u8, unsigned char); -#define __msa_bmzi_b __builtin_msa_bmzi_b extern v16u8 __builtin_msa_bsel_v(v16u8, v16u8, v16u8); -#define __msa_bsel_v __builtin_msa_bsel_v extern v16u8 __builtin_msa_bseli_b(v16u8, v16u8, unsigned char); -#define __msa_bseli_b __builtin_msa_bseli_b extern v16i8 __builtin_msa_shf_b(v16i8, unsigned char); -#define __msa_shf_b __builtin_msa_shf_b extern v8i16 __builtin_msa_shf_h(v8i16, unsigned char); -#define __msa_shf_h __builtin_msa_shf_h extern v4i32 __builtin_msa_shf_w(v4i32, unsigned char); -#define __msa_shf_w __builtin_msa_shf_w extern int __builtin_msa_bnz_v(v16u8); -#define __msa_test_bnz_v __builtin_msa_bnz_v extern int __builtin_msa_bz_v(v16u8); -#define __msa_test_bz_v __builtin_msa_bz_v extern v16i8 __builtin_msa_fill_b(int); -#define __msa_fill_b __builtin_msa_fill_b extern v8i16 __builtin_msa_fill_h(int); -#define __msa_fill_h __builtin_msa_fill_h extern v4i32 __builtin_msa_fill_w(int); -#define __msa_fill_w __builtin_msa_fill_w extern v2i64 __builtin_msa_fill_d(long long); -#define __msa_fill_d __builtin_msa_fill_d extern v16i8 __builtin_msa_pcnt_b(v16i8); -#define __msa_pcnt_b __builtin_msa_pcnt_b extern v8i16 __builtin_msa_pcnt_h(v8i16); -#define __msa_pcnt_h __builtin_msa_pcnt_h extern v4i32 __builtin_msa_pcnt_w(v4i32); -#define __msa_pcnt_w __builtin_msa_pcnt_w extern v2i64 __builtin_msa_pcnt_d(v2i64); -#define __msa_pcnt_d __builtin_msa_pcnt_d extern v16i8 __builtin_msa_nloc_b(v16i8); -#define __msa_nloc_b __builtin_msa_nloc_b extern v8i16 __builtin_msa_nloc_h(v8i16); -#define __msa_nloc_h __builtin_msa_nloc_h extern v4i32 __builtin_msa_nloc_w(v4i32); -#define __msa_nloc_w __builtin_msa_nloc_w extern v2i64 __builtin_msa_nloc_d(v2i64); -#define __msa_nloc_d __builtin_msa_nloc_d extern v16i8 __builtin_msa_nlzc_b(v16i8); -#define __msa_nlzc_b __builtin_msa_nlzc_b extern v8i16 __builtin_msa_nlzc_h(v8i16); -#define __msa_nlzc_h __builtin_msa_nlzc_h extern v4i32 __builtin_msa_nlzc_w(v4i32); -#define __msa_nlzc_w __builtin_msa_nlzc_w extern v2i64 __builtin_msa_nlzc_d(v2i64); -#define __msa_nlzc_d __builtin_msa_nlzc_d extern int __builtin_msa_copy_s_b(v16i8, unsigned char); -#define __msa_copy_s_b __builtin_msa_copy_s_b extern int __builtin_msa_copy_s_h(v8i16, unsigned char); -#define __msa_copy_s_h __builtin_msa_copy_s_h extern int __builtin_msa_copy_s_w(v4i32, unsigned char); -#define __msa_copy_s_w __builtin_msa_copy_s_w extern long long __builtin_msa_copy_s_d(v2i64, unsigned char); -#define __msa_copy_s_d __builtin_msa_copy_s_d extern int __builtin_msa_copy_u_b(v16i8, unsigned char); -#define __msa_copy_u_b __builtin_msa_copy_u_b extern int __builtin_msa_copy_u_h(v8i16, unsigned char); -#define __msa_copy_u_h __builtin_msa_copy_u_h extern int __builtin_msa_copy_u_w(v4i32, unsigned char); -#define __msa_copy_u_w __builtin_msa_copy_u_w extern long long __builtin_msa_copy_u_d(v2i64, unsigned char); -#define __msa_copy_u_d __builtin_msa_copy_u_d extern v16i8 __builtin_msa_insert_b(v16i8, unsigned char, int); -#define __msa_insert_b __builtin_msa_insert_b extern v8i16 __builtin_msa_insert_h(v8i16, unsigned char, int); -#define __msa_insert_h __builtin_msa_insert_h extern v4i32 __builtin_msa_insert_w(v4i32, unsigned char, int); -#define __msa_insert_w __builtin_msa_insert_w extern v2i64 __builtin_msa_insert_d(v2i64, unsigned char, long long); -#define __msa_insert_d __builtin_msa_insert_d extern v16i8 __builtin_msa_insve_b(v16i8, unsigned char, v16i8); -#define __msa_insve_b __builtin_msa_insve_b extern v8i16 __builtin_msa_insve_h(v8i16, unsigned char, v8i16); -#define __msa_insve_h __builtin_msa_insve_h extern v4i32 __builtin_msa_insve_w(v4i32, unsigned char, v4i32); -#define __msa_insve_w __builtin_msa_insve_w extern v2i64 __builtin_msa_insve_d(v2i64, unsigned char, v2i64); -#define __msa_insve_d __builtin_msa_insve_d extern int __builtin_msa_bnz_b(v16u8); -#define __msa_test_bnz_b __builtin_msa_bnz_b extern int __builtin_msa_bnz_h(v8u16); -#define __msa_test_bnz_h __builtin_msa_bnz_h extern int __builtin_msa_bnz_w(v4u32); -#define __msa_test_bnz_w __builtin_msa_bnz_w extern int __builtin_msa_bnz_d(v2u64); -#define __msa_test_bnz_d __builtin_msa_bnz_d extern int __builtin_msa_bz_b(v16u8); -#define __msa_test_bz_b __builtin_msa_bz_b extern int __builtin_msa_bz_h(v8u16); -#define __msa_test_bz_h __builtin_msa_bz_h extern int __builtin_msa_bz_w(v4u32); -#define __msa_test_bz_w __builtin_msa_bz_w extern int __builtin_msa_bz_d(v2u64); -#define __msa_test_bz_d __builtin_msa_bz_d extern v16i8 __builtin_msa_ldi_b(short); -#define __msa_ldi_b __builtin_msa_ldi_b extern v8i16 __builtin_msa_ldi_h(short); -#define __msa_ldi_h __builtin_msa_ldi_h extern v4i32 __builtin_msa_ldi_w(short); -#define __msa_ldi_w __builtin_msa_ldi_w extern v2i64 __builtin_msa_ldi_d(short); -#define __msa_ldi_d __builtin_msa_ldi_d extern v4i32 __builtin_msa_fcaf_w(v4f32, v4f32); -#define __msa_fcaf_w __builtin_msa_fcaf_w extern v2i64 __builtin_msa_fcaf_d(v2f64, v2f64); -#define __msa_fcaf_d __builtin_msa_fcaf_d extern v4i32 __builtin_msa_fcor_w(v4f32, v4f32); -#define __msa_fcor_w __builtin_msa_fcor_w extern v2i64 __builtin_msa_fcor_d(v2f64, v2f64); -#define __msa_fcor_d __builtin_msa_fcor_d extern v4i32 __builtin_msa_fcun_w(v4f32, v4f32); -#define __msa_fcun_w __builtin_msa_fcun_w extern v2i64 __builtin_msa_fcun_d(v2f64, v2f64); -#define __msa_fcun_d __builtin_msa_fcun_d extern v4i32 __builtin_msa_fcune_w(v4f32, v4f32); -#define __msa_fcune_w __builtin_msa_fcune_w extern v2i64 __builtin_msa_fcune_d(v2f64, v2f64); -#define __msa_fcune_d __builtin_msa_fcune_d extern v4i32 __builtin_msa_fcueq_w(v4f32, v4f32); -#define __msa_fcueq_w __builtin_msa_fcueq_w extern v2i64 __builtin_msa_fcueq_d(v2f64, v2f64); -#define __msa_fcueq_d __builtin_msa_fcueq_d extern v4i32 __builtin_msa_fceq_w(v4f32, v4f32); -#define __msa_fceq_w __builtin_msa_fceq_w extern v2i64 __builtin_msa_fceq_d(v2f64, v2f64); -#define __msa_fceq_d __builtin_msa_fceq_d extern v4i32 __builtin_msa_fcne_w(v4f32, v4f32); -#define __msa_fcne_w __builtin_msa_fcne_w extern v2i64 __builtin_msa_fcne_d(v2f64, v2f64); -#define __msa_fcne_d __builtin_msa_fcne_d extern v4i32 __builtin_msa_fclt_w(v4f32, v4f32); -#define __msa_fclt_w __builtin_msa_fclt_w extern v2i64 __builtin_msa_fclt_d(v2f64, v2f64); -#define __msa_fclt_d __builtin_msa_fclt_d extern v4i32 __builtin_msa_fcult_w(v4f32, v4f32); -#define __msa_fcult_w __builtin_msa_fcult_w extern v2i64 __builtin_msa_fcult_d(v2f64, v2f64); -#define __msa_fcult_d __builtin_msa_fcult_d extern v4i32 __builtin_msa_fcle_w(v4f32, v4f32); -#define __msa_fcle_w __builtin_msa_fcle_w extern v2i64 __builtin_msa_fcle_d(v2f64, v2f64); -#define __msa_fcle_d __builtin_msa_fcle_d extern v4i32 __builtin_msa_fcule_w(v4f32, v4f32); -#define __msa_fcule_w __builtin_msa_fcule_w extern v2i64 __builtin_msa_fcule_d(v2f64, v2f64); -#define __msa_fcule_d __builtin_msa_fcule_d extern v4i32 __builtin_msa_fsaf_w(v4f32, v4f32); -#define __msa_fsaf_w __builtin_msa_fsaf_w extern v2i64 __builtin_msa_fsaf_d(v2f64, v2f64); -#define __msa_fsaf_d __builtin_msa_fsaf_d extern v4i32 __builtin_msa_fsor_w(v4f32, v4f32); -#define __msa_fsor_w __builtin_msa_fsor_w extern v2i64 __builtin_msa_fsor_d(v2f64, v2f64); -#define __msa_fsor_d __builtin_msa_fsor_d extern v4i32 __builtin_msa_fsun_w(v4f32, v4f32); -#define __msa_fsun_w __builtin_msa_fsun_w extern v2i64 __builtin_msa_fsun_d(v2f64, v2f64); -#define __msa_fsun_d __builtin_msa_fsun_d extern v4i32 __builtin_msa_fsune_w(v4f32, v4f32); -#define __msa_fsune_w __builtin_msa_fsune_w extern v2i64 __builtin_msa_fsune_d(v2f64, v2f64); -#define __msa_fsune_d __builtin_msa_fsune_d extern v4i32 __builtin_msa_fsueq_w(v4f32, v4f32); -#define __msa_fsueq_w __builtin_msa_fsueq_w extern v2i64 __builtin_msa_fsueq_d(v2f64, v2f64); -#define __msa_fsueq_d __builtin_msa_fsueq_d extern v4i32 __builtin_msa_fseq_w(v4f32, v4f32); -#define __msa_fseq_w __builtin_msa_fseq_w extern v2i64 __builtin_msa_fseq_d(v2f64, v2f64); -#define __msa_fseq_d __builtin_msa_fseq_d extern v4i32 __builtin_msa_fsne_w(v4f32, v4f32); -#define __msa_fsne_w __builtin_msa_fsne_w extern v2i64 __builtin_msa_fsne_d(v2f64, v2f64); -#define __msa_fsne_d __builtin_msa_fsne_d extern v4i32 __builtin_msa_fslt_w(v4f32, v4f32); -#define __msa_fslt_w __builtin_msa_fslt_w extern v2i64 __builtin_msa_fslt_d(v2f64, v2f64); -#define __msa_fslt_d __builtin_msa_fslt_d extern v4i32 __builtin_msa_fsult_w(v4f32, v4f32); -#define __msa_fsult_w __builtin_msa_fsult_w extern v2i64 __builtin_msa_fsult_d(v2f64, v2f64); -#define __msa_fsult_d __builtin_msa_fsult_d extern v4i32 __builtin_msa_fsle_w(v4f32, v4f32); -#define __msa_fsle_w __builtin_msa_fsle_w extern v2i64 __builtin_msa_fsle_d(v2f64, v2f64); -#define __msa_fsle_d __builtin_msa_fsle_d extern v4i32 __builtin_msa_fsule_w(v4f32, v4f32); -#define __msa_fsule_w __builtin_msa_fsule_w extern v2i64 __builtin_msa_fsule_d(v2f64, v2f64); -#define __msa_fsule_d __builtin_msa_fsule_d extern v4f32 __builtin_msa_fadd_w(v4f32, v4f32); -#define __msa_fadd_w __builtin_msa_fadd_w extern v2f64 __builtin_msa_fadd_d(v2f64, v2f64); -#define __msa_fadd_d __builtin_msa_fadd_d extern v4f32 __builtin_msa_fsub_w(v4f32, v4f32); -#define __msa_fsub_w __builtin_msa_fsub_w extern v2f64 __builtin_msa_fsub_d(v2f64, v2f64); -#define __msa_fsub_d __builtin_msa_fsub_d extern v4f32 __builtin_msa_fmul_w(v4f32, v4f32); -#define __msa_fmul_w __builtin_msa_fmul_w extern v2f64 __builtin_msa_fmul_d(v2f64, v2f64); -#define __msa_fmul_d __builtin_msa_fmul_d extern v4f32 __builtin_msa_fdiv_w(v4f32, v4f32); -#define __msa_fdiv_w __builtin_msa_fdiv_w extern v2f64 __builtin_msa_fdiv_d(v2f64, v2f64); -#define __msa_fdiv_d __builtin_msa_fdiv_d extern v4f32 __builtin_msa_fmadd_w(v4f32, v4f32, v4f32); -#define __msa_fmadd_w __builtin_msa_fmadd_w extern v2f64 __builtin_msa_fmadd_d(v2f64, v2f64, v2f64); -#define __msa_fmadd_d __builtin_msa_fmadd_d extern v4f32 __builtin_msa_fmsub_w(v4f32, v4f32, v4f32); -#define __msa_fmsub_w __builtin_msa_fmsub_w extern v2f64 __builtin_msa_fmsub_d(v2f64, v2f64, v2f64); -#define __msa_fmsub_d __builtin_msa_fmsub_d extern v4f32 __builtin_msa_fexp2_w(v4f32, v4i32); -#define __msa_fexp2_w __builtin_msa_fexp2_w extern v2f64 __builtin_msa_fexp2_d(v2f64, v2i64); -#define __msa_fexp2_d __builtin_msa_fexp2_d extern v8i16 __builtin_msa_fexdo_h(v4f32, v4f32); -#define __msa_fexdo_h __builtin_msa_fexdo_h extern v4f32 __builtin_msa_fexdo_w(v2f64, v2f64); -#define __msa_fexdo_w __builtin_msa_fexdo_w extern v8i16 __builtin_msa_ftq_h(v4f32, v4f32); -#define __msa_ftq_h __builtin_msa_ftq_h extern v4i32 __builtin_msa_ftq_w(v2f64, v2f64); -#define __msa_ftq_w __builtin_msa_ftq_w extern v4f32 __builtin_msa_fmin_w(v4f32, v4f32); -#define __msa_fmin_w __builtin_msa_fmin_w extern v2f64 __builtin_msa_fmin_d(v2f64, v2f64); -#define __msa_fmin_d __builtin_msa_fmin_d extern v4f32 __builtin_msa_fmin_a_w(v4f32, v4f32); -#define __msa_fmin_a_w __builtin_msa_fmin_a_w extern v2f64 __builtin_msa_fmin_a_d(v2f64, v2f64); -#define __msa_fmin_a_d __builtin_msa_fmin_a_d extern v4f32 __builtin_msa_fmax_w(v4f32, v4f32); -#define __msa_fmax_w __builtin_msa_fmax_w extern v2f64 __builtin_msa_fmax_d(v2f64, v2f64); -#define __msa_fmax_d __builtin_msa_fmax_d extern v4f32 __builtin_msa_fmax_a_w(v4f32, v4f32); -#define __msa_fmax_a_w __builtin_msa_fmax_a_w extern v2f64 __builtin_msa_fmax_a_d(v2f64, v2f64); -#define __msa_fmax_a_d __builtin_msa_fmax_a_d extern v8i16 __builtin_msa_mul_q_h(v8i16, v8i16); -#define __msa_mul_q_h __builtin_msa_mul_q_h extern v4i32 __builtin_msa_mul_q_w(v4i32, v4i32); -#define __msa_mul_q_w __builtin_msa_mul_q_w extern v8i16 __builtin_msa_mulr_q_h(v8i16, v8i16); -#define __msa_mulr_q_h __builtin_msa_mulr_q_h extern v4i32 __builtin_msa_mulr_q_w(v4i32, v4i32); -#define __msa_mulr_q_w __builtin_msa_mulr_q_w extern v8i16 __builtin_msa_madd_q_h(v8i16, v8i16, v8i16); -#define __msa_madd_q_h __builtin_msa_madd_q_h extern v4i32 __builtin_msa_madd_q_w(v4i32, v4i32, v4i32); -#define __msa_madd_q_w __builtin_msa_madd_q_w extern v8i16 __builtin_msa_maddr_q_h(v8i16, v8i16, v8i16); -#define __msa_maddr_q_h __builtin_msa_maddr_q_h extern v4i32 __builtin_msa_maddr_q_w(v4i32, v4i32, v4i32); -#define __msa_maddr_q_w __builtin_msa_maddr_q_w extern v8i16 __builtin_msa_msub_q_h(v8i16, v8i16, v8i16); -#define __msa_msub_q_h __builtin_msa_msub_q_h extern v4i32 __builtin_msa_msub_q_w(v4i32, v4i32, v4i32); -#define __msa_msub_q_w __builtin_msa_msub_q_w extern v8i16 __builtin_msa_msubr_q_h(v8i16, v8i16, v8i16); -#define __msa_msubr_q_h __builtin_msa_msubr_q_h extern v4i32 __builtin_msa_msubr_q_w(v4i32, v4i32, v4i32); -#define __msa_msubr_q_w __builtin_msa_msubr_q_w extern v4i32 __builtin_msa_fclass_w(v4f32); -#define __msa_fclass_w __builtin_msa_fclass_w extern v2i64 __builtin_msa_fclass_d(v2f64); -#define __msa_fclass_d __builtin_msa_fclass_d extern v4f32 __builtin_msa_fsqrt_w(v4f32); -#define __msa_fsqrt_w __builtin_msa_fsqrt_w extern v2f64 __builtin_msa_fsqrt_d(v2f64); -#define __msa_fsqrt_d __builtin_msa_fsqrt_d extern v4f32 __builtin_msa_frcp_w(v4f32); -#define __msa_frcp_w __builtin_msa_frcp_w extern v2f64 __builtin_msa_frcp_d(v2f64); -#define __msa_frcp_d __builtin_msa_frcp_d extern v4f32 __builtin_msa_frint_w(v4f32); -#define __msa_frint_w __builtin_msa_frint_w extern v2f64 __builtin_msa_frint_d(v2f64); -#define __msa_frint_d __builtin_msa_frint_d extern v4f32 __builtin_msa_frsqrt_w(v4f32); -#define __msa_frsqrt_w __builtin_msa_frsqrt_w extern v2f64 __builtin_msa_frsqrt_d(v2f64); -#define __msa_frsqrt_d __builtin_msa_frsqrt_d extern v4f32 __builtin_msa_flog2_w(v4f32); -#define __msa_flog2_w __builtin_msa_flog2_w extern v2f64 __builtin_msa_flog2_d(v2f64); -#define __msa_flog2_d __builtin_msa_flog2_d extern v4f32 __builtin_msa_fexupl_w(v8i16); -#define __msa_fexupl_w __builtin_msa_fexupl_w extern v2f64 __builtin_msa_fexupl_d(v4f32); -#define __msa_fexupl_d __builtin_msa_fexupl_d extern v4f32 __builtin_msa_fexupr_w(v8i16); -#define __msa_fexupr_w __builtin_msa_fexupr_w extern v2f64 __builtin_msa_fexupr_d(v4f32); -#define __msa_fexupr_d __builtin_msa_fexupr_d extern v4f32 __builtin_msa_ffql_w(v8i16); -#define __msa_ffql_w __builtin_msa_ffql_w extern v2f64 __builtin_msa_ffql_d(v4i32); -#define __msa_ffql_d __builtin_msa_ffql_d extern v4f32 __builtin_msa_ffqr_w(v8i16); -#define __msa_ffqr_w __builtin_msa_ffqr_w extern v2f64 __builtin_msa_ffqr_d(v4i32); -#define __msa_ffqr_d __builtin_msa_ffqr_d extern v4i32 __builtin_msa_ftint_s_w(v4f32); -#define __msa_ftint_s_w __builtin_msa_ftint_s_w extern v2i64 __builtin_msa_ftint_s_d(v2f64); -#define __msa_ftint_s_d __builtin_msa_ftint_s_d extern v4u32 __builtin_msa_ftint_u_w(v4f32); -#define __msa_ftint_u_w __builtin_msa_ftint_u_w extern v2u64 __builtin_msa_ftint_u_d(v2f64); -#define __msa_ftint_u_d __builtin_msa_ftint_u_d extern v4i32 __builtin_msa_ftrunc_s_w(v4f32); -#define __msa_ftrunc_s_w __builtin_msa_ftrunc_s_w extern v2i64 __builtin_msa_ftrunc_s_d(v2f64); -#define __msa_ftrunc_s_d __builtin_msa_ftrunc_s_d extern v4u32 __builtin_msa_ftrunc_u_w(v4f32); -#define __msa_ftrunc_u_w __builtin_msa_ftrunc_u_w extern v2u64 __builtin_msa_ftrunc_u_d(v2f64); -#define __msa_ftrunc_u_d __builtin_msa_ftrunc_u_d extern v4f32 __builtin_msa_ffint_s_w(v4i32); -#define __msa_ffint_s_w __builtin_msa_ffint_s_w extern v2f64 __builtin_msa_ffint_s_d(v2i64); -#define __msa_ffint_s_d __builtin_msa_ffint_s_d extern v4f32 __builtin_msa_ffint_u_w(v4u32); -#define __msa_ffint_u_w __builtin_msa_ffint_u_w extern v2f64 __builtin_msa_ffint_u_d(v2u64); -#define __msa_ffint_u_d __builtin_msa_ffint_u_d extern int __builtin_msa_cfcmsa(unsigned char); -#define __msa_cfcmsa __builtin_msa_cfcmsa extern v16i8 __builtin_msa_move_v(v16i8); -#define __msa_move_v __builtin_msa_move_v extern v4f32 __builtin_msa_cast_to_vector_float(float); -#define __msa_cast_to_vector_float __builtin_msa_cast_to_vector_float extern v2f64 __builtin_msa_cast_to_vector_double(double); -#define __msa_cast_to_vector_double __builtin_msa_cast_to_vector_double extern float __builtin_msa_cast_to_scalar_float(v4f32); -#define __msa_cast_to_scalar_float __builtin_msa_cast_to_scalar_float extern double __builtin_msa_cast_to_scalar_double(v2f64); -#define __msa_cast_to_scalar_double __builtin_msa_cast_to_scalar_double #endif /* __clang__ */ +#define __msa_sll_b __builtin_msa_sll_b +#define __msa_sll_h __builtin_msa_sll_h +#define __msa_sll_w __builtin_msa_sll_w +#define __msa_sll_d __builtin_msa_sll_d +#define __msa_slli_b __builtin_msa_slli_b +#define __msa_slli_h __builtin_msa_slli_h +#define __msa_slli_w __builtin_msa_slli_w +#define __msa_slli_d __builtin_msa_slli_d +#define __msa_sra_b __builtin_msa_sra_b +#define __msa_sra_h __builtin_msa_sra_h +#define __msa_sra_w __builtin_msa_sra_w +#define __msa_sra_d __builtin_msa_sra_d +#define __msa_srai_b __builtin_msa_srai_b +#define __msa_srai_h __builtin_msa_srai_h +#define __msa_srai_w __builtin_msa_srai_w +#define __msa_srai_d __builtin_msa_srai_d +#define __msa_srar_b __builtin_msa_srar_b +#define __msa_srar_h __builtin_msa_srar_h +#define __msa_srar_w __builtin_msa_srar_w +#define __msa_srar_d __builtin_msa_srar_d +#define __msa_srari_b __builtin_msa_srari_b +#define __msa_srari_h __builtin_msa_srari_h +#define __msa_srari_w __builtin_msa_srari_w +#define __msa_srari_d __builtin_msa_srari_d +#define __msa_srl_b __builtin_msa_srl_b +#define __msa_srl_h __builtin_msa_srl_h +#define __msa_srl_w __builtin_msa_srl_w +#define __msa_srl_d __builtin_msa_srl_d +#define __msa_srli_b __builtin_msa_srli_b +#define __msa_srli_h __builtin_msa_srli_h +#define __msa_srli_w __builtin_msa_srli_w +#define __msa_srli_d __builtin_msa_srli_d +#define __msa_srlr_b __builtin_msa_srlr_b +#define __msa_srlr_h __builtin_msa_srlr_h +#define __msa_srlr_w __builtin_msa_srlr_w +#define __msa_srlr_d __builtin_msa_srlr_d +#define __msa_srlri_b __builtin_msa_srlri_b +#define __msa_srlri_h __builtin_msa_srlri_h +#define __msa_srlri_w __builtin_msa_srlri_w +#define __msa_srlri_d __builtin_msa_srlri_d +#define __msa_bclr_b __builtin_msa_bclr_b +#define __msa_bclr_h __builtin_msa_bclr_h +#define __msa_bclr_w __builtin_msa_bclr_w +#define __msa_bclr_d __builtin_msa_bclr_d +#define __msa_bclri_b __builtin_msa_bclri_b +#define __msa_bclri_h __builtin_msa_bclri_h +#define __msa_bclri_w __builtin_msa_bclri_w +#define __msa_bclri_d __builtin_msa_bclri_d +#define __msa_bset_b __builtin_msa_bset_b +#define __msa_bset_h __builtin_msa_bset_h +#define __msa_bset_w __builtin_msa_bset_w +#define __msa_bset_d __builtin_msa_bset_d +#define __msa_bseti_b __builtin_msa_bseti_b +#define __msa_bseti_h __builtin_msa_bseti_h +#define __msa_bseti_w __builtin_msa_bseti_w +#define __msa_bseti_d __builtin_msa_bseti_d +#define __msa_bneg_b __builtin_msa_bneg_b +#define __msa_bneg_h __builtin_msa_bneg_h +#define __msa_bneg_w __builtin_msa_bneg_w +#define __msa_bneg_d __builtin_msa_bneg_d +#define __msa_bnegi_b __builtin_msa_bnegi_b +#define __msa_bnegi_h __builtin_msa_bnegi_h +#define __msa_bnegi_w __builtin_msa_bnegi_w +#define __msa_bnegi_d __builtin_msa_bnegi_d +#define __msa_binsl_b __builtin_msa_binsl_b +#define __msa_binsl_h __builtin_msa_binsl_h +#define __msa_binsl_w __builtin_msa_binsl_w +#define __msa_binsl_d __builtin_msa_binsl_d +#define __msa_binsli_b __builtin_msa_binsli_b +#define __msa_binsli_h __builtin_msa_binsli_h +#define __msa_binsli_w __builtin_msa_binsli_w +#define __msa_binsli_d __builtin_msa_binsli_d +#define __msa_binsr_b __builtin_msa_binsr_b +#define __msa_binsr_h __builtin_msa_binsr_h +#define __msa_binsr_w __builtin_msa_binsr_w +#define __msa_binsr_d __builtin_msa_binsr_d +#define __msa_binsri_b __builtin_msa_binsri_b +#define __msa_binsri_h __builtin_msa_binsri_h +#define __msa_binsri_w __builtin_msa_binsri_w +#define __msa_binsri_d __builtin_msa_binsri_d +#define __msa_addv_b __builtin_msa_addv_b +#define __msa_addv_h __builtin_msa_addv_h +#define __msa_addv_w __builtin_msa_addv_w +#define __msa_addv_d __builtin_msa_addv_d +#define __msa_addvi_b __builtin_msa_addvi_b +#define __msa_addvi_h __builtin_msa_addvi_h +#define __msa_addvi_w __builtin_msa_addvi_w +#define __msa_addvi_d __builtin_msa_addvi_d +#define __msa_subv_b __builtin_msa_subv_b +#define __msa_subv_h __builtin_msa_subv_h +#define __msa_subv_w __builtin_msa_subv_w +#define __msa_subv_d __builtin_msa_subv_d +#define __msa_subvi_b __builtin_msa_subvi_b +#define __msa_subvi_h __builtin_msa_subvi_h +#define __msa_subvi_w __builtin_msa_subvi_w +#define __msa_subvi_d __builtin_msa_subvi_d +#define __msa_max_s_b __builtin_msa_max_s_b +#define __msa_max_s_h __builtin_msa_max_s_h +#define __msa_max_s_w __builtin_msa_max_s_w +#define __msa_max_s_d __builtin_msa_max_s_d +#define __msa_maxi_s_b __builtin_msa_maxi_s_b +#define __msa_maxi_s_h __builtin_msa_maxi_s_h +#define __msa_maxi_s_w __builtin_msa_maxi_s_w +#define __msa_maxi_s_d __builtin_msa_maxi_s_d +#define __msa_max_u_b __builtin_msa_max_u_b +#define __msa_max_u_h __builtin_msa_max_u_h +#define __msa_max_u_w __builtin_msa_max_u_w +#define __msa_max_u_d __builtin_msa_max_u_d +#define __msa_maxi_u_b __builtin_msa_maxi_u_b +#define __msa_maxi_u_h __builtin_msa_maxi_u_h +#define __msa_maxi_u_w __builtin_msa_maxi_u_w +#define __msa_maxi_u_d __builtin_msa_maxi_u_d +#define __msa_min_s_b __builtin_msa_min_s_b +#define __msa_min_s_h __builtin_msa_min_s_h +#define __msa_min_s_w __builtin_msa_min_s_w +#define __msa_min_s_d __builtin_msa_min_s_d +#define __msa_mini_s_b __builtin_msa_mini_s_b +#define __msa_mini_s_h __builtin_msa_mini_s_h +#define __msa_mini_s_w __builtin_msa_mini_s_w +#define __msa_mini_s_d __builtin_msa_mini_s_d +#define __msa_min_u_b __builtin_msa_min_u_b +#define __msa_min_u_h __builtin_msa_min_u_h +#define __msa_min_u_w __builtin_msa_min_u_w +#define __msa_min_u_d __builtin_msa_min_u_d +#define __msa_mini_u_b __builtin_msa_mini_u_b +#define __msa_mini_u_h __builtin_msa_mini_u_h +#define __msa_mini_u_w __builtin_msa_mini_u_w +#define __msa_mini_u_d __builtin_msa_mini_u_d +#define __msa_max_a_b __builtin_msa_max_a_b +#define __msa_max_a_h __builtin_msa_max_a_h +#define __msa_max_a_w __builtin_msa_max_a_w +#define __msa_max_a_d __builtin_msa_max_a_d +#define __msa_min_a_b __builtin_msa_min_a_b +#define __msa_min_a_h __builtin_msa_min_a_h +#define __msa_min_a_w __builtin_msa_min_a_w +#define __msa_min_a_d __builtin_msa_min_a_d +#define __msa_ceq_b __builtin_msa_ceq_b +#define __msa_ceq_h __builtin_msa_ceq_h +#define __msa_ceq_w __builtin_msa_ceq_w +#define __msa_ceq_d __builtin_msa_ceq_d +#define __msa_ceqi_b __builtin_msa_ceqi_b +#define __msa_ceqi_h __builtin_msa_ceqi_h +#define __msa_ceqi_w __builtin_msa_ceqi_w +#define __msa_ceqi_d __builtin_msa_ceqi_d +#define __msa_clt_s_b __builtin_msa_clt_s_b +#define __msa_clt_s_h __builtin_msa_clt_s_h +#define __msa_clt_s_w __builtin_msa_clt_s_w +#define __msa_clt_s_d __builtin_msa_clt_s_d +#define __msa_clti_s_b __builtin_msa_clti_s_b +#define __msa_clti_s_h __builtin_msa_clti_s_h +#define __msa_clti_s_w __builtin_msa_clti_s_w +#define __msa_clti_s_d __builtin_msa_clti_s_d +#define __msa_clt_u_b __builtin_msa_clt_u_b +#define __msa_clt_u_h __builtin_msa_clt_u_h +#define __msa_clt_u_w __builtin_msa_clt_u_w +#define __msa_clt_u_d __builtin_msa_clt_u_d +#define __msa_clti_u_b __builtin_msa_clti_u_b +#define __msa_clti_u_h __builtin_msa_clti_u_h +#define __msa_clti_u_w __builtin_msa_clti_u_w +#define __msa_clti_u_d __builtin_msa_clti_u_d +#define __msa_cle_s_b __builtin_msa_cle_s_b +#define __msa_cle_s_h __builtin_msa_cle_s_h +#define __msa_cle_s_w __builtin_msa_cle_s_w +#define __msa_cle_s_d __builtin_msa_cle_s_d +#define __msa_clei_s_b __builtin_msa_clei_s_b +#define __msa_clei_s_h __builtin_msa_clei_s_h +#define __msa_clei_s_w __builtin_msa_clei_s_w +#define __msa_clei_s_d __builtin_msa_clei_s_d +#define __msa_cle_u_b __builtin_msa_cle_u_b +#define __msa_cle_u_h __builtin_msa_cle_u_h +#define __msa_cle_u_w __builtin_msa_cle_u_w +#define __msa_cle_u_d __builtin_msa_cle_u_d +#define __msa_clei_u_b __builtin_msa_clei_u_b +#define __msa_clei_u_h __builtin_msa_clei_u_h +#define __msa_clei_u_w __builtin_msa_clei_u_w +#define __msa_clei_u_d __builtin_msa_clei_u_d +#define __msa_ld_b __builtin_msa_ld_b +#define __msa_ld_h __builtin_msa_ld_h +#define __msa_ld_w __builtin_msa_ld_w +#define __msa_ld_d __builtin_msa_ld_d +#define __msa_st_b __builtin_msa_st_b +#define __msa_st_h __builtin_msa_st_h +#define __msa_st_w __builtin_msa_st_w +#define __msa_st_d __builtin_msa_st_d +#define __msa_sat_s_b __builtin_msa_sat_s_b +#define __msa_sat_s_h __builtin_msa_sat_s_h +#define __msa_sat_s_w __builtin_msa_sat_s_w +#define __msa_sat_s_d __builtin_msa_sat_s_d +#define __msa_sat_u_b __builtin_msa_sat_u_b +#define __msa_sat_u_h __builtin_msa_sat_u_h +#define __msa_sat_u_w __builtin_msa_sat_u_w +#define __msa_sat_u_d __builtin_msa_sat_u_d +#define __msa_add_a_b __builtin_msa_add_a_b +#define __msa_add_a_h __builtin_msa_add_a_h +#define __msa_add_a_w __builtin_msa_add_a_w +#define __msa_add_a_d __builtin_msa_add_a_d +#define __msa_adds_a_b __builtin_msa_adds_a_b +#define __msa_adds_a_h __builtin_msa_adds_a_h +#define __msa_adds_a_w __builtin_msa_adds_a_w +#define __msa_adds_a_d __builtin_msa_adds_a_d +#define __msa_adds_s_b __builtin_msa_adds_s_b +#define __msa_adds_s_h __builtin_msa_adds_s_h +#define __msa_adds_s_w __builtin_msa_adds_s_w +#define __msa_adds_s_d __builtin_msa_adds_s_d +#define __msa_adds_u_b __builtin_msa_adds_u_b +#define __msa_adds_u_h __builtin_msa_adds_u_h +#define __msa_adds_u_w __builtin_msa_adds_u_w +#define __msa_adds_u_d __builtin_msa_adds_u_d +#define __msa_ave_s_b __builtin_msa_ave_s_b +#define __msa_ave_s_h __builtin_msa_ave_s_h +#define __msa_ave_s_w __builtin_msa_ave_s_w +#define __msa_ave_s_d __builtin_msa_ave_s_d +#define __msa_ave_u_b __builtin_msa_ave_u_b +#define __msa_ave_u_h __builtin_msa_ave_u_h +#define __msa_ave_u_w __builtin_msa_ave_u_w +#define __msa_ave_u_d __builtin_msa_ave_u_d +#define __msa_aver_s_b __builtin_msa_aver_s_b +#define __msa_aver_s_h __builtin_msa_aver_s_h +#define __msa_aver_s_w __builtin_msa_aver_s_w +#define __msa_aver_s_d __builtin_msa_aver_s_d +#define __msa_aver_u_b __builtin_msa_aver_u_b +#define __msa_aver_u_h __builtin_msa_aver_u_h +#define __msa_aver_u_w __builtin_msa_aver_u_w +#define __msa_aver_u_d __builtin_msa_aver_u_d +#define __msa_subs_s_b __builtin_msa_subs_s_b +#define __msa_subs_s_h __builtin_msa_subs_s_h +#define __msa_subs_s_w __builtin_msa_subs_s_w +#define __msa_subs_s_d __builtin_msa_subs_s_d +#define __msa_subs_u_b __builtin_msa_subs_u_b +#define __msa_subs_u_h __builtin_msa_subs_u_h +#define __msa_subs_u_w __builtin_msa_subs_u_w +#define __msa_subs_u_d __builtin_msa_subs_u_d +#define __msa_subsuu_s_b __builtin_msa_subsuu_s_b +#define __msa_subsuu_s_h __builtin_msa_subsuu_s_h +#define __msa_subsuu_s_w __builtin_msa_subsuu_s_w +#define __msa_subsuu_s_d __builtin_msa_subsuu_s_d +#define __msa_subsus_u_b __builtin_msa_subsus_u_b +#define __msa_subsus_u_h __builtin_msa_subsus_u_h +#define __msa_subsus_u_w __builtin_msa_subsus_u_w +#define __msa_subsus_u_d __builtin_msa_subsus_u_d +#define __msa_asub_s_b __builtin_msa_asub_s_b +#define __msa_asub_s_h __builtin_msa_asub_s_h +#define __msa_asub_s_w __builtin_msa_asub_s_w +#define __msa_asub_s_d __builtin_msa_asub_s_d +#define __msa_asub_u_b __builtin_msa_asub_u_b +#define __msa_asub_u_h __builtin_msa_asub_u_h +#define __msa_asub_u_w __builtin_msa_asub_u_w +#define __msa_asub_u_d __builtin_msa_asub_u_d +#define __msa_mulv_b __builtin_msa_mulv_b +#define __msa_mulv_h __builtin_msa_mulv_h +#define __msa_mulv_w __builtin_msa_mulv_w +#define __msa_mulv_d __builtin_msa_mulv_d +#define __msa_maddv_b __builtin_msa_maddv_b +#define __msa_maddv_h __builtin_msa_maddv_h +#define __msa_maddv_w __builtin_msa_maddv_w +#define __msa_maddv_d __builtin_msa_maddv_d +#define __msa_msubv_b __builtin_msa_msubv_b +#define __msa_msubv_h __builtin_msa_msubv_h +#define __msa_msubv_w __builtin_msa_msubv_w +#define __msa_msubv_d __builtin_msa_msubv_d +#define __msa_div_s_b __builtin_msa_div_s_b +#define __msa_div_s_h __builtin_msa_div_s_h +#define __msa_div_s_w __builtin_msa_div_s_w +#define __msa_div_s_d __builtin_msa_div_s_d +#define __msa_div_u_b __builtin_msa_div_u_b +#define __msa_div_u_h __builtin_msa_div_u_h +#define __msa_div_u_w __builtin_msa_div_u_w +#define __msa_div_u_d __builtin_msa_div_u_d +#define __msa_hadd_s_h __builtin_msa_hadd_s_h +#define __msa_hadd_s_w __builtin_msa_hadd_s_w +#define __msa_hadd_s_d __builtin_msa_hadd_s_d +#define __msa_hadd_u_h __builtin_msa_hadd_u_h +#define __msa_hadd_u_w __builtin_msa_hadd_u_w +#define __msa_hadd_u_d __builtin_msa_hadd_u_d +#define __msa_hsub_s_h __builtin_msa_hsub_s_h +#define __msa_hsub_s_w __builtin_msa_hsub_s_w +#define __msa_hsub_s_d __builtin_msa_hsub_s_d +#define __msa_hsub_u_h __builtin_msa_hsub_u_h +#define __msa_hsub_u_w __builtin_msa_hsub_u_w +#define __msa_hsub_u_d __builtin_msa_hsub_u_d +#define __msa_mod_s_b __builtin_msa_mod_s_b +#define __msa_mod_s_h __builtin_msa_mod_s_h +#define __msa_mod_s_w __builtin_msa_mod_s_w +#define __msa_mod_s_d __builtin_msa_mod_s_d +#define __msa_mod_u_b __builtin_msa_mod_u_b +#define __msa_mod_u_h __builtin_msa_mod_u_h +#define __msa_mod_u_w __builtin_msa_mod_u_w +#define __msa_mod_u_d __builtin_msa_mod_u_d +#define __msa_dotp_s_h __builtin_msa_dotp_s_h +#define __msa_dotp_s_w __builtin_msa_dotp_s_w +#define __msa_dotp_s_d __builtin_msa_dotp_s_d +#define __msa_dotp_u_h __builtin_msa_dotp_u_h +#define __msa_dotp_u_w __builtin_msa_dotp_u_w +#define __msa_dotp_u_d __builtin_msa_dotp_u_d +#define __msa_dpadd_s_h __builtin_msa_dpadd_s_h +#define __msa_dpadd_s_w __builtin_msa_dpadd_s_w +#define __msa_dpadd_s_d __builtin_msa_dpadd_s_d +#define __msa_dpadd_u_h __builtin_msa_dpadd_u_h +#define __msa_dpadd_u_w __builtin_msa_dpadd_u_w +#define __msa_dpadd_u_d __builtin_msa_dpadd_u_d +#define __msa_dpsub_s_h __builtin_msa_dpsub_s_h +#define __msa_dpsub_s_w __builtin_msa_dpsub_s_w +#define __msa_dpsub_s_d __builtin_msa_dpsub_s_d +#define __msa_dpsub_u_h __builtin_msa_dpsub_u_h +#define __msa_dpsub_u_w __builtin_msa_dpsub_u_w +#define __msa_dpsub_u_d __builtin_msa_dpsub_u_d +#define __msa_sld_b __builtin_msa_sld_b +#define __msa_sld_h __builtin_msa_sld_h +#define __msa_sld_w __builtin_msa_sld_w +#define __msa_sld_d __builtin_msa_sld_d +#define __msa_sldi_b __builtin_msa_sldi_b +#define __msa_sldi_h __builtin_msa_sldi_h +#define __msa_sldi_w __builtin_msa_sldi_w +#define __msa_sldi_d __builtin_msa_sldi_d +#define __msa_splat_b __builtin_msa_splat_b +#define __msa_splat_h __builtin_msa_splat_h +#define __msa_splat_w __builtin_msa_splat_w +#define __msa_splat_d __builtin_msa_splat_d +#define __msa_splati_b __builtin_msa_splati_b +#define __msa_splati_h __builtin_msa_splati_h +#define __msa_splati_w __builtin_msa_splati_w +#define __msa_splati_d __builtin_msa_splati_d +#define __msa_pckev_b __builtin_msa_pckev_b +#define __msa_pckev_h __builtin_msa_pckev_h +#define __msa_pckev_w __builtin_msa_pckev_w +#define __msa_pckev_d __builtin_msa_pckev_d +#define __msa_pckod_b __builtin_msa_pckod_b +#define __msa_pckod_h __builtin_msa_pckod_h +#define __msa_pckod_w __builtin_msa_pckod_w +#define __msa_pckod_d __builtin_msa_pckod_d +#define __msa_ilvl_b __builtin_msa_ilvl_b +#define __msa_ilvl_h __builtin_msa_ilvl_h +#define __msa_ilvl_w __builtin_msa_ilvl_w +#define __msa_ilvl_d __builtin_msa_ilvl_d +#define __msa_ilvr_b __builtin_msa_ilvr_b +#define __msa_ilvr_h __builtin_msa_ilvr_h +#define __msa_ilvr_w __builtin_msa_ilvr_w +#define __msa_ilvr_d __builtin_msa_ilvr_d +#define __msa_ilvev_b __builtin_msa_ilvev_b +#define __msa_ilvev_h __builtin_msa_ilvev_h +#define __msa_ilvev_w __builtin_msa_ilvev_w +#define __msa_ilvev_d __builtin_msa_ilvev_d +#define __msa_ilvod_b __builtin_msa_ilvod_b +#define __msa_ilvod_h __builtin_msa_ilvod_h +#define __msa_ilvod_w __builtin_msa_ilvod_w +#define __msa_ilvod_d __builtin_msa_ilvod_d +#define __msa_vshf_b __builtin_msa_vshf_b +#define __msa_vshf_h __builtin_msa_vshf_h +#define __msa_vshf_w __builtin_msa_vshf_w +#define __msa_vshf_d __builtin_msa_vshf_d +#define __msa_and_v __builtin_msa_and_v +#define __msa_andi_b __builtin_msa_andi_b +#define __msa_or_v __builtin_msa_or_v +#define __msa_ori_b __builtin_msa_ori_b +#define __msa_nor_v __builtin_msa_nor_v +#define __msa_nori_b __builtin_msa_nori_b +#define __msa_xor_v __builtin_msa_xor_v +#define __msa_xori_b __builtin_msa_xori_b +#define __msa_bmnz_v __builtin_msa_bmnz_v +#define __msa_bmnzi_b __builtin_msa_bmnzi_b +#define __msa_bmz_v __builtin_msa_bmz_v +#define __msa_bmzi_b __builtin_msa_bmzi_b +#define __msa_bsel_v __builtin_msa_bsel_v +#define __msa_bseli_b __builtin_msa_bseli_b +#define __msa_shf_b __builtin_msa_shf_b +#define __msa_shf_h __builtin_msa_shf_h +#define __msa_shf_w __builtin_msa_shf_w +#define __msa_test_bnz_v __builtin_msa_bnz_v +#define __msa_test_bz_v __builtin_msa_bz_v +#define __msa_fill_b __builtin_msa_fill_b +#define __msa_fill_h __builtin_msa_fill_h +#define __msa_fill_w __builtin_msa_fill_w +#define __msa_fill_d __builtin_msa_fill_d +#define __msa_pcnt_b __builtin_msa_pcnt_b +#define __msa_pcnt_h __builtin_msa_pcnt_h +#define __msa_pcnt_w __builtin_msa_pcnt_w +#define __msa_pcnt_d __builtin_msa_pcnt_d +#define __msa_nloc_b __builtin_msa_nloc_b +#define __msa_nloc_h __builtin_msa_nloc_h +#define __msa_nloc_w __builtin_msa_nloc_w +#define __msa_nloc_d __builtin_msa_nloc_d +#define __msa_nlzc_b __builtin_msa_nlzc_b +#define __msa_nlzc_h __builtin_msa_nlzc_h +#define __msa_nlzc_w __builtin_msa_nlzc_w +#define __msa_nlzc_d __builtin_msa_nlzc_d +#define __msa_copy_s_b __builtin_msa_copy_s_b +#define __msa_copy_s_h __builtin_msa_copy_s_h +#define __msa_copy_s_w __builtin_msa_copy_s_w +#define __msa_copy_s_d __builtin_msa_copy_s_d +#define __msa_copy_u_b __builtin_msa_copy_u_b +#define __msa_copy_u_h __builtin_msa_copy_u_h +#define __msa_copy_u_w __builtin_msa_copy_u_w +#define __msa_copy_u_d __builtin_msa_copy_u_d +#define __msa_insert_b __builtin_msa_insert_b +#define __msa_insert_h __builtin_msa_insert_h +#define __msa_insert_w __builtin_msa_insert_w +#define __msa_insert_d __builtin_msa_insert_d +#define __msa_insve_b __builtin_msa_insve_b +#define __msa_insve_h __builtin_msa_insve_h +#define __msa_insve_w __builtin_msa_insve_w +#define __msa_insve_d __builtin_msa_insve_d +#define __msa_test_bnz_b __builtin_msa_bnz_b +#define __msa_test_bnz_h __builtin_msa_bnz_h +#define __msa_test_bnz_w __builtin_msa_bnz_w +#define __msa_test_bnz_d __builtin_msa_bnz_d +#define __msa_test_bz_b __builtin_msa_bz_b +#define __msa_test_bz_h __builtin_msa_bz_h +#define __msa_test_bz_w __builtin_msa_bz_w +#define __msa_test_bz_d __builtin_msa_bz_d +#define __msa_ldi_b __builtin_msa_ldi_b +#define __msa_ldi_h __builtin_msa_ldi_h +#define __msa_ldi_w __builtin_msa_ldi_w +#define __msa_ldi_d __builtin_msa_ldi_d +#define __msa_fcaf_w __builtin_msa_fcaf_w +#define __msa_fcaf_d __builtin_msa_fcaf_d +#define __msa_fcor_w __builtin_msa_fcor_w +#define __msa_fcor_d __builtin_msa_fcor_d +#define __msa_fcun_w __builtin_msa_fcun_w +#define __msa_fcun_d __builtin_msa_fcun_d +#define __msa_fcune_w __builtin_msa_fcune_w +#define __msa_fcune_d __builtin_msa_fcune_d +#define __msa_fcueq_w __builtin_msa_fcueq_w +#define __msa_fcueq_d __builtin_msa_fcueq_d +#define __msa_fceq_w __builtin_msa_fceq_w +#define __msa_fceq_d __builtin_msa_fceq_d +#define __msa_fcne_w __builtin_msa_fcne_w +#define __msa_fcne_d __builtin_msa_fcne_d +#define __msa_fclt_w __builtin_msa_fclt_w +#define __msa_fclt_d __builtin_msa_fclt_d +#define __msa_fcult_w __builtin_msa_fcult_w +#define __msa_fcult_d __builtin_msa_fcult_d +#define __msa_fcle_w __builtin_msa_fcle_w +#define __msa_fcle_d __builtin_msa_fcle_d +#define __msa_fcule_w __builtin_msa_fcule_w +#define __msa_fcule_d __builtin_msa_fcule_d +#define __msa_fsaf_w __builtin_msa_fsaf_w +#define __msa_fsaf_d __builtin_msa_fsaf_d +#define __msa_fsor_w __builtin_msa_fsor_w +#define __msa_fsor_d __builtin_msa_fsor_d +#define __msa_fsun_w __builtin_msa_fsun_w +#define __msa_fsun_d __builtin_msa_fsun_d +#define __msa_fsune_w __builtin_msa_fsune_w +#define __msa_fsune_d __builtin_msa_fsune_d +#define __msa_fsueq_w __builtin_msa_fsueq_w +#define __msa_fsueq_d __builtin_msa_fsueq_d +#define __msa_fseq_w __builtin_msa_fseq_w +#define __msa_fseq_d __builtin_msa_fseq_d +#define __msa_fsne_w __builtin_msa_fsne_w +#define __msa_fsne_d __builtin_msa_fsne_d +#define __msa_fslt_w __builtin_msa_fslt_w +#define __msa_fslt_d __builtin_msa_fslt_d +#define __msa_fsult_w __builtin_msa_fsult_w +#define __msa_fsult_d __builtin_msa_fsult_d +#define __msa_fsle_w __builtin_msa_fsle_w +#define __msa_fsle_d __builtin_msa_fsle_d +#define __msa_fsule_w __builtin_msa_fsule_w +#define __msa_fsule_d __builtin_msa_fsule_d +#define __msa_fadd_w __builtin_msa_fadd_w +#define __msa_fadd_d __builtin_msa_fadd_d +#define __msa_fsub_w __builtin_msa_fsub_w +#define __msa_fsub_d __builtin_msa_fsub_d +#define __msa_fmul_w __builtin_msa_fmul_w +#define __msa_fmul_d __builtin_msa_fmul_d +#define __msa_fdiv_w __builtin_msa_fdiv_w +#define __msa_fdiv_d __builtin_msa_fdiv_d +#define __msa_fmadd_w __builtin_msa_fmadd_w +#define __msa_fmadd_d __builtin_msa_fmadd_d +#define __msa_fmsub_w __builtin_msa_fmsub_w +#define __msa_fmsub_d __builtin_msa_fmsub_d +#define __msa_fexp2_w __builtin_msa_fexp2_w +#define __msa_fexp2_d __builtin_msa_fexp2_d +#define __msa_fexdo_h __builtin_msa_fexdo_h +#define __msa_fexdo_w __builtin_msa_fexdo_w +#define __msa_ftq_h __builtin_msa_ftq_h +#define __msa_ftq_w __builtin_msa_ftq_w +#define __msa_fmin_w __builtin_msa_fmin_w +#define __msa_fmin_d __builtin_msa_fmin_d +#define __msa_fmin_a_w __builtin_msa_fmin_a_w +#define __msa_fmin_a_d __builtin_msa_fmin_a_d +#define __msa_fmax_w __builtin_msa_fmax_w +#define __msa_fmax_d __builtin_msa_fmax_d +#define __msa_fmax_a_w __builtin_msa_fmax_a_w +#define __msa_fmax_a_d __builtin_msa_fmax_a_d +#define __msa_mul_q_h __builtin_msa_mul_q_h +#define __msa_mul_q_w __builtin_msa_mul_q_w +#define __msa_mulr_q_h __builtin_msa_mulr_q_h +#define __msa_mulr_q_w __builtin_msa_mulr_q_w +#define __msa_madd_q_h __builtin_msa_madd_q_h +#define __msa_madd_q_w __builtin_msa_madd_q_w +#define __msa_maddr_q_h __builtin_msa_maddr_q_h +#define __msa_maddr_q_w __builtin_msa_maddr_q_w +#define __msa_msub_q_h __builtin_msa_msub_q_h +#define __msa_msub_q_w __builtin_msa_msub_q_w +#define __msa_msubr_q_h __builtin_msa_msubr_q_h +#define __msa_msubr_q_w __builtin_msa_msubr_q_w +#define __msa_fclass_w __builtin_msa_fclass_w +#define __msa_fclass_d __builtin_msa_fclass_d +#define __msa_fsqrt_w __builtin_msa_fsqrt_w +#define __msa_fsqrt_d __builtin_msa_fsqrt_d +#define __msa_frcp_w __builtin_msa_frcp_w +#define __msa_frcp_d __builtin_msa_frcp_d +#define __msa_frint_w __builtin_msa_frint_w +#define __msa_frint_d __builtin_msa_frint_d +#define __msa_frsqrt_w __builtin_msa_frsqrt_w +#define __msa_frsqrt_d __builtin_msa_frsqrt_d +#define __msa_flog2_w __builtin_msa_flog2_w +#define __msa_flog2_d __builtin_msa_flog2_d +#define __msa_fexupl_w __builtin_msa_fexupl_w +#define __msa_fexupl_d __builtin_msa_fexupl_d +#define __msa_fexupr_w __builtin_msa_fexupr_w +#define __msa_fexupr_d __builtin_msa_fexupr_d +#define __msa_ffql_w __builtin_msa_ffql_w +#define __msa_ffql_d __builtin_msa_ffql_d +#define __msa_ffqr_w __builtin_msa_ffqr_w +#define __msa_ffqr_d __builtin_msa_ffqr_d +#define __msa_ftint_s_w __builtin_msa_ftint_s_w +#define __msa_ftint_s_d __builtin_msa_ftint_s_d +#define __msa_ftint_u_w __builtin_msa_ftint_u_w +#define __msa_ftint_u_d __builtin_msa_ftint_u_d +#define __msa_ftrunc_s_w __builtin_msa_ftrunc_s_w +#define __msa_ftrunc_s_d __builtin_msa_ftrunc_s_d +#define __msa_ftrunc_u_w __builtin_msa_ftrunc_u_w +#define __msa_ftrunc_u_d __builtin_msa_ftrunc_u_d +#define __msa_ffint_s_w __builtin_msa_ffint_s_w +#define __msa_ffint_s_d __builtin_msa_ffint_s_d +#define __msa_ffint_u_w __builtin_msa_ffint_u_w +#define __msa_ffint_u_d __builtin_msa_ffint_u_d +#define __msa_cfcmsa __builtin_msa_cfcmsa +#define __msa_move_v __builtin_msa_move_v +#define __msa_cast_to_vector_float __builtin_msa_cast_to_vector_float +#define __msa_cast_to_vector_double __builtin_msa_cast_to_vector_double +#define __msa_cast_to_scalar_float __builtin_msa_cast_to_scalar_float +#define __msa_cast_to_scalar_double __builtin_msa_cast_to_scalar_double #endif /* defined(__mips_msa) */ #endif /* _MSA_H */ diff --git a/gcc-4.9/gcc/config/mips/mti-elf.h b/gcc-4.9/gcc/config/mips/mti-elf.h index 9b8076c0b..b1aede217 100644 --- a/gcc-4.9/gcc/config/mips/mti-elf.h +++ b/gcc-4.9/gcc/config/mips/mti-elf.h @@ -34,8 +34,10 @@ along with GCC; see the file COPYING3. If not see or -mgp setting. */ \ "%{!mabi=*: %{" MIPS_32BIT_OPTION_SPEC ": -mabi=32;: -mabi=n32}}", \ \ - /* If no FP option is specified, infer one from the ABI/ISA level. */\ - "%{!mfp*: %{mabi=32: %{" MIPS_FPXX_OPTION_SPEC ": -mfpxx}}}", \ + /* If no FP ABI option is specified, infer one from the \ + ABI/ISA level. */ \ + "%{!msoft-float: %{!msingle-float: %{!mfp*: %{!mmsa: %{mabi=32: %{" \ + MIPS_FPXX_OPTION_SPEC ": -mfpxx}}}}}}", \ \ /* Make sure that an endian option is always present. This makes \ things like LINK_SPEC easier to write. */ \ diff --git a/gcc-4.9/gcc/config/mips/mti-linux.h b/gcc-4.9/gcc/config/mips/mti-linux.h index d9b65f82c..101c82a5a 100644 --- a/gcc-4.9/gcc/config/mips/mti-linux.h +++ b/gcc-4.9/gcc/config/mips/mti-linux.h @@ -48,11 +48,13 @@ along with GCC; see the file COPYING3. If not see or -mgp setting. */ \ "%{!mabi=*: %{" MIPS_32BIT_OPTION_SPEC ": -mabi=32;: -mabi=n32}}", \ \ - /* If no FP option is specified, infer one from the ABI/ISA level. */\ - "%{!mfp*: %{mabi=32: %{" MIPS_FPXX_OPTION_SPEC ": -mfpxx}}}", \ + /* If no FP ABI option is specified, infer one from the \ + ABI/ISA level unless there is a conflicting option. */ \ + "%{!msoft-float: %{!msingle-float: %{!mfp*: %{!mmsa: %{mabi=32: %{" \ + MIPS_FPXX_OPTION_SPEC ": -mfpxx}}}}}}", \ \ /* Base SPECs. */ \ BASE_DRIVER_SELF_SPECS \ \ /* Use the standard linux specs for everything else. */ \ - LINUX64_DRIVER_SELF_SPECS + LINUX_DRIVER_SELF_SPECS diff --git a/gcc-4.9/gcc/config/mips/octeon.md b/gcc-4.9/gcc/config/mips/octeon.md index 1d6251c40..960894f0a 100644 --- a/gcc-4.9/gcc/config/mips/octeon.md +++ b/gcc-4.9/gcc/config/mips/octeon.md @@ -22,41 +22,55 @@ ;; Octeon is a dual-issue processor that can issue all instructions on ;; pipe0 and a subset on pipe1. -(define_automaton "octeon_main, octeon_mult") +(define_automaton "octeon_main, octeon_mult, octeon_fpu") (define_cpu_unit "octeon_pipe0" "octeon_main") (define_cpu_unit "octeon_pipe1" "octeon_main") (define_cpu_unit "octeon_mult" "octeon_mult") +(define_cpu_unit "octeon_fpu" "octeon_fpu") (define_insn_reservation "octeon_arith" 1 - (and (eq_attr "cpu" "octeon,octeon2") + (and (eq_attr "cpu" "octeon,octeon2,octeon3") (eq_attr "type" "arith,const,logical,move,shift,signext,slt,nop")) "octeon_pipe0 | octeon_pipe1") -(define_insn_reservation "octeon_condmove" 2 - (and (eq_attr "cpu" "octeon,octeon2") +(define_insn_reservation "octeon_condmove_o1" 2 + (and (eq_attr "cpu" "octeon") (eq_attr "type" "condmove")) "octeon_pipe0 | octeon_pipe1") +(define_insn_reservation "octeon_condmove_o2" 3 + (and (eq_attr "cpu" "octeon2,octeon3") + (eq_attr "type" "condmove") + (not (eq_attr "mode" "SF, DF"))) + "octeon_pipe0 | octeon_pipe1") + +;; movt/movf can only issue in pipe1 +(define_insn_reservation "octeon_condmove_o3_int_on_cc" 3 + (and (eq_attr "cpu" "octeon2,octeon3") + (eq_attr "type" "condmove") + (not (eq_attr "mode" "SF, DF"))) + "octeon_pipe1") + (define_insn_reservation "octeon_load_o1" 2 (and (eq_attr "cpu" "octeon") (eq_attr "type" "load,prefetch,mtc,mfc")) "octeon_pipe0") (define_insn_reservation "octeon_load_o2" 3 - (and (eq_attr "cpu" "octeon2") + (and (eq_attr "cpu" "octeon2,octeon3") (eq_attr "type" "load,prefetch")) "octeon_pipe0") ;; ??? memory-related cop0 reads are pipe0 with 3-cycle latency. ;; Front-end-related ones are 1-cycle on pipe1. Assume front-end for now. (define_insn_reservation "octeon_cop_o2" 1 - (and (eq_attr "cpu" "octeon2") + (and (eq_attr "cpu" "octeon2,octeon3") (eq_attr "type" "mtc,mfc")) "octeon_pipe1") (define_insn_reservation "octeon_store" 1 - (and (eq_attr "cpu" "octeon,octeon2") + (and (eq_attr "cpu" "octeon,octeon2,octeon3") (eq_attr "type" "store")) "octeon_pipe0") @@ -66,7 +80,7 @@ "octeon_pipe0") (define_insn_reservation "octeon_brj_o2" 2 - (and (eq_attr "cpu" "octeon2") + (and (eq_attr "cpu" "octeon2,octeon3") (eq_attr "type" "branch,jump,call,trap")) "octeon_pipe1") @@ -76,7 +90,7 @@ "(octeon_pipe0 | octeon_pipe1) + octeon_mult") (define_insn_reservation "octeon_imul3_o2" 6 - (and (eq_attr "cpu" "octeon2") + (and (eq_attr "cpu" "octeon2,octeon3") (eq_attr "type" "imul3,pop,clz")) "octeon_pipe1 + octeon_mult") @@ -86,7 +100,7 @@ "(octeon_pipe0 | octeon_pipe1) + octeon_mult, octeon_mult") (define_insn_reservation "octeon_imul_o2" 1 - (and (eq_attr "cpu" "octeon2") + (and (eq_attr "cpu" "octeon2,octeon3") (eq_attr "type" "imul,mthi,mtlo")) "octeon_pipe1 + octeon_mult") @@ -96,7 +110,7 @@ "(octeon_pipe0 | octeon_pipe1) + octeon_mult") (define_insn_reservation "octeon_mfhilo_o2" 6 - (and (eq_attr "cpu" "octeon2") + (and (eq_attr "cpu" "octeon2,octeon3") (eq_attr "type" "mfhi,mflo")) "octeon_pipe1 + octeon_mult") @@ -106,7 +120,7 @@ "(octeon_pipe0 | octeon_pipe1) + octeon_mult, octeon_mult*3") (define_insn_reservation "octeon_imadd_o2" 1 - (and (eq_attr "cpu" "octeon2") + (and (eq_attr "cpu" "octeon2,octeon3") (eq_attr "type" "imadd")) "octeon_pipe1 + octeon_mult") @@ -116,13 +130,13 @@ "(octeon_pipe0 | octeon_pipe1) + octeon_mult, octeon_mult*71") (define_insn_reservation "octeon_idiv_o2_si" 18 - (and (eq_attr "cpu" "octeon2") + (and (eq_attr "cpu" "octeon2,octeon3") (eq_attr "mode" "SI") (eq_attr "type" "idiv")) "octeon_pipe1 + octeon_mult, octeon_mult*17") (define_insn_reservation "octeon_idiv_o2_di" 35 - (and (eq_attr "cpu" "octeon2") + (and (eq_attr "cpu" "octeon2,octeon3") (eq_attr "mode" "DI") (eq_attr "type" "idiv")) "octeon_pipe1 + octeon_mult, octeon_mult*34") @@ -131,6 +145,95 @@ ;; patterns. (define_insn_reservation "octeon_unknown" 1 - (and (eq_attr "cpu" "octeon,octeon2") + (and (eq_attr "cpu" "octeon,octeon2,octeon3") (eq_attr "type" "unknown,multi,atomic,syncloop")) "octeon_pipe0 + octeon_pipe1") + +;; Octeon3 FPU + +(define_insn_reservation "octeon3_faddsubcvt" 4 + (and (eq_attr "cpu" "octeon3") + (eq_attr "type" "fadd, fcvt")) + "octeon_pipe1 + octeon_fpu") + +(define_insn_reservation "octeon3_fmul" 5 + (and (eq_attr "cpu" "octeon3") + (eq_attr "type" "fmul")) + "octeon_pipe1 + octeon_fpu") + +(define_insn_reservation "octeon3_fmadd" 9 + (and (eq_attr "cpu" "octeon3") + (eq_attr "type" "fmadd")) + "octeon_pipe1 + octeon_fpu, octeon_fpu") + +(define_insn_reservation "octeon3_div_sf" 12 + (and (eq_attr "cpu" "octeon3") + (eq_attr "type" "fdiv, frdiv") + (eq_attr "mode" "SF")) + "octeon_pipe1 + octeon_fpu, octeon_fpu*8") + +(define_insn_reservation "octeon3_div_df" 22 + (and (eq_attr "cpu" "octeon3") + (eq_attr "type" "fdiv, frdiv") + (eq_attr "mode" "SF")) + "octeon_pipe1 + octeon_fpu, octeon_fpu*18") + +(define_insn_reservation "octeon3_sqrt_sf" 16 + (and (eq_attr "cpu" "octeon3") + (eq_attr "type" "fsqrt") + (eq_attr "mode" "SF")) + "octeon_pipe1 + octeon_fpu, octeon_fpu*12") + +(define_insn_reservation "octeon3_sqrt_df" 30 + (and (eq_attr "cpu" "octeon3") + (eq_attr "type" "fsqrt") + (eq_attr "mode" "DF")) + "octeon_pipe1 + octeon_fpu, octeon_fpu*26") + +(define_insn_reservation "octeon3_rsqrt_sf" 27 + (and (eq_attr "cpu" "octeon3") + (eq_attr "type" "frsqrt") + (eq_attr "mode" "SF")) + "octeon_pipe1 + octeon_fpu, octeon_fpu*23") + +(define_insn_reservation "octeon3_rsqrt_df" 51 + (and (eq_attr "cpu" "octeon3") + (eq_attr "type" "frsqrt") + (eq_attr "mode" "DF")) + "octeon_pipe1 + octeon_fpu, octeon_fpu*47") + +(define_insn_reservation "octeon3_fabsnegmov" 2 + (and (eq_attr "cpu" "octeon3") + (eq_attr "type" "fabs, fneg, fmove")) + "octeon_pipe1 + octeon_fpu") + +(define_insn_reservation "octeon_fcond" 1 + (and (eq_attr "cpu" "octeon3") + (eq_attr "type" "fcmp")) + "octeon_pipe1 + octeon_fpu") + +(define_insn_reservation "octeon_fcondmov" 2 + (and (eq_attr "cpu" "octeon3") + (eq_attr "type" "condmove") + (eq_attr "mode" "SF,DF")) + "octeon_pipe1 + octeon_fpu") + +(define_insn_reservation "octeon_fpmtc1" 2 + (and (eq_attr "cpu" "octeon3") + (eq_attr "type" "mtc")) + "octeon_pipe1 + octeon_fpu") + +(define_insn_reservation "octeon_fpmfc1" 6 + (and (eq_attr "cpu" "octeon3") + (eq_attr "type" "mtc")) + "octeon_pipe1 + octeon_fpu") + +(define_insn_reservation "octeon_fpload" 3 + (and (eq_attr "cpu" "octeon3") + (eq_attr "type" "fpload,fpidxload")) + "octeon_pipe0 + octeon_fpu") + +(define_insn_reservation "octeon_fpstore" 3 + (and (eq_attr "cpu" "octeon3") + (eq_attr "type" "fpstore,fpidxstore")) + "octeon_pipe0 + octeon_pipe1") diff --git a/gcc-4.9/gcc/config/mips/predicates.md b/gcc-4.9/gcc/config/mips/predicates.md index cdb989ff5..3a08e59cf 100644 --- a/gcc-4.9/gcc/config/mips/predicates.md +++ b/gcc-4.9/gcc/config/mips/predicates.md @@ -101,6 +101,10 @@ (and (match_code "const_int,const_double,const_vector") (match_test "op == CONST0_RTX (GET_MODE (op))"))) +(define_predicate "const_yi_operand" + (and (match_code "const_vector") + (match_test "mips_const_vector_same_int_p (op, mode, -1024, 1023)"))) + (define_predicate "const_m1_operand" (and (match_code "const_int,const_double,const_vector") (match_test "op == CONSTM1_RTX (GET_MODE (op))"))) @@ -114,6 +118,12 @@ (not (match_test "TARGET_MIPS16"))) (match_operand 0 "register_operand"))) +(define_predicate "reg_or_0yi_operand" + (ior (and (ior (match_operand 0 "const_0_operand") + (match_operand 0 "const_yi_operand")) + (match_test "TARGET_MSA")) + (match_operand 0 "register_operand"))) + (define_predicate "const_1_operand" (and (match_code "const_int,const_double,const_vector") (match_test "op == CONST1_RTX (GET_MODE (op))"))) @@ -122,6 +132,23 @@ (ior (match_operand 0 "const_1_operand") (match_operand 0 "register_operand"))) +;; These are used in vec_merge, hence accept bitmask as const_int. +(define_predicate "const_exp_2_operand" + (and (match_code "const_int") + (match_test "IN_RANGE (exact_log2 (INTVAL (op)), 0, 1)"))) + +(define_predicate "const_exp_4_operand" + (and (match_code "const_int") + (match_test "IN_RANGE (exact_log2 (INTVAL (op)), 0, 3)"))) + +(define_predicate "const_exp_8_operand" + (and (match_code "const_int") + (match_test "IN_RANGE (exact_log2 (INTVAL (op)), 0, 7)"))) + +(define_predicate "const_exp_16_operand" + (and (match_code "const_int") + (match_test "IN_RANGE (exact_log2 (INTVAL (op)), 0, 15)"))) + ;; This is used for indexing into vectors, and hence only accepts const_int. (define_predicate "const_0_or_1_operand" (and (match_code "const_int") @@ -523,7 +550,18 @@ (match_code "eq,ne,lt,ltu,ge,geu")) (define_predicate "order_operator" - (match_code "lt,ltu,le,leu,ge,geu,gt,gtu")) + (match_code "lt,ltu,le,leu,ge,geu,gt,gtu") +{ + if (XEXP (op, 1) == const0_rtx) + return true; + + if (TARGET_CB_MAYBE + && (GET_CODE (op) == LT || GET_CODE (op) == LTU + || GET_CODE (op) == GE || GET_CODE (op) == GEU)) + return true; + + return false; +}) ;; For NE, cstore uses sltu instructions in which the first operand is $0. ;; This isn't possible in mips16 code. @@ -738,4 +776,3 @@ (define_predicate "reg_or_vector_same_bituimm6_operand" (ior (match_operand 0 "register_operand") (match_operand 0 "const_vector_same_uimm6_operand"))) - diff --git a/gcc-4.9/gcc/config/mips/sync.md b/gcc-4.9/gcc/config/mips/sync.md index cf6c05be2..72d2fe49a 100644 --- a/gcc-4.9/gcc/config/mips/sync.md +++ b/gcc-4.9/gcc/config/mips/sync.md @@ -59,7 +59,7 @@ ;; Can be removed in favor of atomic_compare_and_swap below. (define_insn "sync_compare_and_swap<mode>" [(set (match_operand:GPR 0 "register_operand" "=&d,&d") - (match_operand:GPR 1 "memory_operand" "+ZR,ZR")) + (match_operand:GPR 1 "memory_operand" "+ZC,ZC")) (set (match_dup 1) (unspec_volatile:GPR [(match_operand:GPR 2 "reg_or_0_operand" "dJ,dJ") (match_operand:GPR 3 "arith_operand" "I,d")] @@ -89,7 +89,7 @@ ;; Helper insn for mips_expand_atomic_qihi. (define_insn "compare_and_swap_12" [(set (match_operand:SI 0 "register_operand" "=&d,&d") - (match_operand:SI 1 "memory_operand" "+ZR,ZR")) + (match_operand:SI 1 "memory_operand" "+ZC,ZC")) (set (match_dup 1) (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "d,d") (match_operand:SI 3 "register_operand" "d,d") @@ -106,7 +106,7 @@ (set_attr "sync_insn1_op2" "5")]) (define_insn "sync_add<mode>" - [(set (match_operand:GPR 0 "memory_operand" "+ZR,ZR") + [(set (match_operand:GPR 0 "memory_operand" "+ZC,ZC") (unspec_volatile:GPR [(plus:GPR (match_dup 0) (match_operand:GPR 1 "arith_operand" "I,d"))] @@ -134,7 +134,7 @@ ;; Helper insn for sync_<optab><mode> (define_insn "sync_<optab>_12" - [(set (match_operand:SI 0 "memory_operand" "+ZR") + [(set (match_operand:SI 0 "memory_operand" "+ZC") (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "d") (match_operand:SI 2 "register_operand" "d") @@ -174,7 +174,7 @@ ;; Helper insn for sync_old_<optab><mode> (define_insn "sync_old_<optab>_12" [(set (match_operand:SI 0 "register_operand" "=&d") - (match_operand:SI 1 "memory_operand" "+ZR")) + (match_operand:SI 1 "memory_operand" "+ZC")) (set (match_dup 1) (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "d") @@ -217,7 +217,7 @@ (define_insn "sync_new_<optab>_12" [(set (match_operand:SI 0 "register_operand" "=&d") (unspec_volatile:SI - [(match_operand:SI 1 "memory_operand" "+ZR") + [(match_operand:SI 1 "memory_operand" "+ZC") (match_operand:SI 2 "register_operand" "d") (match_operand:SI 3 "register_operand" "d") (atomic_hiqi_op:SI (match_dup 0) @@ -257,7 +257,7 @@ ;; Helper insn for sync_nand<mode> (define_insn "sync_nand_12" - [(set (match_operand:SI 0 "memory_operand" "+ZR") + [(set (match_operand:SI 0 "memory_operand" "+ZC") (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "d") (match_operand:SI 2 "register_operand" "d") @@ -296,7 +296,7 @@ ;; Helper insn for sync_old_nand<mode> (define_insn "sync_old_nand_12" [(set (match_operand:SI 0 "register_operand" "=&d") - (match_operand:SI 1 "memory_operand" "+ZR")) + (match_operand:SI 1 "memory_operand" "+ZC")) (set (match_dup 1) (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "d") @@ -337,7 +337,7 @@ (define_insn "sync_new_nand_12" [(set (match_operand:SI 0 "register_operand" "=&d") (unspec_volatile:SI - [(match_operand:SI 1 "memory_operand" "+ZR") + [(match_operand:SI 1 "memory_operand" "+ZC") (match_operand:SI 2 "register_operand" "d") (match_operand:SI 3 "register_operand" "d") (match_operand:SI 4 "reg_or_0_operand" "dJ")] @@ -360,7 +360,7 @@ (set_attr "sync_insn1_op2" "4")]) (define_insn "sync_sub<mode>" - [(set (match_operand:GPR 0 "memory_operand" "+ZR") + [(set (match_operand:GPR 0 "memory_operand" "+ZC") (unspec_volatile:GPR [(minus:GPR (match_dup 0) (match_operand:GPR 1 "register_operand" "d"))] @@ -374,7 +374,7 @@ ;; Can be removed in favor of atomic_fetch_add below. (define_insn "sync_old_add<mode>" [(set (match_operand:GPR 0 "register_operand" "=&d,&d") - (match_operand:GPR 1 "memory_operand" "+ZR,ZR")) + (match_operand:GPR 1 "memory_operand" "+ZC,ZC")) (set (match_dup 1) (unspec_volatile:GPR [(plus:GPR (match_dup 1) @@ -389,7 +389,7 @@ (define_insn "sync_old_sub<mode>" [(set (match_operand:GPR 0 "register_operand" "=&d") - (match_operand:GPR 1 "memory_operand" "+ZR")) + (match_operand:GPR 1 "memory_operand" "+ZC")) (set (match_dup 1) (unspec_volatile:GPR [(minus:GPR (match_dup 1) @@ -404,7 +404,7 @@ (define_insn "sync_new_add<mode>" [(set (match_operand:GPR 0 "register_operand" "=&d,&d") - (plus:GPR (match_operand:GPR 1 "memory_operand" "+ZR,ZR") + (plus:GPR (match_operand:GPR 1 "memory_operand" "+ZC,ZC") (match_operand:GPR 2 "arith_operand" "I,d"))) (set (match_dup 1) (unspec_volatile:GPR @@ -420,7 +420,7 @@ (define_insn "sync_new_sub<mode>" [(set (match_operand:GPR 0 "register_operand" "=&d") - (minus:GPR (match_operand:GPR 1 "memory_operand" "+ZR") + (minus:GPR (match_operand:GPR 1 "memory_operand" "+ZC") (match_operand:GPR 2 "register_operand" "d"))) (set (match_dup 1) (unspec_volatile:GPR @@ -435,7 +435,7 @@ (set_attr "sync_insn1_op2" "2")]) (define_insn "sync_<optab><mode>" - [(set (match_operand:GPR 0 "memory_operand" "+ZR,ZR") + [(set (match_operand:GPR 0 "memory_operand" "+ZC,ZC") (unspec_volatile:GPR [(fetchop_bit:GPR (match_operand:GPR 1 "uns_arith_operand" "K,d") (match_dup 0))] @@ -448,7 +448,7 @@ (define_insn "sync_old_<optab><mode>" [(set (match_operand:GPR 0 "register_operand" "=&d,&d") - (match_operand:GPR 1 "memory_operand" "+ZR,ZR")) + (match_operand:GPR 1 "memory_operand" "+ZC,ZC")) (set (match_dup 1) (unspec_volatile:GPR [(fetchop_bit:GPR (match_operand:GPR 2 "uns_arith_operand" "K,d") @@ -463,7 +463,7 @@ (define_insn "sync_new_<optab><mode>" [(set (match_operand:GPR 0 "register_operand" "=&d,&d") - (match_operand:GPR 1 "memory_operand" "+ZR,ZR")) + (match_operand:GPR 1 "memory_operand" "+ZC,ZC")) (set (match_dup 1) (unspec_volatile:GPR [(fetchop_bit:GPR (match_operand:GPR 2 "uns_arith_operand" "K,d") @@ -478,7 +478,7 @@ (set_attr "sync_insn1_op2" "2")]) (define_insn "sync_nand<mode>" - [(set (match_operand:GPR 0 "memory_operand" "+ZR,ZR") + [(set (match_operand:GPR 0 "memory_operand" "+ZC,ZC") (unspec_volatile:GPR [(match_operand:GPR 1 "uns_arith_operand" "K,d")] UNSPEC_SYNC_OLD_OP))] "GENERATE_LL_SC" @@ -490,7 +490,7 @@ (define_insn "sync_old_nand<mode>" [(set (match_operand:GPR 0 "register_operand" "=&d,&d") - (match_operand:GPR 1 "memory_operand" "+ZR,ZR")) + (match_operand:GPR 1 "memory_operand" "+ZC,ZC")) (set (match_dup 1) (unspec_volatile:GPR [(match_operand:GPR 2 "uns_arith_operand" "K,d")] UNSPEC_SYNC_OLD_OP))] @@ -504,7 +504,7 @@ (define_insn "sync_new_nand<mode>" [(set (match_operand:GPR 0 "register_operand" "=&d,&d") - (match_operand:GPR 1 "memory_operand" "+ZR,ZR")) + (match_operand:GPR 1 "memory_operand" "+ZC,ZC")) (set (match_dup 1) (unspec_volatile:GPR [(match_operand:GPR 2 "uns_arith_operand" "K,d")] UNSPEC_SYNC_NEW_OP))] @@ -519,7 +519,7 @@ (define_insn "sync_lock_test_and_set<mode>" [(set (match_operand:GPR 0 "register_operand" "=&d,&d") - (match_operand:GPR 1 "memory_operand" "+ZR,ZR")) + (match_operand:GPR 1 "memory_operand" "+ZC,ZC")) (set (match_dup 1) (unspec_volatile:GPR [(match_operand:GPR 2 "arith_operand" "I,d")] UNSPEC_SYNC_EXCHANGE))] @@ -546,7 +546,7 @@ (define_insn "test_and_set_12" [(set (match_operand:SI 0 "register_operand" "=&d") - (match_operand:SI 1 "memory_operand" "+ZR")) + (match_operand:SI 1 "memory_operand" "+ZC")) (set (match_dup 1) (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "d") (match_operand:SI 3 "register_operand" "d") @@ -576,7 +576,7 @@ ;; TODO: the obscuring unspec can be relaxed for permissive memory ;; models. ;; Same applies to other atomic_* patterns. - (unspec_volatile:GPR [(match_operand:GPR 2 "memory_operand" "+ZR,ZR") + (unspec_volatile:GPR [(match_operand:GPR 2 "memory_operand" "+ZC,ZC") (match_operand:GPR 3 "reg_or_0_operand" "dJ,dJ")] UNSPEC_ATOMIC_COMPARE_AND_SWAP)) (set (match_operand:GPR 1 "register_operand" "=&d,&d") @@ -629,7 +629,7 @@ (define_insn "atomic_exchange<mode>_llsc" [(set (match_operand:GPR 0 "register_operand" "=&d,&d") - (unspec_volatile:GPR [(match_operand:GPR 1 "memory_operand" "+ZR,ZR")] + (unspec_volatile:GPR [(match_operand:GPR 1 "memory_operand" "+ZC,ZC")] UNSPEC_ATOMIC_EXCHANGE)) (set (match_dup 1) (unspec_volatile:GPR [(match_operand:GPR 2 "arith_operand" "I,d")] @@ -684,7 +684,7 @@ (define_insn "atomic_fetch_add<mode>_llsc" [(set (match_operand:GPR 0 "register_operand" "=&d,&d") - (unspec_volatile:GPR [(match_operand:GPR 1 "memory_operand" "+ZR,ZR")] + (unspec_volatile:GPR [(match_operand:GPR 1 "memory_operand" "+ZC,ZC")] UNSPEC_ATOMIC_FETCH_OP)) (set (match_dup 1) (unspec_volatile:GPR diff --git a/gcc-4.9/gcc/config/mips/t-img-elf b/gcc-4.9/gcc/config/mips/t-img-elf index 14733317e..cc5dabbc0 100644 --- a/gcc-4.9/gcc/config/mips/t-img-elf +++ b/gcc-4.9/gcc/config/mips/t-img-elf @@ -22,15 +22,17 @@ # A multilib for mips64r6+LE # A multilib for mips32r6+LE+singlefloat+shortdouble -MULTILIB_OPTIONS = mips64r6 EL msingle-float fshort-double -MULTILIB_DIRNAMES = mips64r6 el sgl short +MULTILIB_OPTIONS = mips64r6 mabi=64 EL msoft-float/msingle-float fshort-double +MULTILIB_DIRNAMES = mips64r6 64 el sof sgl short MULTILIB_MATCHES = EL=mel EB=meb # Don't build 64r6 with single-float MULTILIB_EXCEPTIONS += mips64r6/*msingle-float* MULTILIB_EXCEPTIONS += mips64r6/*fshort-double* +MULTILIB_EXCEPTIONS += mabi=64* MULTILIB_EXCEPTIONS += msingle-float* MULTILIB_EXCEPTIONS += *msingle-float MULTILIB_EXCEPTIONS += fshort-double MULTILIB_EXCEPTIONS += EL/fshort-double +MULTILIB_EXCEPTIONS += *msoft-float/fshort-double |