MCPcopy Create free account
hub / github.com/FEX-Emu/FEX / InsertPSOpImpl

Method InsertPSOpImpl

FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp:1571–1615  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1569}
1570
1571Ref OpDispatchBuilder::InsertPSOpImpl(OpcodeArgs, const X86Tables::DecodedOperand& Src1, const X86Tables::DecodedOperand& Src2,
1572 const X86Tables::DecodedOperand& Imm) {
1573 const uint8_t ImmValue = Imm.Literal();
1574 uint8_t CountS = (ImmValue >> 6);
1575 uint8_t CountD = (ImmValue >> 4) & 0b11;
1576 const uint8_t ZMask = ImmValue & 0xF;
1577
1578 const auto DstSize = OpSizeFromDst(Op);
1579
1580 Ref Dest {};
1581 if (ZMask != 0xF) {
1582 // Only need to load destination if it isn't a full zero
1583 Dest = LoadSource_WithOpSize(FPRClass, Op, Src1, DstSize, Op->Flags);
1584 }
1585
1586 if ((ZMask & (1 << CountD)) == 0) {
1587 // In the case that ZMask overwrites the destination element, then don't even insert
1588 Ref Src {};
1589 if (Src2.IsGPR()) {
1590 Src = LoadSource(FPRClass, Op, Src2, Op->Flags);
1591 } else {
1592 // If loading from memory then CountS is forced to zero
1593 CountS = 0;
1594 Src = LoadSource_WithOpSize(FPRClass, Op, Src2, OpSize::i32Bit, Op->Flags);
1595 }
1596
1597 Dest = _VInsElement(DstSize, OpSize::i32Bit, CountD, CountS, Dest, Src);
1598 }
1599
1600 // ZMask happens after insert
1601 if (ZMask == 0xF) {
1602 return LoadZeroVector(DstSize);
1603 }
1604
1605 if (ZMask) {
1606 auto Zero = LoadZeroVector(DstSize);
1607 for (size_t i = 0; i < 4; ++i) {
1608 if ((ZMask & (1 << i)) != 0) {
1609 Dest = _VInsElement(DstSize, OpSize::i32Bit, i, 0, Dest, Zero);
1610 }
1611 }
1612 }
1613
1614 return Dest;
1615}
1616
1617void OpDispatchBuilder::InsertPSOp(OpcodeArgs) {
1618 Ref Result = InsertPSOpImpl(Op, Op->Dest, Op->Src[0], Op->Src[1]);

Callers

nothing calls this directly

Calls 2

LiteralMethod · 0.80
IsGPRMethod · 0.45

Tested by

no test coverage detected