[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.
This commit is contained in:
parent
3ab43d480d
commit
24d4e1e0e5
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue