aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorLehua Ding <lehua.ding@rivai.ai>2023-09-05 15:44:52 +0800
committerKito Cheng <kito.cheng@sifive.com>2023-09-06 16:11:12 +0800
commit4abcc5009c1ad852e235f368f535c0bf6bfa7697 (patch)
tree68c083f2f1935fa5fe13d2238ba4a8eee356a64f /gcc
parentfdd59c0f73e9e681cd5f4d0eee2dd58d60d8dbe1 (diff)
downloadgcc-4abcc5009c1ad852e235f368f535c0bf6bfa7697.zip
gcc-4abcc5009c1ad852e235f368f535c0bf6bfa7697.tar.gz
gcc-4abcc5009c1ad852e235f368f535c0bf6bfa7697.tar.bz2
RISC-V: Part-3: Output .variant_cc directive for vector function
Functions which follow vector calling convention variant need be annotated by .variant_cc directive according the RISC-V Assembly Programmer's Manual[1] and RISC-V ELF Specification[2]. [1] https://github.com/riscv-non-isa/riscv-asm-manual/blob/master/riscv-asm.md#pseudo-ops [2] https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#dynamic-linking gcc/ChangeLog: * config/riscv/riscv-protos.h (riscv_declare_function_name): Add protos. (riscv_asm_output_alias): Ditto. (riscv_asm_output_external): Ditto. * config/riscv/riscv.cc (riscv_asm_output_variant_cc): Output .variant_cc directive for vector function. (riscv_declare_function_name): Ditto. (riscv_asm_output_alias): Ditto. (riscv_asm_output_external): Ditto. * config/riscv/riscv.h (ASM_DECLARE_FUNCTION_NAME): Implement ASM_DECLARE_FUNCTION_NAME. (ASM_OUTPUT_DEF_FROM_DECLS): Implement ASM_OUTPUT_DEF_FROM_DECLS. (ASM_OUTPUT_EXTERNAL): Implement ASM_OUTPUT_EXTERNAL. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/base/abi-call-variant_cc.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/riscv/riscv-protos.h3
-rw-r--r--gcc/config/riscv/riscv.cc48
-rw-r--r--gcc/config/riscv/riscv.h15
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-variant_cc.c39
4 files changed, 105 insertions, 0 deletions
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index 7c2bbd9..6dbf6b9 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -102,6 +102,9 @@ extern bool riscv_split_64bit_move_p (rtx, rtx);
extern void riscv_split_doubleword_move (rtx, rtx);
extern const char *riscv_output_move (rtx, rtx);
extern const char *riscv_output_return ();
+extern void riscv_declare_function_name (FILE *, const char *, tree);
+extern void riscv_asm_output_alias (FILE *, const tree, const tree);
+extern void riscv_asm_output_external (FILE *, const tree, const char *);
extern bool
riscv_zcmp_valid_stack_adj_bytes_p (HOST_WIDE_INT, int);
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 1bbd92c..228515a 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -7726,6 +7726,54 @@ riscv_emit_attribute ()
riscv_stack_boundary / 8);
}
+/* Output .variant_cc for function symbol which follows vector calling
+ convention. */
+
+static void
+riscv_asm_output_variant_cc (FILE *stream, const tree decl, const char *name)
+{
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ {
+ riscv_cc cc = (riscv_cc) fndecl_abi (decl).id ();
+ if (cc == RISCV_CC_V)
+ {
+ fprintf (stream, "\t.variant_cc\t");
+ assemble_name (stream, name);
+ fprintf (stream, "\n");
+ }
+ }
+}
+
+/* Implement ASM_DECLARE_FUNCTION_NAME. */
+
+void
+riscv_declare_function_name (FILE *stream, const char *name, tree fndecl)
+{
+ riscv_asm_output_variant_cc (stream, fndecl, name);
+ ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "function");
+ ASM_OUTPUT_LABEL (stream, name);
+}
+
+/* Implement ASM_OUTPUT_DEF_FROM_DECLS. */
+
+void
+riscv_asm_output_alias (FILE *stream, const tree decl, const tree target)
+{
+ const char *name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
+ const char *value = IDENTIFIER_POINTER (target);
+ riscv_asm_output_variant_cc (stream, decl, name);
+ ASM_OUTPUT_DEF (stream, name, value);
+}
+
+/* Implement ASM_OUTPUT_EXTERNAL. */
+
+void
+riscv_asm_output_external (FILE *stream, tree decl, const char *name)
+{
+ default_elf_asm_output_external (stream, decl, name);
+ riscv_asm_output_variant_cc (stream, decl, name);
+}
+
/* Implement TARGET_ASM_FILE_START. */
static void
diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
index 68be4f3..7ac7884 100644
--- a/gcc/config/riscv/riscv.h
+++ b/gcc/config/riscv/riscv.h
@@ -1049,6 +1049,21 @@ while (0)
#define ASM_COMMENT_START "#"
+/* Add output .variant_cc directive for specific function definition. */
+#undef ASM_DECLARE_FUNCTION_NAME
+#define ASM_DECLARE_FUNCTION_NAME(STR, NAME, DECL) \
+ riscv_declare_function_name (STR, NAME, DECL)
+
+/* Add output .variant_cc directive for specific alias definition. */
+#undef ASM_OUTPUT_DEF_FROM_DECLS
+#define ASM_OUTPUT_DEF_FROM_DECLS(STR, DECL, TARGET) \
+ riscv_asm_output_alias (STR, DECL, TARGET)
+
+/* Add output .variant_cc directive for specific extern function. */
+#undef ASM_OUTPUT_EXTERNAL
+#define ASM_OUTPUT_EXTERNAL(STR, DECL, NAME) \
+ riscv_asm_output_external (STR, DECL, NAME)
+
#undef SIZE_TYPE
#define SIZE_TYPE (POINTER_SIZE == 64 ? "long unsigned int" : "unsigned int")
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-variant_cc.c b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-variant_cc.c
new file mode 100644
index 0000000..6459f8e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-variant_cc.c
@@ -0,0 +1,39 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O1 --param=riscv-vector-abi -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+void
+f_undef1 (vint8m1_t a);
+void
+f_undef2 (vint8m1x8_t a);
+void
+f_undef3 (vbool1_t a);
+vint8m1_t
+f_undef4 ();
+
+void
+bar_real (vint8m1_t a, vint8m1x8_t b, vbool1_t c)
+{
+ f_undef1 (a);
+ f_undef2 (b);
+ f_undef3 (c);
+}
+
+__attribute__ ((alias ("bar_real"))) void
+bar_alias (vint8m1_t a, vint8m1x8_t b, vbool1_t c);
+
+void
+f_1 (vint8m1_t *a, vint8m1x8_t *b, vbool1_t *c)
+{
+ bar_alias (*a, *b, *c);
+ *a = f_undef4 ();
+}
+
+/* { dg-final { scan-assembler-times {\.variant_cc\tbar_real} 1 } } */
+/* { dg-final { scan-assembler-times {\.variant_cc\tbar_alias} 1 } } */
+/* { dg-final { scan-assembler-times {\.variant_cc\tf_1} 0 } } */
+/* { dg-final { scan-assembler-times {\.variant_cc\tf_undef1} 1 } } */
+/* { dg-final { scan-assembler-times {\.variant_cc\tf_undef2} 1 } } */
+/* { dg-final { scan-assembler-times {\.variant_cc\tf_undef3} 1 } } */
+/* { dg-final { scan-assembler-times {\.variant_cc\tf_undef4} 1 } } */