diff --git a/FEXCore/Source/Interface/Core/JIT/ConversionOps.cpp b/FEXCore/Source/Interface/Core/JIT/ConversionOps.cpp index 2a8bcac29..8d424ce4a 100644 --- a/FEXCore/Source/Interface/Core/JIT/ConversionOps.cpp +++ b/FEXCore/Source/Interface/Core/JIT/ConversionOps.cpp @@ -423,11 +423,11 @@ DEF_OP(Vector_FToI) { const auto Mask = PRED_TMP_32B.Merging(); switch (Op->Round) { - case FEXCore::IR::Round_Nearest.Val: frintn(SubEmitSize, Dst.Z(), Mask, Vector.Z()); break; - case FEXCore::IR::Round_Negative_Infinity.Val: frintm(SubEmitSize, Dst.Z(), Mask, Vector.Z()); break; - case FEXCore::IR::Round_Positive_Infinity.Val: frintp(SubEmitSize, Dst.Z(), Mask, Vector.Z()); break; - case FEXCore::IR::Round_Towards_Zero.Val: frintz(SubEmitSize, Dst.Z(), Mask, Vector.Z()); break; - case FEXCore::IR::Round_Host.Val: frinti(SubEmitSize, Dst.Z(), Mask, Vector.Z()); break; + case IR::RoundMode::Nearest: frintn(SubEmitSize, Dst.Z(), Mask, Vector.Z()); break; + case IR::RoundMode::NegInfinity: frintm(SubEmitSize, Dst.Z(), Mask, Vector.Z()); break; + case IR::RoundMode::PosInfinity: frintp(SubEmitSize, Dst.Z(), Mask, Vector.Z()); break; + case IR::RoundMode::TowardsZero: frintz(SubEmitSize, Dst.Z(), Mask, Vector.Z()); break; + case IR::RoundMode::Host: frinti(SubEmitSize, Dst.Z(), Mask, Vector.Z()); break; } } else { const auto IsScalar = ElementSize == OpSize; @@ -449,21 +449,21 @@ DEF_OP(Vector_FToI) { } switch (Op->Round) { - case IR::Round_Nearest.Val: ROUNDING_FN(frintn); break; - case IR::Round_Negative_Infinity.Val: ROUNDING_FN(frintm); break; - case IR::Round_Positive_Infinity.Val: ROUNDING_FN(frintp); break; - case IR::Round_Towards_Zero.Val: ROUNDING_FN(frintz); break; - case IR::Round_Host.Val: ROUNDING_FN(frinti); break; + case IR::RoundMode::Nearest: ROUNDING_FN(frintn); break; + case IR::RoundMode::NegInfinity: ROUNDING_FN(frintm); break; + case IR::RoundMode::PosInfinity: ROUNDING_FN(frintp); break; + case IR::RoundMode::TowardsZero: ROUNDING_FN(frintz); break; + case IR::RoundMode::Host: ROUNDING_FN(frinti); break; } #undef ROUNDING_FN } else { switch (Op->Round) { - case FEXCore::IR::Round_Nearest.Val: frintn(SubEmitSize, Dst.Q(), Vector.Q()); break; - case FEXCore::IR::Round_Negative_Infinity.Val: frintm(SubEmitSize, Dst.Q(), Vector.Q()); break; - case FEXCore::IR::Round_Positive_Infinity.Val: frintp(SubEmitSize, Dst.Q(), Vector.Q()); break; - case FEXCore::IR::Round_Towards_Zero.Val: frintz(SubEmitSize, Dst.Q(), Vector.Q()); break; - case FEXCore::IR::Round_Host.Val: frinti(SubEmitSize, Dst.Q(), Vector.Q()); break; + case IR::RoundMode::Nearest: frintn(SubEmitSize, Dst.Q(), Vector.Q()); break; + case IR::RoundMode::NegInfinity: frintm(SubEmitSize, Dst.Q(), Vector.Q()); break; + case IR::RoundMode::PosInfinity: frintp(SubEmitSize, Dst.Q(), Vector.Q()); break; + case IR::RoundMode::TowardsZero: frintz(SubEmitSize, Dst.Q(), Vector.Q()); break; + case IR::RoundMode::Host: frinti(SubEmitSize, Dst.Q(), Vector.Q()); break; } } } @@ -539,11 +539,11 @@ DEF_OP(Vector_F64ToI32) { // Then convert to integers using fcvtzs. auto CVTReg = Dst.Z(); switch (Round) { - case IR::Round_Nearest.Val: frintn(ARMEmitter::SubRegSize::i64Bit, Dst.Z(), Mask, Vector.Z()); break; - case IR::Round_Negative_Infinity.Val: frintm(ARMEmitter::SubRegSize::i64Bit, Dst.Z(), Mask, Vector.Z()); break; - case IR::Round_Positive_Infinity.Val: frintp(ARMEmitter::SubRegSize::i64Bit, Dst.Z(), Mask, Vector.Z()); break; - case IR::Round_Towards_Zero.Val: CVTReg = Vector.Z(); break; - case IR::Round_Host.Val: frinti(ARMEmitter::SubRegSize::i64Bit, Dst.Z(), Mask, Vector.Z()); break; + case IR::RoundMode::Nearest: frintn(ARMEmitter::SubRegSize::i64Bit, Dst.Z(), Mask, Vector.Z()); break; + case IR::RoundMode::NegInfinity: frintm(ARMEmitter::SubRegSize::i64Bit, Dst.Z(), Mask, Vector.Z()); break; + case IR::RoundMode::PosInfinity: frintp(ARMEmitter::SubRegSize::i64Bit, Dst.Z(), Mask, Vector.Z()); break; + case IR::RoundMode::TowardsZero: CVTReg = Vector.Z(); break; + case IR::RoundMode::Host: frinti(ARMEmitter::SubRegSize::i64Bit, Dst.Z(), Mask, Vector.Z()); break; } fcvtzs(Dst.Z(), ARMEmitter::SubRegSize::i32Bit, Mask, CVTReg, ARMEmitter::SubRegSize::i64Bit); @@ -567,11 +567,11 @@ DEF_OP(Vector_F64ToI32) { ///< Round float to integral depending on rounding mode. switch (Round) { - case FEXCore::IR::Round_Nearest.Val: frintn(ARMEmitter::SubRegSize::i64Bit, Dst.Q(), Vector.Q()); break; - case FEXCore::IR::Round_Negative_Infinity.Val: frintm(ARMEmitter::SubRegSize::i64Bit, Dst.Q(), Vector.Q()); break; - case FEXCore::IR::Round_Positive_Infinity.Val: frintp(ARMEmitter::SubRegSize::i64Bit, Dst.Q(), Vector.Q()); break; - case FEXCore::IR::Round_Towards_Zero.Val: frintz(ARMEmitter::SubRegSize::i64Bit, Dst.Q(), Vector.Q()); break; - case FEXCore::IR::Round_Host.Val: frinti(ARMEmitter::SubRegSize::i64Bit, Dst.Q(), Vector.Q()); break; + case IR::RoundMode::Nearest: frintn(ARMEmitter::SubRegSize::i64Bit, Dst.Q(), Vector.Q()); break; + case IR::RoundMode::NegInfinity: frintm(ARMEmitter::SubRegSize::i64Bit, Dst.Q(), Vector.Q()); break; + case IR::RoundMode::PosInfinity: frintp(ARMEmitter::SubRegSize::i64Bit, Dst.Q(), Vector.Q()); break; + case IR::RoundMode::TowardsZero: frintz(ARMEmitter::SubRegSize::i64Bit, Dst.Q(), Vector.Q()); break; + case IR::RoundMode::Host: frinti(ARMEmitter::SubRegSize::i64Bit, Dst.Q(), Vector.Q()); break; } // Now narrow from f64 to f32. diff --git a/FEXCore/Source/Interface/Core/JIT/MiscOps.cpp b/FEXCore/Source/Interface/Core/JIT/MiscOps.cpp index 34e731b24..bc41258d1 100644 --- a/FEXCore/Source/Interface/Core/JIT/MiscOps.cpp +++ b/FEXCore/Source/Interface/Core/JIT/MiscOps.cpp @@ -15,6 +15,7 @@ $end_info$ #include #include +#include namespace FEXCore::CPU { @@ -107,10 +108,10 @@ DEF_OP(GetRoundingMode) { // zero. Just swapping 01 and 10. That's a bitfield reverse. Round mode is in // bottom two bits. After reversing as a 32-bit operation, it'll be in [31:30] // and ripe for reinsertion back at 0. - static_assert(IR::ROUND_MODE_NEAREST == 0); - static_assert(IR::ROUND_MODE_NEGATIVE_INFINITY == 1); - static_assert(IR::ROUND_MODE_POSITIVE_INFINITY == 2); - static_assert(IR::ROUND_MODE_TOWARDS_ZERO == 3); + static_assert(FEXCore::ToUnderlying(IR::RoundMode::Nearest) == 0); + static_assert(FEXCore::ToUnderlying(IR::RoundMode::NegInfinity) == 1); + static_assert(FEXCore::ToUnderlying(IR::RoundMode::PosInfinity) == 2); + static_assert(FEXCore::ToUnderlying(IR::RoundMode::TowardsZero) == 3); rbit(ARMEmitter::Size::i32Bit, TMP1, Dst); bfi(ARMEmitter::Size::i64Bit, Dst, TMP1, 30, 2); diff --git a/FEXCore/Source/Interface/Core/JIT/VectorOps.cpp b/FEXCore/Source/Interface/Core/JIT/VectorOps.cpp index af71190a8..7c498ed04 100644 --- a/FEXCore/Source/Interface/Core/JIT/VectorOps.cpp +++ b/FEXCore/Source/Interface/Core/JIT/VectorOps.cpp @@ -744,11 +744,11 @@ DEF_OP(VFToIScalarInsert) { auto Src = *std::get_if(&SrcVar); switch (RoundMode) { - case IR::Round_Nearest: frintn(SubRegSize.Scalar, Dst, Src); break; - case IR::Round_Negative_Infinity: frintm(SubRegSize.Scalar, Dst, Src); break; - case IR::Round_Positive_Infinity: frintp(SubRegSize.Scalar, Dst, Src); break; - case IR::Round_Towards_Zero: frintz(SubRegSize.Scalar, Dst, Src); break; - case IR::Round_Host: frinti(SubRegSize.Scalar, Dst, Src); break; + case IR::RoundMode::Nearest: frintn(SubRegSize.Scalar, Dst, Src); break; + case IR::RoundMode::NegInfinity: frintm(SubRegSize.Scalar, Dst, Src); break; + case IR::RoundMode::PosInfinity: frintp(SubRegSize.Scalar, Dst, Src); break; + case IR::RoundMode::TowardsZero: frintz(SubRegSize.Scalar, Dst, Src); break; + case IR::RoundMode::Host: frinti(SubRegSize.Scalar, Dst, Src); break; } }; diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.h b/FEXCore/Source/Interface/Core/OpcodeDispatcher.h index d8bed89fc..4f4726770 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.h +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.h @@ -565,7 +565,7 @@ public: template void AVXInsertScalar_CVT_Float_To_Float(OpcodeArgs); - RoundType TranslateRoundType(uint8_t Mode); + RoundMode TranslateRoundType(uint8_t Mode); template void InsertScalarRound(OpcodeArgs); diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp index 39a6ab687..1837a3e0a 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp @@ -505,18 +505,18 @@ void OpDispatchBuilder::AVXInsertScalar_CVT_Float_To_Float(OpcodeArgs) { template void OpDispatchBuilder::AVXInsertScalar_CVT_Float_To_Float(OpcodeArgs); template void OpDispatchBuilder::AVXInsertScalar_CVT_Float_To_Float(OpcodeArgs); -RoundType OpDispatchBuilder::TranslateRoundType(uint8_t Mode) { +RoundMode OpDispatchBuilder::TranslateRoundType(uint8_t Mode) { const uint64_t RoundControlSource = (Mode >> 2) & 1; uint64_t RoundControl = Mode & 0b11; static constexpr std::array SourceModes = { - FEXCore::IR::Round_Nearest, - FEXCore::IR::Round_Negative_Infinity, - FEXCore::IR::Round_Positive_Infinity, - FEXCore::IR::Round_Towards_Zero, + RoundMode::Nearest, + RoundMode::NegInfinity, + RoundMode::PosInfinity, + RoundMode::TowardsZero, }; - return RoundControlSource ? Round_Host : SourceModes[RoundControl]; + return RoundControlSource ? RoundMode::Host : SourceModes[RoundControl]; } Ref OpDispatchBuilder::InsertScalarRoundImpl(OpcodeArgs, IR::OpSize DstSize, IR::OpSize ElementSize, const X86Tables::DecodedOperand& Src1Op, @@ -2115,7 +2115,7 @@ Ref OpDispatchBuilder::CVTFPR_To_GPRImpl(OpcodeArgs, Ref Src, IR::OpSize SrcElem // When we lack hardware support, we need a bit of a convoluted sequence of // fixups before before and after conversion to emulate x86 semantics. if (HostRoundingMode) { - Src = _Vector_FToI(SrcElementSize, SrcElementSize, Src, Round_Host); + Src = _Vector_FToI(SrcElementSize, SrcElementSize, Src, RoundMode::Host); } Ref Converted = _Float_ToGPR_ZS(GPRSize, SrcElementSize, Src); @@ -2195,7 +2195,7 @@ Ref OpDispatchBuilder::Vector_CVT_Float_To_Int32Impl(OpcodeArgs, IR::OpSize DstS } else { // Otherwise, we have to do all the fixups, but vectorized. if (HostRoundingMode) { - Src = _Vector_FToI(SrcSize, SrcElementSize, Src, Round_Host); + Src = _Vector_FToI(SrcSize, SrcElementSize, Src, RoundMode::Host); } OpSize OverflowConstSize = ZeroUpperHalf && SrcElementSize == OpSize::i64Bit ? DstSize / 2 : DstSize; @@ -2203,7 +2203,7 @@ Ref OpDispatchBuilder::Vector_CVT_Float_To_Int32Impl(OpcodeArgs, IR::OpSize DstS Ref Converted {}, Cmp {}; if (SrcElementSize == OpSize::i64Bit) { Ref MaxF = LoadAndCacheNamedVectorConstant(SrcSize, NAMED_VECTOR_CVTMAX_F64_I32); - Converted = _Vector_F64ToI32(DstSize, Src, Round_Towards_Zero, ZeroUpperHalf); + Converted = _Vector_F64ToI32(DstSize, Src, RoundMode::TowardsZero, ZeroUpperHalf); Cmp = _VFCMPGT(SrcSize, OpSize::i64Bit, MaxF, Src); Cmp = _VUShrNI(DstSize, OpSize::i64Bit, Cmp, 32); diff --git a/FEXCore/Source/Interface/IR/IR.h b/FEXCore/Source/Interface/IR/IR.h index 96c92e6b6..a94a4306e 100644 --- a/FEXCore/Source/Interface/IR/IR.h +++ b/FEXCore/Source/Interface/IR/IR.h @@ -488,15 +488,6 @@ struct FEX_PACKED TypeDefinition final { static_assert(std::is_trivially_copyable_v); -struct FEX_PACKED RoundType final { - uint8_t Val; - [[nodiscard]] constexpr operator uint8_t() const { - return Val; - } - [[nodiscard]] - friend constexpr bool operator==(const RoundType&, const RoundType&) = default; -}; - class NodeIterator; /* This iterator can be used to step though nodes. diff --git a/FEXCore/Source/Interface/IR/IR.json b/FEXCore/Source/Interface/IR/IR.json index bbf69e348..91276a52c 100644 --- a/FEXCore/Source/Interface/IR/IR.json +++ b/FEXCore/Source/Interface/IR/IR.json @@ -85,6 +85,13 @@ "Store = 1,", "LoadStore = 2,", "Inst = 3," + ], + "class RoundMode : uint8_t": [ + "Nearest = 0,", + "NegInfinity = 1,", + "PosInfinity = 2,", + "TowardsZero = 3, /* Truncate */", + "Host = 4," ] }, "Defines": [ @@ -114,18 +121,6 @@ "constexpr uint8_t FCMP_FLAG_LT = 1", "constexpr uint8_t FCMP_FLAG_UNORDERED = 2", - "constexpr uint8_t ROUND_MODE_NEAREST = 0", - "constexpr uint8_t ROUND_MODE_NEGATIVE_INFINITY = 1", - "constexpr uint8_t ROUND_MODE_POSITIVE_INFINITY = 2", - "constexpr uint8_t ROUND_MODE_TOWARDS_ZERO = 3", - "constexpr uint8_t ROUND_MODE_FLUSH_TO_ZERO = 1 << 2", - - "constexpr FEXCore::IR::RoundType Round_Nearest {ROUND_MODE_NEAREST}", - "constexpr FEXCore::IR::RoundType Round_Negative_Infinity {ROUND_MODE_NEGATIVE_INFINITY}", - "constexpr FEXCore::IR::RoundType Round_Positive_Infinity {ROUND_MODE_POSITIVE_INFINITY}", - "constexpr FEXCore::IR::RoundType Round_Towards_Zero {ROUND_MODE_TOWARDS_ZERO} /* Truncate */", - "constexpr FEXCore::IR::RoundType Round_Host {ROUND_MODE_TOWARDS_ZERO + 1}", - "constexpr FEXCore::IR::MemOffsetType MEM_OFFSET_SXTX {0}", "constexpr FEXCore::IR::MemOffsetType MEM_OFFSET_UXTW {1}", "constexpr FEXCore::IR::MemOffsetType MEM_OFFSET_SXTW {2}", @@ -158,7 +153,7 @@ "SHA256Sum": "SHA256Sum", "MemOffsetType": "MemOffsetType", "BreakDefinition": "BreakDefinition", - "RoundType": "RoundType", + "RoundType": "RoundMode", "FloatCompareOp": "FloatCompareOp", "NamedVectorConstant": "FEXCore::IR::NamedVectorConstant", "IndexNamedVectorConstant": "FEXCore::IR::IndexNamedVectorConstant", diff --git a/FEXCore/Source/Interface/IR/IRDumper.cpp b/FEXCore/Source/Interface/IR/IRDumper.cpp index 2130f8881..061e72c17 100644 --- a/FEXCore/Source/Interface/IR/IRDumper.cpp +++ b/FEXCore/Source/Interface/IR/IRDumper.cpp @@ -136,13 +136,13 @@ static void PrintArg(fextl::stringstream* out, const IRListView*, FenceType Arg) } } -static void PrintArg(fextl::stringstream* out, const IRListView*, FEXCore::IR::RoundType Arg) { +static void PrintArg(fextl::stringstream* out, const IRListView*, RoundMode Arg) { switch (Arg) { - case FEXCore::IR::Round_Nearest: *out << "Nearest"; break; - case FEXCore::IR::Round_Negative_Infinity: *out << "-Inf"; break; - case FEXCore::IR::Round_Positive_Infinity: *out << "+Inf"; break; - case FEXCore::IR::Round_Towards_Zero: *out << "Towards Zero"; break; - case FEXCore::IR::Round_Host: *out << "Host"; break; + case RoundMode::Nearest: *out << "Nearest"; break; + case RoundMode::NegInfinity: *out << "-Inf"; break; + case RoundMode::PosInfinity: *out << "+Inf"; break; + case RoundMode::TowardsZero: *out << "Towards Zero"; break; + case RoundMode::Host: *out << "Host"; break; default: *out << ""; break; } } @@ -154,7 +154,7 @@ static void PrintArg(fextl::stringstream* out, const IRListView*, FEXCore::IR::S case FEXCore::IR::SyscallFlags::NOSYNCSTATEONENTRY: *out << "No Sync State on Entry"; break; case FEXCore::IR::SyscallFlags::NORETURN: *out << "No Return"; break; case FEXCore::IR::SyscallFlags::NOSIDEEFFECTS: *out << "No Side Effects"; break; - default: *out << ""; break; + default: *out << ""; break; } } diff --git a/FEXCore/Source/Interface/IR/Passes/x87StackOptimizationPass.cpp b/FEXCore/Source/Interface/IR/Passes/x87StackOptimizationPass.cpp index ebada4aee..6b15c2de6 100644 --- a/FEXCore/Source/Interface/IR/Passes/x87StackOptimizationPass.cpp +++ b/FEXCore/Source/Interface/IR/Passes/x87StackOptimizationPass.cpp @@ -1180,7 +1180,7 @@ void X87StackOptimization::Run(IREmitter* Emit) { Ref Value {}; if (ReducedPrecisionMode) { - Value = IREmit->_Vector_FToI(OpSize::i64Bit, OpSize::i64Bit, St0, Round_Host); + Value = IREmit->_Vector_FToI(OpSize::i64Bit, OpSize::i64Bit, St0, RoundMode::Host); } else { Value = IREmit->_F80Round(St0); }