The vendor-defined XVentanaCondOps extension adds two instructions with semantics identical to Zicond.
This plugs the 2 new instruction in using the canonical RTX, which also matches the combiner-input for noce_try_store_flag_mask and noce_try_store_flag, defined for conditional-zero. For documentation on XVentanaCondOps, refer to: https://github.com/ventanamicro/ventana-custom-extensions/releases/download/v1.0.1/ventana-custom-extensions-v1.0.1.pdf gcc/ChangeLog: * config/riscv/riscv.cc (riscv_rtx_costs): Recognize idiom for conditional zero as a single instruction for TARGET_XVENTANACONDOPS. * config/riscv/riscv.md: Include xventanacondops.md. * config/riscv/zicond.md: Enable splitters for TARGET_XVENTANACONDOPS. * config/riscv/xventanacondops.md: New file. gcc/testsuite/ChangeLog: * gcc.target/riscv/xventanacondops-and-01.c: New test. * gcc.target/riscv/xventanacondops-and-02.c: New test. * gcc.target/riscv/xventanacondops-eq-01.c: New test. * gcc.target/riscv/xventanacondops-eq-02.c: New test. * gcc.target/riscv/xventanacondops-ifconv-imm.c: New test. * gcc.target/riscv/xventanacondops-le-01.c: New test. * gcc.target/riscv/xventanacondops-le-02.c: New test. * gcc.target/riscv/xventanacondops-lt-01.c: New test. * gcc.target/riscv/xventanacondops-lt-03.c: New test. * gcc.target/riscv/xventanacondops-ne-01.c: New test. * gcc.target/riscv/xventanacondops-ne-03.c: New test. * gcc.target/riscv/xventanacondops-ne-04.c: New test. * gcc.target/riscv/xventanacondops-xor-01.c: New test. Signed-off-by: Philipp Tomsich <philipp.toms...@vrull.eu> --- gcc/config/riscv/riscv.cc | 4 +-- gcc/config/riscv/riscv.md | 5 ++-- gcc/config/riscv/xventanacondops.md | 29 +++++++++++++++++++ gcc/config/riscv/zicond.md | 15 +++++----- .../gcc.target/riscv/xventanacondops-and-01.c | 16 ++++++++++ .../gcc.target/riscv/xventanacondops-and-02.c | 15 ++++++++++ .../gcc.target/riscv/xventanacondops-eq-01.c | 11 +++++++ .../gcc.target/riscv/xventanacondops-eq-02.c | 14 +++++++++ .../riscv/xventanacondops-ifconv-imm.c | 19 ++++++++++++ .../gcc.target/riscv/xventanacondops-le-01.c | 16 ++++++++++ .../gcc.target/riscv/xventanacondops-le-02.c | 11 +++++++ .../gcc.target/riscv/xventanacondops-lt-01.c | 16 ++++++++++ .../gcc.target/riscv/xventanacondops-lt-03.c | 16 ++++++++++ .../gcc.target/riscv/xventanacondops-ne-01.c | 10 +++++++ .../gcc.target/riscv/xventanacondops-ne-03.c | 13 +++++++++ .../gcc.target/riscv/xventanacondops-ne-04.c | 13 +++++++++ .../gcc.target/riscv/xventanacondops-xor-01.c | 14 +++++++++ 17 files changed, 226 insertions(+), 11 deletions(-) create mode 100644 gcc/config/riscv/xventanacondops.md create mode 100644 gcc/testsuite/gcc.target/riscv/xventanacondops-and-01.c create mode 100644 gcc/testsuite/gcc.target/riscv/xventanacondops-and-02.c create mode 100644 gcc/testsuite/gcc.target/riscv/xventanacondops-eq-01.c create mode 100644 gcc/testsuite/gcc.target/riscv/xventanacondops-eq-02.c create mode 100644 gcc/testsuite/gcc.target/riscv/xventanacondops-ifconv-imm.c create mode 100644 gcc/testsuite/gcc.target/riscv/xventanacondops-le-01.c create mode 100644 gcc/testsuite/gcc.target/riscv/xventanacondops-le-02.c create mode 100644 gcc/testsuite/gcc.target/riscv/xventanacondops-lt-01.c create mode 100644 gcc/testsuite/gcc.target/riscv/xventanacondops-lt-03.c create mode 100644 gcc/testsuite/gcc.target/riscv/xventanacondops-ne-01.c create mode 100644 gcc/testsuite/gcc.target/riscv/xventanacondops-ne-03.c create mode 100644 gcc/testsuite/gcc.target/riscv/xventanacondops-ne-04.c create mode 100644 gcc/testsuite/gcc.target/riscv/xventanacondops-xor-01.c diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 7e69a652fc5..94ac8f350e6 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -2331,8 +2331,8 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN return false; case AND: - /* czero.eqz/nez */ - if ((TARGET_ZICOND) + /* czero.eqz/nez or vt.maskc/vt.maskcn */ + if ((TARGET_ZICOND || TARGET_XVENTANACONDOPS) && mode == word_mode && GET_CODE (XEXP (x, 0)) == NEG) { diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 6f255a80379..e6b73c316cb 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -2673,7 +2673,7 @@ (define_split (match_operator:GPR 1 "anyle_operator" [(match_operand:X 2 "register_operand") (match_operand:X 3 "register_operand")]))] - "TARGET_ZICOND" + "TARGET_ZICOND || TARGET_XVENTANACONDOPS" [(set (match_dup 0) (match_dup 4)) (set (match_dup 0) (eq:GPR (match_dup 0) (const_int 0)))] { @@ -2707,7 +2707,7 @@ (define_split (match_operator:GPR 1 "anyge_operator" [(match_operand:X 2 "register_operand") (match_operand:X 3 "register_operand")]))] - "TARGET_ZICOND" + "TARGET_ZICOND || TARGET_XVENTANACONDOPS" [(set (match_dup 0) (match_dup 4)) (set (match_dup 0) (eq:GPR (match_dup 0) (const_int 0)))] { @@ -3255,3 +3255,4 @@ (define_insn "riscv_prefetchi_<mode>" (include "sifive-7.md") (include "vector.md") (include "zicond.md") +(include "xventanacondops.md") diff --git a/gcc/config/riscv/xventanacondops.md b/gcc/config/riscv/xventanacondops.md new file mode 100644 index 00000000000..3cca14feaf9 --- /dev/null +++ b/gcc/config/riscv/xventanacondops.md @@ -0,0 +1,29 @@ +;; Machine description for X-Ventana-CondOps +;; Copyright (C) 2022 Free Software Foundation, Inc. + +;; This file is part of GCC. + +;; GCC is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. + +;; GCC is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; <http://www.gnu.org/licenses/>. + +(define_code_attr vt_n [(eq "n") (ne "")]) + +(define_insn "*vt.maskc<vt_n>" + [(set (match_operand:DI 0 "register_operand" "=r") + (and:DI (neg:DI (eq_or_ne:DI + (match_operand:DI 1 "register_operand" "r") + (const_int 0))) + (match_operand:DI 2 "register_operand" "r")))] + "TARGET_XVENTANACONDOPS" + "vt.maskc<vt_n>\t%0,%2,%1") diff --git a/gcc/config/riscv/zicond.md b/gcc/config/riscv/zicond.md index 0aad61c7009..ea518bbb5b1 100644 --- a/gcc/config/riscv/zicond.md +++ b/gcc/config/riscv/zicond.md @@ -39,7 +39,7 @@ (define_split (const_int 0)])) (match_operand:DI 3 "immediate_operand"))) (clobber (match_operand:DI 4 "register_operand"))] - "TARGET_ZICOND" + "TARGET_ZICOND || TARGET_XVENTANACONDOPS" [(set (match_dup 4) (match_dup 3)) (set (match_dup 0) (and:DI (neg:DI (match_dup 1)) (match_dup 4)))] @@ -60,7 +60,7 @@ (define_split (match_operand:X 3 "arith_operand")])) (match_operand:X 4 "register_operand"))) (clobber (match_operand:X 5 "register_operand"))] - "TARGET_ZICOND" + "TARGET_ZICOND || TARGET_XVENTANACONDOPS" [(set (match_dup 5) (match_dup 6)) (set (match_dup 0) (and:X (neg:X (eq:X (match_dup 5) (const_int 0))) (match_dup 4)))] @@ -77,7 +77,7 @@ (define_split (match_operand:X 3 "arith_operand")])) (match_operand:X 4 "register_operand"))) (clobber (match_operand:X 5 "register_operand"))] - "TARGET_ZICOND" + "TARGET_ZICOND || TARGET_XVENTANACONDOPS" [(set (match_dup 5) (match_dup 1)) (set (match_dup 0) (and:X (neg:X (ne:X (match_dup 5) (const_int 0))) (match_dup 4)))]) @@ -90,7 +90,7 @@ (define_split (match_operand:X 3 "arith_operand")])) (match_operand:X 4 "register_operand"))) (clobber (match_operand:X 5 "register_operand"))] - "TARGET_ZICOND" + "TARGET_ZICOND || TARGET_XVENTANACONDOPS" [(set (match_dup 5) (match_dup 6)) (set (match_dup 0) (and:X (neg:X (eq:X (match_dup 5) (const_int 0))) (match_dup 4)))] @@ -123,7 +123,7 @@ (define_split (match_operand 2 "immediate_operand")) (match_operand:X 3 "register_operand"))) (clobber (match_operand:X 4 "register_operand"))] - "TARGET_ZICOND && TARGET_ZBS" + "(TARGET_ZICOND || TARGET_XVENTANACONDOPS) && TARGET_ZBS" [(set (match_dup 4) (zero_extract:X (match_dup 1) (const_int 1) (match_dup 2))) (set (match_dup 0) (and:X (neg:X (ne:X (match_dup 4) (const_int 0))) (match_dup 3)))]) @@ -136,7 +136,8 @@ (define_split (match_operand 2 "immediate_operand")) (match_operand:X 3 "register_operand"))) (clobber (match_operand:X 4 "register_operand"))] - "TARGET_ZICOND && !TARGET_ZBS && (UINTVAL (operands[2]) < 11)" + "(TARGET_ZICOND || TARGET_XVENTANACONDOPS) + && !TARGET_ZBS && (UINTVAL (operands[2]) < 11)" [(set (match_dup 4) (and:X (match_dup 1) (match_dup 2))) (set (match_dup 0) (and:X (neg:X (ne:X (match_dup 4) (const_int 0))) (match_dup 3)))] @@ -150,6 +151,6 @@ (define_split (const_int 1) (match_operand 2 "immediate_operand")) (const_int 0))))] - "!TARGET_ZICOND && TARGET_ZBS" + "!(TARGET_ZICOND || TARGET_XVENTANACONDOPS) && TARGET_ZBS" [(set (match_dup 0) (zero_extract:X (match_dup 1) (const_int 1) (match_dup 2))) (set (match_dup 0) (plus:X (match_dup 0) (const_int -1)))]) diff --git a/gcc/testsuite/gcc.target/riscv/xventanacondops-and-01.c b/gcc/testsuite/gcc.target/riscv/xventanacondops-and-01.c new file mode 100644 index 00000000000..9b26cdf0513 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xventanacondops-and-01.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_xventanacondops -mabi=lp64" } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */ + +long and1(long a, long b, long c, long d) +{ + if (c < d) + a &= b; + + return a; +} + +/* { dg-final { scan-assembler-times "and\t" 1 } } */ +/* { dg-final { scan-assembler-times "slt" 1 } } */ +/* { dg-final { scan-assembler-times "vt.maskcn" 1 } } */ +/* { dg-final { scan-assembler-times "or\t" 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xventanacondops-and-02.c b/gcc/testsuite/gcc.target/riscv/xventanacondops-and-02.c new file mode 100644 index 00000000000..66d2ec10211 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xventanacondops-and-02.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_xventanacondops -mabi=lp64" } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */ + +int and2(int a, int b, long c) +{ + if (c) + a &= b; + + return a; +} + +/* { dg-final { scan-assembler-times "and\t" 1 } } */ +/* { dg-final { scan-assembler-times "vt.maskcn" 1 } } */ +/* { dg-final { scan-assembler-times "or\t" 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xventanacondops-eq-01.c b/gcc/testsuite/gcc.target/riscv/xventanacondops-eq-01.c new file mode 100644 index 00000000000..bc877d9e81b --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xventanacondops-eq-01.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_xventanacondops -mabi=lp64" } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */ + +long +eq1 (long a, long b) +{ + return (a == 0) ? b : 0; +} + +/* { dg-final { scan-assembler-times "vt.maskcn" 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xventanacondops-eq-02.c b/gcc/testsuite/gcc.target/riscv/xventanacondops-eq-02.c new file mode 100644 index 00000000000..28317613ba8 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xventanacondops-eq-02.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_xventanacondops -mabi=lp64" } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */ + +long +eq2 (long a, long b) +{ + if (a == 0) + return b; + + return 0; +} + +/* { dg-final { scan-assembler-times "vt.maskcn" 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xventanacondops-ifconv-imm.c b/gcc/testsuite/gcc.target/riscv/xventanacondops-ifconv-imm.c new file mode 100644 index 00000000000..0012e7b669c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xventanacondops-ifconv-imm.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_xventanacondops -mabi=lp64" } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */ + +/* Each function below should emit a vt.maskcn instruction */ + +long +foo0 (long a, long b, long c) +{ + if (c) + a = 0; + else + a = 5; + return a; +} + +/* { dg-final { scan-assembler-times "vt.maskcn\t" 1 } } */ +/* { dg-final { scan-assembler-not "beqz\t" } } */ +/* { dg-final { scan-assembler-not "bnez\t" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xventanacondops-le-01.c b/gcc/testsuite/gcc.target/riscv/xventanacondops-le-01.c new file mode 100644 index 00000000000..eb463e3c161 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xventanacondops-le-01.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zba_zbb_zbs_xventanacondops -mabi=lp64 -mbranch-cost=4" } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-O1" "-Os" "-Oz" } } */ + +long long sink (long long); + +long long le1 (long long a, long long b) +{ + if (a <= b) + b = 0; + + return sink(b); +} + +/* { dg-final { scan-assembler-times "sgt\t" 1 } } */ +/* { dg-final { scan-assembler-times "vt.maskc\t" 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xventanacondops-le-02.c b/gcc/testsuite/gcc.target/riscv/xventanacondops-le-02.c new file mode 100644 index 00000000000..daa115d70c5 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xventanacondops-le-02.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zba_zbb_zbs_xventanacondops -mabi=lp64" } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-O1" "-Os" "-Oz" } } */ + +long long le2 (long long a, long long b, long long c) +{ + return (a <= c) ? b : 0; +} + +/* { dg-final { scan-assembler-times "sgt\t" 1 } } */ +/* { dg-final { scan-assembler-times "vt.maskcn\t" 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xventanacondops-lt-01.c b/gcc/testsuite/gcc.target/riscv/xventanacondops-lt-01.c new file mode 100644 index 00000000000..18762ee2bd0 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xventanacondops-lt-01.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_xventanacondops -mabi=lp64" } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */ + +long long sink (long long); + +long long lt3 (long long a, long long b) +{ + if (a < b) + b = 0; + + return sink(b); +} + +/* { dg-final { scan-assembler-times "vt.maskcn\t" 1 } } */ +/* { dg-final { scan-assembler-times "slt\t" 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xventanacondops-lt-03.c b/gcc/testsuite/gcc.target/riscv/xventanacondops-lt-03.c new file mode 100644 index 00000000000..f671f357f91 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xventanacondops-lt-03.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zba_zbb_zbs_xventanacondops -mabi=lp64 -mbranch-cost=4" } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-O1" "-Os" "-Oz" } } */ + +long long sink (long long); + +long long lt3 (long long a, long long b) +{ + if (a < b) + b = 0; + + return sink(b); +} + +/* { dg-final { scan-assembler-times "slt\t" 1 } } */ +/* { dg-final { scan-assembler-times "vt.maskcn\t" 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xventanacondops-ne-01.c b/gcc/testsuite/gcc.target/riscv/xventanacondops-ne-01.c new file mode 100644 index 00000000000..be8375ba5cf --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xventanacondops-ne-01.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_xventanacondops -mabi=lp64" } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */ + +long long ne1(long long a, long long b) +{ + return (a != 0) ? b : 0; +} + +/* { dg-final { scan-assembler-times "vt.maskc" 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xventanacondops-ne-03.c b/gcc/testsuite/gcc.target/riscv/xventanacondops-ne-03.c new file mode 100644 index 00000000000..4a762a1ed61 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xventanacondops-ne-03.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_xventanacondops -mabi=lp64 -mtune=thead-c906" } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-O1" "-Os" "-Oz" } } */ + +long long ne3(long long a, long long b) +{ + if (a != 0) + return b; + + return 0; +} + +/* { dg-final { scan-assembler-times "vt.maskc" 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xventanacondops-ne-04.c b/gcc/testsuite/gcc.target/riscv/xventanacondops-ne-04.c new file mode 100644 index 00000000000..18b35ac7070 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xventanacondops-ne-04.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_xventanacondops -mabi=lp64 -mtune=thead-c906" } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */ + +long long ne4(long long a, long long b) +{ + if (a != 0) + return 0; + + return b; +} + +/* { dg-final { scan-assembler-times "vt.maskcn" 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xventanacondops-xor-01.c b/gcc/testsuite/gcc.target/riscv/xventanacondops-xor-01.c new file mode 100644 index 00000000000..43020790a22 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xventanacondops-xor-01.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_xventanacondops -mabi=lp64" } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */ + +long xor1(long crc, long poly) +{ + if (crc & 1) + crc ^= poly; + + return crc; +} + +/* { dg-final { scan-assembler-times "vt.maskc" 1 } } */ +/* { dg-final { scan-assembler-times "xor\t" 1 } } */ -- 2.34.1