diff options
Diffstat (limited to 'arch/mips/math-emu/cp1emu.c')
-rw-r--r-- | arch/mips/math-emu/cp1emu.c | 26 |
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. */ |
82 | static const unsigned char ieee_rm[4] = { | 85 | static 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; |