
Summary: Clang will replace references to registers using ABI names in inline assembly constraints with references to architecture names, but other frontends do not. LLVM uses the regular assembly parser to parse inline asm, so inline assembly strings can contain references to registers using their ABI names. This patch adds support for parsing constraints using either the ABI name or the architectural register name. This means we do not need to implement the ABI name replacement code in every single frontend, especially those like Rust which are a very thin shim on top of LLVM IR's inline asm, and that constraints can more closely match the assembly strings they refer to. Reviewers: asb, simoncook Reviewed By: simoncook Subscribers: hiraditya, rbar, johnrusso, JDevlieghere, apazos, sabuasal, niosHD, kito-cheng, shiva0217, jrtc27, MaskRay, zzheng, edward-jones, rogfer01, MartinMosbeck, brucehoult, the_o, rkruppe, PkmX, jocewei, psnobl, benna, Jim, s.egerton, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D65947 llvm-svn: 368303
1591 lines
43 KiB
LLVM
1591 lines
43 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
|
; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
|
|
; RUN: | FileCheck -check-prefix=RV32I %s
|
|
; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
|
|
; RUN: | FileCheck -check-prefix=RV64I %s
|
|
|
|
; These test that we can use both the architectural names (x*) and the ABI names
|
|
; (a*, s*, t* etc) to refer to registers in inline asm constraint lists. In each
|
|
; case, the named register should be used for the source register of the `addi`.
|
|
; It is very likely that `a0` will be chosen as the designation register, but
|
|
; this is left to the compiler to choose.
|
|
;
|
|
; The inline assembly will, by default, contain the ABI names for the registers.
|
|
;
|
|
; Parenthesised registers in comments are the other aliases for this register.
|
|
|
|
; NOTE: This test has to pass in 0 to the inline asm, because that's the only
|
|
; value `x0` (`zero`) can take.
|
|
define i32 @explicit_register_x0() nounwind {
|
|
; RV32I-LABEL: explicit_register_x0:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, zero, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_x0:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, zero, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{x0}"(i32 0)
|
|
ret i32 %1
|
|
}
|
|
|
|
; NOTE: This test has to pass in 0 to the inline asm, because that's the only
|
|
; value that `zero` (`x0`) can take.
|
|
define i32 @explicit_register_zero() nounwind {
|
|
; RV32I-LABEL: explicit_register_zero:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, zero, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_zero:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, zero, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{zero}"(i32 0)
|
|
ret i32 %1
|
|
}
|
|
|
|
; NOTE: This test uses `x1` (`ra`) as an input, so it should be saved.
|
|
define i32 @explicit_register_x1(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_x1:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw ra, 12(sp)
|
|
; RV32I-NEXT: mv ra, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, ra, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: lw ra, 12(sp)
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_x1:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -16
|
|
; RV64I-NEXT: sd ra, 8(sp)
|
|
; RV64I-NEXT: mv ra, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, ra, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ld ra, 8(sp)
|
|
; RV64I-NEXT: addi sp, sp, 16
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{x1}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
; NOTE: This test uses `ra` (`x1`) as an input, so it should be saved.
|
|
define i32 @explicit_register_ra(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_ra:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw ra, 12(sp)
|
|
; RV32I-NEXT: mv ra, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, ra, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: lw ra, 12(sp)
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_ra:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -16
|
|
; RV64I-NEXT: sd ra, 8(sp)
|
|
; RV64I-NEXT: mv ra, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, ra, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ld ra, 8(sp)
|
|
; RV64I-NEXT: addi sp, sp, 16
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{ra}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
define i32 @explicit_register_x2(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_x2:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: mv sp, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, sp, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_x2:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: mv sp, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, sp, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{x2}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
define i32 @explicit_register_sp(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_sp:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: mv sp, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, sp, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_sp:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: mv sp, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, sp, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{sp}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
; NOTE: This test uses `x3` (`gp`) as an input, so it should be saved.
|
|
define i32 @explicit_register_x3(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_x3:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw gp, 12(sp)
|
|
; RV32I-NEXT: mv gp, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, gp, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: lw gp, 12(sp)
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_x3:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -16
|
|
; RV64I-NEXT: sd gp, 8(sp)
|
|
; RV64I-NEXT: mv gp, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, gp, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ld gp, 8(sp)
|
|
; RV64I-NEXT: addi sp, sp, 16
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{x3}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
; NOTE: This test uses `gp` (`x3`) as an input, so it should be saved.
|
|
define i32 @explicit_register_gp(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_gp:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw gp, 12(sp)
|
|
; RV32I-NEXT: mv gp, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, gp, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: lw gp, 12(sp)
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_gp:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -16
|
|
; RV64I-NEXT: sd gp, 8(sp)
|
|
; RV64I-NEXT: mv gp, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, gp, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ld gp, 8(sp)
|
|
; RV64I-NEXT: addi sp, sp, 16
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{gp}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
; NOTE: This test uses `x4` (`tp`) as an input, so it should be saved.
|
|
define i32 @explicit_register_x4(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_x4:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw tp, 12(sp)
|
|
; RV32I-NEXT: mv tp, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, tp, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: lw tp, 12(sp)
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_x4:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -16
|
|
; RV64I-NEXT: sd tp, 8(sp)
|
|
; RV64I-NEXT: mv tp, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, tp, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ld tp, 8(sp)
|
|
; RV64I-NEXT: addi sp, sp, 16
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{x4}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
; NOTE: This test uses `tp` (`x4`) as an input, so it should be saved.
|
|
define i32 @explicit_register_tp(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_tp:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw tp, 12(sp)
|
|
; RV32I-NEXT: mv tp, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, tp, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: lw tp, 12(sp)
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_tp:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -16
|
|
; RV64I-NEXT: sd tp, 8(sp)
|
|
; RV64I-NEXT: mv tp, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, tp, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ld tp, 8(sp)
|
|
; RV64I-NEXT: addi sp, sp, 16
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{tp}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
define i32 @explicit_register_x5(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_x5:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: mv t0, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, t0, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_x5:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: mv t0, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, t0, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{x5}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
define i32 @explicit_register_t0(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_t0:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: mv t0, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, t0, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_t0:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: mv t0, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, t0, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{t0}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
define i32 @explicit_register_x6(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_x6:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: mv t1, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, t1, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_x6:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: mv t1, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, t1, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{x6}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
define i32 @explicit_register_t1(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_t1:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: mv t1, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, t1, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_t1:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: mv t1, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, t1, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{t1}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
define i32 @explicit_register_x7(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_x7:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: mv t2, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, t2, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_x7:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: mv t2, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, t2, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{x7}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
define i32 @explicit_register_t2(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_t2:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: mv t2, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, t2, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_t2:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: mv t2, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, t2, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{t2}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
; NOTE: This test uses `x8` (`s0`, `fp`) as an input, so it should be saved.
|
|
define i32 @explicit_register_x8(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_x8:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw s0, 12(sp)
|
|
; RV32I-NEXT: mv s0, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, s0, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: lw s0, 12(sp)
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_x8:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -16
|
|
; RV64I-NEXT: sd s0, 8(sp)
|
|
; RV64I-NEXT: mv s0, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, s0, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ld s0, 8(sp)
|
|
; RV64I-NEXT: addi sp, sp, 16
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{x8}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
; NOTE: This test uses `s0` (`x8`, `fp`) as an input, so it should be saved.
|
|
define i32 @explicit_register_s0(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_s0:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw s0, 12(sp)
|
|
; RV32I-NEXT: mv s0, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, s0, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: lw s0, 12(sp)
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_s0:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -16
|
|
; RV64I-NEXT: sd s0, 8(sp)
|
|
; RV64I-NEXT: mv s0, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, s0, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ld s0, 8(sp)
|
|
; RV64I-NEXT: addi sp, sp, 16
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{s0}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
; NOTE: This test uses `fp` (`x8`, `s0`) as an input, so it should be saved.
|
|
define i32 @explicit_register_fp(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_fp:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw s0, 12(sp)
|
|
; RV32I-NEXT: mv s0, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, s0, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: lw s0, 12(sp)
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_fp:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -16
|
|
; RV64I-NEXT: sd s0, 8(sp)
|
|
; RV64I-NEXT: mv s0, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, s0, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ld s0, 8(sp)
|
|
; RV64I-NEXT: addi sp, sp, 16
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{fp}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
; NOTE: This test uses `x9` (`s1`) as an input, so it should be saved.
|
|
define i32 @explicit_register_x9(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_x9:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw s1, 12(sp)
|
|
; RV32I-NEXT: mv s1, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, s1, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: lw s1, 12(sp)
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_x9:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -16
|
|
; RV64I-NEXT: sd s1, 8(sp)
|
|
; RV64I-NEXT: mv s1, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, s1, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ld s1, 8(sp)
|
|
; RV64I-NEXT: addi sp, sp, 16
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{x9}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
; NOTE: This test uses `s1` (`x9`) as an input, so it should be saved.
|
|
define i32 @explicit_register_s1(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_s1:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw s1, 12(sp)
|
|
; RV32I-NEXT: mv s1, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, s1, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: lw s1, 12(sp)
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_s1:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -16
|
|
; RV64I-NEXT: sd s1, 8(sp)
|
|
; RV64I-NEXT: mv s1, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, s1, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ld s1, 8(sp)
|
|
; RV64I-NEXT: addi sp, sp, 16
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{s1}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
define i32 @explicit_register_x10(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_x10:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, a0, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_x10:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, a0, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{x10}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
define i32 @explicit_register_a0(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_a0:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, a0, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_a0:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, a0, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{a0}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
define i32 @explicit_register_x11(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_x11:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: mv a1, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, a1, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_x11:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: mv a1, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, a1, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{x11}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
define i32 @explicit_register_a1(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_a1:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: mv a1, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, a1, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_a1:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: mv a1, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, a1, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{a1}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
define i32 @explicit_register_x12(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_x12:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: mv a2, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, a2, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_x12:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: mv a2, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, a2, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{x12}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
define i32 @explicit_register_a2(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_a2:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: mv a2, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, a2, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_a2:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: mv a2, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, a2, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{a2}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
define i32 @explicit_register_x13(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_x13:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: mv a3, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, a3, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_x13:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: mv a3, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, a3, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{x13}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
define i32 @explicit_register_a3(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_a3:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: mv a3, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, a3, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_a3:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: mv a3, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, a3, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{a3}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
define i32 @explicit_register_x14(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_x14:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: mv a4, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, a4, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_x14:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: mv a4, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, a4, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{x14}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
define i32 @explicit_register_a4(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_a4:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: mv a4, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, a4, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_a4:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: mv a4, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, a4, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{a4}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
define i32 @explicit_register_x15(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_x15:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: mv a5, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, a5, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_x15:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: mv a5, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, a5, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{x15}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
define i32 @explicit_register_a5(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_a5:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: mv a5, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, a5, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_a5:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: mv a5, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, a5, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{a5}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
define i32 @explicit_register_x16(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_x16:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: mv a6, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, a6, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_x16:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: mv a6, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, a6, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{x16}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
define i32 @explicit_register_a6(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_a6:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: mv a6, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, a6, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_a6:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: mv a6, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, a6, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{a6}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
define i32 @explicit_register_x17(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_x17:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: mv a7, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, a7, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_x17:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: mv a7, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, a7, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{x17}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
define i32 @explicit_register_a7(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_a7:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: mv a7, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, a7, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_a7:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: mv a7, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, a7, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{a7}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
; NOTE: This test uses `x18` (`s2`) as an input, so it should be saved.
|
|
define i32 @explicit_register_x18(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_x18:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw s2, 12(sp)
|
|
; RV32I-NEXT: mv s2, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, s2, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: lw s2, 12(sp)
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_x18:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -16
|
|
; RV64I-NEXT: sd s2, 8(sp)
|
|
; RV64I-NEXT: mv s2, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, s2, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ld s2, 8(sp)
|
|
; RV64I-NEXT: addi sp, sp, 16
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{x18}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
; NOTE: This test uses `s2` (`x18`) as an input, so it should be saved.
|
|
define i32 @explicit_register_s2(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_s2:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw s2, 12(sp)
|
|
; RV32I-NEXT: mv s2, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, s2, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: lw s2, 12(sp)
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_s2:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -16
|
|
; RV64I-NEXT: sd s2, 8(sp)
|
|
; RV64I-NEXT: mv s2, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, s2, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ld s2, 8(sp)
|
|
; RV64I-NEXT: addi sp, sp, 16
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{s2}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
; NOTE: This test uses `x19` (`s3`) as an input, so it should be saved.
|
|
define i32 @explicit_register_x19(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_x19:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw s3, 12(sp)
|
|
; RV32I-NEXT: mv s3, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, s3, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: lw s3, 12(sp)
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_x19:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -16
|
|
; RV64I-NEXT: sd s3, 8(sp)
|
|
; RV64I-NEXT: mv s3, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, s3, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ld s3, 8(sp)
|
|
; RV64I-NEXT: addi sp, sp, 16
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{x19}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
; NOTE: This test uses `s3` (`x19`) as an input, so it should be saved.
|
|
define i32 @explicit_register_s3(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_s3:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw s3, 12(sp)
|
|
; RV32I-NEXT: mv s3, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, s3, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: lw s3, 12(sp)
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_s3:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -16
|
|
; RV64I-NEXT: sd s3, 8(sp)
|
|
; RV64I-NEXT: mv s3, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, s3, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ld s3, 8(sp)
|
|
; RV64I-NEXT: addi sp, sp, 16
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{s3}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
; NOTE: This test uses `x20` (`s4`) as an input, so it should be saved.
|
|
define i32 @explicit_register_x20(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_x20:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw s4, 12(sp)
|
|
; RV32I-NEXT: mv s4, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, s4, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: lw s4, 12(sp)
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_x20:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -16
|
|
; RV64I-NEXT: sd s4, 8(sp)
|
|
; RV64I-NEXT: mv s4, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, s4, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ld s4, 8(sp)
|
|
; RV64I-NEXT: addi sp, sp, 16
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{x20}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
; NOTE: This test uses `s4` (`x20`) as an input, so it should be saved.
|
|
define i32 @explicit_register_s4(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_s4:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw s4, 12(sp)
|
|
; RV32I-NEXT: mv s4, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, s4, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: lw s4, 12(sp)
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_s4:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -16
|
|
; RV64I-NEXT: sd s4, 8(sp)
|
|
; RV64I-NEXT: mv s4, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, s4, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ld s4, 8(sp)
|
|
; RV64I-NEXT: addi sp, sp, 16
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{s4}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
; NOTE: This test uses `x21` (`s5`) as an input, so it should be saved.
|
|
define i32 @explicit_register_x21(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_x21:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw s5, 12(sp)
|
|
; RV32I-NEXT: mv s5, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, s5, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: lw s5, 12(sp)
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_x21:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -16
|
|
; RV64I-NEXT: sd s5, 8(sp)
|
|
; RV64I-NEXT: mv s5, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, s5, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ld s5, 8(sp)
|
|
; RV64I-NEXT: addi sp, sp, 16
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{x21}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
; NOTE: This test uses `s5` (`x21`) as an input, so it should be saved.
|
|
define i32 @explicit_register_s5(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_s5:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw s5, 12(sp)
|
|
; RV32I-NEXT: mv s5, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, s5, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: lw s5, 12(sp)
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_s5:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -16
|
|
; RV64I-NEXT: sd s5, 8(sp)
|
|
; RV64I-NEXT: mv s5, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, s5, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ld s5, 8(sp)
|
|
; RV64I-NEXT: addi sp, sp, 16
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{s5}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
; NOTE: This test uses `x22` (`s6`) as an input, so it should be saved.
|
|
define i32 @explicit_register_x22(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_x22:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw s6, 12(sp)
|
|
; RV32I-NEXT: mv s6, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, s6, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: lw s6, 12(sp)
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_x22:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -16
|
|
; RV64I-NEXT: sd s6, 8(sp)
|
|
; RV64I-NEXT: mv s6, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, s6, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ld s6, 8(sp)
|
|
; RV64I-NEXT: addi sp, sp, 16
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{x22}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
; NOTE: This test uses `s6` (`x22`) as an input, so it should be saved.
|
|
define i32 @explicit_register_s6(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_s6:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw s6, 12(sp)
|
|
; RV32I-NEXT: mv s6, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, s6, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: lw s6, 12(sp)
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_s6:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -16
|
|
; RV64I-NEXT: sd s6, 8(sp)
|
|
; RV64I-NEXT: mv s6, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, s6, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ld s6, 8(sp)
|
|
; RV64I-NEXT: addi sp, sp, 16
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{s6}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
; NOTE: This test uses `x23` (`s7`) as an input, so it should be saved.
|
|
define i32 @explicit_register_x23(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_x23:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw s7, 12(sp)
|
|
; RV32I-NEXT: mv s7, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, s7, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: lw s7, 12(sp)
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_x23:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -16
|
|
; RV64I-NEXT: sd s7, 8(sp)
|
|
; RV64I-NEXT: mv s7, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, s7, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ld s7, 8(sp)
|
|
; RV64I-NEXT: addi sp, sp, 16
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{x23}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
; NOTE: This test uses `s7` (`x23`) as an input, so it should be saved.
|
|
define i32 @explicit_register_s7(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_s7:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw s7, 12(sp)
|
|
; RV32I-NEXT: mv s7, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, s7, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: lw s7, 12(sp)
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_s7:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -16
|
|
; RV64I-NEXT: sd s7, 8(sp)
|
|
; RV64I-NEXT: mv s7, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, s7, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ld s7, 8(sp)
|
|
; RV64I-NEXT: addi sp, sp, 16
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{s7}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
; NOTE: This test uses `x24` (`s8`) as an input, so it should be saved.
|
|
define i32 @explicit_register_x24(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_x24:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw s8, 12(sp)
|
|
; RV32I-NEXT: mv s8, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, s8, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: lw s8, 12(sp)
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_x24:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -16
|
|
; RV64I-NEXT: sd s8, 8(sp)
|
|
; RV64I-NEXT: mv s8, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, s8, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ld s8, 8(sp)
|
|
; RV64I-NEXT: addi sp, sp, 16
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{x24}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
; NOTE: This test uses `s8` (`x24`) as an input, so it should be saved.
|
|
define i32 @explicit_register_s8(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_s8:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw s8, 12(sp)
|
|
; RV32I-NEXT: mv s8, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, s8, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: lw s8, 12(sp)
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_s8:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -16
|
|
; RV64I-NEXT: sd s8, 8(sp)
|
|
; RV64I-NEXT: mv s8, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, s8, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ld s8, 8(sp)
|
|
; RV64I-NEXT: addi sp, sp, 16
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{s8}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
; NOTE: This test uses `x25` (`s9`) as an input, so it should be saved.
|
|
define i32 @explicit_register_x25(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_x25:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw s9, 12(sp)
|
|
; RV32I-NEXT: mv s9, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, s9, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: lw s9, 12(sp)
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_x25:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -16
|
|
; RV64I-NEXT: sd s9, 8(sp)
|
|
; RV64I-NEXT: mv s9, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, s9, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ld s9, 8(sp)
|
|
; RV64I-NEXT: addi sp, sp, 16
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{x25}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
; NOTE: This test uses `s9` (`x25`) as an input, so it should be saved.
|
|
define i32 @explicit_register_s9(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_s9:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw s9, 12(sp)
|
|
; RV32I-NEXT: mv s9, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, s9, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: lw s9, 12(sp)
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_s9:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -16
|
|
; RV64I-NEXT: sd s9, 8(sp)
|
|
; RV64I-NEXT: mv s9, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, s9, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ld s9, 8(sp)
|
|
; RV64I-NEXT: addi sp, sp, 16
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{s9}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
; NOTE: This test uses `x26` (`s10`) as an input, so it should be saved.
|
|
define i32 @explicit_register_x26(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_x26:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw s10, 12(sp)
|
|
; RV32I-NEXT: mv s10, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, s10, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: lw s10, 12(sp)
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_x26:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -16
|
|
; RV64I-NEXT: sd s10, 8(sp)
|
|
; RV64I-NEXT: mv s10, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, s10, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ld s10, 8(sp)
|
|
; RV64I-NEXT: addi sp, sp, 16
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{x26}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
; NOTE: This test uses `s10` (`x28`) as an input, so it should be saved.
|
|
define i32 @explicit_register_s10(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_s10:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw s10, 12(sp)
|
|
; RV32I-NEXT: mv s10, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, s10, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: lw s10, 12(sp)
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_s10:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -16
|
|
; RV64I-NEXT: sd s10, 8(sp)
|
|
; RV64I-NEXT: mv s10, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, s10, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ld s10, 8(sp)
|
|
; RV64I-NEXT: addi sp, sp, 16
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{s10}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
; NOTE: This test uses `x27` (`s11`) as an input, so it should be saved.
|
|
define i32 @explicit_register_x27(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_x27:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw s11, 12(sp)
|
|
; RV32I-NEXT: mv s11, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, s11, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: lw s11, 12(sp)
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_x27:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -16
|
|
; RV64I-NEXT: sd s11, 8(sp)
|
|
; RV64I-NEXT: mv s11, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, s11, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ld s11, 8(sp)
|
|
; RV64I-NEXT: addi sp, sp, 16
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{x27}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
; NOTE: This test uses `s11` (`x27`) as an input, so it should be saved.
|
|
define i32 @explicit_register_s11(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_s11:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: addi sp, sp, -16
|
|
; RV32I-NEXT: sw s11, 12(sp)
|
|
; RV32I-NEXT: mv s11, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, s11, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: lw s11, 12(sp)
|
|
; RV32I-NEXT: addi sp, sp, 16
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_s11:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: addi sp, sp, -16
|
|
; RV64I-NEXT: sd s11, 8(sp)
|
|
; RV64I-NEXT: mv s11, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, s11, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ld s11, 8(sp)
|
|
; RV64I-NEXT: addi sp, sp, 16
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{s11}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
define i32 @explicit_register_x28(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_x28:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: mv t3, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, t3, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_x28:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: mv t3, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, t3, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{x28}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
define i32 @explicit_register_t3(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_t3:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: mv t3, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, t3, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_t3:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: mv t3, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, t3, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{t3}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
define i32 @explicit_register_x29(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_x29:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: mv t4, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, t4, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_x29:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: mv t4, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, t4, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{x29}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
define i32 @explicit_register_t4(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_t4:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: mv t4, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, t4, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_t4:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: mv t4, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, t4, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{t4}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
define i32 @explicit_register_x30(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_x30:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: mv t5, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, t5, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_x30:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: mv t5, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, t5, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{x30}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
define i32 @explicit_register_t5(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_t5:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: mv t5, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, t5, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_t5:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: mv t5, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, t5, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{t5}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
define i32 @explicit_register_x31(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_x31:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: mv t6, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, t6, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_x31:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: mv t6, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, t6, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{x31}"(i32 %a)
|
|
ret i32 %1
|
|
}
|
|
|
|
define i32 @explicit_register_t6(i32 %a) nounwind {
|
|
; RV32I-LABEL: explicit_register_t6:
|
|
; RV32I: # %bb.0:
|
|
; RV32I-NEXT: mv t6, a0
|
|
; RV32I-NEXT: #APP
|
|
; RV32I-NEXT: addi a0, t6, 0
|
|
; RV32I-NEXT: #NO_APP
|
|
; RV32I-NEXT: ret
|
|
;
|
|
; RV64I-LABEL: explicit_register_t6:
|
|
; RV64I: # %bb.0:
|
|
; RV64I-NEXT: mv t6, a0
|
|
; RV64I-NEXT: #APP
|
|
; RV64I-NEXT: addi a0, t6, 0
|
|
; RV64I-NEXT: #NO_APP
|
|
; RV64I-NEXT: ret
|
|
%1 = tail call i32 asm "addi $0, $1, 0", "=r,{t6}"(i32 %a)
|
|
ret i32 %1
|
|
}
|