[(set_attr "type" "simd_store")
(set_attr "mode" "DI")])
-(define_expand "vec_widen_<su>add_hi_<mode>"
- [(match_operand:<VDMODE256> 0 "register_operand")
- (any_extend:<VDMODE256> (match_operand:ILASX_HB 1 "register_operand"))
- (any_extend:<VDMODE256> (match_operand:ILASX_HB 2 "register_operand"))]
- "ISA_HAS_LASX"
-{
- loongarch_expand_vec_widen_hilo (operands[0], operands[1], operands[2],
- <u_bool>, true, "add");
- DONE;
-})
-
-(define_expand "vec_widen_<su>add_lo_<mode>"
- [(match_operand:<VDMODE256> 0 "register_operand")
- (any_extend:<VDMODE256> (match_operand:ILASX_HB 1 "register_operand"))
- (any_extend:<VDMODE256> (match_operand:ILASX_HB 2 "register_operand"))]
- "ISA_HAS_LASX"
-{
- loongarch_expand_vec_widen_hilo (operands[0], operands[1], operands[2],
- <u_bool>, false, "add");
- DONE;
-})
-
-(define_expand "vec_widen_<su>sub_hi_<mode>"
- [(match_operand:<VDMODE256> 0 "register_operand")
- (any_extend:<VDMODE256> (match_operand:ILASX_HB 1 "register_operand"))
- (any_extend:<VDMODE256> (match_operand:ILASX_HB 2 "register_operand"))]
- "ISA_HAS_LASX"
-{
- loongarch_expand_vec_widen_hilo (operands[0], operands[1], operands[2],
- <u_bool>, true, "sub");
- DONE;
-})
-
-(define_expand "vec_widen_<su>sub_lo_<mode>"
- [(match_operand:<VDMODE256> 0 "register_operand")
- (any_extend:<VDMODE256> (match_operand:ILASX_HB 1 "register_operand"))
- (any_extend:<VDMODE256> (match_operand:ILASX_HB 2 "register_operand"))]
- "ISA_HAS_LASX"
-{
- loongarch_expand_vec_widen_hilo (operands[0], operands[1], operands[2],
- <u_bool>, false, "sub");
- DONE;
-})
+(define_int_attr hi_lo [(0 "lo") (1 "hi")])
-(define_expand "vec_widen_<su>mult_hi_<mode>"
+(define_expand "vec_widen_<su><optab>_<hi_lo>_<mode>"
[(match_operand:<VDMODE256> 0 "register_operand")
- (any_extend:<VDMODE256> (match_operand:ILASX_HB 1 "register_operand"))
- (any_extend:<VDMODE256> (match_operand:ILASX_HB 2 "register_operand"))]
+ (match_operand:ILASX_HB 1 "register_operand")
+ (match_operand:ILASX_HB 2 "register_operand")
+ (any_extend (const_int 0))
+ (addsub (const_int 0) (const_int 0))
+ (const_int zero_one)]
"ISA_HAS_LASX"
{
+ rtx (*fn_even) (rtx, rtx, rtx) =
+gen_lasx_xv<optab>wev_<dlasxfmt>_<lasxfmt><u>;
+ rtx (*fn_odd) (rtx, rtx, rtx) =
+gen_lasx_xv<optab>wod_<dlasxfmt>_<lasxfmt><u>;
loongarch_expand_vec_widen_hilo (operands[0], operands[1], operands[2],
- <u_bool>, true, "mult");
+ <zero_one>, fn_even, fn_odd);
DONE;
})
-(define_expand "vec_widen_<su>mult_lo_<mode>"
+(define_expand "vec_widen_<su>mult_<hi_lo>_<mode>"
[(match_operand:<VDMODE256> 0 "register_operand")
- (any_extend:<VDMODE256> (match_operand:ILASX_HB 1 "register_operand"))
- (any_extend:<VDMODE256> (match_operand:ILASX_HB 2 "register_operand"))]
+ (match_operand:ILASX_HB 1 "register_operand")
+ (match_operand:ILASX_HB 2 "register_operand")
+ (any_extend (const_int 0))
+ (const_int zero_one)]
"ISA_HAS_LASX"
{
+ rtx (*fn_even) (rtx, rtx, rtx) =
+gen_lasx_xvmulwev_<dlasxfmt>_<lasxfmt><u>;
+ rtx (*fn_odd) (rtx, rtx, rtx) =
+gen_lasx_xvmulwod_<dlasxfmt>_<lasxfmt><u>;
loongarch_expand_vec_widen_hilo (operands[0], operands[1], operands[2],
- <u_bool>, false, "mult");
+ <zero_one>, fn_even, fn_odd);
DONE;
})
extern void loongarch_expand_vec_cond_expr (machine_mode, machine_mode, rtx *);
extern void loongarch_expand_vec_cond_mask_expr (machine_mode, machine_mode,
rtx *);
-extern void loongarch_expand_vec_widen_hilo (rtx, rtx, rtx, bool, bool, const char *);
+extern void loongarch_expand_vec_widen_hilo (rtx, rtx, rtx, bool,
+ rtx (*)(rtx, rtx, rtx), rtx (*)(rtx, rtx, rtx));
/* Routines implemented in loongarch-c.c. */
void loongarch_cpu_cpp_builtins (cpp_reader *);
extern bool loongarch_explicit_relocs_p (enum loongarch_symbol_type);
extern bool loongarch_symbol_extreme_p (enum loongarch_symbol_type);
extern bool loongarch_option_valid_attribute_p (tree, tree, tree, int);
-extern void loongarch_option_override_internal (struct loongarch_target *, struct gcc_options *, struct gcc_options *);
+extern void loongarch_option_override_internal (struct loongarch_target *,
+ struct gcc_options *, struct gcc_options *);
extern void loongarch_reset_previous_fndecl (void);
extern void loongarch_save_restore_target_globals (tree new_tree);
extern void loongarch_register_pragmas (void);
void
loongarch_expand_vec_widen_hilo (rtx dest, rtx op1, rtx op2,
- bool uns_p, bool high_p, const char *optab)
+ bool high_p, rtx (*fn_even) (rtx, rtx, rtx),
+ rtx (*fn_odd) (rtx, rtx, rtx))
{
machine_mode wmode = GET_MODE (dest);
machine_mode mode = GET_MODE (op1);
- rtx t1, t2, t3;
+ rtx t1 = gen_reg_rtx (wmode);
+ rtx t2 = gen_reg_rtx (wmode);
+ rtx t3 = gen_reg_rtx (wmode);
- t1 = gen_reg_rtx (wmode);
- t2 = gen_reg_rtx (wmode);
- t3 = gen_reg_rtx (wmode);
switch (mode)
{
case V16HImode:
- if (!strcmp (optab, "add"))
- {
- if (!uns_p)
- {
- emit_insn (gen_lasx_xvaddwev_w_h (t1, op1, op2));
- emit_insn (gen_lasx_xvaddwod_w_h (t2, op1, op2));
- }
- else
- {
- emit_insn (gen_lasx_xvaddwev_w_hu (t1, op1, op2));
- emit_insn (gen_lasx_xvaddwod_w_hu (t2, op1, op2));
- }
- }
- else if (!strcmp (optab, "mult"))
- {
- if (!uns_p)
- {
- emit_insn (gen_lasx_xvmulwev_w_h (t1, op1, op2));
- emit_insn (gen_lasx_xvmulwod_w_h (t2, op1, op2));
- }
- else
- {
- emit_insn (gen_lasx_xvmulwev_w_hu (t1, op1, op2));
- emit_insn (gen_lasx_xvmulwod_w_hu (t2, op1, op2));
- }
- }
- else if (!strcmp (optab, "sub"))
- {
- if (!uns_p)
- {
- emit_insn (gen_lasx_xvsubwev_w_h (t1, op1, op2));
- emit_insn (gen_lasx_xvsubwod_w_h (t2, op1, op2));
- }
- else
- {
- emit_insn (gen_lasx_xvsubwev_w_hu (t1, op1, op2));
- emit_insn (gen_lasx_xvsubwod_w_hu (t2, op1, op2));
- }
- }
- break;
-
case V32QImode:
- if (!strcmp (optab, "add"))
{
- if (!uns_p)
- {
- emit_insn (gen_lasx_xvaddwev_h_b (t1, op1, op2));
- emit_insn (gen_lasx_xvaddwod_h_b (t2, op1, op2));
- }
- else
- {
- emit_insn (gen_lasx_xvaddwev_h_bu (t1, op1, op2));
- emit_insn (gen_lasx_xvaddwod_h_bu (t2, op1, op2));
- }
- }
- else if (!strcmp (optab, "mult"))
- {
- if (!uns_p)
- {
- emit_insn (gen_lasx_xvmulwev_h_b (t1, op1, op2));
- emit_insn (gen_lasx_xvmulwod_h_b (t2, op1, op2));
- }
- else
- {
- emit_insn (gen_lasx_xvmulwev_h_bu (t1, op1, op2));
- emit_insn (gen_lasx_xvmulwod_h_bu (t2, op1, op2));
- }
- }
- else if (!strcmp (optab, "sub"))
- {
- if (!uns_p)
- {
- emit_insn (gen_lasx_xvsubwev_h_b (t1, op1, op2));
- emit_insn (gen_lasx_xvsubwod_h_b (t2, op1, op2));
- }
- else
- {
- emit_insn (gen_lasx_xvsubwev_h_bu (t1, op1, op2));
- emit_insn (gen_lasx_xvsubwod_h_bu (t2, op1, op2));
- }
+ emit_insn (fn_even (t1, op1, op2));
+ emit_insn (fn_odd (t2, op1, op2));
}
break;