@@ -207,13 +207,39 @@ riscv_pragma_intrinsic (cpp_reader *)
{
/* To make the the rvv types and intrinsic API available for the
target("arch=+v") attribute, we need to temporally enable the
- TARGET_VECTOR, and disable it after all initialized. */
+ related flags, and disable it after all initialized. */
target_flags |= MASK_VECTOR;
-
+ riscv_vector_elen_flags = riscv_vector_elen_flags
+ | MASK_VECTOR_ELEN_32
+ | MASK_VECTOR_ELEN_64
+ | MASK_VECTOR_ELEN_FP_16
+ | MASK_VECTOR_ELEN_FP_32
+ | MASK_VECTOR_ELEN_FP_64;
+ riscv_zvl_flags = riscv_zvl_flags
+ | MASK_ZVL32B
+ | MASK_ZVL64B
+ | MASK_ZVL128B;
+
+ riscv_option_override ();
+ init_adjust_machine_modes ();
riscv_vector::init_builtins ();
riscv_vector::handle_pragma_vector ();
target_flags &= ~MASK_VECTOR;
+ riscv_vector_elen_flags = riscv_vector_elen_flags
+ & ~MASK_VECTOR_ELEN_32
+ & ~MASK_VECTOR_ELEN_64
+ & ~MASK_VECTOR_ELEN_FP_16
+ & ~MASK_VECTOR_ELEN_FP_32
+ & ~MASK_VECTOR_ELEN_FP_64;
+ riscv_zvl_flags = riscv_zvl_flags
+ & ~MASK_ZVL32B
+ & ~MASK_ZVL64B
+ & ~MASK_ZVL128B;
+
+ /* Re-initialize after the flags are restored. */
+ riscv_option_override ();
+ init_adjust_machine_modes ();
}
}
else
@@ -762,6 +762,7 @@ extern bool
riscv_option_valid_attribute_p (tree, tree, tree, int);
extern void
riscv_override_options_internal (struct gcc_options *);
+extern void riscv_option_override (void);
struct riscv_tune_param;
/* Information about one micro-arch we know about. */
@@ -4588,8 +4588,11 @@ expand_builtin (unsigned int code, tree exp, rtx target)
registered_function &rfn = *(*registered_functions)[code];
if (!TARGET_VECTOR)
- error_at (EXPR_LOCATION (exp),
- "builtin function %qE requires the V ISA extension", exp);
+ {
+ error_at (EXPR_LOCATION (exp),
+ "builtin function %qE requires the V ISA extension", exp);
+ return target;
+ }
return function_expander (rfn.instance, rfn.decl, exp, target).expand ();
}
@@ -5459,6 +5459,96 @@ riscv_v_abi ()
return v_abi;
}
+static bool
+riscv_vector_int_type_p (const_tree type)
+{
+ const char *name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
+
+ return strstr (name, "vint") != NULL || strstr (name, "vuint") != NULL;
+}
+
+static bool
+riscv_vector_float_type_p (const_tree type)
+{
+ const char *name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
+
+ return strstr (name, "vfloat") != NULL;
+}
+
+static unsigned
+riscv_vector_element_bitsize (const_tree type)
+{
+ const char *name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
+
+ if (strstr (name, "bool") != NULL)
+ return 1;
+ if (strstr (name, "int8") != NULL)
+ return 8;
+ else if (strstr (name, "int16") != NULL || strstr (name, "float16") != NULL)
+ return 16;
+ else if (strstr (name, "int32") != NULL || strstr (name, "float32") != NULL)
+ return 32;
+ else if (strstr (name, "int64") != NULL || strstr (name, "float64") != NULL)
+ return 64;
+
+ gcc_unreachable ();
+}
+
+static void
+riscv_validate_vector_type (const_tree type, const char *hint)
+{
+ gcc_assert (riscv_vector_type_p (type));
+
+ if (VECTOR_MODE_P (TYPE_MODE (type)))
+ return;
+
+ if (!TARGET_VECTOR)
+ {
+ error_at (input_location, "%s %qT requires the V ISA extension",
+ hint, type);
+ return;
+ }
+
+ unsigned element_bitsize = riscv_vector_element_bitsize (type);
+ bool int_type_p = riscv_vector_int_type_p (type);
+ bool float_type_p = riscv_vector_float_type_p (type);
+
+ if (int_type_p && element_bitsize == 64
+ && !TARGET_VECTOR_ELEN_64_P (riscv_vector_elen_flags))
+ {
+ error_at (input_location,
+ "%s %qT requires the zve64x, zve64f or zve64d ISA extension",
+ hint, type);
+ return;
+ }
+
+ if (float_type_p && element_bitsize == 16
+ && !TARGET_VECTOR_ELEN_FP_16_P (riscv_vector_elen_flags))
+ {
+ error_at (input_location,
+ "%s %qT requires the zvfhmin or zvfh ISA extension",
+ hint, type);
+ return;
+ }
+
+ if (float_type_p && element_bitsize == 32
+ && !TARGET_VECTOR_ELEN_FP_32_P (riscv_vector_elen_flags))
+ {
+ error_at (input_location,
+ "%s %qT requires the zve32f, zve64f or zve64d ISA extension",
+ hint, type);
+ return;
+ }
+
+ if (float_type_p && element_bitsize == 64
+ && !TARGET_VECTOR_ELEN_FP_64_P (riscv_vector_elen_flags))
+ {
+ error_at (input_location,
+ "%s %qT requires the zve64d ISA extension", hint, type);
+ return;
+ }
+}
+
/* Return true if a function with type FNTYPE returns its value in
RISC-V V registers. */
@@ -5469,9 +5559,7 @@ riscv_return_value_is_vector_type_p (const_tree fntype)
if (riscv_vector_type_p (return_type))
{
- if (!TARGET_VECTOR)
- error_at (input_location,
- "return type %qT requires the V ISA extension", return_type);
+ riscv_validate_vector_type (return_type, "return type");
return true;
}
else
@@ -5490,10 +5578,7 @@ riscv_arguments_is_vector_type_p (const_tree fntype)
tree arg_type = TREE_VALUE (chain);
if (riscv_vector_type_p (arg_type))
{
- if (!TARGET_VECTOR)
- error_at (input_location,
- "argument type %qT requires the V ISA extension",
- arg_type);
+ riscv_validate_vector_type (arg_type, "argument type");
return true;
}
}
@@ -9107,7 +9192,7 @@ riscv_override_options_internal (struct gcc_options *opts)
/* Implement TARGET_OPTION_OVERRIDE. */
-static void
+void
riscv_option_override (void)
{
#ifdef SUBTARGET_OVERRIDE_OPTIONS
new file mode 100644
@@ -0,0 +1,12 @@
+/* Test that we do not have error when compile */
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -O3" } */
+
+#include "riscv_vector.h"
+
+vfloat16m1_t
+__attribute__((target("arch=+v,+zvfh")))
+test_1 (vfloat16m1_t a, vfloat16m1_t b, size_t vl)
+{
+ return __riscv_vfadd_vv_f16m1 (a, b, vl);
+}
new file mode 100644
@@ -0,0 +1,26 @@
+/* Test that we do not have error when compile */
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -O3" } */
+
+#include "riscv_vector.h"
+
+vint8m1_t
+__attribute__((target("arch=+zve32x")))
+test_1 (vint8m1_t a, vint8m1_t b, size_t vl)
+{
+ return __riscv_vadd_vv_i8m1 (a, b, vl);
+}
+
+vint16m1_t
+__attribute__((target("arch=+zve32x")))
+test_2 (vint16m1_t a, vint16m1_t b, size_t vl)
+{
+ return __riscv_vadd_vv_i16m1 (a, b, vl);
+}
+
+vint32m1_t
+__attribute__((target("arch=+zve32x")))
+test_3 (vint32m1_t a, vint32m1_t b, size_t vl)
+{
+ return __riscv_vadd_vv_i32m1 (a, b, vl);
+}
new file mode 100644
@@ -0,0 +1,33 @@
+/* Test that we do not have error when compile */
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -O3" } */
+
+#include "riscv_vector.h"
+
+vint8m1_t
+__attribute__((target("arch=+zve32f")))
+test_1 (vint8m1_t a, vint8m1_t b, size_t vl)
+{
+ return __riscv_vadd_vv_i8m1 (a, b, vl);
+}
+
+vint16m1_t
+__attribute__((target("arch=+zve32f")))
+test_2 (vint16m1_t a, vint16m1_t b, size_t vl)
+{
+ return __riscv_vadd_vv_i16m1 (a, b, vl);
+}
+
+vint32m1_t
+__attribute__((target("arch=+zve32f")))
+test_3 (vint32m1_t a, vint32m1_t b, size_t vl)
+{
+ return __riscv_vadd_vv_i32m1 (a, b, vl);
+}
+
+vfloat32m1_t
+__attribute__((target("arch=+zve32f")))
+test_4 (vfloat32m1_t a, vfloat32m1_t b, size_t vl)
+{
+ return __riscv_vfadd_vv_f32m1 (a, b, vl);
+}
new file mode 100644
@@ -0,0 +1,33 @@
+/* Test that we do not have error when compile */
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -O3" } */
+
+#include "riscv_vector.h"
+
+vint8m1_t
+__attribute__((target("arch=+zve64x")))
+test_1 (vint8m1_t a, vint8m1_t b, size_t vl)
+{
+ return __riscv_vadd_vv_i8m1 (a, b, vl);
+}
+
+vint16m1_t
+__attribute__((target("arch=+zve64x")))
+test_2 (vint16m1_t a, vint16m1_t b, size_t vl)
+{
+ return __riscv_vadd_vv_i16m1 (a, b, vl);
+}
+
+vint32m1_t
+__attribute__((target("arch=+zve64x")))
+test_3 (vint32m1_t a, vint32m1_t b, size_t vl)
+{
+ return __riscv_vadd_vv_i32m1 (a, b, vl);
+}
+
+vint64m1_t
+__attribute__((target("arch=+zve64x")))
+test_4 (vint64m1_t a, vint64m1_t b, size_t vl)
+{
+ return __riscv_vadd_vv_i64m1 (a, b, vl);
+}
new file mode 100644
@@ -0,0 +1,40 @@
+/* Test that we do not have error when compile */
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -O3" } */
+
+#include "riscv_vector.h"
+
+vint8m1_t
+__attribute__((target("arch=+zve64f")))
+test_1 (vint8m1_t a, vint8m1_t b, size_t vl)
+{
+ return __riscv_vadd_vv_i8m1 (a, b, vl);
+}
+
+vint16m1_t
+__attribute__((target("arch=+zve64f")))
+test_2 (vint16m1_t a, vint16m1_t b, size_t vl)
+{
+ return __riscv_vadd_vv_i16m1 (a, b, vl);
+}
+
+vint32m1_t
+__attribute__((target("arch=+zve64f")))
+test_3 (vint32m1_t a, vint32m1_t b, size_t vl)
+{
+ return __riscv_vadd_vv_i32m1 (a, b, vl);
+}
+
+vint64m1_t
+__attribute__((target("arch=+zve64f")))
+test_4 (vint64m1_t a, vint64m1_t b, size_t vl)
+{
+ return __riscv_vadd_vv_i64m1 (a, b, vl);
+}
+
+vfloat32m1_t
+__attribute__((target("arch=+zve64f")))
+test_5 (vfloat32m1_t a, vfloat32m1_t b, size_t vl)
+{
+ return __riscv_vfadd_vv_f32m1 (a, b, vl);
+}
new file mode 100644
@@ -0,0 +1,47 @@
+/* Test that we do not have error when compile */
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -O3" } */
+
+#include "riscv_vector.h"
+
+vint8m1_t
+__attribute__((target("arch=+zve64d")))
+test_1 (vint8m1_t a, vint8m1_t b, size_t vl)
+{
+ return __riscv_vadd_vv_i8m1 (a, b, vl);
+}
+
+vint16m1_t
+__attribute__((target("arch=+zve64d")))
+test_2 (vint16m1_t a, vint16m1_t b, size_t vl)
+{
+ return __riscv_vadd_vv_i16m1 (a, b, vl);
+}
+
+vint32m1_t
+__attribute__((target("arch=+zve64d")))
+test_3 (vint32m1_t a, vint32m1_t b, size_t vl)
+{
+ return __riscv_vadd_vv_i32m1 (a, b, vl);
+}
+
+vint64m1_t
+__attribute__((target("arch=+zve64d")))
+test_4 (vint64m1_t a, vint64m1_t b, size_t vl)
+{
+ return __riscv_vadd_vv_i64m1 (a, b, vl);
+}
+
+vfloat32m1_t
+__attribute__((target("arch=+zve64d")))
+test_5 (vfloat32m1_t a, vfloat32m1_t b, size_t vl)
+{
+ return __riscv_vfadd_vv_f32m1 (a, b, vl);
+}
+
+vfloat64m1_t
+__attribute__((target("arch=+zve64d")))
+test_6 (vfloat64m1_t a, vfloat64m1_t b, size_t vl)
+{
+ return __riscv_vfadd_vv_f64m1 (a, b, vl);
+}
new file mode 100644
@@ -0,0 +1,12 @@
+/* Test that we do not have error when compile */
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -O3" } */
+
+#include "riscv_vector.h"
+
+vfloat32m1_t
+__attribute__((target("arch=+v,+zvfhmin")))
+test_1 (vfloat16mf2_t a, size_t vl)
+{
+ return __riscv_vfwcvt_f_f_v_f32m1 (a, vl);
+}
new file mode 100644
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -O3" } */
+
+#include "riscv_vector.h"
+
+vint64m1_t
+__attribute__((target("arch=+zve32x")))
+test_1 (vint64m1_t a, vint64m1_t b, size_t vl)
+{
+ return __riscv_vadd_vv_i64m1 (a, b, vl);
+}
+
+/* { dg-error "return type 'vint64m1_t' requires the zve64x, zve64f or zve64d ISA extension" "" { target { "riscv*-*-*" } } 0 } */
new file mode 100644
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -O3" } */
+
+#include "riscv_vector.h"
+
+vfloat32m1_t
+__attribute__((target("arch=+zve32x")))
+test_1 (vfloat32m1_t a, vfloat32m1_t b, size_t vl)
+{
+ return __riscv_vfadd_vv_f32m1 (a, b, vl);
+}
+
+/* { dg-error "return type 'vfloat32m1_t' requires the zve32f, zve64f or zve64d ISA extension" "" { target { "riscv*-*-*" } } 0 } */
new file mode 100644
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -O3" } */
+
+#include "riscv_vector.h"
+
+vfloat16m1_t
+__attribute__((target("arch=+zve32x")))
+test_1 (vfloat16m1_t a, vfloat16m1_t b, size_t vl)
+{
+ return __riscv_vfadd_vv_f16m1 (a, b, vl);
+}
+
+/* { dg-error "return type 'vfloat16m1_t' requires the zvfhmin or zvfh ISA extension" "" { target { "riscv*-*-*" } } 0 } */
new file mode 100644
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -O3" } */
+
+#include "riscv_vector.h"
+
+vfloat64m1_t
+__attribute__((target("arch=+zve32x")))
+test_1 (vfloat64m1_t a, vfloat64m1_t b, size_t vl)
+{
+ return __riscv_vfadd_vv_f64m1 (a, b, vl);
+}
+
+/* { dg-error "return type 'vfloat64m1_t' requires the zve64d ISA extension" "" { target { "riscv*-*-*" } } 0 } */
new file mode 100644
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -O3" } */
+
+#include "riscv_vector.h"
+
+vint64m1_t
+__attribute__((target("arch=+zve32f")))
+test_1 (vint64m1_t a, vint64m1_t b, size_t vl)
+{
+ return __riscv_vadd_vv_i64m1 (a, b, vl);
+}
+
+/* { dg-error "return type 'vint64m1_t' requires the zve64x, zve64f or zve64d ISA extension" "" { target { "riscv*-*-*" } } 0 } */
new file mode 100644
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -O3" } */
+
+#include "riscv_vector.h"
+
+vfloat16m1_t
+__attribute__((target("arch=+zve32f")))
+test_1 (vfloat16m1_t a, vfloat16m1_t b, size_t vl)
+{
+ return __riscv_vfadd_vv_f16m1 (a, b, vl);
+}
+
+/* { dg-error "return type 'vfloat16m1_t' requires the zvfhmin or zvfh ISA extension" "" { target { "riscv*-*-*" } } 0 } */
new file mode 100644
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -O3" } */
+
+#include "riscv_vector.h"
+
+vfloat64m1_t
+__attribute__((target("arch=+zve32f")))
+test_1 (vfloat64m1_t a, vfloat64m1_t b, size_t vl)
+{
+ return __riscv_vfadd_vv_f64m1 (a, b, vl);
+}
+
+/* { dg-error "return type 'vfloat64m1_t' requires the zve64d ISA extension" "" { target { "riscv*-*-*" } } 0 } */
new file mode 100644
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -O3" } */
+
+#include "riscv_vector.h"
+
+vfloat32m1_t
+__attribute__((target("arch=+zve64x")))
+test_1 (vfloat32m1_t a, vfloat32m1_t b, size_t vl)
+{
+ return __riscv_vfadd_vv_f32m1 (a, b, vl);
+}
+
+/* { dg-error "return type 'vfloat32m1_t' requires the zve32f, zve64f or zve64d ISA extension" "" { target { "riscv*-*-*" } } 0 } */
new file mode 100644
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -O3" } */
+
+#include "riscv_vector.h"
+
+vfloat16m1_t
+__attribute__((target("arch=+zve64x")))
+test_1 (vfloat16m1_t a, vfloat16m1_t b, size_t vl)
+{
+ return __riscv_vfadd_vv_f16m1 (a, b, vl);
+}
+
+/* { dg-error "return type 'vfloat16m1_t' requires the zvfhmin or zvfh ISA extension" "" { target { "riscv*-*-*" } } 0 } */
new file mode 100644
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -O3" } */
+
+#include "riscv_vector.h"
+
+vfloat64m1_t
+__attribute__((target("arch=+zve64x")))
+test_1 (vfloat64m1_t a, vfloat64m1_t b, size_t vl)
+{
+ return __riscv_vfadd_vv_f64m1 (a, b, vl);
+}
+
+/* { dg-error "return type 'vfloat64m1_t' requires the zve64d ISA extension" "" { target { "riscv*-*-*" } } 0 } */
new file mode 100644
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -O3" } */
+
+#include "riscv_vector.h"
+
+vfloat64m1_t
+__attribute__((target("arch=+zve64f")))
+test_1 (vfloat64m1_t a, vfloat64m1_t b, size_t vl)
+{
+ return __riscv_vfadd_vv_f64m1 (a, b, vl);
+}
+
+/* { dg-error "return type 'vfloat64m1_t' requires the zve64d ISA extension" "" { target { "riscv*-*-*" } } 0 } */
new file mode 100644
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -O3" } */
+
+#include "riscv_vector.h"
+
+vfloat16m1_t
+__attribute__((target("arch=+zve64f")))
+test_1 (vfloat16m1_t a, vfloat16m1_t b, size_t vl)
+{
+ return __riscv_vfadd_vv_f16m1 (a, b, vl);
+}
+
+/* { dg-error "return type 'vfloat16m1_t' requires the zvfhmin or zvfh ISA extension" "" { target { "riscv*-*-*" } } 0 } */
new file mode 100644
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -O3" } */
+
+#include "riscv_vector.h"
+
+vfloat16m1_t
+__attribute__((target("arch=+zve64d")))
+test_1 (vfloat16m1_t a, vfloat16m1_t b, size_t vl)
+{
+ return __riscv_vfadd_vv_f16m1 (a, b, vl);
+}
+
+/* { dg-error "return type 'vfloat16m1_t' requires the zvfhmin or zvfh ISA extension" "" { target { "riscv*-*-*" } } 0 } */
new file mode 100644
@@ -0,0 +1,12 @@
+/* Test that we do not have error when compile */
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -O3" } */
+
+#include "riscv_vector.h"
+
+vfloat32m1_t
+__attribute__((target("arch=+v")))
+test_1 (vfloat32m1_t a, vfloat32m1_t b, size_t vl)
+{
+ return __riscv_vfadd_vv_f32m1 (a, b, vl);
+}