extern void loongarch_expand_vector_group_init (rtx, rtx);
extern void loongarch_expand_vector_init (rtx, rtx);
extern void loongarch_expand_vec_unpack (rtx op[2], bool);
-extern void loongarch_expand_vec_perm (rtx, rtx, rtx, rtx);
extern void loongarch_expand_vec_perm_1 (rtx[]);
extern void loongarch_expand_vector_extract (rtx, rtx, int);
extern void loongarch_expand_vector_reduc (rtx (*)(rtx, rtx, rtx), rtx, rtx);
gen_lowpart (GET_MODE (operands[0]), target));
}
-void
-loongarch_expand_vec_perm (rtx target, rtx op0, rtx op1, rtx sel)
-{
- machine_mode vmode = GET_MODE (target);
- machine_mode vimode = GET_MODE (sel);
- auto nelt = GET_MODE_NUNITS (vmode);
- auto round_reg = gen_reg_rtx (vimode);
- rtx round_data[MAX_VECT_LEN];
-
- for (int i = 0; i < nelt; i += 1)
- {
- round_data[i] = GEN_INT (0x1f);
- }
-
- rtx round_data_rtx = gen_rtx_CONST_VECTOR (vimode, gen_rtvec_v (nelt, round_data));
- emit_move_insn (round_reg, round_data_rtx);
-
- if (vmode != vimode)
- {
- target = lowpart_subreg (vimode, target, vmode);
- op0 = lowpart_subreg (vimode, op0, vmode);
- op1 = lowpart_subreg (vimode, op1, vmode);
- }
-
- switch (vmode)
- {
- case E_V16QImode:
- emit_insn (gen_andv16qi3 (sel, sel, round_reg));
- emit_insn (gen_lsx_vshuf_b (target, op1, op0, sel));
- break;
- case E_V2DFmode:
- case E_V2DImode:
- emit_insn (gen_andv2di3 (sel, sel, round_reg));
- emit_insn (gen_lsx_vshuf_d (target, sel, op1, op0));
- break;
- case E_V4SFmode:
- case E_V4SImode:
- emit_insn (gen_andv4si3 (sel, sel, round_reg));
- emit_insn (gen_lsx_vshuf_w (target, sel, op1, op0));
- break;
- case E_V8HImode:
- emit_insn (gen_andv8hi3 (sel, sel, round_reg));
- emit_insn (gen_lsx_vshuf_h (target, sel, op1, op0));
- break;
- default:
- break;
- }
-}
-
/* Following are the assist function for const vector permutation support. */
static bool
loongarch_is_quad_duplicate (struct expand_vec_perm_d *d)
})
(define_expand "vec_perm<mode>"
- [(match_operand:LSX 0 "register_operand")
- (match_operand:LSX 1 "register_operand")
- (match_operand:LSX 2 "register_operand")
- (match_operand:<VIMODE> 3 "register_operand")]
- "ISA_HAS_LSX"
-{
- loongarch_expand_vec_perm (operands[0], operands[1],
- operands[2], operands[3]);
- DONE;
-})
+ [(set (match_dup 4)
+ (and:<VIMODE> (match_operand:<VIMODE> 3 "register_operand")
+ (match_dup 5)))
+ (set (match_operand:LSX 0 "register_operand")
+ (unspec:LSX [(match_operand:LSX 2 "register_operand")
+ (match_operand:LSX 1 "register_operand")
+ (match_dup 4)]
+ UNSPEC_SIMD_VSHUF))]
+ "ISA_HAS_LSX"
+ {
+ operands[4] = gen_reg_rtx (<VIMODE>mode);
+ operands[5] = gen_const_vec_duplicate (<VIMODE>mode, GEN_INT (0x1f));
+ })
;; Integer operations
(define_insn "add<mode>3"