Skip to content

Commit c5e6352

Browse files
GliniakTriang3l
authored andcommitted
[CPU] Added constant propagation pass for: OPCODE_AND_NOT
1 parent 1887ea0 commit c5e6352

File tree

2 files changed

+25
-22
lines changed

2 files changed

+25
-22
lines changed

src/xenia/cpu/backend/x64/x64_sequences.cc

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2697,34 +2697,28 @@ EMITTER_OPCODE_TABLE(OPCODE_AND, AND_I8, AND_I16, AND_I32, AND_I64, AND_V128);
26972697
template <typename SEQ, typename REG, typename ARGS>
26982698
void EmitAndNotXX(X64Emitter& e, const ARGS& i) {
26992699
if (i.src1.is_constant) {
2700-
if (i.src2.is_constant) {
2701-
// Both constants.
2702-
e.mov(i.dest, i.src1.constant() & ~i.src2.constant());
2703-
} else {
2704-
// src1 constant.
2705-
2706-
// `and` instruction only supports up to 32-bit immediate constants
2707-
// 64-bit constants will need a temp register
2708-
if (i.dest.reg().getBit() == 64) {
2709-
auto temp = GetTempReg<typename decltype(i.src1)::reg_type>(e);
2710-
e.mov(temp, i.src1.constant());
2711-
2712-
if (e.IsFeatureEnabled(kX64EmitBMI1)) {
2713-
if (i.dest.reg().getBit() == 64) {
2714-
e.andn(i.dest.reg().cvt64(), i.src2.reg().cvt64(), temp.cvt64());
2715-
} else {
2716-
e.andn(i.dest.reg().cvt32(), i.src2.reg().cvt32(), temp.cvt32());
2717-
}
2700+
// src1 constant.
2701+
// `and` instruction only supports up to 32-bit immediate constants
2702+
// 64-bit constants will need a temp register
2703+
if (i.dest.reg().getBit() == 64) {
2704+
auto temp = GetTempReg<typename decltype(i.src1)::reg_type>(e);
2705+
e.mov(temp, i.src1.constant());
2706+
2707+
if (e.IsFeatureEnabled(kX64EmitBMI1)) {
2708+
if (i.dest.reg().getBit() == 64) {
2709+
e.andn(i.dest.reg().cvt64(), i.src2.reg().cvt64(), temp.cvt64());
27182710
} else {
2719-
e.mov(i.dest, i.src2);
2720-
e.not_(i.dest);
2721-
e.and_(i.dest, temp);
2711+
e.andn(i.dest.reg().cvt32(), i.src2.reg().cvt32(), temp.cvt32());
27222712
}
27232713
} else {
27242714
e.mov(i.dest, i.src2);
27252715
e.not_(i.dest);
2726-
e.and_(i.dest, uint32_t(i.src1.constant()));
2716+
e.and_(i.dest, temp);
27272717
}
2718+
} else {
2719+
e.mov(i.dest, i.src2);
2720+
e.not_(i.dest);
2721+
e.and_(i.dest, uint32_t(i.src1.constant()));
27282722
}
27292723
} else if (i.src2.is_constant) {
27302724
// src2 constant.

src/xenia/cpu/compiler/passes/constant_propagation_pass.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,15 @@ bool ConstantPropagationPass::Run(HIRBuilder* builder, bool& result) {
648648
result = true;
649649
}
650650
break;
651+
case OPCODE_AND_NOT:
652+
if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) {
653+
v->set_from(i->src2.value);
654+
v->Not();
655+
v->And(i->src1.value);
656+
i->Remove();
657+
result = true;
658+
}
659+
break;
651660
case OPCODE_OR:
652661
if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) {
653662
v->set_from(i->src1.value);

0 commit comments

Comments
 (0)