]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
RISC-V: Add support for 'XVentanaCondOps' reusing 'Zicond' support
authorTsukasa OI <research_trasio@irq.a4lg.com>
Wed, 30 Aug 2023 02:34:35 +0000 (02:34 +0000)
committerTsukasa OI <research_trasio@irq.a4lg.com>
Thu, 7 Sep 2023 00:37:59 +0000 (00:37 +0000)
'XVentanaCondOps' is a vendor extension from Ventana Micro Systems
containing two instructions for conditional move and will be supported on
their Veyron V1 CPU.

And most notably (for historical reasons), 'XVentanaCondOps' and the
standard 'Zicond' extension are functionally equivalent (only encodings and
instruction names are different).

*   czero.eqz == vt.maskc
*   czero.nez == vt.maskcn

This commit adds support for the 'XVentanaCondOps' extension by extending
'Zicond' extension support.  With this, we can now reuse the optimization
using the 'Zicond' extension for the 'XVentanaCondOps' extension.

The specification for the 'XVentanaCondOps' extension is based on:
<https://github.com/ventanamicro/ventana-custom-extensions/releases/download/v1.0.1/ventana-custom-extensions-v1.0.1.pdf>

gcc/ChangeLog:

* common/config/riscv/riscv-common.cc (riscv_ext_flag_table):
Parse 'XVentanaCondOps' extension.
* config/riscv/riscv-opts.h (MASK_XVENTANACONDOPS): New.
(TARGET_XVENTANACONDOPS): Ditto.
(TARGET_ZICOND_LIKE): New to represent targets with conditional
moves like 'Zicond'.  It includes RV64 + 'XVentanaCondOps'.
* config/riscv/riscv.cc (riscv_rtx_costs): Replace TARGET_ZICOND
with TARGET_ZICOND_LIKE.
(riscv_expand_conditional_move): Ditto.
* config/riscv/riscv.md (mov<mode>cc): Replace TARGET_ZICOND with
TARGET_ZICOND_LIKE.
* config/riscv/riscv.opt: Add new riscv_xventana_subext.
* config/riscv/zicond.md: Modify description.
(eqz_ventana): New to match corresponding czero instructions.
(nez_ventana): Ditto.
(*czero.<eqz>.<GPR><X>): Emit a 'XVentanaCondOps' instruction if
'Zicond' is not available but 'XVentanaCondOps' + RV64 is.
(*czero.<eqz>.<GPR><X>): Ditto.
(*czero.eqz.<GPR><X>.opt1): Ditto.
(*czero.nez.<GPR><X>.opt2): Ditto.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/xventanacondops-primitiveSemantics.c: New test,
* gcc.target/riscv/xventanacondops-primitiveSemantics-rv32.c: New
test to make sure that XVentanaCondOps instructions are disabled
on RV32.
* gcc.target/riscv/xventanacondops-xor-01.c: New test,

gcc/common/config/riscv/riscv-common.cc
gcc/config/riscv/riscv-opts.h
gcc/config/riscv/riscv.cc
gcc/config/riscv/riscv.md
gcc/config/riscv/riscv.opt
gcc/config/riscv/zicond.md
gcc/testsuite/gcc.target/riscv/xventanacondops-primitiveSemantics-rv32.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/xventanacondops-primitiveSemantics.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/xventanacondops-xor-01.c [new file with mode: 0644]

index f142212f2edca8e62dafb3a2ef2ff88c6c1a3340..9a0a68fe5db3ef64eea66b4c75b8b8fd3f6d838d 100644 (file)
@@ -1493,6 +1493,8 @@ static const riscv_ext_flag_table_t riscv_ext_flag_table[] =
   {"xtheadmempair", &gcc_options::x_riscv_xthead_subext, MASK_XTHEADMEMPAIR},
   {"xtheadsync",    &gcc_options::x_riscv_xthead_subext, MASK_XTHEADSYNC},
 
+  {"xventanacondops", &gcc_options::x_riscv_xventana_subext, MASK_XVENTANACONDOPS},
+
   {NULL, NULL, 0}
 };
 
index b6b5907e111b60e7765f08b37032664ef1841970..a525f679683cb20ce3db81267c5704bf54728b92 100644 (file)
@@ -321,6 +321,12 @@ enum riscv_entity
 #define TARGET_XTHEADMEMPAIR ((riscv_xthead_subext & MASK_XTHEADMEMPAIR) != 0)
 #define TARGET_XTHEADSYNC    ((riscv_xthead_subext & MASK_XTHEADSYNC) != 0)
 
+#define MASK_XVENTANACONDOPS  (1 << 0)
+
+#define TARGET_XVENTANACONDOPS ((riscv_xventana_subext & MASK_XVENTANACONDOPS) != 0)
+
+#define TARGET_ZICOND_LIKE (TARGET_ZICOND || (TARGET_XVENTANACONDOPS && TARGET_64BIT))
+
 /* We only enable VLS modes for VLA vectorization since fixed length VLMAX mode
    is the highest priority choice and should not conflict with VLS modes.  */
 #define TARGET_VECTOR_VLS                                                      \
index a3d3389e7e253b4407af8e3ec00f59ab14ec1e6b..fb96493d974f4237c78b803f53493bde1a0184e7 100644 (file)
@@ -2767,7 +2767,7 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN
          *total = COSTS_N_INSNS (1);
          return true;
        }
-      else if (TARGET_ZICOND
+      else if (TARGET_ZICOND_LIKE
               && outer_code == SET
               && ((GET_CODE (XEXP (x, 1)) == REG
                    && XEXP (x, 2) == CONST0_RTX (GET_MODE (XEXP (x, 1))))
@@ -3864,7 +3864,7 @@ riscv_expand_conditional_move (rtx dest, rtx op, rtx cons, rtx alt)
                                                          cond, cons, alt)));
       return true;
     }
-  else if (TARGET_ZICOND
+  else if (TARGET_ZICOND_LIKE
           && GET_MODE_CLASS (mode) == MODE_INT)
     {
       /* The comparison must be comparing WORD_MODE objects.   We must
index 9da2a9f1c42996c6b2aaba6cdf479e706655f487..14dc21b6a65af6775f04c0150d40f85e5373fb27 100644 (file)
        (if_then_else:GPR (match_operand 1 "comparison_operator")
                          (match_operand:GPR 2 "sfb_alu_operand")
                          (match_operand:GPR 3 "sfb_alu_operand")))]
-  "TARGET_SFB_ALU || TARGET_XTHEADCONDMOV || TARGET_ZICOND"
+  "TARGET_SFB_ALU || TARGET_XTHEADCONDMOV || TARGET_ZICOND_LIKE"
 {
   if (riscv_expand_conditional_move (operands[0], operands[1],
                                     operands[2], operands[3]))
index 98f342348b738b2b369b2a53e6f9e01991bf7e4d..569e9af2e30cba38605ef88469dd4922c10bb25a 100644 (file)
@@ -257,6 +257,9 @@ int riscv_ztso_subext
 TargetVariable
 int riscv_xthead_subext
 
+TargetVariable
+int riscv_xventana_subext
+
 Enum
 Name(isa_spec_class) Type(enum riscv_isa_spec_class)
 Supported ISA specs (for use with the -misa-spec= option):
index c28bee5d5709bc7d039681bb91b7ac78bbdf16f1..6627be3fa5856607b633b3ce36ccf6821a31ec10 100644 (file)
@@ -1,4 +1,5 @@
-;; Machine description for the RISC-V Zicond extension
+;; Machine description for the RISC-V Zicond extension and functionally-
+;; equivalent XVentanaCondOps vendor extension
 ;; Copyright (C) 2022-23 Free Software Foundation, Inc.
 
 ;; This file is part of GCC.
 (define_code_iterator eq_or_ne [eq ne])
 (define_code_attr eqz [(eq "nez") (ne "eqz")])
 (define_code_attr nez [(eq "eqz") (ne "nez")])
+(define_code_attr eqz_ventana [(eq "n") (ne "")])
+(define_code_attr nez_ventana [(eq "") (ne "n")])
 
-;; Zicond
+;; Zicond / XVentanaCondOps
 (define_insn "*czero.<eqz>.<GPR:mode><X:mode>"
   [(set (match_operand:GPR 0 "register_operand"                      "=r")
         (if_then_else:GPR (eq_or_ne (match_operand:X 1 "register_operand" "r")
                                     (const_int 0))
                           (match_operand:GPR 2 "register_operand"    "r")
                           (const_int 0)))]
-  "TARGET_ZICOND"
-  "czero.<eqz>\t%0,%2,%1"
+  "TARGET_ZICOND_LIKE"
+  {
+    if (TARGET_ZICOND)
+      return "czero.<eqz>\t%0,%2,%1";
+    else if (TARGET_XVENTANACONDOPS && TARGET_64BIT)
+      return "vt.maskc<eqz_ventana>\t%0,%2,%1";
+    else
+      gcc_unreachable ();
+  }
 )
 
 (define_insn "*czero.<nez>.<GPR:mode><X:mode>"
                                     (const_int 0))
                           (const_int 0)
                           (match_operand:GPR 2 "register_operand"   "r")))]
-  "TARGET_ZICOND"
-  "czero.<nez>\t%0,%2,%1"
+  "TARGET_ZICOND_LIKE"
+  {
+    if (TARGET_ZICOND)
+      return "czero.<nez>\t%0,%2,%1";
+    else if (TARGET_XVENTANACONDOPS && TARGET_64BIT)
+      return "vt.maskc<nez_ventana>\t%0,%2,%1";
+    else
+      gcc_unreachable ();
+  }
 )
 
 ;; Special optimization under eq/ne in primitive semantics
                               (const_int 0))
                           (match_operand:GPR 2 "register_operand" "1")
                           (match_operand:GPR 3 "register_operand" "r")))]
-  "TARGET_ZICOND && rtx_equal_p (operands[1], operands[2])"
-  "czero.eqz\t%0,%3,%1"
+  "TARGET_ZICOND_LIKE && rtx_equal_p (operands[1], operands[2])"
+  {
+    if (TARGET_ZICOND)
+      return "czero.eqz\t%0,%3,%1";
+    else if (TARGET_XVENTANACONDOPS && TARGET_64BIT)
+      return "vt.maskc\t%0,%3,%1";
+    else
+      gcc_unreachable ();
+  }
 )
 
 (define_insn "*czero.nez.<GPR:mode><X:mode>.opt2"
                           (match_operand:GPR 2 "register_operand" "r")
                           (match_operand:GPR 3 "register_operand" "1")))]
   "TARGET_ZICOND && rtx_equal_p (operands[1], operands[3])"
-  "czero.eqz\t%0,%2,%1"
+  {
+    if (TARGET_ZICOND)
+      return "czero.eqz\t%0,%2,%1";
+    else if (TARGET_XVENTANACONDOPS && TARGET_64BIT)
+      return "vt.maskc\t%0,%2,%1";
+    else
+      gcc_unreachable ();
+  }
 )
 
 ;; Combine creates this form in some cases (particularly the coremark
                               (match_operand 2 "immediate_operand"))
               (match_operand:X 3 "register_operand")))
    (clobber (match_operand:X 4 "register_operand"))]
-  "TARGET_ZICOND && TARGET_ZBS"
+  "TARGET_ZICOND_LIKE && TARGET_ZBS"
   [(set (match_dup 4) (zero_extract:X (match_dup 1) (const_int 1) (match_dup 2)))
    (set (match_dup 0) (if_then_else:X (eq:X (match_dup 4) (const_int 0))
                                      (const_int 0)
                               (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_LIKE && !TARGET_ZBS && (UINTVAL (operands[2]) < 11)"
   [(set (match_dup 4) (and:X (match_dup 1) (match_dup 2)))
    (set (match_dup 0) (if_then_else:X (eq:X (match_dup 4) (const_int 0))
                                      (const_int 0)
diff --git a/gcc/testsuite/gcc.target/riscv/xventanacondops-primitiveSemantics-rv32.c b/gcc/testsuite/gcc.target/riscv/xventanacondops-primitiveSemantics-rv32.c
new file mode 100644 (file)
index 0000000..862ad30
--- /dev/null
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_xventanacondops -mabi=ilp32d" } */
+/* { dg-skip-if "" { *-*-* } {"-O0" "-Og"} } */
+
+#include "zicond-primitiveSemantics.c"
+
+/* { dg-final { scan-assembler-not "vt\\.maskc\t" } } */
+/* { dg-final { scan-assembler-not "vt\\.maskcn\t" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/xventanacondops-primitiveSemantics.c b/gcc/testsuite/gcc.target/riscv/xventanacondops-primitiveSemantics.c
new file mode 100644 (file)
index 0000000..644ca12
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_xventanacondops -mabi=lp64d" } */
+/* { dg-skip-if "" { *-*-* } {"-O0" "-Og"} } */
+
+#include "zicond-primitiveSemantics.c"
+
+/* { dg-final { scan-assembler-times "vt\\.maskc\t" 6 } } */
+/* { dg-final { scan-assembler-times "vt\\.maskcn\t" 6 } } */
+/* { dg-final { scan-assembler-not "beq" } } */
+/* { dg-final { scan-assembler-not "bne" } } */
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 (file)
index 0000000..634eff8
--- /dev/null
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_xventanacondops -mabi=lp64d" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+
+#include "zicond-xor-01.c"
+
+/* { dg-final { scan-assembler-times "vt\\.maskc\t" 1 } } */
+/* { dg-final { scan-assembler-times "xor\t" 1 } } */