[llvm] 1454db1 - [RISCV] Support resumable non-maskable interrupt handlers (#148134)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 4 01:54:54 PDT 2025
Author: Gergely Futo
Date: 2025-08-04T10:54:50+02:00
New Revision: 1454db130a7e14de4295217f9ff80e5f149564c4
URL: https://github.com/llvm/llvm-project/commit/1454db130a7e14de4295217f9ff80e5f149564c4
DIFF: https://github.com/llvm/llvm-project/commit/1454db130a7e14de4295217f9ff80e5f149564c4.diff
LOG: [RISCV] Support resumable non-maskable interrupt handlers (#148134)
The `rnmi` interrupt attribute value has been added for the `Smrnmi`
extension.
---------
Co-authored-by: Sam Elliott <sam at lenary.co.uk>
Added:
clang/test/Sema/riscv-interrupt-attr-rnmi.c
llvm/test/CodeGen/RISCV/rnmi-interrupt-attr-error.ll
llvm/test/CodeGen/RISCV/rnmi-interrupt-attr.ll
Modified:
clang/docs/ReleaseNotes.rst
clang/include/clang/Basic/Attr.td
clang/include/clang/Basic/AttrDocs.td
clang/lib/CodeGen/Targets/RISCV.cpp
clang/lib/Sema/SemaRISCV.cpp
llvm/docs/RISCVUsage.rst
llvm/lib/Target/RISCV/RISCVISelLowering.cpp
llvm/lib/Target/RISCV/RISCVInstrInfo.td
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 0bd4857077879..652e758e28466 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -198,6 +198,9 @@ LoongArch Support
RISC-V Support
^^^^^^^^^^^^^^
+- Add support for `__attribute__((interrupt("rnmi")))` to be used with the `Smrnmi` extension.
+ With this the `Smrnmi` extension is fully supported.
+
CUDA/HIP Language Changes
^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index b3ff45b3e90a3..17cae80816e9e 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -2361,6 +2361,7 @@ def RISCVInterrupt : InheritableAttr, TargetSpecificAttr<TargetRISCV> {
[
"supervisor",
"machine",
+ "rnmi",
"qci-nest",
"qci-nonest",
"SiFive-CLIC-preemptible",
@@ -2369,6 +2370,7 @@ def RISCVInterrupt : InheritableAttr, TargetSpecificAttr<TargetRISCV> {
[
"supervisor",
"machine",
+ "rnmi",
"qcinest",
"qcinonest",
"SiFiveCLICPreemptible",
diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index 76747d2b11811..326cf0bc842db 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -2905,10 +2905,13 @@ the backend to generate appropriate function entry/exit code so that it can be
used directly as an interrupt service routine.
Permissible values for this parameter are ``machine``, ``supervisor``,
-``qci-nest``, ``qci-nonest``, ``SiFive-CLIC-preemptible``, and
+``rnmi``, ``qci-nest``, ``qci-nonest``, ``SiFive-CLIC-preemptible``, and
``SiFive-CLIC-stack-swap``. If there is no parameter, then it defaults to
``machine``.
+The ``rnmi`` value is used for resumable non-maskable interrupts. It requires the
+standard Smrnmi extension.
+
The ``qci-nest`` and ``qci-nonest`` values require Qualcomm's Xqciint extension
and are used for Machine-mode Interrupts and Machine-mode Non-maskable
interrupts. These use the following instructions from Xqciint to save and
diff --git a/clang/lib/CodeGen/Targets/RISCV.cpp b/clang/lib/CodeGen/Targets/RISCV.cpp
index e3232b61a693c..a7f92981cfbd4 100644
--- a/clang/lib/CodeGen/Targets/RISCV.cpp
+++ b/clang/lib/CodeGen/Targets/RISCV.cpp
@@ -817,6 +817,9 @@ class RISCVTargetCodeGenInfo : public TargetCodeGenInfo {
case RISCVInterruptAttr::supervisor:
Kind = "supervisor";
break;
+ case RISCVInterruptAttr::rnmi:
+ Kind = "rnmi";
+ break;
case RISCVInterruptAttr::qcinest:
Kind = "qci-nest";
break;
diff --git a/clang/lib/Sema/SemaRISCV.cpp b/clang/lib/Sema/SemaRISCV.cpp
index 994cd07c1e263..7b16d080603bf 100644
--- a/clang/lib/Sema/SemaRISCV.cpp
+++ b/clang/lib/Sema/SemaRISCV.cpp
@@ -1552,9 +1552,11 @@ void SemaRISCV::handleInterruptAttr(Decl *D, const ParsedAttr &AL) {
HasSiFiveCLICType = true;
break;
case RISCVInterruptAttr::supervisor:
+ case RISCVInterruptAttr::rnmi:
case RISCVInterruptAttr::qcinest:
case RISCVInterruptAttr::qcinonest:
- // "supervisor" and "qci-(no)nest" cannot be combined with any other types
+ // "supervisor", "rnmi" and "qci-(no)nest" cannot be combined with any
+ // other types
HasUnaryType = true;
break;
}
@@ -1608,6 +1610,14 @@ void SemaRISCV::handleInterruptAttr(Decl *D, const ParsedAttr &AL) {
return;
}
} break;
+ case RISCVInterruptAttr::rnmi: {
+ if (!HasFeature("smrnmi")) {
+ Diag(AL.getLoc(),
+ diag::err_riscv_attribute_interrupt_requires_extension)
+ << RISCVInterruptAttr::ConvertInterruptTypeToStr(Type) << "Smrnmi";
+ return;
+ }
+ } break;
default:
break;
}
diff --git a/clang/test/Sema/riscv-interrupt-attr-rnmi.c b/clang/test/Sema/riscv-interrupt-attr-rnmi.c
new file mode 100644
index 0000000000000..964bae52a56f9
--- /dev/null
+++ b/clang/test/Sema/riscv-interrupt-attr-rnmi.c
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -triple riscv32-unknown-elf -target-feature +smrnmi -emit-llvm -DCHECK_IR < %s | FileCheck %s
+// RUN: %clang_cc1 %s -triple riscv32-unknown-elf -target-feature +smrnmi -verify=enabled,both -fsyntax-only
+// RUN: %clang_cc1 %s -triple riscv32-unknown-elf -verify=disabled,both -fsyntax-only
+// RUN: %clang_cc1 %s -triple riscv32-unknown-elf -target-feature -srnmi -verify=disabled,both -fsyntax-only
+
+#if defined(CHECK_IR)
+// CHECK-LABEL: foo_rnmi_interrupt() #0
+// CHECK: ret void
+__attribute__((interrupt("rnmi")))
+void foo_rnmi_interrupt(void) {}
+
+// CHECK-LABEL: @foo_rnmi_rnmi_interrupt() #0
+// CHECK: ret void
+__attribute__((interrupt("rnmi", "rnmi")))
+void foo_rnmi_rnmi_interrupt(void) {}
+
+// CHECK: attributes #0
+// CHECK: "interrupt"="rnmi"
+#else
+
+__attribute__((interrupt("rnmi"))) void test_rnmi(void) {} // disabled-error {{RISC-V 'interrupt' attribute 'rnmi' requires extension 'Smrnmi'}}
+__attribute__((interrupt("rnmi", "rnmi"))) void test_rnmi_rnmi(void) {} // disabled-error {{RISC-V 'interrupt' attribute 'rnmi' requires extension 'Smrnmi'}}
+
+__attribute__((interrupt("rnmi", "supervisor"))) void foo_rnmi_supervisor(void) {} // both-error {{RISC-V 'interrupt' attribute contains invalid combination of interrupt types}}
+__attribute__((interrupt("rnmi", "machine"))) void foo_rnmi_machine(void) {} // both-error {{RISC-V 'interrupt' attribute contains invalid combination of interrupt types}}
+
+__attribute__((interrupt("RNMI"))) void test_RNMI(void) {} // both-warning {{'interrupt' attribute argument not supported: "RNMI"}}
+#endif
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index 9f6ac558b6f7c..a29e06cdf838d 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -136,7 +136,7 @@ on support follow.
``Smepmp`` Supported
``Smmpm`` Supported
``Smnpm`` Supported
- ``Smrnmi`` Assembly Support
+ ``Smrnmi`` Supported
``Smstateen`` Assembly Support
``Ssaia`` Supported
``Ssccfg`` Supported
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index adbfbeb4669e7..b6d1ee8bc3050 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -22550,6 +22550,7 @@ SDValue RISCVTargetLowering::LowerFormalArguments(
constexpr StringLiteral SupportedInterruptKinds[] = {
"machine",
"supervisor",
+ "rnmi",
"qci-nest",
"qci-nonest",
"SiFive-CLIC-preemptible",
@@ -22567,6 +22568,8 @@ SDValue RISCVTargetLowering::LowerFormalArguments(
reportFatalUsageError(
"'SiFive-CLIC-*' interrupt kinds require XSfmclic extension");
+ if (Kind == "rnmi" && !Subtarget.hasStdExtSmrnmi())
+ reportFatalUsageError("'rnmi' interrupt kind requires Srnmi extension");
const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
if (Kind.starts_with("SiFive-CLIC-preemptible") && TFI->hasFP(MF))
reportFatalUsageError("'SiFive-CLIC-preemptible' interrupt kinds cannot "
@@ -23212,7 +23215,11 @@ RISCVTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
if (Kind == "supervisor")
RetOpc = RISCVISD::SRET_GLUE;
- else if (Kind == "qci-nest" || Kind == "qci-nonest") {
+ else if (Kind == "rnmi") {
+ assert(STI.hasFeature(RISCV::FeatureStdExtSmrnmi) &&
+ "Need Smrnmi extension for rnmi");
+ RetOpc = RISCVISD::MNRET_GLUE;
+ } else if (Kind == "qci-nest" || Kind == "qci-nonest") {
assert(STI.hasFeature(RISCV::FeatureVendorXqciint) &&
"Need Xqciint for qci-(no)nest");
RetOpc = RISCVISD::QC_C_MILEAVERET_GLUE;
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index 653607827282e..8bd383033f11c 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -75,6 +75,8 @@ def riscv_sret_glue : RVSDNode<"SRET_GLUE", SDTNone,
[SDNPHasChain, SDNPOptInGlue]>;
def riscv_mret_glue : RVSDNode<"MRET_GLUE", SDTNone,
[SDNPHasChain, SDNPOptInGlue]>;
+def riscv_mnret_glue : RVSDNode<"MNRET_GLUE", SDTNone,
+ [SDNPHasChain, SDNPOptInGlue]>;
def riscv_mileaveret_glue : RVSDNode<"QC_C_MILEAVERET_GLUE", SDTNone,
[SDNPHasChain, SDNPOptInGlue]>;
@@ -935,7 +937,6 @@ def MRET : Priv<"mret", 0b0011000>, Sched<[]> {
let rs1 = 0;
let rs2 = 0b00010;
}
-} // isBarrier = 1, isReturn = 1, isTerminator = 1
let Predicates = [HasStdExtSmrnmi] in {
def MNRET : Priv<"mnret", 0b0111000>, Sched<[]> {
@@ -944,6 +945,8 @@ def MNRET : Priv<"mnret", 0b0111000>, Sched<[]> {
let rs2 = 0b00010;
}
}// Predicates = [HasStdExtSmrnmi]
+} // isBarrier = 1, isReturn = 1, isTerminator = 1
+
def WFI : Priv<"wfi", 0b0001000>, Sched<[]> {
let rd = 0;
@@ -1801,6 +1804,8 @@ def : Pat<(riscv_call texternalsym:$func), (PseudoCALL texternalsym:$func)>;
def : Pat<(riscv_sret_glue), (SRET)>;
def : Pat<(riscv_mret_glue), (MRET)>;
+let Predicates = [HasStdExtSmrnmi] in
+def : Pat<(riscv_mnret_glue), (MNRET)>;
let isCall = 1, Defs = [X1] in {
let Predicates = [NoStdExtZicfilp] in
diff --git a/llvm/test/CodeGen/RISCV/rnmi-interrupt-attr-error.ll b/llvm/test/CodeGen/RISCV/rnmi-interrupt-attr-error.ll
new file mode 100644
index 0000000000000..19cc9948dade4
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/rnmi-interrupt-attr-error.ll
@@ -0,0 +1,9 @@
+; RUN: not llc -mtriple riscv32-unknown-elf -mattr=-smrnmi -o - %s 2>&1 \
+; RUN: | FileCheck %s
+; RUN: not llc -mtriple riscv64-unknown-elf -mattr=-smrnmi -o - %s 2>&1 \
+; RUN: | FileCheck %s
+
+; CHECK: LLVM ERROR: 'rnmi' interrupt kind requires Srnmi extension
+define void @test_rnmi() "interrupt"="rnmi" {
+ ret void
+}
diff --git a/llvm/test/CodeGen/RISCV/rnmi-interrupt-attr.ll b/llvm/test/CodeGen/RISCV/rnmi-interrupt-attr.ll
new file mode 100644
index 0000000000000..03236a07fc7f5
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/rnmi-interrupt-attr.ll
@@ -0,0 +1,373 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc -mtriple riscv32-unknown-elf -mattr=+smrnmi -o - %s \
+; RUN: -verify-machineinstrs | FileCheck --check-prefix=RNMI-RV32 %s
+
+; RUN: llc -mtriple riscv32-unknown-elf -mattr=+smrnmi -o - %s \
+; RUN: -verify-machineinstrs -frame-pointer=all | FileCheck --check-prefix=RNMI-RV32-FP %s
+
+; RUN: llc -mtriple riscv64-unknown-elf -mattr=+smrnmi -o - %s \
+; RUN: -verify-machineinstrs | FileCheck --check-prefix=RNMI-RV64 %s
+
+; RUN: llc -mtriple riscv64-unknown-elf -mattr=+smrnmi -o - %s \
+; RUN: -verify-machineinstrs -frame-pointer=all | FileCheck --check-prefix=RNMI-RV64-FP %s
+
+define void @test_rnmi_empty() "interrupt"="rnmi" {
+; RNMI-RV32-LABEL: test_rnmi_empty:
+; RNMI-RV32: # %bb.0:
+; RNMI-RV32-NEXT: mnret
+;
+; RNMI-RV32-FP-LABEL: test_rnmi_empty:
+; RNMI-RV32-FP: # %bb.0:
+; RNMI-RV32-FP-NEXT: addi sp, sp, -16
+; RNMI-RV32-FP-NEXT: .cfi_def_cfa_offset 16
+; RNMI-RV32-FP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
+; RNMI-RV32-FP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
+; RNMI-RV32-FP-NEXT: .cfi_offset ra, -4
+; RNMI-RV32-FP-NEXT: .cfi_offset s0, -8
+; RNMI-RV32-FP-NEXT: addi s0, sp, 16
+; RNMI-RV32-FP-NEXT: .cfi_def_cfa s0, 0
+; RNMI-RV32-FP-NEXT: .cfi_def_cfa sp, 16
+; RNMI-RV32-FP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
+; RNMI-RV32-FP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
+; RNMI-RV32-FP-NEXT: .cfi_restore ra
+; RNMI-RV32-FP-NEXT: .cfi_restore s0
+; RNMI-RV32-FP-NEXT: addi sp, sp, 16
+; RNMI-RV32-FP-NEXT: .cfi_def_cfa_offset 0
+; RNMI-RV32-FP-NEXT: mnret
+;
+; RNMI-RV64-LABEL: test_rnmi_empty:
+; RNMI-RV64: # %bb.0:
+; RNMI-RV64-NEXT: mnret
+;
+; RNMI-RV64-FP-LABEL: test_rnmi_empty:
+; RNMI-RV64-FP: # %bb.0:
+; RNMI-RV64-FP-NEXT: addi sp, sp, -16
+; RNMI-RV64-FP-NEXT: .cfi_def_cfa_offset 16
+; RNMI-RV64-FP-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
+; RNMI-RV64-FP-NEXT: sd s0, 0(sp) # 8-byte Folded Spill
+; RNMI-RV64-FP-NEXT: .cfi_offset ra, -8
+; RNMI-RV64-FP-NEXT: .cfi_offset s0, -16
+; RNMI-RV64-FP-NEXT: addi s0, sp, 16
+; RNMI-RV64-FP-NEXT: .cfi_def_cfa s0, 0
+; RNMI-RV64-FP-NEXT: .cfi_def_cfa sp, 16
+; RNMI-RV64-FP-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RNMI-RV64-FP-NEXT: ld s0, 0(sp) # 8-byte Folded Reload
+; RNMI-RV64-FP-NEXT: .cfi_restore ra
+; RNMI-RV64-FP-NEXT: .cfi_restore s0
+; RNMI-RV64-FP-NEXT: addi sp, sp, 16
+; RNMI-RV64-FP-NEXT: .cfi_def_cfa_offset 0
+; RNMI-RV64-FP-NEXT: mnret
+ ret void
+}
+
+declare void @callee()
+
+define void @test_rnmi_caller() "interrupt"="rnmi" {
+; RNMI-RV32-LABEL: test_rnmi_caller:
+; RNMI-RV32: # %bb.0:
+; RNMI-RV32-NEXT: addi sp, sp, -64
+; RNMI-RV32-NEXT: .cfi_def_cfa_offset 64
+; RNMI-RV32-NEXT: sw ra, 60(sp) # 4-byte Folded Spill
+; RNMI-RV32-NEXT: sw t0, 56(sp) # 4-byte Folded Spill
+; RNMI-RV32-NEXT: sw t1, 52(sp) # 4-byte Folded Spill
+; RNMI-RV32-NEXT: sw t2, 48(sp) # 4-byte Folded Spill
+; RNMI-RV32-NEXT: sw a0, 44(sp) # 4-byte Folded Spill
+; RNMI-RV32-NEXT: sw a1, 40(sp) # 4-byte Folded Spill
+; RNMI-RV32-NEXT: sw a2, 36(sp) # 4-byte Folded Spill
+; RNMI-RV32-NEXT: sw a3, 32(sp) # 4-byte Folded Spill
+; RNMI-RV32-NEXT: sw a4, 28(sp) # 4-byte Folded Spill
+; RNMI-RV32-NEXT: sw a5, 24(sp) # 4-byte Folded Spill
+; RNMI-RV32-NEXT: sw a6, 20(sp) # 4-byte Folded Spill
+; RNMI-RV32-NEXT: sw a7, 16(sp) # 4-byte Folded Spill
+; RNMI-RV32-NEXT: sw t3, 12(sp) # 4-byte Folded Spill
+; RNMI-RV32-NEXT: sw t4, 8(sp) # 4-byte Folded Spill
+; RNMI-RV32-NEXT: sw t5, 4(sp) # 4-byte Folded Spill
+; RNMI-RV32-NEXT: sw t6, 0(sp) # 4-byte Folded Spill
+; RNMI-RV32-NEXT: .cfi_offset ra, -4
+; RNMI-RV32-NEXT: .cfi_offset t0, -8
+; RNMI-RV32-NEXT: .cfi_offset t1, -12
+; RNMI-RV32-NEXT: .cfi_offset t2, -16
+; RNMI-RV32-NEXT: .cfi_offset a0, -20
+; RNMI-RV32-NEXT: .cfi_offset a1, -24
+; RNMI-RV32-NEXT: .cfi_offset a2, -28
+; RNMI-RV32-NEXT: .cfi_offset a3, -32
+; RNMI-RV32-NEXT: .cfi_offset a4, -36
+; RNMI-RV32-NEXT: .cfi_offset a5, -40
+; RNMI-RV32-NEXT: .cfi_offset a6, -44
+; RNMI-RV32-NEXT: .cfi_offset a7, -48
+; RNMI-RV32-NEXT: .cfi_offset t3, -52
+; RNMI-RV32-NEXT: .cfi_offset t4, -56
+; RNMI-RV32-NEXT: .cfi_offset t5, -60
+; RNMI-RV32-NEXT: .cfi_offset t6, -64
+; RNMI-RV32-NEXT: call callee
+; RNMI-RV32-NEXT: lw ra, 60(sp) # 4-byte Folded Reload
+; RNMI-RV32-NEXT: lw t0, 56(sp) # 4-byte Folded Reload
+; RNMI-RV32-NEXT: lw t1, 52(sp) # 4-byte Folded Reload
+; RNMI-RV32-NEXT: lw t2, 48(sp) # 4-byte Folded Reload
+; RNMI-RV32-NEXT: lw a0, 44(sp) # 4-byte Folded Reload
+; RNMI-RV32-NEXT: lw a1, 40(sp) # 4-byte Folded Reload
+; RNMI-RV32-NEXT: lw a2, 36(sp) # 4-byte Folded Reload
+; RNMI-RV32-NEXT: lw a3, 32(sp) # 4-byte Folded Reload
+; RNMI-RV32-NEXT: lw a4, 28(sp) # 4-byte Folded Reload
+; RNMI-RV32-NEXT: lw a5, 24(sp) # 4-byte Folded Reload
+; RNMI-RV32-NEXT: lw a6, 20(sp) # 4-byte Folded Reload
+; RNMI-RV32-NEXT: lw a7, 16(sp) # 4-byte Folded Reload
+; RNMI-RV32-NEXT: lw t3, 12(sp) # 4-byte Folded Reload
+; RNMI-RV32-NEXT: lw t4, 8(sp) # 4-byte Folded Reload
+; RNMI-RV32-NEXT: lw t5, 4(sp) # 4-byte Folded Reload
+; RNMI-RV32-NEXT: lw t6, 0(sp) # 4-byte Folded Reload
+; RNMI-RV32-NEXT: .cfi_restore ra
+; RNMI-RV32-NEXT: .cfi_restore t0
+; RNMI-RV32-NEXT: .cfi_restore t1
+; RNMI-RV32-NEXT: .cfi_restore t2
+; RNMI-RV32-NEXT: .cfi_restore a0
+; RNMI-RV32-NEXT: .cfi_restore a1
+; RNMI-RV32-NEXT: .cfi_restore a2
+; RNMI-RV32-NEXT: .cfi_restore a3
+; RNMI-RV32-NEXT: .cfi_restore a4
+; RNMI-RV32-NEXT: .cfi_restore a5
+; RNMI-RV32-NEXT: .cfi_restore a6
+; RNMI-RV32-NEXT: .cfi_restore a7
+; RNMI-RV32-NEXT: .cfi_restore t3
+; RNMI-RV32-NEXT: .cfi_restore t4
+; RNMI-RV32-NEXT: .cfi_restore t5
+; RNMI-RV32-NEXT: .cfi_restore t6
+; RNMI-RV32-NEXT: addi sp, sp, 64
+; RNMI-RV32-NEXT: .cfi_def_cfa_offset 0
+; RNMI-RV32-NEXT: mnret
+;
+; RNMI-RV32-FP-LABEL: test_rnmi_caller:
+; RNMI-RV32-FP: # %bb.0:
+; RNMI-RV32-FP-NEXT: addi sp, sp, -80
+; RNMI-RV32-FP-NEXT: .cfi_def_cfa_offset 80
+; RNMI-RV32-FP-NEXT: sw ra, 76(sp) # 4-byte Folded Spill
+; RNMI-RV32-FP-NEXT: sw t0, 72(sp) # 4-byte Folded Spill
+; RNMI-RV32-FP-NEXT: sw t1, 68(sp) # 4-byte Folded Spill
+; RNMI-RV32-FP-NEXT: sw t2, 64(sp) # 4-byte Folded Spill
+; RNMI-RV32-FP-NEXT: sw s0, 60(sp) # 4-byte Folded Spill
+; RNMI-RV32-FP-NEXT: sw a0, 56(sp) # 4-byte Folded Spill
+; RNMI-RV32-FP-NEXT: sw a1, 52(sp) # 4-byte Folded Spill
+; RNMI-RV32-FP-NEXT: sw a2, 48(sp) # 4-byte Folded Spill
+; RNMI-RV32-FP-NEXT: sw a3, 44(sp) # 4-byte Folded Spill
+; RNMI-RV32-FP-NEXT: sw a4, 40(sp) # 4-byte Folded Spill
+; RNMI-RV32-FP-NEXT: sw a5, 36(sp) # 4-byte Folded Spill
+; RNMI-RV32-FP-NEXT: sw a6, 32(sp) # 4-byte Folded Spill
+; RNMI-RV32-FP-NEXT: sw a7, 28(sp) # 4-byte Folded Spill
+; RNMI-RV32-FP-NEXT: sw t3, 24(sp) # 4-byte Folded Spill
+; RNMI-RV32-FP-NEXT: sw t4, 20(sp) # 4-byte Folded Spill
+; RNMI-RV32-FP-NEXT: sw t5, 16(sp) # 4-byte Folded Spill
+; RNMI-RV32-FP-NEXT: sw t6, 12(sp) # 4-byte Folded Spill
+; RNMI-RV32-FP-NEXT: .cfi_offset ra, -4
+; RNMI-RV32-FP-NEXT: .cfi_offset t0, -8
+; RNMI-RV32-FP-NEXT: .cfi_offset t1, -12
+; RNMI-RV32-FP-NEXT: .cfi_offset t2, -16
+; RNMI-RV32-FP-NEXT: .cfi_offset s0, -20
+; RNMI-RV32-FP-NEXT: .cfi_offset a0, -24
+; RNMI-RV32-FP-NEXT: .cfi_offset a1, -28
+; RNMI-RV32-FP-NEXT: .cfi_offset a2, -32
+; RNMI-RV32-FP-NEXT: .cfi_offset a3, -36
+; RNMI-RV32-FP-NEXT: .cfi_offset a4, -40
+; RNMI-RV32-FP-NEXT: .cfi_offset a5, -44
+; RNMI-RV32-FP-NEXT: .cfi_offset a6, -48
+; RNMI-RV32-FP-NEXT: .cfi_offset a7, -52
+; RNMI-RV32-FP-NEXT: .cfi_offset t3, -56
+; RNMI-RV32-FP-NEXT: .cfi_offset t4, -60
+; RNMI-RV32-FP-NEXT: .cfi_offset t5, -64
+; RNMI-RV32-FP-NEXT: .cfi_offset t6, -68
+; RNMI-RV32-FP-NEXT: addi s0, sp, 80
+; RNMI-RV32-FP-NEXT: .cfi_def_cfa s0, 0
+; RNMI-RV32-FP-NEXT: call callee
+; RNMI-RV32-FP-NEXT: .cfi_def_cfa sp, 80
+; RNMI-RV32-FP-NEXT: lw ra, 76(sp) # 4-byte Folded Reload
+; RNMI-RV32-FP-NEXT: lw t0, 72(sp) # 4-byte Folded Reload
+; RNMI-RV32-FP-NEXT: lw t1, 68(sp) # 4-byte Folded Reload
+; RNMI-RV32-FP-NEXT: lw t2, 64(sp) # 4-byte Folded Reload
+; RNMI-RV32-FP-NEXT: lw s0, 60(sp) # 4-byte Folded Reload
+; RNMI-RV32-FP-NEXT: lw a0, 56(sp) # 4-byte Folded Reload
+; RNMI-RV32-FP-NEXT: lw a1, 52(sp) # 4-byte Folded Reload
+; RNMI-RV32-FP-NEXT: lw a2, 48(sp) # 4-byte Folded Reload
+; RNMI-RV32-FP-NEXT: lw a3, 44(sp) # 4-byte Folded Reload
+; RNMI-RV32-FP-NEXT: lw a4, 40(sp) # 4-byte Folded Reload
+; RNMI-RV32-FP-NEXT: lw a5, 36(sp) # 4-byte Folded Reload
+; RNMI-RV32-FP-NEXT: lw a6, 32(sp) # 4-byte Folded Reload
+; RNMI-RV32-FP-NEXT: lw a7, 28(sp) # 4-byte Folded Reload
+; RNMI-RV32-FP-NEXT: lw t3, 24(sp) # 4-byte Folded Reload
+; RNMI-RV32-FP-NEXT: lw t4, 20(sp) # 4-byte Folded Reload
+; RNMI-RV32-FP-NEXT: lw t5, 16(sp) # 4-byte Folded Reload
+; RNMI-RV32-FP-NEXT: lw t6, 12(sp) # 4-byte Folded Reload
+; RNMI-RV32-FP-NEXT: .cfi_restore ra
+; RNMI-RV32-FP-NEXT: .cfi_restore t0
+; RNMI-RV32-FP-NEXT: .cfi_restore t1
+; RNMI-RV32-FP-NEXT: .cfi_restore t2
+; RNMI-RV32-FP-NEXT: .cfi_restore s0
+; RNMI-RV32-FP-NEXT: .cfi_restore a0
+; RNMI-RV32-FP-NEXT: .cfi_restore a1
+; RNMI-RV32-FP-NEXT: .cfi_restore a2
+; RNMI-RV32-FP-NEXT: .cfi_restore a3
+; RNMI-RV32-FP-NEXT: .cfi_restore a4
+; RNMI-RV32-FP-NEXT: .cfi_restore a5
+; RNMI-RV32-FP-NEXT: .cfi_restore a6
+; RNMI-RV32-FP-NEXT: .cfi_restore a7
+; RNMI-RV32-FP-NEXT: .cfi_restore t3
+; RNMI-RV32-FP-NEXT: .cfi_restore t4
+; RNMI-RV32-FP-NEXT: .cfi_restore t5
+; RNMI-RV32-FP-NEXT: .cfi_restore t6
+; RNMI-RV32-FP-NEXT: addi sp, sp, 80
+; RNMI-RV32-FP-NEXT: .cfi_def_cfa_offset 0
+; RNMI-RV32-FP-NEXT: mnret
+;
+; RNMI-RV64-LABEL: test_rnmi_caller:
+; RNMI-RV64: # %bb.0:
+; RNMI-RV64-NEXT: addi sp, sp, -128
+; RNMI-RV64-NEXT: .cfi_def_cfa_offset 128
+; RNMI-RV64-NEXT: sd ra, 120(sp) # 8-byte Folded Spill
+; RNMI-RV64-NEXT: sd t0, 112(sp) # 8-byte Folded Spill
+; RNMI-RV64-NEXT: sd t1, 104(sp) # 8-byte Folded Spill
+; RNMI-RV64-NEXT: sd t2, 96(sp) # 8-byte Folded Spill
+; RNMI-RV64-NEXT: sd a0, 88(sp) # 8-byte Folded Spill
+; RNMI-RV64-NEXT: sd a1, 80(sp) # 8-byte Folded Spill
+; RNMI-RV64-NEXT: sd a2, 72(sp) # 8-byte Folded Spill
+; RNMI-RV64-NEXT: sd a3, 64(sp) # 8-byte Folded Spill
+; RNMI-RV64-NEXT: sd a4, 56(sp) # 8-byte Folded Spill
+; RNMI-RV64-NEXT: sd a5, 48(sp) # 8-byte Folded Spill
+; RNMI-RV64-NEXT: sd a6, 40(sp) # 8-byte Folded Spill
+; RNMI-RV64-NEXT: sd a7, 32(sp) # 8-byte Folded Spill
+; RNMI-RV64-NEXT: sd t3, 24(sp) # 8-byte Folded Spill
+; RNMI-RV64-NEXT: sd t4, 16(sp) # 8-byte Folded Spill
+; RNMI-RV64-NEXT: sd t5, 8(sp) # 8-byte Folded Spill
+; RNMI-RV64-NEXT: sd t6, 0(sp) # 8-byte Folded Spill
+; RNMI-RV64-NEXT: .cfi_offset ra, -8
+; RNMI-RV64-NEXT: .cfi_offset t0, -16
+; RNMI-RV64-NEXT: .cfi_offset t1, -24
+; RNMI-RV64-NEXT: .cfi_offset t2, -32
+; RNMI-RV64-NEXT: .cfi_offset a0, -40
+; RNMI-RV64-NEXT: .cfi_offset a1, -48
+; RNMI-RV64-NEXT: .cfi_offset a2, -56
+; RNMI-RV64-NEXT: .cfi_offset a3, -64
+; RNMI-RV64-NEXT: .cfi_offset a4, -72
+; RNMI-RV64-NEXT: .cfi_offset a5, -80
+; RNMI-RV64-NEXT: .cfi_offset a6, -88
+; RNMI-RV64-NEXT: .cfi_offset a7, -96
+; RNMI-RV64-NEXT: .cfi_offset t3, -104
+; RNMI-RV64-NEXT: .cfi_offset t4, -112
+; RNMI-RV64-NEXT: .cfi_offset t5, -120
+; RNMI-RV64-NEXT: .cfi_offset t6, -128
+; RNMI-RV64-NEXT: call callee
+; RNMI-RV64-NEXT: ld ra, 120(sp) # 8-byte Folded Reload
+; RNMI-RV64-NEXT: ld t0, 112(sp) # 8-byte Folded Reload
+; RNMI-RV64-NEXT: ld t1, 104(sp) # 8-byte Folded Reload
+; RNMI-RV64-NEXT: ld t2, 96(sp) # 8-byte Folded Reload
+; RNMI-RV64-NEXT: ld a0, 88(sp) # 8-byte Folded Reload
+; RNMI-RV64-NEXT: ld a1, 80(sp) # 8-byte Folded Reload
+; RNMI-RV64-NEXT: ld a2, 72(sp) # 8-byte Folded Reload
+; RNMI-RV64-NEXT: ld a3, 64(sp) # 8-byte Folded Reload
+; RNMI-RV64-NEXT: ld a4, 56(sp) # 8-byte Folded Reload
+; RNMI-RV64-NEXT: ld a5, 48(sp) # 8-byte Folded Reload
+; RNMI-RV64-NEXT: ld a6, 40(sp) # 8-byte Folded Reload
+; RNMI-RV64-NEXT: ld a7, 32(sp) # 8-byte Folded Reload
+; RNMI-RV64-NEXT: ld t3, 24(sp) # 8-byte Folded Reload
+; RNMI-RV64-NEXT: ld t4, 16(sp) # 8-byte Folded Reload
+; RNMI-RV64-NEXT: ld t5, 8(sp) # 8-byte Folded Reload
+; RNMI-RV64-NEXT: ld t6, 0(sp) # 8-byte Folded Reload
+; RNMI-RV64-NEXT: .cfi_restore ra
+; RNMI-RV64-NEXT: .cfi_restore t0
+; RNMI-RV64-NEXT: .cfi_restore t1
+; RNMI-RV64-NEXT: .cfi_restore t2
+; RNMI-RV64-NEXT: .cfi_restore a0
+; RNMI-RV64-NEXT: .cfi_restore a1
+; RNMI-RV64-NEXT: .cfi_restore a2
+; RNMI-RV64-NEXT: .cfi_restore a3
+; RNMI-RV64-NEXT: .cfi_restore a4
+; RNMI-RV64-NEXT: .cfi_restore a5
+; RNMI-RV64-NEXT: .cfi_restore a6
+; RNMI-RV64-NEXT: .cfi_restore a7
+; RNMI-RV64-NEXT: .cfi_restore t3
+; RNMI-RV64-NEXT: .cfi_restore t4
+; RNMI-RV64-NEXT: .cfi_restore t5
+; RNMI-RV64-NEXT: .cfi_restore t6
+; RNMI-RV64-NEXT: addi sp, sp, 128
+; RNMI-RV64-NEXT: .cfi_def_cfa_offset 0
+; RNMI-RV64-NEXT: mnret
+;
+; RNMI-RV64-FP-LABEL: test_rnmi_caller:
+; RNMI-RV64-FP: # %bb.0:
+; RNMI-RV64-FP-NEXT: addi sp, sp, -144
+; RNMI-RV64-FP-NEXT: .cfi_def_cfa_offset 144
+; RNMI-RV64-FP-NEXT: sd ra, 136(sp) # 8-byte Folded Spill
+; RNMI-RV64-FP-NEXT: sd t0, 128(sp) # 8-byte Folded Spill
+; RNMI-RV64-FP-NEXT: sd t1, 120(sp) # 8-byte Folded Spill
+; RNMI-RV64-FP-NEXT: sd t2, 112(sp) # 8-byte Folded Spill
+; RNMI-RV64-FP-NEXT: sd s0, 104(sp) # 8-byte Folded Spill
+; RNMI-RV64-FP-NEXT: sd a0, 96(sp) # 8-byte Folded Spill
+; RNMI-RV64-FP-NEXT: sd a1, 88(sp) # 8-byte Folded Spill
+; RNMI-RV64-FP-NEXT: sd a2, 80(sp) # 8-byte Folded Spill
+; RNMI-RV64-FP-NEXT: sd a3, 72(sp) # 8-byte Folded Spill
+; RNMI-RV64-FP-NEXT: sd a4, 64(sp) # 8-byte Folded Spill
+; RNMI-RV64-FP-NEXT: sd a5, 56(sp) # 8-byte Folded Spill
+; RNMI-RV64-FP-NEXT: sd a6, 48(sp) # 8-byte Folded Spill
+; RNMI-RV64-FP-NEXT: sd a7, 40(sp) # 8-byte Folded Spill
+; RNMI-RV64-FP-NEXT: sd t3, 32(sp) # 8-byte Folded Spill
+; RNMI-RV64-FP-NEXT: sd t4, 24(sp) # 8-byte Folded Spill
+; RNMI-RV64-FP-NEXT: sd t5, 16(sp) # 8-byte Folded Spill
+; RNMI-RV64-FP-NEXT: sd t6, 8(sp) # 8-byte Folded Spill
+; RNMI-RV64-FP-NEXT: .cfi_offset ra, -8
+; RNMI-RV64-FP-NEXT: .cfi_offset t0, -16
+; RNMI-RV64-FP-NEXT: .cfi_offset t1, -24
+; RNMI-RV64-FP-NEXT: .cfi_offset t2, -32
+; RNMI-RV64-FP-NEXT: .cfi_offset s0, -40
+; RNMI-RV64-FP-NEXT: .cfi_offset a0, -48
+; RNMI-RV64-FP-NEXT: .cfi_offset a1, -56
+; RNMI-RV64-FP-NEXT: .cfi_offset a2, -64
+; RNMI-RV64-FP-NEXT: .cfi_offset a3, -72
+; RNMI-RV64-FP-NEXT: .cfi_offset a4, -80
+; RNMI-RV64-FP-NEXT: .cfi_offset a5, -88
+; RNMI-RV64-FP-NEXT: .cfi_offset a6, -96
+; RNMI-RV64-FP-NEXT: .cfi_offset a7, -104
+; RNMI-RV64-FP-NEXT: .cfi_offset t3, -112
+; RNMI-RV64-FP-NEXT: .cfi_offset t4, -120
+; RNMI-RV64-FP-NEXT: .cfi_offset t5, -128
+; RNMI-RV64-FP-NEXT: .cfi_offset t6, -136
+; RNMI-RV64-FP-NEXT: addi s0, sp, 144
+; RNMI-RV64-FP-NEXT: .cfi_def_cfa s0, 0
+; RNMI-RV64-FP-NEXT: call callee
+; RNMI-RV64-FP-NEXT: .cfi_def_cfa sp, 144
+; RNMI-RV64-FP-NEXT: ld ra, 136(sp) # 8-byte Folded Reload
+; RNMI-RV64-FP-NEXT: ld t0, 128(sp) # 8-byte Folded Reload
+; RNMI-RV64-FP-NEXT: ld t1, 120(sp) # 8-byte Folded Reload
+; RNMI-RV64-FP-NEXT: ld t2, 112(sp) # 8-byte Folded Reload
+; RNMI-RV64-FP-NEXT: ld s0, 104(sp) # 8-byte Folded Reload
+; RNMI-RV64-FP-NEXT: ld a0, 96(sp) # 8-byte Folded Reload
+; RNMI-RV64-FP-NEXT: ld a1, 88(sp) # 8-byte Folded Reload
+; RNMI-RV64-FP-NEXT: ld a2, 80(sp) # 8-byte Folded Reload
+; RNMI-RV64-FP-NEXT: ld a3, 72(sp) # 8-byte Folded Reload
+; RNMI-RV64-FP-NEXT: ld a4, 64(sp) # 8-byte Folded Reload
+; RNMI-RV64-FP-NEXT: ld a5, 56(sp) # 8-byte Folded Reload
+; RNMI-RV64-FP-NEXT: ld a6, 48(sp) # 8-byte Folded Reload
+; RNMI-RV64-FP-NEXT: ld a7, 40(sp) # 8-byte Folded Reload
+; RNMI-RV64-FP-NEXT: ld t3, 32(sp) # 8-byte Folded Reload
+; RNMI-RV64-FP-NEXT: ld t4, 24(sp) # 8-byte Folded Reload
+; RNMI-RV64-FP-NEXT: ld t5, 16(sp) # 8-byte Folded Reload
+; RNMI-RV64-FP-NEXT: ld t6, 8(sp) # 8-byte Folded Reload
+; RNMI-RV64-FP-NEXT: .cfi_restore ra
+; RNMI-RV64-FP-NEXT: .cfi_restore t0
+; RNMI-RV64-FP-NEXT: .cfi_restore t1
+; RNMI-RV64-FP-NEXT: .cfi_restore t2
+; RNMI-RV64-FP-NEXT: .cfi_restore s0
+; RNMI-RV64-FP-NEXT: .cfi_restore a0
+; RNMI-RV64-FP-NEXT: .cfi_restore a1
+; RNMI-RV64-FP-NEXT: .cfi_restore a2
+; RNMI-RV64-FP-NEXT: .cfi_restore a3
+; RNMI-RV64-FP-NEXT: .cfi_restore a4
+; RNMI-RV64-FP-NEXT: .cfi_restore a5
+; RNMI-RV64-FP-NEXT: .cfi_restore a6
+; RNMI-RV64-FP-NEXT: .cfi_restore a7
+; RNMI-RV64-FP-NEXT: .cfi_restore t3
+; RNMI-RV64-FP-NEXT: .cfi_restore t4
+; RNMI-RV64-FP-NEXT: .cfi_restore t5
+; RNMI-RV64-FP-NEXT: .cfi_restore t6
+; RNMI-RV64-FP-NEXT: addi sp, sp, 144
+; RNMI-RV64-FP-NEXT: .cfi_def_cfa_offset 0
+; RNMI-RV64-FP-NEXT: mnret
+ call void @callee()
+ ret void
+}
More information about the llvm-commits
mailing list