;; Machine Description for LARCH Loongson ASX ASE
;;
;; Copyright (C) 2018-2024 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
;; .
;;
(define_c_enum "unspec" [
UNSPEC_LASX_XVABSD_S
UNSPEC_LASX_XVABSD_U
UNSPEC_LASX_XVAVG_S
UNSPEC_LASX_XVAVG_U
UNSPEC_LASX_XVAVGR_S
UNSPEC_LASX_XVAVGR_U
UNSPEC_LASX_XVBITCLR
UNSPEC_LASX_XVBITCLRI
UNSPEC_LASX_XVBITREV
UNSPEC_LASX_XVBITREVI
UNSPEC_LASX_XVBITSET
UNSPEC_LASX_XVBITSETI
UNSPEC_LASX_XVFCLASS
UNSPEC_LASX_XVFCVT
UNSPEC_LASX_XVFCVTH
UNSPEC_LASX_XVFCVTL
UNSPEC_LASX_XVFLOGB
UNSPEC_LASX_XVFRECIP
UNSPEC_LASX_XVFRECIPE
UNSPEC_LASX_XVFRINT
UNSPEC_LASX_XVFRSQRT
UNSPEC_LASX_XVFRSQRTE
UNSPEC_LASX_XVFTINT_U
UNSPEC_LASX_XVCLO
UNSPEC_LASX_XVSAT_S
UNSPEC_LASX_XVSAT_U
UNSPEC_LASX_XVREPLVE0
UNSPEC_LASX_XVREPL128VEI
UNSPEC_LASX_XVSRAR
UNSPEC_LASX_XVSRARI
UNSPEC_LASX_XVSRLR
UNSPEC_LASX_XVSRLRI
UNSPEC_LASX_XVSHUF
UNSPEC_LASX_XVSHUF_B
UNSPEC_LASX_BRANCH
UNSPEC_LASX_BRANCH_V
UNSPEC_LASX_MXVEXTW_U
UNSPEC_LASX_XVSLLWIL_S
UNSPEC_LASX_XVSLLWIL_U
UNSPEC_LASX_XVSRAN
UNSPEC_LASX_XVSSRAN_S
UNSPEC_LASX_XVSSRAN_U
UNSPEC_LASX_XVSRARN
UNSPEC_LASX_XVSSRARN_S
UNSPEC_LASX_XVSSRARN_U
UNSPEC_LASX_XVSRLN
UNSPEC_LASX_XVSSRLN_U
UNSPEC_LASX_XVSRLRN
UNSPEC_LASX_XVSSRLRN_U
UNSPEC_LASX_XVFRSTPI
UNSPEC_LASX_XVFRSTP
UNSPEC_LASX_XVSHUF4I
UNSPEC_LASX_XVBSRL_V
UNSPEC_LASX_XVBSLL_V
UNSPEC_LASX_XVEXTRINS
UNSPEC_LASX_XVMSKLTZ
UNSPEC_LASX_XVSIGNCOV
UNSPEC_LASX_XVFTINT_W_D
UNSPEC_LASX_XVFFINT_S_L
UNSPEC_LASX_XVFTINTRZ_W_D
UNSPEC_LASX_XVFTINTRP_W_D
UNSPEC_LASX_XVFTINTRM_W_D
UNSPEC_LASX_XVFTINTRNE_W_D
UNSPEC_LASX_XVFTINTH_L_S
UNSPEC_LASX_XVFTINTL_L_S
UNSPEC_LASX_XVFFINTH_D_W
UNSPEC_LASX_XVFFINTL_D_W
UNSPEC_LASX_XVFTINTRZH_L_S
UNSPEC_LASX_XVFTINTRZL_L_S
UNSPEC_LASX_XVFTINTRPH_L_S
UNSPEC_LASX_XVFTINTRPL_L_S
UNSPEC_LASX_XVFTINTRMH_L_S
UNSPEC_LASX_XVFTINTRML_L_S
UNSPEC_LASX_XVFTINTRNEL_L_S
UNSPEC_LASX_XVFTINTRNEH_L_S
UNSPEC_LASX_XVREPLVE0_Q
UNSPEC_LASX_XVPERM_W
UNSPEC_LASX_XVPERMI_Q
UNSPEC_LASX_XVPERMI_D
UNSPEC_LASX_XVADDWEV
UNSPEC_LASX_XVADDWEV2
UNSPEC_LASX_XVADDWEV3
UNSPEC_LASX_XVSUBWEV
UNSPEC_LASX_XVSUBWEV2
UNSPEC_LASX_XVMULWEV
UNSPEC_LASX_XVMULWEV2
UNSPEC_LASX_XVMULWEV3
UNSPEC_LASX_XVADDWOD
UNSPEC_LASX_XVADDWOD2
UNSPEC_LASX_XVADDWOD3
UNSPEC_LASX_XVSUBWOD
UNSPEC_LASX_XVSUBWOD2
UNSPEC_LASX_XVMULWOD
UNSPEC_LASX_XVMULWOD2
UNSPEC_LASX_XVMULWOD3
UNSPEC_LASX_XVMADDWEV
UNSPEC_LASX_XVMADDWEV2
UNSPEC_LASX_XVMADDWEV3
UNSPEC_LASX_XVMADDWOD
UNSPEC_LASX_XVMADDWOD2
UNSPEC_LASX_XVMADDWOD3
UNSPEC_LASX_XVHADDW_Q_D
UNSPEC_LASX_XVHSUBW_Q_D
UNSPEC_LASX_XVHADDW_QU_DU
UNSPEC_LASX_XVHSUBW_QU_DU
UNSPEC_LASX_XVADD_Q
UNSPEC_LASX_XVSUB_Q
UNSPEC_LASX_XVREPLVE
UNSPEC_LASX_XVSHUF4
UNSPEC_LASX_XVMSKGEZ
UNSPEC_LASX_XVMSKNZ
UNSPEC_LASX_XVEXTH_Q_D
UNSPEC_LASX_XVEXTH_QU_DU
UNSPEC_LASX_XVEXTL_Q_D
UNSPEC_LASX_XVSRLNI
UNSPEC_LASX_XVSRLRNI
UNSPEC_LASX_XVSSRLNI
UNSPEC_LASX_XVSSRLNI2
UNSPEC_LASX_XVSSRLRNI
UNSPEC_LASX_XVSSRLRNI2
UNSPEC_LASX_XVSRANI
UNSPEC_LASX_XVSRARNI
UNSPEC_LASX_XVSSRANI
UNSPEC_LASX_XVSSRANI2
UNSPEC_LASX_XVSSRARNI
UNSPEC_LASX_XVSSRARNI2
UNSPEC_LASX_XVPERMI
UNSPEC_LASX_XVINSVE0
UNSPEC_LASX_XVPICKVE
UNSPEC_LASX_XVSSRLN
UNSPEC_LASX_XVSSRLRN
UNSPEC_LASX_XVEXTL_QU_DU
UNSPEC_LASX_XVLDI
UNSPEC_LASX_XVLDX
UNSPEC_LASX_XVSTX
UNSPEC_LASX_VECINIT_MERGE
UNSPEC_LASX_VEC_SET_INTERNAL
UNSPEC_LASX_XVILVL_INTERNAL
])
;; All vector modes with 256 bits.
(define_mode_iterator LASX [V4DF V8SF V4DI V8SI V16HI V32QI])
;; Same as LASX. Used by vcond to iterate two modes.
(define_mode_iterator LASX_2 [V4DF V8SF V4DI V8SI V16HI V32QI])
;; Only used for splitting insert_d and copy_{u,s}.d.
(define_mode_iterator LASX_D [V4DI V4DF])
;; Only used for splitting insert_d and copy_{u,s}.d.
(define_mode_iterator LASX_WD [V4DI V4DF V8SI V8SF])
;; Only used for copy256_{u,s}.w.
(define_mode_iterator LASX_W [V8SI V8SF])
;; As ILASX but excludes V32QI.
(define_mode_iterator ILASX_DWH [V4DI V8SI V16HI])
;; As LASX but excludes V32QI.
(define_mode_iterator LASX_DWH [V4DF V8SF V4DI V8SI V16HI])
;; As ILASX but excludes V4DI.
(define_mode_iterator ILASX_WHB [V8SI V16HI V32QI])
;; Only integer modes equal or larger than a word.
(define_mode_iterator ILASX_DW [V4DI V8SI])
;; Only integer modes smaller than a word.
(define_mode_iterator ILASX_HB [V16HI V32QI])
;; Only used for immediate set shuffle elements instruction.
(define_mode_iterator LASX_WHB_W [V8SI V16HI V32QI V8SF])
;; The attribute gives the integer vector mode with same size in Loongson ASX.
(define_mode_attr VIMODE256
[(V4DF "V4DI")
(V8SF "V8SI")
(V4DI "V4DI")
(V8SI "V8SI")
(V16HI "V16HI")
(V32QI "V32QI")])
;;attribute gives half modes for vector modes.
;;attribute gives half modes (Same Size) for vector modes.
(define_mode_attr VHSMODE256
[(V16HI "V32QI")
(V8SI "V16HI")
(V4DI "V8SI")])
;;attribute gives half modes for vector modes.
(define_mode_attr VHMODE256
[(V32QI "V16QI")
(V16HI "V8HI")
(V8SI "V4SI")
(V4DI "V2DI")])
;;attribute gives half float modes for vector modes.
(define_mode_attr VFHMODE256
[(V8SF "V4SF")
(V4DF "V2DF")])
;; The attribute gives half int/float modes for vector modes.
(define_mode_attr VHMODE256_ALL
[(V32QI "V16QI")
(V16HI "V8HI")
(V8SI "V4SI")
(V4DI "V2DI")
(V8SF "V4SF")
(V4DF "V2DF")])
;; The attribute gives double modes for vector modes in LASX.
(define_mode_attr VDMODE256
[(V8SI "V4DI")
(V16HI "V8SI")
(V32QI "V16HI")])
;; extended from VDMODE256
(define_mode_attr VDMODEEXD256
[(V4DI "V4DI")
(V8SI "V4DI")
(V16HI "V8SI")
(V32QI "V16HI")])
;; The attribute gives half modes with same number of elements for vector modes.
(define_mode_attr VTRUNCMODE256
[(V16HI "V16QI")
(V8SI "V8HI")
(V4DI "V4SI")])
;; Double-sized Vector MODE with same elemet type. "Vector, Enlarged-MODE"
(define_mode_attr VEMODE256
[(V8SF "V16SF")
(V8SI "V16SI")
(V4DF "V8DF")
(V4DI "V8DI")])
;; This attribute gives the mode of the result for "copy_s_b, copy_u_b" etc.
(define_mode_attr VRES256
[(V4DF "DF")
(V8SF "SF")
(V4DI "DI")
(V8SI "SI")
(V16HI "SI")
(V32QI "SI")])
;; Only used with LASX_D iterator.
(define_mode_attr lasx_d
[(V4DI "reg_or_0")
(V4DF "register")])
;; This attribute gives the 256 bit integer vector mode with same size.
(define_mode_attr mode256_i
[(V4DF "v4di")
(V8SF "v8si")
(V4DI "v4di")
(V8SI "v8si")
(V16HI "v16hi")
(V32QI "v32qi")])
;; This attribute gives the 256 bit float vector mode with same size.
(define_mode_attr mode256_f
[(V4DF "v4df")
(V8SF "v8sf")
(V4DI "v4df")
(V8SI "v8sf")])
;; This attribute gives V32QI mode and V16HI mode with half size.
(define_mode_attr mode256_i_half
[(V32QI "v16qi")
(V16HI "v8hi")])
;; This attribute gives suffix for LASX instructions. HOW?
(define_mode_attr lasxfmt
[(V4DF "d")
(V8SF "w")
(V4DI "d")
(V8SI "w")
(V16HI "h")
(V32QI "b")])
(define_mode_attr flasxfmt
[(V4DF "d")
(V8SF "s")])
(define_mode_attr lasxfmt_u
[(V4DF "du")
(V8SF "wu")
(V4DI "du")
(V8SI "wu")
(V16HI "hu")
(V32QI "bu")])
(define_mode_attr ilasxfmt
[(V4DF "l")
(V8SF "w")])
(define_mode_attr ilasxfmt_u
[(V4DF "lu")
(V8SF "wu")])
;; This attribute gives suffix for integers in VHMODE256.
(define_mode_attr hlasxfmt
[(V4DI "w")
(V8SI "h")
(V16HI "b")])
(define_mode_attr hlasxfmt_u
[(V4DI "wu")
(V8SI "hu")
(V16HI "bu")])
;; This attribute gives suffix for integers in VHSMODE256.
(define_mode_attr hslasxfmt
[(V4DI "w")
(V8SI "h")
(V16HI "b")])
;; This attribute gives define_insn suffix for LASX instructions that need
;; distinction between integer and floating point.
(define_mode_attr lasxfmt_f
[(V4DF "d_f")
(V8SF "w_f")
(V4DI "d")
(V8SI "w")
(V16HI "h")
(V32QI "b")])
(define_mode_attr flasxfmt_f
[(V4DF "d_f")
(V8SF "s_f")
(V4DI "d")
(V8SI "w")
(V16HI "h")
(V32QI "b")])
;; This attribute gives define_insn suffix for LASX instructions that need
;; distinction between integer and floating point.
(define_mode_attr lasxfmt_f_wd
[(V4DF "d_f")
(V8SF "w_f")
(V4DI "d")
(V8SI "w")])
;; This attribute gives suffix for integers in VHMODE256.
(define_mode_attr dlasxfmt
[(V8SI "d")
(V16HI "w")
(V32QI "h")])
(define_mode_attr dlasxfmt_u
[(V8SI "du")
(V16HI "wu")
(V32QI "hu")])
;; for VDMODEEXD256
(define_mode_attr dlasxqfmt
[(V4DI "q")
(V8SI "d")
(V16HI "w")
(V32QI "h")])
;; This is used to form an immediate operand constraint using
;; "const__operand".
(define_mode_attr indeximm256
[(V4DF "0_to_3")
(V8SF "0_to_7")
(V4DI "0_to_3")
(V8SI "0_to_7")
(V16HI "uimm4")
(V32QI "uimm5")])
;; This is used to form an immediate operand constraint using to ref high half
;; "const__operand".
(define_mode_attr indeximm_hi
[(V4DF "2_or_3")
(V8SF "4_to_7")
(V4DI "2_or_3")
(V8SI "4_to_7")
(V16HI "8_to_15")
(V32QI "16_to_31")])
;; This is used to form an immediate operand constraint using to ref low half
;; "const__operand".
(define_mode_attr indeximm_lo
[(V4DF "0_or_1")
(V8SF "0_to_3")
(V4DI "0_or_1")
(V8SI "0_to_3")
(V16HI "uimm3")
(V32QI "uimm4")])
;; This attribute represents bitmask needed for vec_merge using in lasx
;; "const__operand".
(define_mode_attr bitmask256
[(V4DF "exp_4")
(V8SF "exp_8")
(V4DI "exp_4")
(V8SI "exp_8")
(V16HI "exp_16")
(V32QI "exp_32")])
;; This attribute represents bitmask needed for vec_merge using to ref low half
;; "const__operand".
(define_mode_attr bitmask_lo
[(V4DF "exp_2")
(V8SF "exp_4")
(V4DI "exp_2")
(V8SI "exp_4")
(V16HI "exp_8")
(V32QI "exp_16")])
;; This attribute is used to form an immediate operand constraint using
;; "const__operand".
(define_mode_attr bitimm256
[(V32QI "uimm3")
(V16HI "uimm4")
(V8SI "uimm5")
(V4DI "uimm6")])
(define_mode_attr d2lasxfmt
[(V8SI "q")
(V16HI "d")
(V32QI "w")])
(define_mode_attr d2lasxfmt_u
[(V8SI "qu")
(V16HI "du")
(V32QI "wu")])
(define_mode_attr VD2MODE256
[(V8SI "V4DI")
(V16HI "V4DI")
(V32QI "V8SI")])
(define_mode_attr lasxfmt_wd
[(V4DI "d")
(V8SI "w")
(V16HI "w")
(V32QI "w")])
;; Half modes of all LASX vector modes, in lower-case.
(define_mode_attr lasxhalf [(V32QI "v16qi") (V16HI "v8hi")
(V8SI "v4si") (V4DI "v2di")
(V8SF "v4sf") (V4DF "v2df")])
(define_expand "vec_init"
[(match_operand:LASX 0 "register_operand")
(match_operand:LASX 1 "")]
"ISA_HAS_LASX"
{
loongarch_expand_vector_init (operands[0], operands[1]);
DONE;
})
(define_expand "vec_init"
[(match_operand:LASX 0 "register_operand")
(match_operand: 1 "")]
"ISA_HAS_LASX"
{
loongarch_expand_vector_group_init (operands[0], operands[1]);
DONE;
})
;; FIXME: Delete.
(define_insn "vec_pack_trunc_"
[(set (match_operand: 0 "register_operand" "=f")
(vec_concat:
(truncate:
(match_operand:ILASX_DWH 1 "register_operand" "f"))
(truncate:
(match_operand:ILASX_DWH 2 "register_operand" "f"))))]
"ISA_HAS_LASX"
"xvpickev.\t%u0,%u2,%u1\n\txvpermi.d\t%u0,%u0,0xd8"
[(set_attr "type" "simd_permute")
(set_attr "mode" "")
(set_attr "length" "8")])
(define_expand "vec_unpacks_hi_v8sf"
[(set (match_operand:V4DF 0 "register_operand" "=f")
(float_extend:V4DF
(vec_select:V4SF
(match_operand:V8SF 1 "register_operand" "f")
(match_dup 2))))]
"ISA_HAS_LASX"
{
operands[2] = loongarch_lsx_vec_parallel_const_half (V8SFmode,
true/*high_p*/);
})
(define_expand "vec_unpacks_lo_v8sf"
[(set (match_operand:V4DF 0 "register_operand" "=f")
(float_extend:V4DF
(vec_select:V4SF
(match_operand:V8SF 1 "register_operand" "f")
(match_dup 2))))]
"ISA_HAS_LASX"
{
operands[2] = loongarch_lsx_vec_parallel_const_half (V8SFmode,
false/*high_p*/);
})
(define_expand "vec_unpacks_hi_"
[(match_operand: 0 "register_operand")
(match_operand:ILASX_WHB 1 "register_operand")]
"ISA_HAS_LASX"
{
loongarch_expand_vec_unpack (operands, false/*unsigned_p*/,
true/*high_p*/);
DONE;
})
(define_expand "vec_unpacks_lo_"
[(match_operand: 0 "register_operand")
(match_operand:ILASX_WHB 1 "register_operand")]
"ISA_HAS_LASX"
{
loongarch_expand_vec_unpack (operands, false/*unsigned_p*/, false/*high_p*/);
DONE;
})
(define_expand "vec_unpacku_hi_"
[(match_operand: 0 "register_operand")
(match_operand:ILASX_WHB 1 "register_operand")]
"ISA_HAS_LASX"
{
loongarch_expand_vec_unpack (operands, true/*unsigned_p*/, true/*high_p*/);
DONE;
})
(define_expand "vec_unpacku_lo_"
[(match_operand: 0 "register_operand")
(match_operand:ILASX_WHB 1 "register_operand")]
"ISA_HAS_LASX"
{
loongarch_expand_vec_unpack (operands, true/*unsigned_p*/, false/*high_p*/);
DONE;
})
(define_insn "lasx_xvinsgr2vr_"
[(set (match_operand:ILASX_DW 0 "register_operand" "=f")
(vec_merge:ILASX_DW
(vec_duplicate:ILASX_DW
(match_operand: 1 "reg_or_0_operand" "rJ"))
(match_operand:ILASX_DW 2 "register_operand" "0")
(match_operand 3 "const__operand" "")))]
"ISA_HAS_LASX"
{
return "xvinsgr2vr.\t%u0,%z1,%y3";
}
[(set_attr "type" "simd_insert")
(set_attr "mode" "")])
(define_insn "vec_concat"
[(set (match_operand:LASX 0 "register_operand" "=f")
(vec_concat:LASX
(match_operand: 1 "register_operand" "0")
(match_operand: 2 "register_operand" "f")))]
"ISA_HAS_LASX"
{
return "xvpermi.q\t%u0,%u2,0x02";
}
[(set_attr "type" "simd_splat")
(set_attr "mode" "")])
;; xshuf.w
(define_insn "lasx_xvperm_"
[(set (match_operand:LASX_W 0 "register_operand" "=f")
(unspec:LASX_W
[(match_operand:LASX_W 1 "nonimmediate_operand" "f")
(match_operand:V8SI 2 "register_operand" "f")]
UNSPEC_LASX_XVPERM_W))]
"ISA_HAS_LASX"
"xvperm.w\t%u0,%u1,%u2"
[(set_attr "type" "simd_splat")
(set_attr "mode" "")])
;; xvpermi.d
(define_insn "lasx_xvpermi_d_"
[(set (match_operand:LASX 0 "register_operand" "=f")
(unspec:LASX
[(match_operand:LASX 1 "register_operand" "f")
(match_operand:SI 2 "const_uimm8_operand")]
UNSPEC_LASX_XVPERMI_D))]
"ISA_HAS_LASX"
"xvpermi.d\t%u0,%u1,%2"
[(set_attr "type" "simd_splat")
(set_attr "mode" "")])
(define_insn "lasx_xvpermi_d__1"
[(set (match_operand:LASX_D 0 "register_operand" "=f")
(vec_select:LASX_D
(match_operand:LASX_D 1 "register_operand" "f")
(parallel [(match_operand 2 "const_0_to_3_operand")
(match_operand 3 "const_0_to_3_operand")
(match_operand 4 "const_0_to_3_operand")
(match_operand 5 "const_0_to_3_operand")])))]
"ISA_HAS_LASX"
{
int mask = 0;
mask |= INTVAL (operands[2]) << 0;
mask |= INTVAL (operands[3]) << 2;
mask |= INTVAL (operands[4]) << 4;
mask |= INTVAL (operands[5]) << 6;
operands[2] = GEN_INT (mask);
return "xvpermi.d\t%u0,%u1,%2";
}
[(set_attr "type" "simd_splat")
(set_attr "mode" "")])
;; xvpermi.q
(define_insn "lasx_xvpermi_q_"
[(set (match_operand:LASX 0 "register_operand" "=f")
(unspec:LASX
[(match_operand:LASX 1 "register_operand" "0")
(match_operand:LASX 2 "register_operand" "f")
(match_operand 3 "const_uimm8_operand")]
UNSPEC_LASX_XVPERMI_Q))]
"ISA_HAS_LASX"
{
return "xvpermi.q\t%u0,%u2,%3";
}
[(set_attr "type" "simd_splat")
(set_attr "mode" "")])
;; Only for loongarch_expand_vector_init in loongarch.cc.
;; Support a LSX-mode input op2.
(define_insn "lasx_vecinit_merge_"
[(set (match_operand:LASX 0 "register_operand" "=f")
(unspec:LASX
[(match_operand:LASX 1 "register_operand" "0")
(match_operand: 2 "register_operand" "f")
(match_operand 3 "const_uimm8_operand")]
UNSPEC_LASX_VECINIT_MERGE))]
"ISA_HAS_LASX"
"xvpermi.q\t%u0,%u2,%3"
[(set_attr "type" "simd_splat")
(set_attr "mode" "")])
(define_insn "lasx_xvpickve2gr_d"
[(set (match_operand:DI 0 "register_operand" "=r")
(any_extend:DI
(vec_select:DI
(match_operand:V4DI 1 "register_operand" "f")
(parallel [(match_operand 2 "const_0_to_3_operand" "")]))))]
"ISA_HAS_LASX"
"xvpickve2gr.d\t%0,%u1,%2"
[(set_attr "type" "simd_copy")
(set_attr "mode" "V4DI")])
(define_expand "vec_set"
[(match_operand:ILASX_DW 0 "register_operand")
(match_operand: 1 "reg_or_0_operand")
(match_operand 2 "const__operand")]
"ISA_HAS_LASX"
{
rtx index = GEN_INT (1 << INTVAL (operands[2]));
emit_insn (gen_lasx_xvinsgr2vr_ (operands[0], operands[1],
operands[0], index));
DONE;
})
;; Only for loongarch_expand_vector_init in loongarch.cc.
;; Simulate missing instructions xvinsgr2vr.b and xvinsgr2vr.h.
(define_expand "vec_set_internal"
[(match_operand:ILASX_HB 0 "register_operand")
(match_operand: 1 "reg_or_0_operand")
(match_operand 2 "const__operand")]
"ISA_HAS_LASX"
{
rtx index = GEN_INT (1 << INTVAL (operands[2]));
emit_insn (gen_lasx_xvinsgr2vr__internal
(operands[0], operands[1], operands[0], index));
DONE;
})
(define_insn "lasx_xvinsgr2vr__internal"
[(set (match_operand:ILASX_HB 0 "register_operand" "=f")
(unspec:ILASX_HB [(match_operand: 1 "reg_or_0_operand" "rJ")
(match_operand:ILASX_HB 2 "register_operand" "0")
(match_operand 3 "const__operand" "")]
UNSPEC_LASX_VEC_SET_INTERNAL))]
"ISA_HAS_LASX"
{
return "vinsgr2vr.\t%w0,%z1,%y3";
}
[(set_attr "type" "simd_insert")
(set_attr "mode" "")])
(define_expand "vec_set"
[(match_operand:FLASX 0 "register_operand")
(match_operand: 1 "reg_or_0_operand")
(match_operand 2 "const__operand")]
"ISA_HAS_LASX"
{
rtx index = GEN_INT (1 << INTVAL (operands[2]));
emit_insn (gen_lasx_xvinsve0__scalar (operands[0], operands[1],
operands[0], index));
DONE;
})
(define_expand "vec_extract"
[(match_operand: 0 "register_operand")
(match_operand:LASX 1 "register_operand")
(match_operand 2 "const__operand")]
"ISA_HAS_LASX"
{
loongarch_expand_vector_extract (operands[0], operands[1],
INTVAL (operands[2]));
DONE;
})
(define_insn_and_split "vec_extract_0"
[(set (match_operand: 0 "register_operand" "=f")
(vec_select:
(match_operand:FLASX 1 "register_operand" "f")
(parallel [(const_int 0)])))]
"ISA_HAS_LSX"
"#"
"&& reload_completed"
[(set (match_dup 0) (match_dup 1))]
{
operands[1] = gen_rtx_REG (mode, REGNO (operands[1]));
}
[(set_attr "move_type" "fmove")
(set_attr "mode" "")])
(define_expand "vec_perm"
[(match_operand:LASX 0 "register_operand")
(match_operand:LASX 1 "register_operand")
(match_operand:LASX 2 "register_operand")
(match_operand: 3 "register_operand")]
"ISA_HAS_LASX"
{
loongarch_expand_vec_perm_1 (operands);
DONE;
})
;; FIXME: 256??
(define_expand "vcondu"
[(match_operand:LASX 0 "register_operand")
(match_operand:LASX 1 "reg_or_m1_operand")
(match_operand:LASX 2 "reg_or_0_operand")
(match_operator 3 ""
[(match_operand:ILASX 4 "register_operand")
(match_operand:ILASX 5 "register_operand")])]
"ISA_HAS_LASX
&& (GET_MODE_NUNITS (mode)
== GET_MODE_NUNITS (mode))"
{
loongarch_expand_vec_cond_expr (mode, mode,
operands);
DONE;
})
;; FIXME: 256??
(define_expand "vcond"
[(match_operand:LASX 0 "register_operand")
(match_operand:LASX 1 "reg_or_m1_operand")
(match_operand:LASX 2 "reg_or_0_operand")
(match_operator 3 ""
[(match_operand:LASX_2 4 "register_operand")
(match_operand:LASX_2 5 "register_operand")])]
"ISA_HAS_LASX
&& (GET_MODE_NUNITS (mode)
== GET_MODE_NUNITS (mode))"
{
loongarch_expand_vec_cond_expr (mode, mode,
operands);
DONE;
})
;; Same as vcond_
(define_expand "vcond_mask_"
[(match_operand:LASX 0 "register_operand")
(match_operand:LASX 1 "reg_or_m1_operand")
(match_operand:LASX 2 "reg_or_0_operand")
(match_operand: 3 "register_operand")]
"ISA_HAS_LASX"
{
loongarch_expand_vec_cond_mask_expr (mode,
mode, operands);
DONE;
})
(define_expand "lasx_xvrepli"
[(match_operand:ILASX 0 "register_operand")
(match_operand 1 "const_imm10_operand")]
"ISA_HAS_LASX"
{
if (mode == V32QImode)
operands[1] = GEN_INT (trunc_int_for_mode (INTVAL (operands[1]),
mode));
emit_move_insn (operands[0],
loongarch_gen_const_int_vector (mode, INTVAL (operands[1])));
DONE;
})
(define_expand "mov"
[(set (match_operand:LASX 0)
(match_operand:LASX 1))]
"ISA_HAS_LASX"
{
if (loongarch_legitimize_move (mode, operands[0], operands[1]))
DONE;
})
(define_expand "movmisalign"
[(set (match_operand:LASX 0)
(match_operand:LASX 1))]
"ISA_HAS_LASX"
{
if (loongarch_legitimize_move (mode, operands[0], operands[1]))
DONE;
})
;; 256-bit LASX modes can only exist in LASX registers or memory.
(define_insn "mov_lasx"
[(set (match_operand:LASX 0 "nonimmediate_operand" "=f,f,R,*r,*f")
(match_operand:LASX 1 "move_operand" "fYGYI,R,f,*f,*r"))]
"ISA_HAS_LASX"
{ return loongarch_output_move (operands[0], operands[1]); }
[(set_attr "type" "simd_move,simd_load,simd_store,simd_copy,simd_insert")
(set_attr "mode" "")
(set_attr "length" "8,4,4,4,4")])
(define_split
[(set (match_operand:LASX 0 "nonimmediate_operand")
(match_operand:LASX 1 "move_operand"))]
"reload_completed && ISA_HAS_LASX
&& loongarch_split_move_p (operands[0], operands[1])"
[(const_int 0)]
{
loongarch_split_move (operands[0], operands[1]);
DONE;
})
;; LASX
(define_insn "add3"
[(set (match_operand:ILASX 0 "register_operand" "=f,f,f")
(plus:ILASX
(match_operand:ILASX 1 "register_operand" "f,f,f")
(match_operand:ILASX 2 "reg_or_vector_same_ximm5_operand" "f,Unv5,Uuv5")))]
"ISA_HAS_LASX"
{
switch (which_alternative)
{
case 0:
return "xvadd.\t%u0,%u1,%u2";
case 1:
{
HOST_WIDE_INT val = INTVAL (CONST_VECTOR_ELT (operands[2], 0));
operands[2] = GEN_INT (-val);
return "xvsubi.\t%u0,%u1,%d2";
}
case 2:
return "xvaddi.\t%u0,%u1,%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:ILASX 0 "register_operand" "=f,f")
(minus:ILASX
(match_operand:ILASX 1 "register_operand" "f,f")
(match_operand:ILASX 2 "reg_or_vector_same_uimm5_operand" "f,Uuv5")))]
"ISA_HAS_LASX"
"@
xvsub.\t%u0,%u1,%u2
xvsubi.\t%u0,%u1,%E2"
[(set_attr "alu_type" "simd_add")
(set_attr "type" "simd_int_arith")
(set_attr "mode" "")])
(define_insn "mul3"
[(set (match_operand:ILASX 0 "register_operand" "=f")
(mult:ILASX (match_operand:ILASX 1 "register_operand" "f")
(match_operand:ILASX 2 "register_operand" "f")))]
"ISA_HAS_LASX"
"xvmul.\t%u0,%u1,%u2"
[(set_attr "type" "simd_mul")
(set_attr "mode" "")])
(define_insn "lasx_xvmadd_"
[(set (match_operand:ILASX 0 "register_operand" "=f")
(plus:ILASX (mult:ILASX (match_operand:ILASX 2 "register_operand" "f")
(match_operand:ILASX 3 "register_operand" "f"))
(match_operand:ILASX 1 "register_operand" "0")))]
"ISA_HAS_LASX"
"xvmadd.\t%u0,%u2,%u3"
[(set_attr "type" "simd_mul")
(set_attr "mode" "")])
(define_insn "lasx_xvmsub_"
[(set (match_operand:ILASX 0 "register_operand" "=f")
(minus:ILASX (match_operand:ILASX 1 "register_operand" "0")
(mult:ILASX (match_operand:ILASX 2 "register_operand" "f")
(match_operand:ILASX 3 "register_operand" "f"))))]
"ISA_HAS_LASX"
"xvmsub.\t%u0,%u2,%u3"
[(set_attr "type" "simd_mul")
(set_attr "mode" "")])
(define_insn "div3"
[(set (match_operand:ILASX 0 "register_operand" "=f")
(div:ILASX (match_operand:ILASX 1 "register_operand" "f")
(match_operand:ILASX 2 "register_operand" "f")))]
"ISA_HAS_LASX"
{
return loongarch_lsx_output_division ("xvdiv.\t%u0,%u1,%u2",
operands);
}
[(set_attr "type" "simd_div")
(set_attr "mode" "")])
(define_insn "udiv3"
[(set (match_operand:ILASX 0 "register_operand" "=f")
(udiv:ILASX (match_operand:ILASX 1 "register_operand" "f")
(match_operand:ILASX 2 "register_operand" "f")))]
"ISA_HAS_LASX"
{
return loongarch_lsx_output_division ("xvdiv.\t%u0,%u1,%u2",
operands);
}
[(set_attr "type" "simd_div")
(set_attr "mode" "")])
(define_insn "mod3"
[(set (match_operand:ILASX 0 "register_operand" "=f")
(mod:ILASX (match_operand:ILASX 1 "register_operand" "f")
(match_operand:ILASX 2 "register_operand" "f")))]
"ISA_HAS_LASX"
{
return loongarch_lsx_output_division ("xvmod.\t%u0,%u1,%u2",
operands);
}
[(set_attr "type" "simd_div")
(set_attr "mode" "")])
(define_insn "umod3"
[(set (match_operand:ILASX 0 "register_operand" "=f")
(umod:ILASX (match_operand:ILASX 1 "register_operand" "f")
(match_operand:ILASX 2 "register_operand" "f")))]
"ISA_HAS_LASX"
{
return loongarch_lsx_output_division ("xvmod.\t%u0,%u1,%u2",
operands);
}
[(set_attr "type" "simd_div")
(set_attr "mode" "")])
(define_insn "xor3"
[(set (match_operand:LASX 0 "register_operand" "=f,f,f")
(xor:LASX
(match_operand:LASX 1 "register_operand" "f,f,f")
(match_operand:LASX 2 "reg_or_vector_same_val_operand" "f,YC,Urv8")))]
"ISA_HAS_LASX"
"@
xvxor.v\t%u0,%u1,%u2
xvbitrevi.%v0\t%u0,%u1,%V2
xvxori.b\t%u0,%u1,%B2"
[(set_attr "type" "simd_logic,simd_bit,simd_logic")
(set_attr "mode" "")])
(define_insn "ior3"
[(set (match_operand:LASX 0 "register_operand" "=f,f,f")
(ior:LASX
(match_operand:LASX 1 "register_operand" "f,f,f")
(match_operand:LASX 2 "reg_or_vector_same_val_operand" "f,YC,Urv8")))]
"ISA_HAS_LASX"
"@
xvor.v\t%u0,%u1,%u2
xvbitseti.%v0\t%u0,%u1,%V2
xvori.b\t%u0,%u1,%B2"
[(set_attr "type" "simd_logic,simd_bit,simd_logic")
(set_attr "mode" "")])
(define_insn "and3"
[(set (match_operand:LASX 0 "register_operand" "=f,f,f")
(and:LASX
(match_operand:LASX 1 "register_operand" "f,f,f")
(match_operand:LASX 2 "reg_or_vector_same_val_operand" "f,YZ,Urv8")))]
"ISA_HAS_LASX"
{
switch (which_alternative)
{
case 0:
return "xvand.v\t%u0,%u1,%u2";
case 1:
{
rtx elt0 = CONST_VECTOR_ELT (operands[2], 0);
unsigned HOST_WIDE_INT val = ~UINTVAL (elt0);
operands[2] = loongarch_gen_const_int_vector (mode, val & (-val));
return "xvbitclri.%v0\t%u0,%u1,%V2";
}
case 2:
return "xvandi.b\t%u0,%u1,%B2";
default:
gcc_unreachable ();
}
}
[(set_attr "type" "simd_logic,simd_bit,simd_logic")
(set_attr "mode" "")])
(define_insn "one_cmpl2"
[(set (match_operand:ILASX 0 "register_operand" "=f")
(not:ILASX (match_operand:ILASX 1 "register_operand" "f")))]
"ISA_HAS_LASX"
"xvnor.v\t%u0,%u1,%u1"
[(set_attr "type" "simd_logic")
(set_attr "mode" "V32QI")])
;; LASX
(define_insn "vlshr3"
[(set (match_operand:ILASX 0 "register_operand" "=f,f")
(lshiftrt:ILASX
(match_operand:ILASX 1 "register_operand" "f,f")
(match_operand:ILASX 2 "reg_or_vector_same_uimm6_operand" "f,Uuv6")))]
"ISA_HAS_LASX"
"@
xvsrl.\t%u0,%u1,%u2
xvsrli.\t%u0,%u1,%E2"
[(set_attr "type" "simd_shift")
(set_attr "mode" "")])
;; LASX ">>"
(define_insn "vashr3"
[(set (match_operand:ILASX 0 "register_operand" "=f,f")
(ashiftrt:ILASX
(match_operand:ILASX 1 "register_operand" "f,f")
(match_operand:ILASX 2 "reg_or_vector_same_uimm6_operand" "f,Uuv6")))]
"ISA_HAS_LASX"
"@
xvsra.\t%u0,%u1,%u2
xvsrai.\t%u0,%u1,%E2"
[(set_attr "type" "simd_shift")
(set_attr "mode" "")])
;; LASX "<<"
(define_insn "vashl3"
[(set (match_operand:ILASX 0 "register_operand" "=f,f")
(ashift:ILASX
(match_operand:ILASX 1 "register_operand" "f,f")
(match_operand:ILASX 2 "reg_or_vector_same_uimm6_operand" "f,Uuv6")))]
"ISA_HAS_LASX"
"@
xvsll.\t%u0,%u1,%u2
xvslli.\t%u0,%u1,%E2"
[(set_attr "type" "simd_shift")
(set_attr "mode" "")])
(define_insn "add3"
[(set (match_operand:FLASX 0 "register_operand" "=f")
(plus:FLASX (match_operand:FLASX 1 "register_operand" "f")
(match_operand:FLASX 2 "register_operand" "f")))]
"ISA_HAS_LASX"
"xvfadd.\t%u0,%u1,%u2"
[(set_attr "type" "simd_fadd")
(set_attr "mode" "")])
(define_insn "sub3"
[(set (match_operand:FLASX 0 "register_operand" "=f")
(minus:FLASX (match_operand:FLASX 1 "register_operand" "f")
(match_operand:FLASX 2 "register_operand" "f")))]
"ISA_HAS_LASX"
"xvfsub.\t%u0,%u1,%u2"
[(set_attr "type" "simd_fadd")
(set_attr "mode" "")])
(define_insn "mul3"
[(set (match_operand:FLASX 0 "register_operand" "=f")
(mult:FLASX (match_operand:FLASX 1 "register_operand" "f")
(match_operand:FLASX 2 "register_operand" "f")))]
"ISA_HAS_LASX"
"xvfmul.\t%u0,%u1,%u2"
[(set_attr "type" "simd_fmul")
(set_attr "mode" "")])
(define_expand "div3"
[(set (match_operand:FLASX 0 "register_operand")
(div:FLASX (match_operand:FLASX 1 "reg_or_vecotr_1_operand")
(match_operand:FLASX 2 "register_operand")))]
"ISA_HAS_LASX"
{
if (mode == V8SFmode
&& TARGET_RECIP_VEC_DIV
&& optimize_insn_for_speed_p ()
&& flag_finite_math_only && !flag_trapping_math
&& flag_unsafe_math_optimizations)
{
loongarch_emit_swdivsf (operands[0], operands[1],
operands[2], V8SFmode);
DONE;
}
})
(define_insn "*div3"
[(set (match_operand:FLASX 0 "register_operand" "=f")
(div:FLASX (match_operand:FLASX 1 "register_operand" "f")
(match_operand:FLASX 2 "register_operand" "f")))]
"ISA_HAS_LASX"
"xvfdiv.\t%u0,%u1,%u2"
[(set_attr "type" "simd_fdiv")
(set_attr "mode" "")])
(define_insn "fma4"
[(set (match_operand:FLASX 0 "register_operand" "=f")
(fma:FLASX (match_operand:FLASX 1 "register_operand" "f")
(match_operand:FLASX 2 "register_operand" "f")
(match_operand:FLASX 3 "register_operand" "f")))]
"ISA_HAS_LASX"
"xvfmadd.\t%u0,%u1,%u2,%u3"
[(set_attr "type" "simd_fmadd")
(set_attr "mode" "")])
(define_insn "fnma4"
[(set (match_operand:FLASX 0 "register_operand" "=f")
(fma:FLASX (neg:FLASX (match_operand:FLASX 1 "register_operand" "f"))
(match_operand:FLASX 2 "register_operand" "f")
(match_operand:FLASX 3 "register_operand" "0")))]
"ISA_HAS_LASX"
"xvfnmsub.\t%u0,%u1,%u2,%u0"
[(set_attr "type" "simd_fmadd")
(set_attr "mode" "")])
(define_expand "sqrt2"
[(set (match_operand:FLASX 0 "register_operand")
(sqrt:FLASX (match_operand:FLASX 1 "register_operand")))]
"ISA_HAS_LASX"
{
if (mode == V8SFmode
&& TARGET_RECIP_VEC_SQRT
&& flag_unsafe_math_optimizations
&& optimize_insn_for_speed_p ()
&& flag_finite_math_only && !flag_trapping_math)
{
loongarch_emit_swrsqrtsf (operands[0], operands[1], V8SFmode, 0);
DONE;
}
})
(define_insn "*sqrt2"
[(set (match_operand:FLASX 0 "register_operand" "=f")
(sqrt:FLASX (match_operand:FLASX 1 "register_operand" "f")))]
"ISA_HAS_LASX"
"xvfsqrt.\t%u0,%u1"
[(set_attr "type" "simd_fdiv")
(set_attr "mode" "")])
(define_insn "lasx_xvadda_"
[(set (match_operand:ILASX 0 "register_operand" "=f")
(plus:ILASX (abs:ILASX (match_operand:ILASX 1 "register_operand" "f"))
(abs:ILASX (match_operand:ILASX 2 "register_operand" "f"))))]
"ISA_HAS_LASX"
"xvadda.\t%u0,%u1,%u2"
[(set_attr "type" "simd_int_arith")
(set_attr "mode" "")])
(define_insn "ssadd3"
[(set (match_operand:ILASX 0 "register_operand" "=f")
(ss_plus:ILASX (match_operand:ILASX 1 "register_operand" "f")
(match_operand:ILASX 2 "register_operand" "f")))]
"ISA_HAS_LASX"
"xvsadd.\t%u0,%u1,%u2"
[(set_attr "type" "simd_int_arith")
(set_attr "mode" "")])
(define_insn "usadd3"
[(set (match_operand:ILASX 0 "register_operand" "=f")
(us_plus:ILASX (match_operand:ILASX 1 "register_operand" "f")
(match_operand:ILASX 2 "register_operand" "f")))]
"ISA_HAS_LASX"
"xvsadd.\t%u0,%u1,%u2"
[(set_attr "type" "simd_int_arith")
(set_attr "mode" "")])
(define_insn "lasx_xvabsd_s_"
[(set (match_operand:ILASX 0 "register_operand" "=f")
(unspec:ILASX [(match_operand:ILASX 1 "register_operand" "f")
(match_operand:ILASX 2 "register_operand" "f")]
UNSPEC_LASX_XVABSD_S))]
"ISA_HAS_LASX"
"xvabsd.\t%u0,%u1,%u2"
[(set_attr "type" "simd_int_arith")
(set_attr "mode" "")])
(define_insn "lasx_xvabsd_u_"
[(set (match_operand:ILASX 0 "register_operand" "=f")
(unspec:ILASX [(match_operand:ILASX 1 "register_operand" "f")
(match_operand:ILASX 2 "register_operand" "f")]
UNSPEC_LASX_XVABSD_U))]
"ISA_HAS_LASX"
"xvabsd.\t%u0,%u1,%u2"
[(set_attr "type" "simd_int_arith")
(set_attr "mode" "")])
(define_insn "lasx_xvavg_s_"
[(set (match_operand:ILASX 0 "register_operand" "=f")
(unspec:ILASX [(match_operand:ILASX 1 "register_operand" "f")
(match_operand:ILASX 2 "register_operand" "f")]
UNSPEC_LASX_XVAVG_S))]
"ISA_HAS_LASX"
"xvavg.\t%u0,%u1,%u2"
[(set_attr "type" "simd_int_arith")
(set_attr "mode" "")])
(define_insn "lasx_xvavg_u_"
[(set (match_operand:ILASX 0 "register_operand" "=f")
(unspec:ILASX [(match_operand:ILASX 1 "register_operand" "f")
(match_operand:ILASX 2 "register_operand" "f")]
UNSPEC_LASX_XVAVG_U))]
"ISA_HAS_LASX"
"xvavg.\t%u0,%u1,%u2"
[(set_attr "type" "simd_int_arith")
(set_attr "mode" "")])
(define_insn "lasx_xvavgr_s_"
[(set (match_operand:ILASX 0 "register_operand" "=f")
(unspec:ILASX [(match_operand:ILASX 1 "register_operand" "f")
(match_operand:ILASX 2 "register_operand" "f")]
UNSPEC_LASX_XVAVGR_S))]
"ISA_HAS_LASX"
"xvavgr.\t%u0,%u1,%u2"
[(set_attr "type" "simd_int_arith")
(set_attr "mode" "")])
(define_insn "lasx_xvavgr_u_"
[(set (match_operand:ILASX 0 "register_operand" "=f")
(unspec:ILASX [(match_operand:ILASX 1 "register_operand" "f")
(match_operand:ILASX 2 "register_operand" "f")]
UNSPEC_LASX_XVAVGR_U))]
"ISA_HAS_LASX"
"xvavgr.\t%u0,%u1,%u2"
[(set_attr "type" "simd_int_arith")
(set_attr "mode" "")])
(define_insn "lasx_xvbitclr_"
[(set (match_operand:ILASX 0 "register_operand" "=f")
(unspec:ILASX [(match_operand:ILASX 1 "register_operand" "f")
(match_operand:ILASX 2 "register_operand" "f")]
UNSPEC_LASX_XVBITCLR))]
"ISA_HAS_LASX"
"xvbitclr.\t%u0,%u1,%u2"
[(set_attr "type" "simd_bit")
(set_attr "mode" "")])
(define_insn "lasx_xvbitclri_"
[(set (match_operand:ILASX 0 "register_operand" "=f")
(unspec:ILASX [(match_operand:ILASX 1 "register_operand" "f")
(match_operand 2 "const__operand" "")]
UNSPEC_LASX_XVBITCLRI))]
"ISA_HAS_LASX"
"xvbitclri.\t%u0,%u1,%2"
[(set_attr "type" "simd_bit")
(set_attr "mode" "")])
(define_insn "lasx_xvbitrev_"
[(set (match_operand:ILASX 0 "register_operand" "=f")
(unspec:ILASX [(match_operand:ILASX 1 "register_operand" "f")
(match_operand:ILASX 2 "register_operand" "f")]
UNSPEC_LASX_XVBITREV))]
"ISA_HAS_LASX"
"xvbitrev.\t%u0,%u1,%u2"
[(set_attr "type" "simd_bit")
(set_attr "mode" "")])
(define_insn "lasx_xvbitrevi_"
[(set (match_operand:ILASX 0 "register_operand" "=f")
(unspec:ILASX [(match_operand:ILASX 1 "register_operand" "f")
(match_operand 2 "const__operand" "")]
UNSPEC_LASX_XVBITREVI))]
"ISA_HAS_LASX"
"xvbitrevi.\t%u0,%u1,%2"
[(set_attr "type" "simd_bit")
(set_attr "mode" "")])
(define_insn "lasx_xvbitsel_"
[(set (match_operand:LASX 0 "register_operand" "=f")
(ior:LASX (and:LASX (not:LASX
(match_operand:LASX 3 "register_operand" "f"))
(match_operand:LASX 1 "register_operand" "f"))
(and:LASX (match_dup 3)
(match_operand:LASX 2 "register_operand" "f"))))]
"ISA_HAS_LASX"
"xvbitsel.v\t%u0,%u1,%u2,%u3"
[(set_attr "type" "simd_bitmov")
(set_attr "mode" "")])
(define_insn "lasx_xvbitseli_b"
[(set (match_operand:V32QI 0 "register_operand" "=f")
(ior:V32QI (and:V32QI (not:V32QI
(match_operand:V32QI 1 "register_operand" "0"))
(match_operand:V32QI 2 "register_operand" "f"))
(and:V32QI (match_dup 1)
(match_operand:V32QI 3 "const_vector_same_val_operand" "Urv8"))))]
"ISA_HAS_LASX"
"xvbitseli.b\t%u0,%u2,%B3"
[(set_attr "type" "simd_bitmov")
(set_attr "mode" "V32QI")])
(define_insn "lasx_xvbitset_"
[(set (match_operand:ILASX 0 "register_operand" "=f")
(unspec:ILASX [(match_operand:ILASX 1 "register_operand" "f")
(match_operand:ILASX 2 "register_operand" "f")]
UNSPEC_LASX_XVBITSET))]
"ISA_HAS_LASX"
"xvbitset.\t%u0,%u1,%u2"
[(set_attr "type" "simd_bit")
(set_attr "mode" "")])
(define_insn "lasx_xvbitseti_"
[(set (match_operand:ILASX 0 "register_operand" "=f")
(unspec:ILASX [(match_operand:ILASX 1 "register_operand" "f")
(match_operand 2 "const__operand" "")]
UNSPEC_LASX_XVBITSETI))]
"ISA_HAS_LASX"
"xvbitseti.\t%u0,%u1,%2"
[(set_attr "type" "simd_bit")
(set_attr "mode" "")])
(define_insn "lasx_xvs_"
[(set (match_operand:ILASX 0 "register_operand" "=f,f")
(ICC:ILASX
(match_operand:ILASX 1 "register_operand" "f,f")
(match_operand:ILASX 2 "reg_or_vector_same_imm5_operand" "f,Uv5")))]
"ISA_HAS_LASX"
"@
xvs.\t%u0,%u1,%u2
xvs.\t%u0,%u1,%E2"
[(set_attr "type" "simd_int_arith")
(set_attr "mode" "")])
(define_expand "vec_cmp"
[(set (match_operand: 0 "register_operand")
(match_operator 1 ""
[(match_operand:LASX 2 "register_operand")
(match_operand:LASX 3 "register_operand")]))]
"ISA_HAS_LASX"
{
loongarch_expand_vec_cmp (operands);
DONE;
})
(define_expand "vec_cmpu"
[(set (match_operand: 0 "register_operand")
(match_operator 1 ""
[(match_operand:ILASX 2 "register_operand")
(match_operand:ILASX 3 "register_operand")]))]
"ISA_HAS_LASX"
{
loongarch_expand_vec_cmp (operands);
DONE;
})
(define_insn "lasx_xvfclass_"
[(set (match_operand: 0 "register_operand" "=f")
(unspec: [(match_operand:FLASX 1 "register_operand" "f")]
UNSPEC_LASX_XVFCLASS))]
"ISA_HAS_LASX"
"xvfclass.\t%u0,%u1"
[(set_attr "type" "simd_fclass")
(set_attr "mode" "")])
(define_mode_attr fint256
[(V8SF "v8si")
(V4DF "v4di")])
(define_mode_attr FINTCNV256
[(V8SF "I2S")
(V4DF "I2D")])
(define_mode_attr FINTCNV256_2
[(V8SF "S2I")
(V4DF "D2I")])
(define_insn "float2"
[(set (match_operand:FLASX 0 "register_operand" "=f")
(float:FLASX (match_operand: 1 "register_operand" "f")))]
"ISA_HAS_LASX"
"xvffint.