From 965f50e60099d478f0afb517fcec1433bc20e35c Mon Sep 17 00:00:00 2001 From: Ivan Egorov Date: Sat, 26 Sep 2026 08:51:25 +0100 Subject: [PATCH] Fix LZCNT returning the BSR result REP BSR is LZCNT, but its helper answered bsr(x), the index of the highest set bit, where the count of zeros above it is wanted. The two helpers were also named the other way round: the one under REP BSF computes tzcnt and was called Lzcnt. They now carry the name of what they compute, and LZCNT answers bits - 1 - bsr(x). Flags are as they were: CF for a zero source, ZF for a zero result. --- blink/machine.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/blink/machine.c b/blink/machine.c index ad309eb2b..af8211dcd 100644 --- a/blink/machine.c +++ b/blink/machine.c @@ -1046,40 +1046,40 @@ static u64 AluPopcnt(u64 x, struct Machine *m) { return popcount(x); } -static u64 AluLzcnt(u64 x, struct Machine *m, int bits) { +static u64 AluTzcnt(u64 x, struct Machine *m, int bits) { u64 r = x ? bsf(x) : bits; m->flags = SetFlag(m->flags, FLAGS_CF, !x); m->flags = SetFlag(m->flags, FLAGS_ZF, !r); return r; } -static u64 AluLzcnt64(u64 x, struct Machine *m) { - return AluLzcnt(x, m, 64); +static u64 AluTzcnt64(u64 x, struct Machine *m) { + return AluTzcnt(x, m, 64); } -static u64 AluLzcnt32(u64 x, struct Machine *m) { - return AluLzcnt(x, m, 32); +static u64 AluTzcnt32(u64 x, struct Machine *m) { + return AluTzcnt(x, m, 32); } -static u64 AluLzcnt16(u64 x, struct Machine *m) { - return AluLzcnt(x, m, 16); +static u64 AluTzcnt16(u64 x, struct Machine *m) { + return AluTzcnt(x, m, 16); } static u64 AluBsf(u64 x, struct Machine *m) { m->flags = SetFlag(m->flags, FLAGS_ZF, !x); return x ? bsf(x) : 0; } -static u64 AluTzcnt(u64 x, struct Machine *m, int bits) { - u64 r = x ? bsr(x) : bits; +static u64 AluLzcnt(u64 x, struct Machine *m, int bits) { + u64 r = x ? bits - 1 - bsr(x) : bits; m->flags = SetFlag(m->flags, FLAGS_CF, !x); m->flags = SetFlag(m->flags, FLAGS_ZF, !r); return r; } -static u64 AluTzcnt64(u64 x, struct Machine *m) { - return AluTzcnt(x, m, 64); +static u64 AluLzcnt64(u64 x, struct Machine *m) { + return AluLzcnt(x, m, 64); } -static u64 AluTzcnt32(u64 x, struct Machine *m) { - return AluTzcnt(x, m, 32); +static u64 AluLzcnt32(u64 x, struct Machine *m) { + return AluLzcnt(x, m, 32); } -static u64 AluTzcnt16(u64 x, struct Machine *m) { - return AluTzcnt(x, m, 16); +static u64 AluLzcnt16(u64 x, struct Machine *m) { + return AluLzcnt(x, m, 16); } static u64 AluBsr(u64 x, struct Machine *m) { m->flags = SetFlag(m->flags, FLAGS_ZF, !x); @@ -1105,11 +1105,11 @@ static void OpBsf(P) { u64 (*op)(u64, struct Machine *); if (Rep(rde) == 3) { if (Rexw(rde)) { - op = AluLzcnt64; + op = AluTzcnt64; } else if (!Osz(rde)) { - op = AluLzcnt32; + op = AluTzcnt32; } else { - op = AluLzcnt16; + op = AluTzcnt16; } } else { op = AluBsf; @@ -1121,11 +1121,11 @@ static void OpBsr(P) { u64 (*op)(u64, struct Machine *); if (Rep(rde) == 3) { if (Rexw(rde)) { - op = AluTzcnt64; + op = AluLzcnt64; } else if (!Osz(rde)) { - op = AluTzcnt32; + op = AluLzcnt32; } else { - op = AluTzcnt16; + op = AluLzcnt16; } } else { op = AluBsr;