MIPS: math-emu: Add IEEE754 exception statistics to debugfs
authorDeng-Cheng Zhu <dengcheng.zhu@imgtec.com>
Thu, 29 May 2014 19:26:45 +0000 (12:26 -0700)
committerRalf Baechle <ralf@linux-mips.org>
Fri, 30 May 2014 09:55:23 +0000 (11:55 +0200)
Sometimes it's useful to let the user, while doing performance research,
know what in the IEEE754 exceptions has caused many times of FP emulation
when running a specific application. This patch adds 5 more files to
/sys/kernel/debug/mips/fpuemustats/, whose filenames begin with "ieee754".
These stats are in addition to the existing cp1ops, cp1xops, errors, loads
and stores, which may not be useful in understanding the reasons of ieee754
exceptions.

[ralf@linux-mips.org: Fixed reject due to other changes to the kernel
FP assist software.]

Signed-off-by: Deng-Cheng Zhu <dengcheng.zhu@imgtec.com>
Cc: linux-mips@linux-mips.org
Cc: Steven.Hill@imgtec.com
Cc: james.hogan@imgtec.com
Patchwork: http://patchwork.linux-mips.org/patch/7044/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
arch/mips/include/asm/fpu_emulator.h
arch/mips/math-emu/cp1emu.c
arch/mips/math-emu/me-debugfs.c

index f761719eab653df112e0a58954ece04e459c511b..0195745b4b1b47384ef324e52ce14577d4137677 100644 (file)
@@ -39,6 +39,11 @@ struct mips_fpu_emulator_stats {
        local_t cp1ops;
        local_t cp1xops;
        local_t errors;
+       local_t ieee754_inexact;
+       local_t ieee754_underflow;
+       local_t ieee754_overflow;
+       local_t ieee754_zerodiv;
+       local_t ieee754_invalidop;
 };
 
 DECLARE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats);
index 08e6a74fbc95f9996fc05ea8b24890951778aa91..cdfed285c2449189d3c8043189ef8c216e1f32a6 100644 (file)
@@ -1234,14 +1234,22 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
                        SPTOREG(fd, MIPSInst_FD(ir));
 
                      copcsr:
-                       if (ieee754_cxtest(IEEE754_INEXACT))
+                       if (ieee754_cxtest(IEEE754_INEXACT)) {
+                               MIPS_FPU_EMU_INC_STATS(ieee754_inexact);
                                rcsr |= FPU_CSR_INE_X | FPU_CSR_INE_S;
-                       if (ieee754_cxtest(IEEE754_UNDERFLOW))
+                       }
+                       if (ieee754_cxtest(IEEE754_UNDERFLOW)) {
+                               MIPS_FPU_EMU_INC_STATS(ieee754_underflow);
                                rcsr |= FPU_CSR_UDF_X | FPU_CSR_UDF_S;
-                       if (ieee754_cxtest(IEEE754_OVERFLOW))
+                       }
+                       if (ieee754_cxtest(IEEE754_OVERFLOW)) {
+                               MIPS_FPU_EMU_INC_STATS(ieee754_overflow);
                                rcsr |= FPU_CSR_OVF_X | FPU_CSR_OVF_S;
-                       if (ieee754_cxtest(IEEE754_INVALID_OPERATION))
+                       }
+                       if (ieee754_cxtest(IEEE754_INVALID_OPERATION)) {
+                               MIPS_FPU_EMU_INC_STATS(ieee754_invalidop);
                                rcsr |= FPU_CSR_INV_X | FPU_CSR_INV_S;
+                       }
 
                        ctx->fcr31 = (ctx->fcr31 & ~FPU_CSR_ALL_X) | rcsr;
                        if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
@@ -1468,16 +1476,26 @@ scopuop:
                        rv.s = (*handler.u) (fs);
                        goto copcsr;
 copcsr:
-                       if (ieee754_cxtest(IEEE754_INEXACT))
+                       if (ieee754_cxtest(IEEE754_INEXACT)) {
+                               MIPS_FPU_EMU_INC_STATS(ieee754_inexact);
                                rcsr |= FPU_CSR_INE_X | FPU_CSR_INE_S;
-                       if (ieee754_cxtest(IEEE754_UNDERFLOW))
+                       }
+                       if (ieee754_cxtest(IEEE754_UNDERFLOW)) {
+                               MIPS_FPU_EMU_INC_STATS(ieee754_underflow);
                                rcsr |= FPU_CSR_UDF_X | FPU_CSR_UDF_S;
-                       if (ieee754_cxtest(IEEE754_OVERFLOW))
+                       }
+                       if (ieee754_cxtest(IEEE754_OVERFLOW)) {
+                               MIPS_FPU_EMU_INC_STATS(ieee754_overflow);
                                rcsr |= FPU_CSR_OVF_X | FPU_CSR_OVF_S;
-                       if (ieee754_cxtest(IEEE754_ZERO_DIVIDE))
+                       }
+                       if (ieee754_cxtest(IEEE754_ZERO_DIVIDE)) {
+                               MIPS_FPU_EMU_INC_STATS(ieee754_zerodiv);
                                rcsr |= FPU_CSR_DIV_X | FPU_CSR_DIV_S;
-                       if (ieee754_cxtest(IEEE754_INVALID_OPERATION))
+                       }
+                       if (ieee754_cxtest(IEEE754_INVALID_OPERATION)) {
+                               MIPS_FPU_EMU_INC_STATS(ieee754_invalidop);
                                rcsr |= FPU_CSR_INV_X | FPU_CSR_INV_S;
+                       }
                        break;
 
                        /* unary conv ops */
index 95ed9f9bd2b074a76ead940c6485508366435266..becdd63e14a9365da5718b6be247de303f21f78a 100644 (file)
@@ -56,6 +56,11 @@ do {                                                                 \
        FPU_STAT_CREATE(cp1ops);
        FPU_STAT_CREATE(cp1xops);
        FPU_STAT_CREATE(errors);
+       FPU_STAT_CREATE(ieee754_inexact);
+       FPU_STAT_CREATE(ieee754_underflow);
+       FPU_STAT_CREATE(ieee754_overflow);
+       FPU_STAT_CREATE(ieee754_zerodiv);
+       FPU_STAT_CREATE(ieee754_invalidop);
 
        return 0;
 }