aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/riscv/autovec.md
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/riscv/autovec.md')
-rw-r--r--gcc/config/riscv/autovec.md298
1 files changed, 222 insertions, 76 deletions
diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md
index f1641d7..19100b5 100644
--- a/gcc/config/riscv/autovec.md
+++ b/gcc/config/riscv/autovec.md
@@ -22,29 +22,27 @@
;; == Loads/Stores
;; =========================================================================
-;; len_load/len_store is a sub-optimal pattern for RVV auto-vectorization support.
-;; We will replace them when len_maskload/len_maskstore is supported in loop vectorizer.
-(define_expand "len_load_<mode>"
+(define_expand "len_maskload<mode><vm>"
[(match_operand:V 0 "register_operand")
(match_operand:V 1 "memory_operand")
- (match_operand 2 "vector_length_operand")
- (match_operand 3 "const_0_operand")]
+ (match_operand 2 "autovec_length_operand")
+ (match_operand:<VM> 3 "vector_mask_operand")
+ (match_operand 4 "const_0_operand")]
"TARGET_VECTOR"
{
- riscv_vector::emit_nonvlmax_insn (code_for_pred_mov (<MODE>mode),
- riscv_vector::RVV_UNOP, operands, operands[2]);
+ riscv_vector::expand_load_store (operands, true);
DONE;
})
-(define_expand "len_store_<mode>"
+(define_expand "len_maskstore<mode><vm>"
[(match_operand:V 0 "memory_operand")
(match_operand:V 1 "register_operand")
- (match_operand 2 "vector_length_operand")
- (match_operand 3 "const_0_operand")]
+ (match_operand 2 "autovec_length_operand")
+ (match_operand:<VM> 3 "vector_mask_operand")
+ (match_operand 4 "const_0_operand")]
"TARGET_VECTOR"
{
- riscv_vector::emit_nonvlmax_insn (code_for_pred_mov (<MODE>mode),
- riscv_vector::RVV_UNOP, operands, operands[2]);
+ riscv_vector::expand_load_store (operands, false);
DONE;
})
@@ -314,44 +312,6 @@
)
;; -------------------------------------------------------------------------
-;; ---- [INT,FP] Compare and select
-;; -------------------------------------------------------------------------
-;; The patterns in this section are synthetic.
-;; -------------------------------------------------------------------------
-
-(define_expand "vcond<V:mode><VI:mode>"
- [(set (match_operand:V 0 "register_operand")
- (if_then_else:V
- (match_operator 3 "comparison_operator"
- [(match_operand:VI 4 "register_operand")
- (match_operand:VI 5 "register_operand")])
- (match_operand:V 1 "register_operand")
- (match_operand:V 2 "register_operand")))]
- "TARGET_VECTOR && known_eq (GET_MODE_NUNITS (<V:MODE>mode),
- GET_MODE_NUNITS (<VI:MODE>mode))"
- {
- riscv_vector::expand_vcond (operands);
- DONE;
- }
-)
-
-(define_expand "vcondu<V:mode><VI:mode>"
- [(set (match_operand:V 0 "register_operand")
- (if_then_else:V
- (match_operator 3 "comparison_operator"
- [(match_operand:VI 4 "register_operand")
- (match_operand:VI 5 "register_operand")])
- (match_operand:V 1 "register_operand")
- (match_operand:V 2 "register_operand")))]
- "TARGET_VECTOR && known_eq (GET_MODE_NUNITS (<V:MODE>mode),
- GET_MODE_NUNITS (<VI:MODE>mode))"
- {
- riscv_vector::expand_vcond (operands);
- DONE;
- }
-)
-
-;; -------------------------------------------------------------------------
;; ---- [INT] Sign and zero extension
;; -------------------------------------------------------------------------
;; Includes:
@@ -596,40 +556,41 @@
;; result after reload_completed.
(define_expand "fma<mode>4"
[(parallel
- [(set (match_operand:VI 0 "register_operand" "=vr")
+ [(set (match_operand:VI 0 "register_operand")
(plus:VI
(mult:VI
- (match_operand:VI 1 "register_operand" " vr")
- (match_operand:VI 2 "register_operand" " vr"))
- (match_operand:VI 3 "register_operand" " vr")))
- (clobber (match_scratch:SI 4))])]
+ (match_operand:VI 1 "register_operand")
+ (match_operand:VI 2 "register_operand"))
+ (match_operand:VI 3 "register_operand")))
+ (clobber (match_dup 4))])]
"TARGET_VECTOR"
- {})
+ {
+ operands[4] = gen_reg_rtx (Pmode);
+ })
-(define_insn_and_split "*fma<mode>"
+(define_insn_and_split "*fma<VI:mode><P:mode>"
[(set (match_operand:VI 0 "register_operand" "=vr, vr, ?&vr")
(plus:VI
(mult:VI
(match_operand:VI 1 "register_operand" " %0, vr, vr")
(match_operand:VI 2 "register_operand" " vr, vr, vr"))
(match_operand:VI 3 "register_operand" " vr, 0, vr")))
- (clobber (match_scratch:SI 4 "=r,r,r"))]
+ (clobber (match_operand:P 4 "register_operand" "=r,r,r"))]
"TARGET_VECTOR"
"#"
"&& reload_completed"
[(const_int 0)]
{
- PUT_MODE (operands[4], Pmode);
- riscv_vector::emit_vlmax_vsetvl (<MODE>mode, operands[4]);
+ riscv_vector::emit_vlmax_vsetvl (<VI:MODE>mode, operands[4]);
if (which_alternative == 2)
emit_insn (gen_rtx_SET (operands[0], operands[3]));
rtx ops[] = {operands[0], operands[1], operands[2], operands[3], operands[0]};
- riscv_vector::emit_vlmax_ternary_insn (code_for_pred_mul_plus (<MODE>mode),
- riscv_vector::RVV_TERNOP, ops, operands[4]);
+ riscv_vector::emit_vlmax_ternary_insn (code_for_pred_mul_plus (<VI:MODE>mode),
+ riscv_vector::RVV_TERNOP, ops, operands[4]);
DONE;
}
[(set_attr "type" "vimuladd")
- (set_attr "mode" "<MODE>")])
+ (set_attr "mode" "<VI:MODE>")])
;; -------------------------------------------------------------------------
;; ---- [INT] VNMSAC and VNMSUB
@@ -641,40 +602,225 @@
(define_expand "fnma<mode>4"
[(parallel
- [(set (match_operand:VI 0 "register_operand" "=vr")
+ [(set (match_operand:VI 0 "register_operand")
(minus:VI
- (match_operand:VI 3 "register_operand" " vr")
+ (match_operand:VI 3 "register_operand")
(mult:VI
- (match_operand:VI 1 "register_operand" " vr")
- (match_operand:VI 2 "register_operand" " vr"))))
- (clobber (match_scratch:SI 4))])]
+ (match_operand:VI 1 "register_operand")
+ (match_operand:VI 2 "register_operand"))))
+ (clobber (match_dup 4))])]
"TARGET_VECTOR"
- {})
+ {
+ operands[4] = gen_reg_rtx (Pmode);
+ })
-(define_insn_and_split "*fnma<mode>"
+(define_insn_and_split "*fnma<VI:mode><P:mode>"
[(set (match_operand:VI 0 "register_operand" "=vr, vr, ?&vr")
(minus:VI
(match_operand:VI 3 "register_operand" " vr, 0, vr")
(mult:VI
(match_operand:VI 1 "register_operand" " %0, vr, vr")
(match_operand:VI 2 "register_operand" " vr, vr, vr"))))
- (clobber (match_scratch:SI 4 "=r,r,r"))]
+ (clobber (match_operand:P 4 "register_operand" "=r,r,r"))]
"TARGET_VECTOR"
"#"
"&& reload_completed"
[(const_int 0)]
{
- PUT_MODE (operands[4], Pmode);
- riscv_vector::emit_vlmax_vsetvl (<MODE>mode, operands[4]);
+ riscv_vector::emit_vlmax_vsetvl (<VI:MODE>mode, operands[4]);
if (which_alternative == 2)
emit_insn (gen_rtx_SET (operands[0], operands[3]));
rtx ops[] = {operands[0], operands[1], operands[2], operands[3], operands[0]};
- riscv_vector::emit_vlmax_ternary_insn (code_for_pred_minus_mul (<MODE>mode),
- riscv_vector::RVV_TERNOP, ops, operands[4]);
+ riscv_vector::emit_vlmax_ternary_insn (code_for_pred_minus_mul (<VI:MODE>mode),
+ riscv_vector::RVV_TERNOP, ops, operands[4]);
DONE;
}
[(set_attr "type" "vimuladd")
- (set_attr "mode" "<MODE>")])
+ (set_attr "mode" "<VI:MODE>")])
+
+;; -------------------------------------------------------------------------
+;; ---- [FP] VFMACC and VFMADD
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - vfmacc
+;; - vfmadd
+;; -------------------------------------------------------------------------
+
+(define_expand "fma<mode>4"
+ [(parallel
+ [(set (match_operand:VF_AUTO 0 "register_operand")
+ (fma:VF_AUTO
+ (match_operand:VF_AUTO 1 "register_operand")
+ (match_operand:VF_AUTO 2 "register_operand")
+ (match_operand:VF_AUTO 3 "register_operand")))
+ (clobber (match_dup 4))])]
+ "TARGET_VECTOR"
+ {
+ operands[4] = gen_reg_rtx (Pmode);
+ })
+
+(define_insn_and_split "*fma<VF_AUTO:mode><P:mode>"
+ [(set (match_operand:VF_AUTO 0 "register_operand" "=vr, vr, ?&vr")
+ (fma:VF_AUTO
+ (match_operand:VF_AUTO 1 "register_operand" " %0, vr, vr")
+ (match_operand:VF_AUTO 2 "register_operand" " vr, vr, vr")
+ (match_operand:VF_AUTO 3 "register_operand" " vr, 0, vr")))
+ (clobber (match_operand:P 4 "register_operand" "=r,r,r"))]
+ "TARGET_VECTOR"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ {
+ riscv_vector::emit_vlmax_vsetvl (<VF_AUTO:MODE>mode, operands[4]);
+ if (which_alternative == 2)
+ emit_insn (gen_rtx_SET (operands[0], operands[3]));
+ rtx ops[] = {operands[0], operands[1], operands[2], operands[3], operands[0]};
+ riscv_vector::emit_vlmax_fp_ternary_insn (code_for_pred_mul (PLUS, <VF_AUTO:MODE>mode),
+ riscv_vector::RVV_TERNOP, ops, operands[4]);
+ DONE;
+ }
+ [(set_attr "type" "vfmuladd")
+ (set_attr "mode" "<VF_AUTO:MODE>")])
+
+;; -------------------------------------------------------------------------
+;; ---- [FP] VFNMSAC and VFNMSUB
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - vfnmsac
+;; - vfnmsub
+;; -------------------------------------------------------------------------
+
+(define_expand "fnma<mode>4"
+ [(parallel
+ [(set (match_operand:VF_AUTO 0 "register_operand")
+ (fma:VF_AUTO
+ (neg:VF_AUTO
+ (match_operand:VF_AUTO 1 "register_operand"))
+ (match_operand:VF_AUTO 2 "register_operand")
+ (match_operand:VF_AUTO 3 "register_operand")))
+ (clobber (match_dup 4))])]
+ "TARGET_VECTOR"
+ {
+ operands[4] = gen_reg_rtx (Pmode);
+ })
+
+(define_insn_and_split "*fnma<VF_AUTO:mode><P:mode>"
+ [(set (match_operand:VF_AUTO 0 "register_operand" "=vr, vr, ?&vr")
+ (fma:VF_AUTO
+ (neg:VF_AUTO
+ (match_operand:VF_AUTO 1 "register_operand" " %0, vr, vr"))
+ (match_operand:VF_AUTO 2 "register_operand" " vr, vr, vr")
+ (match_operand:VF_AUTO 3 "register_operand" " vr, 0, vr")))
+ (clobber (match_operand:P 4 "register_operand" "=r,r,r"))]
+ "TARGET_VECTOR"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ {
+ riscv_vector::emit_vlmax_vsetvl (<VF_AUTO:MODE>mode, operands[4]);
+ if (which_alternative == 2)
+ emit_insn (gen_rtx_SET (operands[0], operands[3]));
+ rtx ops[] = {operands[0], operands[1], operands[2], operands[3], operands[0]};
+ riscv_vector::emit_vlmax_fp_ternary_insn (code_for_pred_mul_neg (PLUS, <VF_AUTO:MODE>mode),
+ riscv_vector::RVV_TERNOP, ops, operands[4]);
+ DONE;
+ }
+ [(set_attr "type" "vfmuladd")
+ (set_attr "mode" "<VF_AUTO:MODE>")])
+
+;; -------------------------------------------------------------------------
+;; ---- [FP] VFMSAC and VFMSUB
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - vfmsac
+;; - vfmsub
+;; -------------------------------------------------------------------------
+
+(define_expand "fms<mode>4"
+ [(parallel
+ [(set (match_operand:VF_AUTO 0 "register_operand")
+ (fma:VF_AUTO
+ (match_operand:VF_AUTO 1 "register_operand")
+ (match_operand:VF_AUTO 2 "register_operand")
+ (neg:VF_AUTO
+ (match_operand:VF_AUTO 3 "register_operand"))))
+ (clobber (match_dup 4))])]
+ "TARGET_VECTOR"
+ {
+ operands[4] = gen_reg_rtx (Pmode);
+ })
+
+(define_insn_and_split "*fms<VF_AUTO:mode><P:mode>"
+ [(set (match_operand:VF_AUTO 0 "register_operand" "=vr, vr, ?&vr")
+ (fma:VF_AUTO
+ (match_operand:VF_AUTO 1 "register_operand" " %0, vr, vr")
+ (match_operand:VF_AUTO 2 "register_operand" " vr, vr, vr")
+ (neg:VF_AUTO
+ (match_operand:VF_AUTO 3 "register_operand" " vr, 0, vr"))))
+ (clobber (match_operand:P 4 "register_operand" "=r,r,r"))]
+ "TARGET_VECTOR"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ {
+ riscv_vector::emit_vlmax_vsetvl (<VF_AUTO:MODE>mode, operands[4]);
+ if (which_alternative == 2)
+ emit_insn (gen_rtx_SET (operands[0], operands[3]));
+ rtx ops[] = {operands[0], operands[1], operands[2], operands[3], operands[0]};
+ riscv_vector::emit_vlmax_fp_ternary_insn (code_for_pred_mul (MINUS, <VF_AUTO:MODE>mode),
+ riscv_vector::RVV_TERNOP, ops, operands[4]);
+ DONE;
+ }
+ [(set_attr "type" "vfmuladd")
+ (set_attr "mode" "<VF_AUTO:MODE>")])
+
+;; -------------------------------------------------------------------------
+;; ---- [FP] VFMSAC and VFMSUB
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - vfmsac
+;; - vfmsub
+;; -------------------------------------------------------------------------
+
+(define_expand "fnms<mode>4"
+ [(parallel
+ [(set (match_operand:VF_AUTO 0 "register_operand")
+ (fma:VF_AUTO
+ (neg:VF_AUTO
+ (match_operand:VF_AUTO 1 "register_operand"))
+ (match_operand:VF_AUTO 2 "register_operand")
+ (neg:VF_AUTO
+ (match_operand:VF_AUTO 3 "register_operand"))))
+ (clobber (match_dup 4))])]
+ "TARGET_VECTOR"
+ {
+ operands[4] = gen_reg_rtx (Pmode);
+ })
+
+(define_insn_and_split "*fnms<VF_AUTO:mode><P:mode>"
+ [(set (match_operand:VF_AUTO 0 "register_operand" "=vr, vr, ?&vr")
+ (fma:VF_AUTO
+ (neg:VF_AUTO
+ (match_operand:VF_AUTO 1 "register_operand" " %0, vr, vr"))
+ (match_operand:VF_AUTO 2 "register_operand" " vr, vr, vr")
+ (neg:VF_AUTO
+ (match_operand:VF_AUTO 3 "register_operand" " vr, 0, vr"))))
+ (clobber (match_operand:P 4 "register_operand" "=r,r,r"))]
+ "TARGET_VECTOR"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ {
+ riscv_vector::emit_vlmax_vsetvl (<VF_AUTO:MODE>mode, operands[4]);
+ if (which_alternative == 2)
+ emit_insn (gen_rtx_SET (operands[0], operands[3]));
+ rtx ops[] = {operands[0], operands[1], operands[2], operands[3], operands[0]};
+ riscv_vector::emit_vlmax_fp_ternary_insn (code_for_pred_mul_neg (MINUS, <VF_AUTO:MODE>mode),
+ riscv_vector::RVV_TERNOP, ops, operands[4]);
+ DONE;
+ }
+ [(set_attr "type" "vfmuladd")
+ (set_attr "mode" "<VF_AUTO:MODE>")])
;; =========================================================================
;; == SELECT_VL