[A64] Fix CNTLZ_I8/I16 returning 32 for zero input
Add sentinel bits after the left-shift so clz stops at the correct count (8 or 16) instead of counting through all 32 bits of the widened register. Unlikely to hit in practice since PPC only has cntlzw/cntlzd, but corrects existing sub-word variants.
This commit is contained in:
@@ -2402,7 +2402,10 @@ struct CNTLZ_I8 : Sequence<CNTLZ_I8, I<OPCODE_CNTLZ, I8Op, I8Op>> {
|
||||
e.mov(i.dest, static_cast<uint64_t>(count));
|
||||
} else {
|
||||
// clz operates on 32-bit, so shift left 24 to put byte in top.
|
||||
// OR a sentinel bit at position 23 so that a zero byte yields 8,
|
||||
// not 32.
|
||||
e.lsl(e.w0, i.src1, 24);
|
||||
e.orr(e.w0, e.w0, 1u << 23);
|
||||
e.clz(i.dest, e.w0);
|
||||
}
|
||||
}
|
||||
@@ -2418,7 +2421,9 @@ struct CNTLZ_I16 : Sequence<CNTLZ_I16, I<OPCODE_CNTLZ, I8Op, I16Op>> {
|
||||
}
|
||||
e.mov(i.dest, static_cast<uint64_t>(count));
|
||||
} else {
|
||||
// Sentinel bit at position 15 caps the result at 16 for zero input.
|
||||
e.lsl(e.w0, i.src1, 16);
|
||||
e.orr(e.w0, e.w0, 1u << 15);
|
||||
e.clz(i.dest, e.w0);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user