mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-14 13:00:41 +02:00
OpcodeDispatcher: Move SHUFOp implementation to helper function
Will be useful for handling both the SSE and AVX variants in the same place.
This commit is contained in:
1 parent
3ac7b2cddf
commit
449645669a
2 files changed
+34
-30
No files matched your search
@@ -832,6 +832,11 @@ private:
|
||||
OrderedNode* PSRLDOpImpl(OpcodeArgs, size_t ElementSize,
|
||||
OrderedNode *Src, OrderedNode *ShiftVec);
|
||||
|
||||
OrderedNode* SHUFOpImpl(OpcodeArgs, size_t ElementSize,
|
||||
const X86Tables::DecodedOperand& Src1,
|
||||
const X86Tables::DecodedOperand& Src2,
|
||||
const X86Tables::DecodedOperand& Imm);
|
||||
|
||||
OrderedNode* VFCMPOpImpl(OpcodeArgs, size_t ElementSize, bool Scalar,
|
||||
OrderedNode *Src1, OrderedNode *Src2, uint8_t CompType);
|
||||
|
||||
|
||||
@@ -1100,45 +1100,44 @@ void OpDispatchBuilder::VPSHUFWOp<2, true>(OpcodeArgs);
|
||||
template
|
||||
void OpDispatchBuilder::VPSHUFWOp<4, true>(OpcodeArgs);
|
||||
|
||||
template<size_t ElementSize>
|
||||
void OpDispatchBuilder::SHUFOp(OpcodeArgs) {
|
||||
static_assert(ElementSize != 0);
|
||||
OrderedNode* OpDispatchBuilder::SHUFOpImpl(OpcodeArgs, size_t ElementSize,
|
||||
const X86Tables::DecodedOperand& Src1,
|
||||
const X86Tables::DecodedOperand& Src2,
|
||||
const X86Tables::DecodedOperand& Imm) {
|
||||
OrderedNode *Src1Node = LoadSource(FPRClass, Op, Src1, Op->Flags, -1);
|
||||
OrderedNode *Src2Node = LoadSource(FPRClass, Op, Src2, Op->Flags, -1);
|
||||
|
||||
const auto Size = GetSrcSize(Op);
|
||||
OrderedNode *Src1 = LoadSource(FPRClass, Op, Op->Dest, Op->Flags, -1);
|
||||
OrderedNode *Src2 = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1);
|
||||
uint8_t Shuffle = Op->Src[1].Data.Literal.Value;
|
||||
LOGMAN_THROW_A_FMT(Imm.IsLiteral(), "Imm needs to be a literal");
|
||||
uint8_t Shuffle = Imm.Data.Literal.Value;
|
||||
|
||||
uint8_t NumElements = Size / ElementSize;
|
||||
const uint8_t Size = GetSrcSize(Op);
|
||||
const uint8_t NumElements = Size / ElementSize;
|
||||
|
||||
auto Dest = Src1;
|
||||
std::array<OrderedNode*, 4> Srcs = {
|
||||
};
|
||||
|
||||
for (int i = 0; i < (NumElements >> 1); ++i) {
|
||||
Srcs[i] = Src1;
|
||||
std::array<OrderedNode*, 4> Srcs{};
|
||||
for (size_t i = 0; i < (NumElements >> 1); ++i) {
|
||||
Srcs[i] = Src1Node;
|
||||
}
|
||||
for (size_t i = (NumElements >> 1); i < NumElements; ++i) {
|
||||
Srcs[i] = Src2Node;
|
||||
}
|
||||
|
||||
for (int i = (NumElements >> 1); i < NumElements; ++i) {
|
||||
Srcs[i] = Src2;
|
||||
}
|
||||
|
||||
// 32bit:
|
||||
// [31:0] = Src1[Selection]
|
||||
// [63:32] = Src1[Selection]
|
||||
// [95:64] = Src2[Selection]
|
||||
// [127:96] = Src2[Selection]
|
||||
// 64bit:
|
||||
// [63:0] = Src1[Selection]
|
||||
// [127:64] = Src2[Selection]
|
||||
uint8_t SelectionMask = NumElements - 1;
|
||||
uint8_t ShiftAmount = std::popcount(SelectionMask);
|
||||
OrderedNode *Dest = Src1Node;
|
||||
const uint8_t SelectionMask = NumElements - 1;
|
||||
const uint8_t ShiftAmount = std::popcount(SelectionMask);
|
||||
for (uint8_t Element = 0; Element < NumElements; ++Element) {
|
||||
Dest = _VInsElement(Size, ElementSize, Element, Shuffle & SelectionMask, Dest, Srcs[Element]);
|
||||
const auto SrcIndex = Shuffle & SelectionMask;
|
||||
|
||||
Dest = _VInsElement(Size, ElementSize, Element, SrcIndex, Dest, Srcs[Element]);
|
||||
Shuffle >>= ShiftAmount;
|
||||
}
|
||||
|
||||
StoreResult(FPRClass, Op, Dest, -1);
|
||||
return Dest;
|
||||
}
|
||||
|
||||
template<size_t ElementSize>
|
||||
void OpDispatchBuilder::SHUFOp(OpcodeArgs) {
|
||||
OrderedNode *Result = SHUFOpImpl(Op, ElementSize, Op->Dest, Op->Src[0], Op->Src[1]);
|
||||
StoreResult(FPRClass, Op, Result, -1);
|
||||
}
|
||||
|
||||
template
|
||||
|
||||
Reference in new issue
Block a user