powerpc: Fix bugs in emulate_step()
This fixes some bugs in emulate_step(). First, the setting of the carry bit for the arithmetic right-shift instructions was not correct on 64-bit machines because we were masking with a mask of type int rather than unsigned long. Secondly, the sld (shift left doubleword) instruction was using the wrong instruction field for the register containing the shift count. Signed-off-by: Paul Mackerras <paulus@samba.org> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
This commit is contained in:
parent
bd6ba3518f
commit
e698b96678
@ -1198,7 +1198,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
|
||||
sh = regs->gpr[rb] & 0x3f;
|
||||
ival = (signed int) regs->gpr[rd];
|
||||
regs->gpr[ra] = ival >> (sh < 32 ? sh : 31);
|
||||
if (ival < 0 && (sh >= 32 || (ival & ((1 << sh) - 1)) != 0))
|
||||
if (ival < 0 && (sh >= 32 || (ival & ((1ul << sh) - 1)) != 0))
|
||||
regs->xer |= XER_CA;
|
||||
else
|
||||
regs->xer &= ~XER_CA;
|
||||
@ -1208,7 +1208,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
|
||||
sh = rb;
|
||||
ival = (signed int) regs->gpr[rd];
|
||||
regs->gpr[ra] = ival >> sh;
|
||||
if (ival < 0 && (ival & ((1 << sh) - 1)) != 0)
|
||||
if (ival < 0 && (ival & ((1ul << sh) - 1)) != 0)
|
||||
regs->xer |= XER_CA;
|
||||
else
|
||||
regs->xer &= ~XER_CA;
|
||||
@ -1216,7 +1216,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
|
||||
|
||||
#ifdef __powerpc64__
|
||||
case 27: /* sld */
|
||||
sh = regs->gpr[rd] & 0x7f;
|
||||
sh = regs->gpr[rb] & 0x7f;
|
||||
if (sh < 64)
|
||||
regs->gpr[ra] = regs->gpr[rd] << sh;
|
||||
else
|
||||
@ -1235,7 +1235,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
|
||||
sh = regs->gpr[rb] & 0x7f;
|
||||
ival = (signed long int) regs->gpr[rd];
|
||||
regs->gpr[ra] = ival >> (sh < 64 ? sh : 63);
|
||||
if (ival < 0 && (sh >= 64 || (ival & ((1 << sh) - 1)) != 0))
|
||||
if (ival < 0 && (sh >= 64 || (ival & ((1ul << sh) - 1)) != 0))
|
||||
regs->xer |= XER_CA;
|
||||
else
|
||||
regs->xer &= ~XER_CA;
|
||||
@ -1246,7 +1246,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
|
||||
sh = rb | ((instr & 2) << 4);
|
||||
ival = (signed long int) regs->gpr[rd];
|
||||
regs->gpr[ra] = ival >> sh;
|
||||
if (ival < 0 && (ival & ((1 << sh) - 1)) != 0)
|
||||
if (ival < 0 && (ival & ((1ul << sh) - 1)) != 0)
|
||||
regs->xer |= XER_CA;
|
||||
else
|
||||
regs->xer &= ~XER_CA;
|
||||
|
Loading…
Reference in New Issue
Block a user