* [PATCH v2 1/5] powerpc/lib/sstep: Add cmpb instruction emulation
@ 2017-07-24 1:01 Matt Brown
2017-07-24 1:01 ` [PATCH v2 2/5] powerpc/lib/sstep: Add popcnt " Matt Brown
` (3 more replies)
0 siblings, 4 replies; 12+ messages in thread
From: Matt Brown @ 2017-07-24 1:01 UTC (permalink / raw)
To: linuxppc-dev
This patch adds emulation of the cmpb instruction, enabling xmon to
emulate this instruction.
Tested for correctness against the cmpb asm instruction on ppc64le.
Signed-off-by: Matt Brown <matthew.brown.dev@gmail.com>
---
v2:
- fixed opcode
- fixed mask typecasting
---
arch/powerpc/lib/sstep.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index 33117f8..87d277f 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -596,6 +596,22 @@ static nokprobe_inline void do_cmp_unsigned(struct pt_regs *regs, unsigned long
regs->ccr = (regs->ccr & ~(0xf << shift)) | (crval << shift);
}
+static nokprobe_inline void do_cmpb(struct pt_regs *regs, unsigned long v1,
+ unsigned long v2, int rd)
+{
+ unsigned long long out_val, mask;
+ int i;
+
+ out_val = 0;
+ for (i = 0; i < 8; i++) {
+ mask = 0xffUL << (i * 8);
+ if ((v1 & mask) == (v2 & mask))
+ out_val |= mask;
+ }
+
+ regs->gpr[rd] = out_val;
+}
+
static nokprobe_inline int trap_compare(long v1, long v2)
{
int ret = 0;
@@ -1049,6 +1065,10 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs,
do_cmp_unsigned(regs, val, val2, rd >> 2);
goto instr_done;
+ case 508: /* cmpb */
+ do_cmpb(regs, regs->gpr[rd], regs->gpr[rb], ra);
+ goto instr_done;
+
/*
* Arithmetic instructions
*/
--
2.9.3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 2/5] powerpc/lib/sstep: Add popcnt instruction emulation
2017-07-24 1:01 [PATCH v2 1/5] powerpc/lib/sstep: Add cmpb instruction emulation Matt Brown
@ 2017-07-24 1:01 ` Matt Brown
2017-07-24 7:36 ` Segher Boessenkool
2017-07-24 10:28 ` Balbir Singh
2017-07-24 1:01 ` [PATCH v2 3/5] powerpc/lib/sstep: Add bpermd " Matt Brown
` (2 subsequent siblings)
3 siblings, 2 replies; 12+ messages in thread
From: Matt Brown @ 2017-07-24 1:01 UTC (permalink / raw)
To: linuxppc-dev
This adds emulations for the popcntb, popcntw, and popcntd instructions.
Tested for correctness against the popcnt{b,w,d} instructions on ppc64le.
Signed-off-by: Matt Brown <matthew.brown.dev@gmail.com>
---
v2:
- fixed opcodes
- fixed typecasting
- fixed bitshifting error for both 32 and 64bit arch
---
arch/powerpc/lib/sstep.c | 43 ++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 42 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index 87d277f..e6a16a3 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -612,6 +612,35 @@ static nokprobe_inline void do_cmpb(struct pt_regs *regs, unsigned long v1,
regs->gpr[rd] = out_val;
}
+/*
+ * The size parameter is used to adjust the equivalent popcnt instruction.
+ * popcntb = 8, popcntw = 32, popcntd = 64
+ */
+static nokprobe_inline void do_popcnt(struct pt_regs *regs, unsigned long v1,
+ int size, int ra)
+{
+ unsigned long long high, low, mask;
+ unsigned int n;
+ int i, j;
+
+ high = 0;
+ low = 0;
+
+ for (i = 0; i < (64 / size); i++) {
+ n = 0;
+ for (j = 0; j < size; j++) {
+ mask = 1UL << (j + (i * size));
+ if (v1 & mask)
+ n++;
+ }
+ if ((i * size) < 32)
+ low |= n << (i * size);
+ else
+ high |= n << ((i * size) - 32);
+ }
+ regs->gpr[ra] = (high << 32) | low;
+}
+
static nokprobe_inline int trap_compare(long v1, long v2)
{
int ret = 0;
@@ -1194,6 +1223,10 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs,
regs->gpr[ra] = regs->gpr[rd] & ~regs->gpr[rb];
goto logical_done;
+ case 122: /* popcntb */
+ do_popcnt(regs, regs->gpr[rd], 8, ra);
+ goto logical_done;
+
case 124: /* nor */
regs->gpr[ra] = ~(regs->gpr[rd] | regs->gpr[rb]);
goto logical_done;
@@ -1206,6 +1239,10 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs,
regs->gpr[ra] = regs->gpr[rd] ^ regs->gpr[rb];
goto logical_done;
+ case 378: /* popcntw */
+ do_popcnt(regs, regs->gpr[rd], 32, ra);
+ goto logical_done;
+
case 412: /* orc */
regs->gpr[ra] = regs->gpr[rd] | ~regs->gpr[rb];
goto logical_done;
@@ -1217,7 +1254,11 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs,
case 476: /* nand */
regs->gpr[ra] = ~(regs->gpr[rd] & regs->gpr[rb]);
goto logical_done;
-
+#ifdef __powerpc64__
+ case 506: /* popcntd */
+ do_popcnt(regs, regs->gpr[rd], 64, ra);
+ goto logical_done;
+#endif
case 922: /* extsh */
regs->gpr[ra] = (signed short) regs->gpr[rd];
goto logical_done;
--
2.9.3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v2 2/5] powerpc/lib/sstep: Add popcnt instruction emulation
2017-07-24 1:01 ` [PATCH v2 2/5] powerpc/lib/sstep: Add popcnt " Matt Brown
@ 2017-07-24 7:36 ` Segher Boessenkool
2017-07-24 10:28 ` Balbir Singh
1 sibling, 0 replies; 12+ messages in thread
From: Segher Boessenkool @ 2017-07-24 7:36 UTC (permalink / raw)
To: Matt Brown; +Cc: linuxppc-dev
Hi Matt,
On Mon, Jul 24, 2017 at 11:01:06AM +1000, Matt Brown wrote:
> + for (i = 0; i < (64 / size); i++) {
If you do
for (i = 0; i < 64; i += size)
things are slightly nicer.
> + if ((i * size) < 32)
> + low |= n << (i * size);
> + else
> + high |= n << ((i * size) - 32);
> + }
> + regs->gpr[ra] = (high << 32) | low;
Why have separate high and low vars?
And there are much better ways to calculate popcount, of course.
Segher
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 2/5] powerpc/lib/sstep: Add popcnt instruction emulation
2017-07-24 1:01 ` [PATCH v2 2/5] powerpc/lib/sstep: Add popcnt " Matt Brown
2017-07-24 7:36 ` Segher Boessenkool
@ 2017-07-24 10:28 ` Balbir Singh
2017-07-25 0:53 ` Matt Brown
1 sibling, 1 reply; 12+ messages in thread
From: Balbir Singh @ 2017-07-24 10:28 UTC (permalink / raw)
To: Matt Brown; +Cc: open list:LINUX FOR POWERPC (32-BIT AND 64-BIT)
On Mon, Jul 24, 2017 at 11:01 AM, Matt Brown
<matthew.brown.dev@gmail.com> wrote:
> This adds emulations for the popcntb, popcntw, and popcntd instructions.
> Tested for correctness against the popcnt{b,w,d} instructions on ppc64le.
>
> Signed-off-by: Matt Brown <matthew.brown.dev@gmail.com>
> ---
> v2:
> - fixed opcodes
> - fixed typecasting
> - fixed bitshifting error for both 32 and 64bit arch
> ---
> arch/powerpc/lib/sstep.c | 43 ++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 42 insertions(+), 1 deletion(-)
>
> diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
> index 87d277f..e6a16a3 100644
> --- a/arch/powerpc/lib/sstep.c
> +++ b/arch/powerpc/lib/sstep.c
> @@ -612,6 +612,35 @@ static nokprobe_inline void do_cmpb(struct pt_regs *regs, unsigned long v1,
> regs->gpr[rd] = out_val;
> }
>
> +/*
> + * The size parameter is used to adjust the equivalent popcnt instruction.
> + * popcntb = 8, popcntw = 32, popcntd = 64
> + */
> +static nokprobe_inline void do_popcnt(struct pt_regs *regs, unsigned long v1,
> + int size, int ra)
> +{
> + unsigned long long high, low, mask;
> + unsigned int n;
> + int i, j;
> +
> + high = 0;
> + low = 0;
> +
> + for (i = 0; i < (64 / size); i++) {
> + n = 0;
> + for (j = 0; j < size; j++) {
> + mask = 1UL << (j + (i * size));
> + if (v1 & mask)
> + n++;
> + }
> + if ((i * size) < 32)
> + low |= n << (i * size);
> + else
> + high |= n << ((i * size) - 32);
> + }
> + regs->gpr[ra] = (high << 32) | low;
> +}
There's a way to do it in very efficient way via the Giles-Miller
method of side-ways addition
Please see
http://opensourceforu.com/2012/06/power-programming-bitwise-tips-tricks/
and lib/hweight.c, you can reuse the code from lib/hweight.c
Balbir Singh
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 2/5] powerpc/lib/sstep: Add popcnt instruction emulation
2017-07-24 10:28 ` Balbir Singh
@ 2017-07-25 0:53 ` Matt Brown
0 siblings, 0 replies; 12+ messages in thread
From: Matt Brown @ 2017-07-25 0:53 UTC (permalink / raw)
To: Balbir Singh; +Cc: open list:LINUX FOR POWERPC (32-BIT AND 64-BIT)
On Mon, Jul 24, 2017 at 8:28 PM, Balbir Singh <bsingharora@gmail.com> wrote:
> On Mon, Jul 24, 2017 at 11:01 AM, Matt Brown
> <matthew.brown.dev@gmail.com> wrote:
>> This adds emulations for the popcntb, popcntw, and popcntd instructions.
>> Tested for correctness against the popcnt{b,w,d} instructions on ppc64le.
>>
>> Signed-off-by: Matt Brown <matthew.brown.dev@gmail.com>
>> ---
>> v2:
>> - fixed opcodes
>> - fixed typecasting
>> - fixed bitshifting error for both 32 and 64bit arch
>> ---
>> arch/powerpc/lib/sstep.c | 43 ++++++++++++++++++++++++++++++++++++++++++-
>> 1 file changed, 42 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
>> index 87d277f..e6a16a3 100644
>> --- a/arch/powerpc/lib/sstep.c
>> +++ b/arch/powerpc/lib/sstep.c
>> @@ -612,6 +612,35 @@ static nokprobe_inline void do_cmpb(struct pt_regs *regs, unsigned long v1,
>> regs->gpr[rd] = out_val;
>> }
>>
>> +/*
>> + * The size parameter is used to adjust the equivalent popcnt instruction.
>> + * popcntb = 8, popcntw = 32, popcntd = 64
>> + */
>> +static nokprobe_inline void do_popcnt(struct pt_regs *regs, unsigned long v1,
>> + int size, int ra)
>> +{
>> + unsigned long long high, low, mask;
>> + unsigned int n;
>> + int i, j;
>> +
>> + high = 0;
>> + low = 0;
>> +
>> + for (i = 0; i < (64 / size); i++) {
>> + n = 0;
>> + for (j = 0; j < size; j++) {
>> + mask = 1UL << (j + (i * size));
>> + if (v1 & mask)
>> + n++;
>> + }
>> + if ((i * size) < 32)
>> + low |= n << (i * size);
>> + else
>> + high |= n << ((i * size) - 32);
>> + }
>> + regs->gpr[ra] = (high << 32) | low;
>> +}
>
> There's a way to do it in very efficient way via the Giles-Miller
> method of side-ways addition
>
> Please see
>
> http://opensourceforu.com/2012/06/power-programming-bitwise-tips-tricks/
> and lib/hweight.c, you can reuse the code from lib/hweight.c
Oh that's a really cool technique.
We could use that for the parity instructions too.
>
> Balbir Singh
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2 3/5] powerpc/lib/sstep: Add bpermd instruction emulation
2017-07-24 1:01 [PATCH v2 1/5] powerpc/lib/sstep: Add cmpb instruction emulation Matt Brown
2017-07-24 1:01 ` [PATCH v2 2/5] powerpc/lib/sstep: Add popcnt " Matt Brown
@ 2017-07-24 1:01 ` Matt Brown
2017-07-24 1:01 ` [PATCH 4/5] powerpc/lib/sstep: Add prty " Matt Brown
2017-07-24 1:01 ` [PATCH v2 5/5] powerpc/lib/sstep: Add isel " Matt Brown
3 siblings, 0 replies; 12+ messages in thread
From: Matt Brown @ 2017-07-24 1:01 UTC (permalink / raw)
To: linuxppc-dev
This adds emulation for the bpermd instruction.
Tested for correctness against the bpermd instruction on ppc64le.
Signed-off-by: Matt Brown <matthew.brown.dev@gmail.com>
---
v2:
- fixed opcode
- added ifdef tags to do_bpermd func
- fixed bitshifting errors
---
arch/powerpc/lib/sstep.c | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index e6a16a3..a756f44 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -641,6 +641,24 @@ static nokprobe_inline void do_popcnt(struct pt_regs *regs, unsigned long v1,
regs->gpr[ra] = (high << 32) | low;
}
+#ifdef __powerpc64__
+static nokprobe_inline void do_bpermd(struct pt_regs *regs, unsigned long v1,
+ unsigned long v2, int ra)
+{
+ unsigned char perm, idx;
+ unsigned int i;
+
+ perm = 0;
+ for (i = 0; i < 8; i++) {
+ idx = (v1 >> (i * 8)) & 0xff;
+ if (idx < 64)
+ if (v2 & PPC_BIT(idx))
+ perm |= 1 << i;
+ }
+ regs->gpr[ra] = perm;
+}
+#endif /* __powerpc64__ */
+
static nokprobe_inline int trap_compare(long v1, long v2)
{
int ret = 0;
@@ -1230,7 +1248,11 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs,
case 124: /* nor */
regs->gpr[ra] = ~(regs->gpr[rd] | regs->gpr[rb]);
goto logical_done;
-
+#ifdef __powerpc64__
+ case 252: /* bpermd */
+ do_bpermd(regs, regs->gpr[rd], regs->gpr[rb], ra);
+ goto logical_done;
+#endif
case 284: /* xor */
regs->gpr[ra] = ~(regs->gpr[rd] ^ regs->gpr[rb]);
goto logical_done;
--
2.9.3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 4/5] powerpc/lib/sstep: Add prty instruction emulation
2017-07-24 1:01 [PATCH v2 1/5] powerpc/lib/sstep: Add cmpb instruction emulation Matt Brown
2017-07-24 1:01 ` [PATCH v2 2/5] powerpc/lib/sstep: Add popcnt " Matt Brown
2017-07-24 1:01 ` [PATCH v2 3/5] powerpc/lib/sstep: Add bpermd " Matt Brown
@ 2017-07-24 1:01 ` Matt Brown
2017-07-24 1:01 ` [PATCH v2 5/5] powerpc/lib/sstep: Add isel " Matt Brown
3 siblings, 0 replies; 12+ messages in thread
From: Matt Brown @ 2017-07-24 1:01 UTC (permalink / raw)
To: linuxppc-dev
This add emulation for the prtyw and prtyd instructions.
Tested for logical correctness against the prtyw and prtyd instructions
on ppc64le.
Signed-off-by: Matt Brown <matthew.brown.dev@gmail.com>
---
v2:
- fixed opcodes
- fixed bitshifting and typecast errors
- merged do_prtyw and do_prtyd into single function
---
arch/powerpc/lib/sstep.c | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index a756f44..1820fd6 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -658,6 +658,29 @@ static nokprobe_inline void do_bpermd(struct pt_regs *regs, unsigned long v1,
regs->gpr[ra] = perm;
}
#endif /* __powerpc64__ */
+/*
+ * The size parameter adjusts the equivalent prty instruction.
+ * prtyw = 32, prtyd = 64
+ */
+static nokprobe_inline void do_prty(struct pt_regs *regs, unsigned long v,
+ int size, int ra)
+{
+ unsigned long long high, low;
+ unsigned int i;
+
+ high = 0;
+ low = 0;
+
+ for (i = 0; i < 8; i++) {
+ if (v & (1UL << (i * 8)))
+ (i < 4) ? (low++) : (high++);
+ }
+
+ if (size == 32)
+ regs->gpr[ra] = ((high & 1) << 32) | (low & 1);
+ else
+ regs->gpr[ra] = (high + low) & 1;
+}
static nokprobe_inline int trap_compare(long v1, long v2)
{
@@ -1248,6 +1271,14 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs,
case 124: /* nor */
regs->gpr[ra] = ~(regs->gpr[rd] | regs->gpr[rb]);
goto logical_done;
+
+ case 154: /* prtyw */
+ do_prty(regs, regs->gpr[rd], 32, ra);
+ goto logical_done;
+
+ case 186: /* prtyd */
+ do_prty(regs, regs->gpr[rd], 64, ra);
+ goto logical_done;
#ifdef __powerpc64__
case 252: /* bpermd */
do_bpermd(regs, regs->gpr[rd], regs->gpr[rb], ra);
--
2.9.3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 5/5] powerpc/lib/sstep: Add isel instruction emulation
2017-07-24 1:01 [PATCH v2 1/5] powerpc/lib/sstep: Add cmpb instruction emulation Matt Brown
` (2 preceding siblings ...)
2017-07-24 1:01 ` [PATCH 4/5] powerpc/lib/sstep: Add prty " Matt Brown
@ 2017-07-24 1:01 ` Matt Brown
3 siblings, 0 replies; 12+ messages in thread
From: Matt Brown @ 2017-07-24 1:01 UTC (permalink / raw)
To: linuxppc-dev
This adds emulation for the isel instruction.
Tested for correctness against the isel instruction and its extended
mnemonics (lt, gt, eq) on ppc64le.
Signed-off-by: Matt Brown <matthew.brown.dev@gmail.com>
---
v2:
- fixed opcode
- fixed definition to include the 'if RA=0, a=0' clause
- fixed ccr bitshifting error
---
arch/powerpc/lib/sstep.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index b08eb96..e1f4ec6 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -1246,6 +1246,17 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs,
/*
* Logical instructions
*/
+ case 15: /* isel */
+ mb = (instr >> 6) & 0x1f; /* bc */
+ val = (regs->ccr >> (31 - mb)) & 1;
+ val2 = (ra) ? regs->gpr[ra] : 0;
+
+ if (val)
+ regs->gpr[rd] = val2;
+ else
+ regs->gpr[rd] = regs->gpr[rb];
+ goto logical_done;
+
case 26: /* cntlzw */
asm("cntlzw %0,%1" : "=r" (regs->gpr[ra]) :
"r" (regs->gpr[rd]));
--
2.9.3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 1/5] powerpc/lib/sstep: Add cmpb instruction emulation
@ 2017-07-13 3:25 Matt Brown
2017-07-13 3:25 ` [PATCH 4/5] powerpc/lib/sstep: Add prty " Matt Brown
0 siblings, 1 reply; 12+ messages in thread
From: Matt Brown @ 2017-07-13 3:25 UTC (permalink / raw)
To: linuxppc-dev; +Cc: anton
This patch adds emulation of the cmpb instruction, enabling xmon to
emulate this instruction.
Signed-off-by: Matt Brown <matthew.brown.dev@gmail.com>
---
arch/powerpc/lib/sstep.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index 33117f8..f3e9ba8 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -596,6 +596,23 @@ static nokprobe_inline void do_cmp_unsigned(struct pt_regs *regs, unsigned long
regs->ccr = (regs->ccr & ~(0xf << shift)) | (crval << shift);
}
+static nokprobe_inline void do_cmpb(struct pt_regs *regs, unsigned long v1,
+ unsigned long v2, int rd)
+{
+ unsigned long out_val, mask;
+ int i;
+
+ out_val = 0;
+ for (i = 0; i < 8; i++) {
+ mask = 0xff << (i * 8);
+
+ if ((v1 & mask) == (v2 & mask))
+ out_val |= mask;
+ }
+
+ regs->gpr[rd] = out_val;
+}
+
static nokprobe_inline int trap_compare(long v1, long v2)
{
int ret = 0;
@@ -1049,6 +1066,13 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs,
do_cmp_unsigned(regs, val, val2, rd >> 2);
goto instr_done;
+ case 19173952: /* cmpb */
+ val = regs->gpr[rd];
+ val2 = regs->gpr[rb];
+
+ do_cmpb(regs, val, val2, ra);
+ goto instr_done;
+
/*
* Arithmetic instructions
*/
--
2.9.3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 4/5] powerpc/lib/sstep: Add prty instruction emulation
2017-07-13 3:25 [PATCH 1/5] powerpc/lib/sstep: Add cmpb " Matt Brown
@ 2017-07-13 3:25 ` Matt Brown
2017-07-13 7:37 ` Segher Boessenkool
2017-07-14 19:02 ` kbuild test robot
0 siblings, 2 replies; 12+ messages in thread
From: Matt Brown @ 2017-07-13 3:25 UTC (permalink / raw)
To: linuxppc-dev; +Cc: anton
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(-)
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
*/
--
2.9.3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH 4/5] powerpc/lib/sstep: Add prty instruction emulation
2017-07-13 3:25 ` [PATCH 4/5] powerpc/lib/sstep: Add prty " Matt Brown
@ 2017-07-13 7:37 ` Segher Boessenkool
2017-07-14 0:46 ` Matt Brown
2017-07-14 19:02 ` kbuild test robot
1 sibling, 1 reply; 12+ messages in thread
From: Segher Boessenkool @ 2017-07-13 7:37 UTC (permalink / raw)
To: Matt Brown; +Cc: linuxppc-dev, anton
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
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 4/5] powerpc/lib/sstep: Add prty instruction emulation
2017-07-13 7:37 ` Segher Boessenkool
@ 2017-07-14 0:46 ` Matt Brown
0 siblings, 0 replies; 12+ messages in thread
From: Matt Brown @ 2017-07-14 0:46 UTC (permalink / raw)
To: Segher Boessenkool; +Cc: linuxppc-dev, Anton Blanchard
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
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 4/5] powerpc/lib/sstep: Add prty instruction emulation
2017-07-13 3:25 ` [PATCH 4/5] powerpc/lib/sstep: Add prty " Matt Brown
2017-07-13 7:37 ` Segher Boessenkool
@ 2017-07-14 19:02 ` kbuild test robot
1 sibling, 0 replies; 12+ messages in thread
From: kbuild test robot @ 2017-07-14 19:02 UTC (permalink / raw)
To: Matt Brown; +Cc: kbuild-all, linuxppc-dev, anton
[-- Attachment #1: Type: text/plain, Size: 1774 bytes --]
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
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 17566 bytes --]
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2017-07-25 0:53 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-07-24 1:01 [PATCH v2 1/5] powerpc/lib/sstep: Add cmpb instruction emulation Matt Brown
2017-07-24 1:01 ` [PATCH v2 2/5] powerpc/lib/sstep: Add popcnt " Matt Brown
2017-07-24 7:36 ` Segher Boessenkool
2017-07-24 10:28 ` Balbir Singh
2017-07-25 0:53 ` Matt Brown
2017-07-24 1:01 ` [PATCH v2 3/5] powerpc/lib/sstep: Add bpermd " Matt Brown
2017-07-24 1:01 ` [PATCH 4/5] powerpc/lib/sstep: Add prty " Matt Brown
2017-07-24 1:01 ` [PATCH v2 5/5] powerpc/lib/sstep: Add isel " Matt Brown
-- strict thread matches above, loose matches on Subject: below --
2017-07-13 3:25 [PATCH 1/5] powerpc/lib/sstep: Add cmpb " Matt Brown
2017-07-13 3:25 ` [PATCH 4/5] powerpc/lib/sstep: Add prty " Matt Brown
2017-07-13 7:37 ` Segher Boessenkool
2017-07-14 0:46 ` Matt Brown
2017-07-14 19:02 ` kbuild test robot
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).