diff options
author | Paul Burton <paul.burton@imgtec.com> | 2014-02-13 11:26:41 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2014-03-26 23:09:09 +0100 |
commit | bbd426f542cb61f2322e15dab4507f2661090c06 (patch) | |
tree | 66cc94a921b0342a4a412646d549562a578fc257 /arch/mips/math-emu | |
parent | 490b004febb3fe9aca7330a729b29fe935be3b31 (diff) | |
download | linux-stable-bbd426f542cb61f2322e15dab4507f2661090c06.tar.gz linux-stable-bbd426f542cb61f2322e15dab4507f2661090c06.tar.bz2 linux-stable-bbd426f542cb61f2322e15dab4507f2661090c06.zip |
MIPS: Simplify FP context access
This patch replaces the fpureg_t typedef with a "union fpureg" enabling
easier access to 32 & 64 bit values. This allows the access macros used
in cp1emu.c to be simplified somewhat. It will also make it easier to
expand the width of the FP registers as will be done in a future
patch in order to support the 128 bit registers introduced with MSA.
No behavioural change is intended by this patch.
Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Reviewed-by: Qais Yousef <qais.yousef@imgtec.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/6532/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/math-emu')
-rw-r--r-- | arch/mips/math-emu/cp1emu.c | 37 | ||||
-rw-r--r-- | arch/mips/math-emu/kernel_linkage.c | 21 |
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(¤t->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(¤t->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(¤t->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(¤t->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(¤t->thread.fpu.fpr[i], 0, fpr_val); } err |= __get_user(current->thread.fpu.fcr31, &sc->sc_fpc_csr); |