summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGliniak <Gliniak93@gmail.com>2022-03-07 08:17:51 +0100
committerTriang3l <triang3l@yandex.ru>2023-07-27 23:41:45 +0300
commitc5e6352c349ca65b7119bab08d19797e95eb1509 (patch)
treee882744fd558eb8281720d00cd94c9b3e6f50d70 /src
parent1887ea0795ab050ad8f2e2ef3e1918b0f342d3b4 (diff)
[CPU] Added constant propagation pass for: OPCODE_AND_NOT
Diffstat (limited to 'src')
-rw-r--r--src/xenia/cpu/backend/x64/x64_sequences.cc38
-rw-r--r--src/xenia/cpu/compiler/passes/constant_propagation_pass.cc9
2 files changed, 25 insertions, 22 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 <typename SEQ, typename REG, typename ARGS>
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.
-
- // `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<typename decltype(i.src1)::reg_type>(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());
- }
+ // 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<typename decltype(i.src1)::reg_type>(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.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);