From: Sandipan Das > Sent: 09 October 2017 12:07 > According to the GCC documentation, the behaviour of __builtin_clz() > and __builtin_clzl() is undefined if the value of the input argument > is zero. Without handling this special case, these builtins have been > used for emulating the following instructions: > * Count Leading Zeros Word (cntlzw[.]) > * Count Leading Zeros Doubleword (cntlzd[.]) > > This fixes the emulated behaviour of these instructions by adding an > additional check for this special case.
Presumably the result is undefined because the underlying cpu instruction is used - and it's return value is implementation defined. Here you are emulating the cpu instruction - so executing one will give the same answer as it the 'real' one were execucted. Indeed it might be worth an asm statement that definitely executes the cpu instruction? David > > Signed-off-by: Sandipan Das <sandi...@linux.vnet.ibm.com> > --- > arch/powerpc/lib/sstep.c | 12 ++++++++++-- > 1 file changed, 10 insertions(+), 2 deletions(-) > > diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c > index 0f7e41bd7e88..ebbc0b92650c 100644 > --- a/arch/powerpc/lib/sstep.c > +++ b/arch/powerpc/lib/sstep.c > @@ -1717,11 +1717,19 @@ int analyse_instr(struct instruction_op *op, const > struct pt_regs *regs, > * Logical instructions > */ > case 26: /* cntlzw */ > - op->val = __builtin_clz((unsigned int) regs->gpr[rd]); > + val = (unsigned int) regs->gpr[rd]; > + if (val == 0) > + op->val = 32; > + else > + op->val = __builtin_clz(val); > goto logical_done; > #ifdef __powerpc64__ > case 58: /* cntlzd */ > - op->val = __builtin_clzl(regs->gpr[rd]); > + val = regs->gpr[rd]; > + if (val == 0) > + op->val = 64; > + else > + op->val = __builtin_clzl(val); > goto logical_done; > #endif > case 28: /* and */ > -- > 2.13.6