There was once a RISC-V extension draft ("N"), which introduced
user-level interrupts. However, it was never ratified and the
specification draft has been removed from the RISC-V ISA manual
in commit `b6cade07034` with the comment "it'll likely need to
be redesigned".
Support for a N extension never made it to GCC, but we support
fuction attributes for user-level interrupt handlers that use
the URET instruction.
The "user" interrupt attribute was documented in the RISC-V C API,
but has been removed in PR #106 in May 2025 (driven by LLVM devs/
maintainers and ack'ed by at least one GCC maintainer).
Let's drop URET support from GCC as well.
gcc/ChangeLog:
* config/riscv/riscv.cc (enum riscv_privilege_levels): Remove USER_MODE.
(riscv_handle_type_attribute): Remove "user" interrupts.
(riscv_expand_epilogue): Likewise.
(riscv_get_interrupt_type): Likewise.
* config/riscv/riscv.md (riscv_uret): Remove URET pattern.
* doc/extend.texi: Remove documentation of user interrupts.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/interrupt-conflict-mode.c: Remove "user"
interrupts.
* gcc.target/riscv/xtheadint-push-pop.c: Likewise.
* gcc.target/riscv/interrupt-umode.c: Removed.
Reported-by: Sam Elliott <[email protected]>
Signed-off-by: Christoph Müllner <[email protected]>
---
gcc/config/riscv/riscv.cc | 19 ++++++++-----------
gcc/config/riscv/riscv.md | 8 --------
gcc/doc/extend.texi | 4 ++--
.../riscv/interrupt-conflict-mode.c | 2 +-
.../gcc.target/riscv/interrupt-umode.c | 8 --------
.../gcc.target/riscv/xtheadint-push-pop.c | 6 ------
6 files changed, 11 insertions(+), 36 deletions(-)
delete mode 100644 gcc/testsuite/gcc.target/riscv/interrupt-umode.c
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index b80d2a0efab4..b4f2d138efa9 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, RNMI_MODE
+ UNKNOWN_MODE, SUPERVISOR_MODE, MACHINE_MODE, RNMI_MODE
};
struct GTY(()) mode_switching_info {
@@ -6929,11 +6929,12 @@ riscv_handle_type_attribute (tree *node
ATTRIBUTE_UNUSED, tree name, tree args,
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"))
+ else if (strcmp (string, "supervisor")
+ && strcmp (string, "machine")
+ && strcmp (string, "rnmi"))
{
warning (OPT_Wattributes,
- "argument to %qE attribute is not %<\"user\"%>,
%<\"supervisor\"%>, "
+ "argument to %qE attribute is not %<\"supervisor\"%>, "
"%<\"machine\"%>, or %<\"rnmi\"%>", name);
*no_add_attrs = true;
}
@@ -9715,14 +9716,12 @@ riscv_expand_epilogue (int style)
if (th_int_mask && TH_INT_INTERRUPT (cfun))
emit_jump_insn (gen_th_int_pop ());
- else if (mode == MACHINE_MODE)
- 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 ());
+ else /* Must be MACHINE_MODE. */
+ emit_jump_insn (gen_riscv_mret ());
}
else if (style != SIBCALL_RETURN)
{
@@ -12064,9 +12063,7 @@ riscv_get_interrupt_type (tree decl)
{
const char *string = TREE_STRING_POINTER (TREE_VALUE (attr_args));
- if (!strcmp (string, "user"))
- return USER_MODE;
- else if (!strcmp (string, "supervisor"))
+ if (!strcmp (string, "supervisor"))
return SUPERVISOR_MODE;
else if (!strcmp (string, "rnmi"))
return RNMI_MODE;
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 0f29baa47e20..578dd43441e2 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -120,7 +120,6 @@ (define_c_enum "unspecv" [
;; Interrupt handler instructions.
UNSPECV_MRET
UNSPECV_SRET
- UNSPECV_URET
UNSPECV_MNRET
;; Blockage and synchronization.
@@ -4167,13 +4166,6 @@ (define_insn "riscv_sret"
"sret"
[(set_attr "type" "ret")])
-(define_insn "riscv_uret"
- [(return)
- (unspec_volatile [(const_int 0)] UNSPECV_URET)]
- ""
- "uret"
- [(set_attr "type" "ret")])
-
(define_insn "riscv_mnret"
[(return)
(unspec_volatile [(const_int 0)] UNSPECV_MNRET)]
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 125eaf46331b..224d6197d639 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -5654,10 +5654,10 @@ You can specify the kind of interrupt to be handled by
adding an optional
parameter to the interrupt attribute like this:
@smallexample
-void f (void) __attribute__ ((interrupt ("user")));
+void f (void) __attribute__ ((interrupt ("supervisor")));
@end smallexample
-Permissible values for this parameter are @code{user}, @code{supervisor},
+Permissible values for this parameter are @code{supervisor},
@code{machine}, and @code{rnmi}. If there is no parameter, then it
defaults to @code{machine}.
diff --git a/gcc/testsuite/gcc.target/riscv/interrupt-conflict-mode.c
b/gcc/testsuite/gcc.target/riscv/interrupt-conflict-mode.c
index 81ebf5fba67d..15cc3eeb7304 100644
--- a/gcc/testsuite/gcc.target/riscv/interrupt-conflict-mode.c
+++ b/gcc/testsuite/gcc.target/riscv/interrupt-conflict-mode.c
@@ -1,7 +1,7 @@
/* Verify proper errors are generated for conflicted interrupt type. */
/* { dg-do compile } */
/* { dg-options "" } */
-void __attribute__ ((interrupt ("user")))
+void __attribute__ ((interrupt ("supervisor")))
foo(void);
void __attribute__ ((interrupt ("machine")))
diff --git a/gcc/testsuite/gcc.target/riscv/interrupt-umode.c
b/gcc/testsuite/gcc.target/riscv/interrupt-umode.c
deleted file mode 100644
index 042abf02ad29..000000000000
--- a/gcc/testsuite/gcc.target/riscv/interrupt-umode.c
+++ /dev/null
@@ -1,8 +0,0 @@
-/* Verify the return instruction is mret. */
-/* { dg-do compile } */
-/* { dg-options "" } */
-void __attribute__ ((interrupt ("user")))
-foo (void)
-{
-}
-/* { dg-final { scan-assembler {\muret} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadint-push-pop.c
b/gcc/testsuite/gcc.target/riscv/xtheadint-push-pop.c
index dc5609c8f76e..167fa15843ce 100644
--- a/gcc/testsuite/gcc.target/riscv/xtheadint-push-pop.c
+++ b/gcc/testsuite/gcc.target/riscv/xtheadint-push-pop.c
@@ -20,12 +20,6 @@ void func_machine (void)
/* { dg-final { scan-assembler-times {\mth\.ipop\M} 2 { target { rv32 } } } }
*/
-__attribute__ ((interrupt ("user")))
-void func_usr (void)
-{
- f ();
-}
-
__attribute__ ((interrupt ("supervisor")))
void func_supervisor (void)
{
--
2.50.1