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:
parent
d608898abc
commit
930d6288a2
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue