Skip to content

Commit 0885d8f

Browse files
authored
Simplify ANDN (shadps4-emu#2511)
1 parent f975c06 commit 0885d8f

File tree

1 file changed

+28
-7
lines changed

1 file changed

+28
-7
lines changed

src/core/cpu_patches.cpp

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -264,16 +264,37 @@ static void GenerateANDN(const ZydisDecodedOperand* operands, Xbyak::CodeGenerat
264264
const auto src1 = ZydisToXbyakRegisterOperand(operands[1]);
265265
const auto src2 = ZydisToXbyakOperand(operands[2]);
266266

267-
const auto scratch = AllocateScratchRegister({&dst, &src1, src2.get()}, dst.getBit());
267+
// Check if src2 is a memory operand or a register different to dst.
268+
// In those cases, we don't need to use a temporary register and are free to modify dst.
269+
// In cases where dst and src2 are the same register, a temporary needs to be used to avoid
270+
// modifying src2.
271+
bool src2_uses_dst = false;
272+
if (src2->isMEM()) {
273+
const auto base = src2->getAddress().getRegExp().getBase().getIdx();
274+
const auto index = src2->getAddress().getRegExp().getIndex().getIdx();
275+
src2_uses_dst = base == dst.getIdx() || index == dst.getIdx();
276+
} else {
277+
ASSERT(src2->isREG());
278+
src2_uses_dst = src2->getReg() == dst;
279+
}
268280

269-
SaveRegisters(c, {scratch});
281+
if (!src2_uses_dst) {
282+
if (dst != src1)
283+
c.mov(dst, src1);
284+
c.not_(dst);
285+
c.and_(dst, *src2);
286+
} else {
287+
const auto scratch = AllocateScratchRegister({&dst, &src1, src2.get()}, dst.getBit());
270288

271-
c.mov(scratch, src1);
272-
c.not_(scratch);
273-
c.and_(scratch, *src2);
274-
c.mov(dst, scratch);
289+
SaveRegisters(c, {scratch});
275290

276-
RestoreRegisters(c, {scratch});
291+
c.mov(scratch, src1);
292+
c.not_(scratch);
293+
c.and_(scratch, *src2);
294+
c.mov(dst, scratch);
295+
296+
RestoreRegisters(c, {scratch});
297+
}
277298
}
278299

279300
static void GenerateBEXTR(const ZydisDecodedOperand* operands, Xbyak::CodeGenerator& c) {

0 commit comments

Comments
 (0)