From c5e6352c349ca65b7119bab08d19797e95eb1509 Mon Sep 17 00:00:00 2001 From: Gliniak Date: Mon, 7 Mar 2022 08:17:51 +0100 Subject: [PATCH] [CPU] Added constant propagation pass for: OPCODE_AND_NOT --- src/xenia/cpu/backend/x64/x64_sequences.cc | 36 ++++++++----------- .../passes/constant_propagation_pass.cc | 9 +++++ 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/src/xenia/cpu/backend/x64/x64_sequences.cc b/src/xenia/cpu/backend/x64/x64_sequences.cc index d8da70122..dabd65b2b 100644 --- a/src/xenia/cpu/backend/x64/x64_sequences.cc +++ b/src/xenia/cpu/backend/x64/x64_sequences.cc @@ -2697,34 +2697,28 @@ EMITTER_OPCODE_TABLE(OPCODE_AND, AND_I8, AND_I16, AND_I32, AND_I64, AND_V128); template void EmitAndNotXX(X64Emitter& e, const ARGS& i) { if (i.src1.is_constant) { - if (i.src2.is_constant) { - // Both constants. - e.mov(i.dest, i.src1.constant() & ~i.src2.constant()); - } else { - // src1 constant. + // src1 constant. + // `and` instruction only supports up to 32-bit immediate constants + // 64-bit constants will need a temp register + if (i.dest.reg().getBit() == 64) { + auto temp = GetTempReg(e); + e.mov(temp, i.src1.constant()); - // `and` instruction only supports up to 32-bit immediate constants - // 64-bit constants will need a temp register - if (i.dest.reg().getBit() == 64) { - auto temp = GetTempReg(e); - e.mov(temp, i.src1.constant()); - - if (e.IsFeatureEnabled(kX64EmitBMI1)) { - if (i.dest.reg().getBit() == 64) { - e.andn(i.dest.reg().cvt64(), i.src2.reg().cvt64(), temp.cvt64()); - } else { - e.andn(i.dest.reg().cvt32(), i.src2.reg().cvt32(), temp.cvt32()); - } + if (e.IsFeatureEnabled(kX64EmitBMI1)) { + if (i.dest.reg().getBit() == 64) { + e.andn(i.dest.reg().cvt64(), i.src2.reg().cvt64(), temp.cvt64()); } else { - e.mov(i.dest, i.src2); - e.not_(i.dest); - e.and_(i.dest, temp); + e.andn(i.dest.reg().cvt32(), i.src2.reg().cvt32(), temp.cvt32()); } } else { e.mov(i.dest, i.src2); e.not_(i.dest); - e.and_(i.dest, uint32_t(i.src1.constant())); + e.and_(i.dest, temp); } + } else { + e.mov(i.dest, i.src2); + e.not_(i.dest); + e.and_(i.dest, uint32_t(i.src1.constant())); } } else if (i.src2.is_constant) { // src2 constant. diff --git a/src/xenia/cpu/compiler/passes/constant_propagation_pass.cc b/src/xenia/cpu/compiler/passes/constant_propagation_pass.cc index b6b0376fa..77c3f21b6 100644 --- a/src/xenia/cpu/compiler/passes/constant_propagation_pass.cc +++ b/src/xenia/cpu/compiler/passes/constant_propagation_pass.cc @@ -648,6 +648,15 @@ bool ConstantPropagationPass::Run(HIRBuilder* builder, bool& result) { result = true; } break; + case OPCODE_AND_NOT: + if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { + v->set_from(i->src2.value); + v->Not(); + v->And(i->src1.value); + i->Remove(); + result = true; + } + break; case OPCODE_OR: if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { v->set_from(i->src1.value);