From 24d4e1e0e55333cc4561bb39bd306f7a21af0506 Mon Sep 17 00:00:00 2001 From: Wunkolo Date: Sun, 2 Jan 2022 16:56:04 -0800 Subject: [PATCH] [x64] Add `BMI1`-based acceleration for `AndNot` In the case of having two register operands for `AndNot`, the `andn` instruction can be used when the host supports `BMI1`. `andn` only supports 32-bit and 64-bit operands, so some register up-casting is needed. --- src/xenia/cpu/backend/x64/x64_sequences.cc | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/xenia/cpu/backend/x64/x64_sequences.cc b/src/xenia/cpu/backend/x64/x64_sequences.cc index 90471b248..15ddebef3 100644 --- a/src/xenia/cpu/backend/x64/x64_sequences.cc +++ b/src/xenia/cpu/backend/x64/x64_sequences.cc @@ -2656,13 +2656,23 @@ void EmitAndNotXX(X64Emitter& e, const ARGS& i) { } } else { // neither are constant - if (i.dest == i.src2) { - e.not_(i.dest); - e.and_(i.dest, i.src1); + if (e.IsFeatureEnabled(kX64EmitBMI1)) { + if (i.dest.reg().getBit() == 64) { + e.andn(i.dest.reg().cvt64(), i.src2.reg().cvt64(), + i.src1.reg().cvt64()); + } else { + e.andn(i.dest.reg().cvt32(), i.src2.reg().cvt32(), + i.src1.reg().cvt32()); + } } else { - e.mov(i.dest, i.src2); - e.not_(i.dest); - e.and_(i.dest, i.src1); + if (i.dest == i.src2) { + e.not_(i.dest); + e.and_(i.dest, i.src1); + } else { + e.mov(i.dest, i.src2); + e.not_(i.dest); + e.and_(i.dest, i.src1); + } } } }