mirror of
https://github.com/FEX-Emu/FEX.git
synced 2024-12-14 01:18:46 +00:00
AVX128: Implement support for vblend{ps,pd}/vpblendvb
This commit is contained in:
parent
eb3e314946
commit
4544e5b51f
@ -1191,6 +1191,9 @@ public:
|
||||
|
||||
void AVX128_MASKMOV(OpcodeArgs);
|
||||
|
||||
template<size_t ElementSize>
|
||||
void AVX128_VectorVariableBlend(OpcodeArgs);
|
||||
|
||||
// End of AVX 128-bit implementation
|
||||
|
||||
void InvalidOp(OpcodeArgs);
|
||||
|
@ -368,9 +368,9 @@ void OpDispatchBuilder::InstallAVX128Handlers() {
|
||||
|
||||
// TODO: {OPD(3, 0b01, 0x46), 1, &OpDispatchBuilder::VPERM2Op},
|
||||
|
||||
// TODO: {OPD(3, 0b01, 0x4A), 1, &OpDispatchBuilder::AVXVectorVariableBlend<4>},
|
||||
// TODO: {OPD(3, 0b01, 0x4B), 1, &OpDispatchBuilder::AVXVectorVariableBlend<8>},
|
||||
// TODO: {OPD(3, 0b01, 0x4C), 1, &OpDispatchBuilder::AVXVectorVariableBlend<1>},
|
||||
{OPD(3, 0b01, 0x4A), 1, &OpDispatchBuilder::AVX128_VectorVariableBlend<4>},
|
||||
{OPD(3, 0b01, 0x4B), 1, &OpDispatchBuilder::AVX128_VectorVariableBlend<8>},
|
||||
{OPD(3, 0b01, 0x4C), 1, &OpDispatchBuilder::AVX128_VectorVariableBlend<1>},
|
||||
|
||||
{OPD(3, 0b01, 0x60), 1, &OpDispatchBuilder::AVX128_VPCMPESTRM},
|
||||
{OPD(3, 0b01, 0x61), 1, &OpDispatchBuilder::AVX128_VPCMPESTRI},
|
||||
@ -2007,4 +2007,36 @@ void OpDispatchBuilder::AVX128_MASKMOV(OpcodeArgs) {
|
||||
_StoreMem(FPRClass, Size, MemDest, XMMReg, 1);
|
||||
}
|
||||
|
||||
template<size_t ElementSize>
|
||||
void OpDispatchBuilder::AVX128_VectorVariableBlend(OpcodeArgs) {
|
||||
const auto Size = GetSrcSize(Op);
|
||||
const auto Is128Bit = Size == Core::CPUState::XMM_SSE_REG_SIZE;
|
||||
const auto Src3Selector = Op->Src[2].Literal();
|
||||
|
||||
constexpr auto ElementSizeBits = ElementSize * 8;
|
||||
|
||||
auto Src1 = AVX128_LoadSource_WithOpSize(Op, Op->Src[0], Op->Flags, !Is128Bit);
|
||||
auto Src2 = AVX128_LoadSource_WithOpSize(Op, Op->Src[1], Op->Flags, !Is128Bit);
|
||||
|
||||
uint8_t MaskRegister = (Src3Selector >> 4) & 0b1111;
|
||||
RefPair Mask {.Low = AVX128_LoadXMMRegister(MaskRegister, false)};
|
||||
|
||||
if (!Is128Bit) {
|
||||
Mask.High = AVX128_LoadXMMRegister(MaskRegister, true);
|
||||
}
|
||||
|
||||
auto Convert = [this](Ref Src1, Ref Src2, Ref Mask) {
|
||||
Ref Shifted = _VSShrI(OpSize::i128Bit, ElementSize, Mask, ElementSizeBits - 1);
|
||||
return _VBSL(OpSize::i128Bit, Shifted, Src2, Src1);
|
||||
};
|
||||
|
||||
RefPair Result {};
|
||||
Result.Low = Convert(Src1.Low, Src2.Low, Mask.Low);
|
||||
if (!Is128Bit) {
|
||||
Result.High = Convert(Src1.High, Src2.High, Mask.High);
|
||||
}
|
||||
|
||||
AVX128_StoreResult_WithOpSize(Op, Op->Dest, Result);
|
||||
}
|
||||
|
||||
} // namespace FEXCore::IR
|
||||
|
Loading…
Reference in New Issue
Block a user