summaryrefslogtreecommitdiff
path: root/arch/mips/math-emu/cp1emu.c
diff options
context:
space:
mode:
authorLeonid Yegoshin <Leonid.Yegoshin@imgtec.com>2013-11-07 12:48:28 +0000
committerRalf Baechle <ralf@linux-mips.org>2014-01-13 23:40:55 +0100
commit1ac944007bede6d6f934831959b0e2b65c82d291 (patch)
treeda2b1745bd4c8cd447574e7bd9b44d220b0f2f4b /arch/mips/math-emu/cp1emu.c
parent7e22e91102c6b9df7c4ae2168910e19d2bb14cd6 (diff)
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: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com> Signed-off-by: Steven J. Hill <Steven.Hill@imgtec.com> Signed-off-by: Paul Burton <paul.burton@imgtec.com> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/6112/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/math-emu/cp1emu.c')
-rw-r--r--arch/mips/math-emu/cp1emu.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c
index efe008846ed0..aaf7c92f4629 100644
--- a/arch/mips/math-emu/cp1emu.c
+++ b/arch/mips/math-emu/cp1emu.c
@@ -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 | (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 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,
break;
#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:
/* copregister rd -> gpr[rt] */
if (MIPSInst_RT(ir) != 0) {
@@ -1263,6 +1286,7 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
#endif
default:
+sigill:
return SIGILL;
}