>>>>> On Mon, 13 Aug 2001 10:34:46 -0700 (PDT), Wayne Gowcher <wgowcher@yahoo.com> said: wgowcher> a 23 % reduction in the Floating Point Index benchmark Current CVS kernel uses FPU emulator unconditionally. If one floating point intruction causes a 'Unimplemented' exception (denormalized result, etc.) following floating point instructions are also handle by FPU emulator (not only the instruction which raise the exception). I do not know this is really desired behavior, but here is a patch to change this. If Unimplemented exception had been occured during the benchmark, aplying this patch may result better performance. --- Atsushi Nemoto
diff -ur linux.sgi/arch/mips/kernel/traps.c linux/arch/mips/kernel/traps.c --- linux.sgi/arch/mips/kernel/traps.c Sun Aug 5 23:39:20 2001 +++ linux/arch/mips/kernel/traps.c Thu Aug 16 12:20:23 2001 @@ -60,7 +60,7 @@ extern asmlinkage void handle_mcheck(void); extern asmlinkage void handle_reserved(void); -extern int fpu_emulator_cop1Handler(struct pt_regs *); +extern int fpu_emulator_cop1Handler(struct pt_regs *, int); char watch_available = 0; @@ -306,7 +306,8 @@ save_fp(current); /* Run the emulator */ - sig = fpu_emulator_cop1Handler(regs); + /* Emulate only one insn if we have FPU. */ + sig = fpu_emulator_cop1Handler(regs, 1); /* * We can't allow the emulated instruction to leave the @@ -605,7 +606,7 @@ current->used_math = 1; } } - sig = fpu_emulator_cop1Handler(regs); + sig = fpu_emulator_cop1Handler(regs, 0); last_task_used_math = current; if (sig) force_sig(sig, current); diff -ur linux.sgi/arch/mips/math-emu/cp1emu.c linux/arch/mips/math-emu/cp1emu.c --- linux.sgi/arch/mips/math-emu/cp1emu.c Sun Aug 5 23:39:27 2001 +++ linux/arch/mips/math-emu/cp1emu.c Thu Aug 16 12:21:07 2001 @@ -1662,7 +1662,7 @@ * hit a non-fp instruction, or a backward branch. This cuts down dramatically * on the per instruction exception overhead. */ -int fpu_emulator_cop1Handler(struct pt_regs *xcp) +int fpu_emulator_cop1Handler(struct pt_regs *xcp, int maxcount) { struct mips_fpu_soft_struct *ctx = ¤t->thread.fpu.soft; unsigned long oldepc, prevepc; @@ -1682,6 +1682,8 @@ sig = cop1Emulate(xcp, ctx); else xcp->cp0_epc += 4; /* skip nops */ + if (maxcount && --maxcount <= 0) + break; } while (xcp->cp0_epc > prevepc && sig == 0); /* SIGILL indicates a non-fpu instruction */