aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorWunkolo <[email protected]>2024-02-04 12:23:29 -0800
committermerry <[email protected]>2024-02-06 18:15:34 +0000
commiteb5eb9cdf7c50879ab313a99be0d8f0bae50a2f0 (patch)
tree812710051a901e1616b4a2aa59ad65254a4349c0 /src
parent1e5e7a7ae642e182230ee1df64f0fde4698fd2a4 (diff)
downloaddynarmic-eb5eb9cdf7c50879ab313a99be0d8f0bae50a2f0.tar.gz
dynarmic-eb5eb9cdf7c50879ab313a99be0d8f0bae50a2f0.zip
emit_x64_vector: GNFI implementation of EmitVectorCountLeadingZeros8
Diffstat (limited to 'src')
-rw-r--r--src/dynarmic/backend/x64/emit_x64_vector.cpp21
1 files changed, 21 insertions, 0 deletions
diff --git a/src/dynarmic/backend/x64/emit_x64_vector.cpp b/src/dynarmic/backend/x64/emit_x64_vector.cpp
index 6e68b862..4f47f2e0 100644
--- a/src/dynarmic/backend/x64/emit_x64_vector.cpp
+++ b/src/dynarmic/backend/x64/emit_x64_vector.cpp
@@ -946,6 +946,27 @@ static void EmitVectorCountLeadingZeros(VectorArray<T>& result, const VectorArra
}
void EmitX64::EmitVectorCountLeadingZeros8(EmitContext& ctx, IR::Inst* inst) {
+ if (code.HasHostFeature(HostFeature::GFNI)) {
+ auto args = ctx.reg_alloc.GetArgumentInfo(inst);
+
+ const Xbyak::Xmm data = ctx.reg_alloc.UseScratchXmm(args[0]);
+ const Xbyak::Xmm result = ctx.reg_alloc.ScratchXmm();
+
+ // Reverse bits:
+ code.gf2p8affineqb(data, code.BConst<64>(xword, 0x8040201008040201), 0);
+
+ // Perform a tzcnt:
+ // Isolate lowest set bit
+ code.pcmpeqb(result, result);
+ code.paddb(result, data);
+ code.pandn(result, data);
+ // Convert lowest set bit into an index
+ code.gf2p8affineqb(result, code.BConst<64>(xword, 0xaaccf0ff'00000000), 8);
+
+ ctx.reg_alloc.DefineValue(inst, result);
+ return;
+ }
+
if (code.HasHostFeature(HostFeature::SSSE3)) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst);