diff options
author | yulong <shiyulong@iscas.ac.cn> | 2024-11-08 00:19:04 +0800 |
---|---|---|
committer | Kito Cheng <kito.cheng@sifive.com> | 2024-11-12 22:35:20 +0800 |
commit | 4bee5252c1dedad044300ff89731ac26e27c9b21 (patch) | |
tree | 5ab4500fda5e4ba462ae91d8016e08b3252ca59d | |
parent | 705a21035bddc856c1e434d5502f69758e82c7e9 (diff) | |
download | gcc-4bee5252c1dedad044300ff89731ac26e27c9b21.zip gcc-4bee5252c1dedad044300ff89731ac26e27c9b21.tar.gz gcc-4bee5252c1dedad044300ff89731ac26e27c9b21.tar.bz2 |
RISC-V: Add norelax function attribute
This patch adds norelax function attribute that be discussed in riscv-c-api-doc PR#94.
URL:https://github.com/riscv-non-isa/riscv-c-api-doc/pull/94
gcc/ChangeLog:
* config/riscv/riscv.cc (riscv_declare_function_name): Add new
attribute.
-rw-r--r-- | gcc/config/riscv/riscv.cc | 44 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/target-attr-norelax.c | 21 |
2 files changed, 49 insertions, 16 deletions
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 2e9ac28..2e1e3a9 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -654,6 +654,10 @@ static const attribute_spec riscv_gnu_attributes[] = types. */ {"riscv_rvv_vector_bits", 1, 1, false, true, false, true, riscv_handle_rvv_vector_bits_attribute, NULL}, + /* This attribute is used to declare a function, forcing it to use the + standard vector calling convention variant. Syntax: + __attribute__((norelax)). */ + {"norelax", 0, 0, true, false, false, false, NULL, NULL}, }; static const scoped_attribute_specs riscv_gnu_attribute_table = @@ -10051,24 +10055,31 @@ 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_FUNCTION_LABEL (stream, name, fndecl); - if (DECL_FUNCTION_SPECIFIC_TARGET (fndecl)) + if (DECL_FUNCTION_SPECIFIC_TARGET (fndecl) + || lookup_attribute ("norelax", DECL_ATTRIBUTES (fndecl))) { fprintf (stream, "\t.option push\n"); + if (lookup_attribute ("norelax", DECL_ATTRIBUTES (fndecl))) + { + fprintf (stream, "\t.option norelax\n"); + } + if (DECL_FUNCTION_SPECIFIC_TARGET (fndecl)) + { + struct cl_target_option *local_cl_target + = TREE_TARGET_OPTION (DECL_FUNCTION_SPECIFIC_TARGET (fndecl)); + struct cl_target_option *global_cl_target + = TREE_TARGET_OPTION (target_option_default_node); - struct cl_target_option *local_cl_target = - TREE_TARGET_OPTION (DECL_FUNCTION_SPECIFIC_TARGET (fndecl)); - struct cl_target_option *global_cl_target = - TREE_TARGET_OPTION (target_option_default_node); - - const char *local_arch_str = get_arch_str (local_cl_target); - const char *arch_str = local_arch_str != NULL - ? local_arch_str - : riscv_arch_str (true).c_str (); - fprintf (stream, "\t.option arch, %s\n", arch_str); - const char *local_tune_str = get_tune_str (local_cl_target); - const char *global_tune_str = get_tune_str (global_cl_target); - if (strcmp (local_tune_str, global_tune_str) != 0) - fprintf (stream, "\t# tune = %s\n", local_tune_str); + const char *local_arch_str = get_arch_str (local_cl_target); + const char *arch_str = local_arch_str != NULL + ? local_arch_str + : riscv_arch_str (true).c_str (); + fprintf (stream, "\t.option arch, %s\n", arch_str); + const char *local_tune_str = get_tune_str (local_cl_target); + const char *global_tune_str = get_tune_str (global_cl_target); + if (strcmp (local_tune_str, global_tune_str) != 0) + fprintf (stream, "\t# tune = %s\n", local_tune_str); + } } } @@ -10078,7 +10089,8 @@ riscv_declare_function_size (FILE *stream, const char *name, tree fndecl) if (!flag_inhibit_size_directive) ASM_OUTPUT_MEASURED_SIZE (stream, name); - if (DECL_FUNCTION_SPECIFIC_TARGET (fndecl)) + if (DECL_FUNCTION_SPECIFIC_TARGET (fndecl) + || lookup_attribute ("norelax", DECL_ATTRIBUTES (fndecl))) { fprintf (stream, "\t.option pop\n"); } diff --git a/gcc/testsuite/gcc.target/riscv/target-attr-norelax.c b/gcc/testsuite/gcc.target/riscv/target-attr-norelax.c new file mode 100644 index 0000000..77de619 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/target-attr-norelax.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc" { target { rv64 } } } */ + +__attribute__((norelax)) +void foo1() +{} + +void foo2(void) +{} + +int main() +{ + foo1(); + foo2(); + return 0; +} + +/* { dg-final { scan-assembler-times ".option push\t" 1 } } */ +/* { dg-final { scan-assembler-times ".option norelax\t" 1 } } */ +/* { dg-final { scan-assembler-times ".option pop\t" 1 } } */ |