Skip to content

Commit 1603eeb

Browse files
committed
RISC-V: Add support for resumable non-maskable interrupt (RNMI) handlers
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: riscv-non-isa/riscv-c-api-doc#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 <[email protected]>
1 parent 2142ff2 commit 1603eeb

File tree

4 files changed

+34
-6
lines changed

4 files changed

+34
-6
lines changed

gcc/config/riscv/riscv.cc

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ struct GTY(()) riscv_frame_info {
170170
};
171171

172172
enum riscv_privilege_levels {
173-
UNKNOWN_MODE, USER_MODE, SUPERVISOR_MODE, MACHINE_MODE
173+
UNKNOWN_MODE, USER_MODE, SUPERVISOR_MODE, MACHINE_MODE, RNMI_MODE
174174
};
175175

176176
struct GTY(()) mode_switching_info {
@@ -6924,12 +6924,17 @@ riscv_handle_type_attribute (tree *node ATTRIBUTE_UNUSED, tree name, tree args,
69246924
}
69256925

69266926
string = TREE_STRING_POINTER (cst);
6927-
if (strcmp (string, "user") && strcmp (string, "supervisor")
6928-
&& strcmp (string, "machine"))
6927+
if (!strcmp (string, "rnmi") && !TARGET_SMRNMI)
6928+
{
6929+
error ("attribute 'rnmi' requires the Smrnmi ISA extension");
6930+
*no_add_attrs = true;
6931+
}
6932+
else if (strcmp (string, "user") && strcmp (string, "supervisor")
6933+
&& strcmp (string, "machine") && strcmp (string, "rnmi"))
69296934
{
69306935
warning (OPT_Wattributes,
69316936
"argument to %qE attribute is not %<\"user\"%>, %<\"supervisor\"%>, "
6932-
"or %<\"machine\"%>", name);
6937+
"%<\"machine\"%>, or %<\"rnmi\"%>", name);
69336938
*no_add_attrs = true;
69346939
}
69356940
}
@@ -9714,6 +9719,8 @@ riscv_expand_epilogue (int style)
97149719
emit_jump_insn (gen_riscv_mret ());
97159720
else if (mode == SUPERVISOR_MODE)
97169721
emit_jump_insn (gen_riscv_sret ());
9722+
else if (mode == RNMI_MODE)
9723+
emit_jump_insn (gen_riscv_mnret ());
97179724
else
97189725
emit_jump_insn (gen_riscv_uret ());
97199726
}
@@ -12061,6 +12068,8 @@ riscv_get_interrupt_type (tree decl)
1206112068
return USER_MODE;
1206212069
else if (!strcmp (string, "supervisor"))
1206312070
return SUPERVISOR_MODE;
12071+
else if (!strcmp (string, "rnmi"))
12072+
return RNMI_MODE;
1206412073
else /* Must be "machine". */
1206512074
return MACHINE_MODE;
1206612075
}

gcc/config/riscv/riscv.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@
121121
UNSPECV_MRET
122122
UNSPECV_SRET
123123
UNSPECV_URET
124+
UNSPECV_MNRET
124125

125126
;; Blockage and synchronization.
126127
UNSPECV_BLOCKAGE
@@ -4173,6 +4174,13 @@
41734174
"uret"
41744175
[(set_attr "type" "ret")])
41754176

4177+
(define_insn "riscv_mnret"
4178+
[(return)
4179+
(unspec_volatile [(const_int 0)] UNSPECV_MNRET)]
4180+
"TARGET_SMRNMI"
4181+
"mnret"
4182+
[(set_attr "type" "ret")])
4183+
41764184
(define_insn "stack_tie<mode>"
41774185
[(set (mem:BLK (scratch))
41784186
(unspec:BLK [(match_operand:X 0 "register_operand" "r")

gcc/doc/extend.texi

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5658,8 +5658,8 @@ void f (void) __attribute__ ((interrupt ("user")));
56585658
@end smallexample
56595659

56605660
Permissible values for this parameter are @code{user}, @code{supervisor},
5661-
and @code{machine}. If there is no parameter, then it defaults to
5662-
@code{machine}.
5661+
@code{machine}, and @code{rnmi}. If there is no parameter, then it
5662+
defaults to @code{machine}.
56635663

56645664
@cindex @code{riscv_vector_cc} function attribute, RISC-V
56655665
@item riscv_vector_cc
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/* Verify the return instruction is mnret. */
2+
/* { dg-do compile } */
3+
/* { dg-options "-march=rv32gc_smrnmi" { target { rv32 } } } */
4+
/* { dg-options "-march=rv64gc_smrnmi" { target { rv64 } } } */
5+
6+
void __attribute__ ((interrupt ("rnmi")))
7+
foo (void)
8+
{
9+
}
10+
11+
/* { dg-final { scan-assembler {\mmnret} } } */

0 commit comments

Comments
 (0)