Sometimes I want to know what kind of (and how many times) FP exceptions occurred in run time. Here is a patch to provide us these informations via /proc/cpuinfo. Any comments are welcome. (This patch is not tested on SMP) diff -ur linux-sgi-cvs/arch/mips/config.in linux.new/arch/mips/config.in --- linux-sgi-cvs/arch/mips/config.in Wed Nov 21 10:31:56 2001 +++ linux.new/arch/mips/config.in Wed Nov 21 15:45:44 2001 @@ -359,6 +359,7 @@ else bool 'Generate little endian code' CONFIG_CPU_LITTLE_ENDIAN fi +bool 'Support for FPU Exception statistics' CONFIG_MIPS_FPE_STATS if [ "$CONFIG_PROC_FS" = "y" ]; then define_bool CONFIG_KCORE_ELF y diff -ur linux-sgi-cvs/arch/mips/kernel/proc.c linux.new/arch/mips/kernel/proc.c --- linux-sgi-cvs/arch/mips/kernel/proc.c Mon Oct 22 10:29:56 2001 +++ linux.new/arch/mips/kernel/proc.c Wed Nov 21 15:43:24 2001 @@ -19,6 +19,10 @@ #ifndef CONFIG_CPU_HAS_LLSC unsigned long ll_ops, sc_ops; #endif +#ifdef CONFIG_MIPS_FPE_STATS +unsigned int fpu_exceptions[6]; +static char fpe_types[6] = {'I', 'U', 'O', 'Z', 'V', 'E'}; +#endif /* * BUFFER is PAGE_SIZE bytes long. @@ -61,6 +65,9 @@ mach_nec_vr41xx_names}; unsigned int version = read_32bit_cp0_register(CP0_PRID); int len; +#ifdef CONFIG_MIPS_FPE_STATS + int i; +#endif len = sprintf(buffer, "cpu\t\t\t: MIPS\n"); len += sprintf(buffer + len, "cpu model\t\t: %s V%d.%d\n", @@ -101,6 +108,14 @@ ll_ops); len += sprintf(buffer + len, "sc emulations\t\t: %lu\n", sc_ops); +#endif +#ifdef CONFIG_MIPS_FPE_STATS + len += sprintf(buffer + len, "fpu exceptions\t\t:"); + for (i = 0; i < sizeof(fpu_exceptions) / sizeof(fpu_exceptions[0]); i++) { + len += sprintf(buffer + len, " %u(%c)", + fpu_exceptions[i], fpe_types[i]); + } + len += sprintf(buffer + len, "\n"); #endif return len; } diff -ur linux-sgi-cvs/arch/mips/kernel/traps.c linux.new/arch/mips/kernel/traps.c --- linux-sgi-cvs/arch/mips/kernel/traps.c Wed Nov 21 10:31:57 2001 +++ linux.new/arch/mips/kernel/traps.c Wed Nov 21 15:46:15 2001 @@ -461,6 +461,18 @@ */ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) { +#ifdef CONFIG_MIPS_FPE_STATS + extern unsigned int fpu_exceptions[]; + unsigned char fpe; + int i; + fpe = ((fcr31 & FPU_CSR_ALL_X) / FPU_CSR_INE_X) & + ((fcr31 | ~FPU_CSR_ALL_E) / FPU_CSR_INE_E); + for (i = 0; i < 6; i++) { + if (fpe & (1 << i)) + fpu_exceptions[i]++; + } +#endif + if (fcr31 & FPU_CSR_UNI_X) { extern void save_fp(struct task_struct *); extern void restore_fp(struct task_struct *); --- Atsushi Nemoto