This patch will cause gcc.dg/vect/bb-slp-35.c test to fail.
gcc/ChangeLog:
* config/loongarch/lasx.md (hi_lo): Move to ...
* config/loongarch/simd.md (hi_lo): ... here.
* config/loongarch/loongarch.cc
(loongarch_expand_vec_widen_hilo): Add 128-bit data processing.
* config/loongarch/lsx.md
(vec_widen_<su><optab>_<hi_lo>_<mode>): New define_expand.
(vec_widen_<su>mult_<hi_lo>_<mode>): Likewise.
[(set_attr "type" "simd_store")
(set_attr "mode" "DI")])
-(define_int_attr hi_lo [(0 "lo") (1 "hi")])
-
(define_expand "vec_widen_<su><optab>_<hi_lo>_<mode>"
[(match_operand:<VDMODE256> 0 "register_operand")
(match_operand:ILASX_HB 1 "register_operand")
{
emit_insn (fn_even (t1, op1, op2));
emit_insn (fn_odd (t2, op1, op2));
+ loongarch_expand_vec_interleave (t3, t1, t2, high_p);
+ }
+ break;
+
+ case V8HImode:
+ {
+ emit_insn (fn_even (t1, op1, op2));
+ emit_insn (fn_odd (t2, op1, op2));
+ if (high_p)
+ emit_insn (gen_lsx_vilvh_w (t3, t1, t2));
+ else
+ emit_insn (gen_lsx_vilvl_w (t3, t1, t2));
+ }
+ break;
+
+ case V16QImode:
+ {
+ emit_insn (fn_even (t1, op1, op2));
+ emit_insn (fn_odd (t2, op1, op2));
+ if (high_p)
+ emit_insn (gen_lsx_vilvh_h (t3, t1, t2));
+ else
+ emit_insn (gen_lsx_vilvl_h (t3, t1, t2));
}
break;
gcc_unreachable ();
}
- loongarch_expand_vec_interleave (t3, t1, t2, high_p);
emit_move_insn (dest, gen_lowpart (wmode, t3));
}
[(set (match_dup 0)
(vec_duplicate:V2DI (match_dup 1)))]
"")
+
+(define_expand "vec_widen_<su><optab>_<hi_lo>_<mode>"
+ [(match_operand:<VDMODE> 0 "register_operand")
+ (match_operand:ILSX_HB 1 "register_operand")
+ (match_operand:ILSX_HB 2 "register_operand")
+ (any_extend (const_int 0))
+ (addsub (const_int 0) (const_int 0))
+ (const_int zero_one)]
+ "ISA_HAS_LSX"
+{
+ rtx (*fn_even) (rtx, rtx, rtx) =
+gen_lsx_v<optab>wev_<dlsxfmt>_<lsxfmt><u>;
+ rtx (*fn_odd) (rtx, rtx, rtx) =
+gen_lsx_v<optab>wod_<dlsxfmt>_<lsxfmt><u>;
+ loongarch_expand_vec_widen_hilo (operands[0], operands[1], operands[2],
+ <zero_one>, fn_even, fn_odd);
+ DONE;
+})
+
+(define_expand "vec_widen_<su>mult_<hi_lo>_<mode>"
+ [(match_operand:<VDMODE> 0 "register_operand")
+ (match_operand:ILSX_HB 1 "register_operand")
+ (match_operand:ILSX_HB 2 "register_operand")
+ (any_extend (const_int 0))
+ (const_int zero_one)]
+ "ISA_HAS_LSX"
+{
+ rtx (*fn_even) (rtx, rtx, rtx) =
+gen_lsx_vmulwev_<dlsxfmt>_<lsxfmt><u>;
+ rtx (*fn_odd) (rtx, rtx, rtx) =
+gen_lsx_vmulwod_<dlsxfmt>_<lsxfmt><u>;
+ loongarch_expand_vec_widen_hilo (operands[0], operands[1], operands[2],
+ <zero_one>, fn_even, fn_odd);
+ DONE;
+})
(V4SI "uimm5") (V8SI "uimm5")
(V2DI "uimm6") (V4DI "uimm6")])
+(define_int_attr hi_lo [(0 "lo") (1 "hi")])
+
;; =======================================================================
;; For many LASX instructions, the only difference of it from the LSX
;; counterpart is the length of vector operands. Describe these LSX/LASX