LGTM :) Christoph Müllner <christoph.muell...@vrull.eu> 於 2025年7月25日 週五 05:33 寫道:
> The Smrnmi extension introduces the nmret instruction to return from RNMI > handlers. We already have basic Smrnmi support. This patch introduces > support for the nmret instruction and the ability to set the function > attribute `__attribute__ ((interrupt ("rnmi")))` to let the compiler > generate RNMI handlers. > > The attribute name is proposed in a PR for the RISC C API and approved > by LLVM maintainers: > https://github.com/riscv-non-isa/riscv-c-api-doc/pull/116 > > gcc/ChangeLog: > > * config/riscv/riscv.cc (enum riscv_privilege_levels): Add > RNMI_MODE. > (riscv_handle_type_attribute): Handle 'rnmi' interrupt attribute. > (riscv_expand_epilogue): Generate nmret for RNMI handlers. > (riscv_get_interrupt_type): Handle 'rnmi' interrupt attribute. > * config/riscv/riscv.md (riscv_rnmi): Add nmret INSN. > * doc/extend.texi: Add documentation for 'rnmi' interrupt > attribute. > > gcc/testsuite/ChangeLog: > > * gcc.target/riscv/interrupt-rnmi.c: New test. > > Signed-off-by: Christoph Müllner <christoph.muell...@vrull.eu> > --- > gcc/config/riscv/riscv.cc | 17 +++++++++++++---- > gcc/config/riscv/riscv.md | 8 ++++++++ > gcc/doc/extend.texi | 4 ++-- > gcc/testsuite/gcc.target/riscv/interrupt-rnmi.c | 11 +++++++++++ > 4 files changed, 34 insertions(+), 6 deletions(-) > create mode 100644 gcc/testsuite/gcc.target/riscv/interrupt-rnmi.c > > diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc > index cb9fe31c8b14..ac8bc9e99e48 100644 > --- a/gcc/config/riscv/riscv.cc > +++ b/gcc/config/riscv/riscv.cc > @@ -170,7 +170,7 @@ struct GTY(()) riscv_frame_info { > }; > > enum riscv_privilege_levels { > - UNKNOWN_MODE, USER_MODE, SUPERVISOR_MODE, MACHINE_MODE > + UNKNOWN_MODE, USER_MODE, SUPERVISOR_MODE, MACHINE_MODE, RNMI_MODE > }; > > struct GTY(()) mode_switching_info { > @@ -6899,12 +6899,17 @@ riscv_handle_type_attribute (tree *node > ATTRIBUTE_UNUSED, tree name, tree args, > } > > string = TREE_STRING_POINTER (cst); > - if (strcmp (string, "user") && strcmp (string, "supervisor") > - && strcmp (string, "machine")) > + if (!strcmp (string, "rnmi") && !TARGET_SMRNMI) > + { > + error ("attribute 'rnmi' requires the Smrnmi ISA extension"); > + *no_add_attrs = true; > + } > + else if (strcmp (string, "user") && strcmp (string, "supervisor") > + && strcmp (string, "machine") && strcmp (string, "rnmi")) > { > warning (OPT_Wattributes, > "argument to %qE attribute is not %<\"user\"%>, > %<\"supervisor\"%>, " > - "or %<\"machine\"%>", name); > + "%<\"machine\"%>, or %<\"rnmi\"%>", name); > *no_add_attrs = true; > } > } > @@ -9689,6 +9694,8 @@ riscv_expand_epilogue (int style) > emit_jump_insn (gen_riscv_mret ()); > else if (mode == SUPERVISOR_MODE) > emit_jump_insn (gen_riscv_sret ()); > + else if (mode == RNMI_MODE) > + emit_jump_insn (gen_riscv_mnret ()); > else > emit_jump_insn (gen_riscv_uret ()); > } > @@ -12036,6 +12043,8 @@ riscv_get_interrupt_type (tree decl) > return USER_MODE; > else if (!strcmp (string, "supervisor")) > return SUPERVISOR_MODE; > + else if (!strcmp (string, "rnmi")) > + return RNMI_MODE; > else /* Must be "machine". */ > return MACHINE_MODE; > } > diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md > index c3b504d08836..0f29baa47e20 100644 > --- a/gcc/config/riscv/riscv.md > +++ b/gcc/config/riscv/riscv.md > @@ -121,6 +121,7 @@ (define_c_enum "unspecv" [ > UNSPECV_MRET > UNSPECV_SRET > UNSPECV_URET > + UNSPECV_MNRET > > ;; Blockage and synchronization. > UNSPECV_BLOCKAGE > @@ -4173,6 +4174,13 @@ (define_insn "riscv_uret" > "uret" > [(set_attr "type" "ret")]) > > +(define_insn "riscv_mnret" > + [(return) > + (unspec_volatile [(const_int 0)] UNSPECV_MNRET)] > + "TARGET_SMRNMI" > + "mnret" > + [(set_attr "type" "ret")]) > + > (define_insn "stack_tie<mode>" > [(set (mem:BLK (scratch)) > (unspec:BLK [(match_operand:X 0 "register_operand" "r") > diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi > index 8c29e24c2670..86d539aa29f5 100644 > --- a/gcc/doc/extend.texi > +++ b/gcc/doc/extend.texi > @@ -5658,8 +5658,8 @@ void f (void) __attribute__ ((interrupt ("user"))); > @end smallexample > > Permissible values for this parameter are @code{user}, @code{supervisor}, > -and @code{machine}. If there is no parameter, then it defaults to > -@code{machine}. > +@code{machine}, and @code{rnmi}. If there is no parameter, then it > +defaults to @code{machine}. > > @cindex @code{riscv_vector_cc} function attribute, RISC-V > @item riscv_vector_cc > diff --git a/gcc/testsuite/gcc.target/riscv/interrupt-rnmi.c > b/gcc/testsuite/gcc.target/riscv/interrupt-rnmi.c > new file mode 100644 > index 000000000000..f3401080823e > --- /dev/null > +++ b/gcc/testsuite/gcc.target/riscv/interrupt-rnmi.c > @@ -0,0 +1,11 @@ > +/* Verify the return instruction is mnret. */ > +/* { dg-do compile } */ > +/* { dg-options "-march=rv32gc_smrnmi" { target { rv32 } } } */ > +/* { dg-options "-march=rv64gc_smrnmi" { target { rv64 } } } */ > + > +void __attribute__ ((interrupt ("rnmi"))) > +foo (void) > +{ > +} > + > +/* { dg-final { scan-assembler {\mmnret} } } */ > -- > 2.50.1 > >