Commit 08a07904 authored by Ralf Baechle's avatar Ralf Baechle

MIPS: math-emu: Remove most ifdefery.

Most of these tests should be runtime tests.  This also finally means
that on a MIPS III systems MIPS IV opcodes are going to result in an
exception as they're supposed to.
Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 9e8bad1f
...@@ -183,6 +183,17 @@ ...@@ -183,6 +183,17 @@
/* /*
* Shortcuts ... * Shortcuts ...
*/ */
#define cpu_has_mips_2_3_4_5 (cpu_has_mips_2 | cpu_has_mips_3_4_5)
#define cpu_has_mips_3_4_5 (cpu_has_mips_3 | cpu_has_mips_4_5)
#define cpu_has_mips_4_5 (cpu_has_mips_4 | cpu_has_mips_5)
#define cpu_has_mips_2_3_4_5_r (cpu_has_mips_2 | cpu_has_mips_3_4_5_r)
#define cpu_has_mips_3_4_5_r (cpu_has_mips_3 | cpu_has_mips_4_5_r)
#define cpu_has_mips_4_5_r (cpu_has_mips_4 | cpu_has_mips_5_r)
#define cpu_has_mips_5_r (cpu_has_mips_5 | cpu_has_mips_r)
#define cpu_has_mips_4_5_r2 (cpu_has_mips_4_5 | cpu_has_mips_r2)
#define cpu_has_mips32 (cpu_has_mips32r1 | cpu_has_mips32r2) #define cpu_has_mips32 (cpu_has_mips32r1 | cpu_has_mips32r2)
#define cpu_has_mips64 (cpu_has_mips64r1 | cpu_has_mips64r2) #define cpu_has_mips64 (cpu_has_mips64r1 | cpu_has_mips64r2)
#define cpu_has_mips_r1 (cpu_has_mips32r1 | cpu_has_mips64r1) #define cpu_has_mips_r1 (cpu_has_mips32r1 | cpu_has_mips64r1)
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
*/ */
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/debugfs.h> #include <linux/debugfs.h>
#include <linux/kconfig.h>
#include <linux/percpu-defs.h> #include <linux/percpu-defs.h>
#include <linux/perf_event.h> #include <linux/perf_event.h>
...@@ -50,22 +51,13 @@ ...@@ -50,22 +51,13 @@
#include "ieee754.h" #include "ieee754.h"
/* Strap kernel emulator for full MIPS IV emulation */
#ifdef __mips
#undef __mips
#endif
#define __mips 4
/* Function which emulates a floating point instruction. */ /* Function which emulates a floating point instruction. */
static int fpu_emu(struct pt_regs *, struct mips_fpu_struct *, static int fpu_emu(struct pt_regs *, struct mips_fpu_struct *,
mips_instruction); mips_instruction);
#if __mips >= 4 && __mips != 32
static int fpux_emu(struct pt_regs *, static int fpux_emu(struct pt_regs *,
struct mips_fpu_struct *, mips_instruction, void *__user *); struct mips_fpu_struct *, mips_instruction, void *__user *);
#endif
/* Control registers */ /* Control registers */
...@@ -95,7 +87,6 @@ static const unsigned char mips_rm[4] = { ...@@ -95,7 +87,6 @@ static const unsigned char mips_rm[4] = {
[IEEE754_RU] = FPU_CSR_RU, [IEEE754_RU] = FPU_CSR_RU,
}; };
#if __mips >= 4
/* convert condition code register number to csr bit */ /* convert condition code register number to csr bit */
static const unsigned int fpucondbit[8] = { static const unsigned int fpucondbit[8] = {
FPU_CSR_COND0, FPU_CSR_COND0,
...@@ -107,7 +98,6 @@ static const unsigned int fpucondbit[8] = { ...@@ -107,7 +98,6 @@ static const unsigned int fpucondbit[8] = {
FPU_CSR_COND6, FPU_CSR_COND6,
FPU_CSR_COND7 FPU_CSR_COND7
}; };
#endif
/* (microMIPS) Convert 16-bit register encoding to 32-bit register encoding. */ /* (microMIPS) Convert 16-bit register encoding to 32-bit register encoding. */
static const unsigned int reg16to32map[8] = {16, 17, 2, 3, 4, 5, 6, 7}; static const unsigned int reg16to32map[8] = {16, 17, 2, 3, 4, 5, 6, 7};
...@@ -860,13 +850,13 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, ...@@ -860,13 +850,13 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
*/ */
static inline int cop1_64bit(struct pt_regs *xcp) static inline int cop1_64bit(struct pt_regs *xcp)
{ {
#if defined(CONFIG_64BIT) && !defined(CONFIG_MIPS32_O32) if (config_enabled(CONFIG_64BIT) && !config_enabled(CONFIG_MIPS32_O32))
return 1; return 1;
#elif defined(CONFIG_32BIT) && !defined(CONFIG_MIPS_O32_FP64_SUPPORT) else if (config_enabled(CONFIG_32BIT) &&
!config_enabled(CONFIG_MIPS_O32_FP64_SUPPORT))
return 0; return 0;
#else
return !test_thread_flag(TIF_32BIT_FPREGS); return !test_thread_flag(TIF_32BIT_FPREGS);
#endif
} }
#define SIFROMREG(si, x) \ #define SIFROMREG(si, x) \
...@@ -1070,8 +1060,10 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx, ...@@ -1070,8 +1060,10 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
case cop1_op: case cop1_op:
switch (MIPSInst_RS(ir)) { switch (MIPSInst_RS(ir)) {
#if defined(__mips64)
case dmfc_op: case dmfc_op:
if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
return SIGILL;
/* copregister fs -> gpr[rt] */ /* copregister fs -> gpr[rt] */
if (MIPSInst_RT(ir) != 0) { if (MIPSInst_RT(ir) != 0) {
DIFROMREG(xcp->regs[MIPSInst_RT(ir)], DIFROMREG(xcp->regs[MIPSInst_RT(ir)],
...@@ -1080,10 +1072,12 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx, ...@@ -1080,10 +1072,12 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
break; break;
case dmtc_op: case dmtc_op:
if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
return SIGILL;
/* copregister fs <- rt */ /* copregister fs <- rt */
DITOREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir)); DITOREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir));
break; break;
#endif
case mfhc_op: case mfhc_op:
if (!cpu_has_mips_r2) if (!cpu_has_mips_r2)
...@@ -1173,16 +1167,18 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx, ...@@ -1173,16 +1167,18 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
} }
case bc_op:{ case bc_op:{
unsigned int cbit;
int likely = 0; int likely = 0;
if (delay_slot(xcp)) if (delay_slot(xcp))
return SIGILL; return SIGILL;
#if __mips >= 4 if (cpu_has_mips_4_5_r)
cond = ctx->fcr31 & fpucondbit[MIPSInst_RT(ir) >> 2]; cbit = fpucondbit[MIPSInst_RT(ir) >> 2];
#else else
cond = ctx->fcr31 & FPU_CSR_COND; cbit = FPU_CSR_COND;
#endif cond = ctx->fcr31 & cbit;
switch (MIPSInst_RT(ir) & 3) { switch (MIPSInst_RT(ir) & 3) {
case bcfl_op: case bcfl_op:
likely = 1; likely = 1;
...@@ -1235,23 +1231,32 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx, ...@@ -1235,23 +1231,32 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
switch (MIPSInst_OPCODE(ir)) { switch (MIPSInst_OPCODE(ir)) {
case lwc1_op: case lwc1_op:
goto emul;
case swc1_op: case swc1_op:
#if (__mips >= 2 || defined(__mips64)) goto emul;
case ldc1_op: case ldc1_op:
case sdc1_op: case sdc1_op:
#endif if (cpu_has_mips_2_3_4_5 ||
cpu_has_mips64)
goto emul;
return SIGILL;
goto emul;
case cop1_op: case cop1_op:
#if __mips >= 4 && __mips != 32 goto emul;
case cop1x_op: case cop1x_op:
#endif if (cpu_has_mips_4_5 || cpu_has_mips64)
/* its one of ours */ /* its one of ours */
goto emul; goto emul;
#if __mips >= 4
return SIGILL;
case spec_op: case spec_op:
if (!cpu_has_mips_4_5_r)
return SIGILL;
if (MIPSInst_FUNC(ir) == movc_op) if (MIPSInst_FUNC(ir) == movc_op)
goto emul; goto emul;
break; break;
#endif
} }
/* /*
...@@ -1291,17 +1296,22 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx, ...@@ -1291,17 +1296,22 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
} }
break; break;
#if __mips >= 4 && __mips != 32
case cop1x_op:{ case cop1x_op:{
int sig = fpux_emu(xcp, ctx, ir, fault_addr); int sig;
if (!cpu_has_mips_4_5 && !cpu_has_mips64)
return SIGILL;
sig = fpux_emu(xcp, ctx, ir, fault_addr);
if (sig) if (sig)
return sig; return sig;
break; break;
} }
#endif
#if __mips >= 4
case spec_op: case spec_op:
if (!cpu_has_mips_4_5_r)
return SIGILL;
if (MIPSInst_FUNC(ir) != movc_op) if (MIPSInst_FUNC(ir) != movc_op)
return SIGILL; return SIGILL;
cond = fpucondbit[MIPSInst_RT(ir) >> 2]; cond = fpucondbit[MIPSInst_RT(ir) >> 2];
...@@ -1309,8 +1319,6 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx, ...@@ -1309,8 +1319,6 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
xcp->regs[MIPSInst_RD(ir)] = xcp->regs[MIPSInst_RD(ir)] =
xcp->regs[MIPSInst_RS(ir)]; xcp->regs[MIPSInst_RS(ir)];
break; break;
#endif
default: default:
sigill: sigill:
return SIGILL; return SIGILL;
...@@ -1339,8 +1347,6 @@ static const unsigned char cmptab[8] = { ...@@ -1339,8 +1347,6 @@ static const unsigned char cmptab[8] = {
}; };
#if __mips >= 4 && __mips != 32
/* /*
* Additional MIPS4 instructions * Additional MIPS4 instructions
*/ */
...@@ -1571,7 +1577,6 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, ...@@ -1571,7 +1577,6 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
return 0; return 0;
} }
#endif
...@@ -1588,9 +1593,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, ...@@ -1588,9 +1593,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
union ieee754dp d; union ieee754dp d;
union ieee754sp s; union ieee754sp s;
int w; int w;
#ifdef __mips64
s64 l; s64 l;
#endif
} rv; /* resulting value */ } rv; /* resulting value */
MIPS_FPU_EMU_INC_STATS(cp1ops); MIPS_FPU_EMU_INC_STATS(cp1ops);
...@@ -1617,21 +1620,34 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, ...@@ -1617,21 +1620,34 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
goto scopbop; goto scopbop;
/* unary ops */ /* unary ops */
#if __mips >= 2 || defined(__mips64)
case fsqrt_op: case fsqrt_op:
if (!cpu_has_mips_4_5_r)
return SIGILL;
handler.u = ieee754sp_sqrt; handler.u = ieee754sp_sqrt;
goto scopuop; goto scopuop;
#endif /*
#if __mips >= 4 && __mips != 32 * Note that on some MIPS IV implementations such as the
* R5000 and R8000 the FSQRT and FRECIP instructions do not
* achieve full IEEE-754 accuracy - however this emulator does.
*/
case frsqrt_op: case frsqrt_op:
if (!cpu_has_mips_4_5_r2)
return SIGILL;
handler.u = fpemu_sp_rsqrt; handler.u = fpemu_sp_rsqrt;
goto scopuop; goto scopuop;
case frecip_op: case frecip_op:
if (!cpu_has_mips_4_5_r2)
return SIGILL;
handler.u = fpemu_sp_recip; handler.u = fpemu_sp_recip;
goto scopuop; goto scopuop;
#endif
#if __mips >= 4
case fmovc_op: case fmovc_op:
if (!cpu_has_mips_4_5_r)
return SIGILL;
cond = fpucondbit[MIPSInst_FT(ir) >> 2]; cond = fpucondbit[MIPSInst_FT(ir) >> 2];
if (((ctx->fcr31 & cond) != 0) != if (((ctx->fcr31 & cond) != 0) !=
((MIPSInst_FT(ir) & 1) != 0)) ((MIPSInst_FT(ir) & 1) != 0))
...@@ -1639,16 +1655,21 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, ...@@ -1639,16 +1655,21 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
SPFROMREG(rv.s, MIPSInst_FS(ir)); SPFROMREG(rv.s, MIPSInst_FS(ir));
break; break;
case fmovz_op: case fmovz_op:
if (!cpu_has_mips_4_5_r)
return SIGILL;
if (xcp->regs[MIPSInst_FT(ir)] != 0) if (xcp->regs[MIPSInst_FT(ir)] != 0)
return 0; return 0;
SPFROMREG(rv.s, MIPSInst_FS(ir)); SPFROMREG(rv.s, MIPSInst_FS(ir));
break; break;
case fmovn_op: case fmovn_op:
if (!cpu_has_mips_4_5_r)
return SIGILL;
if (xcp->regs[MIPSInst_FT(ir)] == 0) if (xcp->regs[MIPSInst_FT(ir)] == 0)
return 0; return 0;
SPFROMREG(rv.s, MIPSInst_FS(ir)); SPFROMREG(rv.s, MIPSInst_FS(ir));
break; break;
#endif
case fabs_op: case fabs_op:
handler.u = ieee754sp_abs; handler.u = ieee754sp_abs;
goto scopuop; goto scopuop;
...@@ -1712,7 +1733,6 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, ...@@ -1712,7 +1733,6 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
goto copcsr; goto copcsr;
} }
#if __mips >= 2 || defined(__mips64)
case fround_op: case fround_op:
case ftrunc_op: case ftrunc_op:
case fceil_op: case fceil_op:
...@@ -1720,6 +1740,9 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, ...@@ -1720,6 +1740,9 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
unsigned int oldrm = ieee754_csr.rm; unsigned int oldrm = ieee754_csr.rm;
union ieee754sp fs; union ieee754sp fs;
if (!cpu_has_mips_2_3_4_5 && !cpu_has_mips64)
return SIGILL;
SPFROMREG(fs, MIPSInst_FS(ir)); SPFROMREG(fs, MIPSInst_FS(ir));
ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))]; ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))];
rv.w = ieee754sp_tint(fs); rv.w = ieee754sp_tint(fs);
...@@ -1727,12 +1750,13 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, ...@@ -1727,12 +1750,13 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
rfmt = w_fmt; rfmt = w_fmt;
goto copcsr; goto copcsr;
} }
#endif /* __mips >= 2 */
#if defined(__mips64)
case fcvtl_op:{ case fcvtl_op:{
union ieee754sp fs; union ieee754sp fs;
if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
return SIGILL;
SPFROMREG(fs, MIPSInst_FS(ir)); SPFROMREG(fs, MIPSInst_FS(ir));
rv.l = ieee754sp_tlong(fs); rv.l = ieee754sp_tlong(fs);
rfmt = l_fmt; rfmt = l_fmt;
...@@ -1746,6 +1770,9 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, ...@@ -1746,6 +1770,9 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
unsigned int oldrm = ieee754_csr.rm; unsigned int oldrm = ieee754_csr.rm;
union ieee754sp fs; union ieee754sp fs;
if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
return SIGILL;
SPFROMREG(fs, MIPSInst_FS(ir)); SPFROMREG(fs, MIPSInst_FS(ir));
ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))]; ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))];
rv.l = ieee754sp_tlong(fs); rv.l = ieee754sp_tlong(fs);
...@@ -1753,7 +1780,6 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, ...@@ -1753,7 +1780,6 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
rfmt = l_fmt; rfmt = l_fmt;
goto copcsr; goto copcsr;
} }
#endif /* defined(__mips64) */
default: default:
if (MIPSInst_FUNC(ir) >= fcmp_op) { if (MIPSInst_FUNC(ir) >= fcmp_op) {
...@@ -1802,21 +1828,33 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, ...@@ -1802,21 +1828,33 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
goto dcopbop; goto dcopbop;
/* unary ops */ /* unary ops */
#if __mips >= 2 || defined(__mips64)
case fsqrt_op: case fsqrt_op:
if (!cpu_has_mips_2_3_4_5_r)
return SIGILL;
handler.u = ieee754dp_sqrt; handler.u = ieee754dp_sqrt;
goto dcopuop; goto dcopuop;
#endif /*
#if __mips >= 4 && __mips != 32 * Note that on some MIPS IV implementations such as the
* R5000 and R8000 the FSQRT and FRECIP instructions do not
* achieve full IEEE-754 accuracy - however this emulator does.
*/
case frsqrt_op: case frsqrt_op:
if (!cpu_has_mips_4_5_r2)
return SIGILL;
handler.u = fpemu_dp_rsqrt; handler.u = fpemu_dp_rsqrt;
goto dcopuop; goto dcopuop;
case frecip_op: case frecip_op:
if (!cpu_has_mips_4_5_r2)
return SIGILL;
handler.u = fpemu_dp_recip; handler.u = fpemu_dp_recip;
goto dcopuop; goto dcopuop;
#endif
#if __mips >= 4
case fmovc_op: case fmovc_op:
if (!cpu_has_mips_4_5_r)
return SIGILL;
cond = fpucondbit[MIPSInst_FT(ir) >> 2]; cond = fpucondbit[MIPSInst_FT(ir) >> 2];
if (((ctx->fcr31 & cond) != 0) != if (((ctx->fcr31 & cond) != 0) !=
((MIPSInst_FT(ir) & 1) != 0)) ((MIPSInst_FT(ir) & 1) != 0))
...@@ -1824,16 +1862,21 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, ...@@ -1824,16 +1862,21 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
DPFROMREG(rv.d, MIPSInst_FS(ir)); DPFROMREG(rv.d, MIPSInst_FS(ir));
break; break;
case fmovz_op: case fmovz_op:
if (!cpu_has_mips_4_5_r)
return SIGILL;
if (xcp->regs[MIPSInst_FT(ir)] != 0) if (xcp->regs[MIPSInst_FT(ir)] != 0)
return 0; return 0;
DPFROMREG(rv.d, MIPSInst_FS(ir)); DPFROMREG(rv.d, MIPSInst_FS(ir));
break; break;
case fmovn_op: case fmovn_op:
if (!cpu_has_mips_4_5_r)
return SIGILL;
if (xcp->regs[MIPSInst_FT(ir)] == 0) if (xcp->regs[MIPSInst_FT(ir)] == 0)
return 0; return 0;
DPFROMREG(rv.d, MIPSInst_FS(ir)); DPFROMREG(rv.d, MIPSInst_FS(ir));
break; break;
#endif
case fabs_op: case fabs_op:
handler.u = ieee754dp_abs; handler.u = ieee754dp_abs;
goto dcopuop; goto dcopuop;
...@@ -1886,7 +1929,6 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, ...@@ -1886,7 +1929,6 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
goto copcsr; goto copcsr;
} }
#if __mips >= 2 || defined(__mips64)
case fround_op: case fround_op:
case ftrunc_op: case ftrunc_op:
case fceil_op: case fceil_op:
...@@ -1894,6 +1936,9 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, ...@@ -1894,6 +1936,9 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
unsigned int oldrm = ieee754_csr.rm; unsigned int oldrm = ieee754_csr.rm;
union ieee754dp fs; union ieee754dp fs;
if (!cpu_has_mips_2_3_4_5_r)
return SIGILL;
DPFROMREG(fs, MIPSInst_FS(ir)); DPFROMREG(fs, MIPSInst_FS(ir));
ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))]; ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))];
rv.w = ieee754dp_tint(fs); rv.w = ieee754dp_tint(fs);
...@@ -1901,12 +1946,13 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, ...@@ -1901,12 +1946,13 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
rfmt = w_fmt; rfmt = w_fmt;
goto copcsr; goto copcsr;
} }
#endif
#if defined(__mips64)
case fcvtl_op:{ case fcvtl_op:{
union ieee754dp fs; union ieee754dp fs;
if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
return SIGILL;
DPFROMREG(fs, MIPSInst_FS(ir)); DPFROMREG(fs, MIPSInst_FS(ir));
rv.l = ieee754dp_tlong(fs); rv.l = ieee754dp_tlong(fs);
rfmt = l_fmt; rfmt = l_fmt;
...@@ -1920,6 +1966,9 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, ...@@ -1920,6 +1966,9 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
unsigned int oldrm = ieee754_csr.rm; unsigned int oldrm = ieee754_csr.rm;
union ieee754dp fs; union ieee754dp fs;
if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
return SIGILL;
DPFROMREG(fs, MIPSInst_FS(ir)); DPFROMREG(fs, MIPSInst_FS(ir));
ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))]; ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))];
rv.l = ieee754dp_tlong(fs); rv.l = ieee754dp_tlong(fs);
...@@ -1927,7 +1976,6 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, ...@@ -1927,7 +1976,6 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
rfmt = l_fmt; rfmt = l_fmt;
goto copcsr; goto copcsr;
} }
#endif /* __mips >= 3 */
default: default:
if (MIPSInst_FUNC(ir) >= fcmp_op) { if (MIPSInst_FUNC(ir) >= fcmp_op) {
...@@ -1978,9 +2026,12 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, ...@@ -1978,9 +2026,12 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
break; break;
} }
#if defined(__mips64)
case l_fmt:{ case l_fmt:{
u64 bits; u64 bits;
if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
return SIGILL;
DIFROMREG(bits, MIPSInst_FS(ir)); DIFROMREG(bits, MIPSInst_FS(ir));
switch (MIPSInst_FUNC(ir)) { switch (MIPSInst_FUNC(ir)) {
...@@ -1999,7 +2050,6 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, ...@@ -1999,7 +2050,6 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
} }
break; break;
} }
#endif
default: default:
return SIGILL; return SIGILL;
...@@ -2022,18 +2072,19 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, ...@@ -2022,18 +2072,19 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
* Now we can safely write the result back to the register file. * Now we can safely write the result back to the register file.
*/ */
switch (rfmt) { switch (rfmt) {
case -1:{ unsigned int cbit;
#if __mips >= 4 case -1:
cond = fpucondbit[MIPSInst_FD(ir) >> 2];
#else if (cpu_has_mips_4_5_r)
cond = FPU_CSR_COND; cbit = fpucondbit[MIPSInst_RT(ir) >> 2];
#endif else
cbit = FPU_CSR_COND;
if (rv.w) if (rv.w)
ctx->fcr31 |= cond; ctx->fcr31 |= cbit;
else else
ctx->fcr31 &= ~cond; ctx->fcr31 &= ~cbit;
break; break;
}
case d_fmt: case d_fmt:
DPTOREG(rv.d, MIPSInst_FD(ir)); DPTOREG(rv.d, MIPSInst_FD(ir));
break; break;
...@@ -2043,11 +2094,12 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, ...@@ -2043,11 +2094,12 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
case w_fmt: case w_fmt:
SITOREG(rv.w, MIPSInst_FD(ir)); SITOREG(rv.w, MIPSInst_FD(ir));
break; break;
#if defined(__mips64)
case l_fmt: case l_fmt:
if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
return SIGILL;
DITOREG(rv.l, MIPSInst_FD(ir)); DITOREG(rv.l, MIPSInst_FD(ir));
break; break;
#endif
default: default:
return SIGILL; return SIGILL;
} }
......
...@@ -45,15 +45,14 @@ ...@@ -45,15 +45,14 @@
/* special constants /* special constants
*/ */
#if (defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN) || defined(__MIPSEL__)
#define SPSTR(s, b, m) {m, b, s}
#define DPSTR(s, b, mh, ml) {ml, mh, b, s}
#endif
#ifdef __MIPSEB__ #ifdef __MIPSEB__
#define SPSTR(s, b, m) {s, b, m} #define SPSTR(s, b, m) {s, b, m}
#define DPSTR(s, b, mh, ml) {s, b, mh, ml} #define DPSTR(s, b, mh, ml) {s, b, mh, ml}
#elif defined(__MIPSEL__)
#define SPSTR(s, b, m) {m, b, s}
#define DPSTR(s, b, mh, ml) {ml, mh, b, s}
#else /* !defined (__MIPSEB__) && !defined (__MIPSEL__) */
#error "MIPS but neither __MIPSEB__ nor __MIPSEL__?"
#endif #endif
const struct ieee754dp_const __ieee754dp_spcvals[] = { const struct ieee754dp_const __ieee754dp_spcvals[] = {
......
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