@@ -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}
};
@@ -319,6 +319,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 \
@@ -2725,7 +2725,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))))
@@ -3822,7 +3822,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
@@ -2577,7 +2577,7 @@
(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]))
@@ -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):
@@ -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.
@@ -20,6 +21,8 @@
(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 "maskcn") (ne "maskc")])
+(define_code_attr nez_ventana [(eq "maskc") (ne "maskcn")])
;; Zicond
(define_insn "*czero.<eqz>.<GPR:mode><X:mode>"
@@ -28,8 +31,15 @@
(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.<eqz_ventana>\t%0,%2,%1";
+ else
+ gcc_unreachable ();
+ }
)
(define_insn "*czero.<nez>.<GPR:mode><X:mode>"
@@ -38,8 +48,15 @@
(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.<nez_ventana>\t%0,%2,%1";
+ else
+ gcc_unreachable ();
+ }
)
;; Special optimization under eq/ne in primitive semantics
@@ -49,8 +66,15 @@
(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"
@@ -59,8 +83,15 @@
(const_int 0))
(match_operand:GPR 2 "register_operand" "r")
(match_operand:GPR 3 "register_operand" "1")))]
- "TARGET_ZICOND && rtx_equal_p (operands[1], operands[3])"
- "czero.nez\t%0,%2,%1"
+ "TARGET_ZICOND_LIKE && rtx_equal_p (operands[1], operands[3])"
+ {
+ if (TARGET_ZICOND)
+ return "czero.nez\t%0,%2,%1";
+ else if (TARGET_XVENTANACONDOPS && TARGET_64BIT)
+ return "vt.maskcn\t%0,%2,%1";
+ else
+ gcc_unreachable ();
+ }
)
;; Combine creates this form in some cases (particularly the coremark
@@ -72,7 +103,7 @@
(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)
@@ -85,7 +116,7 @@
(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)
new file mode 100644
@@ -0,0 +1,45 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_xventanacondops -mabi=ilp32d" } */
+
+long primitiveSemantics_00(long a, long b) { return a == 0 ? 0 : b; }
+
+long primitiveSemantics_01(long a, long b) { return a != 0 ? 0 : b; }
+
+long primitiveSemantics_02(long a, long b) { return a == 0 ? b : 0; }
+
+long primitiveSemantics_03(long a, long b) { return a != 0 ? b : 0; }
+
+long primitiveSemantics_04(long a, long b) {
+ if (a)
+ b = 0;
+ return b;
+}
+
+long primitiveSemantics_05(long a, long b) {
+ if (!a)
+ b = 0;
+ return b;
+}
+
+int primitiveSemantics_06(int a, int b) { return a == 0 ? 0 : b; }
+
+int primitiveSemantics_07(int a, int b) { return a != 0 ? 0 : b; }
+
+int primitiveSemantics_08(int a, int b) { return a == 0 ? b : 0; }
+
+int primitiveSemantics_09(int a, int b) { return a != 0 ? b : 0; }
+
+int primitiveSemantics_10(int a, int b) {
+ if (a)
+ b = 0;
+ return b;
+}
+
+int primitiveSemantics_11(int a, int b) {
+ if (!a)
+ b = 0;
+ return b;
+}
+
+/* { dg-final { scan-assembler-not "vt\\.maskc\t" } } */
+/* { dg-final { scan-assembler-not "vt\\.maskcn\t" } } */
new file mode 100644
@@ -0,0 +1,48 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_xventanacondops -mabi=lp64d" } */
+/* { dg-skip-if "" { *-*-* } {"-O0" "-Og"} } */
+
+long primitiveSemantics_00(long a, long b) { return a == 0 ? 0 : b; }
+
+long primitiveSemantics_01(long a, long b) { return a != 0 ? 0 : b; }
+
+long primitiveSemantics_02(long a, long b) { return a == 0 ? b : 0; }
+
+long primitiveSemantics_03(long a, long b) { return a != 0 ? b : 0; }
+
+long primitiveSemantics_04(long a, long b) {
+ if (a)
+ b = 0;
+ return b;
+}
+
+long primitiveSemantics_05(long a, long b) {
+ if (!a)
+ b = 0;
+ return b;
+}
+
+int primitiveSemantics_06(int a, int b) { return a == 0 ? 0 : b; }
+
+int primitiveSemantics_07(int a, int b) { return a != 0 ? 0 : b; }
+
+int primitiveSemantics_08(int a, int b) { return a == 0 ? b : 0; }
+
+int primitiveSemantics_09(int a, int b) { return a != 0 ? b : 0; }
+
+int primitiveSemantics_10(int a, int b) {
+ if (a)
+ b = 0;
+ return b;
+}
+
+int primitiveSemantics_11(int a, int b) {
+ if (!a)
+ b = 0;
+ return b;
+}
+
+/* { 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" } } */
new file mode 100644
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_xventanacondops -mabi=lp64d" } */
+/* { 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\t" 1 } } */
+/* { dg-final { scan-assembler-times "xor\t" 1 } } */