powerpc: sstep: Add support for maddhd, maddhdu, maddld instructions

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)

As suggested by Michael, this uses a raw .long for specifying the
instruction word when using inline assembly to retain compatibility
with older binutils.

Signed-off-by: Sandipan Das <sandipan@linux.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:
Sandipan Das 2019-02-22 12:23:27 +05:30 committed by Michael Ellerman
parent d608898abc
commit 930d6288a2
2 changed files with 48 additions and 2 deletions

View File

@ -335,6 +335,9 @@
#define PPC_INST_MULLW 0x7c0001d6
#define PPC_INST_MULHWU 0x7c000016
#define PPC_INST_MULLI 0x1c000000
#define PPC_INST_MADDHD 0x10000030
#define PPC_INST_MADDHDU 0x10000031
#define PPC_INST_MADDLD 0x10000033
#define PPC_INST_DIVWU 0x7c000396
#define PPC_INST_DIVD 0x7c0003d2
#define PPC_INST_RLWINM 0x54000000
@ -377,6 +380,7 @@
/* macros to insert fields into opcodes */
#define ___PPC_RA(a) (((a) & 0x1f) << 16)
#define ___PPC_RB(b) (((b) & 0x1f) << 11)
#define ___PPC_RC(c) (((c) & 0x1f) << 6)
#define ___PPC_RS(s) (((s) & 0x1f) << 21)
#define ___PPC_RT(t) ___PPC_RS(t)
#define ___PPC_R(r) (((r) & 0x1) << 16)
@ -396,7 +400,7 @@
#define __PPC_WS(w) (((w) & 0x1f) << 11)
#define __PPC_SH(s) __PPC_WS(s)
#define __PPC_SH64(s) (__PPC_SH(s) | (((s) & 0x20) >> 4))
#define __PPC_MB(s) (((s) & 0x1f) << 6)
#define __PPC_MB(s) ___PPC_RC(s)
#define __PPC_ME(s) (((s) & 0x1f) << 1)
#define __PPC_MB64(s) (__PPC_MB(s) | ((s) & 0x20))
#define __PPC_ME64(s) __PPC_MB64(s)
@ -438,6 +442,15 @@
#define PPC_STQCX(t, a, b) stringify_in_c(.long PPC_INST_STQCX | \
___PPC_RT(t) | ___PPC_RA(a) | \
___PPC_RB(b))
#define PPC_MADDHD(t, a, b, c) stringify_in_c(.long PPC_INST_MADDHD | \
___PPC_RT(t) | ___PPC_RA(a) | \
___PPC_RB(b) | ___PPC_RC(c))
#define PPC_MADDHDU(t, a, b, c) stringify_in_c(.long PPC_INST_MADDHDU | \
___PPC_RT(t) | ___PPC_RA(a) | \
___PPC_RB(b) | ___PPC_RC(c))
#define PPC_MADDLD(t, a, b, c) stringify_in_c(.long PPC_INST_MADDLD | \
___PPC_RT(t) | ___PPC_RA(a) | \
___PPC_RB(b) | ___PPC_RC(c))
#define PPC_MSGSND(b) stringify_in_c(.long PPC_INST_MSGSND | \
___PPC_RB(b))
#define PPC_MSGSYNC stringify_in_c(.long PPC_INST_MSGSYNC)

View File

@ -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 volatile(PPC_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 volatile(PPC_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 volatile(PPC_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;