Simplify ANDN (#2511)

This commit is contained in:
Paris Oplopoios 2025-02-24 12:53:11 +02:00 committed by GitHub
parent f975c0603c
commit 0885d8fce7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -264,6 +264,26 @@ static void GenerateANDN(const ZydisDecodedOperand* operands, Xbyak::CodeGenerat
const auto src1 = ZydisToXbyakRegisterOperand(operands[1]);
const auto src2 = ZydisToXbyakOperand(operands[2]);
// Check if src2 is a memory operand or a register different to dst.
// In those cases, we don't need to use a temporary register and are free to modify dst.
// In cases where dst and src2 are the same register, a temporary needs to be used to avoid
// modifying src2.
bool src2_uses_dst = false;
if (src2->isMEM()) {
const auto base = src2->getAddress().getRegExp().getBase().getIdx();
const auto index = src2->getAddress().getRegExp().getIndex().getIdx();
src2_uses_dst = base == dst.getIdx() || index == dst.getIdx();
} else {
ASSERT(src2->isREG());
src2_uses_dst = src2->getReg() == dst;
}
if (!src2_uses_dst) {
if (dst != src1)
c.mov(dst, src1);
c.not_(dst);
c.and_(dst, *src2);
} else {
const auto scratch = AllocateScratchRegister({&dst, &src1, src2.get()}, dst.getBit());
SaveRegisters(c, {scratch});
@ -274,6 +294,7 @@ static void GenerateANDN(const ZydisDecodedOperand* operands, Xbyak::CodeGenerat
c.mov(dst, scratch);
RestoreRegisters(c, {scratch});
}
}
static void GenerateBEXTR(const ZydisDecodedOperand* operands, Xbyak::CodeGenerator& c) {