aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/gcc/config/mips/mips-msa.md
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.9/gcc/config/mips/mips-msa.md')
-rw-r--r--gcc-4.9/gcc/config/mips/mips-msa.md2905
1 files changed, 2905 insertions, 0 deletions
diff --git a/gcc-4.9/gcc/config/mips/mips-msa.md b/gcc-4.9/gcc/config/mips/mips-msa.md
new file mode 100644
index 000000000..37f5fcab5
--- /dev/null
+++ b/gcc-4.9/gcc/config/mips/mips-msa.md
@@ -0,0 +1,2905 @@
+;; Machine Description for MIPS MSA ASE
+;; Based on the MIPS MSA spec Revision 1.07 30/8/2013
+;; Contributed by Chao-ying Fu (fu@mips.com), MIPS Technologies, Inc.
+;;
+;; Copyright (C) 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_c_enum "unspec" [
+ UNSPEC_MSA_ADDVI
+ UNSPEC_MSA_ANDI_B
+ UNSPEC_MSA_ASUB_S
+ UNSPEC_MSA_ASUB_U
+ UNSPEC_MSA_AVE_S
+ UNSPEC_MSA_AVE_U
+ UNSPEC_MSA_AVER_S
+ UNSPEC_MSA_AVER_U
+ UNSPEC_MSA_BCLR
+ UNSPEC_MSA_BCLRI
+ UNSPEC_MSA_BINSL
+ UNSPEC_MSA_BINSLI
+ UNSPEC_MSA_BINSR
+ UNSPEC_MSA_BINSRI
+ UNSPEC_MSA_BMNZ_V
+ UNSPEC_MSA_BMNZI_B
+ UNSPEC_MSA_BMZ_V
+ UNSPEC_MSA_BMZI_B
+ UNSPEC_MSA_BNEG
+ UNSPEC_MSA_BNEGI
+ UNSPEC_MSA_BSEL_V
+ UNSPEC_MSA_BSELI_B
+ UNSPEC_MSA_BSET
+ UNSPEC_MSA_BSETI
+ UNSPEC_MSA_BNZ_V
+ UNSPEC_MSA_BZ_V
+ UNSPEC_MSA_BNZ
+ 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
+ UNSPEC_MSA_DPADD_S
+ UNSPEC_MSA_DPADD_U
+ UNSPEC_MSA_DPSUB_S
+ UNSPEC_MSA_DPSUB_U
+ UNSPEC_MSA_FCAF
+ UNSPEC_MSA_FCLASS
+ UNSPEC_MSA_FCUNE
+ UNSPEC_MSA_FEXDO
+ UNSPEC_MSA_FEXP2
+ UNSPEC_MSA_FEXUPL
+ UNSPEC_MSA_FEXUPR
+ UNSPEC_MSA_FFINT_S
+ 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
+ UNSPEC_MSA_FRSQRT
+ UNSPEC_MSA_FSAF
+ UNSPEC_MSA_FSEQ
+ UNSPEC_MSA_FSLE
+ UNSPEC_MSA_FSLT
+ UNSPEC_MSA_FSNE
+ UNSPEC_MSA_FSOR
+ UNSPEC_MSA_FSUEQ
+ UNSPEC_MSA_FSULE
+ UNSPEC_MSA_FSULT
+ UNSPEC_MSA_FSUN
+ UNSPEC_MSA_FSUNE
+ UNSPEC_MSA_FTINT_S
+ UNSPEC_MSA_FTINT_U
+ UNSPEC_MSA_FTRUNC_S
+ UNSPEC_MSA_FTRUNC_U
+ UNSPEC_MSA_FTQ
+ UNSPEC_MSA_HADD_S
+ 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
+ UNSPEC_MSA_MSUBR_Q
+ UNSPEC_MSA_MUL_Q
+ UNSPEC_MSA_MULR_Q
+ UNSPEC_MSA_NLOC
+ UNSPEC_MSA_NLZC
+ UNSPEC_MSA_NORI_B
+ UNSPEC_MSA_ORI_B
+ UNSPEC_MSA_PCKEV
+ UNSPEC_MSA_PCKOD
+ UNSPEC_MSA_PCNT
+ UNSPEC_MSA_SAT_S
+ UNSPEC_MSA_SAT_U
+ UNSPEC_MSA_SHF
+ UNSPEC_MSA_SLD
+ UNSPEC_MSA_SLDI
+ UNSPEC_MSA_SLLI
+ UNSPEC_MSA_SPLAT
+ UNSPEC_MSA_SPLATI
+ UNSPEC_MSA_SRAI
+ UNSPEC_MSA_SRAR
+ UNSPEC_MSA_SRARI
+ UNSPEC_MSA_SRLI
+ UNSPEC_MSA_SRLR
+ UNSPEC_MSA_SRLRI
+ UNSPEC_MSA_SUBS_S
+ UNSPEC_MSA_SUBS_U
+ UNSPEC_MSA_SUBSUU_S
+ UNSPEC_MSA_SUBSUS_U
+ UNSPEC_MSA_SUBVI
+ UNSPEC_MSA_TSTNZ_V
+ UNSPEC_MSA_TSTZ_V
+ UNSPEC_MSA_TSTNZ
+ UNSPEC_MSA_TSTZ
+ UNSPEC_MSA_VSHF
+ UNSPEC_MSA_XORI_B
+ UNSPEC_MSA_CAST_TO_SCALAR
+ UNSPEC_MSA_CAST_TO_VECTOR
+])
+
+;; Attributes to categorize MSA instructions based on execution units
+(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"
+ (const_string "unknown"))
+
+;; All vector modes with 128 bits.
+(define_mode_iterator MODE128 [V2DF V4SF V2DI V4SI V8HI V16QI])
+(define_mode_iterator MSA [V2DF V4SF V2DI V4SI V8HI V16QI])
+
+;; Same as MSA. Used by vcond to iterate two modes.
+(define_mode_iterator MSA_2 [V2DF V4SF V2DI V4SI V8HI V16QI])
+
+;; Only integer modes.
+(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])
+
+;; mode that can be combine copy+inset with subreg info insve.
+(define_mode_iterator INSVE_2 [V8HI V16QI])
+
+;; As IMSA but excludeds V16QI.
+(define_mode_iterator IMSA_X [V2DI V4SI V8HI])
+
+;; Only used with insert.
+(define_mode_iterator MSA_3 [V16QI V8HI V2DF V4SF])
+
+;; Only integer modes for fixed-point madd_q/maddr_q.
+(define_mode_iterator QMSA [V4SI V8HI])
+
+;; Only floating-point modes.
+(define_mode_iterator FMSA [V2DF V4SF])
+
+;; Only integer modes for dot product.
+(define_mode_iterator IDOTP128 [V2DI V4SI V8HI])
+
+;; Only used in spliters
+(define_mode_iterator SPLIT [V2DI V2DF])
+
+;; Only used with SPILT iteraror
+(define_mode_attr predicate
+ [(V2DI "reg_or_0")
+ (V2DF "register")])
+
+(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 VIMODE
+ [(V2DF "V2DI")
+ (V4SF "V4SI")
+ (V2DI "V2DI")
+ (V4SI "V4SI")
+ (V8HI "V8HI")
+ (V16QI "V16QI")])
+
+;; This attribute gives the integer vector mode with same size.
+(define_mode_attr mode_i
+ [(V2DF "v2di")
+ (V4SF "v4si")
+ (V2DI "v2di")
+ (V4SI "v4si")
+ (V8HI "v8hi")
+ (V16QI "v16qi")])
+
+;; This attribute gives the mode of the result for "copy_s_b, copy_u_b" etc.
+(define_mode_attr RES
+ [(V2DF "DF")
+ (V4SF "SF")
+ (V2DI "DI")
+ (V4SI "SI")
+ (V8HI "SI")
+ (V16QI "SI")])
+
+;; This attribute qives suffix for MSA instructions.
+(define_mode_attr msafmt
+ [(V2DF "d")
+ (V4SF "w")
+ (V2DI "d")
+ (V4SI "w")
+ (V8HI "h")
+ (V16QI "b")])
+
+;; This is used in msa_cast* to output mov.s or mov.d.
+(define_mode_attr unitfmt
+ [(V2DF "d")
+ (V4SF "s")])
+
+;; This attribute qives 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")
+ (V2DI "d")
+ (V4SI "w")
+ (V8HI "h")
+ (V16QI "b")])
+
+;; The mask for shift amounts.
+(define_mode_attr shift_mask
+ [(V2DI "63")
+ (V4SI "31")
+ (V8HI "15")
+ (V16QI "7")])
+
+;; 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")
+ (V2DI "0_or_1")
+ (V4SI "0_to_3")
+ (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")
+ (V4SI "SI")
+ (V8HI "SI")
+ (V16QI "SI")])
+
+;; This attribute used to form an immediate operand constraint
+;; using "const_<bitimm>_operand"
+(define_mode_attr bitimm
+ [(V16QI "uimm3")
+ (V8HI "uimm4")
+ (V4SI "uimm5")
+ (V2DI "uimm6")
+ ])
+
+(define_expand "vec_init<mode>"
+ [(match_operand:MSA 0 "register_operand")
+ (match_operand:MSA 1 "")]
+ "ISA_HAS_MSA"
+{
+ mips_expand_vector_init (operands[0], operands[1]);
+ DONE;
+})
+
+(define_expand "vec_extract<mode>"
+ [(match_operand:<UNITMODE> 0 "register_operand")
+ (match_operand:IMSA 1 "register_operand")
+ (match_operand 2 "const_<indeximm>_operand")]
+ "ISA_HAS_MSA"
+{
+ if (<UNITMODE>mode == QImode || <UNITMODE>mode == HImode)
+ {
+ rtx dest1 = gen_reg_rtx (SImode);
+ emit_insn (gen_msa_copy_s_<msafmt> (dest1, operands[1], operands[2]));
+ emit_move_insn (operands[0],
+ gen_lowpart (<UNITMODE>mode, dest1));
+ }
+ else
+ emit_insn (gen_msa_copy_s_<msafmt> (operands[0], operands[1], operands[2]));
+ DONE;
+})
+
+(define_expand "vec_extract<mode>"
+ [(match_operand:<UNITMODE> 0 "register_operand")
+ (match_operand:FMSA 1 "register_operand")
+ (match_operand 2 "const_<indeximm>_operand")]
+ "ISA_HAS_MSA"
+{
+ rtx temp;
+ HOST_WIDE_INT val = UINTVAL (operands[2]);
+
+ if (val == 0)
+ temp = operands[1];
+ else
+ {
+ /* We need to do the SLDI operation in V16QImode and adjust
+ operand[2] accordingly. */
+ rtx tempb = gen_reg_rtx (V16QImode);
+ rtx op1b = gen_reg_rtx (V16QImode);
+ emit_move_insn (op1b, gen_rtx_SUBREG (V16QImode, operands[1], 0));
+ rtx op2b = GEN_INT (val * GET_MODE_SIZE (<UNITMODE>mode));
+ gcc_assert (UINTVAL (op2b) < GET_MODE_NUNITS (V16QImode));
+ emit_insn (gen_msa_sldi_b (tempb, op1b, op1b, op2b));
+ temp = gen_reg_rtx (<MODE>mode);
+ emit_move_insn (temp, gen_rtx_SUBREG (<MODE>mode, tempb, 0));
+ }
+ emit_insn (gen_msa_cast_to_scalar_<msafmt_f> (operands[0], temp));
+ DONE;
+})
+
+(define_expand "vec_set<mode>"
+ [(match_operand:IMSA 0 "register_operand")
+ (match_operand:<UNITMODE> 1 "register_operand")
+ (match_operand 2 "const_<indeximm>_operand")]
+ "ISA_HAS_MSA"
+{
+ emit_insn (gen_msa_insert_<msafmt> (operands[0], operands[0], operands[2],
+ operands[1]));
+ DONE;
+})
+
+(define_expand "vec_set<mode>"
+ [(match_operand:FMSA 0 "register_operand")
+ (match_operand:<UNITMODE> 1 "register_operand")
+ (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]));
+ DONE;
+})
+
+(define_expand "vcondu<MSA_2:mode><IMSA:mode>"
+ [(set (match_operand:MSA_2 0 "register_operand")
+ (if_then_else:MSA_2
+ (match_operator 3 ""
+ [(match_operand:IMSA 4 "register_operand")
+ (match_operand:IMSA 5 "register_operand")])
+ (match_operand:MSA_2 1 "reg_or_m1_operand")
+ (match_operand:MSA_2 2 "reg_or_0_operand")))]
+ "ISA_HAS_MSA
+ && (GET_MODE_NUNITS (<MSA_2:MODE>mode)
+ == GET_MODE_NUNITS (<IMSA:MODE>mode))"
+{
+ mips_expand_vec_cond_expr (<MSA_2:MODE>mode,
+ <MSA_2:VIMODE>mode,
+ operands,
+ gen_and<MSA_2:mode_i>3,
+ gen_msa_nor_v_<MSA_2:msafmt>,
+ gen_ior<MSA_2:mode_i>3);
+ DONE;
+})
+
+(define_expand "vcond<MSA_2:mode><MSA:mode>"
+ [(set (match_operand:MSA_2 0 "register_operand")
+ (if_then_else:MSA_2
+ (match_operator 3 ""
+ [(match_operand:MSA 4 "register_operand")
+ (match_operand:MSA 5 "register_operand")])
+ (match_operand:MSA_2 1 "reg_or_m1_operand")
+ (match_operand:MSA_2 2 "reg_or_0_operand")))]
+ "ISA_HAS_MSA
+ && (GET_MODE_NUNITS (<MSA_2:MODE>mode)
+ == GET_MODE_NUNITS (<MSA:MODE>mode))"
+{
+ mips_expand_vec_cond_expr (<MSA_2:MODE>mode,
+ <MSA_2:VIMODE>mode,
+ operands,
+ gen_and<MSA_2:mode_i>3,
+ gen_msa_nor_v_<MSA_2:msafmt>,
+ gen_ior<MSA_2:mode_i>3);
+ DONE;
+})
+
+(define_insn "msa_insert_<msafmt>"
+ [(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))]
+ "ISA_HAS_MSA"
+ "insert.<msafmt>\t%w0[%2],%z3"
+ [(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.
+
+(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))]
+ "ISA_HAS_MSA"
+ "insert.<msafmt>\t%w0[%2],%z3"
+ [(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))]
+ "reload_completed && TARGET_MSA && !TARGET_64BIT"
+ [(const_int 0)]
+{
+ mips_split_msa_insert_d (operands[0], operands[1], operands[2], operands[3]);
+ 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))]
+ "ISA_HAS_MSA"
+ "insve.<msafmt>\t%w0[%2],%w3[0]"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic_l")])
+
+;; 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))]
+ "ISA_HAS_MSA"
+ "insve.<msafmt>\t%w0[%2],%w3[0]"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic_l")])
+
+;; 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))]
+ "ISA_HAS_MSA"
+ "insve.<msafmt>\t%w0[%2],%w3[0]"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic_l")])
+
+;; 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))]
+ "ISA_HAS_MSA"
+ "insve.<msafmt>\t%w0[%2],%w3[%4]"
+ [(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))]
+ "ISA_HAS_MSA"
+ "insve.<msafmt>\t%w0[%2],%w3[0]"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic_l")])
+
+;; 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))]
+ "ISA_HAS_MSA"
+ "insve.<msafmt>\t%w0[%2],%w3[0]"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic_l")])
+
+;; 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))]
+ "ISA_HAS_MSA"
+ "copy_s.<msafmt>\t%0,%w1[%2]"
+ [(set_attr "type" "mfc")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_store4")])
+
+(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))]
+ "reload_completed && TARGET_MSA && !TARGET_64BIT"
+ [(const_int 0)]
+{
+ mips_split_msa_copy_d (operands[0], operands[1], operands[2], gen_msa_copy_s_w);
+ DONE;
+})
+
+;; 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))]
+ "ISA_HAS_MSA"
+ "copy_u.<msafmt>\t%0,%w1[%2]"
+ [(set_attr "type" "mfc")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_store4")])
+
+(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))]
+ "reload_completed && TARGET_MSA && !TARGET_64BIT"
+ [(const_int 0)]
+{
+ mips_split_msa_copy_d (operands[0], operands[1], operands[2], gen_msa_copy_u_w);
+ DONE;
+})
+
+(define_expand "vec_perm<mode>"
+ [(match_operand:MSA 0 "register_operand")
+ (match_operand:MSA 1 "register_operand")
+ (match_operand:MSA 2 "register_operand")
+ (match_operand:<VIMODE> 3 "register_operand")]
+ "ISA_HAS_MSA"
+{
+ /* 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. */
+ emit_insn (gen_msa_vshf<mode> (operands[0], operands[3], operands[2],
+ operands[1]));
+ DONE;
+})
+
+(define_expand "neg<mode>2"
+ [(match_operand:IMSA 0 "register_operand")
+ (match_operand:IMSA 1 "register_operand")]
+ "ISA_HAS_MSA"
+{
+ rtx reg = gen_reg_rtx (<MODE>mode);
+ emit_insn (gen_msa_ldi<mode> (reg, const0_rtx));
+ emit_insn (gen_sub<mode>3 (operands[0], reg, operands[1]));
+ DONE;
+})
+
+(define_expand "neg<mode>2"
+ [(match_operand:FMSA 0 "register_operand")
+ (match_operand:FMSA 1 "register_operand")]
+ "ISA_HAS_MSA"
+{
+ rtx reg = gen_reg_rtx (<MODE>mode);
+ emit_insn (gen_msa_ld0<mode> (reg, const0_rtx));
+ 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")]
+ "ISA_HAS_MSA"
+ {
+ unsigned n_elts = GET_MODE_NUNITS (<MODE>mode);
+ rtvec v = rtvec_alloc (n_elts);
+ HOST_WIDE_INT val = INTVAL (operands[1]);
+ unsigned int i;
+
+ if (<MODE>mode != V16QImode)
+ {
+ unsigned shift = HOST_BITS_PER_WIDE_INT - 10;
+ val = trunc_int_for_mode ((val << shift) >> shift, <UNITMODE>mode);
+ }
+ else
+ 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)));
+ 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")
+ (match_operand:MSA 2 "register_operand" "f")
+ (match_operand:MSA 3 "register_operand" "f")]
+ UNSPEC_MSA_VSHF))]
+ "ISA_HAS_MSA"
+ "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")])
+
+(define_expand "mov<mode>"
+ [(set (match_operand:MODE128 0)
+ (match_operand:MODE128 1))]
+ "TARGET_64BIT || 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"
+{
+ 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.
+(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))"
+{ 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;
+})
+
+(define_split
+ [(set (match_operand:MSA 0 "nonimmediate_operand")
+ (match_operand:MSA 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]));
+ mips_split_move_insn (operands[0], operands[1], curr_insn);
+ DONE;
+})
+
+;; Offset load
+(define_expand "msa_ld_<msafmt_f>"
+ [(match_operand:MSA 0 "register_operand")
+ (match_operand 1 "pmode_register_operand")
+ (match_operand 2 "aq10<msafmt>_operand")]
+ "ISA_HAS_MSA"
+{
+ rtx addr = plus_constant (GET_MODE (operands[1]), operands[1],
+ INTVAL (operands[2]));
+ mips_emit_move (operands[0], gen_rtx_MEM (<MODE>mode, addr));
+ DONE;
+})
+
+;; Offset store
+(define_expand "msa_st_<msafmt_f>"
+ [(match_operand:MSA 0 "register_operand")
+ (match_operand 1 "pmode_register_operand")
+ (match_operand 2 "aq10<msafmt>_operand")]
+ "ISA_HAS_MSA"
+{
+ rtx addr = plus_constant (GET_MODE (operands[1]), operands[1],
+ INTVAL (operands[2]));
+ mips_emit_move (gen_rtx_MEM (<MODE>mode, addr), operands[0]);
+ DONE;
+})
+
+;; Integer operations
+(define_insn "add<mode>3"
+ [(set (match_operand:IMSA 0 "register_operand" "=f,f,f")
+ (plus:IMSA (match_operand:IMSA 1 "register_operand" "f,f,f")
+ (match_operand:IMSA 2 "reg_or_vector_same_ximm5_operand" "f,Unv5,Uuv5")))]
+ "ISA_HAS_MSA"
+ {
+ switch (which_alternative)
+ {
+ case 0:
+ return "addv.<msafmt>\t%w0,%w1,%w2";
+ case 1:
+ {
+ HOST_WIDE_INT val = INTVAL (CONST_VECTOR_ELT (operands[2], 0));
+
+ operands[2] = GEN_INT (-val);
+ return "subvi.<msafmt>\t%w0,%w1,%d2";
+ }
+ case 2:
+ {
+ HOST_WIDE_INT val = INTVAL (CONST_VECTOR_ELT (operands[2], 0));
+
+ operands[2] = GEN_INT (val);
+ return "addvi.<msafmt>\t%w0,%w1,%d2";
+ }
+ default:
+ gcc_unreachable ();
+ }
+ }
+ [(set_attr "alu_type" "add")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_int_add")])
+
+(define_insn "sub<mode>3"
+ [(set (match_operand:IMSA 0 "register_operand" "=f,f,f")
+ (minus:IMSA (match_operand:IMSA 1 "register_operand" "f,f,f")
+ (match_operand:IMSA 2 "reg_or_vector_same_ximm5_operand" "f,Unv5,Uuv5")))]
+ "ISA_HAS_MSA"
+ {
+ switch (which_alternative)
+ {
+ case 0:
+ return "subv.<msafmt>\t%w0,%w1,%w2";
+ case 1:
+ {
+ HOST_WIDE_INT val = INTVAL (CONST_VECTOR_ELT (operands[2], 0));
+
+ operands[2] = GEN_INT (-val);
+ return "addvi.<msafmt>\t%w0,%w1,%d2";
+ }
+ case 2:
+ {
+ HOST_WIDE_INT val = INTVAL (CONST_VECTOR_ELT (operands[2], 0));
+
+ operands[2] = GEN_INT (val);
+ return "subvi.<msafmt>\t%w0,%w1,%d2";
+ }
+ default:
+ gcc_unreachable ();
+ }
+ }
+ [(set_attr "alu_type" "sub")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_int_add")])
+
+(define_insn "mul<mode>3"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (mult:IMSA (match_operand:IMSA 1 "register_operand" "f")
+ (match_operand:IMSA 2 "register_operand" "f")))]
+ "ISA_HAS_MSA"
+ "mulv.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "imul3")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_mult")])
+
+(define_insn "msa_maddv_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (plus:IMSA (mult:IMSA (match_operand:IMSA 2 "register_operand" "f")
+ (match_operand:IMSA 3 "register_operand" "f"))
+ (match_operand:IMSA 1 "register_operand" "0")))]
+ "ISA_HAS_MSA"
+ "maddv.<msafmt>\t%w0,%w2,%w3"
+ [(set_attr "type" "imadd")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_mult")])
+
+(define_insn "msa_msubv_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (minus:IMSA (match_operand:IMSA 1 "register_operand" "0")
+ (mult:IMSA (match_operand:IMSA 2 "register_operand" "f")
+ (match_operand:IMSA 3 "register_operand" "f"))))]
+ "ISA_HAS_MSA"
+ "msubv.<msafmt>\t%w0,%w2,%w3"
+ [(set_attr "type" "imadd")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_mult")])
+
+(define_insn "div<mode>3"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (div:IMSA (match_operand:IMSA 1 "register_operand" "f")
+ (match_operand:IMSA 2 "register_operand" "f")))]
+ "ISA_HAS_MSA"
+ { return mips_msa_output_division ("div_s.<msafmt>\t%w0,%w1,%w2", operands); }
+ [(set_attr "type" "idiv3")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_div")])
+
+(define_insn "udiv<mode>3"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (udiv:IMSA (match_operand:IMSA 1 "register_operand" "f")
+ (match_operand:IMSA 2 "register_operand" "f")))]
+ "ISA_HAS_MSA"
+ { return mips_msa_output_division ("div_u.<msafmt>\t%w0,%w1,%w2", operands); }
+ [(set_attr "type" "idiv3")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_div")])
+
+(define_insn "mod<mode>3"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (mod:IMSA (match_operand:IMSA 1 "register_operand" "f")
+ (match_operand:IMSA 2 "register_operand" "f")))]
+ "ISA_HAS_MSA"
+ { return mips_msa_output_division ("mod_s.<msafmt>\t%w0,%w1,%w2", operands); }
+ [(set_attr "type" "idiv3")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_div")])
+
+(define_insn "umod<mode>3"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (umod:IMSA (match_operand:IMSA 1 "register_operand" "f")
+ (match_operand:IMSA 2 "register_operand" "f")))]
+ "ISA_HAS_MSA"
+ { return mips_msa_output_division ("mod_u.<msafmt>\t%w0,%w1,%w2", operands); }
+ [(set_attr "type" "idiv3")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_div")])
+
+(define_insn "xorv16qi3"
+ [(set (match_operand:V16QI 0 "register_operand" "=f,f")
+ (xor:V16QI (match_operand:V16QI 1 "register_operand" "f,f")
+ (match_operand:V16QI 2 "reg_or_vector_same_byte_operand" "f,Ubv8")))]
+ "ISA_HAS_MSA"
+ {
+ if (which_alternative == 1)
+ {
+ operands[2] = CONST_VECTOR_ELT (operands[2], 0);
+ return "xori.b\t%w0,%w1,%B2";
+ }
+ else
+ return "xor.v\t%w0,%w1,%w2";
+ }
+ [(set_attr "alu_type" "xor")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic")])
+
+(define_insn "xor<mode>3"
+ [(set (match_operand:IMSA_X 0 "register_operand" "=f,f")
+ (xor:IMSA_X (match_operand:IMSA_X 1 "register_operand" "f,f")
+ (match_operand:IMSA_X 2 "reg_or_vector_same_<mode>_set_operand" "f,YC")))]
+ "ISA_HAS_MSA"
+ {
+ if (which_alternative == 1)
+ {
+ HOST_WIDE_INT val = INTVAL (CONST_VECTOR_ELT (operands[2], 0));
+ int vlog2 = exact_log2 (val);
+ gcc_assert (vlog2 != -1);
+ operands[2] = GEN_INT (vlog2);
+ return "bnegi.%v0\t%w0,%w1,%2";
+ }
+ else
+ return "xor.v\t%w0,%w1,%w2";
+ }
+ [(set_attr "alu_type" "xor")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic")])
+
+(define_insn "iorv16qi3"
+ [(set (match_operand:V16QI 0 "register_operand" "=f,f")
+ (ior:V16QI (match_operand:V16QI 1 "register_operand" "f,f")
+ (match_operand:V16QI 2 "reg_or_vector_same_byte_operand" "f,Ubv8")))]
+ "ISA_HAS_MSA"
+ {
+ if (which_alternative == 1)
+ {
+ operands[2] = CONST_VECTOR_ELT (operands[2], 0);
+ return "ori.b\t%w0,%w1,%B2";
+ }
+ else
+ return "or.v\t%w0,%w1,%w2";
+ }
+ [(set_attr "alu_type" "or")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic")])
+
+(define_insn "ior<mode>3"
+ [(set (match_operand:IMSA_X 0 "register_operand" "=f,f")
+ (ior:IMSA_X (match_operand:IMSA_X 1 "register_operand" "f,f")
+ (match_operand:IMSA_X 2 "reg_or_vector_same_<mode>_set_operand" "f,YC")))]
+ "ISA_HAS_MSA"
+ {
+ if (which_alternative == 1)
+ {
+ HOST_WIDE_INT val = INTVAL (CONST_VECTOR_ELT (operands[2], 0));
+ int vlog2 = exact_log2 (val);
+ gcc_assert (vlog2 != -1);
+ operands[2] = GEN_INT (vlog2);
+ return "bseti.%v0\t%w0,%w1,%2";
+ }
+ else
+ return "or.v\t%w0,%w1,%w2";
+ }
+ [(set_attr "alu_type" "or")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic")])
+
+(define_insn "andv16qi3"
+ [(set (match_operand:V16QI 0 "register_operand" "=f,f")
+ (and:V16QI (match_operand:V16QI 1 "register_operand" "f,f")
+ (match_operand:V16QI 2 "reg_or_vector_same_byte_operand" "f,Ubv8")))]
+ "ISA_HAS_MSA"
+ {
+ if (which_alternative == 1)
+ {
+ operands[2] = CONST_VECTOR_ELT (operands[2], 0);
+ return "andi.b\t%w0,%w0,%B2";
+ }
+ else
+ return "and.v\t%w0,%w1,%w2";
+ }
+ [(set_attr "alu_type" "and")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic")])
+
+(define_insn "and<mode>3"
+ [(set (match_operand:IMSA_X 0 "register_operand" "=f,f")
+ (and:IMSA_X (match_operand:IMSA_X 1 "register_operand" "f,f")
+ (match_operand:IMSA_X 2 "reg_or_vector_same_<mode>_clr_operand" "f,YZ")))]
+ "ISA_HAS_MSA"
+ {
+ if (which_alternative == 1)
+ {
+ HOST_WIDE_INT val = INTVAL (CONST_VECTOR_ELT (operands[2], 0));
+ int vlog2 = exact_log2 (~val);
+ gcc_assert (vlog2 != -1);
+ operands[2] = GEN_INT (vlog2);
+ return "bclri.%v0\t%w0,%w1,%2";
+ }
+ else
+ return "and.v\t%w0,%w1,%w2";
+ }
+ [(set_attr "alu_type" "and")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic")])
+
+(define_insn "one_cmpl<mode>2"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (not:IMSA (match_operand:IMSA 1 "register_operand" "f")))]
+ "ISA_HAS_MSA"
+ "nor.v\t%w0,%w1,%w1"
+ [(set_attr "alu_type" "nor")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic")])
+
+(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")))]
+ "ISA_HAS_MSA"
+{
+ if (which_alternative == 0)
+ return "srl.<msafmt>\t%w0,%w1,%w2";
+
+ operands[2] = GEN_INT (INTVAL (CONST_VECTOR_ELT (operands[2], 0))
+ & <shift_mask>);
+ return "srli.<msafmt>\t%w0,%w1,%2";
+}
+ [(set_attr "type" "shift")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic")])
+
+(define_insn "vashr<mode>3"
+ [(set (match_operand:IMSA 0 "register_operand" "=f,f")
+ (ashiftrt: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)
+ return "sra.<msafmt>\t%w0,%w1,%w2";
+
+ operands[2] = GEN_INT (INTVAL (CONST_VECTOR_ELT (operands[2], 0))
+ & <shift_mask>);
+ return "srai.<msafmt>\t%w0,%w1,%2";
+}
+ [(set_attr "type" "shift")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic")])
+
+(define_insn "vashl<mode>3"
+ [(set (match_operand:IMSA 0 "register_operand" "=f,f")
+ (ashift: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)
+ return "sll.<msafmt>\t%w0,%w1,%w2";
+
+ operands[2] = GEN_INT (INTVAL (CONST_VECTOR_ELT (operands[2], 0))
+ & <shift_mask>);
+ return "slli.<msafmt>\t%w0,%w1,%2";
+}
+ [(set_attr "type" "shift")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic")])
+
+;; Floating-point operations
+(define_insn "add<mode>3"
+ [(set (match_operand:FMSA 0 "register_operand" "=f")
+ (plus:FMSA (match_operand:FMSA 1 "register_operand" "f")
+ (match_operand:FMSA 2 "register_operand" "f")))]
+ "ISA_HAS_MSA"
+ "fadd.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "fadd")
+ (set_attr "mode" "<UNITMODE>")
+ (set_attr "msa_execunit" "msa_eu_float4")])
+
+(define_insn "sub<mode>3"
+ [(set (match_operand:FMSA 0 "register_operand" "=f")
+ (minus:FMSA (match_operand:FMSA 1 "register_operand" "f")
+ (match_operand:FMSA 2 "register_operand" "f")))]
+ "ISA_HAS_MSA"
+ "fsub.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "fadd")
+ (set_attr "mode" "<UNITMODE>")
+ (set_attr "msa_execunit" "msa_eu_float4")])
+
+(define_insn "mul<mode>3"
+ [(set (match_operand:FMSA 0 "register_operand" "=f")
+ (mult:FMSA (match_operand:FMSA 1 "register_operand" "f")
+ (match_operand:FMSA 2 "register_operand" "f")))]
+ "ISA_HAS_MSA"
+ "fmul.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "fmul")
+ (set_attr "mode" "<UNITMODE>")
+ (set_attr "msa_execunit" "msa_eu_float5")])
+
+(define_insn "div<mode>3"
+ [(set (match_operand:FMSA 0 "register_operand" "=f")
+ (div:FMSA (match_operand:FMSA 1 "register_operand" "f")
+ (match_operand:FMSA 2 "register_operand" "f")))]
+ "ISA_HAS_MSA"
+ "fdiv.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "fdiv")
+ (set_attr "mode" "<UNITMODE>")
+ (set_attr "msa_execunit" "msa_eu_fdiv")])
+
+(define_insn "msa_fmadd_<msafmt>"
+ [(set (match_operand:FMSA 0 "register_operand" "=f")
+ (plus:FMSA (mult:FMSA (match_operand:FMSA 2 "register_operand" "f")
+ (match_operand:FMSA 3 "register_operand" "f"))
+ (match_operand:FMSA 1 "register_operand" "0")))]
+ "ISA_HAS_MSA"
+ "fmadd.<msafmt>\t%w0,%w2,%w3"
+ [(set_attr "type" "fmadd")
+ (set_attr "mode" "<UNITMODE>")
+ (set_attr "msa_execunit" "msa_eu_float8")])
+
+(define_insn "msa_fmsub_<msafmt>"
+ [(set (match_operand:FMSA 0 "register_operand" "=f")
+ (minus:FMSA (match_operand:FMSA 1 "register_operand" "0")
+ (mult:FMSA (match_operand:FMSA 2 "register_operand" "f")
+ (match_operand:FMSA 3 "register_operand" "f"))))]
+ "ISA_HAS_MSA"
+ "fmsub.<msafmt>\t%w0,%w2,%w3"
+ [(set_attr "type" "fmadd")
+ (set_attr "mode" "<UNITMODE>")
+ (set_attr "msa_execunit" "msa_eu_float8")])
+
+(define_insn "sqrt<mode>2"
+ [(set (match_operand:FMSA 0 "register_operand" "=f")
+ (sqrt:FMSA (match_operand:FMSA 1 "register_operand" "f")))]
+ "ISA_HAS_MSA"
+ "fsqrt.<msafmt>\t%w0,%w1"
+ [(set_attr "type" "fsqrt")
+ (set_attr "mode" "<UNITMODE>")
+ (set_attr "msa_execunit" "msa_eu_fdiv")])
+
+;; Built-in functions
+(define_insn "msa_add_a_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (plus:IMSA (abs:IMSA (match_operand:IMSA 1 "register_operand" "f"))
+ (abs:IMSA (match_operand:IMSA 2 "register_operand" "f"))))]
+ "ISA_HAS_MSA"
+ "add_a.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_int_add")])
+
+(define_insn "msa_adds_a_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (ss_plus:IMSA (abs:IMSA (match_operand:IMSA 1 "register_operand" "f"))
+ (abs:IMSA (match_operand:IMSA 2 "register_operand" "f"))))]
+ "ISA_HAS_MSA"
+ "adds_a.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_int_add")])
+
+(define_insn "ssadd<mode>3"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (ss_plus:IMSA (match_operand:IMSA 1 "register_operand" "f")
+ (match_operand:IMSA 2 "register_operand" "f")))]
+ "ISA_HAS_MSA"
+ "adds_s.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_int_add")])
+
+(define_insn "usadd<mode>3"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (us_plus:IMSA (match_operand:IMSA 1 "register_operand" "f")
+ (match_operand:IMSA 2 "register_operand" "f")))]
+ "ISA_HAS_MSA"
+ "adds_u.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_int_add")])
+
+(define_insn "msa_addvi_<msafmt>"
+ [(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))]
+ "ISA_HAS_MSA"
+ "addvi.<msafmt>\t%w0,%w1,%2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_int_add")])
+
+(define_insn "msa_andi_b"
+ [(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))]
+ "ISA_HAS_MSA"
+ "andi.b\t%w0,%w1,%2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic")])
+
+(define_insn "msa_asub_s_<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_ASUB_S))]
+ "ISA_HAS_MSA"
+ "asub_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_asub_u_<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_ASUB_U))]
+ "ISA_HAS_MSA"
+ "asub_u.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_int_add")])
+
+(define_insn "msa_ave_s_<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_AVE_S))]
+ "ISA_HAS_MSA"
+ "ave_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_ave_u_<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_AVE_U))]
+ "ISA_HAS_MSA"
+ "ave_u.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_int_add")])
+
+(define_insn "msa_aver_s_<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_AVER_S))]
+ "ISA_HAS_MSA"
+ "aver_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_aver_u_<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_AVER_U))]
+ "ISA_HAS_MSA"
+ "aver_u.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_int_add")])
+
+(define_insn "msa_bclr_<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_BCLR))]
+ "ISA_HAS_MSA"
+ "bclr.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic")])
+
+(define_insn "msa_bclri_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
+ (match_operand 2 "const_<bitimm>_operand" "")]
+ UNSPEC_MSA_BCLRI))]
+ "ISA_HAS_MSA"
+ "bclri.<msafmt>\t%w0,%w1,%2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic")])
+
+(define_insn "msa_binsl_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "0")
+ (match_operand:IMSA 2 "register_operand" "f")
+ (match_operand:IMSA 3 "register_operand" "f")]
+ UNSPEC_MSA_BINSL))]
+ "ISA_HAS_MSA"
+ "binsl.<msafmt>\t%w0,%w2,%w3"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic_l")])
+
+(define_insn "msa_binsli_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "0")
+ (match_operand:IMSA 2 "register_operand" "f")
+ (match_operand 3 "const_<bitimm>_operand" "")]
+ UNSPEC_MSA_BINSLI))]
+ "ISA_HAS_MSA"
+ "binsli.<msafmt>\t%w0,%w2,%3"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic_l")])
+
+(define_insn "msa_binsr_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "0")
+ (match_operand:IMSA 2 "register_operand" "f")
+ (match_operand:IMSA 3 "register_operand" "f")]
+ UNSPEC_MSA_BINSR))]
+ "ISA_HAS_MSA"
+ "binsr.<msafmt>\t%w0,%w2,%w3"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic_l")])
+
+(define_insn "msa_binsri_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "0")
+ (match_operand:IMSA 2 "register_operand" "f")
+ (match_operand 3 "const_<bitimm>_operand" "")]
+ UNSPEC_MSA_BINSRI))]
+ "ISA_HAS_MSA"
+ "binsri.<msafmt>\t%w0,%w2,%3"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic_l")])
+
+(define_insn "msa_bmnz_v_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "0")
+ (match_operand:IMSA 2 "register_operand" "f")
+ (match_operand:IMSA 3 "register_operand" "f")]
+ UNSPEC_MSA_BMNZ_V))]
+ "ISA_HAS_MSA"
+ "bmnz.v\t%w0,%w2,%w3"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic_l")])
+
+(define_insn "msa_bmnzi_b"
+ [(set (match_operand:V16QI 0 "register_operand" "=f")
+ (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "0")
+ (match_operand:V16QI 2 "register_operand" "f")
+ (match_operand 3 "const_uimm8_operand" "")]
+ UNSPEC_MSA_BMNZI_B))]
+ "ISA_HAS_MSA"
+ "bmnzi.b\t%w0,%w2,%3"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic_l")])
+
+(define_insn "msa_bmz_v_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "0")
+ (match_operand:IMSA 2 "register_operand" "f")
+ (match_operand:IMSA 3 "register_operand" "f")]
+ UNSPEC_MSA_BMZ_V))]
+ "ISA_HAS_MSA"
+ "bmz.v\t%w0,%w2,%w3"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic_l")])
+
+(define_insn "msa_bmzi_b"
+ [(set (match_operand:V16QI 0 "register_operand" "=f")
+ (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "0")
+ (match_operand:V16QI 2 "register_operand" "f")
+ (match_operand 3 "const_uimm8_operand" "")]
+ UNSPEC_MSA_BMZI_B))]
+ "ISA_HAS_MSA"
+ "bmzi.b\t%w0,%w2,%3"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic_l")])
+
+(define_insn "msa_bneg_<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_BNEG))]
+ "ISA_HAS_MSA"
+ "bneg.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "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))]
+ "ISA_HAS_MSA"
+ "bnegi.<msafmt>\t%w0,%w1,%2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic")])
+
+(define_insn "msa_bsel_v_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "0")
+ (match_operand:IMSA 2 "register_operand" "f")
+ (match_operand:IMSA 3 "register_operand" "f")]
+ UNSPEC_MSA_BSEL_V))]
+ "ISA_HAS_MSA"
+ "bsel.v\t%w0,%w2,%w3"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")])
+
+(define_insn "msa_bseli_b"
+ [(set (match_operand:V16QI 0 "register_operand" "=f")
+ (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "0")
+ (match_operand:V16QI 2 "register_operand" "f")
+ (match_operand 3 "const_uimm8_operand" "")]
+ UNSPEC_MSA_BSELI_B))]
+ "ISA_HAS_MSA"
+ "bseli.b\t%w0,%w2,%3"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic_l")])
+
+(define_insn "msa_bset_<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_BSET))]
+ "ISA_HAS_MSA"
+ "bset.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic")])
+
+(define_insn "msa_bseti_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
+ (match_operand 2 "const_<bitimm>_operand" "")]
+ UNSPEC_MSA_BSETI))]
+ "ISA_HAS_MSA"
+ "bseti.<msafmt>\t%w0,%w1,%2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic")])
+
+(define_code_iterator ICC [eq le leu lt ltu])
+
+(define_code_attr icc
+ [(eq "eq")
+ (le "le_s")
+ (leu "le_u")
+ (lt "lt_s")
+ (ltu "lt_u")])
+
+(define_code_attr icci
+ [(eq "eqi")
+ (le "lei_s")
+ (leu "lei_u")
+ (lt "lti_s")
+ (ltu "lti_u")])
+
+(define_code_attr cmpi
+ [(eq "s")
+ (le "s")
+ (leu "u")
+ (lt "s")
+ (ltu "u")])
+
+(define_insn "msa_c<ICC:icc>_<IMSA:msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (ICC:IMSA (match_operand:IMSA 1 "register_operand" "f")
+ (match_operand:IMSA 2 "register_operand" "f")))]
+ "ISA_HAS_MSA"
+ "c<ICC:icc>.<IMSA:msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_int_add")])
+
+(define_insn "msa_c<ICC:icci>i_<IMSA:msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (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";
+ }
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_int_add")])
+
+(define_insn "msa_c<ICC:icci>_<IMSA:msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(ICC:IMSA (match_operand:IMSA 1 "register_operand" "f")
+ (match_operand 2 "const_imm5_operand" ""))]
+ UNSPEC_MSA_CMPI))]
+ "ISA_HAS_MSA"
+ "c<ICC:icci>.<IMSA:msafmt>\t%w0,%w1,%2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_int_add")])
+
+(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))]
+ "ISA_HAS_MSA"
+ "dotp_s.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_mult")])
+
+(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))]
+ "ISA_HAS_MSA"
+ "dotp_u.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_mult")])
+
+(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))]
+ "ISA_HAS_MSA"
+ "dpadd_s.<msafmt>\t%w0,%w2,%w3"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_mult")])
+
+(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))]
+ "ISA_HAS_MSA"
+ "dpadd_u.<msafmt>\t%w0,%w2,%w3"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_mult")])
+
+(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))]
+ "ISA_HAS_MSA"
+ "dpsub_s.<msafmt>\t%w0,%w2,%w3"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_mult")])
+
+(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))]
+ "ISA_HAS_MSA"
+ "dpsub_u.<msafmt>\t%w0,%w2,%w3"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_mult")])
+
+(define_insn "msa_fclass_<msafmt>"
+ [(set (match_operand:<VIMODE> 0 "register_operand" "=f")
+ (unspec:<VIMODE> [(match_operand:FMSA 1 "register_operand" "f")]
+ UNSPEC_MSA_FCLASS))]
+ "ISA_HAS_MSA"
+ "fclass.<msafmt>\t%w0,%w1"
+ [(set_attr "type" "fcmp")
+ (set_attr "mode" "<UNITMODE>")
+ (set_attr "msa_execunit" "msa_eu_float2_l")])
+
+(define_insn "msa_fcaf_<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_FCAF))]
+ "ISA_HAS_MSA"
+ "fcaf.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "fcmp")
+ (set_attr "mode" "<UNITMODE>")
+ (set_attr "msa_execunit" "msa_eu_cmp")])
+
+(define_insn "msa_fcune_<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_FCUNE))]
+ "ISA_HAS_MSA"
+ "fcune.<FMSA:msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "fcmp")
+ (set_attr "mode" "<UNITMODE>")
+ (set_attr "msa_execunit" "msa_eu_cmp")])
+
+(define_code_iterator FCC [unordered ordered eq ne le lt uneq unle unlt])
+
+(define_code_attr fcc
+ [(unordered "fcun")
+ (ordered "fcor")
+ (eq "fceq")
+ (ne "fcne")
+ (uneq "fcueq")
+ (unle "fcule")
+ (unlt "fcult")
+ (le "fcle")
+ (lt "fclt")])
+
+(define_insn "msa_<FCC:fcc>_<FMSA:msafmt>"
+ [(set (match_operand:<VIMODE> 0 "register_operand" "=f")
+ (FCC:<VIMODE> (match_operand:FMSA 1 "register_operand" "f")
+ (match_operand:FMSA 2 "register_operand" "f")))]
+ "ISA_HAS_MSA"
+ "<FCC:fcc>.<FMSA:msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "fcmp")
+ (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>"
+ [(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))]
+ "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"
+ [(set_attr "type" "fcmp")
+ (set_attr "mode" "<UNITMODE>")
+ (set_attr "msa_execunit" "msa_eu_cmp")])
+
+(define_insn "msa_fexp2_<msafmt>"
+ [(set (match_operand:FMSA 0 "register_operand" "=f")
+ (unspec:FMSA [(match_operand:FMSA 1 "register_operand" "f")
+ (match_operand:<VIMODE> 2 "register_operand" "f")]
+ UNSPEC_MSA_FEXP2))]
+ "ISA_HAS_MSA"
+ "fexp2.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "fmul")
+ (set_attr "mode" "<UNITMODE>")
+ (set_attr "msa_execunit" "msa_eu_float2")])
+
+(define_mode_attr FINT
+ [(V4SF "V4SI")
+ (V2DF "V2DI")])
+
+(define_mode_attr fint
+ [(V4SF "v4si")
+ (V2DF "v2di")])
+
+(define_mode_attr FINTCNV
+ [(V4SF "I2S")
+ (V2DF "I2D")])
+
+(define_mode_attr FINTCNV_2
+ [(V4SF "S2I")
+ (V2DF "D2I")])
+
+(define_insn "float<FMSA:mode><fint>2"
+ [(set (match_operand:FMSA 0 "register_operand" "=f")
+ (float:<MODE> (match_operand:<FINT> 1 "register_operand" "f")))]
+ "ISA_HAS_MSA"
+ "ffint_s.<msafmt>\t%w0,%w1"
+ [(set_attr "type" "fcvt")
+ (set_attr "cnv_mode" "<FINTCNV>")
+ (set_attr "mode" "<UNITMODE>")
+ (set_attr "msa_execunit" "msa_eu_float4")])
+
+(define_insn "floatuns<FMSA:mode><fint>2"
+ [(set (match_operand:FMSA 0 "register_operand" "=f")
+ (unsigned_float:<MODE> (match_operand:<FINT> 1 "register_operand" "f")))]
+ "ISA_HAS_MSA"
+ "ffint_u.<msafmt>\t%w0,%w1"
+ [(set_attr "type" "fcvt")
+ (set_attr "cnv_mode" "<FINTCNV>")
+ (set_attr "mode" "<UNITMODE>")
+ (set_attr "msa_execunit" "msa_eu_float4")])
+
+(define_mode_attr FFQ
+ [(V4SF "V8HI")
+ (V2DF "V4SI")])
+
+(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))]
+ "ISA_HAS_MSA"
+ "ffql.<msafmt>\t%w0,%w1"
+ [(set_attr "type" "fcvt")
+ (set_attr "cnv_mode" "<FINTCNV>")
+ (set_attr "mode" "<UNITMODE>")
+ (set_attr "msa_execunit" "msa_eu_float4")])
+
+(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))]
+ "ISA_HAS_MSA"
+ "ffqr.<msafmt>\t%w0,%w1"
+ [(set_attr "type" "fcvt")
+ (set_attr "cnv_mode" "<FINTCNV>")
+ (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))]
+ "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))]
+ "reload_completed && TARGET_MSA && !TARGET_64BIT"
+ [(const_int 0)]
+{
+ mips_split_msa_fill_d (operands[0], operands[1]);
+ DONE;
+})
+
+(define_split
+ [(set (match_operand:V2DF 0 "register_operand")
+ (unspec:V2DF [(match_operand:DF 1 "register_operand")]
+ UNSPEC_MSA_FILL))]
+ "reload_completed && TARGET_MSA && !TARGET_64BIT"
+ [(const_int 0)]
+{
+ mips_split_msa_fill_d (operands[0], operands[1]);
+ DONE;
+})
+
+(define_insn "msa_flog2_<msafmt>"
+ [(set (match_operand:FMSA 0 "register_operand" "=f")
+ (unspec:FMSA [(match_operand:FMSA 1 "register_operand" "f")]
+ UNSPEC_MSA_FLOG2))]
+ "ISA_HAS_MSA"
+ "flog2.<msafmt>\t%w0,%w1"
+ [(set_attr "type" "fmul")
+ (set_attr "mode" "<UNITMODE>")
+ (set_attr "msa_execunit" "msa_eu_float2_l")])
+
+;;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")))]
+ "ISA_HAS_MSA"
+ "fmax.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "fadd")
+ (set_attr "mode" "<UNITMODE>")
+ (set_attr "msa_execunit" "msa_eu_float2")])
+
+;;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")))]
+ "ISA_HAS_MSA"
+ "fmax_a.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "fadd")
+ (set_attr "mode" "<UNITMODE>")
+ (set_attr "msa_execunit" "msa_eu_float2")])
+
+;;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")))]
+ "ISA_HAS_MSA"
+ "fmin.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "fadd")
+ (set_attr "mode" "<UNITMODE>")
+ (set_attr "msa_execunit" "msa_eu_float2")])
+
+;;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")))]
+ "ISA_HAS_MSA"
+ "fmin_a.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "fadd")
+ (set_attr "mode" "<UNITMODE>")
+ (set_attr "msa_execunit" "msa_eu_float2")])
+
+(define_insn "msa_frcp_<msafmt>"
+ [(set (match_operand:FMSA 0 "register_operand" "=f")
+ (unspec:FMSA [(match_operand:FMSA 1 "register_operand" "f")]
+ UNSPEC_MSA_FRCP))]
+ "ISA_HAS_MSA"
+ "frcp.<msafmt>\t%w0,%w1"
+ [(set_attr "type" "frdiv")
+ (set_attr "mode" "<UNITMODE>")])
+
+(define_insn "msa_frint_<msafmt>"
+ [(set (match_operand:FMSA 0 "register_operand" "=f")
+ (unspec:FMSA [(match_operand:FMSA 1 "register_operand" "f")]
+ UNSPEC_MSA_FRINT))]
+ "ISA_HAS_MSA"
+ "frint.<msafmt>\t%w0,%w1"
+ [(set_attr "type" "fmul")
+ (set_attr "mode" "<UNITMODE>")
+ (set_attr "msa_execunit" "msa_eu_float4")])
+
+(define_insn "msa_frsqrt_<msafmt>"
+ [(set (match_operand:FMSA 0 "register_operand" "=f")
+ (unspec:FMSA [(match_operand:FMSA 1 "register_operand" "f")]
+ UNSPEC_MSA_FRSQRT))]
+ "ISA_HAS_MSA"
+ "frsqrt.<msafmt>\t%w0,%w1"
+ [(set_attr "type" "frsqrt")
+ (set_attr "mode" "<UNITMODE>")])
+
+(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"
+ [(set_attr "type" "fcvt")
+ (set_attr "cnv_mode" "<FINTCNV_2>")
+ (set_attr "mode" "<UNITMODE>")
+ (set_attr "msa_execunit" "msa_eu_float4")])
+
+(define_insn "msa_ftint_u_<msafmt>"
+ [(set (match_operand:<FINT> 0 "register_operand" "=f")
+ (unspec:<FINT> [(match_operand:FMSA 1 "register_operand" "f")]
+ UNSPEC_MSA_FTINT_U))]
+ "ISA_HAS_MSA"
+ "ftint_u.<msafmt>\t%w0,%w1"
+ [(set_attr "type" "fcvt")
+ (set_attr "cnv_mode" "<FINTCNV_2>")
+ (set_attr "mode" "<UNITMODE>")
+ (set_attr "msa_execunit" "msa_eu_float4")])
+
+(define_insn "msa_ftrunc_s_<msafmt>"
+ [(set (match_operand:<FINT> 0 "register_operand" "=f")
+ (unspec:<FINT> [(match_operand:FMSA 1 "register_operand" "f")]
+ UNSPEC_MSA_FTRUNC_S))]
+ "ISA_HAS_MSA"
+ "ftrunc_s.<msafmt>\t%w0,%w1"
+ [(set_attr "type" "fcvt")
+ (set_attr "cnv_mode" "<FINTCNV_2>")
+ (set_attr "mode" "<UNITMODE>")
+ (set_attr "msa_execunit" "msa_eu_float4")])
+
+(define_insn "msa_ftrunc_u_<msafmt>"
+ [(set (match_operand:<FINT> 0 "register_operand" "=f")
+ (unspec:<FINT> [(match_operand:FMSA 1 "register_operand" "f")]
+ UNSPEC_MSA_FTRUNC_U))]
+ "ISA_HAS_MSA"
+ "ftrunc_u.<msafmt>\t%w0,%w1"
+ [(set_attr "type" "fcvt")
+ (set_attr "cnv_mode" "<FINTCNV_2>")
+ (set_attr "mode" "<UNITMODE>")
+ (set_attr "msa_execunit" "msa_eu_float4")])
+
+(define_insn "msa_ftq_h"
+ [(set (match_operand:V8HI 0 "register_operand" "=f")
+ (unspec:V8HI [(match_operand:V4SF 1 "register_operand" "f")
+ (match_operand:V4SF 2 "register_operand" "f")]
+ UNSPEC_MSA_FTQ))]
+ "ISA_HAS_MSA"
+ "ftq.h\t%w0,%w1,%w2"
+ [(set_attr "type" "fcvt")
+ (set_attr "cnv_mode" "S2I")
+ (set_attr "mode" "SF")
+ (set_attr "msa_execunit" "msa_eu_float4")])
+
+(define_insn "msa_ftq_w"
+ [(set (match_operand:V4SI 0 "register_operand" "=f")
+ (unspec:V4SI [(match_operand:V2DF 1 "register_operand" "f")
+ (match_operand:V2DF 2 "register_operand" "f")]
+ UNSPEC_MSA_FTQ))]
+ "ISA_HAS_MSA"
+ "ftq.w\t%w0,%w1,%w2"
+ [(set_attr "type" "fcvt")
+ (set_attr "cnv_mode" "D2I")
+ (set_attr "mode" "DF")
+ (set_attr "msa_execunit" "msa_eu_float4")])
+
+(define_mode_iterator IZMODE [V8HI V4SI V2DI])
+(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")
+ (match_operand:<IZDOUBLE> 2 "register_operand" "f")]
+ UNSPEC_MSA_HADD_S))]
+ "ISA_HAS_MSA"
+ "hadd_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_hadd_u_<msafmt>"
+ [(set (match_operand:IZMODE 0 "register_operand" "=f")
+ (unspec:<MODE> [(match_operand:<IZDOUBLE> 1 "register_operand" "f")
+ (match_operand:<IZDOUBLE> 2 "register_operand" "f")]
+ UNSPEC_MSA_HADD_U))]
+ "ISA_HAS_MSA"
+ "hadd_u.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_int_add")])
+
+(define_insn "msa_hsub_s_<msafmt>"
+ [(set (match_operand:IZMODE 0 "register_operand" "=f")
+ (unspec:<MODE> [(match_operand:<IZDOUBLE> 1 "register_operand" "f")
+ (match_operand:<IZDOUBLE> 2 "register_operand" "f")]
+ UNSPEC_MSA_HSUB_S))]
+ "ISA_HAS_MSA"
+ "hsub_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_hsub_u_<msafmt>"
+ [(set (match_operand:IZMODE 0 "register_operand" "=f")
+ (unspec:<MODE> [(match_operand:<IZDOUBLE> 1 "register_operand" "f")
+ (match_operand:<IZDOUBLE> 2 "register_operand" "f")]
+ UNSPEC_MSA_HSUB_U))]
+ "ISA_HAS_MSA"
+ "hsub_u.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "arith")
+ (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))]
+ "ISA_HAS_MSA"
+ "ilvev.<msafmt>\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))]
+ "ISA_HAS_MSA"
+ "ilvl.<msafmt>\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))]
+ "ISA_HAS_MSA"
+ "ilvod.<msafmt>\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))]
+ "ISA_HAS_MSA"
+ "ilvr.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "alu_type" "add")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic")])
+
+(define_insn "msa_madd_q_<msafmt>"
+ [(set (match_operand:QMSA 0 "register_operand" "=f")
+ (unspec:QMSA [(match_operand:QMSA 1 "register_operand" "0")
+ (match_operand:QMSA 2 "register_operand" "f")
+ (match_operand:QMSA 3 "register_operand" "f")]
+ UNSPEC_MSA_MADD_Q))]
+ "ISA_HAS_MSA"
+ "madd_q.<msafmt>\t%w0,%w2,%w3"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_mult")])
+
+(define_insn "msa_maddr_q_<msafmt>"
+ [(set (match_operand:QMSA 0 "register_operand" "=f")
+ (unspec:QMSA [(match_operand:QMSA 1 "register_operand" "0")
+ (match_operand:QMSA 2 "register_operand" "f")
+ (match_operand:QMSA 3 "register_operand" "f")]
+ UNSPEC_MSA_MADDR_Q))]
+ "ISA_HAS_MSA"
+ "maddr_q.<msafmt>\t%w0,%w2,%w3"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_mult")])
+
+(define_insn "msa_max_a_<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_MAX_A))]
+ "ISA_HAS_MSA"
+ "max_a.<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_s_<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_MAX_S))]
+ "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>"
+ [(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))]
+ "ISA_HAS_MSA"
+ "max_u.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_int_add")])
+
+(define_insn "msa_maxi_s_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
+ (match_operand 2 "const_imm5_operand" "")]
+ UNSPEC_MSA_MAXI_S))]
+ "ISA_HAS_MSA"
+ "maxi_s.<msafmt>\t%w0,%w1,%2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_int_add")])
+
+(define_insn "msa_maxi_u_<msafmt>"
+ [(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_MAXI_U))]
+ "ISA_HAS_MSA"
+ "maxi_u.<msafmt>\t%w0,%w1,%2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_int_add")])
+
+(define_insn "msa_min_a_<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_MIN_A))]
+ "ISA_HAS_MSA"
+ "min_a.<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_s_<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_MIN_S))]
+ "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>"
+ [(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))]
+ "ISA_HAS_MSA"
+ "min_u.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_int_add")])
+
+(define_insn "msa_mini_s_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
+ (match_operand 2 "const_imm5_operand" "")]
+ UNSPEC_MSA_MINI_S))]
+ "ISA_HAS_MSA"
+ "mini_s.<msafmt>\t%w0,%w1,%2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_int_add")])
+
+(define_insn "msa_mini_u_<msafmt>"
+ [(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_MINI_U))]
+ "ISA_HAS_MSA"
+ "mini_u.<msafmt>\t%w0,%w1,%2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_int_add")])
+
+(define_insn "msa_msub_q_<msafmt>"
+ [(set (match_operand:QMSA 0 "register_operand" "=f")
+ (unspec:QMSA [(match_operand:QMSA 1 "register_operand" "0")
+ (match_operand:QMSA 2 "register_operand" "f")
+ (match_operand:QMSA 3 "register_operand" "f")]
+ UNSPEC_MSA_MSUB_Q))]
+ "ISA_HAS_MSA"
+ "msub_q.<msafmt>\t%w0,%w2,%w3"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_mult")])
+
+(define_insn "msa_msubr_q_<msafmt>"
+ [(set (match_operand:QMSA 0 "register_operand" "=f")
+ (unspec:QMSA [(match_operand:QMSA 1 "register_operand" "0")
+ (match_operand:QMSA 2 "register_operand" "f")
+ (match_operand:QMSA 3 "register_operand" "f")]
+ UNSPEC_MSA_MSUBR_Q))]
+ "ISA_HAS_MSA"
+ "msubr_q.<msafmt>\t%w0,%w2,%w3"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_mult")])
+
+(define_insn "msa_mul_q_<msafmt>"
+ [(set (match_operand:QMSA 0 "register_operand" "=f")
+ (unspec:QMSA [(match_operand:QMSA 1 "register_operand" "f")
+ (match_operand:QMSA 2 "register_operand" "f")]
+ UNSPEC_MSA_MUL_Q))]
+ "ISA_HAS_MSA"
+ "mul_q.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_mult")])
+
+(define_insn "msa_mulr_q_<msafmt>"
+ [(set (match_operand:QMSA 0 "register_operand" "=f")
+ (unspec:QMSA [(match_operand:QMSA 1 "register_operand" "f")
+ (match_operand:QMSA 2 "register_operand" "f")]
+ UNSPEC_MSA_MULR_Q))]
+ "ISA_HAS_MSA"
+ "mulr_q.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_mult")])
+
+(define_insn "msa_nloc_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")]
+ UNSPEC_MSA_NLOC))]
+ "ISA_HAS_MSA"
+ "nloc.<msafmt>\t%w0,%w1"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic")])
+
+(define_insn "clz<mode>2"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (clz:IMSA (match_operand:IMSA 1 "register_operand" "f")))]
+ "ISA_HAS_MSA"
+ "nlzc.<msafmt>\t%w0,%w1"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic")])
+
+(define_insn "msa_nor_v_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (and:IMSA (not:IMSA (match_operand:IMSA 1 "register_operand" "f"))
+ (not:IMSA (match_operand:IMSA 2 "register_operand" "f"))))]
+ "ISA_HAS_MSA"
+ "nor.v\t%w0,%w1,%w2"
+ [(set_attr "alu_type" "nor")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic")])
+
+(define_insn "msa_nori_b"
+ [(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_NORI_B))]
+ "ISA_HAS_MSA"
+ "nori.b\t%w0,%w1,%2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic")])
+
+(define_insn "msa_ori_b"
+ [(set (match_operand:V16QI 0 "register_operand" "=f")
+ (ior:V16QI (match_operand:V16QI 1 "register_operand" "f")
+ (match_operand 2 "const_uimm8_operand" "")))]
+ "ISA_HAS_MSA"
+ "ori.b\t%w0,%w1,%2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic")])
+
+(define_insn "msa_pckev_<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_PCKEV))]
+ "ISA_HAS_MSA"
+ "pckev.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "alu_type" "add")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic")])
+
+(define_insn "msa_pckod_<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_PCKOD))]
+ "ISA_HAS_MSA"
+ "pckod.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "alu_type" "add")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic")])
+
+(define_insn "popcount<mode>2"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (popcount:IMSA (match_operand:IMSA 1 "register_operand" "f")))]
+ "ISA_HAS_MSA"
+ "pcnt.<msafmt>\t%w0,%w1"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic")])
+
+(define_insn "msa_sat_s_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
+ (match_operand 2 "const_<bitimm>_operand" "")]
+ UNSPEC_MSA_SAT_S))]
+ "ISA_HAS_MSA"
+ "sat_s.<msafmt>\t%w0,%w1,%2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic3")])
+
+(define_insn "msa_sat_u_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
+ (match_operand 2 "const_<bitimm>_operand" "")]
+ UNSPEC_MSA_SAT_U))]
+ "ISA_HAS_MSA"
+ "sat_u.<msafmt>\t%w0,%w1,%2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic3")])
+
+(define_insn "msa_shf_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
+ (match_operand 2 "const_uimm8_operand" "")]
+ UNSPEC_MSA_SHF))]
+ "ISA_HAS_MSA"
+ "shf.<msafmt>\t%w0,%w1,%2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic")])
+
+(define_insn "msa_shf_w_f"
+ [(set (match_operand:V4SF 0 "register_operand" "=f")
+ (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "f")
+ (match_operand 2 "const_uimm8_operand" "")]
+ UNSPEC_MSA_SHF))]
+ "ISA_HAS_MSA"
+ "shf.w\t%w0,%w1,%2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic")])
+
+(define_insn "msa_slli_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
+ (match_operand 2 "const_<bitimm>_operand" "")]
+ UNSPEC_MSA_SLLI))]
+ "ISA_HAS_MSA"
+ "slli.<msafmt>\t%w0,%w1,%2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic")])
+
+(define_insn "msa_srai_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA[(match_operand:IMSA 1 "register_operand" "f")
+ (match_operand 2 "const_<bitimm>_operand" "")]
+ UNSPEC_MSA_SRAI))]
+ "ISA_HAS_MSA"
+ "srai.<msafmt>\t%w0,%w1,%2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic")])
+
+(define_insn "msa_srar_<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_SRAR))]
+ "ISA_HAS_MSA"
+ "srar.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic")])
+
+(define_insn "msa_srari_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
+ (match_operand 2 "const_<bitimm>_operand" "")]
+ UNSPEC_MSA_SRARI))]
+ "ISA_HAS_MSA"
+ "srari.<msafmt>\t%w0,%w1,%2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic")])
+
+(define_insn "msa_srli_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
+ (match_operand 2 "const_<bitimm>_operand" "")]
+ UNSPEC_MSA_SRLI))]
+ "ISA_HAS_MSA"
+ "srli.<msafmt>\t%w0,%w1,%2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic")])
+
+(define_insn "msa_srlr_<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_SRLR))]
+ "ISA_HAS_MSA"
+ "srlr.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic")])
+
+(define_insn "msa_srlri_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
+ (match_operand 2 "const_<bitimm>_operand" "")]
+ UNSPEC_MSA_SRLRI))]
+ "ISA_HAS_MSA"
+ "srlri.<msafmt>\t%w0,%w1,%2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic")])
+
+(define_insn "msa_subs_s_<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_SUBS_S))]
+ "ISA_HAS_MSA"
+ "subs_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_subs_u_<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_SUBS_U))]
+ "ISA_HAS_MSA"
+ "subs_u.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_int_add")])
+
+(define_insn "msa_subsuu_s_<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_SUBSUU_S))]
+ "ISA_HAS_MSA"
+ "subsuu_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_subsus_u_<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_SUBSUS_U))]
+ "ISA_HAS_MSA"
+ "subsus_u.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_int_add")])
+
+(define_insn "msa_subvi_<msafmt>"
+ [(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_SUBVI))]
+ "ISA_HAS_MSA"
+ "subvi.<msafmt>\t%w0,%w1,%2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_int_add")])
+
+(define_insn "msa_xori_b"
+ [(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_XORI_B))]
+ "ISA_HAS_MSA"
+ "xori.b\t%w0,%w1,%2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic")])
+
+(define_insn "msa_sld_<msafmt_f>"
+ [(set (match_operand:MSA 0 "register_operand" "=f")
+ (unspec:MSA [(match_operand:MSA 1 "register_operand" "0")
+ (match_operand:MSA 2 "register_operand" "f")
+ (match_operand:SI 3 "reg_or_0_operand" "dJ")]
+ UNSPEC_MSA_SLD))]
+ "ISA_HAS_MSA"
+ "sld.<msafmt>\t%w0,%w2[%z3]"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic_l")])
+
+(define_insn "msa_sldi_<msafmt_f>"
+ [(set (match_operand:MSA 0 "register_operand" "=f")
+ (unspec:MSA [(match_operand:MSA 1 "register_operand" "0")
+ (match_operand:MSA 2 "register_operand" "f")
+ (match_operand 3 "const_<indeximm>_operand" "")]
+ UNSPEC_MSA_SLDI))]
+ "ISA_HAS_MSA"
+ "sldi.<msafmt>\t%w0,%w2[%3]"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic_l")])
+
+(define_insn "msa_splat_<msafmt_f>"
+ [(set (match_operand:MSA 0 "register_operand" "=f")
+ (unspec:MSA [(match_operand:MSA 1 "register_operand" "f")
+ (match_operand:SI 2 "reg_or_0_operand" "dJ")]
+ UNSPEC_MSA_SPLAT))]
+ "ISA_HAS_MSA"
+ "splat.<msafmt>\t%w0,%w1[%z2]"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic")])
+
+(define_insn "msa_splati_<msafmt_f>"
+ [(set (match_operand:MSA 0 "register_operand" "=f")
+ (unspec:MSA [(match_operand:MSA 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")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic")])
+
+;; 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))]
+ "ISA_HAS_MSA"
+ "splati.<msafmt>\t%w0,%w1[%2]"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_logic")])
+
+(define_insn "msa_cfcmsa"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (unspec_volatile:SI [(match_operand 1 "const_uimm5_operand" "")]
+ UNSPEC_MSA_CFCMSA))]
+ "ISA_HAS_MSA"
+ "cfcmsa\t%0,$%1"
+ [(set_attr "type" "mfc")
+ (set_attr "mode" "SI")
+ (set_attr "msa_execunit" "msa_eu_store4")])
+
+(define_insn "msa_ctcmsa"
+ [(unspec_volatile [(match_operand 0 "const_uimm5_operand" "")
+ (match_operand:SI 1 "register_operand" "d")]
+ UNSPEC_MSA_CTCMSA)]
+ "ISA_HAS_MSA"
+ "ctcmsa\t$%0,%1"
+ [(set_attr "type" "mtc")
+ (set_attr "mode" "SI")
+ (set_attr "msa_execunit" "msa_eu_store4")])
+
+(define_insn "msa_fexdo_h"
+ [(set (match_operand:V8HI 0 "register_operand" "=f")
+ (unspec:V8HI [(match_operand:V4SF 1 "register_operand" "f")
+ (match_operand:V4SF 2 "register_operand" "f")]
+ UNSPEC_MSA_FEXDO))]
+ "ISA_HAS_MSA"
+ "fexdo.h\t%w0,%w1,%w2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_float4")])
+
+(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))]
+ "ISA_HAS_MSA"
+ "fexdo.w\t%w0,%w1,%w2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_float4")])
+
+(define_insn "msa_fexupl_w"
+ [(set (match_operand:V4SF 0 "register_operand" "=f")
+ (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "f")]
+ UNSPEC_MSA_FEXUPL))]
+ "ISA_HAS_MSA"
+ "fexupl.w\t%w0,%w1"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_float4")])
+
+(define_insn "msa_fexupl_d"
+ [(set (match_operand:V2DF 0 "register_operand" "=f")
+ (unspec:V2DF [(match_operand:V4SF 1 "register_operand" "f")]
+ UNSPEC_MSA_FEXUPL))]
+ "ISA_HAS_MSA"
+ "fexupl.d\t%w0,%w1"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_float4")])
+
+(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))]
+ "ISA_HAS_MSA"
+ "fexupr.w\t%w0,%w1"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_float4")])
+
+(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))]
+ "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>"
+ [(set (pc) (if_then_else
+ (ne (unspec:SI [(match_operand:MSA 1 "register_operand" "f")]
+ UNSPEC_MSA_BNZ_V)
+ (match_operand:SI 2 "const_0_operand"))
+ (label_ref (match_operand 0))
+ (pc)))]
+ "ISA_HAS_MSA"
+ {
+ return mips_output_conditional_branch (insn, operands,
+ MIPS_BRANCH ("bnz.v", "%w1,%0"),
+ MIPS_BRANCH ("bz.v", "%w1,%0"));
+ }
+ [(set_attr "type" "branch")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_store4")])
+
+(define_expand "msa_bnz_v_<msafmt_f>"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (unspec:SI [(match_operand:MSA 1 "register_operand" "f")]
+ UNSPEC_MSA_TSTNZ_V))]
+ "ISA_HAS_MSA"
+ {
+ mips_expand_msa_branch (operands, gen_msa_branch_nz_v_<MSA:msafmt_f>);
+ DONE;
+ })
+
+(define_insn "msa_branchz_v_<msafmt_f>"
+ [(set (pc) (if_then_else
+ (eq (unspec:SI [(match_operand:MSA 1 "register_operand" "f")]
+ UNSPEC_MSA_BZ_V)
+ (match_operand:SI 2 "const_0_operand"))
+ (label_ref (match_operand 0))
+ (pc)))]
+ "ISA_HAS_MSA"
+ {
+ return mips_output_conditional_branch (insn, operands,
+ MIPS_BRANCH ("bz.v", "%w1,%0"),
+ MIPS_BRANCH ("bnz.v", "%w1,%0"));
+ }
+ [(set_attr "type" "branch")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_store4")])
+
+(define_expand "msa_bz_v_<msafmt_f>"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (unspec:SI [(match_operand:MSA 1 "register_operand" "f")]
+ UNSPEC_MSA_TSTZ_V))]
+ "ISA_HAS_MSA"
+ {
+ mips_expand_msa_branch (operands, gen_msa_branchz_v_<MSA:msafmt_f>);
+ DONE;
+ })
+
+(define_insn "msa_branchnz_<msafmt_f>"
+ [(set (pc) (if_then_else
+ (ne (unspec:SI [(match_operand:MSA 1 "register_operand" "f")]
+ UNSPEC_MSA_BNZ)
+ (match_operand:SI 2 "const_0_operand"))
+ (label_ref (match_operand 0))
+ (pc)))]
+ "ISA_HAS_MSA"
+ {
+ return mips_output_conditional_branch (insn, operands,
+ MIPS_BRANCH ("bnz.<msafmt>", "%w1,%0"),
+ MIPS_BRANCH ("bz.<msafmt>", "%w1,%0"));
+
+ }
+
+ [(set_attr "type" "branch")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_store4")])
+
+(define_expand "msa_bnz_<msafmt>"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (unspec:SI [(match_operand:IMSA 1 "register_operand" "f")]
+ UNSPEC_MSA_TSTNZ))]
+ "ISA_HAS_MSA"
+ {
+ mips_expand_msa_branch (operands, gen_msa_branchnz_<IMSA:msafmt>);
+ DONE;
+ })
+
+(define_insn "msa_branchz_<msafmt>"
+ [(set (pc) (if_then_else
+ (eq (unspec:SI [(match_operand:IMSA 1 "register_operand" "f")]
+ UNSPEC_MSA_BZ)
+ (match_operand:IMSA 2 "const_0_operand"))
+ (label_ref (match_operand 0))
+ (pc)))]
+ "ISA_HAS_MSA"
+ {
+ return mips_output_conditional_branch (insn, operands,
+ MIPS_BRANCH ("bz.<msafmt>", "%w1,%0"),
+ MIPS_BRANCH ("bnz.<msafmt>","%w1,%0"));
+ }
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")
+ (set_attr "msa_execunit" "msa_eu_store4")])
+
+(define_expand "msa_bz_<msafmt>"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (unspec:SI [(match_operand:IMSA 1 "register_operand" "f")]
+ UNSPEC_MSA_TSTZ))]
+ "ISA_HAS_MSA"
+ {
+ mips_expand_msa_branch (operands, gen_msa_branchz_<IMSA:msafmt>);
+ DONE;
+ })
+
+;; Note that this instruction treats scalar as vector registers freely.
+(define_insn "msa_cast_to_vector_<msafmt_f>"
+ [(set (match_operand:FMSA 0 "register_operand" "=f")
+ (unspec:FMSA [(match_operand:<UNITMODE> 1 "register_operand" "f")]
+ UNSPEC_MSA_CAST_TO_VECTOR))]
+ "ISA_HAS_MSA"
+{
+ if (REGNO (operands[0]) == REGNO (operands[1]))
+ return "nop\t# Cast %1 to %w0";
+ else
+ return "mov.<unitfmt>\t%0,%1\t# Cast %1 to %w0";
+}
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")])
+
+;; Note that this instruction treats vector as scalar registers freely.
+(define_insn "msa_cast_to_scalar_<msafmt_f>"
+ [(set (match_operand:<UNITMODE> 0 "register_operand" "=f")
+ (unspec:<UNITMODE> [(match_operand:FMSA 1 "register_operand" "f")]
+ UNSPEC_MSA_CAST_TO_SCALAR))]
+ "ISA_HAS_MSA"
+{
+ if (REGNO (operands[0]) == REGNO (operands[1]))
+ return "nop\t# Cast %w1 to %0";
+ else
+ return "mov.<unitfmt>\t%0,%1\t# Cast %w1 to %0";
+}
+ [(set_attr "type" "arith")
+ (set_attr "mode" "TI")])