;; Machine Description for MIPS MSA ASE ;; Based on the MIPS MSA spec Revision 1.11 8/4/2014 ;; ;; Copyright (C) 2015-2021 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__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__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__operand”. (define_mode_attr bitimm [(V16QI “uimm3”) (V8HI “uimm4”) (V4SI “uimm5”) (V2DI “uimm6”)])

(define_expand “vec_init” [(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_” [(set (match_operand: 0 “register_operand” “=f”) (vec_concat: (truncate: (match_operand:IMSA_DWH 1 “register_operand” “f”)) (truncate: (match_operand:IMSA_DWH 2 “register_operand” “f”))))] “ISA_HAS_MSA” “pckev.\t%w0,%w2,%w1” [(set_attr “type” “simd_permute”) (set_attr “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_” [(match_operand: 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_” [(match_operand: 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_” [(match_operand: 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_” [(match_operand: 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” [(match_operand: 0 “register_operand”) (match_operand:IMSA 1 “register_operand”) (match_operand 2 “const__operand”)] “ISA_HAS_MSA” { if (mode == QImode || mode == HImode) { rtx dest1 = gen_reg_rtx (SImode); emit_insn (gen_msa_copy_s_ (dest1, operands[1], operands[2])); emit_move_insn (operands[0], gen_lowpart (mode, dest1)); } else emit_insn (gen_msa_copy_s_ (operands[0], operands[1], operands[2])); DONE; })

(define_expand “vec_extract” [(match_operand: 0 “register_operand”) (match_operand:FMSA 1 “register_operand”) (match_operand 2 “const__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_lowpart (V16QImode, operands[1])); rtx n = GEN_INT (val * GET_MODE_SIZE (mode)); gcc_assert (INTVAL (n) < GET_MODE_NUNITS (V16QImode)); emit_insn (gen_msa_sldi_b (wd, ws, ws, n)); temp = gen_reg_rtx (mode); emit_move_insn (temp, gen_lowpart (mode, wd)); } emit_insn (gen_msa_vec_extract_<msafmt_f> (operands[0], temp)); DONE; })

(define_insn_and_split “msa_vec_extract_<msafmt_f>” [(set (match_operand: 0 “register_operand” “=f”) (vec_select: (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 (mode == SFmode && !TARGET_ODD_SPREG && (REGNO (operands[1]) & 1)) { emit_move_insn (gen_rtx_REG (mode, REGNO (operands[0])), operands[1]); operands[1] = operands[0]; } else operands[1] = gen_rtx_REG (mode, REGNO (operands[1])); } [(set_attr “move_type” “fmove”) (set_attr “mode” “”)])

(define_expand “vec_set” [(match_operand:IMSA 0 “register_operand”) (match_operand: 1 “reg_or_0_operand”) (match_operand 2 “const__operand”)] “ISA_HAS_MSA” { rtx index = GEN_INT (1 << INTVAL (operands[2])); emit_insn (gen_msa_insert_ (operands[0], operands[1], operands[0], index)); DONE; })

(define_expand “vec_set” [(match_operand:FMSA 0 “register_operand”) (match_operand: 1 “register_operand”) (match_operand 2 “const__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 “vconduMSA:modeIMSA: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:MODEmode) == GET_MODE_NUNITS (IMSA:MODEmode))” { mips_expand_vec_cond_expr (MSA:MODEmode, MSA:VIMODEmode, operands); DONE; })

(define_expand “vcondMSA: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:MODEmode) == GET_MODE_NUNITS (<MSA_2:MODE>mode))” { mips_expand_vec_cond_expr (MSA:MODEmode, MSA:VIMODEmode, operands); DONE; })

(define_expand “vec_cmpMSA:mode<mode_i>” [(match_operand: 0 “register_operand”) (match_operator 1 "" [(match_operand:MSA 2 “register_operand”) (match_operand:MSA 3 “register_operand”)])] “ISA_HAS_MSA” { mips_expand_vec_cmp_expr (operands); DONE; })

(define_expand “vec_cmpuIMSA:mode<mode_i>” [(match_operand: 0 “register_operand”) (match_operator 1 "" [(match_operand:IMSA 2 “register_operand”) (match_operand:IMSA 3 “register_operand”)])] “ISA_HAS_MSA” { mips_expand_vec_cmp_expr (operands); DONE; })

(define_insn “msa_insert_<msafmt_f>” [(set (match_operand:MSA 0 “register_operand” “=f,f”) (vec_merge:MSA (vec_duplicate:MSA (match_operand: 1 “reg_or_0_operand” “dJ,f”)) (match_operand:MSA 2 “register_operand” “0,0”) (match_operand 3 “const__operand” "")))] “ISA_HAS_MSA” { if (which_alternative == 1) return “insve.\t%w0[%y3],%w1[0]”;

if (!TARGET_64BIT && (mode == V2DImode || mode == V2DFmode)) return “#”; else return “insert.\t%w0[%y3],%z1”; } [(set_attr “type” “simd_insert”) (set_attr “mode” “”)])

(define_split [(set (match_operand:MSA_D 0 “register_operand”) (vec_merge:MSA_D (vec_duplicate:MSA_D (match_operand: 1 “<MSA_D:msa_d>_operand”)) (match_operand:MSA_D 2 “register_operand”) (match_operand 3 “const__operand”)))] “reload_completed && ISA_HAS_MSA && !TARGET_64BIT” [(const_int 0)] { if (REG_P (operands[1]) && FP_REG_P (REGNO (operands[1]))) FAIL; 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: (match_operand:MSA 1 “register_operand” “f”) (parallel [(const_int 0)]))) (match_operand:MSA 2 “register_operand” “0”) (match_operand 3 “const__operand” "")))] “ISA_HAS_MSA” “insve.\t%w0[%y3],%w1[0]” [(set_attr “type” “simd_insert”) (set_attr “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: 1 “register_operand” “f”)) (match_operand:FMSA 2 “register_operand” “0”) (match_operand 3 “const__operand” "")))] “ISA_HAS_MSA” “insve.\t%w0[%y3],%w1[0]” [(set_attr “type” “simd_insert”) (set_attr “mode” “”)])

(define_insn “msa_copy__” [(set (match_operand: 0 “register_operand” “=d”) (any_extend: (vec_select: (match_operand:IMSA_HB 1 “register_operand” “f”) (parallel [(match_operand 2 “const__operand” "")]))))] “ISA_HAS_MSA” “copy_.\t%0,%w1[%2]” [(set_attr “type” “simd_copy”) (set_attr “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: (match_operand:MSA_W 1 “register_operand” “f”) (parallel [(match_operand 2 “const__operand” "")]))))] “ISA_HAS_MSA && TARGET_64BIT” “copy_s.\t%0,%w1[%2]” [(set_attr “type” “simd_copy”) (set_attr “mode” “”)])

(define_insn “msa_copy_s_<msafmt_f>” [(set (match_operand: 0 “register_operand” “=d”) (vec_select: (match_operand:MSA_W 1 “register_operand” “f”) (parallel [(match_operand 2 “const__operand” "")])))] “ISA_HAS_MSA” “copy_s.\t%0,%w1[%2]” [(set_attr “type” “simd_copy”) (set_attr “mode” “”)])

(define_insn_and_split “msa_copy_s_<msafmt_f>” [(set (match_operand: 0 “register_operand” “=d”) (vec_select: (match_operand:MSA_D 1 “register_operand” “f”) (parallel [(match_operand 2 “const__operand” "")])))] “ISA_HAS_MSA” { if (TARGET_64BIT) return “copy_s.\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” “”)])

(define_expand “abs2” [(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); emit_move_insn (reg, CONST0_RTX (mode)); emit_insn (gen_msa_add_a_ (operands[0], operands[1], reg)); DONE; })

(define_expand “neg2” [(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); emit_move_insn (reg, CONST0_RTX (mode)); operands[2] = reg; })

(define_expand “msa_ldi” [(match_operand:IMSA 0 “register_operand”) (match_operand 1 “const_imm10_operand”)] “ISA_HAS_MSA” { if (mode == V16QImode) operands[1] = GEN_INT (trunc_int_for_mode (INTVAL (operands[1]), mode)); emit_move_insn (operands[0], mips_gen_const_int_vector (mode, INTVAL (operands[1]))); DONE; })

(define_insn “vec_perm” [(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: 3 “register_operand” “0”)] UNSPEC_MSA_VSHF))] “ISA_HAS_MSA” “vshf.\t%w0,%w2,%w1” [(set_attr “type” “simd_sld”) (set_attr “mode” “”)])

(define_expand “mov” [(set (match_operand:MSA 0) (match_operand:MSA 1))] “ISA_HAS_MSA” { if (mips_legitimize_move (mode, operands[0], operands[1])) DONE; })

(define_expand “movmisalign” [(set (match_operand:MSA 0) (match_operand:MSA 1))] “ISA_HAS_MSA” { if (mips_legitimize_move (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_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” “”)])

(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_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, 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_operand”)] “ISA_HAS_MSA” { rtx addr = plus_constant (GET_MODE (operands[1]), operands[1], INTVAL (operands[2])); mips_emit_move (gen_rtx_MEM (mode, addr), operands[0]); DONE; })

;; Integer operations (define_insn “add3” [(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.\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” “”)])

(define_insn “sub3” [(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.\t%w0,%w1,%w2 subvi.\t%w0,%w1,%E2” [(set_attr “alu_type” “simd_add”) (set_attr “type” “simd_int_arith”) (set_attr “mode” “”)])

(define_insn “mul3” [(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.\t%w0,%w1,%w2” [(set_attr “type” “simd_mul”) (set_attr “mode” “”)])

(define_insn “msa_maddv_” [(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.\t%w0,%w1,%w2” [(set_attr “type” “simd_mul”) (set_attr “mode” “”)])

(define_insn “msa_msubv_” [(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.\t%w0,%w2,%w3” [(set_attr “type” “simd_mul”) (set_attr “mode” “”)])

(define_insn “div3” [(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.\t%w0,%w1,%w2”, operands); } [(set_attr “type” “simd_div”) (set_attr “mode” “”)])

(define_insn “udiv3” [(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.\t%w0,%w1,%w2”, operands); } [(set_attr “type” “simd_div”) (set_attr “mode” “”)])

(define_insn “mod3” [(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.\t%w0,%w1,%w2”, operands); } [(set_attr “type” “simd_div”) (set_attr “mode” “”)])

(define_insn “umod3” [(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.\t%w0,%w1,%w2”, operands); } [(set_attr “type” “simd_div”) (set_attr “mode” “”)])

(define_insn “xor3” [(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” “”)])

(define_insn “ior3” [(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” “”)])

(define_insn “and3” [(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, 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” “”)])

(define_insn “one_cmpl2” [(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 “vlshr3” [(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” { if (which_alternative == 0) return “srl.\t%w0,%w1,%w2”;

return mips_msa_output_shift_immediate(“srli.\t%w0,%w1,%E2”, operands); } [(set_attr “type” “simd_shift”) (set_attr “mode” “”)])

(define_insn “vashr3” [(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.\t%w0,%w1,%w2”;

return mips_msa_output_shift_immediate(“srai.\t%w0,%w1,%E2”, operands); } [(set_attr “type” “simd_shift”) (set_attr “mode” “”)])

(define_insn “vashl3” [(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.\t%w0,%w1,%w2”;

return mips_msa_output_shift_immediate(“slli.\t%w0,%w1,%E2”, operands); } [(set_attr “type” “simd_shift”) (set_attr “mode” “”)])

;; Floating-point operations (define_insn “add3” [(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.\t%w0,%w1,%w2” [(set_attr “type” “simd_fadd”) (set_attr “mode” “”)])

(define_insn “sub3” [(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.\t%w0,%w1,%w2” [(set_attr “type” “simd_fadd”) (set_attr “mode” “”)])

(define_insn “mul3” [(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.\t%w0,%w1,%w2” [(set_attr “type” “simd_fmul”) (set_attr “mode” “”)])

(define_insn “div3” [(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.\t%w0,%w1,%w2” [(set_attr “type” “simd_fdiv”) (set_attr “mode” “”)])

(define_insn “fma4” [(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.\t%w0,%w1,%w2” [(set_attr “type” “simd_fmadd”) (set_attr “mode” “”)])

(define_insn “fnma4” [(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.\t%w0,%w1,%w2” [(set_attr “type” “simd_fmadd”) (set_attr “mode” “”)])

(define_insn “sqrt2” [(set (match_operand:FMSA 0 “register_operand” “=f”) (sqrt:FMSA (match_operand:FMSA 1 “register_operand” “f”)))] “ISA_HAS_MSA” “fsqrt.\t%w0,%w1” [(set_attr “type” “simd_fdiv”) (set_attr “mode” “”)])

;; Built-in functions (define_insn “msa_add_a_” [(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.\t%w0,%w1,%w2” [(set_attr “type” “simd_int_arith”) (set_attr “mode” “”)])

(define_insn “msa_adds_a_” [(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.\t%w0,%w1,%w2” [(set_attr “type” “simd_int_arith”) (set_attr “mode” “”)])

(define_insn “ssadd3” [(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.\t%w0,%w1,%w2” [(set_attr “type” “simd_int_arith”) (set_attr “mode” “”)])

(define_insn “usadd3” [(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.\t%w0,%w1,%w2” [(set_attr “type” “simd_int_arith”) (set_attr “mode” “”)])

(define_insn “msa_asub_s_” [(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.\t%w0,%w1,%w2” [(set_attr “type” “simd_int_arith”) (set_attr “mode” “”)])

(define_insn “msa_asub_u_” [(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.\t%w0,%w1,%w2” [(set_attr “type” “simd_int_arith”) (set_attr “mode” “”)])

(define_insn “msa_ave_s_” [(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.\t%w0,%w1,%w2” [(set_attr “type” “simd_int_arith”) (set_attr “mode” “”)])

(define_insn “msa_ave_u_” [(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.\t%w0,%w1,%w2” [(set_attr “type” “simd_int_arith”) (set_attr “mode” “”)])

(define_insn “msa_aver_s_” [(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.\t%w0,%w1,%w2” [(set_attr “type” “simd_int_arith”) (set_attr “mode” “”)])

(define_insn “msa_aver_u_” [(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.\t%w0,%w1,%w2” [(set_attr “type” “simd_int_arith”) (set_attr “mode” “”)])

(define_insn “msa_bclr_” [(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.\t%w0,%w1,%w2” [(set_attr “type” “simd_bit”) (set_attr “mode” “”)])

(define_insn “msa_bclri_” [(set (match_operand:IMSA 0 “register_operand” “=f”) (unspec:IMSA [(match_operand:IMSA 1 “register_operand” “f”) (match_operand 2 “const__operand” "")] UNSPEC_MSA_BCLRI))] “ISA_HAS_MSA” “bclri.\t%w0,%w1,%2” [(set_attr “type” “simd_bit”) (set_attr “mode” “”)])

(define_insn “msa_binsl_” [(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.\t%w0,%w2,%w3” [(set_attr “type” “simd_bitins”) (set_attr “mode” “”)])

(define_insn “msa_binsli_” [(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__operand” "")] UNSPEC_MSA_BINSLI))] “ISA_HAS_MSA” “binsli.\t%w0,%w2,%3” [(set_attr “type” “simd_bitins”) (set_attr “mode” “”)])

(define_insn “msa_binsr_” [(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.\t%w0,%w2,%w3” [(set_attr “type” “simd_bitins”) (set_attr “mode” “”)])

(define_insn “msa_binsri_” [(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__operand” "")] UNSPEC_MSA_BINSRI))] “ISA_HAS_MSA” “binsri.\t%w0,%w2,%3” [(set_attr “type” “simd_bitins”) (set_attr “mode” “”)])

(define_insn “msa_bmnz_” [(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” “”)])

(define_insn “msa_bmz_” [(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” “”)])

(define_insn “msa_bneg_” [(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.\t%w0,%w1,%w2” [(set_attr “type” “simd_bit”) (set_attr “mode” “”)])

(define_insn “msa_bnegi_” [(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.\t%w0,%w1,%2” [(set_attr “type” “simd_bit”) (set_attr “mode” “”)])

(define_insn “msa_bsel_” [(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” “”)])

(define_insn “msa_bset_” [(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.\t%w0,%w1,%w2” [(set_attr “type” “simd_bit”) (set_attr “mode” “”)])

(define_insn “msa_bseti_” [(set (match_operand:IMSA 0 “register_operand” “=f”) (unspec:IMSA [(match_operand:IMSA 1 “register_operand” “f”) (match_operand 2 “const__operand” "")] UNSPEC_MSA_BSETI))] “ISA_HAS_MSA” “bseti.\t%w0,%w1,%2” [(set_attr “type” “simd_bit”) (set_attr “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_cICC: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:cmpiimm5_operand” “f,UICC:cmpiv5”)))] “ISA_HAS_MSA” “@ cICC:icc.IMSA:msafmt\t%w0,%w1,%w2 cICC:icci.IMSA:msafmt\t%w0,%w1,%E2” [(set_attr “type” “simd_int_arith”) (set_attr “mode” “”)])

(define_insn “msa_dotp__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_.d\t%w0,%w1,%w2” [(set_attr “type” “simd_mul”) (set_attr “mode” “V2DI”)])

(define_insn “msa_dotp__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_.w\t%w0,%w1,%w2” [(set_attr “type” “simd_mul”) (set_attr “mode” “V4SI”)])

(define_insn “msa_dotp__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_.h\t%w0,%w1,%w2” [(set_attr “type” “simd_mul”) (set_attr “mode” “V8HI”)])

(define_insn “msa_dpadd__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_.d\t%w0,%w2,%w3” [(set_attr “type” “simd_mul”) (set_attr “mode” “V2DI”)])

(define_insn “msa_dpadd__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_.w\t%w0,%w2,%w3” [(set_attr “type” “simd_mul”) (set_attr “mode” “V4SI”)])

(define_insn “msa_dpadd__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_.h\t%w0,%w2,%w3” [(set_attr “type” “simd_mul”) (set_attr “mode” “V8HI”)])

(define_insn “msa_dpsub__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_.d\t%w0,%w2,%w3” [(set_attr “type” “simd_mul”) (set_attr “mode” “V2DI”)])

(define_insn “msa_dpsub__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_.w\t%w0,%w2,%w3” [(set_attr “type” “simd_mul”) (set_attr “mode” “V4SI”)])

(define_insn “msa_dpsub__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_.h\t%w0,%w2,%w3” [(set_attr “type” “simd_mul”) (set_attr “mode” “V8HI”)])

(define_insn “msa_fclass_” [(set (match_operand: 0 “register_operand” “=f”) (unspec: [(match_operand:FMSA 1 “register_operand” “f”)] UNSPEC_MSA_FCLASS))] “ISA_HAS_MSA” “fclass.\t%w0,%w1” [(set_attr “type” “simd_fclass”) (set_attr “mode” “”)])

(define_insn “msa_fcaf_” [(set (match_operand: 0 “register_operand” “=f”) (unspec: [(match_operand:FMSA 1 “register_operand” “f”) (match_operand:FMSA 2 “register_operand” “f”)] UNSPEC_MSA_FCAF))] “ISA_HAS_MSA” “fcaf.\t%w0,%w1,%w2” [(set_attr “type” “simd_fcmp”) (set_attr “mode” “”)])

(define_insn “msa_fcune_FMSA:msafmt” [(set (match_operand: 0 “register_operand” “=f”) (unspec: [(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” “”)])

(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: 0 “register_operand” “=f”) (FCC: (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” “”)])

(define_insn “msa__FMSA:msafmt” [(set (match_operand: 0 “register_operand” “=f”) (unspec: [(match_operand:FMSA 1 “register_operand” “f”) (match_operand:FMSA 2 “register_operand” “f”)] FSC_UNS))] “ISA_HAS_MSA” “.FMSA:msafmt\t%w0,%w1,%w2” [(set_attr “type” “simd_fcmp”) (set_attr “mode” “”)])

(define_insn “msa_fexp2_” [(set (match_operand:FMSA 0 “register_operand” “=f”) (unspec:FMSA [(match_operand:FMSA 1 “register_operand” “f”) (match_operand: 2 “register_operand” “f”)] UNSPEC_MSA_FEXP2))] “ISA_HAS_MSA” “fexp2.\t%w0,%w1,%w2” [(set_attr “type” “simd_fexp2”) (set_attr “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 “floatFMSA:mode2” [(set (match_operand:FMSA 0 “register_operand” “=f”) (float:FMSA (match_operand: 1 “register_operand” “f”)))] “ISA_HAS_MSA” “ffint_s.\t%w0,%w1” [(set_attr “type” “simd_fcvt”) (set_attr “cnv_mode” “”) (set_attr “mode” “”)])

(define_insn “floatunsFMSA:mode2” [(set (match_operand:FMSA 0 “register_operand” “=f”) (unsigned_float:FMSA (match_operand: 1 “register_operand” “f”)))] “ISA_HAS_MSA” “ffint_u.\t%w0,%w1” [(set_attr “type” “simd_fcvt”) (set_attr “cnv_mode” “”) (set_attr “mode” “”)])

(define_mode_attr FFQ [(V4SF “V8HI”) (V2DF “V4SI”)])

(define_insn “msa_ffql_” [(set (match_operand:FMSA 0 “register_operand” “=f”) (unspec:FMSA [(match_operand: 1 “register_operand” “f”)] UNSPEC_MSA_FFQL))] “ISA_HAS_MSA” “ffql.\t%w0,%w1” [(set_attr “type” “simd_fcvt”) (set_attr “cnv_mode” “”) (set_attr “mode” “”)])

(define_insn “msa_ffqr_” [(set (match_operand:FMSA 0 “register_operand” “=f”) (unspec:FMSA [(match_operand: 1 “register_operand” “f”)] UNSPEC_MSA_FFQR))] “ISA_HAS_MSA” “ffqr.\t%w0,%w1” [(set_attr “type” “simd_fcvt”) (set_attr “cnv_mode” “”) (set_attr “mode” “”)])

(define_insn “msa_fill_<msafmt_f>” [(set (match_operand:MSA 0 “register_operand” “=f,f”) (vec_duplicate:MSA (match_operand: 1 “reg_or_0_operand” “d,J”)))] “ISA_HAS_MSA” { if (which_alternative == 1) return “ldi.\t%w0,0”;

if (!TARGET_64BIT && (mode == V2DImode || mode == V2DFmode)) return “#”; else return “fill.\t%w0,%z1”; } [(set_attr “type” “simd_fill”) (set_attr “mode” “”)])

(define_split [(set (match_operand:MSA_D 0 “register_operand”) (vec_duplicate:MSA_D (match_operand: 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_” [(set (match_operand:FMSA 0 “register_operand” “=f”) (unspec:FMSA [(match_operand:FMSA 1 “register_operand” “f”)] UNSPEC_MSA_FLOG2))] “ISA_HAS_MSA” “flog2.\t%w0,%w1” [(set_attr “type” “simd_flog2”) (set_attr “mode” “”)])

(define_insn “smax3” [(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.\t%w0,%w1,%w2” [(set_attr “type” “simd_fminmax”) (set_attr “mode” “”)])

(define_insn “msa_fmax_a_” [(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.\t%w0,%w1,%w2” [(set_attr “type” “simd_fminmax”) (set_attr “mode” “”)])

(define_insn “smin3” [(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.\t%w0,%w1,%w2” [(set_attr “type” “simd_fminmax”) (set_attr “mode” “”)])

(define_insn “msa_fmin_a_” [(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.\t%w0,%w1,%w2” [(set_attr “type” “simd_fminmax”) (set_attr “mode” “”)])

(define_insn “msa_frcp_” [(set (match_operand:FMSA 0 “register_operand” “=f”) (unspec:FMSA [(match_operand:FMSA 1 “register_operand” “f”)] UNSPEC_MSA_FRCP))] “ISA_HAS_MSA” “frcp.\t%w0,%w1” [(set_attr “type” “simd_fdiv”) (set_attr “mode” “”)])

(define_insn “msa_frint_” [(set (match_operand:FMSA 0 “register_operand” “=f”) (unspec:FMSA [(match_operand:FMSA 1 “register_operand” “f”)] UNSPEC_MSA_FRINT))] “ISA_HAS_MSA” “frint.\t%w0,%w1” [(set_attr “type” “simd_fcvt”) (set_attr “mode” “”)])

(define_insn “msa_frsqrt_” [(set (match_operand:FMSA 0 “register_operand” “=f”) (unspec:FMSA [(match_operand:FMSA 1 “register_operand” “f”)] UNSPEC_MSA_FRSQRT))] “ISA_HAS_MSA” “frsqrt.\t%w0,%w1” [(set_attr “type” “simd_fdiv”) (set_attr “mode” “”)])

(define_insn “msa_ftint_s_” [(set (match_operand: 0 “register_operand” “=f”) (unspec: [(match_operand:FMSA 1 “register_operand” “f”)] UNSPEC_MSA_FTINT_S))] “ISA_HAS_MSA” “ftint_s.\t%w0,%w1” [(set_attr “type” “simd_fcvt”) (set_attr “cnv_mode” “<FINTCNV_2>”) (set_attr “mode” “”)])

(define_insn “msa_ftint_u_” [(set (match_operand: 0 “register_operand” “=f”) (unspec: [(match_operand:FMSA 1 “register_operand” “f”)] UNSPEC_MSA_FTINT_U))] “ISA_HAS_MSA” “ftint_u.\t%w0,%w1” [(set_attr “type” “simd_fcvt”) (set_attr “cnv_mode” “<FINTCNV_2>”) (set_attr “mode” “”)])

(define_insn “fix_truncFMSA:mode<mode_i>2” [(set (match_operand: 0 “register_operand” “=f”) (fix: (match_operand:FMSA 1 “register_operand” “f”)))] “ISA_HAS_MSA” “ftrunc_s.\t%w0,%w1” [(set_attr “type” “simd_fcvt”) (set_attr “cnv_mode” “<FINTCNV_2>”) (set_attr “mode” “”)])

(define_insn “fixuns_truncFMSA:mode<mode_i>2” [(set (match_operand: 0 “register_operand” “=f”) (unsigned_fix: (match_operand:FMSA 1 “register_operand” “f”)))] “ISA_HAS_MSA” “ftrunc_u.\t%w0,%w1” [(set_attr “type” “simd_fcvt”) (set_attr “cnv_mode” “<FINTCNV_2>”) (set_attr “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__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_.h\t%w0,%w1,%w2” [(set_attr “type” “simd_int_arith”) (set_attr “mode” “V8HI”)])

(define_insn “msa_h__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_.w\t%w0,%w1,%w2” [(set_attr “type” “simd_int_arith”) (set_attr “mode” “V4SI”)])

(define_insn “msa_h__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_.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_” [(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.\t%w0,%w2,%w3” [(set_attr “type” “simd_mul”) (set_attr “mode” “”)])

(define_insn “msa_maddr_q_” [(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.\t%w0,%w2,%w3” [(set_attr “type” “simd_mul”) (set_attr “mode” “”)])

(define_insn “msa_max_a_” [(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.\t%w0,%w1,%w2” [(set_attr “type” “simd_int_arith”) (set_attr “mode” “”)])

(define_insn “smax3” [(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.\t%w0,%w1,%w2 maxi_s.\t%w0,%w1,%E2” [(set_attr “type” “simd_int_arith”) (set_attr “mode” “”)])

(define_insn “umax3” [(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.\t%w0,%w1,%w2 maxi_u.\t%w0,%w1,%B2” [(set_attr “type” “simd_int_arith”) (set_attr “mode” “”)])

(define_insn “msa_min_a_” [(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.\t%w0,%w1,%w2” [(set_attr “type” “simd_int_arith”) (set_attr “mode” “”)])

(define_insn “smin3” [(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.\t%w0,%w1,%w2 mini_s.\t%w0,%w1,%E2” [(set_attr “type” “simd_int_arith”) (set_attr “mode” “”)])

(define_insn “umin3” [(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.\t%w0,%w1,%w2 mini_u.\t%w0,%w1,%B2” [(set_attr “type” “simd_int_arith”) (set_attr “mode” “”)])

(define_insn “msa_msub_q_” [(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.\t%w0,%w2,%w3” [(set_attr “type” “simd_mul”) (set_attr “mode” “”)])

(define_insn “msa_msubr_q_” [(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.\t%w0,%w2,%w3” [(set_attr “type” “simd_mul”) (set_attr “mode” “”)])

(define_insn “msa_mul_q_” [(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.\t%w0,%w1,%w2” [(set_attr “type” “simd_mul”) (set_attr “mode” “”)])

(define_insn “msa_mulr_q_” [(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.\t%w0,%w1,%w2” [(set_attr “type” “simd_mul”) (set_attr “mode” “”)])

(define_insn “msa_nloc_” [(set (match_operand:IMSA 0 “register_operand” “=f”) (unspec:IMSA [(match_operand:IMSA 1 “register_operand” “f”)] UNSPEC_MSA_NLOC))] “ISA_HAS_MSA” “nloc.\t%w0,%w1” [(set_attr “type” “simd_bit”) (set_attr “mode” “”)])

(define_insn “clz2” [(set (match_operand:IMSA 0 “register_operand” “=f”) (clz:IMSA (match_operand:IMSA 1 “register_operand” “f”)))] “ISA_HAS_MSA” “nlzc.\t%w0,%w1” [(set_attr “type” “simd_bit”) (set_attr “mode” “”)])

(define_insn “msa_nor_” [(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” “”)])

(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 “popcount2” [(set (match_operand:IMSA 0 “register_operand” “=f”) (popcount:IMSA (match_operand:IMSA 1 “register_operand” “f”)))] “ISA_HAS_MSA” “pcnt.\t%w0,%w1” [(set_attr “type” “simd_pcnt”) (set_attr “mode” “”)])

(define_insn “msa_sat_s_” [(set (match_operand:IMSA 0 “register_operand” “=f”) (unspec:IMSA [(match_operand:IMSA 1 “register_operand” “f”) (match_operand 2 “const__operand” "")] UNSPEC_MSA_SAT_S))] “ISA_HAS_MSA” “sat_s.\t%w0,%w1,%2” [(set_attr “type” “simd_sat”) (set_attr “mode” “”)])

(define_insn “msa_sat_u_” [(set (match_operand:IMSA 0 “register_operand” “=f”) (unspec:IMSA [(match_operand:IMSA 1 “register_operand” “f”) (match_operand 2 “const__operand” "")] UNSPEC_MSA_SAT_U))] “ISA_HAS_MSA” “sat_u.\t%w0,%w1,%2” [(set_attr “type” “simd_sat”) (set_attr “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.\t%w0,%w1,%X2”; } [(set_attr “type” “simd_shf”) (set_attr “mode” “”)])

(define_insn “msa_srar_” [(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.\t%w0,%w1,%w2” [(set_attr “type” “simd_shift”) (set_attr “mode” “”)])

(define_insn “msa_srari_” [(set (match_operand:IMSA 0 “register_operand” “=f”) (unspec:IMSA [(match_operand:IMSA 1 “register_operand” “f”) (match_operand 2 “const__operand” "")] UNSPEC_MSA_SRARI))] “ISA_HAS_MSA” “srari.\t%w0,%w1,%2” [(set_attr “type” “simd_shift”) (set_attr “mode” “”)])

(define_insn “msa_srlr_” [(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.\t%w0,%w1,%w2” [(set_attr “type” “simd_shift”) (set_attr “mode” “”)])

(define_insn “msa_srlri_” [(set (match_operand:IMSA 0 “register_operand” “=f”) (unspec:IMSA [(match_operand:IMSA 1 “register_operand” “f”) (match_operand 2 “const__operand” "")] UNSPEC_MSA_SRLRI))] “ISA_HAS_MSA” “srlri.\t%w0,%w1,%2” [(set_attr “type” “simd_shift”) (set_attr “mode” “”)])

(define_insn “msa_subs_s_” [(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.\t%w0,%w1,%w2” [(set_attr “type” “simd_int_arith”) (set_attr “mode” “”)])

(define_insn “msa_subs_u_” [(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.\t%w0,%w1,%w2” [(set_attr “type” “simd_int_arith”) (set_attr “mode” “”)])

(define_insn “msa_subsuu_s_” [(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.\t%w0,%w1,%w2” [(set_attr “type” “simd_int_arith”) (set_attr “mode” “”)])

(define_insn “msa_subsus_u_” [(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.\t%w0,%w1,%w2” [(set_attr “type” “simd_int_arith”) (set_attr “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.\t%w0,%w2[%z3]” [(set_attr “type” “simd_sld”) (set_attr “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__operand” "")] UNSPEC_MSA_SLDI))] “ISA_HAS_MSA” “sldi.\t%w0,%w2[%3]” [(set_attr “type” “simd_sld”) (set_attr “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.\t%w0,%w1[%z2]” [(set_attr “type” “simd_splat”) (set_attr “mode” “”)])

(define_insn “msa_splati_<msafmt_f>” [(set (match_operand:MSA 0 “register_operand” “=f”) (vec_duplicate:MSA (vec_select: (match_operand:MSA 1 “register_operand” “f”) (parallel [(match_operand 2 “const__operand” "")]))))] “ISA_HAS_MSA” “splati.\t%w0,%w1[%2]” [(set_attr “type” “simd_splat”) (set_attr “mode” “”)])

(define_insn “msa_splati_<msafmt_f>_scalar” [(set (match_operand:FMSA 0 “register_operand” “=f”) (unspec:FMSA [(match_operand: 1 “register_operand” “f”)] UNSPEC_MSA_SPLATI))] “ISA_HAS_MSA” “splati.\t%w0,%w1[0]” [(set_attr “type” “simd_splat”) (set_attr “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__<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 (“.”, “%w1,%0”), MIPS_BRANCH (“<msabr_neg>.”, “%w1,%0”)); } [(set_attr “type” “simd_branch”) (set_attr “mode” “”) (set_attr “compact_form” “never”) (set_attr “branch_likely” “no”)])

(define_insn “msa_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 (“.v”, “%w1,%0”), MIPS_BRANCH (“<msabr_neg>.v”, “%w1,%0”)); } [(set_attr “type” “simd_branch”) (set_attr “mode” “TI”) (set_attr “compact_form” “never”) (set_attr “branch_likely” “no”)])