diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md index 775eaa825b0cb8d471e0a46797f94046f4585d38..706cd9717cb1e554a8362e9ee364ba1ae9cb7e24 100644 --- a/gcc/config/riscv/autovec.md +++ b/gcc/config/riscv/autovec.md @@ -2345,39 +2345,39 @@ ;; op[0] = (narrow) ((wide) op[1] + (wide) op[2] + 1)) >> 1; ;; ------------------------------------------------------------------------- -(define_expand "<u>avg<v_double_trunc>3_floor" +(define_expand "avg<v_double_trunc>3_floor" [(set (match_operand:<V_DOUBLE_TRUNC> 0 "register_operand") (truncate:<V_DOUBLE_TRUNC> - (<ext_to_rshift>:VWEXTI + (ashiftrt:VWEXTI (plus:VWEXTI - (any_extend:VWEXTI + (sign_extend:VWEXTI (match_operand:<V_DOUBLE_TRUNC> 1 "register_operand")) - (any_extend:VWEXTI + (sign_extend:VWEXTI (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))))))] "TARGET_VECTOR" { /* First emit a widening addition. */ rtx tmp1 = gen_reg_rtx (<MODE>mode); rtx ops1[] = {tmp1, operands[1], operands[2]}; - insn_code icode = code_for_pred_dual_widen (PLUS, <CODE>, <MODE>mode); + insn_code icode = code_for_pred_dual_widen (PLUS, SIGN_EXTEND, <MODE>mode); riscv_vector::emit_vlmax_insn (icode, riscv_vector::BINARY_OP, ops1); /* Then a narrowing shift. */ rtx ops2[] = {operands[0], tmp1, const1_rtx}; - icode = code_for_pred_narrow_scalar (<EXT_TO_RSHIFT>, <MODE>mode); + icode = code_for_pred_narrow_scalar (ASHIFTRT, <MODE>mode); riscv_vector::emit_vlmax_insn (icode, riscv_vector::BINARY_OP, ops2); DONE; }) -(define_expand "<u>avg<v_double_trunc>3_ceil" +(define_expand "avg<v_double_trunc>3_ceil" [(set (match_operand:<V_DOUBLE_TRUNC> 0 "register_operand") (truncate:<V_DOUBLE_TRUNC> - (<ext_to_rshift>:VWEXTI + (ashiftrt:VWEXTI (plus:VWEXTI (plus:VWEXTI - (any_extend:VWEXTI + (sign_extend:VWEXTI (match_operand:<V_DOUBLE_TRUNC> 1 "register_operand")) - (any_extend:VWEXTI + (sign_extend:VWEXTI (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))) (const_int 1)))))] "TARGET_VECTOR" @@ -2385,7 +2385,7 @@ /* First emit a widening addition. */ rtx tmp1 = gen_reg_rtx (<MODE>mode); rtx ops1[] = {tmp1, operands[1], operands[2]}; - insn_code icode = code_for_pred_dual_widen (PLUS, <CODE>, <MODE>mode); + insn_code icode = code_for_pred_dual_widen (PLUS, SIGN_EXTEND, <MODE>mode); riscv_vector::emit_vlmax_insn (icode, riscv_vector::BINARY_OP, ops1); /* Then add 1. */ @@ -2396,11 +2396,37 @@ /* Finally, a narrowing shift. */ rtx ops3[] = {operands[0], tmp2, const1_rtx}; - icode = code_for_pred_narrow_scalar (<EXT_TO_RSHIFT>, <MODE>mode); + icode = code_for_pred_narrow_scalar (ASHIFTRT, <MODE>mode); riscv_vector::emit_vlmax_insn (icode, riscv_vector::BINARY_OP, ops3); DONE; }) +;; csrwi vxrm, 2 +;; vaaddu.vv vd, vs2, vs1 +(define_expand "uavg<mode>3_floor" + [(match_operand:V_VLSI 0 "register_operand") + (match_operand:V_VLSI 1 "register_operand") + (match_operand:V_VLSI 2 "register_operand")] + "TARGET_VECTOR" +{ + insn_code icode = code_for_pred (UNSPEC_VAADDU, <MODE>mode); + riscv_vector::emit_vlmax_insn (icode, riscv_vector::BINARY_OP_VXRM_RDN, operands); + DONE; +}) + +;; csrwi vxrm, 0 +;; vaaddu.vv vd, vs2, vs1 +(define_expand "uavg<mode>3_ceil" + [(match_operand:V_VLSI 0 "register_operand") + (match_operand:V_VLSI 1 "register_operand") + (match_operand:V_VLSI 2 "register_operand")] + "TARGET_VECTOR" +{ + insn_code icode = code_for_pred (UNSPEC_VAADDU, <MODE>mode); + riscv_vector::emit_vlmax_insn (icode, riscv_vector::BINARY_OP_VXRM_RNU, operands); + DONE; +}) + ;; ------------------------------------------------------------------------- ;; ---- [FP] Rounding. ;; ------------------------------------------------------------------------- diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index 00a5b645abe03c8799b9a322d24d7897773f633f..fc0097acde3900a8cffca8a35c09c8f1ae27bf8f 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -366,6 +366,12 @@ enum insn_flags : unsigned int /* Means INSN has FRM operand and the value is FRM_RNE. */ FRM_RNE_P = 1 << 19, + + /* Means INSN has VXRM operand and the value is VXRM_RNU. */ + VXRM_RNU_P = 1 << 20, + + /* Means INSN has VXRM operand and the value is VXRM_RDN. */ + VXRM_RDN_P = 1 << 21, }; enum insn_type : unsigned int @@ -426,6 +432,8 @@ enum insn_type : unsigned int BINARY_OP_TAMU = __MASK_OP_TAMU | BINARY_OP_P, BINARY_OP_TUMA = __MASK_OP_TUMA | BINARY_OP_P, BINARY_OP_FRM_DYN = BINARY_OP | FRM_DYN_P, + BINARY_OP_VXRM_RNU = BINARY_OP | VXRM_RNU_P, + BINARY_OP_VXRM_RDN = BINARY_OP | VXRM_RDN_P, /* Ternary operator. Always have real merge operand. */ TERNARY_OP = HAS_DEST_P | HAS_MASK_P | USE_ALL_TRUES_MASK_P | HAS_MERGE_P diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc index 2491522191a12f20e58ce0f4b4f91e9501922879..7ae579ba890142ed4d890e66cbac21ff4a430750 100644 --- a/gcc/config/riscv/riscv-v.cc +++ b/gcc/config/riscv/riscv-v.cc @@ -207,6 +207,13 @@ public: add_input_operand (frm_rtx, Pmode); } + void + add_rounding_mode_operand (enum fixed_point_rounding_mode rounding_mode) + { + rtx frm_rtx = gen_int_mode (rounding_mode, Pmode); + add_input_operand (frm_rtx, Pmode); + } + /* Return the vtype mode based on insn_flags. vtype mode mean the mode vsetvl insn set. */ machine_mode @@ -334,6 +341,10 @@ public: add_rounding_mode_operand (FRM_RMM); else if (m_insn_flags & FRM_RNE_P) add_rounding_mode_operand (FRM_RNE); + else if (m_insn_flags & VXRM_RNU_P) + add_rounding_mode_operand (VXRM_RNU); + else if (m_insn_flags & VXRM_RDN_P) + add_rounding_mode_operand (VXRM_RDN); gcc_assert (insn_data[(int) icode].n_operands == m_opno); expand (icode, any_mem_p); diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md index b4a276dc2c89c4edb0d46beb8d4da63bc5665ae9..c2ea7e8b10ac8d6b9de36a7909e34ca13a4cedf8 100644 --- a/gcc/config/riscv/vector-iterators.md +++ b/gcc/config/riscv/vector-iterators.md @@ -3581,11 +3581,6 @@ (define_code_attr nmsub_nmadd [(plus "nmsub") (minus "nmadd")]) (define_code_attr nmsac_nmacc [(plus "nmsac") (minus "nmacc")]) -(define_code_attr ext_to_rshift [(sign_extend "ashiftrt") - (zero_extend "lshiftrt")]) -(define_code_attr EXT_TO_RSHIFT [(sign_extend "ASHIFTRT") - (zero_extend "LSHIFTRT")]) - (define_code_iterator and_ior [and ior]) (define_code_iterator any_float_binop [plus mult minus div]) diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md index 24b7b4394bee223b9b44429642ffe53d72150c87..c1a282a27b307ff85118790f3e86586bda9ddb49 100644 --- a/gcc/config/riscv/vector.md +++ b/gcc/config/riscv/vector.md @@ -4239,8 +4239,8 @@ (set_attr "mode" "<MODE>")]) (define_insn "@pred_<sat_op><mode>" - [(set (match_operand:VI 0 "register_operand" "=vd, vd, vr, vr") - (if_then_else:VI + [(set (match_operand:V_VLSI 0 "register_operand" "=vd, vd, vr, vr") + (if_then_else:V_VLSI (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1,Wc1") (match_operand 5 "vector_length_operand" " rK, rK, rK, rK") @@ -4251,10 +4251,10 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM) (reg:SI VXRM_REGNUM)] UNSPEC_VPREDICATE) - (unspec:VI - [(match_operand:VI 3 "register_operand" " vr, vr, vr, vr") - (match_operand:VI 4 "register_operand" " vr, vr, vr, vr")] VSAT_OP) - (match_operand:VI 2 "vector_merge_operand" " vu, 0, vu, 0")))] + (unspec:V_VLSI + [(match_operand:V_VLSI 3 "register_operand" " vr, vr, vr, vr") + (match_operand:V_VLSI 4 "register_operand" " vr, vr, vr, vr")] VSAT_OP) + (match_operand:V_VLSI 2 "vector_merge_operand" " vu, 0, vu, 0")))] "TARGET_VECTOR" "v<sat_op>.vv\t%0,%3,%4%p1" [(set_attr "type" "<sat_insn_type>") diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-1.c index d53bd3a386ad8397a8676539475a8625e2df3b26..2327a3d018e151f5eee5828ba24f81ba0f6f8cc8 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-1.c @@ -26,9 +26,9 @@ DEF_AVG_FLOOR (uint8_t, uint16_t, 1024) DEF_AVG_FLOOR (uint8_t, uint16_t, 2048) /* { dg-final { scan-assembler-times {vwadd\.vv} 10 } } */ -/* { dg-final { scan-assembler-times {vwaddu\.vv} 10 } } */ +/* { dg-final { scan-assembler-times {csrwi\s*vxrm,\s*2} 10 } } */ /* { dg-final { scan-assembler-times {vnsra\.wi} 10 } } */ -/* { dg-final { scan-assembler-times {vnsrl\.wi} 10 } } */ +/* { dg-final { scan-assembler-times {vaaddu\.vv} 10 } } */ /* { dg-final { scan-assembler-not {csrr} } } */ /* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ /* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-2.c index 68d1df73a5fb742bc0194371f6a0bcd5f2b0894f..8030810fdbd136fa2dffcbc01ca0428af56d19b5 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-2.c @@ -24,9 +24,9 @@ DEF_AVG_FLOOR (uint16_t, uint32_t, 512) DEF_AVG_FLOOR (uint16_t, uint32_t, 1024) /* { dg-final { scan-assembler-times {vwadd\.vv} 9 } } */ -/* { dg-final { scan-assembler-times {vwaddu\.vv} 9 } } */ +/* { dg-final { scan-assembler-times {csrwi\s*vxrm,\s*2} 9 } } */ /* { dg-final { scan-assembler-times {vnsra\.wi} 9 } } */ -/* { dg-final { scan-assembler-times {vnsrl\.wi} 9 } } */ +/* { dg-final { scan-assembler-times {vaaddu\.vv} 9 } } */ /* { dg-final { scan-assembler-not {csrr} } } */ /* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ /* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-3.c index 07ffab61f678bcabdf45db27fe3aab80d9c36eab..dce0ffa346e6c395a3e84e1e19ba8d51afbd2bbf 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-3.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-3.c @@ -22,9 +22,9 @@ DEF_AVG_FLOOR (uint32_t, uint64_t, 256) DEF_AVG_FLOOR (uint32_t, uint64_t, 512) /* { dg-final { scan-assembler-times {vwadd\.vv} 8 } } */ -/* { dg-final { scan-assembler-times {vwaddu\.vv} 8 } } */ +/* { dg-final { scan-assembler-times {csrwi\s*vxrm,\s*2} 8 } } */ /* { dg-final { scan-assembler-times {vnsra\.wi} 8 } } */ -/* { dg-final { scan-assembler-times {vnsrl\.wi} 8 } } */ +/* { dg-final { scan-assembler-times {vaaddu\.vv} 8 } } */ /* { dg-final { scan-assembler-not {csrr} } } */ /* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ /* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-4.c index 83e219ca09a980dc79dac139d01048bceab6541e..65912fb39f2f88738579f545258c51963454b77c 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-4.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-4.c @@ -26,10 +26,10 @@ DEF_AVG_CEIL (uint8_t, uint16_t, 1024) DEF_AVG_CEIL (uint8_t, uint16_t, 2048) /* { dg-final { scan-assembler-times {vwadd\.vv} 10 } } */ -/* { dg-final { scan-assembler-times {vwaddu\.vv} 10 } } */ +/* { dg-final { scan-assembler-times {csrwi\s*vxrm,\s*0} 10 } } */ /* { dg-final { scan-assembler-times {vnsra\.wi} 10 } } */ -/* { dg-final { scan-assembler-times {vnsrl\.wi} 10 } } */ -/* { dg-final { scan-assembler-times {vadd\.vi} 20 } } */ +/* { dg-final { scan-assembler-times {vaaddu\.vv} 10 } } */ +/* { dg-final { scan-assembler-times {vadd\.vi} 10 } } */ /* { dg-final { scan-assembler-not {csrr} } } */ /* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ /* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-5.c index 325faeaa93039d3d69239eaea0c99eafa7572441..a197b24c234ba02abe1cd65875904a29cdd1bbc7 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-5.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-5.c @@ -24,10 +24,10 @@ DEF_AVG_CEIL (uint16_t, uint32_t, 512) DEF_AVG_CEIL (uint16_t, uint32_t, 1024) /* { dg-final { scan-assembler-times {vwadd\.vv} 9 } } */ -/* { dg-final { scan-assembler-times {vwaddu\.vv} 9 } } */ +/* { dg-final { scan-assembler-times {csrwi\s*vxrm,\s*0} 9 } } */ /* { dg-final { scan-assembler-times {vnsra\.wi} 9 } } */ -/* { dg-final { scan-assembler-times {vnsrl\.wi} 9 } } */ -/* { dg-final { scan-assembler-times {vadd\.vi} 18 } } */ +/* { dg-final { scan-assembler-times {vaaddu\.vv} 9 } } */ +/* { dg-final { scan-assembler-times {vadd\.vi} 9 } } */ /* { dg-final { scan-assembler-not {csrr} } } */ /* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ /* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-6.c index d836428c7f46a0e9270ac315248dfa0db47e79d3..a53de71a01b09f8e10e25e7b6cd3fd86dc2164a8 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-6.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/avg-6.c @@ -22,10 +22,10 @@ DEF_AVG_CEIL (uint16_t, uint32_t, 256) DEF_AVG_CEIL (uint16_t, uint32_t, 512) /* { dg-final { scan-assembler-times {vwadd\.vv} 8 } } */ -/* { dg-final { scan-assembler-times {vwaddu\.vv} 8 } } */ +/* { dg-final { scan-assembler-times {csrwi\s*vxrm,\s*0} 8 } } */ /* { dg-final { scan-assembler-times {vnsra\.wi} 8 } } */ -/* { dg-final { scan-assembler-times {vnsrl\.wi} 8 } } */ -/* { dg-final { scan-assembler-times {vadd\.vi} 16 } } */ +/* { dg-final { scan-assembler-times {vaaddu\.vv} 8 } } */ +/* { dg-final { scan-assembler-times {vadd\.vi} 8 } } */ /* { dg-final { scan-assembler-not {csrr} } } */ /* { dg-final { scan-tree-dump-not "1,1" "optimized" } } */ /* { dg-final { scan-tree-dump-not "2,2" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/vec-avg-rv32gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/vec-avg-rv32gcv.c index e2754339d942c0d6c56378abbd3944a2624c4bf7..6874a3dab1b6beb5d695ec3178816ad2f05d273a 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/vec-avg-rv32gcv.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/vec-avg-rv32gcv.c @@ -4,7 +4,8 @@ #include "vec-avg-template.h" /* { dg-final { scan-assembler-times {\tvwadd\.vv} 6 } } */ -/* { dg-final { scan-assembler-times {\tvwaddu\.vv} 6 } } */ -/* { dg-final { scan-assembler-times {\tvadd\.vi} 6 } } */ -/* { dg-final { scan-assembler-times {\tvnsrl.wi} 6 } } */ +/* { dg-final { scan-assembler-times {csrwi\s*vxrm,\s*0} 3 } } */ +/* { dg-final { scan-assembler-times {csrwi\s*vxrm,\s*2} 3 } } */ +/* { dg-final { scan-assembler-times {\tvadd\.vi} 3 } } */ /* { dg-final { scan-assembler-times {\tvnsra.wi} 6 } } */ +/* { dg-final { scan-assembler-times {vaaddu\.vv} 6 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/vec-avg-rv64gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/vec-avg-rv64gcv.c index 1f0ef29566dd9bde2589ec0fc8a4127abd1a2bd0..06f35e1481237e8cbbfa696e3075c62405756d0a 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/vec-avg-rv64gcv.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/vec-avg-rv64gcv.c @@ -4,7 +4,8 @@ #include "vec-avg-template.h" /* { dg-final { scan-assembler-times {\tvwadd\.vv} 6 } } */ -/* { dg-final { scan-assembler-times {\tvwaddu\.vv} 6 } } */ -/* { dg-final { scan-assembler-times {\tvadd\.vi} 6 } } */ -/* { dg-final { scan-assembler-times {\tvnsrl\.wi} 6 } } */ +/* { dg-final { scan-assembler-times {csrwi\s*vxrm,\s*0} 3 } } */ +/* { dg-final { scan-assembler-times {csrwi\s*vxrm,\s*2} 3 } } */ +/* { dg-final { scan-assembler-times {\tvadd\.vi} 3 } } */ /* { dg-final { scan-assembler-times {\tvnsra\.wi} 6 } } */ +/* { dg-final { scan-assembler-times {vaaddu\.vv} 6 } } */