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
(set_attr "cnv_mode" "<FINTCNV256_2>")
(set_attr "mode" "<MODE>")])
-(define_insn "lasx_xvh<optab>w_h<u>_b<u>"
- [(set (match_operand:V16HI 0 "register_operand" "=f")
- (addsub:V16HI
- (any_extend:V16HI
- (vec_select:V16QI
- (match_operand:V32QI 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)
- (const_int 17) (const_int 19)
- (const_int 21) (const_int 23)
- (const_int 25) (const_int 27)
- (const_int 29) (const_int 31)])))
- (any_extend:V16HI
- (vec_select:V16QI
- (match_operand:V32QI 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_LASX"
- "xvh<optab>w.h<u>.b<u>\t%u0,%u1,%u2"
- [(set_attr "type" "simd_int_arith")
- (set_attr "mode" "V16HI")])
-
-(define_insn "lasx_xvh<optab>w_w<u>_h<u>"
- [(set (match_operand:V8SI 0 "register_operand" "=f")
- (addsub:V8SI
- (any_extend:V8SI
- (vec_select:V8HI
- (match_operand:V16HI 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:V8SI
- (vec_select:V8HI
- (match_operand:V16HI 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_LASX"
- "xvh<optab>w.w<u>.h<u>\t%u0,%u1,%u2"
- [(set_attr "type" "simd_int_arith")
- (set_attr "mode" "V8SI")])
-
-(define_insn "lasx_xvh<optab>w_d<u>_w<u>"
- [(set (match_operand:V4DI 0 "register_operand" "=f")
- (addsub:V4DI
- (any_extend:V4DI
- (vec_select:V4SI
- (match_operand:V8SI 1 "register_operand" "f")
- (parallel [(const_int 1) (const_int 3)
- (const_int 5) (const_int 7)])))
- (any_extend:V4DI
- (vec_select:V4SI
- (match_operand:V8SI 2 "register_operand" "f")
- (parallel [(const_int 0) (const_int 2)
- (const_int 4) (const_int 6)])))))]
- "ISA_HAS_LASX"
- "xvh<optab>w.d<u>.w<u>\t%u0,%u1,%u2"
- [(set_attr "type" "simd_int_arith")
- (set_attr "mode" "V4DI")])
-
(define_insn "lasx_xvpackev_b"
[(set (match_operand:V32QI 0 "register_operand" "=f")
(vec_select:V32QI
[(set_attr "type" "simd_int_arith")
(set_attr "mode" "V4DI")])
-;;XVHADDW.Q.D
-;;TODO2
-(define_insn "lasx_xvhaddw_q_d"
- [(set (match_operand:V4DI 0 "register_operand" "=f")
- (unspec:V4DI [(match_operand:V4DI 1 "register_operand" "f")
- (match_operand:V4DI 2 "register_operand" "f")]
- UNSPEC_LASX_XVHADDW_Q_D))]
- "ISA_HAS_LASX"
- "xvhaddw.q.d\t%u0,%u1,%u2"
- [(set_attr "type" "simd_int_arith")
- (set_attr "mode" "V4DI")])
-
-;;XVHSUBW.Q.D
-;;TODO2
-(define_insn "lasx_xvhsubw_q_d"
- [(set (match_operand:V4DI 0 "register_operand" "=f")
- (unspec:V4DI [(match_operand:V4DI 1 "register_operand" "f")
- (match_operand:V4DI 2 "register_operand" "f")]
- UNSPEC_LASX_XVHSUBW_Q_D))]
- "ISA_HAS_LASX"
- "xvhsubw.q.d\t%u0,%u1,%u2"
- [(set_attr "type" "simd_int_arith")
- (set_attr "mode" "V4DI")])
-
-;;XVHADDW.QU.DU
-;;TODO2
-(define_insn "lasx_xvhaddw_qu_du"
- [(set (match_operand:V4DI 0 "register_operand" "=f")
- (unspec:V4DI [(match_operand:V4DI 1 "register_operand" "f")
- (match_operand:V4DI 2 "register_operand" "f")]
- UNSPEC_LASX_XVHADDW_QU_DU))]
- "ISA_HAS_LASX"
- "xvhaddw.qu.du\t%u0,%u1,%u2"
- [(set_attr "type" "simd_int_arith")
- (set_attr "mode" "V4DI")])
-
-;;XVHSUBW.QU.DU
-;;TODO2
-(define_insn "lasx_xvhsubw_qu_du"
- [(set (match_operand:V4DI 0 "register_operand" "=f")
- (unspec:V4DI [(match_operand:V4DI 1 "register_operand" "f")
- (match_operand:V4DI 2 "register_operand" "f")]
- UNSPEC_LASX_XVHSUBW_QU_DU))]
- "ISA_HAS_LASX"
- "xvhsubw.qu.du\t%u0,%u1,%u2"
- [(set_attr "type" "simd_int_arith")
- (set_attr "mode" "V4DI")])
-
;;XVADD.Q
;;TODO2
(define_insn "lasx_xvadd_q"
rtx tmp = gen_reg_rtx (V4DImode);
rtx tmp1 = gen_reg_rtx (V4DImode);
rtx vec_res = gen_reg_rtx (V4DImode);
- emit_insn (gen_lasx_xvhaddw_q_d (tmp, operands[1], operands[1]));
+ emit_insn (gen_lasx_haddw_q_d_punned (tmp, operands[1], operands[1]));
emit_insn (gen_lasx_xvpermi_d_v4di (tmp1, tmp, GEN_INT (2)));
emit_insn (gen_addv4di3 (vec_res, tmp, tmp1));
emit_insn (gen_vec_extractv4didi (operands[0], vec_res, const0_rtx));
rtx tmp1 = gen_reg_rtx (V4DImode);
rtx vec_res = gen_reg_rtx (V4DImode);
emit_insn (gen_lasx_xvhaddw_d_w (tmp, operands[1], operands[1]));
- emit_insn (gen_lasx_xvhaddw_q_d (tmp1, tmp, tmp));
+ emit_insn (gen_lasx_haddw_q_d_punned (tmp1, tmp, tmp));
emit_insn (gen_lasx_xvpermi_d_v4di (tmp, tmp1, GEN_INT (2)));
emit_insn (gen_addv4di3 (vec_res, tmp, tmp1));
emit_insn (gen_vec_extractv8sisi (operands[0], gen_lowpart (V8SImode,vec_res),
#define CODE_FOR_lsx_vaddwod_q_du_d CODE_FOR_lsx_addwod_q_du_d_punned
#define CODE_FOR_lsx_vmulwod_q_du_d CODE_FOR_lsx_mulwod_q_du_d_punned
+#define CODE_FOR_lsx_vhaddw_q_d CODE_FOR_lsx_haddw_q_d_punned
+#define CODE_FOR_lsx_vhaddw_qu_du CODE_FOR_lsx_haddw_qu_du_punned
+#define CODE_FOR_lsx_vhsubw_q_d CODE_FOR_lsx_hsubw_q_d_punned
+#define CODE_FOR_lsx_vhsubw_qu_du CODE_FOR_lsx_hsubw_qu_du_punned
+
/* LoongArch ASX define CODE_FOR_lasx_mxxx */
#define CODE_FOR_lasx_xvsadd_b CODE_FOR_ssaddv32qi3
#define CODE_FOR_lasx_xvsadd_h CODE_FOR_ssaddv16hi3
#define CODE_FOR_lasx_xvaddwod_q_du_d CODE_FOR_lasx_addwod_q_du_d_punned
#define CODE_FOR_lasx_xvmulwod_q_du_d CODE_FOR_lasx_mulwod_q_du_d_punned
+#define CODE_FOR_lasx_xvhaddw_q_d CODE_FOR_lasx_haddw_q_d_punned
+#define CODE_FOR_lasx_xvhaddw_qu_du CODE_FOR_lasx_haddw_qu_du_punned
+#define CODE_FOR_lasx_xvhsubw_q_d CODE_FOR_lasx_hsubw_q_d_punned
+#define CODE_FOR_lasx_xvhsubw_qu_du CODE_FOR_lasx_hsubw_qu_du_punned
+
static const struct loongarch_builtin_description loongarch_builtins[] = {
#define LARCH_MOVFCSR2GR 0
DIRECT_BUILTIN (movfcsr2gr, LARCH_USI_FTYPE_UQI, hard_float),
UNSPEC_LSX_VSTX
UNSPEC_LSX_VEXTL_QU_DU
UNSPEC_LSX_VSETEQZ_V
- UNSPEC_LSX_VHADDW_Q_D
- UNSPEC_LSX_VHADDW_QU_DU
- UNSPEC_LSX_VHSUBW_Q_D
- UNSPEC_LSX_VHSUBW_QU_DU
UNSPEC_LSX_VMADDWEV
UNSPEC_LSX_VMADDWEV2
UNSPEC_LSX_VMADDWEV3
(set_attr "cnv_mode" "<FINTCNV_2>")
(set_attr "mode" "<MODE>")])
-(define_insn "lsx_vh<optab>w_h<u>_b<u>"
- [(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_LSX"
- "vh<optab>w.h<u>.b<u>\t%w0,%w1,%w2"
- [(set_attr "type" "simd_int_arith")
- (set_attr "mode" "V8HI")])
-
-(define_insn "lsx_vh<optab>w_w<u>_h<u>"
- [(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_LSX"
- "vh<optab>w.w<u>.h<u>\t%w0,%w1,%w2"
- [(set_attr "type" "simd_int_arith")
- (set_attr "mode" "V4SI")])
-
-(define_insn "lsx_vh<optab>w_d<u>_w<u>"
- [(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_LSX"
- "vh<optab>w.d<u>.w<u>\t%w0,%w1,%w2"
- [(set_attr "type" "simd_int_arith")
- (set_attr "mode" "V2DI")])
-
(define_insn "lsx_vpackev_b"
[(set (match_operand:V16QI 0 "register_operand" "=f")
(vec_select:V16QI
(match_operand:V2DI 1 "register_operand")]
"ISA_HAS_LSX"
{
- rtx tmp = gen_reg_rtx (V2DImode);
+ rtx tmp = gen_reg_rtx (V1TImode);
emit_insn (gen_lsx_vhaddw_q_d (tmp, operands[1], operands[1]));
- emit_insn (gen_vec_extractv2didi (operands[0], tmp, const0_rtx));
+ emit_insn (gen_vec_extractv2didi (operands[0],
+ gen_lowpart (V2DImode, tmp),
+ const0_rtx));
DONE;
})
"ISA_HAS_LSX"
{
rtx tmp = gen_reg_rtx (V2DImode);
- rtx tmp1 = gen_reg_rtx (V2DImode);
+ rtx tmp1 = gen_reg_rtx (V1TImode);
emit_insn (gen_lsx_vhaddw_d_w (tmp, operands[1], operands[1]));
emit_insn (gen_lsx_vhaddw_q_d (tmp1, tmp, tmp));
emit_insn (gen_vec_extractv4sisi (operands[0], gen_lowpart (V4SImode,tmp1),
DONE;
})
-(define_insn "lsx_vhaddw_q_d"
- [(set (match_operand:V2DI 0 "register_operand" "=f")
- (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f")
- (match_operand:V2DI 2 "register_operand" "f")]
- UNSPEC_LSX_VHADDW_Q_D))]
- "ISA_HAS_LSX"
- "vhaddw.q.d\t%w0,%w1,%w2"
- [(set_attr "type" "simd_int_arith")
- (set_attr "mode" "V2DI")])
-
-(define_insn "lsx_vhaddw_qu_du"
- [(set (match_operand:V2DI 0 "register_operand" "=f")
- (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f")
- (match_operand:V2DI 2 "register_operand" "f")]
- UNSPEC_LSX_VHADDW_QU_DU))]
- "ISA_HAS_LSX"
- "vhaddw.qu.du\t%w0,%w1,%w2"
- [(set_attr "type" "simd_int_arith")
- (set_attr "mode" "V2DI")])
-
-(define_insn "lsx_vhsubw_q_d"
- [(set (match_operand:V2DI 0 "register_operand" "=f")
- (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f")
- (match_operand:V2DI 2 "register_operand" "f")]
- UNSPEC_LSX_VHSUBW_Q_D))]
- "ISA_HAS_LSX"
- "vhsubw.q.d\t%w0,%w1,%w2"
- [(set_attr "type" "simd_int_arith")
- (set_attr "mode" "V2DI")])
-
-(define_insn "lsx_vhsubw_qu_du"
- [(set (match_operand:V2DI 0 "register_operand" "=f")
- (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "f")
- (match_operand:V2DI 2 "register_operand" "f")]
- UNSPEC_LSX_VHSUBW_QU_DU))]
- "ISA_HAS_LSX"
- "vhsubw.qu.du\t%w0,%w1,%w2"
- [(set_attr "type" "simd_int_arith")
- (set_attr "mode" "V2DI")])
-
(define_insn "lsx_vmaddwev_d_w<u>"
[(set (match_operand:V2DI 0 "register_operand" "=f")
(plus:V2DI
DONE;
})
+(define_insn "simd_h<optab>w_<mode>_<su>"
+ [(set (match_operand:<WVEC_HALF> 0 "register_operand" "=f")
+ (addsub:<WVEC_HALF>
+ (any_extend:<WVEC_HALF>
+ (vec_select:<VEC_HALF>
+ (match_operand:IVEC 1 "register_operand" "f")
+ (match_operand:IVEC 3 "vect_par_cnst_even_or_odd_half")))
+ (any_extend:<WVEC_HALF>
+ (vec_select:<VEC_HALF>
+ (match_operand:IVEC 2 "register_operand" "f")
+ (match_operand:IVEC 4 "vect_par_cnst_even_or_odd_half")))))]
+ "!rtx_equal_p (operands[3], operands[4])"
+{
+ if (!INTVAL (XVECEXP (operands[3], 0, 0)))
+ std::swap (operands[1], operands[2]);
+ return "<x>vh<optab>w.<simdfmt_w><u>.<simdfmt><u>\t%<wu>0,%<wu>1,%<wu>2";
+}
+ [(set_attr "type" "simd_int_arith")
+ (set_attr "mode" "<WVEC_HALF>")])
+
+(define_expand "<simd_isa>_<x>vh<optab>w_<simdfmt_w><u>_<simdfmt><u>"
+ [(match_operand:<WVEC_HALF> 0 "register_operand" "=f")
+ (match_operand:IVEC 1 "register_operand" " f")
+ (match_operand:IVEC 2 "register_operand" " f")
+ (any_extend (const_int 0))
+ (addsub (const_int 0) (const_int 0))]
+ ""
+{
+ int nelts = GET_MODE_NUNITS (<WVEC_HALF>mode);
+ rtx op3 = loongarch_gen_stepped_int_parallel (nelts, 1, 2);
+ rtx op4 = loongarch_gen_stepped_int_parallel (nelts, 0, 2);
+ rtx insn = gen_simd_h<optab>w_<mode>_<su> (operands[0], operands[1],
+ operands[2], op3, op4);
+ emit_insn (insn);
+ DONE;
+})
+
; For "historical" reason we need a punned version of q_d variants.
(define_mode_iterator DIVEC [(V2DI "ISA_HAS_LSX") (V4DI "ISA_HAS_LASX")])
DONE;
})
+(define_expand "<simd_isa>_h<optab>w_q<u>_d<u>_punned"
+ [(match_operand:DIVEC 0 "register_operand" "=f")
+ (match_operand:DIVEC 1 "register_operand" "f")
+ (match_operand:DIVEC 2 "register_operand" "f")
+ (any_extend (const_int 0))
+ (addsub (const_int 0) (const_int 0))]
+ ""
+{
+ rtx t = gen_reg_rtx (<WVEC_HALF>mode);
+ emit_insn (gen_<simd_isa>_<x>vh<optab>w_q<u>_d<u> (t, operands[1],
+ operands[2]));
+ emit_move_insn (operands[0], gen_lowpart (<MODE>mode, t));
+ DONE;
+})
+
; The LoongArch SX Instructions.
(include "lsx.md")