* [PATCH] powerpc: emulate power5 popcntb instruction
@ 2006-08-17 18:53 Will Schmidt
2006-08-17 19:24 ` Segher Boessenkool
0 siblings, 1 reply; 18+ messages in thread
From: Will Schmidt @ 2006-08-17 18:53 UTC (permalink / raw)
To: linuxppc-dev, Paul Mackerras
In an attempt to make it easier for a power5 optimized app to run on a
power4 or a 970 or random earlier machine, this provides emulation of the popcntb
instruction.
tested on power4 and 970.
Signed-off-by: Will Schmidt <will_schmidt@vnet.ibm.com>
---
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 2105767..3e5ed30 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -588,6 +588,8 @@ #define INST_LSWX 0x7c00042a
#define INST_STSWI 0x7c0005aa
#define INST_STSWX 0x7c00052a
+#define INST_POPCNTB 0x7c0000f4
+
static int emulate_string_inst(struct pt_regs *regs, u32 instword)
{
u8 rT = (instword >> 21) & 0x1f;
@@ -656,6 +658,26 @@ static int emulate_string_inst(struct pt
return 0;
}
+static int emulate_popcntb_inst(struct pt_regs *regs, u32 instword)
+{
+ u32 ra,rs;
+ u32 countreg,tmp;
+ u32 x,y;
+
+ ra = (instword >> 16) & 0x1f;
+ rs = (instword >> 21) & 0x1f;
+ countreg = regs->gpr[rs];
+ regs->gpr[ra] = 0;
+
+ /* y=4 bytes, x=8 bits/byte */
+ for (y = 0; y < 4; y++) {
+ for (tmp = 0, x = 0; x < 8; x++)
+ if (countreg & (0x1 << (x + 8 * y))) tmp++;
+ regs->gpr[ra] += (tmp << 8 * y );
+ }
+ return 0;
+}
+
static int emulate_instruction(struct pt_regs *regs)
{
u32 instword;
@@ -693,6 +715,11 @@ static int emulate_instruction(struct pt
if ((instword & INST_STRING_GEN_MASK) == INST_STRING)
return emulate_string_inst(regs, instword);
+ /* Emulate the popcntb (Population Count Bytes) instruction. */
+ if ((instword & INST_POPCNTB) == INST_POPCNTB) {
+ return emulate_popcntb_inst(regs, instword);
+ }
+
return -EINVAL;
}
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH] powerpc: emulate power5 popcntb instruction
2006-08-17 18:53 [PATCH] powerpc: emulate power5 popcntb instruction Will Schmidt
@ 2006-08-17 19:24 ` Segher Boessenkool
2006-08-18 18:11 ` Will Schmidt
0 siblings, 1 reply; 18+ messages in thread
From: Segher Boessenkool @ 2006-08-17 19:24 UTC (permalink / raw)
To: will_schmidt; +Cc: linuxppc-dev, Paul Mackerras
> +static int emulate_popcntb_inst(struct pt_regs *regs, u32 instword)
> +{
> + u32 ra,rs;
> + u32 countreg,tmp;
> + u32 x,y;
> +
> + ra = (instword >> 16) & 0x1f;
> + rs = (instword >> 21) & 0x1f;
> + countreg = regs->gpr[rs];
> + regs->gpr[ra] = 0;
> +
> + /* y=4 bytes, x=8 bits/byte */
> + for (y = 0; y < 4; y++) {
> + for (tmp = 0, x = 0; x < 8; x++)
> + if (countreg & (0x1 << (x + 8 * y))) tmp++;
> + regs->gpr[ra] += (tmp << 8 * y );
> + }
> + return 0;
> +}
x in, x out:
x -= (x >> 1) & 0x5555555555555555;
x = (x & 0x3333333333333333) + ((x >> 2) & 0x3333333333333333);
x = (x + (x >> 4)) & 0x0f0f0f0f0f0f0f0f;
(Your code only runs on 4 bytes; shouldn't it be 8?)
Segher
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH] powerpc: emulate power5 popcntb instruction
2006-08-17 19:24 ` Segher Boessenkool
@ 2006-08-18 18:11 ` Will Schmidt
2006-08-18 19:05 ` Arnd Bergmann
2006-08-18 19:42 ` Kumar Gala
0 siblings, 2 replies; 18+ messages in thread
From: Will Schmidt @ 2006-08-18 18:11 UTC (permalink / raw)
To: Segher Boessenkool; +Cc: linuxppc-dev, Paul Mackerras
In an attempt to make it easier for a power5 optimized app to run on a
power4 or a 970 or random earlier machine, this provides emulation of
the popcntb instruction. Rewritten to use a slicker algorithm as
suggested by Segher. I left a 'tmp' variable in play, as it seemed
cleaner to use tmp than referring to regs->gpr[rs] and [ra] multiple
times within the magic algorithm.
Also tested on power4 with both 32 and 64 userspace this time.
*blush*. :-)
Signed-off-by: Will Schmidt <will_schmidt@vnet.ibm.com>
---
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 2105767..a0e80dd 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -588,6 +588,8 @@ #define INST_LSWX 0x7c00042a
#define INST_STSWI 0x7c0005aa
#define INST_STSWX 0x7c00052a
+#define INST_POPCNTB 0x7c0000f4
+
static int emulate_string_inst(struct pt_regs *regs, u32 instword)
{
u8 rT = (instword >> 21) & 0x1f;
@@ -656,6 +658,23 @@ static int emulate_string_inst(struct pt
return 0;
}
+static int emulate_popcntb_inst(struct pt_regs *regs, u32 instword)
+{
+ u32 ra,rs;
+ unsigned long tmp;
+
+ ra = (instword >> 16) & 0x1f;
+ rs = (instword >> 21) & 0x1f;
+
+ tmp = regs->gpr[rs];
+ tmp = tmp - ((tmp >> 1) & 0x5555555555555555);
+ tmp = (tmp & 0x3333333333333333) + ((tmp >> 2) & 0x3333333333333333);
+ tmp = (tmp + (tmp >> 4)) & 0x0f0f0f0f0f0f0f0f;
+ regs->gpr[ra] = tmp;
+
+ return 0;
+}
+
static int emulate_instruction(struct pt_regs *regs)
{
u32 instword;
@@ -693,6 +712,11 @@ static int emulate_instruction(struct pt
if ((instword & INST_STRING_GEN_MASK) == INST_STRING)
return emulate_string_inst(regs, instword);
+ /* Emulate the popcntb (Population Count Bytes) instruction. */
+ if ((instword & INST_POPCNTB) == INST_POPCNTB) {
+ return emulate_popcntb_inst(regs, instword);
+ }
+
return -EINVAL;
}
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH] powerpc: emulate power5 popcntb instruction
2006-08-18 18:11 ` Will Schmidt
@ 2006-08-18 19:05 ` Arnd Bergmann
2006-08-18 19:30 ` Kumar Gala
2006-08-19 19:10 ` segher
2006-08-18 19:42 ` Kumar Gala
1 sibling, 2 replies; 18+ messages in thread
From: Arnd Bergmann @ 2006-08-18 19:05 UTC (permalink / raw)
To: linuxppc-dev, will_schmidt; +Cc: Paul Mackerras
On Friday 18 August 2006 20:11, Will Schmidt wrote:
> +#define INST_POPCNTB 0x7c0000f4
> +
> +=A0=A0=A0=A0=A0=A0=A0/* Emulate the popcntb (Population Count Bytes) ins=
truction. */
> +=A0=A0=A0=A0=A0=A0=A0if ((instword & INST_POPCNTB) =3D=3D INST_POPCNTB) {
> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0return emulate_popcntb_inst=
(regs, instword);
> +=A0=A0=A0=A0=A0=A0=A0}
> +
Is that the right check? The other similar traps check against a
mask of 0x7c0007fe.
Arnd <><
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH] powerpc: emulate power5 popcntb instruction
2006-08-18 19:05 ` Arnd Bergmann
@ 2006-08-18 19:30 ` Kumar Gala
2006-08-19 19:10 ` segher
1 sibling, 0 replies; 18+ messages in thread
From: Kumar Gala @ 2006-08-18 19:30 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linuxppc-dev, Paul Mackerras
On Aug 18, 2006, at 2:05 PM, Arnd Bergmann wrote:
> On Friday 18 August 2006 20:11, Will Schmidt wrote:
>> +#define INST_POPCNTB 0x7c0000f4
>> +
>
>> + /* Emulate the popcntb (Population Count Bytes)
>> instruction. */
>> + if ((instword & INST_POPCNTB) == INST_POPCNTB) {
>> + return emulate_popcntb_inst(regs, instword);
>> + }
>> +
>
> Is that the right check? The other similar traps check against a
> mask of 0x7c0007fe.
I agree with Arnd here, its better to check with a larger mask to
ensure that bits that should be '0' in the minor opcode are.
For example, if you had an instruction that was 0x7c0000f7 it would
match.
- kumar
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH] powerpc: emulate power5 popcntb instruction
2006-08-18 18:11 ` Will Schmidt
2006-08-18 19:05 ` Arnd Bergmann
@ 2006-08-18 19:42 ` Kumar Gala
2006-08-19 19:09 ` segher
1 sibling, 1 reply; 18+ messages in thread
From: Kumar Gala @ 2006-08-18 19:42 UTC (permalink / raw)
To: will_schmidt; +Cc: linuxppc-dev, Paul Mackerras
>
> +static int emulate_popcntb_inst(struct pt_regs *regs, u32 instword)
> +{
> + u32 ra,rs;
> + unsigned long tmp;
> +
> + ra = (instword >> 16) & 0x1f;
> + rs = (instword >> 21) & 0x1f;
> +
> + tmp = regs->gpr[rs];
> + tmp = tmp - ((tmp >> 1) & 0x5555555555555555);
> + tmp = (tmp & 0x3333333333333333) + ((tmp >> 2) &
> 0x3333333333333333);
> + tmp = (tmp + (tmp >> 4)) & 0x0f0f0f0f0f0f0f0f;
> + regs->gpr[ra] = tmp;
> +
> + return 0;
> +}
This is going to give warnings on ppc32 kernel compiles, maybe
something like:
(unsigned long) 0x5555555555555555ull
- kumar
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH] powerpc: emulate power5 popcntb instruction
2006-08-18 19:42 ` Kumar Gala
@ 2006-08-19 19:09 ` segher
0 siblings, 0 replies; 18+ messages in thread
From: segher @ 2006-08-19 19:09 UTC (permalink / raw)
To: galak; +Cc: linuxppc-dev, paulus
>> +static int emulate_popcntb_inst(struct pt_regs *regs, u32 instword)
>> +{
>> + u32 ra,rs;
>> + unsigned long tmp;
>> +
>> + ra = (instword >> 16) & 0x1f;
>> + rs = (instword >> 21) & 0x1f;
>> +
>> + tmp = regs->gpr[rs];
>> + tmp = tmp - ((tmp >> 1) & 0x5555555555555555);
>> + tmp = (tmp & 0x3333333333333333) + ((tmp >> 2) &
>> 0x3333333333333333);
>> + tmp = (tmp + (tmp >> 4)) & 0x0f0f0f0f0f0f0f0f;
>> + regs->gpr[ra] = tmp;
>> +
>> + return 0;
>> +}
>
> This is going to give warnings on ppc32 kernel compiles, maybe
> something like:
>
> (unsigned long) 0x5555555555555555ull
Nah, just make "tmp" an u64. And/or don't do this emulation on
32-bit machines at all.
And if the compiler warns about the non-qualified constants --
well, we should compile with -std=gnu99 anyway, eh?
Segher
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH] powerpc: emulate power5 popcntb instruction
2006-08-18 19:05 ` Arnd Bergmann
2006-08-18 19:30 ` Kumar Gala
@ 2006-08-19 19:10 ` segher
2006-08-19 20:19 ` Arnd Bergmann
1 sibling, 1 reply; 18+ messages in thread
From: segher @ 2006-08-19 19:10 UTC (permalink / raw)
To: arnd; +Cc: linuxppc-dev, paulus
>> +#define INST_POPCNTB 0x7c0000f4
>> +
>
>> + /* Emulate the popcntb (Population Count Bytes) instruction.
>> */ + if ((instword & INST_POPCNTB) == INST_POPCNTB) {
>> + return emulate_popcntb_inst(regs, instword);
>> + }
>> +
>
> Is that the right check? The other similar traps check against a
> mask of 0x7c0007fe.
I hope you mean 0xfc0007fe?
Segher
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH] powerpc: emulate power5 popcntb instruction
2006-08-19 19:10 ` segher
@ 2006-08-19 20:19 ` Arnd Bergmann
2006-08-19 23:32 ` segher
0 siblings, 1 reply; 18+ messages in thread
From: Arnd Bergmann @ 2006-08-19 20:19 UTC (permalink / raw)
To: linuxppc-dev; +Cc: paulus, segher
T24gU2F0dXJkYXkgMTkgQXVndXN0IDIwMDYgMjE6MTAsIHNlZ2hlckBnYXRlLmNyYXNoaW5nLm9y
ZyB3cm90ZToKPiA+IElzIHRoYXQgdGhlIHJpZ2h0IGNoZWNrPyBUaGUgb3RoZXIgc2ltaWxhciB0
cmFwcyBjaGVjayBhZ2FpbnN0IGEKPiA+IG1hc2sgb2YgMHg3YzAwMDdmZS4KPiAKPiBJIGhvcGUg
eW91IG1lYW4gMHhmYzAwMDdmZT8KPiAKCk5vLCB0aGUgY29kZSBpbiBxdWVzdGlvbiBpcyAKCiNk
ZWZpbmUgSU5TVF9NRlNQUl9QVlKtt623t7e3t7e3MHg3YzFmNDJhNgojZGVmaW5lIElOU1RfTUZT
UFJfUFZSX01BU0utt7e3tzB4ZmMxZmZmZmYKCiNkZWZpbmUgSU5TVF9EQ0JBrbe3t7e3t623t7e3
t7e3MHg3YzAwMDVlYwojZGVmaW5lIElOU1RfRENCQV9NQVNLrbett7e3t7e3tzB4N2MwMDA3ZmUK
CiNkZWZpbmUgSU5TVF9NQ1JYUq23t7e3t623t7e3t7e3MHg3YzAwMDQwMAojZGVmaW5lIElOU1Rf
TUNSWFJfTUFTS62tt7e3t7e3tzB4N2MwMDA3ZmUKCiNkZWZpbmUgSU5TVF9TVFJJTkett7e3t623
t7e3t7e3MHg3YzAwMDQyYQojZGVmaW5lIElOU1RfU1RSSU5HX01BU0utt7e3t7e3tzB4N2MwMDA3
ZmUKI2RlZmluZSBJTlNUX1NUUklOR19HRU5fTUFTS623t7cweDdjMDAwNjdlCiNkZWZpbmUgSU5T
VF9MU1dJrbe3t7e3t623t7e3t7e3MHg3YzAwMDRhYQojZGVmaW5lIElOU1RfTFNXWK23t7e3t7et
t7e3t7e3tzB4N2MwMDA0MmEKI2RlZmluZSBJTlNUX1NUU1dJrbe3t7e3rbe3t7e3t7cweDdjMDAw
NWFhCiNkZWZpbmUgSU5TVF9TVFNXWK23t7e3t623t7e3t7e3MHg3YzAwMDUyYQoKV2hhdCBkb2Vz
IHRoZSBNU0IgZG8gaW4gb3VyIGluc3RydWN0aW9ucz8KCglBcm5kIDw+PAo=
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH] powerpc: emulate power5 popcntb instruction
2006-08-19 20:19 ` Arnd Bergmann
@ 2006-08-19 23:32 ` segher
2006-08-21 20:09 ` Will Schmidt
0 siblings, 1 reply; 18+ messages in thread
From: segher @ 2006-08-19 23:32 UTC (permalink / raw)
To: arnd; +Cc: linuxppc-dev, paulus, segher
>> > Is that the right check? The other similar traps check against a
>> mask of 0x7c0007fe.
>>
>> I hope you mean 0xfc0007fe?
>>
>
> No, the code in question is
>
> #define INST_MFSPR_PVR········0x7c1f42a6
> #define INST_MFSPR_PVR_MASK····0xfc1fffff
>
> #define INST_DCBA·············0x7c0005ec
> #define INST_DCBA_MASK········0x7c0007fe
>
> #define INST_MCRXR············0x7c000400
> #define INST_MCRXR_MASK·······0x7c0007fe
>
> #define INST_STRING···········0x7c00042a
> #define INST_STRING_MASK·······0x7c0007fe
> #define INST_STRING_GEN_MASK···0x7c00067e
> #define INST_LSWI·············0x7c0004aa
> #define INST_LSWX·············0x7c00042a
> #define INST_STSWI············0x7c0005aa
> #define INST_STSWX············0x7c00052a
>
> What does the MSB do in our instructions?
Bits 0..5 are the primary opcode, for all insns;
bits 21..30 are the secondary opcode, for insns that
have one (all in primary opcode 31 do).
So we have a bug here; could you take care of it please
Arnd?
Segher
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH] powerpc: emulate power5 popcntb instruction
2006-08-19 23:32 ` segher
@ 2006-08-21 20:09 ` Will Schmidt
2006-08-24 6:36 ` Paul Mackerras
0 siblings, 1 reply; 18+ messages in thread
From: Will Schmidt @ 2006-08-21 20:09 UTC (permalink / raw)
To: segher; +Cc: linuxppc-dev, paulus, arnd
On Sat, 2006-19-08 at 18:32 -0500, segher@gate.crashing.org wrote:
> >> > Is that the right check? The other similar traps check against a
> >> mask of 0x7c0007fe.
> >>
> So we have a bug here; could you take care of it please
> Arnd?
I'm not Arnd :-) , but since I'm poking at it anyways,.. how about
this?
In an attempt to make it easier for a power5 optimized app to run on a
power4 or a 970 or random earlier machine, this provides emulation of
the popcntb instruction.
This version incorporates the suggestions from Arnd, Kumar and Segher;
including using a better MASK for popcntb, updating the existing masks
to include the msb for the instruction primary opcode.
Signed-off-by: Will Schmidt <will_schmidt@vnet.ibm.com>
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 2105767..caba187 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -575,19 +575,22 @@ #define INST_MFSPR_PVR 0x7c1f42a6
#define INST_MFSPR_PVR_MASK 0xfc1fffff
#define INST_DCBA 0x7c0005ec
-#define INST_DCBA_MASK 0x7c0007fe
+#define INST_DCBA_MASK 0xfc0007fe
#define INST_MCRXR 0x7c000400
-#define INST_MCRXR_MASK 0x7c0007fe
+#define INST_MCRXR_MASK 0xfc0007fe
#define INST_STRING 0x7c00042a
-#define INST_STRING_MASK 0x7c0007fe
-#define INST_STRING_GEN_MASK 0x7c00067e
+#define INST_STRING_MASK 0xfc0007fe
+#define INST_STRING_GEN_MASK 0xfc00067e
#define INST_LSWI 0x7c0004aa
#define INST_LSWX 0x7c00042a
#define INST_STSWI 0x7c0005aa
#define INST_STSWX 0x7c00052a
+#define INST_POPCNTB 0x7c0000f4
+#define INST_POPCNTB_MASK 0xfc0007fe
+
static int emulate_string_inst(struct pt_regs *regs, u32 instword)
{
u8 rT = (instword >> 21) & 0x1f;
@@ -656,6 +659,23 @@ static int emulate_string_inst(struct pt
return 0;
}
+static int emulate_popcntb_inst(struct pt_regs *regs, u32 instword)
+{
+ u32 ra,rs;
+ u64 tmp;
+
+ ra = (instword >> 16) & 0x1f;
+ rs = (instword >> 21) & 0x1f;
+
+ tmp = regs->gpr[rs];
+ tmp = tmp - ((tmp >> 1) & 0x5555555555555555);
+ tmp = (tmp & 0x3333333333333333) + ((tmp >> 2) & 0x3333333333333333);
+ tmp = (tmp + (tmp >> 4)) & 0x0f0f0f0f0f0f0f0f;
+ regs->gpr[ra] = tmp;
+
+ return 0;
+}
+
static int emulate_instruction(struct pt_regs *regs)
{
u32 instword;
@@ -693,6 +713,11 @@ static int emulate_instruction(struct pt
if ((instword & INST_STRING_GEN_MASK) == INST_STRING)
return emulate_string_inst(regs, instword);
+ /* Emulate the popcntb (Population Count Bytes) instruction. */
+ if ((instword & INST_POPCNTB_MASK) == INST_POPCNTB) {
+ return emulate_popcntb_inst(regs, instword);
+ }
+
return -EINVAL;
}
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH] powerpc: emulate power5 popcntb instruction
2006-08-21 20:09 ` Will Schmidt
@ 2006-08-24 6:36 ` Paul Mackerras
2006-08-24 15:53 ` Segher Boessenkool
2006-08-28 18:03 ` Willschm
0 siblings, 2 replies; 18+ messages in thread
From: Paul Mackerras @ 2006-08-24 6:36 UTC (permalink / raw)
To: will_schmidt; +Cc: linuxppc-dev, arnd, segher
Will Schmidt writes:
> I'm not Arnd :-) , but since I'm poking at it anyways,.. how about
> this?
I just did a patch to fix the existing masks. Could you do a new
version of this patch that doesn't include the unrelated mask fixes
please? Also it would be really nice if you could figure out a way to
avoid doing the unnecessary 64-bit logical operations on 32-bit
machines - i.e. using an unsigned long for tmp, but then the constants
become problematic. Maybe you need something like
#define LCONST(x) ((unsigned long)(x##ULL))
Thanks,
Paul.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH] powerpc: emulate power5 popcntb instruction
2006-08-24 6:36 ` Paul Mackerras
@ 2006-08-24 15:53 ` Segher Boessenkool
2006-08-25 9:59 ` Gabriel Paubert
2006-08-25 12:57 ` Paul Mackerras
2006-08-28 18:03 ` Willschm
1 sibling, 2 replies; 18+ messages in thread
From: Segher Boessenkool @ 2006-08-24 15:53 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev, arnd, segher
> Also it would be really nice if you could figure out a way to
> avoid doing the unnecessary 64-bit logical operations on 32-bit
> machines
Like I asked before -- should we run this emulation on 32-bit
machines at all? The instruction only exists in the 64-bit
architecture after all.
Segher
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH] powerpc: emulate power5 popcntb instruction
2006-08-24 15:53 ` Segher Boessenkool
@ 2006-08-25 9:59 ` Gabriel Paubert
2006-08-25 12:57 ` Paul Mackerras
1 sibling, 0 replies; 18+ messages in thread
From: Gabriel Paubert @ 2006-08-25 9:59 UTC (permalink / raw)
To: Segher Boessenkool; +Cc: linuxppc-dev, Paul Mackerras, segher, arnd
On Thu, Aug 24, 2006 at 05:53:56PM +0200, Segher Boessenkool wrote:
> > Also it would be really nice if you could figure out a way to
> > avoid doing the unnecessary 64-bit logical operations on 32-bit
> > machines
>
> Like I asked before -- should we run this emulation on 32-bit
> machines at all? The instruction only exists in the 64-bit
> architecture after all.
It's useless for now, but I would not be surprised if someone
creates a new 32 bit processor which includes this instruction.
Gabriel
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH] powerpc: emulate power5 popcntb instruction
2006-08-24 15:53 ` Segher Boessenkool
2006-08-25 9:59 ` Gabriel Paubert
@ 2006-08-25 12:57 ` Paul Mackerras
1 sibling, 0 replies; 18+ messages in thread
From: Paul Mackerras @ 2006-08-25 12:57 UTC (permalink / raw)
To: Segher Boessenkool; +Cc: linuxppc-dev, arnd, segher
Segher Boessenkool writes:
> Like I asked before -- should we run this emulation on 32-bit
> machines at all? The instruction only exists in the 64-bit
> architecture after all.
It could be argued either way, but on the whole I would prefer to
minimize the number of things which could cause a 32-bit program that
runs quite happily on a 64-bit CPU to fail on a 32-bit CPU...
Paul.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH] powerpc: emulate power5 popcntb instruction
2006-08-24 6:36 ` Paul Mackerras
2006-08-24 15:53 ` Segher Boessenkool
@ 2006-08-28 18:03 ` Willschm
2006-08-29 6:43 ` Segher Boessenkool
1 sibling, 1 reply; 18+ messages in thread
From: Willschm @ 2006-08-28 18:03 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev, arnd, segher
On Thu, 2006-24-08 at 16:36 +1000, Paul Mackerras wrote:
> Will Schmidt writes:
>
> I just did a patch to fix the existing masks. Could you do a new
> version of this patch that doesn't include the unrelated mask fixes
> please? Also it would be really nice if you could figure out a way to
> avoid doing the unnecessary 64-bit logical operations on 32-bit
> machines - i.e. using an unsigned long for tmp, but then the constants
> become problematic. Maybe you need something like
>
> #define LCONST(x) ((unsigned long)(x##ULL))
Ok, how about this..
In an attempt to make it easier for a power5 optimized app to run on a
power4 or a 970 or random earlier machine, this provides emulation of
the popcntb instruction.
Signed-off-by: Will Schmidt <will_schmidt@vnet.ibm.com>
---
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 2105767..f85a3af 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -588,6 +588,9 @@ #define INST_LSWX 0x7c00042a
#define INST_STSWI 0x7c0005aa
#define INST_STSWX 0x7c00052a
+#define INST_POPCNTB 0x7c0000f4
+#define INST_POPCNTB_MASK 0xfc0007fe
+
static int emulate_string_inst(struct pt_regs *regs, u32 instword)
{
u8 rT = (instword >> 21) & 0x1f;
@@ -656,6 +659,25 @@ static int emulate_string_inst(struct pt
return 0;
}
+#define LCONST(x) ((unsigned long)(x##ULL))
+
+static int emulate_popcntb_inst(struct pt_regs *regs, u32 instword)
+{
+ u32 ra,rs;
+ u64 tmp;
+
+ ra = (instword >> 16) & 0x1f;
+ rs = (instword >> 21) & 0x1f;
+
+ tmp = regs->gpr[rs];
+ tmp = tmp - ((tmp >> 1) & LCONST(0x5555555555555555));
+ tmp = (tmp & LCONST(0x3333333333333333)) + ((tmp >> 2) & LCONST(0x3333333333333333));
+ tmp = (tmp + (tmp >> 4)) & LCONST(0x0f0f0f0f0f0f0f0f);
+ regs->gpr[ra] = tmp;
+
+ return 0;
+}
+
static int emulate_instruction(struct pt_regs *regs)
{
u32 instword;
@@ -693,6 +715,11 @@ static int emulate_instruction(struct pt
if ((instword & INST_STRING_GEN_MASK) == INST_STRING)
return emulate_string_inst(regs, instword);
+ /* Emulate the popcntb (Population Count Bytes) instruction. */
+ if ((instword & INST_POPCNTB_MASK) == INST_POPCNTB) {
+ return emulate_popcntb_inst(regs, instword);
+ }
+
return -EINVAL;
}
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH] powerpc: emulate power5 popcntb instruction
2006-08-28 18:03 ` Willschm
@ 2006-08-29 6:43 ` Segher Boessenkool
2006-08-30 18:11 ` Will Schmidt
0 siblings, 1 reply; 18+ messages in thread
From: Segher Boessenkool @ 2006-08-29 6:43 UTC (permalink / raw)
To: Willschm; +Cc: linuxppc-dev, Paul Mackerras, segher, arnd
>> I just did a patch to fix the existing masks.
Thanks Paul.
>> Could you do a new
>> version of this patch that doesn't include the unrelated mask fixes
>> please? Also it would be really nice if you could figure out a
>> way to
>> avoid doing the unnecessary 64-bit logical operations on 32-bit
>> machines - i.e. using an unsigned long for tmp, but then the
>> constants
>> become problematic. Maybe you need something like
>>
>> #define LCONST(x) ((unsigned long)(x##ULL))
>
> Ok, how about this..
Hrm. The LCONST() thing is butt ugly though; you can just write
0x3333333333333333ULL etc. and GCC will do the right thing (i.e.
efficient code), and not warn (don't need the "ULL" even when in
C99/gnu99 mode, as we should be but aren't, heh).
You want to make tmp and unsigned long instead of an u64...
Segher
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH] powerpc: emulate power5 popcntb instruction
2006-08-29 6:43 ` Segher Boessenkool
@ 2006-08-30 18:11 ` Will Schmidt
0 siblings, 0 replies; 18+ messages in thread
From: Will Schmidt @ 2006-08-30 18:11 UTC (permalink / raw)
To: Segher Boessenkool; +Cc: linuxppc-dev, Paul Mackerras, segher, arnd
On Tue, 2006-29-08 at 08:43 +0200, Segher Boessenkool wrote:
> >> I just did a patch to fix the existing masks.
>
> Thanks Paul.
>
> >> Could you do a new
> >> version of this patch that doesn't include the unrelated mask fixes
> >> please? Also it would be really nice if you could figure out a
> >> way to
> >> avoid doing the unnecessary 64-bit logical operations on 32-bit
> >> machines - i.e. using an unsigned long for tmp, but then the
> >> constants
> >> become problematic. Maybe you need something like
> >>
> >> #define LCONST(x) ((unsigned long)(x##ULL))
> >
> > Ok, how about this..
>
> Hrm. The LCONST() thing is butt ugly though; you can just write
> 0x3333333333333333ULL etc. and GCC will do the right thing (i.e.
> efficient code), and not warn (don't need the "ULL" even when in
> C99/gnu99 mode, as we should be but aren't, heh).
>
> You want to make tmp and unsigned long instead of an u64...
Ok, so back to unsigned-long to let the 32-bit stuff be happy..
Now a bit of a tangent question: As far as just 64-bit is concerned, is
there actually any difference between u64 and unsigned long? Am
wondering why you suggested that change to u64 from unsigned long
earlier in the thread.
this version looks to build clean with arch=ppc (32-bit).
This provides emulation of the power5 instruction popcntb.
Signed-off-by: Will Schmidt <will_schmidt@vnet.ibm.com>
---
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 2105767..4014d71 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -588,6 +588,9 @@ #define INST_LSWX 0x7c00042a
#define INST_STSWI 0x7c0005aa
#define INST_STSWX 0x7c00052a
+#define INST_POPCNTB 0x7c0000f4
+#define INST_POPCNTB_MASK 0xfc0007fe
+
static int emulate_string_inst(struct pt_regs *regs, u32 instword)
{
u8 rT = (instword >> 21) & 0x1f;
@@ -656,6 +659,23 @@ static int emulate_string_inst(struct pt
return 0;
}
+static int emulate_popcntb_inst(struct pt_regs *regs, u32 instword)
+{
+ u32 ra,rs;
+ unsigned long tmp;
+
+ ra = (instword >> 16) & 0x1f;
+ rs = (instword >> 21) & 0x1f;
+
+ tmp = regs->gpr[rs];
+ tmp = tmp - ((tmp >> 1) & 0x5555555555555555ULL);
+ tmp = (tmp & 0x3333333333333333ULL) + ((tmp >> 2) & 0x3333333333333333ULL);
+ tmp = (tmp + (tmp >> 4)) & 0x0f0f0f0f0f0f0f0fULL;
+ regs->gpr[ra] = tmp;
+
+ return 0;
+}
+
static int emulate_instruction(struct pt_regs *regs)
{
u32 instword;
@@ -693,6 +713,11 @@ static int emulate_instruction(struct pt
if ((instword & INST_STRING_GEN_MASK) == INST_STRING)
return emulate_string_inst(regs, instword);
+ /* Emulate the popcntb (Population Count Bytes) instruction. */
+ if ((instword & INST_POPCNTB_MASK) == INST_POPCNTB) {
+ return emulate_popcntb_inst(regs, instword);
+ }
+
return -EINVAL;
}
^ permalink raw reply related [flat|nested] 18+ messages in thread
end of thread, other threads:[~2006-08-30 18:11 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-08-17 18:53 [PATCH] powerpc: emulate power5 popcntb instruction Will Schmidt
2006-08-17 19:24 ` Segher Boessenkool
2006-08-18 18:11 ` Will Schmidt
2006-08-18 19:05 ` Arnd Bergmann
2006-08-18 19:30 ` Kumar Gala
2006-08-19 19:10 ` segher
2006-08-19 20:19 ` Arnd Bergmann
2006-08-19 23:32 ` segher
2006-08-21 20:09 ` Will Schmidt
2006-08-24 6:36 ` Paul Mackerras
2006-08-24 15:53 ` Segher Boessenkool
2006-08-25 9:59 ` Gabriel Paubert
2006-08-25 12:57 ` Paul Mackerras
2006-08-28 18:03 ` Willschm
2006-08-29 6:43 ` Segher Boessenkool
2006-08-30 18:11 ` Will Schmidt
2006-08-18 19:42 ` Kumar Gala
2006-08-19 19:09 ` segher
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).