diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 542ddd5e6042c..db0900695a4d6 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -1073,6 +1073,9 @@ RISC-V Support - Add support for the `__builtin_riscv_pause()` intrinsic from the `Zihintpause` extension. +- 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 224cb6a32af28..2cd4661830664 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -2361,6 +2361,7 @@ def RISCVInterrupt : InheritableAttr, TargetSpecificAttr { [ "supervisor", "machine", + "rnmi", "qci-nest", "qci-nonest", "SiFive-CLIC-preemptible", @@ -2369,6 +2370,7 @@ def RISCVInterrupt : InheritableAttr, TargetSpecificAttr { [ "supervisor", "machine", + "rnmi", "qcinest", "qcinonest", "SiFiveCLICPreemptible", diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index fefdaba7f8bf5..7d86d4ec01681 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 cc110e1115ed5..0d77b24d21d05 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 158a20cce7f85..b7ac38b4a8091 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 456f3aedbf034..880def32d9bb7 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -22242,6 +22242,7 @@ SDValue RISCVTargetLowering::LowerFormalArguments( constexpr StringLiteral SupportedInterruptKinds[] = { "machine", "supervisor", + "rnmi", "qci-nest", "qci-nonest", "SiFive-CLIC-preemptible", @@ -22259,6 +22260,10 @@ SDValue RISCVTargetLowering::LowerFormalArguments( reportFatalUsageError( "'SiFive-CLIC-*' interrupt kinds require XSfmclic extension"); + if (Kind == "rnmi" && !Subtarget.hasStdExtSmrnmi()) + reportFatalUsageError("Handling of resumable non-maskable interrupts " + "handling requires Smrnmi extension"); + const TargetFrameLowering *TFI = Subtarget.getFrameLowering(); if (Kind.starts_with("SiFive-CLIC-preemptible") && TFI->hasFP(MF)) reportFatalUsageError("'SiFive-CLIC-preemptible' interrupt kinds cannot " @@ -22891,7 +22896,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 f63531a0109b0..8e69deb67bd2f 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]>; @@ -921,7 +923,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<[]> { @@ -930,6 +931,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; @@ -1787,6 +1790,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..e71978a2b016b --- /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: Handling of resumable non-maskable interrupts handling requires Smrnmi 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 +}