On 2017/10/09 11:07AM, Sandipan Das wrote: > 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.
So: Fixes: 3cdfcbfd32b9d ("powerpc: Change analyse_instr so it doesn't modify *regs") > > 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); Can be made more compact: op->val = ( val ? __builtin_clz(val) : 32 ); - Naveen > 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 >