AVX128: Implement support for vpmovmskb

This commit is contained in:
Ryan Houdek authored and Alyssa Rosenzweig committed 2024-06-21 15:53:52 -04:00
1 parent b58a57d225
commit ad122cf463
2 files changed
+31 -1

No files matched your search

@@ -1045,6 +1045,7 @@ public:
void AVX128_ExtendVectorElements(OpcodeArgs);
template<size_t ElementSize>
void AVX128_MOVMSK(OpcodeArgs);
void AVX128_MOVMSKB(OpcodeArgs);
// End of AVX 128-bit implementation
@@ -199,7 +199,7 @@ void OpDispatchBuilder::InstallAVX128Handlers() {
{OPD(1, 0b01, 0xD4), 1, &OpDispatchBuilder::AVX128_VectorALU<IR::OP_VADD, 8>},
{OPD(1, 0b01, 0xD5), 1, &OpDispatchBuilder::AVX128_VectorALU<IR::OP_VMUL, 2>},
{OPD(1, 0b01, 0xD6), 1, &OpDispatchBuilder::AVX128_MOVQ},
// TODO: {OPD(1, 0b01, 0xD7), 1, &OpDispatchBuilder::MOVMSKOpOne},
{OPD(1, 0b01, 0xD7), 1, &OpDispatchBuilder::AVX128_MOVMSKB},
{OPD(1, 0b01, 0xD8), 1, &OpDispatchBuilder::AVX128_VectorALU<IR::OP_VUQSUB, 1>},
{OPD(1, 0b01, 0xD9), 1, &OpDispatchBuilder::AVX128_VectorALU<IR::OP_VUQSUB, 2>},
@@ -1145,4 +1145,33 @@ void OpDispatchBuilder::AVX128_MOVMSK(OpcodeArgs) {
StoreResult_WithOpSize(GPRClass, Op, Op->Dest, GPR, CTX->GetGPRSize(), -1);
}
void OpDispatchBuilder::AVX128_MOVMSKB(OpcodeArgs) {
const auto SrcSize = GetSrcSize(Op);
const auto Is128Bit = SrcSize == Core::CPUState::XMM_SSE_REG_SIZE;
auto Src = AVX128_LoadSource_WithOpSize(Op, Op->Src[0], Op->Flags, !Is128Bit);
Ref VMask = LoadAndCacheNamedVectorConstant(OpSize::i128Bit, NAMED_VECTOR_MOVMASKB);
auto Mask1Byte = [this](Ref Src, Ref VMask) {
auto VCMP = _VCMPLTZ(OpSize::i128Bit, OpSize::i8Bit, Src);
auto VAnd = _VAnd(OpSize::i128Bit, OpSize::i8Bit, VCMP, VMask);
auto VAdd1 = _VAddP(OpSize::i128Bit, OpSize::i8Bit, VAnd, VAnd);
auto VAdd2 = _VAddP(OpSize::i128Bit, OpSize::i8Bit, VAdd1, VAdd1);
auto VAdd3 = _VAddP(OpSize::i64Bit, OpSize::i8Bit, VAdd2, VAdd2);
///< 16-bits of data per 128-bit
return _VExtractToGPR(OpSize::i128Bit, 2, VAdd3, 0);
};
Ref Result = Mask1Byte(Src.Low, VMask);
if (!Is128Bit) {
auto ResultHigh = Mask1Byte(Src.High, VMask);
Result = _Orlshl(OpSize::i64Bit, Result, ResultHigh, 16);
}
StoreResult(GPRClass, Op, Result, -1);
}
} // namespace FEXCore::IR