diff --git a/External/FEXCore/Source/Interface/Core/Interpreter/VectorOps.cpp b/External/FEXCore/Source/Interface/Core/Interpreter/VectorOps.cpp index 9fbb74f93..71ffe2ac0 100644 --- a/External/FEXCore/Source/Interface/Core/Interpreter/VectorOps.cpp +++ b/External/FEXCore/Source/Interface/Core/Interpreter/VectorOps.cpp @@ -2280,16 +2280,13 @@ DEF_OP(VRev64) { DEF_OP(VPCMPESTRX) { const auto Op = IROp->C(); - const auto Is64Bit = Op->GPRSize == 8; + const auto Control = Op->Control; const auto RAX = *GetSrc(Data->SSAData, Op->RAX); const auto RDX = *GetSrc(Data->SSAData, Op->RDX); const auto LHS = *GetSrc<__uint128_t*>(Data->SSAData, Op->LHS); const auto RHS = *GetSrc<__uint128_t*>(Data->SSAData, Op->RHS); - // We can be cheeky and encode the size at bit 8 to save a parameter - const auto Control = Op->Control | (uint16_t(Is64Bit) << 8); - const auto Result = OpHandlers::handle(RAX, RDX, LHS, RHS, Control); memset(GDP, 0, sizeof(uint64_t)); diff --git a/External/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp b/External/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp index 911127160..6cd242ef6 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp @@ -450,16 +450,13 @@ void Arm64JITCore::Op_Unhandled(IR::IROp_Header const *IROp, IR::NodeID Node) { PushDynamicRegsAndLR(TMP1); const auto Op = IROp->C(); - const auto Is64Bit = Op->GPRSize == 8; + const auto Control = Op->Control; const auto Src1 = GetVReg(Op->LHS.ID()); const auto Src2 = GetVReg(Op->RHS.ID()); const auto SrcRAX = GetReg(Op->RAX.ID()); const auto SrcRDX = GetReg(Op->RDX.ID()); - // We can be cheeky and encode the size at bit 8 to save a parameter - const auto Control = Op->Control | (uint16_t(Is64Bit) << 8); - mov(ARMEmitter::XReg::x0, SrcRAX.X()); mov(ARMEmitter::XReg::x1, SrcRDX.X()); diff --git a/External/FEXCore/Source/Interface/Core/JIT/x86_64/JIT.cpp b/External/FEXCore/Source/Interface/Core/JIT/x86_64/JIT.cpp index bbabcbe10..a509cd642 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/x86_64/JIT.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/x86_64/JIT.cpp @@ -308,16 +308,13 @@ void X86JITCore::Op_Unhandled(IR::IROp_Header *IROp, IR::NodeID Node) { PushRegs(); const auto Op = IROp->C(); - const auto Is64Bit = Op->GPRSize == 8; + const auto Control = Op->Control; const auto LHS = GetSrc(Op->LHS.ID()); const auto RHS = GetSrc(Op->RHS.ID()); const auto SrcRAX = GetSrc(Op->RAX.ID()); const auto SrcRDX = GetSrc(Op->RDX.ID()); - // Encode the size check into the 8th bit to save a parameter - const auto Control = Op->Control | (uint16_t(Is64Bit) << 8); - mov(rdi, SrcRAX); mov(rsi, SrcRDX); diff --git a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp index db7545f52..516db3b77 100644 --- a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp +++ b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp @@ -4812,7 +4812,7 @@ void OpDispatchBuilder::VPERMILRegOp<8>(OpcodeArgs); void OpDispatchBuilder::PCMPXSTRXOpImpl(OpcodeArgs, bool IsExplicit, bool IsMask) { LOGMAN_THROW_A_FMT(Op->Src[1].IsLiteral(), "Src[1] needs to be a literal"); - const auto Control = Op->Src[1].Data.Literal.Value; + const uint16_t Control = Op->Src[1].Data.Literal.Value; // SSE4.2 string instructions modify flags, so invalidate // any previously deferred flags. @@ -4830,12 +4830,18 @@ void OpDispatchBuilder::PCMPXSTRXOpImpl(OpcodeArgs, bool IsExplicit, bool IsMask OrderedNode *IntermediateResult{}; if (IsExplicit) { // Will be 4 in the absence of a REX.W bit and 8 in the presence of a REX.W bit. + // + // While the control bit immediate for the instruction itself is only ever 8 bits + // in size, we use it as a 16-bit value so that we can use the 8th bit to signify + // whether or not RAX and RDX should be interpreted as a 64-bit value. const auto SrcSize = GetSrcSize(Op); + const auto Is64Bit = SrcSize == 8; + const auto NewControl = uint16_t(Control | (uint16_t(Is64Bit) << 8)); OrderedNode *SrcRAX = LoadGPRRegister(X86State::REG_RAX); OrderedNode *SrcRDX = LoadGPRRegister(X86State::REG_RDX); - IntermediateResult = _VPCMPESTRX(SrcSize, Src1, Src2, SrcRAX, SrcRDX, Control); + IntermediateResult = _VPCMPESTRX(Src1, Src2, SrcRAX, SrcRDX, NewControl); } else { IntermediateResult = _VPCMPISTRX(Src1, Src2, Control); } diff --git a/External/FEXCore/Source/Interface/IR/IR.json b/External/FEXCore/Source/Interface/IR/IR.json index ee7c50c74..62845de93 100644 --- a/External/FEXCore/Source/Interface/IR/IR.json +++ b/External/FEXCore/Source/Interface/IR/IR.json @@ -1405,7 +1405,7 @@ "DestSize": "RegisterSize" }, - "GPR = VPCMPESTRX u8:$GPRSize, FPR:$LHS, FPR:$RHS, GPR:$RAX, GPR:$RDX, u8:$Control": { + "GPR = VPCMPESTRX FPR:$LHS, FPR:$RHS, GPR:$RAX, GPR:$RDX, u16:$Control": { "Desc": ["Performs intermediate behavior analogous to the x86 PCMPESTRI/PCMPESTRM instruction", "This will return the intermediate result of a PCMPESTR-type operation, but NOT the final", "result. This must be derived from the intermediate result", @@ -1414,7 +1414,6 @@ "flags into the upper 16-bits of the 32-bit result, as these can also be derived over the", "course of creating the intermediate result" ], - "HasSideEffects": true, "DestSize": "4" }, "GPR = VPCMPISTRX FPR:$LHS, FPR:$RHS, u8:$Control": { @@ -1426,7 +1425,6 @@ "flags into the upper 16-bits of the 32-bit result, as these can also be derived over the", "course of creating the intermediate result" ], - "HasSideEffects": true, "DestSize": "4" } },