diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index 7cf72f8f2..1fe05438c 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -385,7 +385,7 @@ void OpDispatchBuilder::SecondaryALUOp(OpcodeArgs) { } case FEXCore::IR::IROps::OP_OR: { Dest = _AtomicFetchOr(IR::SizeToOpSize(Size), Src, DestMem); - Result = _Or(Dest, Src); + Result = _Or(IR::SizeToOpSize(std::max(4u, std::max(GetOpSize(Dest), GetOpSize(Src)))), Dest, Src); break; } case FEXCore::IR::IROps::OP_AND: { @@ -883,7 +883,7 @@ OrderedNode *OpDispatchBuilder::SelectCC(uint8_t OP, OrderedNode *TrueValue, Ord case 0x6: { // JNA - Jump if CF == 1 || ZC == 1 auto Flag1 = GetRFLAG(FEXCore::X86State::RFLAG_ZF_LOC); auto Flag2 = GetRFLAG(FEXCore::X86State::RFLAG_CF_LOC); - auto Check = _Or(Flag1, Flag2); + auto Check = _Or(IR::SizeToOpSize(std::max(4u, std::max(GetOpSize(Flag1), GetOpSize(Flag2)))), Flag1, Flag2); SrcCond = _Select(FEXCore::IR::COND_EQ, Check, OneConst, TrueValue, FalseValue); break; @@ -891,7 +891,7 @@ OrderedNode *OpDispatchBuilder::SelectCC(uint8_t OP, OrderedNode *TrueValue, Ord case 0x7: { // JA - Jump if CF == 0 && ZF == 0 auto Flag1 = GetRFLAG(FEXCore::X86State::RFLAG_ZF_LOC); auto Flag2 = GetRFLAG(FEXCore::X86State::RFLAG_CF_LOC); - auto Check = _Or(Flag1, Flag2); + auto Check = _Or(IR::SizeToOpSize(std::max(4u, std::max(GetOpSize(Flag1), GetOpSize(Flag2)))), Flag1, Flag2); SrcCond = _Select(FEXCore::IR::COND_EQ, Check, ZeroConst, TrueValue, FalseValue); break; @@ -941,7 +941,7 @@ OrderedNode *OpDispatchBuilder::SelectCC(uint8_t OP, OrderedNode *TrueValue, Ord auto Select2 = _Select(FEXCore::IR::COND_NEQ, Flag2, Flag3, OneConst, ZeroConst); - auto Check = _Or(Select1, Select2); + auto Check = _Or(IR::SizeToOpSize(std::max(4u, std::max(GetOpSize(Select1), GetOpSize(Select2)))), Select1, Select2); SrcCond = _Select(FEXCore::IR::COND_EQ, Check, OneConst, TrueValue, FalseValue); break; @@ -1541,7 +1541,7 @@ void OpDispatchBuilder::SAHFOp(OpcodeArgs) { Src = _Andn(Src, _Constant(0b101000)); // Set the bit that is always set here - Src = _Or(Src, _Constant(0b10)); + Src = _Or(OpSize::i64Bit, Src, _Constant(0b10)); // Store the lower 8 bits in to RFLAGS SetPackedRFLAG(true, Src); @@ -1908,7 +1908,7 @@ void OpDispatchBuilder::SHLDOp(OpcodeArgs) { auto Tmp1 = _Lshl(OpSize::i64Bit, Dest, Shift); auto Tmp2 = _Lshr(Size == 64 ? OpSize::i64Bit : OpSize::i32Bit, Src, ShiftRight); - OrderedNode *Res = _Or(Tmp1, Tmp2); + OrderedNode *Res = _Or(OpSize::i64Bit, Tmp1, Tmp2); // If shift count was zero then output doesn't change // Needs to be checked for the 32bit operand case @@ -1968,7 +1968,7 @@ void OpDispatchBuilder::SHLDImmediateOp(OpcodeArgs) { auto Tmp1 = _Lshl(OpSize::i64Bit, Dest, ShiftLeft); auto Tmp2 = _Lshr(OpSize::i32Bit, Src, ShiftRight); - Res = _Or(Tmp1, Tmp2); + Res = _Or(OpSize::i64Bit, Tmp1, Tmp2); } else { // 32-bit and 64-bit SHLD behaves like an EXTR where the lower bits are filled from the source. @@ -2008,7 +2008,7 @@ void OpDispatchBuilder::SHRDOp(OpcodeArgs) { auto Tmp1 = _Lshr(Size == 64 ? OpSize::i64Bit : OpSize::i32Bit, Dest, Shift); auto Tmp2 = _Lshl(OpSize::i64Bit, Src, ShiftLeft); - OrderedNode *Res = _Or(Tmp1, Tmp2); + OrderedNode *Res = _Or(OpSize::i64Bit, Tmp1, Tmp2); // If shift count was zero then output doesn't change // Needs to be checked for the 32bit operand case @@ -2067,7 +2067,7 @@ void OpDispatchBuilder::SHRDImmediateOp(OpcodeArgs) { auto Tmp1 = _Lshr(Size == 64 ? OpSize::i64Bit : OpSize::i32Bit, Dest, ShiftRight); auto Tmp2 = _Lshl(OpSize::i64Bit, Src, ShiftLeft); - Res = _Or(Tmp1, Tmp2); + Res = _Or(OpSize::i64Bit, Tmp1, Tmp2); } else { // 32-bit and 64-bit SHRD behaves like an EXTR where the upper bits are filled from the source. @@ -2541,7 +2541,7 @@ void OpDispatchBuilder::RCROp1Bit(OpcodeArgs) { OrderedNode *Res = _Bfe(Size - Shift, Shift, Dest); // inject the CF - Res = _Or(Res, _Lshl(OpSize::i32Bit, CF, _Constant(Size, Size - Shift))); + Res = _Or(OpSize::i32Bit, Res, _Lshl(OpSize::i32Bit, CF, _Constant(Size, Size - Shift))); StoreResult(GPRClass, Op, Res, -1); @@ -2612,7 +2612,8 @@ void OpDispatchBuilder::RCROp(OpcodeArgs) { Src, One, TmpHigher, Zero); - Res = _Or(Res, CompareResult); + // TODO: Can use OpSizeFromSrc(Op) + Res = _Or(IR::SizeToOpSize(std::max(4u, std::max(GetOpSize(Res), GetOpSize(CompareResult)))), Res, CompareResult); // If Shift != 0 then we can inject the CF OrderedNode *CFShl = _Sub(_Constant(Size, Size), Src); @@ -2622,7 +2623,8 @@ void OpDispatchBuilder::RCROp(OpcodeArgs) { Src, One, TmpCF, Zero); - Res = _Or(Res, CompareResult); + // TODO: Can use OpSizeFromSrc(Op) + Res = _Or(IR::SizeToOpSize(std::max(4u, std::max(GetOpSize(Res), GetOpSize(CompareResult)))), Res, CompareResult); StoreResult(GPRClass, Op, Res, -1); @@ -2753,7 +2755,7 @@ void OpDispatchBuilder::RCLOp1Bit(OpcodeArgs) { // Rotate left and insert CF in to lowest bit OrderedNode *Res = _Lshl(Size == 64 ? OpSize::i64Bit : OpSize::i32Bit, Dest, _Constant(Size, 1)); - Res = _Or(Res, CF); + Res = _Or(IR::SizeToOpSize(std::max(4u, std::max(GetOpSize(Res), GetOpSize(CF)))), Res, CF); // Our new CF will be the top bit of the source auto NewCF = _Bfe(1, Size - 1, Dest); @@ -2798,7 +2800,8 @@ void OpDispatchBuilder::RCLOp(OpcodeArgs) { Src, One, TmpHigher, Zero); - Res = _Or(Res, CompareResult); + // TODO: Can use OpSizeFromSrc(Op) + Res = _Or(IR::SizeToOpSize(std::max(4u, std::max(GetOpSize(Res), GetOpSize(CompareResult)))), Res, CompareResult); // If Shift != 0 then we can inject the CF OrderedNode *CFShl = _Sub(Src, _Constant(Size, 1)); @@ -2808,7 +2811,8 @@ void OpDispatchBuilder::RCLOp(OpcodeArgs) { Src, One, TmpCF, Zero); - Res = _Or(Res, CompareResult); + // TODO: Can use OpSizeFromSrc(Op) + Res = _Or(IR::SizeToOpSize(std::max(4u, std::max(GetOpSize(Res), GetOpSize(CompareResult)))), Res, CompareResult); StoreResult(GPRClass, Op, Res, -1); @@ -3069,7 +3073,7 @@ void OpDispatchBuilder::BTSOp(OpcodeArgs) { Result = _Lshr(IR::SizeToOpSize(std::max(4u, GetOpSize(Dest))), Dest, BitSelect); OrderedNode *BitMask = _Lshl(OpSize::i64Bit, _Constant(1), BitSelect); - Dest = _Or(Dest, BitMask); + Dest = _Or(OpSize::i64Bit, Dest, BitMask); StoreResult(GPRClass, Op, Dest, -1); } else { // Load the address to the memory location @@ -3099,7 +3103,7 @@ void OpDispatchBuilder::BTSOp(OpcodeArgs) { // Now shift in to the correct bit location Result = _Lshr(IR::SizeToOpSize(std::max(4u, GetOpSize(Value))), Value, BitSelect); - Value = _Or(Value, BitMask); + Value = _Or(OpSize::i64Bit, Value, BitMask); _StoreMemAutoTSO(GPRClass, 1, MemoryLocation, Value, 1); } } @@ -3404,7 +3408,7 @@ void OpDispatchBuilder::DAAOp(OpcodeArgs) { SetRFLAG(_Constant(0)); CalculateDeferredFlags(); - auto Cond = _Or(AF, _Select(FEXCore::IR::COND_UGT, _And(AL, _Constant(0xF)), _Constant(9), _Constant(1), _Constant(0))); + auto Cond = _Or(OpSize::i64Bit, AF, _Select(FEXCore::IR::COND_UGT, _And(AL, _Constant(0xF)), _Constant(9), _Constant(1), _Constant(0))); auto FalseBlock = CreateNewCodeBlockAfter(GetCurrentBlock()); auto TrueBlock = CreateNewCodeBlockAfter(FalseBlock); auto EndBlock = CreateNewCodeBlockAfter(TrueBlock); @@ -3426,14 +3430,14 @@ void OpDispatchBuilder::DAAOp(OpcodeArgs) { // The `CF` variable is the original CF from the start of the operation // The `NewCF` will be _Constant(0) stored aboved. // So Or(CF, _Constant(0)) ill mean CF gets updated to the old value in the true case? - SetRFLAG(_Or(CF, NewCF)); + SetRFLAG(_Or(OpSize::i64Bit, CF, NewCF)); SetRFLAG(_Constant(1)); CalculateDeferredFlags(); _Jump(EndBlock); } SetCurrentCodeBlock(EndBlock); - Cond = _Or(CF, _Select(FEXCore::IR::COND_UGT, AL, _Constant(0x99), _Constant(1), _Constant(0))); + Cond = _Or(OpSize::i64Bit, CF, _Select(FEXCore::IR::COND_UGT, AL, _Constant(0x99), _Constant(1), _Constant(0))); FalseBlock = CreateNewCodeBlockAfter(GetCurrentBlock()); TrueBlock = CreateNewCodeBlockAfter(FalseBlock); EndBlock = CreateNewCodeBlockAfter(TrueBlock); @@ -3472,7 +3476,7 @@ void OpDispatchBuilder::DASOp(OpcodeArgs) { SetRFLAG(_Constant(0)); CalculateDeferredFlags(); - auto Cond = _Or(AF, _Select(FEXCore::IR::COND_UGT, _And(AL, _Constant(0xf)), _Constant(9), _Constant(1), _Constant(0))); + auto Cond = _Or(OpSize::i64Bit, AF, _Select(FEXCore::IR::COND_UGT, _And(AL, _Constant(0xf)), _Constant(9), _Constant(1), _Constant(0))); auto FalseBlock = CreateNewCodeBlockAfter(GetCurrentBlock()); auto TrueBlock = CreateNewCodeBlockAfter(FalseBlock); auto EndBlock = CreateNewCodeBlockAfter(TrueBlock); @@ -3494,14 +3498,14 @@ void OpDispatchBuilder::DASOp(OpcodeArgs) { // The `CF` variable is the original CF from the start of the operation // The `NewCF` will be _Constant(0) stored aboved. // So Or(CF, _Constant(0)) ill mean CF gets updated to the old value in the true case? - SetRFLAG(_Or(CF, NewCF)); + SetRFLAG(_Or(OpSize::i64Bit, CF, NewCF)); SetRFLAG(_Constant(1)); CalculateDeferredFlags(); _Jump(EndBlock); } SetCurrentCodeBlock(EndBlock); - Cond = _Or(CF, _Select(FEXCore::IR::COND_UGT, AL, _Constant(0x99), _Constant(1), _Constant(0))); + Cond = _Or(OpSize::i64Bit, CF, _Select(FEXCore::IR::COND_UGT, AL, _Constant(0x99), _Constant(1), _Constant(0))); FalseBlock = CreateNewCodeBlockAfter(GetCurrentBlock()); TrueBlock = CreateNewCodeBlockAfter(FalseBlock); EndBlock = CreateNewCodeBlockAfter(TrueBlock); @@ -3535,7 +3539,7 @@ void OpDispatchBuilder::AAAOp(OpcodeArgs) { auto AF = GetRFLAG(FEXCore::X86State::RFLAG_AF_LOC); auto AL = LoadGPRRegister(X86State::REG_RAX, 1); auto AX = LoadGPRRegister(X86State::REG_RAX, 2); - auto Cond = _Or(AF, _Select(FEXCore::IR::COND_UGT, _And(AL, _Constant(0xF)), _Constant(9), _Constant(1), _Constant(0))); + auto Cond = _Or(OpSize::i64Bit, AF, _Select(FEXCore::IR::COND_UGT, _And(AL, _Constant(0xF)), _Constant(9), _Constant(1), _Constant(0))); auto FalseBlock = CreateNewCodeBlockAfter(GetCurrentBlock()); auto TrueBlock = CreateNewCodeBlockAfter(FalseBlock); @@ -3570,7 +3574,7 @@ void OpDispatchBuilder::AASOp(OpcodeArgs) { auto AF = GetRFLAG(FEXCore::X86State::RFLAG_AF_LOC); auto AL = LoadGPRRegister(X86State::REG_RAX, 1); auto AX = LoadGPRRegister(X86State::REG_RAX, 2); - auto Cond = _Or(AF, _Select(FEXCore::IR::COND_UGT, _And(AL, _Constant(0xF)), _Constant(9), _Constant(1), _Constant(0))); + auto Cond = _Or(OpSize::i64Bit, AF, _Select(FEXCore::IR::COND_UGT, _And(AL, _Constant(0xF)), _Constant(9), _Constant(1), _Constant(0))); auto FalseBlock = CreateNewCodeBlockAfter(GetCurrentBlock()); auto TrueBlock = CreateNewCodeBlockAfter(FalseBlock); @@ -4314,7 +4318,7 @@ void OpDispatchBuilder::POPFOp(OpcodeArgs) { // Bit 1 is always 1 // Bit 9 is always 1 because we always have interrupts enabled - Src = _Or(Src, _Constant(Size * 8, 0x202)); + Src = _Or(OpSize::i64Bit, Src, _Constant(Size * 8, 0x202)); SetPackedRFLAG(false, Src); } diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.h b/FEXCore/Source/Interface/Core/OpcodeDispatcher.h index e5a269658..0647afa0b 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.h +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.h @@ -581,6 +581,7 @@ public: void VZEROOp(OpcodeArgs); // X87 Ops + OrderedNode *ReconstructFSW(); template void FLD(OpcodeArgs); template diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Flags.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Flags.cpp index a2f64a147..8e09e0aa8 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Flags.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Flags.cpp @@ -163,7 +163,7 @@ OrderedNode *OpDispatchBuilder::GetPackedRFLAG(uint32_t FlagsMask) { // The constant is OR'ed in at the end, to avoid a pointless or xzr, #2. if ((1U << X86State::RFLAG_RESERVED_LOC) & FlagsMask) - Original = _Or(Original, _Constant(2)); + Original = _Or(OpSize::i64Bit, Original, _Constant(2)); return Original; } diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp index 5a4050835..1297601f2 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp @@ -812,7 +812,7 @@ void OpDispatchBuilder::MOVMSKOp(OpcodeArgs) { Tmp = _Lshl(IR::SizeToOpSize(ElementSize), Tmp, _Constant(i)); // Or it with the current value - CurrentVal = _Or(CurrentVal, Tmp); + CurrentVal = _Or(OpSize::i64Bit, CurrentVal, Tmp); } StoreResult(GPRClass, Op, CurrentVal, -1); } @@ -2613,23 +2613,8 @@ void OpDispatchBuilder::SaveX87State(OpcodeArgs, OrderedNode *MemBase) { } { - // We must construct the FSW from our various bits - // TODO: This should use BFI OrderedNode *MemLocation = _Add(MemBase, _Constant(2)); - OrderedNode *FSW = _Constant(0); - auto Top = GetX87Top(); - FSW = _Or(FSW, _Lshl(OpSize::i32Bit, Top, _Constant(11))); - - auto C0 = GetRFLAG(FEXCore::X86State::X87FLAG_C0_LOC); - auto C1 = GetRFLAG(FEXCore::X86State::X87FLAG_C1_LOC); - auto C2 = GetRFLAG(FEXCore::X86State::X87FLAG_C2_LOC); - auto C3 = GetRFLAG(FEXCore::X86State::X87FLAG_C3_LOC); - - FSW = _Or(FSW, _Lshl(OpSize::i32Bit, C0, _Constant(8))); - FSW = _Or(FSW, _Lshl(OpSize::i32Bit, C1, _Constant(9))); - FSW = _Or(FSW, _Lshl(OpSize::i32Bit, C2, _Constant(10))); - FSW = _Or(FSW, _Lshl(OpSize::i32Bit, C3, _Constant(14))); - _StoreMem(GPRClass, 2, MemLocation, FSW, 2); + _StoreMem(GPRClass, 2, MemLocation, ReconstructFSW(), 2); } { diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher/X87.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher/X87.cpp index 4087e3680..ad6ae374f 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher/X87.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher/X87.cpp @@ -38,7 +38,7 @@ void OpDispatchBuilder::SetX87TopTag(OrderedNode *Value, X87Tag Tag) { OrderedNode *NewFTW = _Andn(FTW, Mask); if (Tag != X87Tag::Valid) { auto TagVal = _Lshl(OpSize::i64Bit, _Constant(ToUnderlying(Tag)), TopOffset); - NewFTW = _Or(NewFTW, TagVal); + NewFTW = _Or(OpSize::i64Bit, NewFTW, TagVal); } _StoreContext(2, GPRClass, NewFTW, offsetof(FEXCore::Core::CPUState, FTW)); @@ -56,6 +56,25 @@ void OpDispatchBuilder::SetX87Top(OrderedNode *Value) { _StoreContext(1, GPRClass, Value, offsetof(FEXCore::Core::CPUState, flags) + FEXCore::X86State::X87FLAG_TOP_LOC); } +OrderedNode *OpDispatchBuilder::ReconstructFSW() { + // We must construct the FSW from our various bits + // TODO: These should use BFI + OrderedNode *FSW = _Constant(0); + auto Top = GetX87Top(); + FSW = _Or(OpSize::i64Bit, FSW, _Lshl(OpSize::i32Bit, Top, _Constant(11))); + + auto C0 = GetRFLAG(FEXCore::X86State::X87FLAG_C0_LOC); + auto C1 = GetRFLAG(FEXCore::X86State::X87FLAG_C1_LOC); + auto C2 = GetRFLAG(FEXCore::X86State::X87FLAG_C2_LOC); + auto C3 = GetRFLAG(FEXCore::X86State::X87FLAG_C3_LOC); + + FSW = _Or(OpSize::i64Bit, FSW, _Lshl(OpSize::i32Bit, C0, _Constant(8))); + FSW = _Or(OpSize::i64Bit, FSW, _Lshl(OpSize::i32Bit, C1, _Constant(9))); + FSW = _Or(OpSize::i64Bit, FSW, _Lshl(OpSize::i32Bit, C2, _Constant(10))); + FSW = _Or(OpSize::i64Bit, FSW, _Lshl(OpSize::i32Bit, C3, _Constant(14))); + return FSW; +} + template void OpDispatchBuilder::FLD(OpcodeArgs) { // Update TOP @@ -187,7 +206,7 @@ void OpDispatchBuilder::FILD(OpcodeArgs) { auto adjusted_exponent = _Sub(_Constant(0x3fff + 63), shift); auto zeroed_exponent = _Select(COND_EQ, absolute, zero, zero, adjusted_exponent); - auto upper = _Or(sign, zeroed_exponent); + auto upper = _Or(OpSize::i64Bit, sign, zeroed_exponent); OrderedNode *converted = _VCastFromGPR(16, 8, shifted); @@ -588,8 +607,8 @@ void OpDispatchBuilder::FTST(OpcodeArgs) { OrderedNode *HostFlag_CF = _GetHostFlag(Res, FCMP_FLAG_LT); OrderedNode *HostFlag_ZF = _GetHostFlag(Res, FCMP_FLAG_EQ); OrderedNode *HostFlag_Unordered = _GetHostFlag(Res, FCMP_FLAG_UNORDERED); - HostFlag_CF = _Or(HostFlag_CF, HostFlag_Unordered); - HostFlag_ZF = _Or(HostFlag_ZF, HostFlag_Unordered); + HostFlag_CF = _Or(OpSize::i32Bit, HostFlag_CF, HostFlag_Unordered); + HostFlag_ZF = _Or(OpSize::i32Bit, HostFlag_ZF, HostFlag_Unordered); SetRFLAG(HostFlag_CF); SetRFLAG(_Constant(0)); @@ -679,8 +698,8 @@ void OpDispatchBuilder::FCOMI(OpcodeArgs) { OrderedNode *HostFlag_CF = _GetHostFlag(Res, FCMP_FLAG_LT); OrderedNode *HostFlag_ZF = _GetHostFlag(Res, FCMP_FLAG_EQ); OrderedNode *HostFlag_Unordered = _GetHostFlag(Res, FCMP_FLAG_UNORDERED); - HostFlag_CF = _Or(HostFlag_CF, HostFlag_Unordered); - HostFlag_ZF = _Or(HostFlag_ZF, HostFlag_Unordered); + HostFlag_CF = _Or(OpSize::i32Bit, HostFlag_CF, HostFlag_Unordered); + HostFlag_ZF = _Or(OpSize::i32Bit, HostFlag_ZF, HostFlag_Unordered); if constexpr (whichflags == FCOMIFlags::FLAGS_X87) { SetRFLAG(HostFlag_CF); @@ -1003,22 +1022,7 @@ void OpDispatchBuilder::X87FNSTENV(OpcodeArgs) { { OrderedNode *MemLocation = _Add(Mem, _Constant(Size * 1)); - // We must construct the FSW from our various bits - // TODO: These should use BFI - OrderedNode *FSW = _Constant(0); - auto Top = GetX87Top(); - FSW = _Or(FSW, _Lshl(OpSize::i32Bit, Top, _Constant(11))); - - auto C0 = GetRFLAG(FEXCore::X86State::X87FLAG_C0_LOC); - auto C1 = GetRFLAG(FEXCore::X86State::X87FLAG_C1_LOC); - auto C2 = GetRFLAG(FEXCore::X86State::X87FLAG_C2_LOC); - auto C3 = GetRFLAG(FEXCore::X86State::X87FLAG_C3_LOC); - - FSW = _Or(FSW, _Lshl(OpSize::i32Bit, C0, _Constant(8))); - FSW = _Or(FSW, _Lshl(OpSize::i32Bit, C1, _Constant(9))); - FSW = _Or(FSW, _Lshl(OpSize::i32Bit, C2, _Constant(10))); - FSW = _Or(FSW, _Lshl(OpSize::i32Bit, C3, _Constant(14))); - _StoreMem(GPRClass, Size, MemLocation, FSW, Size); + _StoreMem(GPRClass, Size, MemLocation, ReconstructFSW(), Size); } auto ZeroConst = _Constant(0); @@ -1085,23 +1089,7 @@ void OpDispatchBuilder::X87LDSW(OpcodeArgs) { } void OpDispatchBuilder::X87FNSTSW(OpcodeArgs) { - // We must construct the FSW from our various bits - // TODO: These should use BFI - OrderedNode *FSW = _Constant(0); - auto Top = GetX87Top(); - FSW = _Or(FSW, _Lshl(OpSize::i32Bit, Top, _Constant(11))); - - auto C0 = GetRFLAG(FEXCore::X86State::X87FLAG_C0_LOC); - auto C1 = GetRFLAG(FEXCore::X86State::X87FLAG_C1_LOC); - auto C2 = GetRFLAG(FEXCore::X86State::X87FLAG_C2_LOC); - auto C3 = GetRFLAG(FEXCore::X86State::X87FLAG_C3_LOC); - - FSW = _Or(FSW, _Lshl(OpSize::i32Bit, C0, _Constant(8))); - FSW = _Or(FSW, _Lshl(OpSize::i32Bit, C1, _Constant(9))); - FSW = _Or(FSW, _Lshl(OpSize::i32Bit, C2, _Constant(10))); - FSW = _Or(FSW, _Lshl(OpSize::i32Bit, C3, _Constant(14))); - - StoreResult(GPRClass, Op, FSW, -1); + StoreResult(GPRClass, Op, ReconstructFSW(), -1); } void OpDispatchBuilder::X87FNSAVE(OpcodeArgs) { @@ -1136,21 +1124,7 @@ void OpDispatchBuilder::X87FNSAVE(OpcodeArgs) { { OrderedNode *MemLocation = _Add(Mem, _Constant(Size * 1)); - // We must construct the FSW from our various bits - // TODO: These should use BFI - OrderedNode *FSW = _Constant(0); - FSW = _Or(FSW, _Lshl(OpSize::i32Bit, Top, _Constant(11))); - - auto C0 = GetRFLAG(FEXCore::X86State::X87FLAG_C0_LOC); - auto C1 = GetRFLAG(FEXCore::X86State::X87FLAG_C1_LOC); - auto C2 = GetRFLAG(FEXCore::X86State::X87FLAG_C2_LOC); - auto C3 = GetRFLAG(FEXCore::X86State::X87FLAG_C3_LOC); - - FSW = _Or(FSW, _Lshl(OpSize::i32Bit, C0, _Constant(8))); - FSW = _Or(FSW, _Lshl(OpSize::i32Bit, C1, _Constant(9))); - FSW = _Or(FSW, _Lshl(OpSize::i32Bit, C2, _Constant(10))); - FSW = _Or(FSW, _Lshl(OpSize::i32Bit, C3, _Constant(14))); - _StoreMem(GPRClass, Size, MemLocation, FSW, Size); + _StoreMem(GPRClass, Size, MemLocation, ReconstructFSW(), Size); } auto ZeroConst = _Constant(0); diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher/X87F64.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher/X87F64.cpp index fa2496bf9..e4e4063f3 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher/X87F64.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher/X87F64.cpp @@ -635,8 +635,8 @@ void OpDispatchBuilder::FTSTF64(OpcodeArgs) { OrderedNode *HostFlag_CF = _GetHostFlag(Res, FCMP_FLAG_LT); OrderedNode *HostFlag_ZF = _GetHostFlag(Res, FCMP_FLAG_EQ); OrderedNode *HostFlag_Unordered = _GetHostFlag(Res, FCMP_FLAG_UNORDERED); - HostFlag_CF = _Or(HostFlag_CF, HostFlag_Unordered); - HostFlag_ZF = _Or(HostFlag_ZF, HostFlag_Unordered); + HostFlag_CF = _Or(OpSize::i32Bit, HostFlag_CF, HostFlag_Unordered); + HostFlag_ZF = _Or(OpSize::i32Bit, HostFlag_ZF, HostFlag_Unordered); SetRFLAG(HostFlag_CF); SetRFLAG(_Constant(0)); @@ -668,7 +668,7 @@ void OpDispatchBuilder::FXTRACTF64(OpcodeArgs) { exp = _Sub(exp, _Constant(1023)); exp = _Float_FromGPR_S(8, 8, exp); OrderedNode* sig = _And(gpr, _Constant(0x800fffffffffffffLL)); - sig = _Or(sig, _Constant(0x3ff0000000000000LL)); + sig = _Or(OpSize::i64Bit, sig, _Constant(0x3ff0000000000000LL)); sig = _VCastFromGPR(8, 8, sig); // Write to ST[TOP] _StoreContextIndexed(exp, orig_top, 8, MMBaseOffset(), 16, FPRClass); @@ -716,8 +716,8 @@ void OpDispatchBuilder::FCOMIF64(OpcodeArgs) { OrderedNode *HostFlag_ZF = _GetHostFlag(Res, FCMP_FLAG_EQ); OrderedNode *HostFlag_Unordered = _GetHostFlag(Res, FCMP_FLAG_UNORDERED); - HostFlag_CF = _Or(HostFlag_CF, HostFlag_Unordered); - HostFlag_ZF = _Or(HostFlag_ZF, HostFlag_Unordered); + HostFlag_CF = _Or(OpSize::i32Bit, HostFlag_CF, HostFlag_Unordered); + HostFlag_ZF = _Or(OpSize::i32Bit, HostFlag_ZF, HostFlag_Unordered); if constexpr (whichflags == FCOMIFlags::FLAGS_X87) { SetRFLAG(HostFlag_CF); @@ -954,21 +954,7 @@ void OpDispatchBuilder::X87FNSAVEF64(OpcodeArgs) { { OrderedNode *MemLocation = _Add(Mem, _Constant(Size * 1)); - // We must construct the FSW from our various bits - // TODO: These should use BFI - OrderedNode *FSW = _Constant(0); - FSW = _Or(FSW, _Lshl(OpSize::i32Bit, Top, _Constant(11))); - - auto C0 = GetRFLAG(FEXCore::X86State::X87FLAG_C0_LOC); - auto C1 = GetRFLAG(FEXCore::X86State::X87FLAG_C1_LOC); - auto C2 = GetRFLAG(FEXCore::X86State::X87FLAG_C2_LOC); - auto C3 = GetRFLAG(FEXCore::X86State::X87FLAG_C3_LOC); - - FSW = _Or(FSW, _Lshl(OpSize::i32Bit, C0, _Constant(8))); - FSW = _Or(FSW, _Lshl(OpSize::i32Bit, C1, _Constant(9))); - FSW = _Or(FSW, _Lshl(OpSize::i32Bit, C2, _Constant(10))); - FSW = _Or(FSW, _Lshl(OpSize::i32Bit, C3, _Constant(14))); - _StoreMem(GPRClass, Size, MemLocation, FSW, Size); + _StoreMem(GPRClass, Size, MemLocation, ReconstructFSW(), Size); } auto ZeroConst = _Constant(0); diff --git a/FEXCore/Source/Interface/IR/Passes/ConstProp.cpp b/FEXCore/Source/Interface/IR/Passes/ConstProp.cpp index 082d71aa2..da2e96ccf 100644 --- a/FEXCore/Source/Interface/IR/Passes/ConstProp.cpp +++ b/FEXCore/Source/Interface/IR/Passes/ConstProp.cpp @@ -904,8 +904,7 @@ bool ConstProp::ConstantPropagation(IREmitter *IREmit, const IRListView& Current uint64_t NewConstant = SourceMask << Op->lsb; if (ConstantSrc & 1) { - auto orr = IREmit->_Or(CurrentIR.GetNode(Op->Header.Args[0]), IREmit->_Constant(NewConstant)); - orr.first->Header.Size = IROp->Size; + auto orr = IREmit->_Or(IR::SizeToOpSize(IROp->Size), CurrentIR.GetNode(Op->Header.Args[0]), IREmit->_Constant(NewConstant)); IREmit->ReplaceAllUsesWith(CodeNode, orr); Changed = true; } diff --git a/FEXCore/include/FEXCore/IR/IREmitter.h b/FEXCore/include/FEXCore/IR/IREmitter.h index 7cac987b3..3832fdd51 100644 --- a/FEXCore/include/FEXCore/IR/IREmitter.h +++ b/FEXCore/include/FEXCore/IR/IREmitter.h @@ -99,9 +99,6 @@ friend class FEXCore::IR::PassManager; IRPair _Sub(OrderedNode *_Src1, OrderedNode *_Src2) { return _Sub(static_cast(std::max(4, std::max(GetOpSize(_Src1), GetOpSize(_Src2)))), _Src1, _Src2); } - IRPair _Or(OrderedNode *_Src1, OrderedNode *_Src2) { - return _Or(static_cast(std::max(GetOpSize(_Src1), GetOpSize(_Src2))), _Src1, _Src2); - } IRPair _Xor(OrderedNode *_Src1, OrderedNode *_Src2) { return _Xor(static_cast(std::max(4, std::max(GetOpSize(_Src1), GetOpSize(_Src2)))), _Src1, _Src2); }