Skip to content

Commit

Permalink
Fix get/set_fpcr_aarch64 (#44256)
Browse files Browse the repository at this point in the history
On Aarch64, the `fpcr` register is 64bit wide, although the top 32bit
are currently unused and reserved for future usage. Nevertheless, we
should safe and restore the full 64 bit, not just 32 bit. This also
silences a compiler warning about this. Reference:
<https://developer.arm.com/documentation/ddi0595/2021-06/AArch64-Registers/FPCR--Floating-point-Control-Register>
  • Loading branch information
fingolfin authored Feb 19, 2022
1 parent f852c88 commit 5bd0545
Showing 1 changed file with 9 additions and 9 deletions.
18 changes: 9 additions & 9 deletions src/processor_arm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1843,20 +1843,20 @@ extern "C" int jl_test_cpu_feature(jl_cpu_feature_t feature)

#ifdef _CPU_AARCH64_
// FPCR FZ, bit [24]
static constexpr uint32_t fpcr_fz_mask = 1 << 24;
static constexpr uint64_t fpcr_fz_mask = 1 << 24;
// FPCR FZ16, bit [19]
static constexpr uint32_t fpcr_fz16_mask = 1 << 19;
static constexpr uint64_t fpcr_fz16_mask = 1 << 19;
// FPCR DN, bit [25]
static constexpr uint32_t fpcr_dn_mask = 1 << 25;
static constexpr uint64_t fpcr_dn_mask = 1 << 25;

static inline uint32_t get_fpcr_aarch64(void)
static inline uint64_t get_fpcr_aarch64(void)
{
uint32_t fpcr;
uint64_t fpcr;
asm volatile("mrs %0, fpcr" : "=r"(fpcr));
return fpcr;
}

static inline void set_fpcr_aarch64(uint32_t fpcr)
static inline void set_fpcr_aarch64(uint64_t fpcr)
{
asm volatile("msr fpcr, %0" :: "r"(fpcr));
}
Expand All @@ -1868,8 +1868,8 @@ extern "C" JL_DLLEXPORT int32_t jl_get_zero_subnormals(void)

extern "C" JL_DLLEXPORT int32_t jl_set_zero_subnormals(int8_t isZero)
{
uint32_t fpcr = get_fpcr_aarch64();
static uint32_t mask = fpcr_fz_mask | (jl_test_cpu_feature(JL_AArch64_fullfp16) ? fpcr_fz16_mask : 0);
uint64_t fpcr = get_fpcr_aarch64();
static uint64_t mask = fpcr_fz_mask | (jl_test_cpu_feature(JL_AArch64_fullfp16) ? fpcr_fz16_mask : 0);
fpcr = isZero ? (fpcr | mask) : (fpcr & ~mask);
set_fpcr_aarch64(fpcr);
return 0;
Expand All @@ -1882,7 +1882,7 @@ extern "C" JL_DLLEXPORT int32_t jl_get_default_nans(void)

extern "C" JL_DLLEXPORT int32_t jl_set_default_nans(int8_t isDefault)
{
uint32_t fpcr = get_fpcr_aarch64();
uint64_t fpcr = get_fpcr_aarch64();
fpcr = isDefault ? (fpcr | fpcr_dn_mask) : (fpcr & ~fpcr_dn_mask);
set_fpcr_aarch64(fpcr);
return 0;
Expand Down

0 comments on commit 5bd0545

Please sign in to comment.