aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/math-emu/cp1emu.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/math-emu/cp1emu.c')
-rw-r--r--arch/mips/math-emu/cp1emu.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c
index 8f2f8e9d8b21..47842b7d26ae 100644
--- a/arch/mips/math-emu/cp1emu.c
+++ b/arch/mips/math-emu/cp1emu.c
@@ -78,6 +78,9 @@ DEFINE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats);
78#define FPCREG_RID 0 /* $0 = revision id */ 78#define FPCREG_RID 0 /* $0 = revision id */
79#define FPCREG_CSR 31 /* $31 = csr */ 79#define FPCREG_CSR 31 /* $31 = csr */
80 80
81/* Determine rounding mode from the RM bits of the FCSR */
82#define modeindex(v) ((v) & FPU_CSR_RM)
83
81/* Convert Mips rounding mode (0..3) to IEEE library modes. */ 84/* Convert Mips rounding mode (0..3) to IEEE library modes. */
82static const unsigned char ieee_rm[4] = { 85static const unsigned char ieee_rm[4] = {
83 [FPU_CSR_RN] = IEEE754_RN, 86 [FPU_CSR_RN] = IEEE754_RN,
@@ -351,7 +354,8 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
351 354
352 if (MIPSInst_RD(ir) == FPCREG_CSR) { 355 if (MIPSInst_RD(ir) == FPCREG_CSR) {
353 value = ctx->fcr31; 356 value = ctx->fcr31;
354 value = (value & ~0x3) | mips_rm[value & 0x3]; 357 value = (value & ~FPU_CSR_RM) |
358 mips_rm[modeindex(value)];
355#ifdef CSRTRACE 359#ifdef CSRTRACE
356 printk("%p gpr[%d]<-csr=%08x\n", 360 printk("%p gpr[%d]<-csr=%08x\n",
357 (void *) (xcp->cp0_epc), 361 (void *) (xcp->cp0_epc),
@@ -384,10 +388,14 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
384 (void *) (xcp->cp0_epc), 388 (void *) (xcp->cp0_epc),
385 MIPSInst_RT(ir), value); 389 MIPSInst_RT(ir), value);
386#endif 390#endif
387 value &= (FPU_CSR_FLUSH | FPU_CSR_ALL_E | FPU_CSR_ALL_S | 0x03); 391
388 ctx->fcr31 &= ~(FPU_CSR_FLUSH | FPU_CSR_ALL_E | FPU_CSR_ALL_S | 0x03); 392 /*
389 /* convert to ieee library modes */ 393 * Don't write reserved bits,
390 ctx->fcr31 |= (value & ~0x3) | ieee_rm[value & 0x3]; 394 * and convert to ieee library modes
395 */
396 ctx->fcr31 = (value &
397 ~(FPU_CSR_RSVD | FPU_CSR_RM)) |
398 ieee_rm[modeindex(value)];
391 } 399 }
392 if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) { 400 if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
393 return SIGFPE; 401 return SIGFPE;
@@ -900,7 +908,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
900 ieee754sp fs; 908 ieee754sp fs;
901 909
902 SPFROMREG(fs, MIPSInst_FS(ir)); 910 SPFROMREG(fs, MIPSInst_FS(ir));
903 ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3]; 911 ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))];
904 rv.w = ieee754sp_tint(fs); 912 rv.w = ieee754sp_tint(fs);
905 ieee754_csr.rm = oldrm; 913 ieee754_csr.rm = oldrm;
906 rfmt = w_fmt; 914 rfmt = w_fmt;
@@ -926,7 +934,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
926 ieee754sp fs; 934 ieee754sp fs;
927 935
928 SPFROMREG(fs, MIPSInst_FS(ir)); 936 SPFROMREG(fs, MIPSInst_FS(ir));
929 ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3]; 937 ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))];
930 rv.l = ieee754sp_tlong(fs); 938 rv.l = ieee754sp_tlong(fs);
931 ieee754_csr.rm = oldrm; 939 ieee754_csr.rm = oldrm;
932 rfmt = l_fmt; 940 rfmt = l_fmt;
@@ -1074,7 +1082,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1074 ieee754dp fs; 1082 ieee754dp fs;
1075 1083
1076 DPFROMREG(fs, MIPSInst_FS(ir)); 1084 DPFROMREG(fs, MIPSInst_FS(ir));
1077 ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3]; 1085 ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))];
1078 rv.w = ieee754dp_tint(fs); 1086 rv.w = ieee754dp_tint(fs);
1079 ieee754_csr.rm = oldrm; 1087 ieee754_csr.rm = oldrm;
1080 rfmt = w_fmt; 1088 rfmt = w_fmt;
@@ -1100,7 +1108,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1100 ieee754dp fs; 1108 ieee754dp fs;
1101 1109
1102 DPFROMREG(fs, MIPSInst_FS(ir)); 1110 DPFROMREG(fs, MIPSInst_FS(ir));
1103 ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3]; 1111 ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))];
1104 rv.l = ieee754dp_tlong(fs); 1112 rv.l = ieee754dp_tlong(fs);
1105 ieee754_csr.rm = oldrm; 1113 ieee754_csr.rm = oldrm;
1106 rfmt = l_fmt; 1114 rfmt = l_fmt;