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 <sandi...@linux.ibm.com>
---
 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

Reply via email to