summaryrefslogtreecommitdiff
path: root/arch/mips/math-emu
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/math-emu')
-rw-r--r--arch/mips/math-emu/cp1emu.c37
-rw-r--r--arch/mips/math-emu/kernel_linkage.c21
2 files changed, 36 insertions, 22 deletions
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c
index 506925b2c3f3..196cf1ab65af 100644
--- a/arch/mips/math-emu/cp1emu.c
+++ b/arch/mips/math-emu/cp1emu.c
@@ -876,20 +876,28 @@ static inline int cop1_64bit(struct pt_regs *xcp)
#endif
}
-#define SIFROMREG(si, x) ((si) = cop1_64bit(xcp) || !(x & 1) ? \
- (int)ctx->fpr[x] : (int)(ctx->fpr[x & ~1] >> 32))
+#define SIFROMREG(si, x) do { \
+ if (cop1_64bit(xcp)) \
+ (si) = get_fpr32(&ctx->fpr[x], 0); \
+ else \
+ (si) = get_fpr32(&ctx->fpr[(x) & ~1], (x) & 1); \
+} while (0)
-#define SITOREG(si, x) (ctx->fpr[x & ~(cop1_64bit(xcp) == 0)] = \
- cop1_64bit(xcp) || !(x & 1) ? \
- ctx->fpr[x & ~1] >> 32 << 32 | (u32)(si) : \
- ctx->fpr[x & ~1] << 32 >> 32 | (u64)(si) << 32)
+#define SITOREG(si, x) do { \
+ if (cop1_64bit(xcp)) \
+ set_fpr32(&ctx->fpr[x], 0, si); \
+ else \
+ set_fpr32(&ctx->fpr[(x) & ~1], (x) & 1, si); \
+} while (0)
-#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 SIFROMHREG(si, x) ((si) = get_fpr32(&ctx->fpr[x], 1))
+#define SITOHREG(si, x) set_fpr32(&ctx->fpr[x], 1, si)
-#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 DIFROMREG(di, x) \
+ ((di) = get_fpr64(&ctx->fpr[(x) & ~(cop1_64bit(xcp) == 0)], 0))
+
+#define DITOREG(di, x) \
+ set_fpr64(&ctx->fpr[(x) & ~(cop1_64bit(xcp) == 0)], 0, di)
#define SPFROMREG(sp, x) SIFROMREG((sp).bits, x)
#define SPTOREG(sp, x) SITOREG((sp).bits, x)
@@ -1960,15 +1968,18 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
#if defined(__mips64)
case l_fmt:{
+ u64 bits;
+ DIFROMREG(bits, MIPSInst_FS(ir));
+
switch (MIPSInst_FUNC(ir)) {
case fcvts_op:
/* convert long to single precision real */
- rv.s = ieee754sp_flong(ctx->fpr[MIPSInst_FS(ir)]);
+ rv.s = ieee754sp_flong(bits);
rfmt = s_fmt;
goto copcsr;
case fcvtd_op:
/* convert long to double precision real */
- rv.d = ieee754dp_flong(ctx->fpr[MIPSInst_FS(ir)]);
+ rv.d = ieee754dp_flong(bits);
rfmt = d_fmt;
goto copcsr;
default:
diff --git a/arch/mips/math-emu/kernel_linkage.c b/arch/mips/math-emu/kernel_linkage.c
index 3aeae07ed5b8..9b46213b1035 100644
--- a/arch/mips/math-emu/kernel_linkage.c
+++ b/arch/mips/math-emu/kernel_linkage.c
@@ -40,9 +40,8 @@ void fpu_emulator_init_fpu(void)
}
current->thread.fpu.fcr31 = 0;
- for (i = 0; i < 32; i++) {
- current->thread.fpu.fpr[i] = SIGNALLING_NAN;
- }
+ for (i = 0; i < 32; i++)
+ set_fpr64(&current->thread.fpu.fpr[i], 0, SIGNALLING_NAN);
}
@@ -59,7 +58,8 @@ int fpu_emulator_save_context(struct sigcontext __user *sc)
for (i = 0; i < 32; i++) {
err |=
- __put_user(current->thread.fpu.fpr[i], &sc->sc_fpregs[i]);
+ __put_user(get_fpr64(&current->thread.fpu.fpr[i], 0),
+ &sc->sc_fpregs[i]);
}
err |= __put_user(current->thread.fpu.fcr31, &sc->sc_fpc_csr);
@@ -70,10 +70,11 @@ int fpu_emulator_restore_context(struct sigcontext __user *sc)
{
int i;
int err = 0;
+ u64 fpr_val;
for (i = 0; i < 32; i++) {
- err |=
- __get_user(current->thread.fpu.fpr[i], &sc->sc_fpregs[i]);
+ err |= __get_user(fpr_val, &sc->sc_fpregs[i]);
+ set_fpr64(&current->thread.fpu.fpr[i], 0, fpr_val);
}
err |= __get_user(current->thread.fpu.fcr31, &sc->sc_fpc_csr);
@@ -93,7 +94,8 @@ int fpu_emulator_save_context32(struct sigcontext32 __user *sc)
for (i = 0; i < 32; i += inc) {
err |=
- __put_user(current->thread.fpu.fpr[i], &sc->sc_fpregs[i]);
+ __put_user(get_fpr64(&current->thread.fpu.fpr[i], 0),
+ &sc->sc_fpregs[i]);
}
err |= __put_user(current->thread.fpu.fcr31, &sc->sc_fpc_csr);
@@ -105,10 +107,11 @@ int fpu_emulator_restore_context32(struct sigcontext32 __user *sc)
int i;
int err = 0;
int inc = test_thread_flag(TIF_32BIT_FPREGS) ? 2 : 1;
+ u64 fpr_val;
for (i = 0; i < 32; i += inc) {
- err |=
- __get_user(current->thread.fpu.fpr[i], &sc->sc_fpregs[i]);
+ err |= __get_user(fpr_val, &sc->sc_fpregs[i]);
+ set_fpr64(&current->thread.fpu.fpr[i], 0, fpr_val);
}
err |= __get_user(current->thread.fpu.fcr31, &sc->sc_fpc_csr);