#include #include namespace Codegen { namespace { constexpr std::uint8_t kPrefixPacked = 0x66; constexpr std::uint8_t kScratch = 0; constexpr std::uint64_t kLineMask = ~std::uint64_t{63}; constexpr std::array kPushRcx = {0x51}; constexpr std::array kPopRcx = {0x59}; constexpr std::array kMovqXmm0Rax = {0x66, 0x48, 0x0F, 0x6E, 0xC0}; constexpr std::array kMovdXmm0Eax = {0x66, 0x0F, 0x6E, 0xC0}; constexpr std::array kMovqRcxXmm0 = {0x66, 0x48, 0x0F, 0x7E, 0xC1}; constexpr std::array kMovntdqRcx = {0x66, 0x0F, 0xE7, 0x01}; constexpr std::array kMovntdqRcx16 = {0x66, 0x0F, 0xE7, 0x41, 0x10}; constexpr std::array kMovntdqRcx32 = {0x66, 0x0F, 0xE7, 0x41, 0x20}; constexpr std::array kMovntdqRcx48 = {0x66, 0x0F, 0xE7, 0x41, 0x30}; } void ClzeroLowering::EmitOutOfLine(StubBodyBuilder& body, const ClzeroOperands& operands) const { StubConstant lineMask{}; for (std::size_t byte = 0; byte < 8; ++byte) lineMask[byte] = static_cast(kLineMask >> (byte * 8)); body.Spill(kScratch); body.Raw(kPushRcx); if (operands.AddressSize32) body.Raw(kMovdXmm0Eax); else body.Raw(kMovqXmm0Rax); body.RipOperand({0x0F, 0xDB}, kScratch, lineMask); body.Raw(kMovqRcxXmm0); body.Sse(kPrefixPacked, {0x0F, 0xEF}, kScratch, kScratch); body.Raw(kMovntdqRcx); body.Raw(kMovntdqRcx16); body.Raw(kMovntdqRcx32); body.Raw(kMovntdqRcx48); body.Raw(kPopRcx); body.Restore(kScratch); } LoweredBody ClzeroLowering::LowerOutOfLine(const ClzeroOperands& operands, std::span trailing) const { StubBodyBuilder body; EmitOutOfLine(body, operands); body.Raw(trailing); return body.Finish(); } }