| 1687 | } |
| 1688 | |
| 1689 | void OpDispatchBuilder::BEXTRBMIOp(OpcodeArgs) { |
| 1690 | // Essentially (Src1 >> Start) & ((1 << Length) - 1) |
| 1691 | // along with some edge-case handling and flag setting. |
| 1692 | |
| 1693 | LOGMAN_THROW_A_FMT(Op->InstSize >= 4, "No masking needed"); |
| 1694 | auto* Src1 = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags, {.AllowUpperGarbage = true}); |
| 1695 | auto* Src2 = LoadSource(GPRClass, Op, Op->Src[1], Op->Flags, {.AllowUpperGarbage = true}); |
| 1696 | |
| 1697 | const auto Size = OpSizeFromSrc(Op); |
| 1698 | const auto SrcSize = IR::OpSizeAsBits(Size); |
| 1699 | const auto MaxSrcBit = SrcSize - 1; |
| 1700 | auto MaxSrcBitOp = Constant(MaxSrcBit); |
| 1701 | |
| 1702 | // Shift the operand down to the starting bit |
| 1703 | auto Start = _Bfe(OpSizeFromSrc(Op), 8, 0, Src2); |
| 1704 | auto Shifted = _Lshr(Size, Src1, Start); |
| 1705 | |
| 1706 | // Shifts larger than operand size need to be set to zero. |
| 1707 | auto SanitizedShifted = _Select(Size, Size, CondClassType {IR::COND_ULE}, Start, MaxSrcBitOp, Shifted, Constant(0)); |
| 1708 | |
| 1709 | // Now handle the length specifier. |
| 1710 | auto Length = _Bfe(Size, 8, 8, Src2); |
| 1711 | |
| 1712 | // Now build up the mask |
| 1713 | // (1 << Length) - 1 = ~(~0 << Length) |
| 1714 | auto AllOnes = Constant(~0ull); |
| 1715 | auto InvertedMask = _Lshl(Size, AllOnes, Length); |
| 1716 | |
| 1717 | // Now put it all together and make the result. |
| 1718 | auto Masked = _Andn(Size, SanitizedShifted, InvertedMask); |
| 1719 | |
| 1720 | // Sanitize the length. If it is above the max, we don't do the masking. |
| 1721 | auto Dest = _Select(Size, Size, CondClassType {IR::COND_ULE}, Length, MaxSrcBitOp, Masked, SanitizedShifted); |
| 1722 | |
| 1723 | // Finally store the result. |
| 1724 | StoreResult(GPRClass, Op, Dest, OpSize::iInvalid); |
| 1725 | |
| 1726 | // ZF is set properly. CF and OF are defined as being set to zero. SF, PF, and |
| 1727 | // AF are undefined. |
| 1728 | SetNZ_ZeroCV(GetOpSize(Dest), Dest); |
| 1729 | InvalidatePF_AF(); |
| 1730 | } |
| 1731 | |
| 1732 | void OpDispatchBuilder::BLSIBMIOp(OpcodeArgs) { |
| 1733 | // Equivalent to performing: SRC & -SRC |
nothing calls this directly
no test coverage detected