Skip to content

Commit

Permalink
Remove Float16
Browse files Browse the repository at this point in the history
We aren't using it. We won't be using it. We need unit tests in our
lives if we want this.
  • Loading branch information
Sonicadvance1 committed May 13, 2024
1 parent 9305fb1 commit b803573
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 111 deletions.
5 changes: 2 additions & 3 deletions CodeEmitter/CodeEmitter/ASIMDOps.inl
Original file line number Diff line number Diff line change
Expand Up @@ -3034,9 +3034,8 @@ public:
uint32_t o2;
uint32_t Imm;
if (size == SubRegSize::i16Bit) {
op = 0;
o2 = 1;
Imm = FP16ToImm8(Float16(Value));
LOGMAN_MSG_A_FMT("Unsupported");
FEX_UNREACHABLE;
}
else if (size == SubRegSize::i32Bit) {
op = 0;
Expand Down
74 changes: 0 additions & 74 deletions CodeEmitter/CodeEmitter/Emitter.h
Original file line number Diff line number Diff line change
Expand Up @@ -756,80 +756,6 @@ class Emitter : public ARMEmitter::Buffer {
Bind<false>(&Label->Forward);
}

class Float16 final {
public:
// Float16 format:
// Bit[15] - Sign
// Bit[14:10] - Exponent
// Bit[9:0] - Fraction
Float16(double Value) {
const auto AsBits = ToBits(Value);
const uint16_t Sign = AsBits >> 63;
const uint16_t Exponent = (AsBits >> 52) & 0b0111'1111'1111;
const uint64_t Fraction = AsBits & ((1ULL << 52) - 1);

switch (std::fpclassify(Value)) {
case FP_NORMAL: {
// 11-bit Exponent converted down to 5-bits.
// - Exponent biased by 1023 in 64-bit.
// - Only biased by 15.
const uint16_t UnbiasedExponent = Exponent - 1023;
const uint16_t BiasedFP16Exponent = UnbiasedExponent + 15;
LOGMAN_THROW_A_FMT((BiasedFP16Exponent & ~0b1'1111U) == 0, "Exponent too large to fit in to raw bits");

// 52-bit Fraction converted down to 10-bits.
uint32_t FractionAdjusted = Fraction >> 42; // Only retain upper 10-bits
if ((Fraction >> 41) & 1) {
// Round up if the bottom bit being shifted out is set.
FractionAdjusted += 1;
}
RawBits = (Sign << 15) | (BiasedFP16Exponent << 10) | FractionAdjusted;
break;
}
case FP_ZERO:
// Positive or negative zero.
// Exponent and Fraction as zero.
RawBits = Sign << 15;
break;
case FP_INFINITE:
// Positive or negative infinite
// Exponent is fully set, Fraction must be zero.
RawBits = (Sign << 15) | (0b1'1111 << 10);
break;
case FP_SUBNORMAL:
case FP_NAN:
// TODO: Can be encoded if necessary, but only handle when necessary.
default: LOGMAN_MSG_A_FMT("Invalid FP type");
}
}

uint8_t ToImm8() const {
// ARM imm8 float encoding
// Bit[7] - Sign
// Bit[6] - Exponent
// Bit[5:0] - Fraction
uint8_t Result {};

// Sign bit
Result |= ((RawBits >> 15) & 1) << 7;

// Exponent - Cuts off the bottom 4 bits and the top 1 bit.
Result |= ((RawBits >> 13) & 1) << 6;

// Bottom Exponent & Fraction (Cuts off bottom 6 bits)
Result |= (RawBits >> 6) & 0b11'1111;
return Result;
}

uint16_t RawBits {};
private:
uint64_t ToBits(double Value) {
uint64_t Result {};
memcpy(&Result, &Value, sizeof(Value));
return Result;
}
};

#include <CodeEmitter/VixlUtils.inl>

public:
Expand Down
20 changes: 7 additions & 13 deletions CodeEmitter/CodeEmitter/SVEOps.inl
Original file line number Diff line number Diff line change
Expand Up @@ -1512,7 +1512,8 @@ public:
size == ARMEmitter::SubRegSize::i64Bit, "Unsupported fmov size");
uint32_t Imm{};
if (size == SubRegSize::i16Bit) {
Imm = FP16ToImm8(Float16(Value));
LOGMAN_MSG_A_FMT("Unsupported");
FEX_UNREACHABLE;
} else if (size == SubRegSize::i32Bit) {
Imm = FP32ToImm8(Value);
} else if (size == SubRegSize::i64Bit) {
Expand Down Expand Up @@ -3513,7 +3514,8 @@ private:
size == SubRegSize::i64Bit, "Unsupported fcpy/fmov size");
uint32_t imm{};
if (size == SubRegSize::i16Bit) {
imm = FP16ToImm8(Float16(value));
LOGMAN_MSG_A_FMT("Unsupported");
FEX_UNREACHABLE;
} else if (size == SubRegSize::i32Bit) {
imm = FP32ToImm8(value);
} else if (size == SubRegSize::i64Bit) {
Expand Down Expand Up @@ -5228,15 +5230,14 @@ private:

// Alias that returns the equivalently sized unsigned type for a floating-point type T.
template <typename T>
requires(std::is_same_v<T, float> || std::is_same_v<T, double> || std::is_same_v<T, Float16>)
using FloatToEquivalentUInt = std::conditional_t<std::is_same_v<T, Float16>, uint16_t,
std::conditional_t<std::is_same_v<T, float>, uint32_t, uint64_t>>;
requires(std::is_same_v<T, float> || std::is_same_v<T, double>)
using FloatToEquivalentUInt = std::conditional_t<std::is_same_v<T, float>, uint32_t, uint64_t>;

// Determines if a floating-point value is capable of being converted
// into an 8-bit immediate. See pseudocode definition of VFPExpandImm
// in ARM A-profile reference manual for a general overview of how this was derived.
template <typename T>
requires(std::is_same_v<T, float> || std::is_same_v<T, double> || std::is_same_v<T, Float16>)
requires(std::is_same_v<T, float> || std::is_same_v<T, double>)
[[nodiscard, maybe_unused]] static bool IsValidFPValueForImm8(T value) {
const uint64_t bits = FEXCore::BitCast<FloatToEquivalentUInt<T>>(value);
const uint64_t datasize_idx = FEXCore::ilog2(sizeof(T)) - 1;
Expand Down Expand Up @@ -5277,13 +5278,6 @@ private:
return true;
}

static uint32_t FP16ToImm8(Float16 value) {
LOGMAN_THROW_A_FMT(IsValidFPValueForImm8(value),
"Value cannot be encoded into an 8-bit immediate");

return value.ToImm8();
}

static uint32_t FP32ToImm8(float value) {
LOGMAN_THROW_A_FMT(IsValidFPValueForImm8(value),
"Value ({}) cannot be encoded into an 8-bit immediate", value);
Expand Down
4 changes: 2 additions & 2 deletions CodeEmitter/CodeEmitter/ScalarOps.inl
Original file line number Diff line number Diff line change
Expand Up @@ -1059,8 +1059,8 @@ public:
uint32_t imm8;
uint32_t imm5 = 0b0'0000;
if (size == ARMEmitter::ScalarRegSize::i16Bit) {
ptype = 0b11;
imm8 = FP16ToImm8(Float16(Value));
LOGMAN_MSG_A_FMT("Unsupported");
FEX_UNREACHABLE;
}
else if (size == ARMEmitter::ScalarRegSize::i32Bit) {
ptype = 0b00;
Expand Down
4 changes: 2 additions & 2 deletions FEXCore/unittests/Emitter/ASIMD_Tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2094,11 +2094,11 @@ TEST_CASE_METHOD(TestDisassembler, "Emitter: ASIMD: Advanced SIMD three same") {
TEST_CASE_METHOD(TestDisassembler, "Emitter: ASIMD: Advanced SIMD modified immediate") {
// XXX: ORR - 32-bit/16-bit
// XXX: MOVI - Shifting ones
TEST_SINGLE(fmov(SubRegSize::i16Bit, QReg::q30, 1.0), "fmov v30.8h, #0x70 (1.0000)");
// TEST_SINGLE(fmov(SubRegSize::i16Bit, QReg::q30, 1.0), "fmov v30.8h, #0x70 (1.0000)");
TEST_SINGLE(fmov(SubRegSize::i32Bit, QReg::q30, 1.0), "fmov v30.4s, #0x70 (1.0000)");
TEST_SINGLE(fmov(SubRegSize::i64Bit, QReg::q30, 1.0), "fmov v30.2d, #0x70 (1.0000)");

TEST_SINGLE(fmov(SubRegSize::i16Bit, DReg::d30, 1.0), "fmov v30.4h, #0x70 (1.0000)");
// TEST_SINGLE(fmov(SubRegSize::i16Bit, DReg::d30, 1.0), "fmov v30.4h, #0x70 (1.0000)");
TEST_SINGLE(fmov(SubRegSize::i32Bit, DReg::d30, 1.0), "fmov v30.2s, #0x70 (1.0000)");
// TEST_SINGLE(fmov(SubRegSize::i64Bit, DReg::d30, 1.0), "fmov v30.1d, #0x70 (1.0000)");

Expand Down
32 changes: 16 additions & 16 deletions FEXCore/unittests/Emitter/SVE_Tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2336,69 +2336,69 @@ TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE broadcast integer immediat
}

TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE broadcast floating-point immediate (predicated)") {
TEST_SINGLE(fcpy(SubRegSize::i16Bit, ZReg::z30, PReg::p6.Merging(), -0.125), "fmov z30.h, p6/m, #0xc0 (-0.1250)");
// TEST_SINGLE(fcpy(SubRegSize::i16Bit, ZReg::z30, PReg::p6.Merging(), -0.125), "fmov z30.h, p6/m, #0xc0 (-0.1250)");
TEST_SINGLE(fcpy(SubRegSize::i32Bit, ZReg::z30, PReg::p6.Merging(), -0.125), "fmov z30.s, p6/m, #0xc0 (-0.1250)");
TEST_SINGLE(fcpy(SubRegSize::i64Bit, ZReg::z30, PReg::p6.Merging(), -0.125), "fmov z30.d, p6/m, #0xc0 (-0.1250)");

TEST_SINGLE(fcpy(SubRegSize::i16Bit, ZReg::z30, PReg::p6.Merging(), 0.5), "fmov z30.h, p6/m, #0x60 (0.5000)");
// TEST_SINGLE(fcpy(SubRegSize::i16Bit, ZReg::z30, PReg::p6.Merging(), 0.5), "fmov z30.h, p6/m, #0x60 (0.5000)");
TEST_SINGLE(fcpy(SubRegSize::i32Bit, ZReg::z30, PReg::p6.Merging(), 0.5), "fmov z30.s, p6/m, #0x60 (0.5000)");
TEST_SINGLE(fcpy(SubRegSize::i64Bit, ZReg::z30, PReg::p6.Merging(), 0.5), "fmov z30.d, p6/m, #0x60 (0.5000)");

TEST_SINGLE(fcpy(SubRegSize::i16Bit, ZReg::z30, PReg::p6.Merging(), 1.0), "fmov z30.h, p6/m, #0x70 (1.0000)");
// TEST_SINGLE(fcpy(SubRegSize::i16Bit, ZReg::z30, PReg::p6.Merging(), 1.0), "fmov z30.h, p6/m, #0x70 (1.0000)");
TEST_SINGLE(fcpy(SubRegSize::i32Bit, ZReg::z30, PReg::p6.Merging(), 1.0), "fmov z30.s, p6/m, #0x70 (1.0000)");
TEST_SINGLE(fcpy(SubRegSize::i64Bit, ZReg::z30, PReg::p6.Merging(), 1.0), "fmov z30.d, p6/m, #0x70 (1.0000)");

TEST_SINGLE(fcpy(SubRegSize::i16Bit, ZReg::z30, PReg::p6.Merging(), 31.0), "fmov z30.h, p6/m, #0x3f (31.0000)");
// TEST_SINGLE(fcpy(SubRegSize::i16Bit, ZReg::z30, PReg::p6.Merging(), 31.0), "fmov z30.h, p6/m, #0x3f (31.0000)");
TEST_SINGLE(fcpy(SubRegSize::i32Bit, ZReg::z30, PReg::p6.Merging(), 31.0), "fmov z30.s, p6/m, #0x3f (31.0000)");
TEST_SINGLE(fcpy(SubRegSize::i64Bit, ZReg::z30, PReg::p6.Merging(), 31.0), "fmov z30.d, p6/m, #0x3f (31.0000)");

TEST_SINGLE(fmov(SubRegSize::i16Bit, ZReg::z30, PReg::p6.Merging(), -0.125), "fmov z30.h, p6/m, #0xc0 (-0.1250)");
// TEST_SINGLE(fmov(SubRegSize::i16Bit, ZReg::z30, PReg::p6.Merging(), -0.125), "fmov z30.h, p6/m, #0xc0 (-0.1250)");
TEST_SINGLE(fmov(SubRegSize::i32Bit, ZReg::z30, PReg::p6.Merging(), -0.125), "fmov z30.s, p6/m, #0xc0 (-0.1250)");
TEST_SINGLE(fmov(SubRegSize::i64Bit, ZReg::z30, PReg::p6.Merging(), -0.125), "fmov z30.d, p6/m, #0xc0 (-0.1250)");

TEST_SINGLE(fmov(SubRegSize::i16Bit, ZReg::z30, PReg::p6.Merging(), 0.5), "fmov z30.h, p6/m, #0x60 (0.5000)");
// TEST_SINGLE(fmov(SubRegSize::i16Bit, ZReg::z30, PReg::p6.Merging(), 0.5), "fmov z30.h, p6/m, #0x60 (0.5000)");
TEST_SINGLE(fmov(SubRegSize::i32Bit, ZReg::z30, PReg::p6.Merging(), 0.5), "fmov z30.s, p6/m, #0x60 (0.5000)");
TEST_SINGLE(fmov(SubRegSize::i64Bit, ZReg::z30, PReg::p6.Merging(), 0.5), "fmov z30.d, p6/m, #0x60 (0.5000)");

TEST_SINGLE(fmov(SubRegSize::i16Bit, ZReg::z30, PReg::p6.Merging(), 1.0), "fmov z30.h, p6/m, #0x70 (1.0000)");
// TEST_SINGLE(fmov(SubRegSize::i16Bit, ZReg::z30, PReg::p6.Merging(), 1.0), "fmov z30.h, p6/m, #0x70 (1.0000)");
TEST_SINGLE(fmov(SubRegSize::i32Bit, ZReg::z30, PReg::p6.Merging(), 1.0), "fmov z30.s, p6/m, #0x70 (1.0000)");
TEST_SINGLE(fmov(SubRegSize::i64Bit, ZReg::z30, PReg::p6.Merging(), 1.0), "fmov z30.d, p6/m, #0x70 (1.0000)");

TEST_SINGLE(fmov(SubRegSize::i16Bit, ZReg::z30, PReg::p6.Merging(), 31.0), "fmov z30.h, p6/m, #0x3f (31.0000)");
// TEST_SINGLE(fmov(SubRegSize::i16Bit, ZReg::z30, PReg::p6.Merging(), 31.0), "fmov z30.h, p6/m, #0x3f (31.0000)");
TEST_SINGLE(fmov(SubRegSize::i32Bit, ZReg::z30, PReg::p6.Merging(), 31.0), "fmov z30.s, p6/m, #0x3f (31.0000)");
TEST_SINGLE(fmov(SubRegSize::i64Bit, ZReg::z30, PReg::p6.Merging(), 31.0), "fmov z30.d, p6/m, #0x3f (31.0000)");
}

TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE broadcast floating-point immediate (unpredicated)") {
TEST_SINGLE(fdup(SubRegSize::i16Bit, ZReg::z30, -0.125), "fmov z30.h, #0xc0 (-0.1250)");
// TEST_SINGLE(fdup(SubRegSize::i16Bit, ZReg::z30, -0.125), "fmov z30.h, #0xc0 (-0.1250)");
TEST_SINGLE(fdup(SubRegSize::i32Bit, ZReg::z30, -0.125), "fmov z30.s, #0xc0 (-0.1250)");
TEST_SINGLE(fdup(SubRegSize::i64Bit, ZReg::z30, -0.125), "fmov z30.d, #0xc0 (-0.1250)");

TEST_SINGLE(fdup(SubRegSize::i16Bit, ZReg::z30, 0.5), "fmov z30.h, #0x60 (0.5000)");
// TEST_SINGLE(fdup(SubRegSize::i16Bit, ZReg::z30, 0.5), "fmov z30.h, #0x60 (0.5000)");
TEST_SINGLE(fdup(SubRegSize::i32Bit, ZReg::z30, 0.5), "fmov z30.s, #0x60 (0.5000)");
TEST_SINGLE(fdup(SubRegSize::i64Bit, ZReg::z30, 0.5), "fmov z30.d, #0x60 (0.5000)");

TEST_SINGLE(fdup(SubRegSize::i16Bit, ZReg::z30, 1.0), "fmov z30.h, #0x70 (1.0000)");
// TEST_SINGLE(fdup(SubRegSize::i16Bit, ZReg::z30, 1.0), "fmov z30.h, #0x70 (1.0000)");
TEST_SINGLE(fdup(SubRegSize::i32Bit, ZReg::z30, 1.0), "fmov z30.s, #0x70 (1.0000)");
TEST_SINGLE(fdup(SubRegSize::i64Bit, ZReg::z30, 1.0), "fmov z30.d, #0x70 (1.0000)");

TEST_SINGLE(fdup(SubRegSize::i16Bit, ZReg::z30, 31.0), "fmov z30.h, #0x3f (31.0000)");
// TEST_SINGLE(fdup(SubRegSize::i16Bit, ZReg::z30, 31.0), "fmov z30.h, #0x3f (31.0000)");
TEST_SINGLE(fdup(SubRegSize::i32Bit, ZReg::z30, 31.0), "fmov z30.s, #0x3f (31.0000)");
TEST_SINGLE(fdup(SubRegSize::i64Bit, ZReg::z30, 31.0), "fmov z30.d, #0x3f (31.0000)");

TEST_SINGLE(fmov(SubRegSize::i16Bit, ZReg::z30, -0.125), "fmov z30.h, #0xc0 (-0.1250)");
// TEST_SINGLE(fmov(SubRegSize::i16Bit, ZReg::z30, -0.125), "fmov z30.h, #0xc0 (-0.1250)");
TEST_SINGLE(fmov(SubRegSize::i32Bit, ZReg::z30, -0.125), "fmov z30.s, #0xc0 (-0.1250)");
TEST_SINGLE(fmov(SubRegSize::i64Bit, ZReg::z30, -0.125), "fmov z30.d, #0xc0 (-0.1250)");

TEST_SINGLE(fmov(SubRegSize::i16Bit, ZReg::z30, 0.5), "fmov z30.h, #0x60 (0.5000)");
// TEST_SINGLE(fmov(SubRegSize::i16Bit, ZReg::z30, 0.5), "fmov z30.h, #0x60 (0.5000)");
TEST_SINGLE(fmov(SubRegSize::i32Bit, ZReg::z30, 0.5), "fmov z30.s, #0x60 (0.5000)");
TEST_SINGLE(fmov(SubRegSize::i64Bit, ZReg::z30, 0.5), "fmov z30.d, #0x60 (0.5000)");

TEST_SINGLE(fmov(SubRegSize::i16Bit, ZReg::z30, 1.0), "fmov z30.h, #0x70 (1.0000)");
// TEST_SINGLE(fmov(SubRegSize::i16Bit, ZReg::z30, 1.0), "fmov z30.h, #0x70 (1.0000)");
TEST_SINGLE(fmov(SubRegSize::i32Bit, ZReg::z30, 1.0), "fmov z30.s, #0x70 (1.0000)");
TEST_SINGLE(fmov(SubRegSize::i64Bit, ZReg::z30, 1.0), "fmov z30.d, #0x70 (1.0000)");

TEST_SINGLE(fmov(SubRegSize::i16Bit, ZReg::z30, 31.0), "fmov z30.h, #0x3f (31.0000)");
// TEST_SINGLE(fmov(SubRegSize::i16Bit, ZReg::z30, 31.0), "fmov z30.h, #0x3f (31.0000)");
TEST_SINGLE(fmov(SubRegSize::i32Bit, ZReg::z30, 31.0), "fmov z30.s, #0x3f (31.0000)");
TEST_SINGLE(fmov(SubRegSize::i64Bit, ZReg::z30, 31.0), "fmov z30.d, #0x3f (31.0000)");
}
Expand Down
4 changes: 3 additions & 1 deletion FEXCore/unittests/Emitter/Scalar_Tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -757,10 +757,11 @@ TEST_CASE_METHOD(TestDisassembler, "Emitter: Scalar: Floating-point compare") {
TEST_SINGLE(fcmpe(HReg::h30), "fcmpe h30, #0.0");
}
TEST_CASE_METHOD(TestDisassembler, "Emitter: Scalar: Floating-point immediate") {
TEST_SINGLE(fmov(ScalarRegSize::i16Bit, VReg::v30, 1.0), "fmov h30, #0x70 (1.0000)");
// TEST_SINGLE(fmov(ScalarRegSize::i16Bit, VReg::v30, 1.0), "fmov h30, #0x70 (1.0000)");
TEST_SINGLE(fmov(ScalarRegSize::i32Bit, VReg::v30, 1.0), "fmov s30, #0x70 (1.0000)");
TEST_SINGLE(fmov(ScalarRegSize::i64Bit, VReg::v30, 1.0), "fmov d30, #0x70 (1.0000)");

#if 0
float Decoding[] = {
2.000000, 4.000000, 8.000000, 16.000000, 0.125000, 0.250000, 0.500000, 1.000000, 2.125000, 4.250000, 8.500000, 17.000000,
0.132812, 0.265625, 0.531250, 1.062500, 2.250000, 4.500000, 9.000000, 18.000000, 0.140625, 0.281250, 0.562500, 1.125000,
Expand Down Expand Up @@ -813,6 +814,7 @@ TEST_CASE_METHOD(TestDisassembler, "Emitter: Scalar: Floating-point immediate")
for (size_t i = 0; i < (sizeof(Decoding) / sizeof(Decoding[0])); ++i) {
TEST_SINGLE(fmov(ScalarRegSize::i16Bit, VReg::v30, Decoding[i]), DecodingString[i]);
}
#endif
}
TEST_CASE_METHOD(TestDisassembler, "Emitter: Scalar: Floating-point conditional compare") {
TEST_SINGLE(fccmp(SReg::s30, SReg::s29, StatusFlags::None, Condition::CC_AL), "fccmp s30, s29, #nzcv, al");
Expand Down

0 comments on commit b803573

Please sign in to comment.