Mercurial > hg > CbC > CbC_gcc
diff gcc/config/mips/mips-msa.md @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | |
children | 84e7813d76e9 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gcc/config/mips/mips-msa.md Fri Oct 27 22:46:09 2017 +0900 @@ -0,0 +1,2749 @@ +;; Machine Description for MIPS MSA ASE +;; Based on the MIPS MSA spec Revision 1.11 8/4/2014 +;; +;; Copyright (C) 2015-2017 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_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_BNEG + UNSPEC_MSA_BNEGI + UNSPEC_MSA_BSET + UNSPEC_MSA_BSETI + UNSPEC_MSA_BRANCH_V + UNSPEC_MSA_BRANCH + UNSPEC_MSA_CFCMSA + UNSPEC_MSA_CTCMSA + UNSPEC_MSA_FCAF + UNSPEC_MSA_FCLASS + UNSPEC_MSA_FCUNE + UNSPEC_MSA_FEXDO + UNSPEC_MSA_FEXP2 + UNSPEC_MSA_FEXUPL + UNSPEC_MSA_FEXUPR + UNSPEC_MSA_FFQL + UNSPEC_MSA_FFQR + UNSPEC_MSA_FLOG2 + 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_FTQ + UNSPEC_MSA_MADD_Q + UNSPEC_MSA_MADDR_Q + UNSPEC_MSA_MSUB_Q + UNSPEC_MSA_MSUBR_Q + UNSPEC_MSA_MUL_Q + UNSPEC_MSA_MULR_Q + UNSPEC_MSA_NLOC + UNSPEC_MSA_SAT_S + UNSPEC_MSA_SAT_U + UNSPEC_MSA_SLD + UNSPEC_MSA_SLDI + UNSPEC_MSA_SPLAT + UNSPEC_MSA_SPLATI + UNSPEC_MSA_SRAR + UNSPEC_MSA_SRARI + UNSPEC_MSA_SRLR + UNSPEC_MSA_SRLRI + UNSPEC_MSA_SUBS_S + UNSPEC_MSA_SUBS_U + UNSPEC_MSA_SUBSUU_S + UNSPEC_MSA_SUBSUS_U + UNSPEC_MSA_VSHF +]) + +;; All vector modes with 128 bits. +(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 used for splitting insert_d and copy_{u,s}.d. +(define_mode_iterator MSA_D [V2DI V2DF]) + +;; Only used for copy_{u,s}.w. +(define_mode_iterator MSA_W [V4SI V4SF]) + +;; Only integer modes. +(define_mode_iterator IMSA [V2DI V4SI V8HI V16QI]) + +;; As IMSA but excludes V16QI. +(define_mode_iterator IMSA_DWH [V2DI V4SI V8HI]) + +;; As IMSA but excludes V2DI. +(define_mode_iterator IMSA_WHB [V4SI V8HI V16QI]) + +;; Only integer modes equal or larger than a word. +(define_mode_iterator IMSA_DW [V2DI V4SI]) + +;; Only integer modes smaller than a word. +(define_mode_iterator IMSA_HB [V8HI V16QI]) + +;; Only integer modes for fixed-point madd_q/maddr_q. +(define_mode_iterator IMSA_WH [V4SI V8HI]) + +;; Only floating-point modes. +(define_mode_iterator FMSA [V2DF V4SF]) + +;; Only used for immediate set shuffle elements instruction. +(define_mode_iterator MSA_WHB_W [V4SI V8HI V16QI V4SF]) + +;; The attribute gives the integer vector mode with same size. +(define_mode_attr VIMODE + [(V2DF "V2DI") + (V4SF "V4SI") + (V2DI "V2DI") + (V4SI "V4SI") + (V8HI "V8HI") + (V16QI "V16QI")]) + +;; The attribute gives half modes for vector modes. +(define_mode_attr VHMODE + [(V8HI "V16QI") + (V4SI "V8HI") + (V2DI "V4SI")]) + +;; The attribute gives double modes for vector modes. +(define_mode_attr VDMODE + [(V4SI "V2DI") + (V8HI "V4SI") + (V16QI "V8HI")]) + +;; The attribute gives half modes with same number of elements for vector modes. +(define_mode_attr VTRUNCMODE + [(V8HI "V8QI") + (V4SI "V4HI") + (V2DI "V2SI")]) + +;; This attribute gives the mode of the result for "copy_s_b, copy_u_b" etc. +(define_mode_attr VRES + [(V2DF "DF") + (V4SF "SF") + (V2DI "DI") + (V4SI "SI") + (V8HI "SI") + (V16QI "SI")]) + +;; Only used with MSA_D iterator. +(define_mode_attr msa_d + [(V2DI "reg_or_0") + (V2DF "register")]) + +;; 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 suffix for MSA instructions. +(define_mode_attr msafmt + [(V2DF "d") + (V4SF "w") + (V2DI "d") + (V4SI "w") + (V8HI "h") + (V16QI "b")]) + +;; This attribute gives suffix for integers in VHMODE. +(define_mode_attr hmsafmt + [(V2DI "w") + (V4SI "h") + (V8HI "b")]) + +;; This attribute gives define_insn suffix for MSA instructions that 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")]) + +;; 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 represents bitmask needed for vec_merge using +;; "const_<bitmask>_operand". +(define_mode_attr bitmask + [(V2DF "exp_2") + (V4SF "exp_4") + (V2DI "exp_2") + (V4SI "exp_4") + (V8HI "exp_8") + (V16QI "exp_16")]) + +;; This attribute is used to form 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><unitmode>" + [(match_operand:MSA 0 "register_operand") + (match_operand:MSA 1 "")] + "ISA_HAS_MSA" +{ + mips_expand_vector_init (operands[0], operands[1]); + DONE; +}) + +;; pckev pattern with implicit type conversion. +(define_insn "vec_pack_trunc_<mode>" + [(set (match_operand:<VHMODE> 0 "register_operand" "=f") + (vec_concat:<VHMODE> + (truncate:<VTRUNCMODE> + (match_operand:IMSA_DWH 1 "register_operand" "f")) + (truncate:<VTRUNCMODE> + (match_operand:IMSA_DWH 2 "register_operand" "f"))))] + "ISA_HAS_MSA" + "pckev.<hmsafmt>\t%w0,%w2,%w1" + [(set_attr "type" "simd_permute") + (set_attr "mode" "<MODE>")]) + +(define_expand "vec_unpacks_hi_v4sf" + [(set (match_operand:V2DF 0 "register_operand" "=f") + (float_extend:V2DF + (vec_select:V2SF + (match_operand:V4SF 1 "register_operand" "f") + (match_dup 2))))] + "ISA_HAS_MSA" +{ + operands[2] = mips_msa_vec_parallel_const_half (V4SFmode, true/*high_p*/); +}) + +(define_expand "vec_unpacks_lo_v4sf" + [(set (match_operand:V2DF 0 "register_operand" "=f") + (float_extend:V2DF + (vec_select:V2SF + (match_operand:V4SF 1 "register_operand" "f") + (match_dup 2))))] + "ISA_HAS_MSA" +{ + operands[2] = mips_msa_vec_parallel_const_half (V4SFmode, false/*high_p*/); +}) + +(define_expand "vec_unpacks_hi_<mode>" + [(match_operand:<VDMODE> 0 "register_operand") + (match_operand:IMSA_WHB 1 "register_operand")] + "ISA_HAS_MSA" +{ + mips_expand_vec_unpack (operands, false/*unsigned_p*/, true/*high_p*/); + DONE; +}) + +(define_expand "vec_unpacks_lo_<mode>" + [(match_operand:<VDMODE> 0 "register_operand") + (match_operand:IMSA_WHB 1 "register_operand")] + "ISA_HAS_MSA" +{ + mips_expand_vec_unpack (operands, false/*unsigned_p*/, false/*high_p*/); + DONE; +}) + +(define_expand "vec_unpacku_hi_<mode>" + [(match_operand:<VDMODE> 0 "register_operand") + (match_operand:IMSA_WHB 1 "register_operand")] + "ISA_HAS_MSA" +{ + mips_expand_vec_unpack (operands, true/*unsigned_p*/, true/*high_p*/); + DONE; +}) + +(define_expand "vec_unpacku_lo_<mode>" + [(match_operand:<VDMODE> 0 "register_operand") + (match_operand:IMSA_WHB 1 "register_operand")] + "ISA_HAS_MSA" +{ + mips_expand_vec_unpack (operands, true/*unsigned_p*/, false/*high_p*/); + DONE; +}) + +(define_expand "vec_extract<mode><unitmode>" + [(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><unitmode>" + [(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 = INTVAL (operands[2]); + + if (val == 0) + temp = operands[1]; + else + { + /* We need to do the SLDI operation in V16QImode and adjust + operands[2] accordingly. */ + rtx wd = gen_reg_rtx (V16QImode); + rtx ws = gen_reg_rtx (V16QImode); + emit_move_insn (ws, gen_rtx_SUBREG (V16QImode, operands[1], 0)); + rtx n = GEN_INT (val * GET_MODE_SIZE (<UNITMODE>mode)); + gcc_assert (INTVAL (n) < GET_MODE_NUNITS (V16QImode)); + emit_insn (gen_msa_sldi_b (wd, ws, ws, n)); + temp = gen_reg_rtx (<MODE>mode); + emit_move_insn (temp, gen_rtx_SUBREG (<MODE>mode, wd, 0)); + } + emit_insn (gen_msa_vec_extract_<msafmt_f> (operands[0], temp)); + DONE; +}) + +(define_insn_and_split "msa_vec_extract_<msafmt_f>" + [(set (match_operand:<UNITMODE> 0 "register_operand" "=f") + (vec_select:<UNITMODE> + (match_operand:FMSA 1 "register_operand" "f") + (parallel [(const_int 0)])))] + "ISA_HAS_MSA" + "#" + "&& reload_completed" + [(set (match_dup 0) (match_dup 1))] +{ + /* An MSA register cannot be reinterpreted as a single precision + register when using -mno-odd-spreg and the MSA register is + an odd number. */ + if (<UNITMODE>mode == SFmode && !TARGET_ODD_SPREG + && (REGNO (operands[1]) & 1)) + { + emit_move_insn (gen_rtx_REG (<MODE>mode, REGNO (operands[0])), + operands[1]); + operands[1] = operands[0]; + } + else + operands[1] = gen_rtx_REG (<UNITMODE>mode, REGNO (operands[1])); +} + [(set_attr "move_type" "fmove") + (set_attr "mode" "<UNITMODE>")]) + +(define_expand "vec_set<mode>" + [(match_operand:IMSA 0 "register_operand") + (match_operand:<UNITMODE> 1 "reg_or_0_operand") + (match_operand 2 "const_<indeximm>_operand")] + "ISA_HAS_MSA" +{ + rtx index = GEN_INT (1 << INTVAL (operands[2])); + emit_insn (gen_msa_insert_<msafmt> (operands[0], operands[1], + operands[0], index)); + 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" +{ + rtx index = GEN_INT (1 << INTVAL (operands[2])); + emit_insn (gen_msa_insve_<msafmt_f>_scalar (operands[0], operands[1], + operands[0], index)); + DONE; +}) + +(define_expand "vcondu<MSA:mode><IMSA:mode>" + [(match_operand:MSA 0 "register_operand") + (match_operand:MSA 1 "reg_or_m1_operand") + (match_operand:MSA 2 "reg_or_0_operand") + (match_operator 3 "" + [(match_operand:IMSA 4 "register_operand") + (match_operand:IMSA 5 "register_operand")])] + "ISA_HAS_MSA + && (GET_MODE_NUNITS (<MSA:MODE>mode) == GET_MODE_NUNITS (<IMSA:MODE>mode))" +{ + mips_expand_vec_cond_expr (<MSA:MODE>mode, <MSA:VIMODE>mode, operands); + DONE; +}) + +(define_expand "vcond<MSA:mode><MSA_2:mode>" + [(match_operand:MSA 0 "register_operand") + (match_operand:MSA 1 "reg_or_m1_operand") + (match_operand:MSA 2 "reg_or_0_operand") + (match_operator 3 "" + [(match_operand:MSA_2 4 "register_operand") + (match_operand:MSA_2 5 "register_operand")])] + "ISA_HAS_MSA + && (GET_MODE_NUNITS (<MSA:MODE>mode) == GET_MODE_NUNITS (<MSA_2:MODE>mode))" +{ + mips_expand_vec_cond_expr (<MSA:MODE>mode, <MSA:VIMODE>mode, operands); + DONE; +}) + +(define_insn "msa_insert_<msafmt_f>" + [(set (match_operand:MSA 0 "register_operand" "=f") + (vec_merge:MSA + (vec_duplicate:MSA + (match_operand:<UNITMODE> 1 "reg_or_0_operand" "dJ")) + (match_operand:MSA 2 "register_operand" "0") + (match_operand 3 "const_<bitmask>_operand" "")))] + "ISA_HAS_MSA" +{ + if (!TARGET_64BIT && (<MODE>mode == V2DImode || <MODE>mode == V2DFmode)) + return "#"; + else + return "insert.<msafmt>\t%w0[%y3],%z1"; +} + [(set_attr "type" "simd_insert") + (set_attr "mode" "<MODE>")]) + +(define_split + [(set (match_operand:MSA_D 0 "register_operand") + (vec_merge:MSA_D + (vec_duplicate:MSA_D + (match_operand:<UNITMODE> 1 "<MSA_D:msa_d>_operand")) + (match_operand:MSA_D 2 "register_operand") + (match_operand 3 "const_<bitmask>_operand")))] + "reload_completed && ISA_HAS_MSA && !TARGET_64BIT" + [(const_int 0)] +{ + mips_split_msa_insert_d (operands[0], operands[2], operands[3], operands[1]); + DONE; +}) + +(define_insn "msa_insve_<msafmt_f>" + [(set (match_operand:MSA 0 "register_operand" "=f") + (vec_merge:MSA + (vec_duplicate:MSA + (vec_select:<UNITMODE> + (match_operand:MSA 1 "register_operand" "f") + (parallel [(const_int 0)]))) + (match_operand:MSA 2 "register_operand" "0") + (match_operand 3 "const_<bitmask>_operand" "")))] + "ISA_HAS_MSA" + "insve.<msafmt>\t%w0[%y3],%w1[0]" + [(set_attr "type" "simd_insert") + (set_attr "mode" "<MODE>")]) + +;; Operand 3 is a scalar. +(define_insn "msa_insve_<msafmt_f>_scalar" + [(set (match_operand:FMSA 0 "register_operand" "=f") + (vec_merge:FMSA + (vec_duplicate:FMSA + (match_operand:<UNITMODE> 1 "register_operand" "f")) + (match_operand:FMSA 2 "register_operand" "0") + (match_operand 3 "const_<bitmask>_operand" "")))] + "ISA_HAS_MSA" + "insve.<msafmt>\t%w0[%y3],%w1[0]" + [(set_attr "type" "simd_insert") + (set_attr "mode" "<MODE>")]) + +(define_insn "msa_copy_<su>_<msafmt>" + [(set (match_operand:<VRES> 0 "register_operand" "=d") + (any_extend:<VRES> + (vec_select:<UNITMODE> + (match_operand:IMSA_HB 1 "register_operand" "f") + (parallel [(match_operand 2 "const_<indeximm>_operand" "")]))))] + "ISA_HAS_MSA" + "copy_<su>.<msafmt>\t%0,%w1[%2]" + [(set_attr "type" "simd_copy") + (set_attr "mode" "<MODE>")]) + +(define_insn "msa_copy_u_w" + [(set (match_operand:DI 0 "register_operand" "=d") + (zero_extend:DI + (vec_select:SI + (match_operand:V4SI 1 "register_operand" "f") + (parallel [(match_operand 2 "const_0_to_3_operand" "")]))))] + "ISA_HAS_MSA && TARGET_64BIT" + "copy_u.w\t%0,%w1[%2]" + [(set_attr "type" "simd_copy") + (set_attr "mode" "V4SI")]) + +(define_insn "msa_copy_s_<msafmt_f>_64bit" + [(set (match_operand:DI 0 "register_operand" "=d") + (sign_extend:DI + (vec_select:<UNITMODE> + (match_operand:MSA_W 1 "register_operand" "f") + (parallel [(match_operand 2 "const_<indeximm>_operand" "")]))))] + "ISA_HAS_MSA && TARGET_64BIT" + "copy_s.<msafmt>\t%0,%w1[%2]" + [(set_attr "type" "simd_copy") + (set_attr "mode" "<MODE>")]) + +(define_insn "msa_copy_s_<msafmt_f>" + [(set (match_operand:<UNITMODE> 0 "register_operand" "=d") + (vec_select:<UNITMODE> + (match_operand:MSA_W 1 "register_operand" "f") + (parallel [(match_operand 2 "const_<indeximm>_operand" "")])))] + "ISA_HAS_MSA" + "copy_s.<msafmt>\t%0,%w1[%2]" + [(set_attr "type" "simd_copy") + (set_attr "mode" "<MODE>")]) + +(define_insn_and_split "msa_copy_s_<msafmt_f>" + [(set (match_operand:<UNITMODE> 0 "register_operand" "=d") + (vec_select:<UNITMODE> + (match_operand:MSA_D 1 "register_operand" "f") + (parallel [(match_operand 2 "const_<indeximm>_operand" "")])))] + "ISA_HAS_MSA" +{ + if (TARGET_64BIT) + return "copy_s.<msafmt>\t%0,%w1[%2]"; + else + return "#"; +} + "reload_completed && ISA_HAS_MSA && !TARGET_64BIT" + [(const_int 0)] +{ + mips_split_msa_copy_d (operands[0], operands[1], operands[2], + gen_msa_copy_s_w); + DONE; +} + [(set_attr "type" "simd_copy") + (set_attr "mode" "<MODE>")]) + +(define_expand "vec_perm_const<mode>" + [(match_operand:MSA 0 "register_operand") + (match_operand:MSA 1 "register_operand") + (match_operand:MSA 2 "register_operand") + (match_operand:<VIMODE> 3 "")] + "ISA_HAS_MSA" +{ + if (mips_expand_vec_perm_const (operands)) + DONE; + else + FAIL; +}) + +(define_expand "abs<mode>2" + [(match_operand:IMSA 0 "register_operand" "=f") + (abs:IMSA (match_operand:IMSA 1 "register_operand" "f"))] + "ISA_HAS_MSA" +{ + rtx reg = gen_reg_rtx (<MODE>mode); + emit_move_insn (reg, CONST0_RTX (<MODE>mode)); + emit_insn (gen_msa_add_a_<msafmt> (operands[0], operands[1], reg)); + DONE; +}) + +(define_expand "neg<mode>2" + [(set (match_operand:MSA 0 "register_operand") + (minus:MSA (match_dup 2) + (match_operand:MSA 1 "register_operand")))] + "ISA_HAS_MSA" +{ + rtx reg = gen_reg_rtx (<MODE>mode); + emit_move_insn (reg, CONST0_RTX (<MODE>mode)); + operands[2] = reg; +}) + +(define_expand "msa_ldi<mode>" + [(match_operand:IMSA 0 "register_operand") + (match_operand 1 "const_imm10_operand")] + "ISA_HAS_MSA" +{ + if (<MODE>mode == V16QImode) + operands[1] = GEN_INT (trunc_int_for_mode (INTVAL (operands[1]), + <UNITMODE>mode)); + emit_move_insn (operands[0], + mips_gen_const_int_vector (<MODE>mode, INTVAL (operands[1]))); + DONE; +}) + +(define_insn "vec_perm<mode>" + [(set (match_operand:MSA 0 "register_operand" "=f") + (unspec:MSA [(match_operand:MSA 1 "register_operand" "f") + (match_operand:MSA 2 "register_operand" "f") + (match_operand:<VIMODE> 3 "register_operand" "0")] + UNSPEC_MSA_VSHF))] + "ISA_HAS_MSA" + "vshf.<msafmt>\t%w0,%w2,%w1" + [(set_attr "type" "simd_sld") + (set_attr "mode" "<MODE>")]) + +(define_expand "mov<mode>" + [(set (match_operand:MSA 0) + (match_operand:MSA 1))] + "ISA_HAS_MSA" +{ + if (mips_legitimize_move (<MODE>mode, operands[0], operands[1])) + DONE; +}) + +(define_expand "movmisalign<mode>" + [(set (match_operand:MSA 0) + (match_operand:MSA 1))] + "ISA_HAS_MSA" +{ + if (mips_legitimize_move (<MODE>mode, operands[0], operands[1])) + DONE; +}) + +;; 128-bit MSA modes can only exist in MSA registers or memory. An exception +;; is allowing MSA modes for GP registers for arguments and return values. +(define_insn "mov<mode>_msa" + [(set (match_operand:MSA 0 "nonimmediate_operand" "=f,f,R,*d,*f") + (match_operand:MSA 1 "move_operand" "fYGYI,R,f,*f,*d"))] + "ISA_HAS_MSA" + { return mips_output_move (operands[0], operands[1]); } + [(set_attr "type" "simd_move,simd_load,simd_store,simd_copy,simd_insert") + (set_attr "mode" "<MODE>")]) + +(define_split + [(set (match_operand:MSA 0 "nonimmediate_operand") + (match_operand:MSA 1 "move_operand"))] + "reload_completed && ISA_HAS_MSA + && mips_split_move_insn_p (operands[0], operands[1], insn)" + [(const_int 0)] +{ + 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: + return "addvi.<msafmt>\t%w0,%w1,%E2"; + default: + gcc_unreachable (); + } +} + [(set_attr "alu_type" "simd_add") + (set_attr "type" "simd_int_arith") + (set_attr "mode" "<MODE>")]) + +(define_insn "sub<mode>3" + [(set (match_operand:IMSA 0 "register_operand" "=f,f") + (minus:IMSA + (match_operand:IMSA 1 "register_operand" "f,f") + (match_operand:IMSA 2 "reg_or_vector_same_uimm5_operand" "f,Uuv5")))] + "ISA_HAS_MSA" + "@ + subv.<msafmt>\t%w0,%w1,%w2 + subvi.<msafmt>\t%w0,%w1,%E2" + [(set_attr "alu_type" "simd_add") + (set_attr "type" "simd_int_arith") + (set_attr "mode" "<MODE>")]) + +(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" "simd_mul") + (set_attr "mode" "<MODE>")]) + +(define_insn "msa_maddv_<msafmt>" + [(set (match_operand:IMSA 0 "register_operand" "=f") + (plus:IMSA (mult:IMSA (match_operand:IMSA 1 "register_operand" "f") + (match_operand:IMSA 2 "register_operand" "f")) + (match_operand:IMSA 3 "register_operand" "0")))] + "ISA_HAS_MSA" + "maddv.<msafmt>\t%w0,%w1,%w2" + [(set_attr "type" "simd_mul") + (set_attr "mode" "<MODE>")]) + +(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" "simd_mul") + (set_attr "mode" "<MODE>")]) + +(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" "simd_div") + (set_attr "mode" "<MODE>")]) + +(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" "simd_div") + (set_attr "mode" "<MODE>")]) + +(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" "simd_div") + (set_attr "mode" "<MODE>")]) + +(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" "simd_div") + (set_attr "mode" "<MODE>")]) + +(define_insn "xor<mode>3" + [(set (match_operand:IMSA 0 "register_operand" "=f,f,f") + (xor:IMSA + (match_operand:IMSA 1 "register_operand" "f,f,f") + (match_operand:IMSA 2 "reg_or_vector_same_val_operand" "f,YC,Urv8")))] + "ISA_HAS_MSA" + "@ + xor.v\t%w0,%w1,%w2 + bnegi.%v0\t%w0,%w1,%V2 + xori.b\t%w0,%w1,%B2" + [(set_attr "type" "simd_logic,simd_bit,simd_logic") + (set_attr "mode" "<MODE>")]) + +(define_insn "ior<mode>3" + [(set (match_operand:IMSA 0 "register_operand" "=f,f,f") + (ior:IMSA + (match_operand:IMSA 1 "register_operand" "f,f,f") + (match_operand:IMSA 2 "reg_or_vector_same_val_operand" "f,YC,Urv8")))] + "ISA_HAS_MSA" + "@ + or.v\t%w0,%w1,%w2 + bseti.%v0\t%w0,%w1,%V2 + ori.b\t%w0,%w1,%B2" + [(set_attr "type" "simd_logic,simd_bit,simd_logic") + (set_attr "mode" "<MODE>")]) + +(define_insn "and<mode>3" + [(set (match_operand:IMSA 0 "register_operand" "=f,f,f") + (and:IMSA + (match_operand:IMSA 1 "register_operand" "f,f,f") + (match_operand:IMSA 2 "reg_or_vector_same_val_operand" "f,YZ,Urv8")))] + "ISA_HAS_MSA" +{ + switch (which_alternative) + { + case 0: + return "and.v\t%w0,%w1,%w2"; + case 1: + { + rtx elt0 = CONST_VECTOR_ELT (operands[2], 0); + unsigned HOST_WIDE_INT val = ~UINTVAL (elt0); + operands[2] = mips_gen_const_int_vector (<MODE>mode, val & (-val)); + return "bclri.%v0\t%w0,%w1,%V2"; + } + case 2: + return "andi.b\t%w0,%w1,%B2"; + default: + gcc_unreachable (); + } +} + [(set_attr "type" "simd_logic,simd_bit,simd_logic") + (set_attr "mode" "<MODE>")]) + +(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 "type" "simd_logic") + (set_attr "mode" "TI")]) + +(define_insn "vlshr<mode>3" + [(set (match_operand:IMSA 0 "register_operand" "=f,f") + (lshiftrt:IMSA + (match_operand:IMSA 1 "register_operand" "f,f") + (match_operand:IMSA 2 "reg_or_vector_same_uimm6_operand" "f,Uuv6")))] + "ISA_HAS_MSA" + "@ + srl.<msafmt>\t%w0,%w1,%w2 + srli.<msafmt>\t%w0,%w1,%E2" + [(set_attr "type" "simd_shift") + (set_attr "mode" "<MODE>")]) + +(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" + "@ + sra.<msafmt>\t%w0,%w1,%w2 + srai.<msafmt>\t%w0,%w1,%E2" + [(set_attr "type" "simd_shift") + (set_attr "mode" "<MODE>")]) + +(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" + "@ + sll.<msafmt>\t%w0,%w1,%w2 + slli.<msafmt>\t%w0,%w1,%E2" + [(set_attr "type" "simd_shift") + (set_attr "mode" "<MODE>")]) + +;; 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" "simd_fadd") + (set_attr "mode" "<MODE>")]) + +(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" "simd_fadd") + (set_attr "mode" "<MODE>")]) + +(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" "simd_fmul") + (set_attr "mode" "<MODE>")]) + +(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" "simd_fdiv") + (set_attr "mode" "<MODE>")]) + +(define_insn "fma<mode>4" + [(set (match_operand:FMSA 0 "register_operand" "=f") + (fma:FMSA (match_operand:FMSA 1 "register_operand" "f") + (match_operand:FMSA 2 "register_operand" "f") + (match_operand:FMSA 3 "register_operand" "0")))] + "ISA_HAS_MSA" + "fmadd.<msafmt>\t%w0,%w1,%w2" + [(set_attr "type" "simd_fmadd") + (set_attr "mode" "<MODE>")]) + +(define_insn "fnma<mode>4" + [(set (match_operand:FMSA 0 "register_operand" "=f") + (fma:FMSA (neg:FMSA (match_operand:FMSA 1 "register_operand" "f")) + (match_operand:FMSA 2 "register_operand" "f") + (match_operand:FMSA 3 "register_operand" "0")))] + "ISA_HAS_MSA" + "fmsub.<msafmt>\t%w0,%w1,%w2" + [(set_attr "type" "simd_fmadd") + (set_attr "mode" "<MODE>")]) + +(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" "simd_fdiv") + (set_attr "mode" "<MODE>")]) + +;; 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" "simd_int_arith") + (set_attr "mode" "<MODE>")]) + +(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" "simd_int_arith") + (set_attr "mode" "<MODE>")]) + +(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" "simd_int_arith") + (set_attr "mode" "<MODE>")]) + +(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" "simd_int_arith") + (set_attr "mode" "<MODE>")]) + +(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" "simd_int_arith") + (set_attr "mode" "<MODE>")]) + +(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" "simd_int_arith") + (set_attr "mode" "<MODE>")]) + +(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" "simd_int_arith") + (set_attr "mode" "<MODE>")]) + +(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" "simd_int_arith") + (set_attr "mode" "<MODE>")]) + +(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" "simd_int_arith") + (set_attr "mode" "<MODE>")]) + +(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" "simd_int_arith") + (set_attr "mode" "<MODE>")]) + +(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" "simd_bit") + (set_attr "mode" "<MODE>")]) + +(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" "simd_bit") + (set_attr "mode" "<MODE>")]) + +(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" "simd_bitins") + (set_attr "mode" "<MODE>")]) + +(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" "simd_bitins") + (set_attr "mode" "<MODE>")]) + +(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" "simd_bitins") + (set_attr "mode" "<MODE>")]) + +(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" "simd_bitins") + (set_attr "mode" "<MODE>")]) + +(define_insn "msa_bmnz_<msafmt>" + [(set (match_operand:IMSA 0 "register_operand" "=f,f") + (ior:IMSA (and:IMSA (match_operand:IMSA 2 "register_operand" "f,f") + (match_operand:IMSA 3 "reg_or_vector_same_val_operand" "f,Urv8")) + (and:IMSA (not:IMSA (match_dup 3)) + (match_operand:IMSA 1 "register_operand" "0,0"))))] + "ISA_HAS_MSA" + "@ + bmnz.v\t%w0,%w2,%w3 + bmnzi.b\t%w0,%w2,%B3" + [(set_attr "type" "simd_bitmov") + (set_attr "mode" "<MODE>")]) + +(define_insn "msa_bmz_<msafmt>" + [(set (match_operand:IMSA 0 "register_operand" "=f,f") + (ior:IMSA (and:IMSA (not:IMSA + (match_operand:IMSA 3 "reg_or_vector_same_val_operand" "f,Urv8")) + (match_operand:IMSA 2 "register_operand" "f,f")) + (and:IMSA (match_operand:IMSA 1 "register_operand" "0,0") + (match_dup 3))))] + "ISA_HAS_MSA" + "@ + bmz.v\t%w0,%w2,%w3 + bmzi.b\t%w0,%w2,%B3" + [(set_attr "type" "simd_bitmov") + (set_attr "mode" "<MODE>")]) + +(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" "simd_bit") + (set_attr "mode" "<MODE>")]) + +(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" "simd_bit") + (set_attr "mode" "<MODE>")]) + +(define_insn "msa_bsel_<msafmt>" + [(set (match_operand:IMSA 0 "register_operand" "=f,f") + (ior:IMSA (and:IMSA (not:IMSA + (match_operand:IMSA 1 "register_operand" "0,0")) + (match_operand:IMSA 2 "register_operand" "f,f")) + (and:IMSA (match_dup 1) + (match_operand:IMSA 3 "reg_or_vector_same_val_operand" "f,Urv8"))))] + "ISA_HAS_MSA" + "@ + bsel.v\t%w0,%w2,%w3 + bseli.b\t%w0,%w2,%B3" + [(set_attr "type" "simd_bitmov") + (set_attr "mode" "<MODE>")]) + +(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" "simd_bit") + (set_attr "mode" "<MODE>")]) + +(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" "simd_bit") + (set_attr "mode" "<MODE>")]) + +(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,f") + (ICC:IMSA + (match_operand:IMSA 1 "register_operand" "f,f") + (match_operand:IMSA 2 "reg_or_vector_same_<ICC:cmpi>imm5_operand" "f,U<ICC:cmpi>v5")))] + "ISA_HAS_MSA" + "@ + c<ICC:icc>.<IMSA:msafmt>\t%w0,%w1,%w2 + c<ICC:icci>.<IMSA:msafmt>\t%w0,%w1,%E2" + [(set_attr "type" "simd_int_arith") + (set_attr "mode" "<MODE>")]) + +(define_insn "msa_dotp_<su>_d" + [(set (match_operand:V2DI 0 "register_operand" "=f") + (plus:V2DI + (mult:V2DI + (any_extend:V2DI + (vec_select:V2SI + (match_operand:V4SI 1 "register_operand" "%f") + (parallel [(const_int 0) (const_int 2)]))) + (any_extend:V2DI + (vec_select:V2SI + (match_operand:V4SI 2 "register_operand" "f") + (parallel [(const_int 0) (const_int 2)])))) + (mult:V2DI + (any_extend:V2DI + (vec_select:V2SI (match_dup 1) + (parallel [(const_int 1) (const_int 3)]))) + (any_extend:V2DI + (vec_select:V2SI (match_dup 2) + (parallel [(const_int 1) (const_int 3)]))))))] + "ISA_HAS_MSA" + "dotp_<su>.d\t%w0,%w1,%w2" + [(set_attr "type" "simd_mul") + (set_attr "mode" "V2DI")]) + +(define_insn "msa_dotp_<su>_w" + [(set (match_operand:V4SI 0 "register_operand" "=f") + (plus:V4SI + (mult:V4SI + (any_extend:V4SI + (vec_select:V4HI + (match_operand:V8HI 1 "register_operand" "%f") + (parallel [(const_int 0) (const_int 2) + (const_int 4) (const_int 6)]))) + (any_extend:V4SI + (vec_select:V4HI + (match_operand:V8HI 2 "register_operand" "f") + (parallel [(const_int 0) (const_int 2) + (const_int 4) (const_int 6)])))) + (mult:V4SI + (any_extend:V4SI + (vec_select:V4HI (match_dup 1) + (parallel [(const_int 1) (const_int 3) + (const_int 5) (const_int 7)]))) + (any_extend:V4SI + (vec_select:V4HI (match_dup 2) + (parallel [(const_int 1) (const_int 3) + (const_int 5) (const_int 7)]))))))] + "ISA_HAS_MSA" + "dotp_<su>.w\t%w0,%w1,%w2" + [(set_attr "type" "simd_mul") + (set_attr "mode" "V4SI")]) + +(define_insn "msa_dotp_<su>_h" + [(set (match_operand:V8HI 0 "register_operand" "=f") + (plus:V8HI + (mult:V8HI + (any_extend:V8HI + (vec_select:V8QI + (match_operand:V16QI 1 "register_operand" "%f") + (parallel [(const_int 0) (const_int 2) + (const_int 4) (const_int 6) + (const_int 8) (const_int 10) + (const_int 12) (const_int 14)]))) + (any_extend:V8HI + (vec_select:V8QI + (match_operand:V16QI 2 "register_operand" "f") + (parallel [(const_int 0) (const_int 2) + (const_int 4) (const_int 6) + (const_int 8) (const_int 10) + (const_int 12) (const_int 14)])))) + (mult:V8HI + (any_extend:V8HI + (vec_select:V8QI (match_dup 1) + (parallel [(const_int 1) (const_int 3) + (const_int 5) (const_int 7) + (const_int 9) (const_int 11) + (const_int 13) (const_int 15)]))) + (any_extend:V8HI + (vec_select:V8QI (match_dup 2) + (parallel [(const_int 1) (const_int 3) + (const_int 5) (const_int 7) + (const_int 9) (const_int 11) + (const_int 13) (const_int 15)]))))))] + "ISA_HAS_MSA" + "dotp_<su>.h\t%w0,%w1,%w2" + [(set_attr "type" "simd_mul") + (set_attr "mode" "V8HI")]) + +(define_insn "msa_dpadd_<su>_d" + [(set (match_operand:V2DI 0 "register_operand" "=f") + (plus:V2DI + (plus:V2DI + (mult:V2DI + (any_extend:V2DI + (vec_select:V2SI + (match_operand:V4SI 2 "register_operand" "%f") + (parallel [(const_int 0) (const_int 2)]))) + (any_extend:V2DI + (vec_select:V2SI + (match_operand:V4SI 3 "register_operand" "f") + (parallel [(const_int 0) (const_int 2)])))) + (mult:V2DI + (any_extend:V2DI + (vec_select:V2SI (match_dup 2) + (parallel [(const_int 1) (const_int 3)]))) + (any_extend:V2DI + (vec_select:V2SI (match_dup 3) + (parallel [(const_int 1) (const_int 3)]))))) + (match_operand:V2DI 1 "register_operand" "0")))] + "ISA_HAS_MSA" + "dpadd_<su>.d\t%w0,%w2,%w3" + [(set_attr "type" "simd_mul") + (set_attr "mode" "V2DI")]) + +(define_insn "msa_dpadd_<su>_w" + [(set (match_operand:V4SI 0 "register_operand" "=f") + (plus:V4SI + (plus:V4SI + (mult:V4SI + (any_extend:V4SI + (vec_select:V4HI + (match_operand:V8HI 2 "register_operand" "%f") + (parallel [(const_int 0) (const_int 2) + (const_int 4) (const_int 6)]))) + (any_extend:V4SI + (vec_select:V4HI + (match_operand:V8HI 3 "register_operand" "f") + (parallel [(const_int 0) (const_int 2) + (const_int 4) (const_int 6)])))) + (mult:V4SI + (any_extend:V4SI + (vec_select:V4HI (match_dup 2) + (parallel [(const_int 1) (const_int 3) + (const_int 5) (const_int 7)]))) + (any_extend:V4SI + (vec_select:V4HI (match_dup 3) + (parallel [(const_int 1) (const_int 3) + (const_int 5) (const_int 7)]))))) + (match_operand:V4SI 1 "register_operand" "0")))] + "ISA_HAS_MSA" + "dpadd_<su>.w\t%w0,%w2,%w3" + [(set_attr "type" "simd_mul") + (set_attr "mode" "V4SI")]) + +(define_insn "msa_dpadd_<su>_h" + [(set (match_operand:V8HI 0 "register_operand" "=f") + (plus:V8HI + (plus:V8HI + (mult:V8HI + (any_extend:V8HI + (vec_select:V8QI + (match_operand:V16QI 2 "register_operand" "%f") + (parallel [(const_int 0) (const_int 2) + (const_int 4) (const_int 6) + (const_int 8) (const_int 10) + (const_int 12) (const_int 14)]))) + (any_extend:V8HI + (vec_select:V8QI + (match_operand:V16QI 3 "register_operand" "f") + (parallel [(const_int 0) (const_int 2) + (const_int 4) (const_int 6) + (const_int 8) (const_int 10) + (const_int 12) (const_int 14)])))) + (mult:V8HI + (any_extend:V8HI + (vec_select:V8QI (match_dup 2) + (parallel [(const_int 1) (const_int 3) + (const_int 5) (const_int 7) + (const_int 9) (const_int 11) + (const_int 13) (const_int 15)]))) + (any_extend:V8HI + (vec_select:V8QI (match_dup 3) + (parallel [(const_int 1) (const_int 3) + (const_int 5) (const_int 7) + (const_int 9) (const_int 11) + (const_int 13) (const_int 15)]))))) + (match_operand:V8HI 1 "register_operand" "0")))] + "ISA_HAS_MSA" + "dpadd_<su>.h\t%w0,%w2,%w3" + [(set_attr "type" "simd_mul") + (set_attr "mode" "V8HI")]) + +(define_insn "msa_dpsub_<su>_d" + [(set (match_operand:V2DI 0 "register_operand" "=f") + (minus:V2DI + (match_operand:V2DI 1 "register_operand" "0") + (plus:V2DI + (mult:V2DI + (any_extend:V2DI + (vec_select:V2SI + (match_operand:V4SI 2 "register_operand" "%f") + (parallel [(const_int 0) (const_int 2)]))) + (any_extend:V2DI + (vec_select:V2SI + (match_operand:V4SI 3 "register_operand" "f") + (parallel [(const_int 0) (const_int 2)])))) + (mult:V2DI + (any_extend:V2DI + (vec_select:V2SI (match_dup 2) + (parallel [(const_int 1) (const_int 3)]))) + (any_extend:V2DI + (vec_select:V2SI (match_dup 3) + (parallel [(const_int 1) (const_int 3)])))))))] + "ISA_HAS_MSA" + "dpsub_<su>.d\t%w0,%w2,%w3" + [(set_attr "type" "simd_mul") + (set_attr "mode" "V2DI")]) + +(define_insn "msa_dpsub_<su>_w" + [(set (match_operand:V4SI 0 "register_operand" "=f") + (minus:V4SI + (match_operand:V4SI 1 "register_operand" "0") + (plus:V4SI + (mult:V4SI + (any_extend:V4SI + (vec_select:V4HI + (match_operand:V8HI 2 "register_operand" "%f") + (parallel [(const_int 0) (const_int 2) + (const_int 4) (const_int 6)]))) + (any_extend:V4SI + (vec_select:V4HI + (match_operand:V8HI 3 "register_operand" "f") + (parallel [(const_int 0) (const_int 2) + (const_int 4) (const_int 6)])))) + (mult:V4SI + (any_extend:V4SI + (vec_select:V4HI (match_dup 2) + (parallel [(const_int 1) (const_int 3) + (const_int 5) (const_int 7)]))) + (any_extend:V4SI + (vec_select:V4HI (match_dup 3) + (parallel [(const_int 1) (const_int 3) + (const_int 5) (const_int 7)])))))))] + "ISA_HAS_MSA" + "dpsub_<su>.w\t%w0,%w2,%w3" + [(set_attr "type" "simd_mul") + (set_attr "mode" "V4SI")]) + +(define_insn "msa_dpsub_<su>_h" + [(set (match_operand:V8HI 0 "register_operand" "=f") + (minus:V8HI + (match_operand:V8HI 1 "register_operand" "0") + (plus:V8HI + (mult:V8HI + (any_extend:V8HI + (vec_select:V8QI + (match_operand:V16QI 2 "register_operand" "%f") + (parallel [(const_int 0) (const_int 2) + (const_int 4) (const_int 6) + (const_int 8) (const_int 10) + (const_int 12) (const_int 14)]))) + (any_extend:V8HI + (vec_select:V8QI + (match_operand:V16QI 3 "register_operand" "f") + (parallel [(const_int 0) (const_int 2) + (const_int 4) (const_int 6) + (const_int 8) (const_int 10) + (const_int 12) (const_int 14)])))) + (mult:V8HI + (any_extend:V8HI + (vec_select:V8QI (match_dup 2) + (parallel [(const_int 1) (const_int 3) + (const_int 5) (const_int 7) + (const_int 9) (const_int 11) + (const_int 13) (const_int 15)]))) + (any_extend:V8HI + (vec_select:V8QI (match_dup 3) + (parallel [(const_int 1) (const_int 3) + (const_int 5) (const_int 7) + (const_int 9) (const_int 11) + (const_int 13) (const_int 15)])))))))] + "ISA_HAS_MSA" + "dpsub_<su>.h\t%w0,%w2,%w3" + [(set_attr "type" "simd_mul") + (set_attr "mode" "V8HI")]) + +(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" "simd_fclass") + (set_attr "mode" "<MODE>")]) + +(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" "simd_fcmp") + (set_attr "mode" "<MODE>")]) + +(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" "simd_fcmp") + (set_attr "mode" "<MODE>")]) + +(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_int_iterator FSC_UNS [UNSPEC_MSA_FSAF UNSPEC_MSA_FSUN UNSPEC_MSA_FSOR + UNSPEC_MSA_FSEQ UNSPEC_MSA_FSNE UNSPEC_MSA_FSUEQ + UNSPEC_MSA_FSUNE UNSPEC_MSA_FSULE UNSPEC_MSA_FSULT + UNSPEC_MSA_FSLE UNSPEC_MSA_FSLT]) + +(define_int_attr fsc + [(UNSPEC_MSA_FSAF "fsaf") + (UNSPEC_MSA_FSUN "fsun") + (UNSPEC_MSA_FSOR "fsor") + (UNSPEC_MSA_FSEQ "fseq") + (UNSPEC_MSA_FSNE "fsne") + (UNSPEC_MSA_FSUEQ "fsueq") + (UNSPEC_MSA_FSUNE "fsune") + (UNSPEC_MSA_FSULE "fsule") + (UNSPEC_MSA_FSULT "fsult") + (UNSPEC_MSA_FSLE "fsle") + (UNSPEC_MSA_FSLT "fslt")]) + +(define_insn "msa_<FCC:fcc>_<FMSA:msafmt>" + [(set (match_operand:<VIMODE> 0 "register_operand" "=f") + (FCC:<VIMODE> (match_operand:FMSA 1 "register_operand" "f") + (match_operand:FMSA 2 "register_operand" "f")))] + "ISA_HAS_MSA" + "<FCC:fcc>.<FMSA:msafmt>\t%w0,%w1,%w2" + [(set_attr "type" "simd_fcmp") + (set_attr "mode" "<MODE>")]) + +(define_insn "msa_<fsc>_<FMSA:msafmt>" + [(set (match_operand:<VIMODE> 0 "register_operand" "=f") + (unspec:<VIMODE> [(match_operand:FMSA 1 "register_operand" "f") + (match_operand:FMSA 2 "register_operand" "f")] + FSC_UNS))] + "ISA_HAS_MSA" + "<fsc>.<FMSA:msafmt>\t%w0,%w1,%w2" + [(set_attr "type" "simd_fcmp") + (set_attr "mode" "<MODE>")]) + +(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" "simd_fexp2") + (set_attr "mode" "<MODE>")]) + +(define_mode_attr fint + [(V4SF "v4si") + (V2DF "v2di")]) + +(define_mode_attr FQ + [(V4SF "V8HI") + (V2DF "V4SI")]) + +(define_mode_attr FINTCNV + [(V4SF "I2S") + (V2DF "I2D")]) + +(define_mode_attr FINTCNV_2 + [(V4SF "S2I") + (V2DF "D2I")]) + +(define_insn "float<fint><FMSA:mode>2" + [(set (match_operand:FMSA 0 "register_operand" "=f") + (float:FMSA (match_operand:<VIMODE> 1 "register_operand" "f")))] + "ISA_HAS_MSA" + "ffint_s.<msafmt>\t%w0,%w1" + [(set_attr "type" "simd_fcvt") + (set_attr "cnv_mode" "<FINTCNV>") + (set_attr "mode" "<MODE>")]) + +(define_insn "floatuns<fint><FMSA:mode>2" + [(set (match_operand:FMSA 0 "register_operand" "=f") + (unsigned_float:FMSA + (match_operand:<VIMODE> 1 "register_operand" "f")))] + "ISA_HAS_MSA" + "ffint_u.<msafmt>\t%w0,%w1" + [(set_attr "type" "simd_fcvt") + (set_attr "cnv_mode" "<FINTCNV>") + (set_attr "mode" "<MODE>")]) + +(define_mode_attr FFQ + [(V4SF "V8HI") + (V2DF "V4SI")]) + +(define_insn "msa_ffql_<msafmt>" + [(set (match_operand:FMSA 0 "register_operand" "=f") + (unspec:FMSA [(match_operand:<FQ> 1 "register_operand" "f")] + UNSPEC_MSA_FFQL))] + "ISA_HAS_MSA" + "ffql.<msafmt>\t%w0,%w1" + [(set_attr "type" "simd_fcvt") + (set_attr "cnv_mode" "<FINTCNV>") + (set_attr "mode" "<MODE>")]) + +(define_insn "msa_ffqr_<msafmt>" + [(set (match_operand:FMSA 0 "register_operand" "=f") + (unspec:FMSA [(match_operand:<FQ> 1 "register_operand" "f")] + UNSPEC_MSA_FFQR))] + "ISA_HAS_MSA" + "ffqr.<msafmt>\t%w0,%w1" + [(set_attr "type" "simd_fcvt") + (set_attr "cnv_mode" "<FINTCNV>") + (set_attr "mode" "<MODE>")]) + +(define_insn "msa_fill_<msafmt_f>" + [(set (match_operand:MSA 0 "register_operand" "=f,f") + (vec_duplicate:MSA + (match_operand:<UNITMODE> 1 "reg_or_0_operand" "d,J")))] + "ISA_HAS_MSA" +{ + if (which_alternative == 1) + return "ldi.<msafmt>\t%w0,0"; + + if (!TARGET_64BIT && (<MODE>mode == V2DImode || <MODE>mode == V2DFmode)) + return "#"; + else + return "fill.<msafmt>\t%w0,%z1"; +} + [(set_attr "type" "simd_fill") + (set_attr "mode" "<MODE>")]) + +(define_split + [(set (match_operand:MSA_D 0 "register_operand") + (vec_duplicate:MSA_D + (match_operand:<UNITMODE> 1 "register_operand")))] + "reload_completed && ISA_HAS_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" "simd_flog2") + (set_attr "mode" "<MODE>")]) + +(define_insn "smax<mode>3" + [(set (match_operand:FMSA 0 "register_operand" "=f") + (smax:FMSA (match_operand:FMSA 1 "register_operand" "f") + (match_operand:FMSA 2 "register_operand" "f")))] + "ISA_HAS_MSA" + "fmax.<msafmt>\t%w0,%w1,%w2" + [(set_attr "type" "simd_fminmax") + (set_attr "mode" "<MODE>")]) + +(define_insn "msa_fmax_a_<msafmt>" + [(set (match_operand:FMSA 0 "register_operand" "=f") + (if_then_else:FMSA + (gt (abs:FMSA (match_operand:FMSA 1 "register_operand" "f")) + (abs:FMSA (match_operand:FMSA 2 "register_operand" "f"))) + (match_dup 1) + (match_dup 2)))] + "ISA_HAS_MSA" + "fmax_a.<msafmt>\t%w0,%w1,%w2" + [(set_attr "type" "simd_fminmax") + (set_attr "mode" "<MODE>")]) + +(define_insn "smin<mode>3" + [(set (match_operand:FMSA 0 "register_operand" "=f") + (smin:FMSA (match_operand:FMSA 1 "register_operand" "f") + (match_operand:FMSA 2 "register_operand" "f")))] + "ISA_HAS_MSA" + "fmin.<msafmt>\t%w0,%w1,%w2" + [(set_attr "type" "simd_fminmax") + (set_attr "mode" "<MODE>")]) + +(define_insn "msa_fmin_a_<msafmt>" + [(set (match_operand:FMSA 0 "register_operand" "=f") + (if_then_else:FMSA + (lt (abs:FMSA (match_operand:FMSA 1 "register_operand" "f")) + (abs:FMSA (match_operand:FMSA 2 "register_operand" "f"))) + (match_dup 1) + (match_dup 2)))] + "ISA_HAS_MSA" + "fmin_a.<msafmt>\t%w0,%w1,%w2" + [(set_attr "type" "simd_fminmax") + (set_attr "mode" "<MODE>")]) + +(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" "simd_fdiv") + (set_attr "mode" "<MODE>")]) + +(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" "simd_fcvt") + (set_attr "mode" "<MODE>")]) + +(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" "simd_fdiv") + (set_attr "mode" "<MODE>")]) + +(define_insn "msa_ftint_s_<msafmt>" + [(set (match_operand:<VIMODE> 0 "register_operand" "=f") + (unspec:<VIMODE> [(match_operand:FMSA 1 "register_operand" "f")] + UNSPEC_MSA_FTINT_S))] + "ISA_HAS_MSA" + "ftint_s.<msafmt>\t%w0,%w1" + [(set_attr "type" "simd_fcvt") + (set_attr "cnv_mode" "<FINTCNV_2>") + (set_attr "mode" "<MODE>")]) + +(define_insn "msa_ftint_u_<msafmt>" + [(set (match_operand:<VIMODE> 0 "register_operand" "=f") + (unspec:<VIMODE> [(match_operand:FMSA 1 "register_operand" "f")] + UNSPEC_MSA_FTINT_U))] + "ISA_HAS_MSA" + "ftint_u.<msafmt>\t%w0,%w1" + [(set_attr "type" "simd_fcvt") + (set_attr "cnv_mode" "<FINTCNV_2>") + (set_attr "mode" "<MODE>")]) + +(define_insn "fix_trunc<FMSA:mode><mode_i>2" + [(set (match_operand:<VIMODE> 0 "register_operand" "=f") + (fix:<VIMODE> (match_operand:FMSA 1 "register_operand" "f")))] + "ISA_HAS_MSA" + "ftrunc_s.<msafmt>\t%w0,%w1" + [(set_attr "type" "simd_fcvt") + (set_attr "cnv_mode" "<FINTCNV_2>") + (set_attr "mode" "<MODE>")]) + +(define_insn "fixuns_trunc<FMSA:mode><mode_i>2" + [(set (match_operand:<VIMODE> 0 "register_operand" "=f") + (unsigned_fix:<VIMODE> (match_operand:FMSA 1 "register_operand" "f")))] + "ISA_HAS_MSA" + "ftrunc_u.<msafmt>\t%w0,%w1" + [(set_attr "type" "simd_fcvt") + (set_attr "cnv_mode" "<FINTCNV_2>") + (set_attr "mode" "<MODE>")]) + +(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" "simd_fcvt") + (set_attr "cnv_mode" "S2I") + (set_attr "mode" "V4SF")]) + +(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" "simd_fcvt") + (set_attr "cnv_mode" "D2I") + (set_attr "mode" "V2DF")]) + +(define_insn "msa_h<optab>_<su>_h" + [(set (match_operand:V8HI 0 "register_operand" "=f") + (addsub:V8HI + (any_extend:V8HI + (vec_select:V8QI + (match_operand:V16QI 1 "register_operand" "f") + (parallel [(const_int 1) (const_int 3) + (const_int 5) (const_int 7) + (const_int 9) (const_int 11) + (const_int 13) (const_int 15)]))) + (any_extend:V8HI + (vec_select:V8QI + (match_operand:V16QI 2 "register_operand" "f") + (parallel [(const_int 0) (const_int 2) + (const_int 4) (const_int 6) + (const_int 8) (const_int 10) + (const_int 12) (const_int 14)])))))] + "ISA_HAS_MSA" + "h<optab>_<su>.h\t%w0,%w1,%w2" + [(set_attr "type" "simd_int_arith") + (set_attr "mode" "V8HI")]) + +(define_insn "msa_h<optab>_<su>_w" + [(set (match_operand:V4SI 0 "register_operand" "=f") + (addsub:V4SI + (any_extend:V4SI + (vec_select:V4HI + (match_operand:V8HI 1 "register_operand" "f") + (parallel [(const_int 1) (const_int 3) + (const_int 5) (const_int 7)]))) + (any_extend:V4SI + (vec_select:V4HI + (match_operand:V8HI 2 "register_operand" "f") + (parallel [(const_int 0) (const_int 2) + (const_int 4) (const_int 6)])))))] + "ISA_HAS_MSA" + "h<optab>_<su>.w\t%w0,%w1,%w2" + [(set_attr "type" "simd_int_arith") + (set_attr "mode" "V4SI")]) + +(define_insn "msa_h<optab>_<su>_d" + [(set (match_operand:V2DI 0 "register_operand" "=f") + (addsub:V2DI + (any_extend:V2DI + (vec_select:V2SI + (match_operand:V4SI 1 "register_operand" "f") + (parallel [(const_int 1) (const_int 3)]))) + (any_extend:V2DI + (vec_select:V2SI + (match_operand:V4SI 2 "register_operand" "f") + (parallel [(const_int 0) (const_int 2)])))))] + "ISA_HAS_MSA" + "h<optab>_<su>.d\t%w0,%w1,%w2" + [(set_attr "type" "simd_int_arith") + (set_attr "mode" "V2DI")]) + +(define_insn "msa_ilvev_b" + [(set (match_operand:V16QI 0 "register_operand" "=f") + (vec_select:V16QI + (vec_concat:V32QI + (match_operand:V16QI 1 "register_operand" "f") + (match_operand:V16QI 2 "register_operand" "f")) + (parallel [(const_int 0) (const_int 16) + (const_int 2) (const_int 18) + (const_int 4) (const_int 20) + (const_int 6) (const_int 22) + (const_int 8) (const_int 24) + (const_int 10) (const_int 26) + (const_int 12) (const_int 28) + (const_int 14) (const_int 30)])))] + "ISA_HAS_MSA" + "ilvev.b\t%w0,%w2,%w1" + [(set_attr "type" "simd_permute") + (set_attr "mode" "V16QI")]) + +(define_insn "msa_ilvev_h" + [(set (match_operand:V8HI 0 "register_operand" "=f") + (vec_select:V8HI + (vec_concat:V16HI + (match_operand:V8HI 1 "register_operand" "f") + (match_operand:V8HI 2 "register_operand" "f")) + (parallel [(const_int 0) (const_int 8) + (const_int 2) (const_int 10) + (const_int 4) (const_int 12) + (const_int 6) (const_int 14)])))] + "ISA_HAS_MSA" + "ilvev.h\t%w0,%w2,%w1" + [(set_attr "type" "simd_permute") + (set_attr "mode" "V8HI")]) + +(define_insn "msa_ilvev_w" + [(set (match_operand:V4SI 0 "register_operand" "=f") + (vec_select:V4SI + (vec_concat:V8SI + (match_operand:V4SI 1 "register_operand" "f") + (match_operand:V4SI 2 "register_operand" "f")) + (parallel [(const_int 0) (const_int 4) + (const_int 2) (const_int 6)])))] + "ISA_HAS_MSA" + "ilvev.w\t%w0,%w2,%w1" + [(set_attr "type" "simd_permute") + (set_attr "mode" "V4SI")]) + +(define_insn "msa_ilvev_w_f" + [(set (match_operand:V4SF 0 "register_operand" "=f") + (vec_select:V4SF + (vec_concat:V8SF + (match_operand:V4SF 1 "register_operand" "f") + (match_operand:V4SF 2 "register_operand" "f")) + (parallel [(const_int 0) (const_int 4) + (const_int 2) (const_int 6)])))] + "ISA_HAS_MSA" + "ilvev.w\t%w0,%w2,%w1" + [(set_attr "type" "simd_permute") + (set_attr "mode" "V4SF")]) + +(define_insn "msa_ilvl_b" + [(set (match_operand:V16QI 0 "register_operand" "=f") + (vec_select:V16QI + (vec_concat:V32QI + (match_operand:V16QI 1 "register_operand" "f") + (match_operand:V16QI 2 "register_operand" "f")) + (parallel [(const_int 8) (const_int 24) + (const_int 9) (const_int 25) + (const_int 10) (const_int 26) + (const_int 11) (const_int 27) + (const_int 12) (const_int 28) + (const_int 13) (const_int 29) + (const_int 14) (const_int 30) + (const_int 15) (const_int 31)])))] + "ISA_HAS_MSA" + "ilvl.b\t%w0,%w2,%w1" + [(set_attr "type" "simd_permute") + (set_attr "mode" "V16QI")]) + +(define_insn "msa_ilvl_h" + [(set (match_operand:V8HI 0 "register_operand" "=f") + (vec_select:V8HI + (vec_concat:V16HI + (match_operand:V8HI 1 "register_operand" "f") + (match_operand:V8HI 2 "register_operand" "f")) + (parallel [(const_int 4) (const_int 12) + (const_int 5) (const_int 13) + (const_int 6) (const_int 14) + (const_int 7) (const_int 15)])))] + "ISA_HAS_MSA" + "ilvl.h\t%w0,%w2,%w1" + [(set_attr "type" "simd_permute") + (set_attr "mode" "V8HI")]) + +(define_insn "msa_ilvl_w" + [(set (match_operand:V4SI 0 "register_operand" "=f") + (vec_select:V4SI + (vec_concat:V8SI + (match_operand:V4SI 1 "register_operand" "f") + (match_operand:V4SI 2 "register_operand" "f")) + (parallel [(const_int 2) (const_int 6) + (const_int 3) (const_int 7)])))] + "ISA_HAS_MSA" + "ilvl.w\t%w0,%w2,%w1" + [(set_attr "type" "simd_permute") + (set_attr "mode" "V4SI")]) + +(define_insn "msa_ilvl_w_f" + [(set (match_operand:V4SF 0 "register_operand" "=f") + (vec_select:V4SF + (vec_concat:V8SF + (match_operand:V4SF 1 "register_operand" "f") + (match_operand:V4SF 2 "register_operand" "f")) + (parallel [(const_int 2) (const_int 6) + (const_int 3) (const_int 7)])))] + "ISA_HAS_MSA" + "ilvl.w\t%w0,%w2,%w1" + [(set_attr "type" "simd_permute") + (set_attr "mode" "V4SF")]) + +(define_insn "msa_ilvl_d" + [(set (match_operand:V2DI 0 "register_operand" "=f") + (vec_select:V2DI + (vec_concat:V4DI + (match_operand:V2DI 1 "register_operand" "f") + (match_operand:V2DI 2 "register_operand" "f")) + (parallel [(const_int 1) (const_int 3)])))] + "ISA_HAS_MSA" + "ilvl.d\t%w0,%w2,%w1" + [(set_attr "type" "simd_permute") + (set_attr "mode" "V2DI")]) + +(define_insn "msa_ilvl_d_f" + [(set (match_operand:V2DF 0 "register_operand" "=f") + (vec_select:V2DF + (vec_concat:V4DF + (match_operand:V2DF 1 "register_operand" "f") + (match_operand:V2DF 2 "register_operand" "f")) + (parallel [(const_int 1) (const_int 3)])))] + "ISA_HAS_MSA" + "ilvl.d\t%w0,%w2,%w1" + [(set_attr "type" "simd_permute") + (set_attr "mode" "V2DF")]) + +(define_insn "msa_ilvod_b" + [(set (match_operand:V16QI 0 "register_operand" "=f") + (vec_select:V16QI + (vec_concat:V32QI + (match_operand:V16QI 1 "register_operand" "f") + (match_operand:V16QI 2 "register_operand" "f")) + (parallel [(const_int 1) (const_int 17) + (const_int 3) (const_int 19) + (const_int 5) (const_int 21) + (const_int 7) (const_int 23) + (const_int 9) (const_int 25) + (const_int 11) (const_int 27) + (const_int 13) (const_int 29) + (const_int 15) (const_int 31)])))] + "ISA_HAS_MSA" + "ilvod.b\t%w0,%w2,%w1" + [(set_attr "type" "simd_permute") + (set_attr "mode" "V16QI")]) + +(define_insn "msa_ilvod_h" + [(set (match_operand:V8HI 0 "register_operand" "=f") + (vec_select:V8HI + (vec_concat:V16HI + (match_operand:V8HI 1 "register_operand" "f") + (match_operand:V8HI 2 "register_operand" "f")) + (parallel [(const_int 1) (const_int 9) + (const_int 3) (const_int 11) + (const_int 5) (const_int 13) + (const_int 7) (const_int 15)])))] + "ISA_HAS_MSA" + "ilvod.h\t%w0,%w2,%w1" + [(set_attr "type" "simd_permute") + (set_attr "mode" "V8HI")]) + +(define_insn "msa_ilvod_w" + [(set (match_operand:V4SI 0 "register_operand" "=f") + (vec_select:V4SI + (vec_concat:V8SI + (match_operand:V4SI 1 "register_operand" "f") + (match_operand:V4SI 2 "register_operand" "f")) + (parallel [(const_int 1) (const_int 5) + (const_int 3) (const_int 7)])))] + "ISA_HAS_MSA" + "ilvod.w\t%w0,%w2,%w1" + [(set_attr "type" "simd_permute") + (set_attr "mode" "V4SI")]) + +(define_insn "msa_ilvod_w_f" + [(set (match_operand:V4SF 0 "register_operand" "=f") + (vec_select:V4SF + (vec_concat:V8SF + (match_operand:V4SF 1 "register_operand" "f") + (match_operand:V4SF 2 "register_operand" "f")) + (parallel [(const_int 1) (const_int 5) + (const_int 3) (const_int 7)])))] + "ISA_HAS_MSA" + "ilvod.w\t%w0,%w2,%w1" + [(set_attr "type" "simd_permute") + (set_attr "mode" "V4SF")]) + +(define_insn "msa_ilvr_b" + [(set (match_operand:V16QI 0 "register_operand" "=f") + (vec_select:V16QI + (vec_concat:V32QI + (match_operand:V16QI 1 "register_operand" "f") + (match_operand:V16QI 2 "register_operand" "f")) + (parallel [(const_int 0) (const_int 16) + (const_int 1) (const_int 17) + (const_int 2) (const_int 18) + (const_int 3) (const_int 19) + (const_int 4) (const_int 20) + (const_int 5) (const_int 21) + (const_int 6) (const_int 22) + (const_int 7) (const_int 23)])))] + "ISA_HAS_MSA" + "ilvr.b\t%w0,%w2,%w1" + [(set_attr "type" "simd_permute") + (set_attr "mode" "V16QI")]) + +(define_insn "msa_ilvr_h" + [(set (match_operand:V8HI 0 "register_operand" "=f") + (vec_select:V8HI + (vec_concat:V16HI + (match_operand:V8HI 1 "register_operand" "f") + (match_operand:V8HI 2 "register_operand" "f")) + (parallel [(const_int 0) (const_int 8) + (const_int 1) (const_int 9) + (const_int 2) (const_int 10) + (const_int 3) (const_int 11)])))] + "ISA_HAS_MSA" + "ilvr.h\t%w0,%w2,%w1" + [(set_attr "type" "simd_permute") + (set_attr "mode" "V8HI")]) + +(define_insn "msa_ilvr_w" + [(set (match_operand:V4SI 0 "register_operand" "=f") + (vec_select:V4SI + (vec_concat:V8SI + (match_operand:V4SI 1 "register_operand" "f") + (match_operand:V4SI 2 "register_operand" "f")) + (parallel [(const_int 0) (const_int 4) + (const_int 1) (const_int 5)])))] + "ISA_HAS_MSA" + "ilvr.w\t%w0,%w2,%w1" + [(set_attr "type" "simd_permute") + (set_attr "mode" "V4SI")]) + +(define_insn "msa_ilvr_w_f" + [(set (match_operand:V4SF 0 "register_operand" "=f") + (vec_select:V4SF + (vec_concat:V8SF + (match_operand:V4SF 1 "register_operand" "f") + (match_operand:V4SF 2 "register_operand" "f")) + (parallel [(const_int 0) (const_int 4) + (const_int 1) (const_int 5)])))] + "ISA_HAS_MSA" + "ilvr.w\t%w0,%w2,%w1" + [(set_attr "type" "simd_permute") + (set_attr "mode" "V4SF")]) + +(define_insn "msa_ilvr_d" + [(set (match_operand:V2DI 0 "register_operand" "=f") + (vec_select:V2DI + (vec_concat:V4DI + (match_operand:V2DI 1 "register_operand" "f") + (match_operand:V2DI 2 "register_operand" "f")) + (parallel [(const_int 0) (const_int 2)])))] + "ISA_HAS_MSA" + "ilvr.d\t%w0,%w2,%w1" + [(set_attr "type" "simd_permute") + (set_attr "mode" "V2DI")]) + +(define_insn "msa_ilvr_d_f" + [(set (match_operand:V2DF 0 "register_operand" "=f") + (vec_select:V2DF + (vec_concat:V4DF + (match_operand:V2DF 1 "register_operand" "f") + (match_operand:V2DF 2 "register_operand" "f")) + (parallel [(const_int 0) (const_int 2)])))] + "ISA_HAS_MSA" + "ilvr.d\t%w0,%w2,%w1" + [(set_attr "type" "simd_permute") + (set_attr "mode" "V2DF")]) + +(define_insn "msa_madd_q_<msafmt>" + [(set (match_operand:IMSA_WH 0 "register_operand" "=f") + (unspec:IMSA_WH [(match_operand:IMSA_WH 1 "register_operand" "0") + (match_operand:IMSA_WH 2 "register_operand" "f") + (match_operand:IMSA_WH 3 "register_operand" "f")] + UNSPEC_MSA_MADD_Q))] + "ISA_HAS_MSA" + "madd_q.<msafmt>\t%w0,%w2,%w3" + [(set_attr "type" "simd_mul") + (set_attr "mode" "<MODE>")]) + +(define_insn "msa_maddr_q_<msafmt>" + [(set (match_operand:IMSA_WH 0 "register_operand" "=f") + (unspec:IMSA_WH [(match_operand:IMSA_WH 1 "register_operand" "0") + (match_operand:IMSA_WH 2 "register_operand" "f") + (match_operand:IMSA_WH 3 "register_operand" "f")] + UNSPEC_MSA_MADDR_Q))] + "ISA_HAS_MSA" + "maddr_q.<msafmt>\t%w0,%w2,%w3" + [(set_attr "type" "simd_mul") + (set_attr "mode" "<MODE>")]) + +(define_insn "msa_max_a_<msafmt>" + [(set (match_operand:IMSA 0 "register_operand" "=f") + (if_then_else:IMSA + (gt (abs:IMSA (match_operand:IMSA 1 "register_operand" "f")) + (abs:IMSA (match_operand:IMSA 2 "register_operand" "f"))) + (match_dup 1) + (match_dup 2)))] + "ISA_HAS_MSA" + "max_a.<msafmt>\t%w0,%w1,%w2" + [(set_attr "type" "simd_int_arith") + (set_attr "mode" "<MODE>")]) + +(define_insn "smax<mode>3" + [(set (match_operand:IMSA 0 "register_operand" "=f,f") + (smax:IMSA (match_operand:IMSA 1 "register_operand" "f,f") + (match_operand:IMSA 2 "reg_or_vector_same_simm5_operand" "f,Usv5")))] + "ISA_HAS_MSA" + "@ + max_s.<msafmt>\t%w0,%w1,%w2 + maxi_s.<msafmt>\t%w0,%w1,%E2" + [(set_attr "type" "simd_int_arith") + (set_attr "mode" "<MODE>")]) + +(define_insn "umax<mode>3" + [(set (match_operand:IMSA 0 "register_operand" "=f,f") + (umax:IMSA (match_operand:IMSA 1 "register_operand" "f,f") + (match_operand:IMSA 2 "reg_or_vector_same_uimm5_operand" "f,Uuv5")))] + "ISA_HAS_MSA" + "@ + max_u.<msafmt>\t%w0,%w1,%w2 + maxi_u.<msafmt>\t%w0,%w1,%B2" + [(set_attr "type" "simd_int_arith") + (set_attr "mode" "<MODE>")]) + +(define_insn "msa_min_a_<msafmt>" + [(set (match_operand:IMSA 0 "register_operand" "=f") + (if_then_else:IMSA + (lt (abs:IMSA (match_operand:IMSA 1 "register_operand" "f")) + (abs:IMSA (match_operand:IMSA 2 "register_operand" "f"))) + (match_dup 1) + (match_dup 2)))] + "ISA_HAS_MSA" + "min_a.<msafmt>\t%w0,%w1,%w2" + [(set_attr "type" "simd_int_arith") + (set_attr "mode" "<MODE>")]) + +(define_insn "smin<mode>3" + [(set (match_operand:IMSA 0 "register_operand" "=f,f") + (smin:IMSA (match_operand:IMSA 1 "register_operand" "f,f") + (match_operand:IMSA 2 "reg_or_vector_same_simm5_operand" "f,Usv5")))] + "ISA_HAS_MSA" + "@ + min_s.<msafmt>\t%w0,%w1,%w2 + mini_s.<msafmt>\t%w0,%w1,%E2" + [(set_attr "type" "simd_int_arith") + (set_attr "mode" "<MODE>")]) + +(define_insn "umin<mode>3" + [(set (match_operand:IMSA 0 "register_operand" "=f,f") + (umin:IMSA (match_operand:IMSA 1 "register_operand" "f,f") + (match_operand:IMSA 2 "reg_or_vector_same_uimm5_operand" "f,Uuv5")))] + "ISA_HAS_MSA" + "@ + min_u.<msafmt>\t%w0,%w1,%w2 + mini_u.<msafmt>\t%w0,%w1,%B2" + [(set_attr "type" "simd_int_arith") + (set_attr "mode" "<MODE>")]) + +(define_insn "msa_msub_q_<msafmt>" + [(set (match_operand:IMSA_WH 0 "register_operand" "=f") + (unspec:IMSA_WH [(match_operand:IMSA_WH 1 "register_operand" "0") + (match_operand:IMSA_WH 2 "register_operand" "f") + (match_operand:IMSA_WH 3 "register_operand" "f")] + UNSPEC_MSA_MSUB_Q))] + "ISA_HAS_MSA" + "msub_q.<msafmt>\t%w0,%w2,%w3" + [(set_attr "type" "simd_mul") + (set_attr "mode" "<MODE>")]) + +(define_insn "msa_msubr_q_<msafmt>" + [(set (match_operand:IMSA_WH 0 "register_operand" "=f") + (unspec:IMSA_WH [(match_operand:IMSA_WH 1 "register_operand" "0") + (match_operand:IMSA_WH 2 "register_operand" "f") + (match_operand:IMSA_WH 3 "register_operand" "f")] + UNSPEC_MSA_MSUBR_Q))] + "ISA_HAS_MSA" + "msubr_q.<msafmt>\t%w0,%w2,%w3" + [(set_attr "type" "simd_mul") + (set_attr "mode" "<MODE>")]) + +(define_insn "msa_mul_q_<msafmt>" + [(set (match_operand:IMSA_WH 0 "register_operand" "=f") + (unspec:IMSA_WH [(match_operand:IMSA_WH 1 "register_operand" "f") + (match_operand:IMSA_WH 2 "register_operand" "f")] + UNSPEC_MSA_MUL_Q))] + "ISA_HAS_MSA" + "mul_q.<msafmt>\t%w0,%w1,%w2" + [(set_attr "type" "simd_mul") + (set_attr "mode" "<MODE>")]) + +(define_insn "msa_mulr_q_<msafmt>" + [(set (match_operand:IMSA_WH 0 "register_operand" "=f") + (unspec:IMSA_WH [(match_operand:IMSA_WH 1 "register_operand" "f") + (match_operand:IMSA_WH 2 "register_operand" "f")] + UNSPEC_MSA_MULR_Q))] + "ISA_HAS_MSA" + "mulr_q.<msafmt>\t%w0,%w1,%w2" + [(set_attr "type" "simd_mul") + (set_attr "mode" "<MODE>")]) + +(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" "simd_bit") + (set_attr "mode" "<MODE>")]) + +(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" "simd_bit") + (set_attr "mode" "<MODE>")]) + +(define_insn "msa_nor_<msafmt>" + [(set (match_operand:IMSA 0 "register_operand" "=f,f") + (and:IMSA (not:IMSA (match_operand:IMSA 1 "register_operand" "f,f")) + (not:IMSA (match_operand:IMSA 2 "reg_or_vector_same_val_operand" "f,Urv8"))))] + "ISA_HAS_MSA" + "@ + nor.v\t%w0,%w1,%w2 + nori.b\t%w0,%w1,%B2" + [(set_attr "type" "simd_logic") + (set_attr "mode" "<MODE>")]) + +(define_insn "msa_pckev_b" +[(set (match_operand:V16QI 0 "register_operand" "=f") + (vec_select:V16QI + (vec_concat:V32QI + (match_operand:V16QI 1 "register_operand" "f") + (match_operand:V16QI 2 "register_operand" "f")) + (parallel [(const_int 0) (const_int 2) + (const_int 4) (const_int 6) + (const_int 8) (const_int 10) + (const_int 12) (const_int 14) + (const_int 16) (const_int 18) + (const_int 20) (const_int 22) + (const_int 24) (const_int 26) + (const_int 28) (const_int 30)])))] + "ISA_HAS_MSA" + "pckev.b\t%w0,%w2,%w1" + [(set_attr "type" "simd_permute") + (set_attr "mode" "V16QI")]) + +(define_insn "msa_pckev_h" +[(set (match_operand:V8HI 0 "register_operand" "=f") + (vec_select:V8HI + (vec_concat:V16HI + (match_operand:V8HI 1 "register_operand" "f") + (match_operand:V8HI 2 "register_operand" "f")) + (parallel [(const_int 0) (const_int 2) + (const_int 4) (const_int 6) + (const_int 8) (const_int 10) + (const_int 12) (const_int 14)])))] + "ISA_HAS_MSA" + "pckev.h\t%w0,%w2,%w1" + [(set_attr "type" "simd_permute") + (set_attr "mode" "V8HI")]) + +(define_insn "msa_pckev_w" +[(set (match_operand:V4SI 0 "register_operand" "=f") + (vec_select:V4SI + (vec_concat:V8SI + (match_operand:V4SI 1 "register_operand" "f") + (match_operand:V4SI 2 "register_operand" "f")) + (parallel [(const_int 0) (const_int 2) + (const_int 4) (const_int 6)])))] + "ISA_HAS_MSA" + "pckev.w\t%w0,%w2,%w1" + [(set_attr "type" "simd_permute") + (set_attr "mode" "V4SI")]) + +(define_insn "msa_pckev_w_f" +[(set (match_operand:V4SF 0 "register_operand" "=f") + (vec_select:V4SF + (vec_concat:V8SF + (match_operand:V4SF 1 "register_operand" "f") + (match_operand:V4SF 2 "register_operand" "f")) + (parallel [(const_int 0) (const_int 2) + (const_int 4) (const_int 6)])))] + "ISA_HAS_MSA" + "pckev.w\t%w0,%w2,%w1" + [(set_attr "type" "simd_permute") + (set_attr "mode" "V4SF")]) + +(define_insn "msa_pckod_b" +[(set (match_operand:V16QI 0 "register_operand" "=f") + (vec_select:V16QI + (vec_concat:V32QI + (match_operand:V16QI 1 "register_operand" "f") + (match_operand:V16QI 2 "register_operand" "f")) + (parallel [(const_int 1) (const_int 3) + (const_int 5) (const_int 7) + (const_int 9) (const_int 11) + (const_int 13) (const_int 15) + (const_int 17) (const_int 19) + (const_int 21) (const_int 23) + (const_int 25) (const_int 27) + (const_int 29) (const_int 31)])))] + "ISA_HAS_MSA" + "pckod.b\t%w0,%w2,%w1" + [(set_attr "type" "simd_permute") + (set_attr "mode" "V16QI")]) + +(define_insn "msa_pckod_h" +[(set (match_operand:V8HI 0 "register_operand" "=f") + (vec_select:V8HI + (vec_concat:V16HI + (match_operand:V8HI 1 "register_operand" "f") + (match_operand:V8HI 2 "register_operand" "f")) + (parallel [(const_int 1) (const_int 3) + (const_int 5) (const_int 7) + (const_int 9) (const_int 11) + (const_int 13) (const_int 15)])))] + "ISA_HAS_MSA" + "pckod.h\t%w0,%w2,%w1" + [(set_attr "type" "simd_permute") + (set_attr "mode" "V8HI")]) + +(define_insn "msa_pckod_w" +[(set (match_operand:V4SI 0 "register_operand" "=f") + (vec_select:V4SI + (vec_concat:V8SI + (match_operand:V4SI 1 "register_operand" "f") + (match_operand:V4SI 2 "register_operand" "f")) + (parallel [(const_int 1) (const_int 3) + (const_int 5) (const_int 7)])))] + "ISA_HAS_MSA" + "pckod.w\t%w0,%w2,%w1" + [(set_attr "type" "simd_permute") + (set_attr "mode" "V4SI")]) + +(define_insn "msa_pckod_w_f" +[(set (match_operand:V4SF 0 "register_operand" "=f") + (vec_select:V4SF + (vec_concat:V8SF + (match_operand:V4SF 1 "register_operand" "f") + (match_operand:V4SF 2 "register_operand" "f")) + (parallel [(const_int 1) (const_int 3) + (const_int 5) (const_int 7)])))] + "ISA_HAS_MSA" + "pckod.w\t%w0,%w2,%w1" + [(set_attr "type" "simd_permute") + (set_attr "mode" "V4SF")]) + +(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" "simd_pcnt") + (set_attr "mode" "<MODE>")]) + +(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" "simd_sat") + (set_attr "mode" "<MODE>")]) + +(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" "simd_sat") + (set_attr "mode" "<MODE>")]) + +(define_insn "msa_shf_<msafmt_f>" + [(set (match_operand:MSA_WHB_W 0 "register_operand" "=f") + (vec_select:MSA_WHB_W + (match_operand:MSA_WHB_W 1 "register_operand" "f") + (match_operand 2 "par_const_vector_shf_set_operand" "")))] + "ISA_HAS_MSA" +{ + HOST_WIDE_INT val = 0; + unsigned int i; + + /* We convert the selection to an immediate. */ + for (i = 0; i < 4; i++) + val |= INTVAL (XVECEXP (operands[2], 0, i)) << (2 * i); + + operands[2] = GEN_INT (val); + return "shf.<msafmt>\t%w0,%w1,%X2"; +} + [(set_attr "type" "simd_shf") + (set_attr "mode" "<MODE>")]) + +(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" "simd_shift") + (set_attr "mode" "<MODE>")]) + +(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" "simd_shift") + (set_attr "mode" "<MODE>")]) + +(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" "simd_shift") + (set_attr "mode" "<MODE>")]) + +(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" "simd_shift") + (set_attr "mode" "<MODE>")]) + +(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" "simd_int_arith") + (set_attr "mode" "<MODE>")]) + +(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" "simd_int_arith") + (set_attr "mode" "<MODE>")]) + +(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" "simd_int_arith") + (set_attr "mode" "<MODE>")]) + +(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" "simd_int_arith") + (set_attr "mode" "<MODE>")]) + +(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" "simd_sld") + (set_attr "mode" "<MODE>")]) + +(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" "simd_sld") + (set_attr "mode" "<MODE>")]) + +(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 "register_operand" "d")] + UNSPEC_MSA_SPLAT))] + "ISA_HAS_MSA" + "splat.<msafmt>\t%w0,%w1[%z2]" + [(set_attr "type" "simd_splat") + (set_attr "mode" "<MODE>")]) + +(define_insn "msa_splati_<msafmt_f>" + [(set (match_operand:MSA 0 "register_operand" "=f") + (vec_duplicate:MSA + (vec_select:<UNITMODE> + (match_operand:MSA 1 "register_operand" "f") + (parallel [(match_operand 2 "const_<indeximm>_operand" "")]))))] + "ISA_HAS_MSA" + "splati.<msafmt>\t%w0,%w1[%2]" + [(set_attr "type" "simd_splat") + (set_attr "mode" "<MODE>")]) + +(define_insn "msa_splati_<msafmt_f>_scalar" + [(set (match_operand:FMSA 0 "register_operand" "=f") + (unspec:FMSA [(match_operand:<UNITMODE> 1 "register_operand" "f")] + UNSPEC_MSA_SPLATI))] + "ISA_HAS_MSA" + "splati.<msafmt>\t%w0,%w1[0]" + [(set_attr "type" "simd_splat") + (set_attr "mode" "<MODE>")]) + +(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" "simd_cmsa") + (set_attr "mode" "SI")]) + +(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" "simd_cmsa") + (set_attr "mode" "SI")]) + +(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" "simd_fcvt") + (set_attr "mode" "V8HI")]) + +(define_insn "vec_pack_trunc_v2df" + [(set (match_operand:V4SF 0 "register_operand" "=f") + (vec_concat:V4SF + (float_truncate:V2SF (match_operand:V2DF 1 "register_operand" "f")) + (float_truncate:V2SF (match_operand:V2DF 2 "register_operand" "f"))))] + "ISA_HAS_MSA" + "fexdo.w\t%w0,%w2,%w1" + [(set_attr "type" "simd_fcvt") + (set_attr "mode" "V4SF")]) + +(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" "simd_fcvt") + (set_attr "mode" "V4SF")]) + +(define_insn "msa_fexupl_d" + [(set (match_operand:V2DF 0 "register_operand" "=f") + (float_extend:V2DF + (vec_select:V2SF + (match_operand:V4SF 1 "register_operand" "f") + (parallel [(const_int 2) (const_int 3)]))))] + "ISA_HAS_MSA" + "fexupl.d\t%w0,%w1" + [(set_attr "type" "simd_fcvt") + (set_attr "mode" "V2DF")]) + +(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" "simd_fcvt") + (set_attr "mode" "V4SF")]) + +(define_insn "msa_fexupr_d" + [(set (match_operand:V2DF 0 "register_operand" "=f") + (float_extend:V2DF + (vec_select:V2SF + (match_operand:V4SF 1 "register_operand" "f") + (parallel [(const_int 0) (const_int 1)]))))] + "ISA_HAS_MSA" + "fexupr.d\t%w0,%w1" + [(set_attr "type" "simd_fcvt") + (set_attr "mode" "V2DF")]) + +(define_code_attr msabr + [(eq "bz") + (ne "bnz")]) + +(define_code_attr msabr_neg + [(eq "bnz") + (ne "bz")]) + +(define_insn "msa_<msabr>_<msafmt_f>" + [(set (pc) (if_then_else + (equality_op + (unspec:SI [(match_operand:MSA 1 "register_operand" "f")] + UNSPEC_MSA_BRANCH) + (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 ("<msabr>.<msafmt>", + "%w1,%0"), + MIPS_BRANCH ("<msabr_neg>.<msafmt>", + "%w1,%0")); +} + [(set_attr "type" "simd_branch") + (set_attr "mode" "<MODE>") + (set_attr "compact_form" "never")]) + +(define_insn "msa_<msabr>_v_<msafmt_f>" + [(set (pc) (if_then_else + (equality_op + (unspec:SI [(match_operand:MSA 1 "register_operand" "f")] + UNSPEC_MSA_BRANCH_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 ("<msabr>.v", "%w1,%0"), + MIPS_BRANCH ("<msabr_neg>.v", + "%w1,%0")); +} + [(set_attr "type" "simd_branch") + (set_attr "mode" "TI") + (set_attr "compact_form" "never")])