[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:
@@ -2656,6 +2656,15 @@ void EmitAndNotXX(X64Emitter& e, const ARGS& i) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// neither are constant
|
// neither are constant
|
||||||
|
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 {
|
||||||
if (i.dest == i.src2) {
|
if (i.dest == i.src2) {
|
||||||
e.not_(i.dest);
|
e.not_(i.dest);
|
||||||
e.and_(i.dest, i.src1);
|
e.and_(i.dest, i.src1);
|
||||||
@@ -2666,6 +2675,7 @@ void EmitAndNotXX(X64Emitter& e, const ARGS& i) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
struct AND_NOT_I8 : Sequence<AND_NOT_I8, I<OPCODE_AND_NOT, I8Op, I8Op, I8Op>> {
|
struct AND_NOT_I8 : Sequence<AND_NOT_I8, I<OPCODE_AND_NOT, I8Op, I8Op, I8Op>> {
|
||||||
static void Emit(X64Emitter& e, const EmitArgType& i) {
|
static void Emit(X64Emitter& e, const EmitArgType& i) {
|
||||||
EmitAndNotXX<AND_NOT_I8, Reg8>(e, i);
|
EmitAndNotXX<AND_NOT_I8, Reg8>(e, i);
|
||||||
|
|||||||
Reference in New Issue
Block a user