diff --git a/FEXCore/Source/Interface/Core/Addressing.cpp b/FEXCore/Source/Interface/Core/Addressing.cpp index 8848dcba96..85fb7dcab3 100644 --- a/FEXCore/Source/Interface/Core/Addressing.cpp +++ b/FEXCore/Source/Interface/Core/Addressing.cpp @@ -11,7 +11,7 @@ Ref LoadEffectiveAddress(IREmitter* IREmit, const AddressMode& A, IR::OpSize GPR Ref Tmp = A.Base; if (A.Offset) { - Tmp = Tmp ? IREmit->Add(GPRSize, Tmp, A.Offset) : IREmit->Constant(A.Offset); + Tmp = Tmp ? IREmit->Add(GPRSize, Tmp, A.Offset) : IREmit->Constant(A.Offset, IR::ConstPad::NoPad); } if (A.Index) { @@ -21,7 +21,7 @@ Ref LoadEffectiveAddress(IREmitter* IREmit, const AddressMode& A, IR::OpSize GPR if (Tmp) { Tmp = IREmit->_AddShift(GPRSize, Tmp, A.Index, ShiftType::LSL, Log2); } else { - Tmp = IREmit->_Lshl(GPRSize, A.Index, IREmit->Constant(Log2)); + Tmp = IREmit->_Lshl(GPRSize, A.Index, IREmit->Constant(Log2, IR::ConstPad::NoPad)); } } else { Tmp = Tmp ? IREmit->Add(GPRSize, Tmp, A.Index) : A.Index; @@ -40,7 +40,7 @@ Ref LoadEffectiveAddress(IREmitter* IREmit, const AddressMode& A, IR::OpSize GPR } else if (A.Offset) { uint64_t X = A.Offset; X &= (1ull << Bits) - 1; - Tmp = IREmit->Constant(X); + Tmp = IREmit->Constant(X, IR::ConstPad::NoPad); } } @@ -48,7 +48,7 @@ Ref LoadEffectiveAddress(IREmitter* IREmit, const AddressMode& A, IR::OpSize GPR Tmp = Tmp ? IREmit->Add(GPRSize, Tmp, A.Segment) : A.Segment; } - return Tmp ?: IREmit->Constant(0); + return Tmp ?: IREmit->Constant(0, IR::ConstPad::NoPad); } AddressMode SelectAddressMode(IREmitter* IREmit, const AddressMode& A, IR::OpSize GPRSize, bool HostSupportsTSOImm9, bool AtomicTSO, @@ -102,7 +102,7 @@ AddressMode SelectAddressMode(IREmitter* IREmit, const AddressMode& A, IR::OpSiz return { .Base = LoadEffectiveAddress(IREmit, B, GPRSize, true /* AddSegmentBase */, false), - .Index = IREmit->Constant(A.Offset), + .Index = IREmit->Constant(A.Offset, ConstPad::NoPad), .IndexType = MemOffsetType::SXTX, .IndexScale = 1, }; @@ -135,7 +135,7 @@ AddressMode SelectAddressMode(IREmitter* IREmit, const AddressMode& A, IR::OpSiz return { .Base = LoadEffectiveAddress(IREmit, B, GPRSize, true /* AddSegmentBase */, false), - .Index = IREmit->Constant(A.Offset), + .Index = IREmit->Constant(A.Offset, ConstPad::NoPad), .IndexType = MemOffsetType::SXTX, .IndexScale = 1, }; diff --git a/FEXCore/Source/Interface/Core/Core.cpp b/FEXCore/Source/Interface/Core/Core.cpp index 28219f924a..a2aaca7db2 100644 --- a/FEXCore/Source/Interface/Core/Core.cpp +++ b/FEXCore/Source/Interface/Core/Core.cpp @@ -968,14 +968,17 @@ void ContextImpl::AddThunkTrampolineIRHandler(uintptr_t Entrypoint, uintptr_t Gu const auto GPRSize = this->Config.Is64BitMode ? IR::OpSize::i64Bit : IR::OpSize::i32Bit; + // Thunk entry-points don't get cached, don't need to be padded. if (GPRSize == IR::OpSize::i64Bit) { - IR::Ref R = emit->_StoreRegister(emit->Constant(Entrypoint), GPRSize); + IR::Ref R = emit->_StoreRegister(emit->Constant(Entrypoint, IR::ConstPad::NoPad), GPRSize); R->Reg = IR::PhysicalRegister(IR::RegClass::GPRFixed, X86State::REG_R11).Raw; } else { - emit->_StoreContextFPR(GPRSize, emit->_VCastFromGPR(IR::OpSize::i64Bit, IR::OpSize::i64Bit, emit->Constant(Entrypoint)), + emit->_StoreContextFPR(GPRSize, + emit->_VCastFromGPR(IR::OpSize::i64Bit, IR::OpSize::i64Bit, emit->Constant(Entrypoint, IR::ConstPad::NoPad)), offsetof(Core::CPUState, mm[0][0])); } - emit->_ExitFunction(IR::OpSize::i64Bit, emit->Constant(GuestThunkEntrypoint), IR::BranchHint::None, emit->Invalid(), emit->Invalid()); + emit->_ExitFunction(IR::OpSize::i64Bit, emit->Constant(GuestThunkEntrypoint, IR::ConstPad::NoPad), IR::BranchHint::None, + emit->Invalid(), emit->Invalid()); }, ThunkHandler, (void*)GuestThunkEntrypoint); diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index dea7d4c630..369a94ee48 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -475,7 +475,8 @@ void OpDispatchBuilder::POPSegmentOp(OpcodeArgs, uint32_t SegmentReg) { break; case FEXCore::X86Tables::DecodeFlags::FLAG_SS_PREFIX: // Unset the 'active' bit in the packed TF, skipping the single step exception after this instruction - SetRFLAG(_And(OpSize::i32Bit, GetRFLAG(FEXCore::X86State::RFLAG_TF_RAW_LOC), Constant(1))); + SetRFLAG( + _And(OpSize::i32Bit, GetRFLAG(FEXCore::X86State::RFLAG_TF_RAW_LOC), Constant(1, ConstPad::NoPad))); _StoreContextGPR(DstSize, NewSegment, offsetof(FEXCore::Core::CPUState, ss_idx)); break; case FEXCore::X86Tables::DecodeFlags::FLAG_DS_PREFIX: @@ -1168,7 +1169,7 @@ void OpDispatchBuilder::SAHFOp(OpcodeArgs) { Ref Src = LoadGPRRegister(X86State::REG_RAX, OpSize::i8Bit, 8); // Clear bits that aren't supposed to be set - Src = _Andn(OpSize::i64Bit, Src, Constant(0b101000)); + Src = _Andn(OpSize::i64Bit, Src, Constant(0b101000, ConstPad::NoPad)); // Set the bit that is always set here Src = _Or(OpSize::i64Bit, Src, _InlineConstant(0b10)); @@ -1193,17 +1194,17 @@ void OpDispatchBuilder::FLAGControlOp(OpcodeArgs) { CarryInvert(); break; case 0xF8: // CLC - SetCFInverted(Constant(1)); + SetCFInverted(Constant(1, ConstPad::NoPad)); break; case 0xF9: // STC - SetCFInverted(Constant(0)); + SetCFInverted(Constant(0, ConstPad::NoPad)); break; case 0xFC: // CLD // Transformed - StoreDF(Constant(1)); + StoreDF(Constant(1, ConstPad::NoPad)); break; case 0xFD: // STD - StoreDF(Constant(-1)); + StoreDF(Constant(-1, ConstPad::NoPad)); break; } } @@ -1299,7 +1300,7 @@ void OpDispatchBuilder::MOVSegOp(OpcodeArgs, bool ToSeg) { case FEXCore::X86State::REG_RBP: // GS case FEXCore::X86State::REG_R13: // GS if (Is64BitMode) { - Segment = Constant(0); + Segment = Constant(0, ConstPad::NoPad); } else { Segment = _LoadContextGPR(OpSize::i16Bit, offsetof(FEXCore::Core::CPUState, gs_idx)); } @@ -1307,7 +1308,7 @@ void OpDispatchBuilder::MOVSegOp(OpcodeArgs, bool ToSeg) { case FEXCore::X86State::REG_RSP: // FS case FEXCore::X86State::REG_R12: // FS if (Is64BitMode) { - Segment = Constant(0); + Segment = Constant(0, ConstPad::NoPad); } else { Segment = _LoadContextGPR(OpSize::i16Bit, offsetof(FEXCore::Core::CPUState, fs_idx)); } @@ -1405,7 +1406,7 @@ void OpDispatchBuilder::SHLImmediateOp(OpcodeArgs, bool SHL1Bit) { uint64_t Shift = GetConstantShift(Op, SHL1Bit); const auto Size = GetSrcBitSize(Op); - Ref Result = _Lshl(Size == 64 ? OpSize::i64Bit : OpSize::i32Bit, Dest, Constant(Shift)); + Ref Result = _Lshl(Size == 64 ? OpSize::i64Bit : OpSize::i32Bit, Dest, Constant(Shift, ConstPad::NoPad)); CalculateFlags_ShiftLeftImmediate(OpSizeFromSrc(Op), Result, Dest, Shift); CalculateDeferredFlags(); @@ -1426,7 +1427,7 @@ void OpDispatchBuilder::SHRImmediateOp(OpcodeArgs, bool SHR1Bit) { auto Dest = LoadSourceGPR(Op, Op->Dest, Op->Flags, {.AllowUpperGarbage = Size >= 32}); uint64_t Shift = GetConstantShift(Op, SHR1Bit); - auto ALUOp = _Lshr(Size == 64 ? OpSize::i64Bit : OpSize::i32Bit, Dest, Constant(Shift)); + auto ALUOp = _Lshr(Size == 64 ? OpSize::i64Bit : OpSize::i32Bit, Dest, Constant(Shift, ConstPad::NoPad)); CalculateFlags_ShiftRightImmediate(OpSizeFromSrc(Op), ALUOp, Dest, Shift); CalculateDeferredFlags(); @@ -1455,7 +1456,7 @@ void OpDispatchBuilder::SHLDOp(OpcodeArgs) { // a64 masks the bottom bits, so if we're using a native 32/64-bit shift, we // can negate to do the subtract (it's congruent), which saves a constant. - auto ShiftRight = Size >= 32 ? _Neg(OpSize::i64Bit, Shift) : Sub(OpSize::i64Bit, Constant(Size), Shift); + auto ShiftRight = Size >= 32 ? _Neg(OpSize::i64Bit, Shift) : Sub(OpSize::i64Bit, Constant(Size, ConstPad::NoPad), Shift); auto Tmp1 = _Lshl(OpSize::i64Bit, Dest, Shift); auto Tmp2 = _Lshr(Size == 64 ? OpSize::i64Bit : OpSize::i32Bit, Src, ShiftRight); @@ -1471,7 +1472,7 @@ void OpDispatchBuilder::SHLDOp(OpcodeArgs) { // // TODO: This whole function wants to be wrapped in the if. Maybe b/w pass is // a good idea after all. - Res = _Select(OpSize::i64Bit, OpSize::i64Bit, CondClass::EQ, Shift, Constant(0), Dest, Res); + Res = _Select(OpSize::i64Bit, OpSize::i64Bit, CondClass::EQ, Shift, Constant(0, ConstPad::NoPad), Dest, Res); HandleShift(Op, Res, Dest, ShiftType::LSL, Shift); } @@ -1486,11 +1487,11 @@ void OpDispatchBuilder::SHLDImmediateOp(OpcodeArgs) { if (Shift != 0) { Ref Res {}; if (Size < 32) { - Ref ShiftLeft = Constant(Shift); + Ref ShiftLeft = Constant(Shift, ConstPad::NoPad); auto ShiftRight = Size - Shift; auto Tmp1 = _Lshl(OpSize::i64Bit, Dest, ShiftLeft); - Ref Tmp2 = ShiftRight ? _Lshr(OpSize::i32Bit, Src, Constant(ShiftRight)) : Src; + Ref Tmp2 = ShiftRight ? _Lshr(OpSize::i32Bit, Src, Constant(ShiftRight, ConstPad::NoPad)) : Src; Res = _Or(OpSize::i64Bit, Tmp1, Tmp2); } else { @@ -1526,7 +1527,7 @@ void OpDispatchBuilder::SHRDOp(OpcodeArgs) { Shift = _And(OpSize::i64Bit, Shift, _InlineConstant(0x1F)); } - auto ShiftLeft = Sub(OpSize::i64Bit, Constant(Size), Shift); + auto ShiftLeft = Sub(OpSize::i64Bit, Constant(Size, ConstPad::NoPad), Shift); auto Tmp1 = _Lshr(Size == 64 ? OpSize::i64Bit : OpSize::i32Bit, Dest, Shift); auto Tmp2 = _Lshl(OpSize::i64Bit, Src, ShiftLeft); @@ -1536,7 +1537,7 @@ void OpDispatchBuilder::SHRDOp(OpcodeArgs) { // If shift count was zero then output doesn't change // Needs to be checked for the 32bit operand case // where shift = 0 and the source register still gets Zext - Res = _Select(OpSize::i64Bit, OpSize::i64Bit, CondClass::EQ, Shift, Constant(0), Dest, Res); + Res = _Select(OpSize::i64Bit, OpSize::i64Bit, CondClass::EQ, Shift, Constant(0, ConstPad::NoPad), Dest, Res); HandleShift(Op, Res, Dest, ShiftType::LSR, Shift); } @@ -1551,8 +1552,8 @@ void OpDispatchBuilder::SHRDImmediateOp(OpcodeArgs) { if (Shift != 0) { Ref Res {}; if (Size < 32) { - Ref ShiftRight = Constant(Shift); - auto ShiftLeft = Constant(Size - Shift); + Ref ShiftRight = Constant(Shift, ConstPad::NoPad); + auto ShiftLeft = Constant(Size - Shift, ConstPad::NoPad); auto Tmp1 = _Lshr(OpSize::i32Bit, Dest, ShiftRight); auto Tmp2 = _Lshl(OpSize::i64Bit, Src, ShiftLeft); @@ -1587,7 +1588,7 @@ void OpDispatchBuilder::ASHROp(OpcodeArgs, bool Immediate, bool SHR1Bit) { if (Immediate) { uint64_t Shift = GetConstantShift(Op, SHR1Bit); - Ref Result = _Ashr(OpSize, Dest, Constant(Shift)); + Ref Result = _Ashr(OpSize, Dest, Constant(Shift, ConstPad::NoPad)); CalculateFlags_SignShiftRightImmediate(OpSizeFromSrc(Op), Result, Dest, Shift); CalculateDeferredFlags(); @@ -1681,21 +1682,21 @@ void OpDispatchBuilder::BEXTRBMIOp(OpcodeArgs) { const auto Size = OpSizeFromSrc(Op); const auto SrcSize = IR::OpSizeAsBits(Size); const auto MaxSrcBit = SrcSize - 1; - auto MaxSrcBitOp = Constant(MaxSrcBit); + auto MaxSrcBitOp = Constant(MaxSrcBit, ConstPad::NoPad); // Shift the operand down to the starting bit auto Start = _Bfe(OpSizeFromSrc(Op), 8, 0, Src2); auto Shifted = _Lshr(Size, Src1, Start); // Shifts larger than operand size need to be set to zero. - auto SanitizedShifted = _Select(Size, Size, CondClass::ULE, Start, MaxSrcBitOp, Shifted, Constant(0)); + auto SanitizedShifted = _Select(Size, Size, CondClass::ULE, Start, MaxSrcBitOp, Shifted, Constant(0, ConstPad::NoPad)); // Now handle the length specifier. auto Length = _Bfe(Size, 8, 8, Src2); // Now build up the mask // (1 << Length) - 1 = ~(~0 << Length) - auto AllOnes = Constant(~0ull); + auto AllOnes = Constant(~0ull, ConstPad::NoPad); auto InvertedMask = _Lshl(Size, AllOnes, Length); // Now put it all together and make the result. @@ -1810,7 +1811,7 @@ void OpDispatchBuilder::BZHI(OpcodeArgs) { // Clear the high bits specified by the index. A64 only considers bottom bits // of the shift, so we don't need to mask bottom 8-bits ourselves. // Out-of-bounds results ignored after. - auto Mask = _Lshl(Size, Constant(-1), Index); + auto Mask = _Lshl(Size, Constant(-1, ConstPad::NoPad), Index); auto MaskResult = _Andn(Size, Src, Mask); // If the index is above OperandSize, we don't clear anything. BZHI only @@ -1819,7 +1820,7 @@ void OpDispatchBuilder::BZHI(OpcodeArgs) { // // Because we're clobbering flags internally we ignore all carry invert // shenanigans and use the raw versions here. - _TestNZ(OpSize::i64Bit, Index, Constant(0xFF & ~(OperandSize - 1))); + _TestNZ(OpSize::i64Bit, Index, Constant(0xFF & ~(OperandSize - 1), ConstPad::NoPad)); auto Result = _NZCVSelect(Size, CondClass::NEQ, Src, MaskResult); StoreResultGPR(Op, Result); @@ -1913,7 +1914,7 @@ void OpDispatchBuilder::ADXOp(OpcodeArgs) { // Handles ADCX and ADOX const bool IsADCX = Op->OP == 0x1F6; - auto Zero = Constant(0); + auto Zero = Constant(0, ConstPad::NoPad); // Before we go trashing NZCV, save the current NZCV state. Ref OldNZCV = GetNZCV(); @@ -2333,7 +2334,7 @@ void OpDispatchBuilder::RCLSmallerOp(OpcodeArgs) { auto CF = GetRFLAG(FEXCore::X86State::RFLAG_CF_RAW_LOC); - Ref Tmp = Constant(0); + Ref Tmp = Constant(0, ConstPad::NoPad); for (size_t i = 0; i < (32 + Size + 1); i += (Size + 1)) { // Insert incoming value @@ -2712,9 +2713,9 @@ void OpDispatchBuilder::NOTOp(OpcodeArgs) { Ref MaskConst {}; if (Size == OpSize::i64Bit) { - MaskConst = Constant(~0ULL); + MaskConst = Constant(~0ULL, ConstPad::NoPad); } else { - MaskConst = Constant((1ULL << SizeBits) - 1); + MaskConst = Constant((1ULL << SizeBits) - 1, ConstPad::NoPad); } if (DestIsLockedMem(Op)) { @@ -2733,7 +2734,7 @@ void OpDispatchBuilder::NOTOp(OpcodeArgs) { auto Dest = Op->Dest; if (Dest.Data.GPR.HighBits) { LOGMAN_THROW_A_FMT(Size == OpSize::i8Bit, "Only 8-bit GPRs get high bits"); - MaskConst = Constant(0xFF00); + MaskConst = Constant(0xFF00, ConstPad::NoPad); Dest.Data.GPR.HighBits = false; } @@ -2795,8 +2796,8 @@ void OpDispatchBuilder::PopcountOp(OpcodeArgs) { } Ref OpDispatchBuilder::CalculateAFForDecimal(Ref A) { - auto Nibble = _And(OpSize::i64Bit, A, Constant(0xF)); - auto Greater = Select01(OpSize::i64Bit, CondClass::UGT, Nibble, Constant(9)); + auto Nibble = _And(OpSize::i64Bit, A, Constant(0xF, ConstPad::NoPad)); + auto Greater = Select01(OpSize::i64Bit, CondClass::UGT, Nibble, Constant(9, ConstPad::NoPad)); return _Or(OpSize::i64Bit, LoadAF(), Greater); } @@ -2808,13 +2809,13 @@ void OpDispatchBuilder::DAAOp(OpcodeArgs) { auto AF = CalculateAFForDecimal(AL); // CF |= (AL > 0x99); - CFInv = _And(OpSize::i64Bit, CFInv, Select01(OpSize::i64Bit, CondClass::ULE, AL, Constant(0x99))); + CFInv = _And(OpSize::i64Bit, CFInv, Select01(OpSize::i64Bit, CondClass::ULE, AL, Constant(0x99, ConstPad::NoPad))); // AL = AF ? (AL + 0x6) : AL; - AL = _Select(OpSize::i64Bit, OpSize::i64Bit, CondClass::NEQ, AF, Constant(0), Add(OpSize::i64Bit, AL, 0x6), AL); + AL = _Select(OpSize::i64Bit, OpSize::i64Bit, CondClass::NEQ, AF, Constant(0, ConstPad::NoPad), Add(OpSize::i64Bit, AL, 0x6), AL); // AL = CF ? (AL + 0x60) : AL; - AL = _Select(OpSize::i64Bit, OpSize::i64Bit, CondClass::EQ, CFInv, Constant(0), Add(OpSize::i64Bit, AL, 0x60), AL); + AL = _Select(OpSize::i64Bit, OpSize::i64Bit, CondClass::EQ, CFInv, Constant(0, ConstPad::NoPad), Add(OpSize::i64Bit, AL, 0x60), AL); // SF, ZF, PF set according to result. CF set per above. OF undefined. StoreGPRRegister(X86State::REG_RAX, AL, OpSize::i8Bit); @@ -2831,16 +2832,16 @@ void OpDispatchBuilder::DASOp(OpcodeArgs) { auto AF = CalculateAFForDecimal(AL); // CF |= (AL > 0x99); - CF = _Or(OpSize::i64Bit, CF, Select01(OpSize::i64Bit, CondClass::UGT, AL, Constant(0x99))); + CF = _Or(OpSize::i64Bit, CF, Select01(OpSize::i64Bit, CondClass::UGT, AL, Constant(0x99, ConstPad::NoPad))); // NewCF = CF | (AF && (Borrow from AL - 6)) - auto NewCF = _Or(OpSize::i32Bit, CF, _Select(OpSize::i64Bit, OpSize::i64Bit, CondClass::ULT, AL, Constant(6), AF, CF)); + auto NewCF = _Or(OpSize::i32Bit, CF, _Select(OpSize::i64Bit, OpSize::i64Bit, CondClass::ULT, AL, Constant(6, ConstPad::NoPad), AF, CF)); // AL = AF ? (AL - 0x6) : AL; - AL = _Select(OpSize::i64Bit, OpSize::i64Bit, CondClass::NEQ, AF, Constant(0), Sub(OpSize::i64Bit, AL, 0x6), AL); + AL = _Select(OpSize::i64Bit, OpSize::i64Bit, CondClass::NEQ, AF, Constant(0, ConstPad::NoPad), Sub(OpSize::i64Bit, AL, 0x6), AL); // AL = CF ? (AL - 0x60) : AL; - AL = _Select(OpSize::i64Bit, OpSize::i64Bit, CondClass::NEQ, CF, Constant(0), Sub(OpSize::i64Bit, AL, 0x60), AL); + AL = _Select(OpSize::i64Bit, OpSize::i64Bit, CondClass::NEQ, CF, Constant(0, ConstPad::NoPad), Sub(OpSize::i64Bit, AL, 0x60), AL); // SF, ZF, PF set according to result. CF set per above. OF undefined. StoreGPRRegister(X86State::REG_RAX, AL, OpSize::i8Bit); @@ -2863,7 +2864,7 @@ void OpDispatchBuilder::AAAOp(OpcodeArgs) { A = NZCVSelect(OpSize::i32Bit, CondClass::UGE /* CF = 1 */, Add(OpSize::i32Bit, A, 0x106), A); // AL = AL & 0x0F - A = _And(OpSize::i32Bit, A, Constant(0xFF0F)); + A = _And(OpSize::i32Bit, A, Constant(0xFF0F, ConstPad::NoPad)); StoreGPRRegister(X86State::REG_RAX, A, OpSize::i16Bit); } @@ -2880,13 +2881,13 @@ void OpDispatchBuilder::AASOp(OpcodeArgs) { A = NZCVSelect(OpSize::i32Bit, CondClass::UGE /* CF = 1 */, Sub(OpSize::i32Bit, A, 0x106), A); // AL = AL & 0x0F - A = _And(OpSize::i32Bit, A, Constant(0xFF0F)); + A = _And(OpSize::i32Bit, A, Constant(0xFF0F, ConstPad::NoPad)); StoreGPRRegister(X86State::REG_RAX, A, OpSize::i16Bit); } void OpDispatchBuilder::AAMOp(OpcodeArgs) { auto AL = LoadGPRRegister(X86State::REG_RAX, OpSize::i8Bit); - auto Imm8 = Constant(Op->Src[0].Literal() & 0xFF); + auto Imm8 = Constant(Op->Src[0].Literal() & 0xFF, ConstPad::NoPad); Ref Quotient = _AllocateGPR(true); Ref Remainder = _AllocateGPR(true); _UDiv(OpSize::i64Bit, AL, Invalid(), Imm8, Quotient, Remainder); @@ -2900,10 +2901,10 @@ void OpDispatchBuilder::AAMOp(OpcodeArgs) { void OpDispatchBuilder::AADOp(OpcodeArgs) { auto A = LoadGPRRegister(X86State::REG_RAX); - auto AH = _Lshr(OpSize::i32Bit, A, Constant(8)); - auto Imm8 = Constant(Op->Src[0].Literal() & 0xFF); + auto AH = _Lshr(OpSize::i32Bit, A, Constant(8, ConstPad::NoPad)); + auto Imm8 = Constant(Op->Src[0].Literal() & 0xFF, ConstPad::NoPad); auto NewAL = Add(OpSize::i64Bit, A, _Mul(OpSize::i64Bit, AH, Imm8)); - auto Result = _And(OpSize::i64Bit, NewAL, Constant(0xFF)); + auto Result = _And(OpSize::i64Bit, NewAL, Constant(0xFF, ConstPad::NoPad)); StoreGPRRegister(X86State::REG_RAX, Result, OpSize::i16Bit); SetNZ_ZeroCV(OpSize::i8Bit, Result); @@ -3000,8 +3001,9 @@ void OpDispatchBuilder::SGDTOp(OpcodeArgs) { GDTStoreSize = OpSize::i32Bit; } - _StoreMemGPRAutoTSO(OpSize::i16Bit, DestAddress, Constant(0)); - _StoreMemGPRAutoTSO(GDTStoreSize, AddressMode {.Base = DestAddress, .Offset = 2, .AddrSize = OpSize::i64Bit}, Constant(GDTAddress)); + _StoreMemGPRAutoTSO(OpSize::i16Bit, DestAddress, Constant(0, ConstPad::NoPad)); + _StoreMemGPRAutoTSO(GDTStoreSize, AddressMode {.Base = DestAddress, .Offset = 2, .AddrSize = OpSize::i64Bit}, + Constant(GDTAddress, ConstPad::NoPad)); } void OpDispatchBuilder::SIDTOp(OpcodeArgs) { @@ -3016,29 +3018,30 @@ void OpDispatchBuilder::SIDTOp(OpcodeArgs) { IDTStoreSize = OpSize::i32Bit; } - _StoreMemGPRAutoTSO(OpSize::i16Bit, DestAddress, Constant(0xfff)); - _StoreMemGPRAutoTSO(IDTStoreSize, AddressMode {.Base = DestAddress, .Offset = 2, .AddrSize = OpSize::i64Bit}, Constant(IDTAddress)); + _StoreMemGPRAutoTSO(OpSize::i16Bit, DestAddress, Constant(0xfff, ConstPad::NoPad)); + _StoreMemGPRAutoTSO(IDTStoreSize, AddressMode {.Base = DestAddress, .Offset = 2, .AddrSize = OpSize::i64Bit}, + Constant(IDTAddress, ConstPad::NoPad)); } void OpDispatchBuilder::SMSWOp(OpcodeArgs) { const bool IsMemDst = DestIsMem(Op); IR::OpSize DstSize {OpSize::iInvalid}; - Ref Const = Constant((1U << 31) | ///< PG - Paging - (0U << 30) | ///< CD - Cache Disable - (0U << 29) | ///< NW - Not Writethrough (Legacy, now ignored) - ///< [28:19] - Reserved - (1U << 18) | ///< AM - Alignment Mask - ///< 17 - Reserved - (1U << 16) | ///< WP - Write Protect - ///< [15:6] - Reserved - (1U << 5) | ///< NE - Numeric Error - (1U << 4) | ///< ET - Extension Type (Legacy, now reserved and 1) - (0U << 3) | ///< TS - Task Switched - (0U << 2) | ///< EM - Emulation - (1U << 1) | ///< MP - Monitor Coprocessor - (1U << 0)); ///< PE - Protection Enabled - + Ref Const = Constant((1U << 31) | ///< PG - Paging + (0U << 30) | ///< CD - Cache Disable + (0U << 29) | ///< NW - Not Writethrough (Legacy, now ignored) + ///< [28:19] - Reserved + (1U << 18) | ///< AM - Alignment Mask + ///< 17 - Reserved + (1U << 16) | ///< WP - Write Protect + ///< [15:6] - Reserved + (1U << 5) | ///< NE - Numeric Error + (1U << 4) | ///< ET - Extension Type (Legacy, now reserved and 1) + (0U << 3) | ///< TS - Task Switched + (0U << 2) | ///< EM - Emulation + (1U << 1) | ///< MP - Monitor Coprocessor + (1U << 0), ///< PE - Protection Enabled + ConstPad::NoPad); const auto OpAddr = X86Tables::DecodeFlags::GetOpAddr(Op->Flags, 0); if (Is64BitMode) { DstSize = OpAddr == X86Tables::DecodeFlags::FLAG_OPERAND_SIZE_LAST ? OpSize::i16Bit : @@ -3069,8 +3072,8 @@ OpDispatchBuilder::CycleCounterPair OpDispatchBuilder::CycleCounter(bool SelfSyn Ref CounterHigh {}; auto Counter = _CycleCounter(SelfSynchronizingLoads); if (CTX->Config.TSCScale) { - CounterLow = _Lshl(OpSize::i32Bit, Counter, Constant(CTX->Config.TSCScale)); - CounterHigh = _Lshr(OpSize::i64Bit, Counter, Constant(32 - CTX->Config.TSCScale)); + CounterLow = _Lshl(OpSize::i32Bit, Counter, Constant(CTX->Config.TSCScale, ConstPad::NoPad)); + CounterHigh = _Lshr(OpSize::i64Bit, Counter, Constant(32 - CTX->Config.TSCScale, ConstPad::NoPad)); } else { CounterLow = _Bfe(OpSize::i64Bit, 32, 0, Counter); CounterHigh = _Bfe(OpSize::i64Bit, 32, 32, Counter); @@ -3098,7 +3101,7 @@ void OpDispatchBuilder::INCOp(OpcodeArgs) { HandledLock = true; Ref DestAddress = MakeSegmentAddress(Op, Op->Dest); - Dest = _AtomicFetchAdd(OpSizeFromSrc(Op), Constant(1), DestAddress); + Dest = _AtomicFetchAdd(OpSizeFromSrc(Op), Constant(1, ConstPad::NoPad), DestAddress); } else { Dest = LoadSourceGPR(Op, Op->Dest, Op->Flags, {.AllowUpperGarbage = Size >= 32}); } @@ -3109,7 +3112,7 @@ void OpDispatchBuilder::INCOp(OpcodeArgs) { // Addition producing upper garbage Result = Add(OpSize::i32Bit, Dest, 1); CalculatePF(Result); - CalculateAF(Dest, Constant(1)); + CalculateAF(Dest, Constant(1, ConstPad::NoPad)); // Correctly set NZ flags, preserving C HandleNZCV_RMW(); @@ -3119,7 +3122,7 @@ void OpDispatchBuilder::INCOp(OpcodeArgs) { // getting a negative. So compare the sign bits to calculate V. _RmifNZCV(_Andn(OpSize::i32Bit, Result, Dest), Size - 1, 1); } else { - Result = CalculateFlags_ADD(OpSizeFromSrc(Op), Dest, Constant(1), false); + Result = CalculateFlags_ADD(OpSizeFromSrc(Op), Dest, Constant(1, ConstPad::NoPad), false); } if (!IsLocked) { @@ -3139,7 +3142,7 @@ void OpDispatchBuilder::DECOp(OpcodeArgs) { Ref DestAddress = MakeSegmentAddress(Op, Op->Dest); // Use Add instead of Sub to avoid a NEG - Dest = _AtomicFetchAdd(OpSizeFromSrc(Op), Constant(Size == 64 ? -1 : ((1ULL << Size) - 1)), DestAddress); + Dest = _AtomicFetchAdd(OpSizeFromSrc(Op), Constant(Size == 64 ? -1 : ((1ULL << Size) - 1), ConstPad::NoPad), DestAddress); } else { Dest = LoadSourceGPR(Op, Op->Dest, Op->Flags, {.AllowUpperGarbage = Size >= 32}); } @@ -3150,7 +3153,7 @@ void OpDispatchBuilder::DECOp(OpcodeArgs) { // Subtraction producing upper garbage Result = Sub(OpSize::i32Bit, Dest, 1); CalculatePF(Result); - CalculateAF(Dest, Constant(1)); + CalculateAF(Dest, Constant(1, ConstPad::NoPad)); // Correctly set NZ flags, preserving C HandleNZCV_RMW(); @@ -3160,7 +3163,7 @@ void OpDispatchBuilder::DECOp(OpcodeArgs) { // getting a positive. So compare the sign bits to calculate V. _RmifNZCV(_Andn(OpSize::i32Bit, Dest, Result), Size - 1, 1); } else { - Result = CalculateFlags_SUB(OpSizeFromSrc(Op), Dest, Constant(1), false); + Result = CalculateFlags_SUB(OpSizeFromSrc(Op), Dest, Constant(1, ConstPad::NoPad), false); } if (!IsLocked) { @@ -3208,7 +3211,7 @@ void OpDispatchBuilder::STOSOp(OpcodeArgs) { Ref Counter = LoadGPRRegister(X86State::REG_RCX); auto Result = _MemSet(CTX->IsAtomicTSOEnabled(), Size, Segment ?: InvalidNode, Dest, Src, Counter, LoadDir(1)); - StoreGPRRegister(X86State::REG_RCX, Constant(0)); + StoreGPRRegister(X86State::REG_RCX, Constant(0, ConstPad::NoPad)); StoreGPRRegister(X86State::REG_RDI, Result); } } @@ -3251,7 +3254,7 @@ void OpDispatchBuilder::MOVSOp(OpcodeArgs) { Result_Src = Sub(OpSize::i64Bit, Result_Src, SrcSegment); } - StoreGPRRegister(X86State::REG_RCX, Constant(0)); + StoreGPRRegister(X86State::REG_RCX, Constant(0, ConstPad::NoPad)); StoreGPRRegister(X86State::REG_RDI, Result_Dst); StoreGPRRegister(X86State::REG_RSI, Result_Src); } else { @@ -3607,7 +3610,7 @@ void OpDispatchBuilder::BSWAPOp(OpcodeArgs) { const auto Size = OpSizeFromSrc(Op); if (Size == OpSize::i16Bit) { // BSWAP of 16bit is undef. ZEN+ causes the lower 16bits to get zero'd - Dest = Constant(0); + Dest = Constant(0, ConstPad::NoPad); } else { Dest = LoadSourceGPR_WithOpSize(Op, Op->Dest, GetGPROpSize(), Op->Flags); Dest = _Rev(Size, Dest); @@ -3629,7 +3632,7 @@ void OpDispatchBuilder::POPFOp(OpcodeArgs) { // Bit 1 is always 1 // Bit 9 is always 1 because we always have interrupts enabled - Src = _Or(OpSize::i64Bit, Src, Constant(0x202)); + Src = _Or(OpSize::i64Bit, Src, Constant(0x202, ConstPad::NoPad)); SetPackedRFLAG(false, Src); @@ -3642,7 +3645,7 @@ void OpDispatchBuilder::NEGOp(OpcodeArgs) { HandledLock = (Op->Flags & FEXCore::X86Tables::DecodeFlags::FLAG_LOCK) != 0; const auto Size = OpSizeFromSrc(Op); - auto ZeroConst = Constant(0); + auto ZeroConst = Constant(0, ConstPad::NoPad); if (DestIsLockedMem(Op)) { Ref DestMem = MakeSegmentAddress(Op, Op->Dest); @@ -4330,7 +4333,7 @@ Ref OpDispatchBuilder::LoadGPRRegister(uint32_t GPR, IR::OpSize Size, uint8_t Of // Extract the subregister if requested. const auto OpSize = std::max(OpSize::i32Bit, Size); if (AllowUpperGarbage) { - Reg = _Lshr(OpSize, Reg, Constant(Offset)); + Reg = _Lshr(OpSize, Reg, Constant(Offset, ConstPad::NoPad)); } else { Reg = _Bfe(OpSize, IR::OpSizeAsBits(Size), Offset, Reg); } @@ -4437,7 +4440,7 @@ void OpDispatchBuilder::StoreResult_WithOpSize(RegClass Class, FEXCore::X86Table // For X87 extended doubles, split before storing _StoreMemFPR(OpSize::i64Bit, MemStoreDst, Src, Align); auto Upper = _VExtractToGPR(OpSize::i128Bit, OpSize::i64Bit, Src, 1); - _StoreMemGPR(OpSize::i16Bit, Upper, MemStoreDst, Constant(8), std::min(Align, OpSize::i64Bit), MemOffsetType::SXTX, 1); + _StoreMemGPR(OpSize::i16Bit, Upper, MemStoreDst, Constant(8, ConstPad::NoPad), std::min(Align, OpSize::i64Bit), MemOffsetType::SXTX, 1); } } else { _StoreMemAutoTSO(Class, OpSize, A, Src, Align == OpSize::iInvalid ? OpSize : Align); @@ -4513,7 +4516,7 @@ void OpDispatchBuilder::ALUOp(OpcodeArgs, FEXCore::IR::IROps ALUIROp, FEXCore::I FlushRegisterCache(); // Move 0 into the register - StoreResultGPR(Op, Constant(0)); + StoreResultGPR(Op, Constant(0, ConstPad::NoPad)); return; } @@ -4548,7 +4551,7 @@ void OpDispatchBuilder::ALUOp(OpcodeArgs, FEXCore::IR::IROps ALUIROp, FEXCore::I // adjusted constant here will inline into the arm64 and instruction, so if // flags are not needed, we save an instruction overall. if (ALUIROp == IR::IROps::OP_ANDWITHFLAGS) { - Src = Constant(Const | ~((1ull << IR::OpSizeAsBits(Size)) - 1)); + Src = Constant(Const | ~((1ull << IR::OpSizeAsBits(Size)) - 1), ConstPad::NoPad); ALUIROp = IR::IROps::OP_AND; } } @@ -4603,7 +4606,7 @@ void OpDispatchBuilder::ALUOp(OpcodeArgs, FEXCore::IR::IROps ALUIROp, FEXCore::I void OpDispatchBuilder::LSLOp(OpcodeArgs) { // Emulate by always returning failure, this deviates from both Linux and Windows but // shouldn't be depended on by anything. - SetRFLAG(Constant(0)); + SetRFLAG(Constant(0, ConstPad::NoPad)); } void OpDispatchBuilder::INTOp(OpcodeArgs) { diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.h b/FEXCore/Source/Interface/Core/OpcodeDispatcher.h index eaa3398dde..15f6e3eb79 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.h +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.h @@ -244,7 +244,7 @@ class OpDispatchBuilder final : public IREmitter { template void ForeachDirection(F&& Routine) { // Otherwise, prepare to branch. - auto Zero = Constant(0); + auto Zero = Constant(0, ConstPad::NoPad); // If the shift is zero, do not touch the flags. auto ForwardBlock = CreateNewCodeBlockAfter(GetCurrentBlock()); @@ -1263,7 +1263,7 @@ class OpDispatchBuilder final : public IREmitter { StoreContextHelper(Size, Class, Value, Offset); // If Partial and MMX register, then we need to store all 1s in bits 64-80 if (Partial && Index >= MM0Index && Index <= MM7Index) { - _StoreContextGPR(OpSize::i16Bit, Constant(0xFFFF), Offset + 8); + _StoreContextGPR(OpSize::i16Bit, Constant(0xFFFF, ConstPad::NoPad), Offset + 8); } } } @@ -1697,7 +1697,7 @@ class OpDispatchBuilder final : public IREmitter { } void ZeroNZCV() { - CachedNZCV = Constant(0); + CachedNZCV = Constant(0, ConstPad::NoPad); NZCVDirty = true; } @@ -1712,7 +1712,7 @@ class OpDispatchBuilder final : public IREmitter { if (SetPF) { CalculatePF(SubWithFlags(SrcSize, Res, (uint64_t)0)); } else { - _SubNZCV(SrcSize, Res, Constant(0)); + _SubNZCV(SrcSize, Res, Constant(0, ConstPad::NoPad)); } CFInverted = true; @@ -1783,7 +1783,7 @@ class OpDispatchBuilder final : public IREmitter { } else { // Invert as a GPR unsigned Bit = IndexNZCV(FEXCore::X86State::RFLAG_CF_RAW_LOC); - SetNZCV(_Xor(OpSize::i32Bit, GetNZCV(), Constant(1u << Bit))); + SetNZCV(_Xor(OpSize::i32Bit, GetNZCV(), Constant(1u << Bit, ConstPad::NoPad))); CalculateDeferredFlags(); } @@ -1821,7 +1821,7 @@ class OpDispatchBuilder final : public IREmitter { } HandleNZCVWrite(); - _SubNZCV(OpSize::i32Bit, Constant(0), Value); + _SubNZCV(OpSize::i32Bit, Constant(0, ConstPad::NoPad), Value); CFInverted = true; } @@ -1846,14 +1846,14 @@ class OpDispatchBuilder final : public IREmitter { StoreRegister(Core::CPUState::AF_AS_GREG, false, Value); } else if (BitOffset == FEXCore::X86State::RFLAG_DF_RAW_LOC) { // For DF, we need to transform 0/1 into 1/-1 - StoreDF(_SubShift(OpSize::i64Bit, Constant(1), Value, ShiftType::LSL, 1)); + StoreDF(_SubShift(OpSize::i64Bit, Constant(1, ConstPad::NoPad), Value, ShiftType::LSL, 1)); } else if (BitOffset == FEXCore::X86State::RFLAG_TF_RAW_LOC) { auto PackedTF = _LoadContextGPR(OpSize::i8Bit, offsetof(FEXCore::Core::CPUState, flags[BitOffset])); // An exception should still be raised after an instruction that unsets TF, leave the unblocked bit set but unset // the TF bit to cause such behaviour. The handling code at the start of the next block will then unset the // unblocked bit before raising the exception. - auto NewPackedTF = - _Select(OpSize::i64Bit, OpSize::i64Bit, CondClass::EQ, Value, Constant(0), _And(OpSize::i32Bit, PackedTF, Constant(~1)), Constant(1)); + auto NewPackedTF = _Select(OpSize::i64Bit, OpSize::i64Bit, CondClass::EQ, Value, Constant(0, ConstPad::NoPad), + _And(OpSize::i32Bit, PackedTF, Constant(~1, ConstPad::NoPad)), Constant(1, ConstPad::NoPad)); _StoreContextGPR(OpSize::i8Bit, NewPackedTF, offsetof(FEXCore::Core::CPUState, flags[BitOffset])); } else { _StoreContextGPR(OpSize::i8Bit, Value, offsetof(FEXCore::Core::CPUState, flags[BitOffset])); @@ -1865,7 +1865,7 @@ class OpDispatchBuilder final : public IREmitter { // bits. This allows us to defer the extract in the usual case. When it is // read, bit 4 is extracted. In order to write a constant value of AF, that // means we need to left-shift here to compensate. - SetRFLAG(Constant(K << 4)); + SetRFLAG(Constant(K << 4, ConstPad::NoPad)); } void ZeroPF_AF(); @@ -2089,7 +2089,7 @@ class OpDispatchBuilder final : public IREmitter { auto Value = _Bfe(OpSize::i32Bit, 1, IndexNZCV(BitOffset), GetNZCV()); if (Invert) { - return _Xor(OpSize::i32Bit, Value, Constant(1)); + return _Xor(OpSize::i32Bit, Value, Constant(1, ConstPad::NoPad)); } else { return Value; } @@ -2104,7 +2104,7 @@ class OpDispatchBuilder final : public IREmitter { return LoadGPR(Core::CPUState::AF_AS_GREG); } else if (BitOffset == FEXCore::X86State::RFLAG_DF_RAW_LOC) { // Recover the sign bit, it is the logical DF value - return _Lshr(OpSize::i64Bit, LoadDF(), Constant(63)); + return _Lshr(OpSize::i64Bit, LoadDF(), Constant(63, ConstPad::NoPad)); } else { return _LoadContextGPR(OpSize::i8Bit, offsetof(Core::CPUState, flags[BitOffset])); } @@ -2176,7 +2176,7 @@ class OpDispatchBuilder final : public IREmitter { // Zero AF. Note that the comparison sets the raw PF to 0/1 above, so // PF[4] is 0 so the XOR with PF will have no effect, so setting the AF // byte to zero will indeed zero AF as intended. - SetRFLAG(Constant(0)); + SetRFLAG(Constant(0, ConstPad::NoPad)); } // Convert NZCV from the Arm representation to an eXternal representation @@ -2210,7 +2210,7 @@ class OpDispatchBuilder final : public IREmitter { } SetRFLAG(C); - SetRFLAG(Constant(0)); + SetRFLAG(Constant(0, ConstPad::NoPad)); SetRFLAG(V); SetRFLAG(Z); } @@ -2332,7 +2332,7 @@ class OpDispatchBuilder final : public IREmitter { } // Otherwise, prepare to branch. - auto Zero = Constant(0); + auto Zero = Constant(0, ConstPad::NoPad); // If the shift is zero, do not touch the flags. auto SetBlock = CreateNewCodeBlockAfter(GetCurrentBlock()); @@ -2405,8 +2405,8 @@ class OpDispatchBuilder final : public IREmitter { void ChgStateX87_MMX() override { LOGMAN_THROW_A_FMT(MMXState == MMXState_X87, "Expected state to be x87"); _StackForceSlow(); - SetX87Top(Constant(0)); // top reset to zero - _StoreContextGPR(OpSize::i8Bit, Constant(0xFFFFUL), offsetof(FEXCore::Core::CPUState, AbridgedFTW)); + SetX87Top(Constant(0, ConstPad::NoPad)); // top reset to zero + _StoreContextGPR(OpSize::i8Bit, Constant(0xFFFFUL, ConstPad::NoPad), offsetof(FEXCore::Core::CPUState, AbridgedFTW)); MMXState = MMXState_MMX; } @@ -2639,11 +2639,11 @@ class OpDispatchBuilder final : public IREmitter { } ArithRef And(uint64_t K) { - return IsConstant ? ArithRef(E, C & K) : ArithRef(E, E->_And(OpSize::i64Bit, R, E->Constant(K))); + return IsConstant ? ArithRef(E, C & K) : ArithRef(E, E->_And(OpSize::i64Bit, R, E->Constant(K, ConstPad::NoPad))); } ArithRef Presub(uint64_t K) { - return IsConstant ? ArithRef(E, K - C) : ArithRef(E, E->Sub(OpSize::i64Bit, E->Constant(K), R)); + return IsConstant ? ArithRef(E, K - C) : ArithRef(E, E->Sub(OpSize::i64Bit, E->Constant(K, ConstPad::NoPad), R)); } ArithRef Lshl(uint64_t Shift) { @@ -2652,7 +2652,7 @@ class OpDispatchBuilder final : public IREmitter { } else if (IsConstant) { return ArithRef(E, C << Shift); } else { - return ArithRef(E, E->_Lshl(OpSize::i64Bit, R, E->Constant(Shift))); + return ArithRef(E, E->_Lshl(OpSize::i64Bit, R, E->Constant(Shift, ConstPad::NoPad))); } } @@ -2692,7 +2692,7 @@ class OpDispatchBuilder final : public IREmitter { } if (IsConstant) { - return E->_Bfi(OpSize::i64Bit, Size, Start, Bitfield, E->Constant(C)); + return E->_Bfi(OpSize::i64Bit, Size, Start, Bitfield, E->Constant(C, ConstPad::NoPad)); } else { return E->_Bfi(OpSize::i64Bit, Size, Start, Bitfield, R); } @@ -2708,12 +2708,12 @@ class OpDispatchBuilder final : public IREmitter { return ArithRef(E, Result); } else { - return ArithRef(E, E->_Lshl(Size, E->Constant(1), R)); + return ArithRef(E, E->_Lshl(Size, E->Constant(1, ConstPad::NoPad), R)); } } Ref Ref() { - return IsConstant ? E->Constant(C) : R; + return IsConstant ? E->Constant(C, ConstPad::NoPad) : R; } bool IsDefinitelyZero() const { diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher/AVX_128.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher/AVX_128.cpp index 1dcfd1e14d..1335944e3f 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher/AVX_128.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher/AVX_128.cpp @@ -845,7 +845,7 @@ void OpDispatchBuilder::AVX128_MOVMSK(OpcodeArgs, IR::OpSize ElementSize) { // Inserting the full lower 32-bits offset 31 so the sign bit ends up at offset 63. GPR = _Bfi(OpSize::i64Bit, 32, 31, GPR, GPR); // Shift right to only get the two sign bits we care about. - return _Lshr(OpSize::i64Bit, GPR, Constant(62)); + return _Lshr(OpSize::i64Bit, GPR, Constant(62, ConstPad::NoPad)); }; auto Mask4Byte = [this](Ref Src) { @@ -1838,7 +1838,7 @@ void OpDispatchBuilder::AVX128_VPERMD(OpcodeArgs) { RefPair Result {}; Ref IndexMask = _VectorImm(OpSize::i128Bit, OpSize::i32Bit, 0b111); - Ref AddConst = Constant(0x03020100); + Ref AddConst = Constant(0x03020100, ConstPad::NoPad); Ref Repeating3210 = _VDupFromGPR(OpSize::i128Bit, OpSize::i32Bit, AddConst); Result.Low = DoPerm(Src, Indices.Low, IndexMask, Repeating3210); @@ -2035,7 +2035,7 @@ OpDispatchBuilder::RefPair OpDispatchBuilder::AVX128_VPGatherImpl(OpcodeArgs, Op if (BaseAddr && VSIB.Displacement) { BaseAddr = Add(OpSize::i64Bit, BaseAddr, VSIB.Displacement); } else if (VSIB.Displacement) { - BaseAddr = Constant(VSIB.Displacement); + BaseAddr = Constant(VSIB.Displacement, ConstPad::NoPad); } else if (!BaseAddr) { BaseAddr = Invalid(); } @@ -2133,7 +2133,7 @@ OpDispatchBuilder::RefPair OpDispatchBuilder::AVX128_VPGatherQPSImpl(OpcodeArgs, if (BaseAddr && VSIB.Displacement) { BaseAddr = Add(OpSize::i64Bit, BaseAddr, VSIB.Displacement); } else if (VSIB.Displacement) { - BaseAddr = Constant(VSIB.Displacement); + BaseAddr = Constant(VSIB.Displacement, ConstPad::NoPad); } else if (!BaseAddr) { BaseAddr = Invalid(); } diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Flags.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Flags.cpp index 82c1a1a6c6..5a29303b99 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Flags.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Flags.cpp @@ -28,7 +28,7 @@ constexpr std::array FlagOffsets = { void OpDispatchBuilder::ZeroPF_AF() { // PF is stored inverted, so invert it when we zero. - SetRFLAG(Constant(1)); + SetRFLAG(Constant(1, ConstPad::NoPad)); SetAF(0); } @@ -247,7 +247,7 @@ void OpDispatchBuilder::CalculateAF(Ref Src1, Ref Src2) { // We store the XOR of the arguments. At read time, we XOR with the // appropriate bit of the result (available as the PF flag) and extract the // appropriate bit. Again 64-bit to avoid masking. - Ref XorRes = Src1 == Src2 ? Constant(0) : _Xor(OpSize::i64Bit, Src1, Src2); + Ref XorRes = Src1 == Src2 ? Constant(0, ConstPad::NoPad) : _Xor(OpSize::i64Bit, Src1, Src2); SetRFLAG(XorRes); } diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp index dc7474175f..25d3d984d3 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp @@ -740,7 +740,7 @@ void OpDispatchBuilder::MOVMSKOp(OpcodeArgs, IR::OpSize ElementSize) { // Inserting the full lower 32-bits offset 31 so the sign bit ends up at offset 63. GPR = _Bfi(OpSize::i64Bit, 32, 31, GPR, GPR); // Shift right to only get the two sign bits we care about. - GPR = _Lshr(OpSize::i64Bit, GPR, Constant(62)); + GPR = _Lshr(OpSize::i64Bit, GPR, Constant(62, ConstPad::NoPad)); StoreResultGPR_WithOpSize(Op, Op->Dest, GPR, GetGPROpSize()); } else if (Size == OpSize::i128Bit && ElementSize == OpSize::i32Bit) { // Shift all the sign bits to the bottom of their respective elements. @@ -755,7 +755,7 @@ void OpDispatchBuilder::MOVMSKOp(OpcodeArgs, IR::OpSize ElementSize) { Ref GPR = _VExtractToGPR(Size, OpSize::i32Bit, Src, 0); StoreResultGPR_WithOpSize(Op, Op->Dest, GPR, GetGPROpSize()); } else { - Ref CurrentVal = Constant(0); + Ref CurrentVal = Constant(0, ConstPad::NoPad); for (unsigned i = 0; i < NumElements; ++i) { // Extract the top bit of the element @@ -2121,7 +2121,7 @@ Ref OpDispatchBuilder::CVTFPR_To_GPRImpl(OpcodeArgs, Ref Src, IR::OpSize SrcElem Ref Converted = _Float_ToGPR_ZS(GPRSize, SrcElementSize, Src); bool Dst32 = GPRSize == OpSize::i32Bit; - Ref MaxI = Dst32 ? Constant(0x80000000) : Constant(0x8000000000000000); + Ref MaxI = Dst32 ? Constant(0x80000000, ConstPad::NoPad) : Constant(0x8000000000000000, ConstPad::NoPad); Ref MaxF = LoadAndCacheNamedVectorConstant(SrcElementSize, (SrcElementSize == OpSize::i32Bit) ? (Dst32 ? NAMED_VECTOR_CVTMAX_F32_I32 : NAMED_VECTOR_CVTMAX_F32_I64) : (Dst32 ? NAMED_VECTOR_CVTMAX_F64_I32 : NAMED_VECTOR_CVTMAX_F64_I64)); @@ -2552,7 +2552,7 @@ void OpDispatchBuilder::XSaveOpImpl(OpcodeArgs) { // XSTATE_BV section of the header is 8 bytes in size, but we only really // care about setting at most 3 bits in the first byte. We zero out the rest. - _StoreMemGPR(OpSize::i64Bit, RequestedFeatures, Base, Constant(512), OpSize::i8Bit, MemOffsetType::SXTX, 1); + _StoreMemGPR(OpSize::i64Bit, RequestedFeatures, Base, Constant(512, ConstPad::NoPad), OpSize::i8Bit, MemOffsetType::SXTX, 1); } } @@ -2578,12 +2578,12 @@ void OpDispatchBuilder::SaveX87State(OpcodeArgs, Ref MemBase) { _StoreMemGPR(OpSize::i16Bit, MemBase, FCW, OpSize::i16Bit); } - { _StoreMemGPR(OpSize::i16Bit, ReconstructFSW_Helper(), MemBase, Constant(2), OpSize::i16Bit, MemOffsetType::SXTX, 1); } + { _StoreMemGPR(OpSize::i16Bit, ReconstructFSW_Helper(), MemBase, Constant(2, ConstPad::NoPad), OpSize::i16Bit, MemOffsetType::SXTX, 1); } { // Abridged FTW auto FTW = _LoadContextGPR(OpSize::i8Bit, offsetof(FEXCore::Core::CPUState, AbridgedFTW)); - _StoreMemGPR(OpSize::i8Bit, FTW, MemBase, Constant(4), OpSize::i8Bit, MemOffsetType::SXTX, 1); + _StoreMemGPR(OpSize::i8Bit, FTW, MemBase, Constant(4, ConstPad::NoPad), OpSize::i8Bit, MemOffsetType::SXTX, 1); } // BYTE | 0 1 | 2 3 | 4 | 5 | 6 7 | 8 9 | a b | c d | e f | @@ -2633,7 +2633,7 @@ void OpDispatchBuilder::SaveX87State(OpcodeArgs, Ref MemBase) { // // x87 registers are stored rotated depending on the current TOP. Ref Top = GetX87Top(); - auto SevenConst = Constant(7); + auto SevenConst = Constant(7, ConstPad::NoPad); const auto LoadSize = ReducedPrecisionMode ? OpSize::i64Bit : OpSize::i128Bit; for (uint32_t i = 0; i < Core::CPUState::NUM_MMS; ++i) { @@ -2641,7 +2641,7 @@ void OpDispatchBuilder::SaveX87State(OpcodeArgs, Ref MemBase) { if (ReducedPrecisionMode) { data = _F80CVTTo(data, OpSize::i64Bit); } - _StoreMemFPR(OpSize::i128Bit, data, MemBase, Constant(16 * i + 32), OpSize::i8Bit, MemOffsetType::SXTX, 1); + _StoreMemFPR(OpSize::i128Bit, data, MemBase, Constant(16 * i + 32, ConstPad::NoPad), OpSize::i8Bit, MemOffsetType::SXTX, 1); Top = _And(OpSize::i32Bit, Add(OpSize::i32Bit, Top, 1), SevenConst); } } @@ -2656,7 +2656,7 @@ void OpDispatchBuilder::SaveSSEState(Ref MemBase) { void OpDispatchBuilder::SaveMXCSRState(Ref MemBase) { // Store MXCSR and the mask for all bits. - _StoreMemPairGPR(OpSize::i32Bit, GetMXCSR(), Constant(0xFFFF), MemBase, 24); + _StoreMemPairGPR(OpSize::i32Bit, GetMXCSR(), Constant(0xFFFF, ConstPad::NoPad), MemBase, 24); } void OpDispatchBuilder::SaveAVXState(Ref MemBase) { @@ -2674,7 +2674,7 @@ Ref OpDispatchBuilder::GetMXCSR() { Ref MXCSR = _LoadContextGPR(OpSize::i32Bit, offsetof(FEXCore::Core::CPUState, mxcsr)); // Mask out unsupported bits // Keeps FZ, RC, exception masks, and DAZ - MXCSR = _And(OpSize::i32Bit, MXCSR, Constant(0xFFC0)); + MXCSR = _And(OpSize::i32Bit, MXCSR, Constant(0xFFC0, ConstPad::NoPad)); return MXCSR; } @@ -2684,7 +2684,7 @@ void OpDispatchBuilder::FXRStoreOp(OpcodeArgs) { RestoreX87State(Mem); RestoreSSEState(Mem); - Ref MXCSR = _LoadMemGPR(OpSize::i32Bit, Mem, Constant(24), OpSize::i32Bit, MemOffsetType::SXTX, 1); + Ref MXCSR = _LoadMemGPR(OpSize::i32Bit, Mem, Constant(24, ConstPad::NoPad), OpSize::i32Bit, MemOffsetType::SXTX, 1); RestoreMXCSRState(MXCSR); } @@ -2701,7 +2701,7 @@ void OpDispatchBuilder::XRstorOpImpl(OpcodeArgs) { // Note: we rematerialize Base/Mask in each block to avoid crossblock // liveness. Ref Base = XSaveBase(Op); - Ref Mask = _LoadMemGPR(OpSize::i64Bit, Base, Constant(512), OpSize::i64Bit, MemOffsetType::SXTX, 1); + Ref Mask = _LoadMemGPR(OpSize::i64Bit, Base, Constant(512, ConstPad::NoPad), OpSize::i64Bit, MemOffsetType::SXTX, 1); Ref BitFlag = _Bfe(OpSize, FieldSize, BitIndex, Mask); auto CondJump_ = CondJump(BitFlag, CondClass::NEQ); @@ -2745,7 +2745,7 @@ void OpDispatchBuilder::XRstorOpImpl(OpcodeArgs) { 1, [this, Op] { Ref Base = XSaveBase(Op); - Ref MXCSR = _LoadMemGPR(OpSize::i32Bit, Base, Constant(24), OpSize::i32Bit, MemOffsetType::SXTX, 1); + Ref MXCSR = _LoadMemGPR(OpSize::i32Bit, Base, Constant(24, ConstPad::NoPad), OpSize::i32Bit, MemOffsetType::SXTX, 1); RestoreMXCSRState(MXCSR); }, [] { /* Intentionally do nothing*/ }, 2); @@ -2759,13 +2759,13 @@ void OpDispatchBuilder::RestoreX87State(Ref MemBase) { _StoreContextGPR(OpSize::i16Bit, NewFCW, offsetof(FEXCore::Core::CPUState, FCW)); { - auto NewFSW = _LoadMemGPR(OpSize::i16Bit, MemBase, Constant(2), OpSize::i16Bit, MemOffsetType::SXTX, 1); + auto NewFSW = _LoadMemGPR(OpSize::i16Bit, MemBase, Constant(2, ConstPad::NoPad), OpSize::i16Bit, MemOffsetType::SXTX, 1); ReconstructX87StateFromFSW_Helper(NewFSW); } { // Abridged FTW - auto NewFTW = _LoadMemGPR(OpSize::i8Bit, MemBase, Constant(4), OpSize::i8Bit, MemOffsetType::SXTX, 1); + auto NewFTW = _LoadMemGPR(OpSize::i8Bit, MemBase, Constant(4, ConstPad::NoPad), OpSize::i8Bit, MemOffsetType::SXTX, 1); _StoreContextGPR(OpSize::i8Bit, NewFTW, offsetof(FEXCore::Core::CPUState, AbridgedFTW)); } @@ -2789,7 +2789,7 @@ void OpDispatchBuilder::RestoreSSEState(Ref MemBase) { void OpDispatchBuilder::RestoreMXCSRState(Ref MXCSR) { // Mask out unsupported bits - MXCSR = _And(OpSize::i32Bit, MXCSR, Constant(0xFFC0)); + MXCSR = _And(OpSize::i32Bit, MXCSR, Constant(0xFFC0, ConstPad::NoPad)); _StoreContextGPR(OpSize::i32Bit, MXCSR, offsetof(FEXCore::Core::CPUState, mxcsr)); // We only support the rounding mode and FTZ bit being set @@ -3988,7 +3988,7 @@ void OpDispatchBuilder::VTESTOpImpl(OpSize SrcSize, IR::OpSize ElementSize, Ref const auto ElementSizeInBits = IR::OpSizeAsBits(ElementSize); const auto MaskConstant = uint64_t {1} << (ElementSizeInBits - 1); - Ref Mask = _VDupFromGPR(SrcSize, ElementSize, Constant(MaskConstant)); + Ref Mask = _VDupFromGPR(SrcSize, ElementSize, Constant(MaskConstant, ConstPad::NoPad)); Ref AndTest = _VAnd(SrcSize, OpSize::i8Bit, Src2, Src1); Ref AndNotTest = _VAndn(SrcSize, OpSize::i8Bit, Src2, Src1); @@ -4589,7 +4589,7 @@ void OpDispatchBuilder::VPERMDOp(OpcodeArgs) { // Get rid of any junk unrelated to the relevant selector index bits (bits [2:0]) Ref IndexMask = _VectorImm(DstSize, OpSize::i32Bit, 0b111); - Ref AddConst = Constant(0x03020100); + Ref AddConst = Constant(0x03020100, ConstPad::NoPad); Ref Repeating3210 = _VDupFromGPR(DstSize, OpSize::i32Bit, AddConst); Ref FinalIndices = VPERMDIndices(OpSizeFromDst(Op), Indices, IndexMask, Repeating3210); @@ -4824,7 +4824,7 @@ Ref OpDispatchBuilder::VPERMILRegOpImpl(OpSize DstSize, IR::OpSize ElementSize, Ref ShiftedIndices = _VShlI(DstSize, OpSize::i8Bit, IndexTrn3, IndexShift); uint64_t VConstant = IsPD ? 0x0706050403020100 : 0x03020100; - Ref VectorConst = _VDupFromGPR(DstSize, ElementSize, Constant(VConstant)); + Ref VectorConst = _VDupFromGPR(DstSize, ElementSize, Constant(VConstant, ConstPad::NoPad)); Ref FinalIndices {}; if (Is256Bit) { @@ -4883,7 +4883,7 @@ void OpDispatchBuilder::PCMPXSTRXOpImpl(OpcodeArgs, bool IsExplicit, bool IsMask IntermediateResult = _VPCMPISTRX(Src1, Src2, Control); } - Ref ZeroConst = Constant(0); + Ref ZeroConst = Constant(0, ConstPad::NoPad); if (IsMask) { // For the masked variant of the instructions, if control[6] is set, then we @@ -4920,7 +4920,7 @@ void OpDispatchBuilder::PCMPXSTRXOpImpl(OpcodeArgs, bool IsExplicit, bool IsMask Ref ResultNoFlags = _Bfe(OpSize::i32Bit, 16, 0, IntermediateResult); - Ref IfZero = Constant(16 >> (Control & 1)); + Ref IfZero = Constant(16 >> (Control & 1), ConstPad::NoPad); Ref IfNotZero = UseMSBIndex ? _FindMSB(IR::OpSize::i32Bit, ResultNoFlags) : _FindLSB(IR::OpSize::i32Bit, ResultNoFlags); Ref Result = _Select(OpSize::i64Bit, OpSize::i64Bit, CondClass::EQ, ResultNoFlags, ZeroConst, IfZero, IfNotZero); @@ -5110,7 +5110,7 @@ void OpDispatchBuilder::VPGATHER(OpcodeArgs) { if (BaseAddr && VSIB.Displacement) { BaseAddr = Add(OpSize::i64Bit, BaseAddr, VSIB.Displacement); } else if (VSIB.Displacement) { - BaseAddr = Constant(VSIB.Displacement); + BaseAddr = Constant(VSIB.Displacement, ConstPad::NoPad); } else if (!BaseAddr) { BaseAddr = Invalid(); } diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher/X87.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher/X87.cpp index 55dc55707b..8146309274 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher/X87.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher/X87.cpp @@ -41,13 +41,13 @@ void OpDispatchBuilder::SetX87FTW(Ref FTW) { // Invert FTW and clear the odd bits. Even bits are 1 if the pair // is not equal to 11, and odd bits are 0. - FTW = _Andn(OpSize::i32Bit, Constant(0x55555555), FTW); + FTW = _Andn(OpSize::i32Bit, Constant(0x55555555, ConstPad::NoPad), FTW); // All that's left is to compact away the odd bits. That is a Morton // deinterleave operation, which has a standard solution. See // https://stackoverflow.com/questions/3137266/how-to-de-interleave-bits-unmortonizing - FTW = _And(OpSize::i32Bit, _Orlshr(OpSize::i32Bit, FTW, FTW, 1), Constant(0x33333333)); - FTW = _And(OpSize::i32Bit, _Orlshr(OpSize::i32Bit, FTW, FTW, 2), Constant(0x0f0f0f0f)); + FTW = _And(OpSize::i32Bit, _Orlshr(OpSize::i32Bit, FTW, FTW, 1), Constant(0x33333333, ConstPad::NoPad)); + FTW = _And(OpSize::i32Bit, _Orlshr(OpSize::i32Bit, FTW, FTW, 2), Constant(0x0f0f0f0f, ConstPad::NoPad)); FTW = _Orlshr(OpSize::i32Bit, FTW, FTW, 4); // ...and that's it. StoreContext implicitly does the final masking. @@ -107,16 +107,16 @@ void OpDispatchBuilder::FILD(OpcodeArgs) { SaveNZCV(); // Extract sign and make integer absolute - auto zero = Constant(0); + auto zero = Constant(0, ConstPad::NoPad); _SubNZCV(OpSize::i64Bit, Data, zero); - auto sign = _NZCVSelect(OpSize::i64Bit, CondClass::SLT, Constant(0x8000), zero); + auto sign = _NZCVSelect(OpSize::i64Bit, CondClass::SLT, Constant(0x8000, ConstPad::NoPad), zero); auto absolute = _Neg(OpSize::i64Bit, Data, CondClass::MI); // left justify the absolute integer - auto shift = Sub(OpSize::i64Bit, Constant(63), _FindMSB(IR::OpSize::i64Bit, absolute)); + auto shift = Sub(OpSize::i64Bit, Constant(63, ConstPad::NoPad), _FindMSB(IR::OpSize::i64Bit, absolute)); auto shifted = _Lshl(OpSize::i64Bit, absolute, shift); - auto adjusted_exponent = Sub(OpSize::i64Bit, Constant(0x3fff + 63), shift); + auto adjusted_exponent = Sub(OpSize::i64Bit, Constant(0x3fff + 63, ConstPad::NoPad), shift); auto zeroed_exponent = _Select(OpSize::i64Bit, OpSize::i64Bit, CondClass::EQ, absolute, zero, zero, adjusted_exponent); auto upper = _Or(OpSize::i64Bit, sign, zeroed_exponent); @@ -159,11 +159,11 @@ void OpDispatchBuilder::FIST(OpcodeArgs, bool Truncate) { // Extract the 80-bit float value to check for special cases // Get the upper 64 bits which contain sign and exponent and then the exponent from upper. Ref Upper = _VExtractToGPR(OpSize::i128Bit, OpSize::i64Bit, Data, 1); - Ref Exponent = _And(OpSize::i64Bit, Upper, Constant(0x7fff)); + Ref Exponent = _And(OpSize::i64Bit, Upper, Constant(0x7fff, ConstPad::NoPad)); // Check for NaN/Infinity: exponent = 0x7fff SaveNZCV(); - _TestNZ(OpSize::i64Bit, Exponent, Constant(0x7fff)); + _TestNZ(OpSize::i64Bit, Exponent, Constant(0x7fff, ConstPad::NoPad)); Ref IsSpecial = _NZCVSelect01(CondClass::EQ); // For overflow detection, check if exponent indicates a value >= 2^15 @@ -340,17 +340,17 @@ Ref OpDispatchBuilder::GetX87FTW_Helper() { // https://graphics.stanford.edu/~seander/bithacks.html#InterleaveBMN Ref X = _LoadContextGPR(OpSize::i8Bit, offsetof(FEXCore::Core::CPUState, AbridgedFTW)); X = _Orlshl(OpSize::i32Bit, X, X, 4); - X = _And(OpSize::i32Bit, X, Constant(0x0f0f0f0f)); + X = _And(OpSize::i32Bit, X, Constant(0x0f0f0f0f, ConstPad::NoPad)); X = _Orlshl(OpSize::i32Bit, X, X, 2); - X = _And(OpSize::i32Bit, X, Constant(0x33333333)); + X = _And(OpSize::i32Bit, X, Constant(0x33333333, ConstPad::NoPad)); X = _Orlshl(OpSize::i32Bit, X, X, 1); - X = _And(OpSize::i32Bit, X, Constant(0x55555555)); + X = _And(OpSize::i32Bit, X, Constant(0x55555555, ConstPad::NoPad)); X = _Orlshl(OpSize::i32Bit, X, X, 1); // The above sequence sets valid to 11 and empty to 00, so invert to finalize. static_assert(static_cast(FPState::X87Tag::Valid) == 0b00); static_assert(static_cast(FPState::X87Tag::Empty) == 0b11); - return _Xor(OpSize::i32Bit, X, Constant(0xffff)); + return _Xor(OpSize::i32Bit, X, Constant(0xffff, ConstPad::NoPad)); } void OpDispatchBuilder::X87FNSTENV(OpcodeArgs) { @@ -387,33 +387,33 @@ void OpDispatchBuilder::X87FNSTENV(OpcodeArgs) { _StoreMemGPR(Size, Mem, FCW, Size); } - { _StoreMemGPR(Size, ReconstructFSW_Helper(), Mem, Constant(IR::OpSizeToSize(Size) * 1), Size, MemOffsetType::SXTX, 1); } + { _StoreMemGPR(Size, ReconstructFSW_Helper(), Mem, Constant(IR::OpSizeToSize(Size) * 1, ConstPad::NoPad), Size, MemOffsetType::SXTX, 1); } - auto ZeroConst = Constant(0); + auto ZeroConst = Constant(0, ConstPad::NoPad); { // FTW - _StoreMemGPR(Size, GetX87FTW_Helper(), Mem, Constant(IR::OpSizeToSize(Size) * 2), Size, MemOffsetType::SXTX, 1); + _StoreMemGPR(Size, GetX87FTW_Helper(), Mem, Constant(IR::OpSizeToSize(Size) * 2, ConstPad::NoPad), Size, MemOffsetType::SXTX, 1); } { // Instruction Offset - _StoreMemGPR(Size, ZeroConst, Mem, Constant(IR::OpSizeToSize(Size) * 3), Size, MemOffsetType::SXTX, 1); + _StoreMemGPR(Size, ZeroConst, Mem, Constant(IR::OpSizeToSize(Size) * 3, ConstPad::NoPad), Size, MemOffsetType::SXTX, 1); } { // Instruction CS selector (+ Opcode) - _StoreMemGPR(Size, ZeroConst, Mem, Constant(IR::OpSizeToSize(Size) * 4), Size, MemOffsetType::SXTX, 1); + _StoreMemGPR(Size, ZeroConst, Mem, Constant(IR::OpSizeToSize(Size) * 4, ConstPad::NoPad), Size, MemOffsetType::SXTX, 1); } { // Data pointer offset - _StoreMemGPR(Size, ZeroConst, Mem, Constant(IR::OpSizeToSize(Size) * 5), Size, MemOffsetType::SXTX, 1); + _StoreMemGPR(Size, ZeroConst, Mem, Constant(IR::OpSizeToSize(Size) * 5, ConstPad::NoPad), Size, MemOffsetType::SXTX, 1); } { // Data pointer selector - _StoreMemGPR(Size, ZeroConst, Mem, Constant(IR::OpSizeToSize(Size) * 6), Size, MemOffsetType::SXTX, 1); + _StoreMemGPR(Size, ZeroConst, Mem, Constant(IR::OpSizeToSize(Size) * 6, ConstPad::NoPad), Size, MemOffsetType::SXTX, 1); } } @@ -485,43 +485,44 @@ void OpDispatchBuilder::X87FNSAVE(OpcodeArgs) { _StoreMemGPR(Size, Mem, FCW, Size); } - { _StoreMemGPR(Size, ReconstructFSW_Helper(), Mem, Constant(IR::OpSizeToSize(Size) * 1), Size, MemOffsetType::SXTX, 1); } + { _StoreMemGPR(Size, ReconstructFSW_Helper(), Mem, Constant(IR::OpSizeToSize(Size) * 1, ConstPad::NoPad), Size, MemOffsetType::SXTX, 1); } - auto ZeroConst = Constant(0); + auto ZeroConst = Constant(0, ConstPad::NoPad); { // FTW - _StoreMemGPR(Size, GetX87FTW_Helper(), Mem, Constant(IR::OpSizeToSize(Size) * 2), Size, MemOffsetType::SXTX, 1); + _StoreMemGPR(Size, GetX87FTW_Helper(), Mem, Constant(IR::OpSizeToSize(Size) * 2, ConstPad::NoPad), Size, MemOffsetType::SXTX, 1); } { // Instruction Offset - _StoreMemGPR(Size, ZeroConst, Mem, Constant(IR::OpSizeToSize(Size) * 3), Size, MemOffsetType::SXTX, 1); + _StoreMemGPR(Size, ZeroConst, Mem, Constant(IR::OpSizeToSize(Size) * 3, ConstPad::NoPad), Size, MemOffsetType::SXTX, 1); } { // Instruction CS selector (+ Opcode) - _StoreMemGPR(Size, ZeroConst, Mem, Constant(IR::OpSizeToSize(Size) * 4), Size, MemOffsetType::SXTX, 1); + _StoreMemGPR(Size, ZeroConst, Mem, Constant(IR::OpSizeToSize(Size) * 4, ConstPad::NoPad), Size, MemOffsetType::SXTX, 1); } { // Data pointer offset - _StoreMemGPR(Size, ZeroConst, Mem, Constant(IR::OpSizeToSize(Size) * 5), Size, MemOffsetType::SXTX, 1); + _StoreMemGPR(Size, ZeroConst, Mem, Constant(IR::OpSizeToSize(Size) * 5, ConstPad::NoPad), Size, MemOffsetType::SXTX, 1); } { // Data pointer selector - _StoreMemGPR(Size, ZeroConst, Mem, Constant(IR::OpSizeToSize(Size) * 6), Size, MemOffsetType::SXTX, 1); + _StoreMemGPR(Size, ZeroConst, Mem, Constant(IR::OpSizeToSize(Size) * 6, ConstPad::NoPad), Size, MemOffsetType::SXTX, 1); } - auto SevenConst = Constant(7); + auto SevenConst = Constant(7, ConstPad::NoPad); const auto LoadSize = ReducedPrecisionMode ? OpSize::i64Bit : OpSize::i128Bit; for (int i = 0; i < 7; ++i) { Ref data = _LoadContextFPRIndexed(Top, LoadSize, MMBaseOffset(), IR::OpSizeToSize(OpSize::i128Bit)); if (ReducedPrecisionMode) { data = _F80CVTTo(data, OpSize::i64Bit); } - _StoreMemFPR(OpSize::i128Bit, data, Mem, Constant((IR::OpSizeToSize(Size) * 7) + (10 * i)), OpSize::i8Bit, MemOffsetType::SXTX, 1); + _StoreMemFPR(OpSize::i128Bit, data, Mem, Constant((IR::OpSizeToSize(Size) * 7) + (10 * i), ConstPad::NoPad), OpSize::i8Bit, + MemOffsetType::SXTX, 1); Top = _And(OpSize::i32Bit, Add(OpSize::i32Bit, Top, 1), SevenConst); } @@ -533,9 +534,11 @@ void OpDispatchBuilder::X87FNSAVE(OpcodeArgs) { // ST7 broken in to two parts // Lower 64bits [63:0] // upper 16 bits [79:64] - _StoreMemFPR(OpSize::i64Bit, data, Mem, Constant((IR::OpSizeToSize(Size) * 7) + (7 * 10)), OpSize::i8Bit, MemOffsetType::SXTX, 1); + _StoreMemFPR(OpSize::i64Bit, data, Mem, Constant((IR::OpSizeToSize(Size) * 7) + (7 * 10), ConstPad::NoPad), OpSize::i8Bit, + MemOffsetType::SXTX, 1); auto topBytes = _VDupElement(OpSize::i128Bit, OpSize::i16Bit, data, 4); - _StoreMemFPR(OpSize::i16Bit, topBytes, Mem, Constant((IR::OpSizeToSize(Size) * 7) + (7 * 10) + 8), OpSize::i8Bit, MemOffsetType::SXTX, 1); + _StoreMemFPR(OpSize::i16Bit, topBytes, Mem, Constant((IR::OpSizeToSize(Size) * 7) + (7 * 10) + 8, ConstPad::NoPad), OpSize::i8Bit, + MemOffsetType::SXTX, 1); // reset to default FNINIT(Op); @@ -552,27 +555,28 @@ void OpDispatchBuilder::X87FRSTOR(OpcodeArgs) { // ignore the rounding precision, we're always 64-bit in F64. // extract rounding mode Ref roundingMode = NewFCW; - auto roundShift = Constant(10); - auto roundMask = Constant(3); + auto roundShift = Constant(10, ConstPad::NoPad); + auto roundMask = Constant(3, ConstPad::NoPad); roundingMode = _Lshr(OpSize::i32Bit, roundingMode, roundShift); roundingMode = _And(OpSize::i32Bit, roundingMode, roundMask); _SetRoundingMode(roundingMode, false, roundingMode); } - auto NewFSW = _LoadMemGPR(Size, Mem, Constant(IR::OpSizeToSize(Size) * 1), Size, MemOffsetType::SXTX, 1); + auto NewFSW = _LoadMemGPR(Size, Mem, Constant(IR::OpSizeToSize(Size) * 1, ConstPad::NoPad), Size, MemOffsetType::SXTX, 1); Ref Top = ReconstructX87StateFromFSW_Helper(NewFSW); { // FTW - SetX87FTW(_LoadMemGPR(Size, Mem, Constant(IR::OpSizeToSize(Size) * 2), Size, MemOffsetType::SXTX, 1)); + SetX87FTW(_LoadMemGPR(Size, Mem, Constant(IR::OpSizeToSize(Size) * 2, ConstPad::NoPad), Size, MemOffsetType::SXTX, 1)); } - auto SevenConst = Constant(7); - auto low = Constant(~0ULL); - auto high = Constant(0xFFFF); + auto SevenConst = Constant(7, ConstPad::NoPad); + auto low = Constant(~0ULL, ConstPad::NoPad); + auto high = Constant(0xFFFF, ConstPad::NoPad); Ref Mask = _VLoadTwoGPRs(low, high); const auto StoreSize = ReducedPrecisionMode ? OpSize::i64Bit : OpSize::i128Bit; for (int i = 0; i < 7; ++i) { - Ref Reg = _LoadMemFPR(OpSize::i128Bit, Mem, Constant((IR::OpSizeToSize(Size) * 7) + (10 * i)), OpSize::i8Bit, MemOffsetType::SXTX, 1); + Ref Reg = _LoadMemFPR(OpSize::i128Bit, Mem, Constant((IR::OpSizeToSize(Size) * 7) + (10 * i), ConstPad::NoPad), OpSize::i8Bit, + MemOffsetType::SXTX, 1); // Mask off the top bits Reg = _VAnd(OpSize::i128Bit, OpSize::i128Bit, Reg, Mask); if (ReducedPrecisionMode) { @@ -588,8 +592,10 @@ void OpDispatchBuilder::X87FRSTOR(OpcodeArgs) { // ST7 broken in to two parts // Lower 64bits [63:0] // upper 16 bits [79:64] - Ref Reg = _LoadMemFPR(OpSize::i64Bit, Mem, Constant((IR::OpSizeToSize(Size) * 7) + (10 * 7)), OpSize::i8Bit, MemOffsetType::SXTX, 1); - Ref RegHigh = _LoadMemFPR(OpSize::i16Bit, Mem, Constant((IR::OpSizeToSize(Size) * 7) + (10 * 7) + 8), OpSize::i8Bit, MemOffsetType::SXTX, 1); + Ref Reg = + _LoadMemFPR(OpSize::i64Bit, Mem, Constant((IR::OpSizeToSize(Size) * 7) + (10 * 7), ConstPad::NoPad), OpSize::i8Bit, MemOffsetType::SXTX, 1); + Ref RegHigh = _LoadMemFPR(OpSize::i16Bit, Mem, Constant((IR::OpSizeToSize(Size) * 7) + (10 * 7) + 8, ConstPad::NoPad), OpSize::i8Bit, + MemOffsetType::SXTX, 1); Reg = _VInsElement(OpSize::i128Bit, OpSize::i16Bit, 4, 0, Reg, RegHigh); if (ReducedPrecisionMode) { Reg = _F80CVT(OpSize::i64Bit, Reg); // Convert to double precision @@ -618,13 +624,13 @@ void OpDispatchBuilder::FXCH(OpcodeArgs) { if (Offset != 0) { _F80StackXchange(Offset); } - SetRFLAG(Constant(0)); + SetRFLAG(Constant(0, ConstPad::NoPad)); } void OpDispatchBuilder::X87FYL2X(OpcodeArgs, bool IsFYL2XP1) { if (IsFYL2XP1) { // create an add between top of stack and 1. - Ref One = ReducedPrecisionMode ? _VCastFromGPR(OpSize::i64Bit, OpSize::i64Bit, Constant(0x3FF0000000000000)) : + Ref One = ReducedPrecisionMode ? _VCastFromGPR(OpSize::i64Bit, OpSize::i64Bit, Constant(0x3FF0000000000000, ConstPad::NoPad)) : LoadAndCacheNamedVectorConstant(OpSize::i128Bit, NamedVectorConstant::NAMED_VECTOR_X87_ONE); _F80AddValue(0, One); } @@ -665,7 +671,7 @@ void OpDispatchBuilder::FCOMI(OpcodeArgs, IR::OpSize Width, bool Integer, OpDisp if (WhichFlags == FCOMIFlags::FLAGS_X87) { SetRFLAG(HostFlag_CF); - SetRFLAG(Constant(0)); + SetRFLAG(Constant(0, ConstPad::NoPad)); SetRFLAG(HostFlag_Unordered); SetRFLAG(HostFlag_ZF); } else { @@ -675,7 +681,7 @@ void OpDispatchBuilder::FCOMI(OpcodeArgs, IR::OpSize Width, bool Integer, OpDisp // PF is stored inverted, so invert from the host flag. // TODO: This could perhaps be optimized? - auto PF = _Xor(OpSize::i32Bit, HostFlag_Unordered, Constant(1)); + auto PF = _Xor(OpSize::i32Bit, HostFlag_Unordered, Constant(1, ConstPad::NoPad)); SetRFLAG(PF); } @@ -700,7 +706,7 @@ void OpDispatchBuilder::FTST(OpcodeArgs) { HostFlag_ZF = _Or(OpSize::i32Bit, HostFlag_ZF, HostFlag_Unordered); SetRFLAG(HostFlag_CF); - SetRFLAG(Constant(0)); + SetRFLAG(Constant(0, ConstPad::NoPad)); SetRFLAG(HostFlag_Unordered); SetRFLAG(HostFlag_ZF); @@ -711,7 +717,7 @@ void OpDispatchBuilder::FTST(OpcodeArgs) { void OpDispatchBuilder::X87OpHelper(OpcodeArgs, FEXCore::IR::IROps IROp, bool ZeroC2) { DeriveOp(Result, IROp, _F80SCALEStack()); if (ZeroC2) { - SetRFLAG(Constant(0)); + SetRFLAG(Constant(0, ConstPad::NoPad)); } } @@ -737,7 +743,7 @@ void OpDispatchBuilder::X87ModifySTP(OpcodeArgs, bool Inc) { Ref OpDispatchBuilder::ReconstructFSW_Helper(Ref T) { // Start with the top value auto Top = T ? T : GetX87Top(); - Ref FSW = _Lshl(OpSize::i64Bit, Top, Constant(11)); + Ref FSW = _Lshl(OpSize::i64Bit, Top, Constant(11, ConstPad::NoPad)); // We must construct the FSW from our various bits auto C0 = GetRFLAG(FEXCore::X86State::X87FLAG_C0_LOC); @@ -775,14 +781,14 @@ void OpDispatchBuilder::FNCLEX(OpcodeArgs) { void OpDispatchBuilder::FNINIT(OpcodeArgs) { _SyncStackToSlow(); // Invalidate x87 register caches - auto Zero = Constant(0); + auto Zero = Constant(0, ConstPad::NoPad); if (ReducedPrecisionMode) { _SetRoundingMode(Zero, false, Zero); } // Init FCW to 0x037F - auto NewFCW = Constant(0x037F); + auto NewFCW = Constant(0x037F, ConstPad::NoPad); _StoreContextGPR(OpSize::i16Bit, NewFCW, offsetof(FEXCore::Core::CPUState, FCW)); // Set top to zero @@ -861,7 +867,7 @@ void OpDispatchBuilder::X87FXAM(OpcodeArgs) { auto TopValid = _StackValidTag(0); // In the case of top being invalid then C3:C2:C0 is 0b101 - auto C3 = Select01(OpSize::i32Bit, CondClass::NEQ, TopValid, Constant(1)); + auto C3 = Select01(OpSize::i32Bit, CondClass::NEQ, TopValid, Constant(1, ConstPad::NoPad)); auto C2 = TopValid; auto C0 = C3; // Mirror C3 until something other than zero is supported diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher/X87F64.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher/X87F64.cpp index 4e1175f60c..60e6a13081 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher/X87F64.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher/X87F64.cpp @@ -36,12 +36,12 @@ void OpDispatchBuilder::X87LDENVF64(OpcodeArgs) { _SetRoundingMode(roundingMode, false, roundingMode); _StoreContextGPR(OpSize::i16Bit, NewFCW, offsetof(FEXCore::Core::CPUState, FCW)); - auto NewFSW = _LoadMemGPR(Size, Mem, Constant(IR::OpSizeToSize(Size)), Size, MemOffsetType::SXTX, 1); + auto NewFSW = _LoadMemGPR(Size, Mem, Constant(IR::OpSizeToSize(Size), ConstPad::NoPad), Size, MemOffsetType::SXTX, 1); ReconstructX87StateFromFSW_Helper(NewFSW); { // FTW - SetX87FTW(_LoadMemGPR(Size, Mem, Constant(IR::OpSizeToSize(Size) * 2), Size, MemOffsetType::SXTX, 1)); + SetX87FTW(_LoadMemGPR(Size, Mem, Constant(IR::OpSizeToSize(Size) * 2, ConstPad::NoPad), Size, MemOffsetType::SXTX, 1)); } } @@ -86,7 +86,7 @@ void OpDispatchBuilder::FBSTPF64(OpcodeArgs) { } void OpDispatchBuilder::FLDF64_Const(OpcodeArgs, uint64_t Num) { - auto Data = _VCastFromGPR(OpSize::i64Bit, OpSize::i64Bit, Constant(Num)); + auto Data = _VCastFromGPR(OpSize::i64Bit, OpSize::i64Bit, Constant(Num, ConstPad::NoPad)); _PushStack(Data, Data, OpSize::i64Bit); } @@ -376,21 +376,21 @@ void OpDispatchBuilder::X87FXTRACTF64(OpcodeArgs) { Ref Gpr = _VExtractToGPR(OpSize::i64Bit, OpSize::i64Bit, Node, 0); // zero case - Ref ExpZV = _VCastFromGPR(OpSize::i64Bit, OpSize::i64Bit, Constant(0xfff0'0000'0000'0000UL)); + Ref ExpZV = _VCastFromGPR(OpSize::i64Bit, OpSize::i64Bit, Constant(0xfff0'0000'0000'0000UL, ConstPad::NoPad)); Ref SigZV = Node; // non zero case Ref ExpNZ = _Bfe(OpSize::i64Bit, 11, 52, Gpr); - ExpNZ = Sub(OpSize::i64Bit, ExpNZ, Constant(1023)); + ExpNZ = Sub(OpSize::i64Bit, ExpNZ, Constant(1023, ConstPad::NoPad)); Ref ExpNZV = _Float_FromGPR_S(OpSize::i64Bit, OpSize::i64Bit, ExpNZ); - Ref SigNZ = _And(OpSize::i64Bit, Gpr, Constant(0x800f'ffff'ffff'ffffLL)); - SigNZ = _Or(OpSize::i64Bit, SigNZ, Constant(0x3ff0'0000'0000'0000LL)); + Ref SigNZ = _And(OpSize::i64Bit, Gpr, Constant(0x800f'ffff'ffff'ffffLL, ConstPad::NoPad)); + SigNZ = _Or(OpSize::i64Bit, SigNZ, Constant(0x3ff0'0000'0000'0000LL, ConstPad::NoPad)); Ref SigNZV = _VCastFromGPR(OpSize::i64Bit, OpSize::i64Bit, SigNZ); // Comparison and select to push onto stack SaveNZCV(); - _TestNZ(OpSize::i64Bit, Gpr, Constant(0x7fff'ffff'ffff'ffffUL)); + _TestNZ(OpSize::i64Bit, Gpr, Constant(0x7fff'ffff'ffff'ffffUL, ConstPad::NoPad)); Ref Sig = _NZCVSelectV(OpSize::i64Bit, CondClass::EQ, SigZV, SigNZV); Ref Exp = _NZCVSelectV(OpSize::i64Bit, CondClass::EQ, ExpZV, ExpNZV); diff --git a/FEXCore/Source/Interface/IR/IR.json b/FEXCore/Source/Interface/IR/IR.json index 0960339c32..4794910489 100644 --- a/FEXCore/Source/Interface/IR/IR.json +++ b/FEXCore/Source/Interface/IR/IR.json @@ -936,7 +936,7 @@ ] }, - "GPR = Constant i64:$Constant, ConstPad:$Pad{ConstPad::AutoPad}, i32:$MaxBytes{0}": { + "GPR = Constant i64:$Constant, ConstPad:$Pad, i32:$MaxBytes{0}": { "Desc": ["Generates a 64bit constant inside of a GPR", "Unsupported to create a constant in FPR" ], diff --git a/FEXCore/Source/Interface/IR/IREmitter.h b/FEXCore/Source/Interface/IR/IREmitter.h index 42667d356c..134416d329 100644 --- a/FEXCore/Source/Interface/IR/IREmitter.h +++ b/FEXCore/Source/Interface/IR/IREmitter.h @@ -184,7 +184,7 @@ class IREmitter { } IRPair To01(FEXCore::IR::OpSize CompareSize, OrderedNode* Cmp1) { - return Select01(CompareSize, CondClass::NEQ, Cmp1, Constant(0)); + return Select01(CompareSize, CondClass::NEQ, Cmp1, Constant(0, ConstPad::NoPad)); } IRPair _NZCVSelect01(CondClass Cond) { @@ -203,7 +203,7 @@ class IREmitter { Src2 = -Src2; } - auto Dest = _Add(Size, Src1, Constant(Src2)); + auto Dest = _Add(Size, Src1, Constant(Src2, ConstPad::NoPad)); Dest.first->Header.Op = Op; return Dest; } @@ -249,7 +249,7 @@ class IREmitter { Ref ConstantRefs[32]; uint32_t NrConstants; - Ref Constant(int64_t Value, ConstPad Pad = ConstPad::AutoPad, int32_t MaxBytes = 0) { + Ref Constant(int64_t Value, ConstPad Pad, int32_t MaxBytes = 0) { const ConstantData Data { .Value = Value, .Pad = Pad,