Files
FEX-Emu--FEX/FEXCore/include/FEXCore/Utils/FPState.h
T
Paulo Matos 2b4ec88dae Whole-tree reformat
This follows discussions from #3413.
Followup commits add clang-format file, script and blame ignore lists.
2024-04-12 16:26:02 +02:00

66 lines
1.6 KiB
C++

// SPDX-License-Identifier: MIT
#pragma once
#include <cstdint>
namespace FEXCore::FPState {
enum class X87Tag : uint8_t { Valid = 0b00, Zero = 0b01, Special = 0b10, Empty = 0b11 };
static inline X87Tag GetX87Tag(uint64_t (&Reg)[2], bool Valid) {
if (!Valid) {
return X87Tag::Empty;
}
const uint64_t Exponent = Reg[1] & 0x7fff;
if (Exponent == 0x7fff) {
// (Pseudo) NaN / Inf
return X87Tag::Special;
}
const bool JBit = Reg[0] & (1ULL << 63);
if (Exponent == 0) {
const uint64_t Fraction = Reg[0] & ((1ULL << 63) - 1);
if (!JBit && !Fraction) {
return X87Tag::Zero;
} else {
// (Pseudo) Subnormal
return X87Tag::Special;
}
}
if (JBit) {
// Normal
return X87Tag::Valid;
} else {
// Invalid
return X87Tag::Special;
}
}
static inline uint16_t ConvertFromAbridgedFTW(uint16_t FSW, uint64_t (&MM)[8][2], uint8_t AbridgedFTW) {
const uint32_t StackTop = (FSW >> 11) & 0b111;
uint16_t FTW = 0;
for (uint32_t i = 0; i < 8; i++) {
// The AMD manually incorrectly states there is a direct mapping here, only the intel-manual correctly states
// the stack-relative behaviour
const uint16_t StackIndex = (i - StackTop) & 0b111;
const X87Tag Tag = GetX87Tag(MM[StackIndex], AbridgedFTW & (1 << i));
FTW |= static_cast<uint8_t>(Tag) << (2 * i);
}
return FTW;
}
static inline uint8_t ConvertToAbridgedFTW(uint16_t FTW) {
uint8_t AbridgedFTW = 0;
for (uint32_t i = 0; i < 8; i++) {
const X87Tag Tag = static_cast<X87Tag>((FTW >> (2 * i)) & 3);
AbridgedFTW |= ((Tag == X87Tag::Empty) ? 0 : 1) << i;
}
return AbridgedFTW;
}
} // namespace FEXCore::FPState