Commit 1ac94400 authored by Leonid Yegoshin's avatar Leonid Yegoshin Committed by Ralf Baechle

MIPS: math-emu: Add mfhc1 & mthc1 support.

This patch adds support for the mfhc1 & mthc1 instructions to the FPU
emulator. These instructions were introduced in release 2 of the MIPS32
& MIPS64 architectures and allow access to the most significant 32 bits
of a 64-bit FP register.

[ralf@linux-mips.org: Fix ifdef hell added by original patch.]
Signed-off-by: default avatarLeonid Yegoshin <Leonid.Yegoshin@imgtec.com>
Signed-off-by: default avatarSteven J. Hill <Steven.Hill@imgtec.com>
Signed-off-by: default avatarPaul Burton <paul.burton@imgtec.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/6112/Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 7e22e911
...@@ -98,8 +98,9 @@ enum rt_op { ...@@ -98,8 +98,9 @@ enum rt_op {
*/ */
enum cop_op { enum cop_op {
mfc_op = 0x00, dmfc_op = 0x01, mfc_op = 0x00, dmfc_op = 0x01,
cfc_op = 0x02, mtc_op = 0x04, cfc_op = 0x02, mfhc_op = 0x03,
dmtc_op = 0x05, ctc_op = 0x06, mtc_op = 0x04, dmtc_op = 0x05,
ctc_op = 0x06, mthc_op = 0x07,
bc_op = 0x08, cop_op = 0x10, bc_op = 0x08, cop_op = 0x10,
copm_op = 0x18 copm_op = 0x18
}; };
......
...@@ -878,6 +878,10 @@ static inline int cop1_64bit(struct pt_regs *xcp) ...@@ -878,6 +878,10 @@ static inline int cop1_64bit(struct pt_regs *xcp)
ctx->fpr[x & ~1] >> 32 << 32 | (u32)(si) : \ ctx->fpr[x & ~1] >> 32 << 32 | (u32)(si) : \
ctx->fpr[x & ~1] << 32 >> 32 | (u64)(si) << 32) ctx->fpr[x & ~1] << 32 >> 32 | (u64)(si) << 32)
#define SIFROMHREG(si, x) ((si) = (int)(ctx->fpr[x] >> 32))
#define SITOHREG(si, x) (ctx->fpr[x] = \
ctx->fpr[x] << 32 >> 32 | (u64)(si) << 32)
#define DIFROMREG(di, x) ((di) = ctx->fpr[x & ~(cop1_64bit(xcp) == 0)]) #define DIFROMREG(di, x) ((di) = ctx->fpr[x & ~(cop1_64bit(xcp) == 0)])
#define DITOREG(di, x) (ctx->fpr[x & ~(cop1_64bit(xcp) == 0)] = (di)) #define DITOREG(di, x) (ctx->fpr[x & ~(cop1_64bit(xcp) == 0)] = (di))
...@@ -1055,6 +1059,25 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx, ...@@ -1055,6 +1059,25 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
break; break;
#endif #endif
case mfhc_op:
if (!cpu_has_mips_r2)
goto sigill;
/* copregister rd -> gpr[rt] */
if (MIPSInst_RT(ir) != 0) {
SIFROMHREG(xcp->regs[MIPSInst_RT(ir)],
MIPSInst_RD(ir));
}
break;
case mthc_op:
if (!cpu_has_mips_r2)
goto sigill;
/* copregister rd <- gpr[rt] */
SITOHREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir));
break;
case mfc_op: case mfc_op:
/* copregister rd -> gpr[rt] */ /* copregister rd -> gpr[rt] */
if (MIPSInst_RT(ir) != 0) { if (MIPSInst_RT(ir) != 0) {
...@@ -1263,6 +1286,7 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx, ...@@ -1263,6 +1286,7 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
#endif #endif
default: default:
sigill:
return SIGILL; return SIGILL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment