Skip to content

Commit 78cd158

Browse files
committed
[libc][AArch64] Fix fullbuild when using G++/GCC
The libc uses some functions that GCC does not currently implement, that come from Arm's ACLE header usually. These are: ``` __arm_wsr64 __arm_rsr64 __arm_wsr __arm_rsr ``` This issue was reported to us (#60473) and I've then reported that back to GCC (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108642). Even if these functions are added, clang has some non standard extensions to them that gcc may not take. So we're looking at a fix in gcc 13 at best, and that may not be enough for what we're doing with them. So I've added ifdefs to use alternatives with gcc. For handling the stack pointer, inline assembly is unfortunately the only option. I have verified that the single mov is essentially what __arm_rsr64 generates. For fpsr and fpcr the gcc devs suggested using https://gcc.gnu.org/onlinedocs/gcc-12.2.0/gcc/AArch64-Built-in-Functions.html#AArch64-Built-in-Functions. Reviewed By: sivachandra Differential Revision: https://reviews.llvm.org/D143261
1 parent 0e3089b commit 78cd158

File tree

2 files changed

+35
-4
lines changed

2 files changed

+35
-4
lines changed

libc/src/__support/FPUtil/aarch64/FEnvImpl.h

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,39 @@ struct FEnv {
6767
(status & INEXACT ? FE_INEXACT : 0);
6868
}
6969

70-
static uint32_t getControlWord() { return __arm_rsr("fpcr"); }
70+
static uint32_t getControlWord() {
71+
#ifdef __clang__
72+
// GCC does not currently support __arm_rsr.
73+
return __arm_rsr("fpcr");
74+
#else
75+
return __builtin_aarch64_get_fpcr();
76+
#endif
77+
}
7178

72-
static void writeControlWord(uint32_t fpcr) { __arm_wsr("fpcr", fpcr); }
79+
static void writeControlWord(uint32_t fpcr) {
80+
#ifdef __clang__
81+
// GCC does not currently support __arm_wsr.
82+
__arm_wsr("fpcr", fpcr);
83+
#else
84+
__builtin_aarch64_set_fpcr(fpcr);
85+
#endif
86+
}
7387

74-
static uint32_t getStatusWord() { return __arm_rsr("fpsr"); }
88+
static uint32_t getStatusWord() {
89+
#ifdef __clang__
90+
return __arm_rsr("fpsr");
91+
#else
92+
return __builtin_aarch64_get_fpsr();
93+
#endif
94+
}
7595

76-
static void writeStatusWord(uint32_t fpsr) { __arm_wsr("fpsr", fpsr); }
96+
static void writeStatusWord(uint32_t fpsr) {
97+
#ifdef __clang__
98+
__arm_wsr("fpsr", fpsr);
99+
#else
100+
__builtin_aarch64_set_fpsr(fpsr);
101+
#endif
102+
}
77103
};
78104

79105
LIBC_INLINE int enable_except(int excepts) {

libc/src/__support/threads/linux/thread.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,12 @@ int Thread::run(ThreadStyle style, ThreadRunner runner, void *arg, void *stack,
214214
#ifdef LIBC_TARGET_ARCH_IS_AARCH64
215215
// We set the frame pointer to be the same as the "sp" so that start args
216216
// can be sniffed out from start_thread.
217+
#ifdef __clang__
218+
// GCC does not currently implement __arm_wsr64/__arm_rsr64.
217219
__arm_wsr64("x29", __arm_rsr64("sp"));
220+
#else
221+
asm volatile("mov x29, sp");
222+
#endif
218223
#endif
219224
start_thread();
220225
} else if (clone_result < 0) {

0 commit comments

Comments
 (0)