| 774 | } |
| 775 | |
| 776 | void OpDispatchBuilder::MOVMSKOpOne(OpcodeArgs) { |
| 777 | const auto SrcSize = OpSizeFromSrc(Op); |
| 778 | const auto Is256Bit = SrcSize == OpSize::i256Bit; |
| 779 | const auto ExtractSize = Is256Bit ? OpSize::i32Bit : OpSize::i16Bit; |
| 780 | |
| 781 | Ref Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags); |
| 782 | Ref VMask = LoadAndCacheNamedVectorConstant(SrcSize, NAMED_VECTOR_MOVMASKB); |
| 783 | |
| 784 | auto VCMP = _VCMPLTZ(SrcSize, OpSize::i8Bit, Src); |
| 785 | auto VAnd = _VAnd(SrcSize, OpSize::i8Bit, VCMP, VMask); |
| 786 | |
| 787 | // Since we also handle the MM MOVMSKB here too, |
| 788 | // we need to clamp the lower bound. |
| 789 | const auto VAdd1Size = std::max(SrcSize, OpSize::i128Bit); |
| 790 | const auto VAdd2Size = std::max(SrcSize >> 1, OpSize::i64Bit); |
| 791 | |
| 792 | auto VAdd1 = _VAddP(VAdd1Size, OpSize::i8Bit, VAnd, VAnd); |
| 793 | auto VAdd2 = _VAddP(VAdd2Size, OpSize::i8Bit, VAdd1, VAdd1); |
| 794 | auto VAdd3 = _VAddP(OpSize::i64Bit, OpSize::i8Bit, VAdd2, VAdd2); |
| 795 | |
| 796 | auto Result = _VExtractToGPR(SrcSize, ExtractSize, VAdd3, 0); |
| 797 | |
| 798 | StoreResult(GPRClass, Op, Result, OpSize::iInvalid); |
| 799 | } |
| 800 | |
| 801 | void OpDispatchBuilder::PUNPCKLOp(OpcodeArgs, IR::OpSize ElementSize) { |
| 802 | const auto Size = OpSizeFromSrc(Op); |
nothing calls this directly
no outgoing calls
no test coverage detected