[x64] Add AVX512 optimization for VECTOR_DENORMFLUSH
Use the `vptestnmd`-instruction to quickly test if the exponent bits of each element is zero and put these results into a mask register. This mask register can then be used to write `+0.0` or `-0.0` values depending on the original value's sign-bit. A masked `vrangeps` instruction is used to move zero-values into the effected elements while preserving the sign-bit without having to touch memory.
This commit is contained in:
committed by
Radosław Gliński
parent
3791149f34
commit
7801d53842
@@ -13,6 +13,7 @@
|
||||
#include <cstring>
|
||||
|
||||
#include "xenia/cpu/backend/x64/x64_op.h"
|
||||
#include "xenia/cpu/backend/x64/x64_util.h"
|
||||
|
||||
// For OPCODE_PACK/OPCODE_UNPACK
|
||||
#include "third_party/half/include/half.hpp"
|
||||
@@ -159,6 +160,16 @@ struct VECTOR_DENORMFLUSH
|
||||
: Sequence<VECTOR_DENORMFLUSH,
|
||||
I<OPCODE_VECTOR_DENORMFLUSH, V128Op, V128Op>> {
|
||||
static void Emit(X64Emitter& e, const EmitArgType& i) {
|
||||
if (e.IsFeatureEnabled(kX64EmitAVX512Ortho | kX64EmitAVX512DQ)) {
|
||||
const Xbyak::Opmask denormal_mask = e.k1;
|
||||
e.vptestnmd(denormal_mask, i.src1,
|
||||
e.GetXmmConstPtr(XMMSingleDenormalMask));
|
||||
e.vxorps(e.xmm1, e.xmm1, e.xmm1);
|
||||
e.vrangeps(i.dest.reg() | denormal_mask, i.src1, e.xmm1,
|
||||
FpRangeSelect::AbsMin | FpRangeSign::OperandA);
|
||||
return;
|
||||
}
|
||||
|
||||
e.ChangeMxcsrMode(MXCSRMode::Vmx);
|
||||
e.vxorps(e.xmm1, e.xmm1, e.xmm1); // 0.25 P0123
|
||||
|
||||
|
||||
Reference in New Issue
Block a user