Commit d600cbed authored by David S. Miller's avatar David S. Miller

sparc: Use hweight64() in popc emulation.

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ef7c4d46
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/perf_event.h> #include <linux/perf_event.h>
#include <linux/ratelimit.h> #include <linux/ratelimit.h>
#include <linux/bitops.h>
#include <asm/fpumacro.h> #include <asm/fpumacro.h>
enum direction { enum direction {
...@@ -373,16 +374,11 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn) ...@@ -373,16 +374,11 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn)
} }
} }
static char popc_helper[] = {
0, 1, 1, 2, 1, 2, 2, 3,
1, 2, 2, 3, 2, 3, 3, 4,
};
int handle_popc(u32 insn, struct pt_regs *regs) int handle_popc(u32 insn, struct pt_regs *regs)
{ {
u64 value;
int ret, i, rd = ((insn >> 25) & 0x1f);
int from_kernel = (regs->tstate & TSTATE_PRIV) != 0; int from_kernel = (regs->tstate & TSTATE_PRIV) != 0;
int ret, rd = ((insn >> 25) & 0x1f);
u64 value;
perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, 0); perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, 0);
if (insn & 0x2000) { if (insn & 0x2000) {
...@@ -392,10 +388,7 @@ int handle_popc(u32 insn, struct pt_regs *regs) ...@@ -392,10 +388,7 @@ int handle_popc(u32 insn, struct pt_regs *regs)
maybe_flush_windows(0, insn & 0x1f, rd, from_kernel); maybe_flush_windows(0, insn & 0x1f, rd, from_kernel);
value = fetch_reg(insn & 0x1f, regs); value = fetch_reg(insn & 0x1f, regs);
} }
for (ret = 0, i = 0; i < 16; i++) { ret = hweight64(value);
ret += popc_helper[value & 0xf];
value >>= 4;
}
if (rd < 16) { if (rd < 16) {
if (rd) if (rd)
regs->u_regs[rd] = ret; regs->u_regs[rd] = ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment