Skip to content

Commit 00c0638

Browse files
authored
[AArch64] Intrinsics aarch64_{get,set}_fpsr (#81867)
Two new intrinsics are introduced to read/write FPSR. They are similar to the existing intrinsics aarch64_{get,set}_fpcr.
1 parent 60a904b commit 00c0638

File tree

5 files changed

+69
-8
lines changed

5 files changed

+69
-8
lines changed

llvm/include/llvm/IR/IntrinsicsAArch64.td

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -703,17 +703,19 @@ def int_aarch64_neon_tbx3 : AdvSIMD_Tbx3_Intrinsic;
703703
def int_aarch64_neon_tbx4 : AdvSIMD_Tbx4_Intrinsic;
704704

705705
let TargetPrefix = "aarch64" in {
706-
class FPCR_Get_Intrinsic
706+
class FPENV_Get_Intrinsic
707707
: DefaultAttrsIntrinsic<[llvm_i64_ty], [], [IntrNoMem, IntrHasSideEffects]>;
708-
class FPCR_Set_Intrinsic
708+
class FPENV_Set_Intrinsic
709709
: DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrNoMem, IntrHasSideEffects]>;
710710
class RNDR_Intrinsic
711711
: DefaultAttrsIntrinsic<[llvm_i64_ty, llvm_i1_ty], [], [IntrNoMem, IntrHasSideEffects]>;
712712
}
713713

714-
// FPCR
715-
def int_aarch64_get_fpcr : FPCR_Get_Intrinsic;
716-
def int_aarch64_set_fpcr : FPCR_Set_Intrinsic;
714+
// FP environment registers.
715+
def int_aarch64_get_fpcr : FPENV_Get_Intrinsic;
716+
def int_aarch64_set_fpcr : FPENV_Set_Intrinsic;
717+
def int_aarch64_get_fpsr : FPENV_Get_Intrinsic;
718+
def int_aarch64_set_fpsr : FPENV_Set_Intrinsic;
717719

718720
// Armv8.5-A Random number generation intrinsics
719721
def int_aarch64_rndr : RNDR_Intrinsic;

llvm/lib/Target/AArch64/AArch64InstrInfo.td

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1805,7 +1805,7 @@ def HWASAN_CHECK_MEMACCESS_SHORTGRANULES : Pseudo<
18051805
// The virtual cycle counter register is CNTVCT_EL0.
18061806
def : Pat<(readcyclecounter), (MRS 0xdf02)>;
18071807

1808-
// FPCR register
1808+
// FPCR and FPSR registers.
18091809
let Uses = [FPCR] in
18101810
def MRS_FPCR : Pseudo<(outs GPR64:$dst), (ins),
18111811
[(set GPR64:$dst, (int_aarch64_get_fpcr))]>,
@@ -1817,6 +1817,17 @@ def MSR_FPCR : Pseudo<(outs), (ins GPR64:$val),
18171817
PseudoInstExpansion<(MSR 0xda20, GPR64:$val)>,
18181818
Sched<[WriteSys]>;
18191819

1820+
let Uses = [FPSR] in
1821+
def MRS_FPSR : Pseudo<(outs GPR64:$dst), (ins),
1822+
[(set GPR64:$dst, (int_aarch64_get_fpsr))]>,
1823+
PseudoInstExpansion<(MRS GPR64:$dst, 0xda21)>,
1824+
Sched<[WriteSys]>;
1825+
let Defs = [FPSR] in
1826+
def MSR_FPSR : Pseudo<(outs), (ins GPR64:$val),
1827+
[(int_aarch64_set_fpsr i64:$val)]>,
1828+
PseudoInstExpansion<(MSR 0xda21, GPR64:$val)>,
1829+
Sched<[WriteSys]>;
1830+
18201831
// Generic system instructions
18211832
def SYSxt : SystemXtI<0, "sys">;
18221833
def SYSLxt : SystemLXtI<1, "sysl">;

llvm/lib/Target/AArch64/AArch64RegisterInfo.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,9 @@ def VG : AArch64Reg<0, "vg">, DwarfRegNum<[46]>;
147147
// Floating-point control register
148148
def FPCR : AArch64Reg<0, "fpcr">;
149149

150+
// Floating-point status register.
151+
def FPSR : AArch64Reg<0, "fpsr">;
152+
150153
// GPR register classes with the intersections of GPR32/GPR32sp and
151154
// GPR64/GPR64sp for use by the coalescer.
152155
def GPR32common : RegisterClass<"AArch64", [i32], 32, (sequence "W%u", 0, 30)> {
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
2+
; RUN: llc -mtriple=aarch64 < %s | FileCheck %s
3+
4+
define i64 @get_fpcr() #0 {
5+
; CHECK-LABEL: get_fpcr:
6+
; CHECK: // %bb.0:
7+
; CHECK-NEXT: mrs x0, FPCR
8+
; CHECK-NEXT: ret
9+
%1 = tail call i64 @llvm.aarch64.get.fpcr()
10+
ret i64 %1
11+
}
12+
13+
define void @set_fpcr(i64 %cr) {
14+
; CHECK-LABEL: set_fpcr:
15+
; CHECK: // %bb.0:
16+
; CHECK-NEXT: msr FPCR, x0
17+
; CHECK-NEXT: ret
18+
call void @llvm.aarch64.set.fpcr(i64 %cr)
19+
ret void
20+
}
21+
22+
define i64 @get_fpsr() {
23+
; CHECK-LABEL: get_fpsr:
24+
; CHECK: // %bb.0:
25+
; CHECK-NEXT: mrs x0, FPSR
26+
; CHECK-NEXT: ret
27+
%1 = tail call i64 @llvm.aarch64.get.fpsr()
28+
ret i64 %1
29+
}
30+
31+
define void @set_fpsr(i64 %sr) {
32+
; CHECK-LABEL: set_fpsr:
33+
; CHECK: // %bb.0:
34+
; CHECK-NEXT: msr FPSR, x0
35+
; CHECK-NEXT: ret
36+
call void @llvm.aarch64.set.fpsr(i64 %sr)
37+
ret void
38+
}
39+
40+
declare i64 @llvm.aarch64.get.fpcr()
41+
declare void @llvm.aarch64.set.fpcr(i64)
42+
declare i64 @llvm.aarch64.get.fpsr()
43+
declare void @llvm.aarch64.set.fpsr(i64)
44+
45+
attributes #0 = { nounwind }

0 commit comments

Comments
 (0)