| 1625 | } |
| 1626 | |
| 1627 | void OpDispatchBuilder::PExtrOp(OpcodeArgs, IR::OpSize ElementSize) { |
| 1628 | const auto DstSize = OpSizeFromDst(Op); |
| 1629 | |
| 1630 | Ref Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags); |
| 1631 | uint64_t Index = Op->Src[1].Literal(); |
| 1632 | |
| 1633 | // Fixup of 32-bit element size. |
| 1634 | // When the element size is 32-bit then it can be overriden as 64-bit because the encoding of PEXTRD/PEXTRQ |
| 1635 | // is the same except that REX.W or VEX.W is set to 1. Incredibly frustrating. |
| 1636 | // Use the destination size as the element size in this case. |
| 1637 | auto OverridenElementSize = ElementSize; |
| 1638 | if (ElementSize == OpSize::i32Bit) { |
| 1639 | OverridenElementSize = DstSize; |
| 1640 | } |
| 1641 | |
| 1642 | // AVX version only operates on 128-bit. |
| 1643 | const uint8_t NumElements = IR::NumElements(std::min(OpSizeFromSrc(Op), OpSize::i128Bit), OverridenElementSize); |
| 1644 | Index &= NumElements - 1; |
| 1645 | |
| 1646 | if (Op->Dest.IsGPR()) { |
| 1647 | const auto GPRSize = GetGPROpSize(); |
| 1648 | // Extract already zero extends the result. |
| 1649 | Ref Result = _VExtractToGPR(OpSize::i128Bit, OverridenElementSize, Src, Index); |
| 1650 | StoreResult_WithOpSize(GPRClass, Op, Op->Dest, Result, GPRSize, OpSize::iInvalid); |
| 1651 | return; |
| 1652 | } |
| 1653 | |
| 1654 | // If we are storing to memory then we store the size of the element extracted |
| 1655 | Ref Dest = MakeSegmentAddress(Op, Op->Dest); |
| 1656 | _VStoreVectorElement(OpSize::i128Bit, OverridenElementSize, Src, Index, Dest); |
| 1657 | } |
| 1658 | |
| 1659 | void OpDispatchBuilder::VEXTRACT128Op(OpcodeArgs) { |
| 1660 | const auto DstIsXMM = Op->Dest.IsGPR(); |
nothing calls this directly
no test coverage detected