Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 25 additions & 27 deletions libc/src/__support/FPUtil/aarch64/FEnvImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@

namespace LIBC_NAMESPACE_DECL {
namespace fputil {

struct FEnv {
struct FPState {
uint32_t ControlWord;
Expand All @@ -42,31 +41,31 @@ struct FEnv {
static constexpr uint32_t DOWNWARD = 0x2;
static constexpr uint32_t TOWARDZERO = 0x3;

static constexpr uint32_t INVALID = 0x1;
static constexpr uint32_t DIVBYZERO = 0x2;
static constexpr uint32_t OVERFLOW = 0x4;
static constexpr uint32_t UNDERFLOW = 0x8;
static constexpr uint32_t INEXACT = 0x10;
static constexpr uint32_t INVALID_F = 0x1;
static constexpr uint32_t DIVBYZERO_F = 0x2;
static constexpr uint32_t OVERFLOW_F = 0x4;
static constexpr uint32_t UNDERFLOW_F = 0x8;
static constexpr uint32_t INEXACT_F = 0x10;

// Zero-th bit is the first bit.
static constexpr uint32_t RoundingControlBitPosition = 22;
static constexpr uint32_t ExceptionStatusFlagsBitPosition = 0;
static constexpr uint32_t ExceptionControlFlagsBitPosition = 8;

LIBC_INLINE static uint32_t getStatusValueForExcept(int excepts) {
return ((excepts & FE_INVALID) ? INVALID : 0) |
((excepts & FE_DIVBYZERO) ? DIVBYZERO : 0) |
((excepts & FE_OVERFLOW) ? OVERFLOW : 0) |
((excepts & FE_UNDERFLOW) ? UNDERFLOW : 0) |
((excepts & FE_INEXACT) ? INEXACT : 0);
return ((excepts & FE_INVALID) ? INVALID_F : 0) |
((excepts & FE_DIVBYZERO) ? DIVBYZERO_F : 0) |
((excepts & FE_OVERFLOW) ? OVERFLOW_F : 0) |
((excepts & FE_UNDERFLOW) ? UNDERFLOW_F : 0) |
((excepts & FE_INEXACT) ? INEXACT_F : 0);
}

LIBC_INLINE static int exceptionStatusToMacro(uint32_t status) {
return ((status & INVALID) ? FE_INVALID : 0) |
((status & DIVBYZERO) ? FE_DIVBYZERO : 0) |
((status & OVERFLOW) ? FE_OVERFLOW : 0) |
((status & UNDERFLOW) ? FE_UNDERFLOW : 0) |
((status & INEXACT) ? FE_INEXACT : 0);
return ((status & INVALID_F) ? FE_INVALID : 0) |
((status & DIVBYZERO_F) ? FE_DIVBYZERO : 0) |
((status & OVERFLOW_F) ? FE_OVERFLOW : 0) |
((status & UNDERFLOW_F) ? FE_UNDERFLOW : 0) |
((status & INEXACT_F) ? FE_INEXACT : 0);
}

static uint32_t getControlWord() {
Expand Down Expand Up @@ -171,44 +170,44 @@ LIBC_INLINE int raise_except(int excepts) {
uint32_t toRaise = FEnv::getStatusValueForExcept(excepts);
int result = 0;

if (toRaise & FEnv::INVALID) {
if (toRaise & FEnv::INVALID_F) {
divfunc(zero, zero);
uint32_t statusWord = FEnv::getStatusWord();
if (!((statusWord >> FEnv::ExceptionStatusFlagsBitPosition) &
FEnv::INVALID))
FEnv::INVALID_F))
result = -1;
}

if (toRaise & FEnv::DIVBYZERO) {
if (toRaise & FEnv::DIVBYZERO_F) {
divfunc(one, zero);
uint32_t statusWord = FEnv::getStatusWord();
if (!((statusWord >> FEnv::ExceptionStatusFlagsBitPosition) &
FEnv::DIVBYZERO))
FEnv::DIVBYZERO_F))
result = -1;
}
if (toRaise & FEnv::OVERFLOW) {
if (toRaise & FEnv::OVERFLOW_F) {
divfunc(largeValue, smallValue);
uint32_t statusWord = FEnv::getStatusWord();
if (!((statusWord >> FEnv::ExceptionStatusFlagsBitPosition) &
FEnv::OVERFLOW))
FEnv::OVERFLOW_F))
result = -1;
}
if (toRaise & FEnv::UNDERFLOW) {
if (toRaise & FEnv::UNDERFLOW_F) {
divfunc(smallValue, largeValue);
uint32_t statusWord = FEnv::getStatusWord();
if (!((statusWord >> FEnv::ExceptionStatusFlagsBitPosition) &
FEnv::UNDERFLOW))
FEnv::UNDERFLOW_F))
result = -1;
}
if (toRaise & FEnv::INEXACT) {
if (toRaise & FEnv::INEXACT_F) {
float two = 2.0f;
float three = 3.0f;
// 2.0 / 3.0 cannot be represented exactly in any radix 2 floating point
// format.
divfunc(two, three);
uint32_t statusWord = FEnv::getStatusWord();
if (!((statusWord >> FEnv::ExceptionStatusFlagsBitPosition) &
FEnv::INEXACT))
FEnv::INEXACT_F))
result = -1;
}
return result;
Expand Down Expand Up @@ -278,7 +277,6 @@ LIBC_INLINE int set_env(const fenv_t *envp) {
FEnv::writeStatusWord(state->StatusWord);
return 0;
}

} // namespace fputil
} // namespace LIBC_NAMESPACE_DECL

Expand Down
Loading