OpcodeDispatcher: Handle PCMPESTRI/VPCMPESTRI

This commit is contained in:
Lioncache committed 2023-04-17 21:42:58 -04:00
1 parent 30cb1aaaed
commit 39c73d975b
13 files changed
+1420 -4

No files matched your search

@@ -5978,6 +5978,8 @@ void OpDispatchBuilder::InstallHostSpecificOpcodeHandlers() {
{OPD(3, 0b01, 0x4B), 1, &OpDispatchBuilder::AVXVectorVariableBlend<8>},
{OPD(3, 0b01, 0x4C), 1, &OpDispatchBuilder::AVXVectorVariableBlend<1>},
{OPD(3, 0b01, 0x61), 1, &OpDispatchBuilder::VPCMPESTRIOp},
{OPD(3, 0b01, 0xDF), 1, &OpDispatchBuilder::VAESKeyGenAssistOp},
};
#undef OPD
@@ -7266,6 +7268,8 @@ constexpr uint16_t PF_F2 = 3;
{OPD(0, PF_3A_66, 0x41), 1, &OpDispatchBuilder::DPPOp<8>},
{OPD(0, PF_3A_66, 0x42), 1, &OpDispatchBuilder::MPSADBWOp},
{OPD(0, PF_3A_66, 0x61), 1, &OpDispatchBuilder::VPCMPESTRIOp},
{OPD(0, PF_3A_NONE, 0xCC), 1, &OpDispatchBuilder::SHA1RNDS4Op},
};
#undef PF_3A_NONE
@@ -487,6 +487,8 @@ public:
void VPALIGNROp(OpcodeArgs);
void VPCMPESTRIOp(OpcodeArgs);
void VPERM2Op(OpcodeArgs);
void VPERMDOp(OpcodeArgs);
void VPERMQOp(OpcodeArgs);
@@ -853,6 +855,11 @@ private:
const X86Tables::DecodedOperand& Src2,
const X86Tables::DecodedOperand& Imm);
OrderedNode* PCMPESTRXOpImpl(OpcodeArgs,
const X86Tables::DecodedOperand& Src1,
const X86Tables::DecodedOperand& Src2,
const X86Tables::DecodedOperand& Imm);
OrderedNode* PHADDSOpImpl(OpcodeArgs, const X86Tables::DecodedOperand& Src1,
const X86Tables::DecodedOperand& Src2);
@@ -4552,4 +4552,77 @@ void OpDispatchBuilder::VPERMILRegOp<4>(OpcodeArgs);
template
void OpDispatchBuilder::VPERMILRegOp<8>(OpcodeArgs);
OrderedNode* OpDispatchBuilder::PCMPESTRXOpImpl(OpcodeArgs,
const X86Tables::DecodedOperand& Src1Op,
const X86Tables::DecodedOperand& Src2Op,
const X86Tables::DecodedOperand& Imm) {
LOGMAN_THROW_A_FMT(Imm.IsLiteral(), "Imm needs to be a literal");
const auto Control = Imm.Data.Literal.Value;
// Will be 4 in the absence of a REX.W bit and 8 in the presence of a REX.W bit.
const auto SrcSize = GetSrcSize(Op);
// SSE4.2 string instructions modify flags, so invalidate
// any previously deferred flags.
InvalidateDeferredFlags();
// NOTE: Unlike most other SSE/AVX instructions, the SSE4.2 string and text
// instructions do *not* require memory operands to be aligned on a 16 byte
// boundary (see "Other Exceptions" descriptions for the relevant
// instructions in the Intel Software Development Manual).
//
// So, we specify Src2 as having an alignment of 1 to indicate this.
OrderedNode *Src1 = LoadSource_WithOpSize(FPRClass, Op, Src1Op, 16, Op->Flags, -1);
OrderedNode *Src2 = LoadSource_WithOpSize(FPRClass, Op, Src2Op, 16, Op->Flags, 1);
OrderedNode *SrcRAX = LoadGPRRegister(X86State::REG_RAX);
OrderedNode *SrcRDX = LoadGPRRegister(X86State::REG_RDX);
OrderedNode *IntermediateResult = _VPCMPESTRX(SrcSize, Src1, Src2, SrcRAX, SrcRDX, Control);
OrderedNode *ResultNoFlags = _And(IntermediateResult, _Constant(0xFFFF));
// For the indexed variant of the instructions, if control[6] is set, then we
// store the index of the most significant bit into ECX. If it's not set,
// then we store the least significant bit.
OrderedNode *ZeroConst = _Constant(0);
const auto ECXResult = [&]() -> OrderedNode* {
const auto UseMSBIndex = (Control & 0b0100'0000) != 0;
OrderedNode *IfZero = _Constant(16 >> (Control & 1));
OrderedNode *IfNotZero = UseMSBIndex ? _FindMSB(ResultNoFlags)
: _FindLSB(ResultNoFlags);
return _Select(IR::COND_EQ, ResultNoFlags, ZeroConst,
IfZero, IfNotZero);
}();
// Set all of the necessary flags.
// We use the top 16-bits of the result to store the flags
// in the form:
//
// Bit: 19 18 17 16
// [OF | CF | SF | ZF]
//
const auto GetFlagBit = [this, IntermediateResult](int BitIndex) {
return _Bfe(1, BitIndex, IntermediateResult);
};
SetRFLAG<X86State::RFLAG_ZF_LOC>(GetFlagBit(16));
SetRFLAG<X86State::RFLAG_SF_LOC>(GetFlagBit(17));
SetRFLAG<X86State::RFLAG_CF_LOC>(GetFlagBit(18));
SetRFLAG<X86State::RFLAG_OF_LOC>(GetFlagBit(19));
SetRFLAG<X86State::RFLAG_AF_LOC>(ZeroConst);
SetRFLAG<X86State::RFLAG_PF_LOC>(ZeroConst);
// ... and we're done!
return ECXResult;
}
void OpDispatchBuilder::VPCMPESTRIOp(OpcodeArgs) {
OrderedNode *Result = PCMPESTRXOpImpl(Op, Op->Dest, Op->Src[0], Op->Src[1]);
StoreGPRRegister(X86State::REG_RCX, Result, 4);
}
}
@@ -45,9 +45,9 @@ void InitializeH0F3ATables(Context::OperatingMode Mode) {
{OPD(0, PF_3A_66, 0x44), 1, X86InstInfo{"PCLMULQDQ", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 1, nullptr}},
{OPD(0, PF_3A_66, 0x60), 1, X86InstInfo{"PCMPESTRM", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}},
{OPD(0, PF_3A_66, 0x61), 1, X86InstInfo{"PCMPESTRI", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}},
{OPD(0, PF_3A_66, 0x61), 1, X86InstInfo{"PCMPESTRI", TYPE_INST, GenFlagsSizes(SIZE_128BIT, SIZE_32BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 1, nullptr}},
{OPD(0, PF_3A_66, 0x62), 1, X86InstInfo{"PCMPISTRM", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}},
{OPD(0, PF_3A_66, 0x63), 1, X86InstInfo{"PCMPISTRI", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 1, nullptr}},
{OPD(0, PF_3A_66, 0x63), 1, X86InstInfo{"PCMPISTRI", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}},
{OPD(0, PF_3A_NONE, 0xCC), 1, X86InstInfo{"SHA1RNDS4", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 1, nullptr}},
@@ -453,9 +453,9 @@ void InitializeVEXTables() {
{OPD(3, 0b01, 0x5F), 1, X86InstInfo{"VFMSUBADDPD", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}},
{OPD(3, 0b01, 0x60), 1, X86InstInfo{"VPCMPESTRM", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}},
{OPD(3, 0b01, 0x61), 1, X86InstInfo{"VPCMPESTRI", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}},
{OPD(3, 0b01, 0x61), 1, X86InstInfo{"VPCMPESTRI", TYPE_INST, GenFlagsSizes(SIZE_128BIT, SIZE_32BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 1, nullptr}},
{OPD(3, 0b01, 0x62), 1, X86InstInfo{"VPCMPISTRM", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}},
{OPD(3, 0b01, 0x63), 1, X86InstInfo{"VPCMPISTRI", TYPE_INST, FLAGS_MODRM | FLAGS_XMM_FLAGS, 1, nullptr}},
{OPD(3, 0b01, 0x63), 1, X86InstInfo{"VPCMPISTRI", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}},
{OPD(3, 0b01, 0x68), 1, X86InstInfo{"VFMADDPS", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}},
{OPD(3, 0b01, 0x69), 1, X86InstInfo{"VFMADDPD", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}},