diff options
author | Andreas Schwab <schwab@redhat.com> | 2009-08-25 18:31:56 +0200 |
---|---|---|
committer | Andreas Schwab <schwab@redhat.com> | 2009-08-25 19:31:17 +0200 |
commit | bc9dd948ffc9cf1992d3e77e753789ab897e3dc6 (patch) | |
tree | 160b3fff25473e9394274f8655af2183551902ff /fedora | |
parent | 9aadad69ed7b1a24947f8d5cf878f94096317f81 (diff) | |
download | glibc-bc9dd948ffc9cf1992d3e77e753789ab897e3dc6.tar.gz glibc-bc9dd948ffc9cf1992d3e77e753789ab897e3dc6.tar.xz glibc-bc9dd948ffc9cf1992d3e77e753789ab897e3dc6.zip |
Add emulation of popcntb.
Diffstat (limited to 'fedora')
-rw-r--r-- | fedora/power6emul.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/fedora/power6emul.c b/fedora/power6emul.c index f1d0d20e0f..1b0187bddd 100644 --- a/fedora/power6emul.c +++ b/fedora/power6emul.c @@ -163,6 +163,25 @@ asm (".globl frip, friz, frin, frim\n.hidden frip, friz, frin, frim\n\t" "3:" "mtfsf 0x01,11\n\t" "blr\n"); +#ifdef __powerpc64__ +#define m1 0x5555555555555555L +#define m2 0x3333333333333333L +#define m3 0x0f0f0f0f0f0f0f0fL +#else +#define m1 0x55555555 +#define m2 0x33333333 +#define m3 0x0f0f0f0f +#endif + +static inline unsigned long +popcntb (unsigned long n) +{ + n -= (n >> 1) & m1; + n = (n & m2) + ((n >> 2) & m2); + n = (n + (n >> 4)) & m3; + return n; +} + static void catch_sigill (int signal, struct sigcontext *ctx) { @@ -221,6 +240,18 @@ catch_sigill (int signal, struct sigcontext *ctx) ctx->regs->nip += 4; return; } + if ((insn & 0xfc00ffff) == 0x7c0000f4) /* popcntb */ + { + unsigned long *regs = (unsigned long *) ctx->regs; + unsigned dest = (insn >> 16) & 0x1f; + unsigned src = (insn >> 21) & 0x1f; + unsigned long res = 0; + int i; + + regs[dest] = popcntb (regs[src]); + ctx->regs->nip += 4; + return; + } struct sigaction sa; sa.sa_handler = SIG_DFL; |