Message ID | 20170713032548.451-4-matthew.brown.dev@gmail.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
On Thu, Jul 13, 2017 at 01:25:47PM +1000, Matt Brown wrote: > +static nokprobe_inline void do_prtyw(struct pt_regs *regs, unsigned long v, > + int ra) > +{ > + unsigned long low, high, out; > + unsigned int i; > + > + high = 0; > + low = 0; > + out = 0; > + > + for (i = 0; i < 8; i++) { > + if (v & (1 << (i * 8))) 1UL > + (i < 4) ? (low++) : (high++); > + } > + > + if (low % 2) > + out |= low; > + if (high % 2) > + out |= (high << 32); Only the low bit of each word of the output can be set. Something like out = ((high & 1) << 32) | (low & 1); Segher
On Thu, Jul 13, 2017 at 5:37 PM, Segher Boessenkool <segher@kernel.crashing.org> wrote: > On Thu, Jul 13, 2017 at 01:25:47PM +1000, Matt Brown wrote: >> +static nokprobe_inline void do_prtyw(struct pt_regs *regs, unsigned long v, >> + int ra) >> +{ >> + unsigned long low, high, out; >> + unsigned int i; >> + >> + high = 0; >> + low = 0; >> + out = 0; >> + >> + for (i = 0; i < 8; i++) { >> + if (v & (1 << (i * 8))) > > 1UL > >> + (i < 4) ? (low++) : (high++); >> + } >> + >> + if (low % 2) >> + out |= low; >> + if (high % 2) >> + out |= (high << 32); > > Only the low bit of each word of the output can be set. Something > like > > out = ((high & 1) << 32) | (low & 1); > Ah, I wasn't aware. That way is much more concise too :) Thanks, Matt > > Segher
Hi Matt, [auto build test ERROR on powerpc/next] [also build test ERROR on v4.12 next-20170714] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Matt-Brown/powerpc-lib-sstep-Add-cmpb-instruction-emulation/20170714-020837 base: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next config: powerpc-chrp32_defconfig (attached as .config) compiler: powerpc-linux-gnu-gcc (Debian 6.1.1-9) 6.1.1 20160705 reproduce: wget https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=powerpc All errors (new ones prefixed by >>): arch/powerpc/lib/sstep.c: In function 'do_prtyw': >> arch/powerpc/lib/sstep.c:673:16: error: left shift count >= width of type [-Werror=shift-count-overflow] out |= (high << 32); ^~ cc1: all warnings being treated as errors vim +673 arch/powerpc/lib/sstep.c 654 655 static nokprobe_inline void do_prtyw(struct pt_regs *regs, unsigned long v, 656 int ra) 657 { 658 unsigned long low, high, out; 659 unsigned int i; 660 661 high = 0; 662 low = 0; 663 out = 0; 664 665 for (i = 0; i < 8; i++) { 666 if (v & (1 << (i * 8))) 667 (i < 4) ? (low++) : (high++); 668 } 669 670 if (low % 2) 671 out |= low; 672 if (high % 2) > 673 out |= (high << 32); 674 675 regs->gpr[ra] = out; 676 } 677 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c index 603654d..3228783 100644 --- a/arch/powerpc/lib/sstep.c +++ b/arch/powerpc/lib/sstep.c @@ -652,6 +652,42 @@ static nokprobe_inline void do_bpermd(struct pt_regs *regs, unsigned long v1, regs->gpr[ra] = 0 | perm; } +static nokprobe_inline void do_prtyw(struct pt_regs *regs, unsigned long v, + int ra) +{ + unsigned long low, high, out; + unsigned int i; + + high = 0; + low = 0; + out = 0; + + for (i = 0; i < 8; i++) { + if (v & (1 << (i * 8))) + (i < 4) ? (low++) : (high++); + } + + if (low % 2) + out |= low; + if (high % 2) + out |= (high << 32); + + regs->gpr[ra] = out; +} + +static nokprobe_inline void do_prtyd(struct pt_regs *regs, unsigned long v, + int ra) +{ + unsigned int count, i; + + count = 0; + for (i = 0; i < 8; i++) { + if (v & (1 << (i * 8))) + count++; + } + regs->gpr[ra] = count % 2; +} + static nokprobe_inline int trap_compare(long v1, long v2) { int ret = 0; @@ -1278,16 +1314,15 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, do_popcnt(regs, val, 8, ra); goto logical_done; - case 17076744: /* popcntw */ + case 2101768: /* prtyw */ val = regs->gpr[rd]; - do_popcnt(regs, val, 32, ra); + do_prtyw(regs, val, ra); goto logical_done; -#ifdef __powerpc64__ - case 19173896: /* popcntd */ + + case 2134536: /* prtyd */ val = regs->gpr[rd]; - do_popcnt(regs, val, 64, ra); + do_prtyd(regs, val, ra); goto logical_done; -#endif #ifdef __powerpc64__ case 2396736: /* bpermd */ @@ -1297,6 +1332,17 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, goto logical_done; #endif + case 17076744: /* popcntw */ + val = regs->gpr[rd]; + do_popcnt(regs, val, 32, ra); + goto logical_done; +#ifdef __powerpc64__ + case 19173896: /* popcntd */ + val = regs->gpr[rd]; + do_popcnt(regs, val, 64, ra); + goto logical_done; +#endif + /* * Shift instructions */
This add emulation for the prtyw and prtyd instructions. Signed-off-by: Matt Brown <matthew.brown.dev@gmail.com> --- arch/powerpc/lib/sstep.c | 58 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 52 insertions(+), 6 deletions(-)