Re: [PATCH 1/6] powerpc sstep: Add maddhd, maddhdu, maddld instruction emulation

2019-02-19 Thread Michael Ellerman
Sandipan Das  writes:

> This adds emulation support for the following integer instructions:
>   * Multiply-Add High Doubleword (maddhd)
>   * Multiply-Add High Doubleword Unsigned (maddhdu)
>   * Multiply-Add Low Doubleword (maddld)

This doesn't build with old binutils.

{standard input}:2089: Error: Unrecognized opcode: `maddld'
{standard input}:2104: Error: Unrecognized opcode: `maddhdu'
{standard input}:1141: Error: Unrecognized opcode: `maddhd'


You'll need to add hand built versions, see ppc-opcode.h for examples.

cheers

> diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
> index d81568f783e5..b40ec18515bd 100644
> --- a/arch/powerpc/lib/sstep.c
> +++ b/arch/powerpc/lib/sstep.c
> @@ -1169,7 +1169,7 @@ static nokprobe_inline int trap_compare(long v1, long 
> v2)
>  int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
> unsigned int instr)
>  {
> - unsigned int opcode, ra, rb, rd, spr, u;
> + unsigned int opcode, ra, rb, rc, rd, spr, u;
>   unsigned long int imm;
>   unsigned long int val, val2;
>   unsigned int mb, me, sh;
> @@ -1292,6 +1292,7 @@ int analyse_instr(struct instruction_op *op, const 
> struct pt_regs *regs,
>   rd = (instr >> 21) & 0x1f;
>   ra = (instr >> 16) & 0x1f;
>   rb = (instr >> 11) & 0x1f;
> + rc = (instr >> 6) & 0x1f;
>  
>   switch (opcode) {
>  #ifdef __powerpc64__
> @@ -1305,6 +1306,38 @@ int analyse_instr(struct instruction_op *op, const 
> struct pt_regs *regs,
>   goto trap;
>   return 1;
>  
> +#ifdef __powerpc64__
> + case 4:
> + if (!cpu_has_feature(CPU_FTR_ARCH_300))
> + return -1;
> +
> + switch (instr & 0x3f) {
> + case 48:/* maddhd */
> + asm("maddhd %0,%1,%2,%3" : "=r" (op->val) :
> + "r" (regs->gpr[ra]), "r" (regs->gpr[rb]),
> + "r" (regs->gpr[rc]));
> + goto compute_done;
> +
> + case 49:/* maddhdu */
> + asm("maddhdu %0,%1,%2,%3" : "=r" (op->val) :
> + "r" (regs->gpr[ra]), "r" (regs->gpr[rb]),
> + "r" (regs->gpr[rc]));
> + goto compute_done;
> +
> + case 51:/* maddld */
> + asm("maddld %0,%1,%2,%3" : "=r" (op->val) :
> + "r" (regs->gpr[ra]), "r" (regs->gpr[rb]),
> + "r" (regs->gpr[rc]));
> + goto compute_done;
> + }
> +
> + /*
> +  * There are other instructions from ISA 3.0 with the same
> +  * primary opcode which do not have emulation support yet.
> +  */
> + return -1;
> +#endif
> +
>   case 7: /* mulli */
>   op->val = regs->gpr[ra] * (short) instr;
>   goto compute_done;
> -- 
> 2.14.4


Re: [PATCH 1/6] powerpc sstep: Add maddhd, maddhdu, maddld instruction emulation

2018-09-05 Thread Sandipan Das
Hi Segher,

On Wednesday 05 September 2018 03:42 AM, Segher Boessenkool wrote:
> On Mon, Sep 03, 2018 at 08:49:33PM +0530, Sandipan Das wrote:
>> +#ifdef __powerpc64__
>> +case 4:
>> +if (!cpu_has_feature(CPU_FTR_ARCH_300))
>> +return -1;
>> +
>> +switch (instr & 0x3f) {
>> +case 48:/* maddhd */
>> +asm("maddhd %0,%1,%2,%3" : "=r" (op->val) :
>> +"r" (regs->gpr[ra]), "r" (regs->gpr[rb]),
>> +"r" (regs->gpr[rc]));
>> +goto compute_done;
> 
> If running maddhd does not work, will running it in kernel mode work?
> 

Not sure what you meant here but one of the scenarios that I'm aware of
where this is will be used is if we place a probe at a location having
an maddhd instruction. The kernel would first attempt to emulate its
behaviour, which in this case is done by executing the same instruction
(similar to what is done for mulhd and mulhw) and if that fails, try to
execute the instruction natively.

- Sandipan



Re: [PATCH 1/6] powerpc sstep: Add maddhd, maddhdu, maddld instruction emulation

2018-09-04 Thread Segher Boessenkool
On Mon, Sep 03, 2018 at 08:49:33PM +0530, Sandipan Das wrote:
> +#ifdef __powerpc64__
> + case 4:
> + if (!cpu_has_feature(CPU_FTR_ARCH_300))
> + return -1;
> +
> + switch (instr & 0x3f) {
> + case 48:/* maddhd */
> + asm("maddhd %0,%1,%2,%3" : "=r" (op->val) :
> + "r" (regs->gpr[ra]), "r" (regs->gpr[rb]),
> + "r" (regs->gpr[rc]));
> + goto compute_done;

If running maddhd does not work, will running it in kernel mode work?

I think you should *actually* emulate it.

(Same for the next patch, "darn", but emulation of that is much more
interesting).


Segher


[PATCH 1/6] powerpc sstep: Add maddhd, maddhdu, maddld instruction emulation

2018-09-03 Thread Sandipan Das
This adds emulation support for the following integer instructions:
  * Multiply-Add High Doubleword (maddhd)
  * Multiply-Add High Doubleword Unsigned (maddhdu)
  * Multiply-Add Low Doubleword (maddld)

Signed-off-by: Sandipan Das 
---
 arch/powerpc/lib/sstep.c | 35 ++-
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index d81568f783e5..b40ec18515bd 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -1169,7 +1169,7 @@ static nokprobe_inline int trap_compare(long v1, long v2)
 int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
  unsigned int instr)
 {
-   unsigned int opcode, ra, rb, rd, spr, u;
+   unsigned int opcode, ra, rb, rc, rd, spr, u;
unsigned long int imm;
unsigned long int val, val2;
unsigned int mb, me, sh;
@@ -1292,6 +1292,7 @@ int analyse_instr(struct instruction_op *op, const struct 
pt_regs *regs,
rd = (instr >> 21) & 0x1f;
ra = (instr >> 16) & 0x1f;
rb = (instr >> 11) & 0x1f;
+   rc = (instr >> 6) & 0x1f;
 
switch (opcode) {
 #ifdef __powerpc64__
@@ -1305,6 +1306,38 @@ int analyse_instr(struct instruction_op *op, const 
struct pt_regs *regs,
goto trap;
return 1;
 
+#ifdef __powerpc64__
+   case 4:
+   if (!cpu_has_feature(CPU_FTR_ARCH_300))
+   return -1;
+
+   switch (instr & 0x3f) {
+   case 48:/* maddhd */
+   asm("maddhd %0,%1,%2,%3" : "=r" (op->val) :
+   "r" (regs->gpr[ra]), "r" (regs->gpr[rb]),
+   "r" (regs->gpr[rc]));
+   goto compute_done;
+
+   case 49:/* maddhdu */
+   asm("maddhdu %0,%1,%2,%3" : "=r" (op->val) :
+   "r" (regs->gpr[ra]), "r" (regs->gpr[rb]),
+   "r" (regs->gpr[rc]));
+   goto compute_done;
+
+   case 51:/* maddld */
+   asm("maddld %0,%1,%2,%3" : "=r" (op->val) :
+   "r" (regs->gpr[ra]), "r" (regs->gpr[rb]),
+   "r" (regs->gpr[rc]));
+   goto compute_done;
+   }
+
+   /*
+* There are other instructions from ISA 3.0 with the same
+* primary opcode which do not have emulation support yet.
+*/
+   return -1;
+#endif
+
case 7: /* mulli */
op->val = regs->gpr[ra] * (short) instr;
goto compute_done;
-- 
2.14.4