On Fri, 11 Jun 2004 cgd@xxxxxxxxxxxx wrote:How about the attached (lightly tested) patch?
Unfortunately, at this point, Linux should probably accept the
divide-by-zero code in both locations.
I think that's not a big trouble for Linux -- the path is rare and not critical for performance.
David Daney.
*** ../linux-avtrex/linux/arch/mips/kernel/traps.c 2004-02-26 11:14:09.000000000 -0800 --- arch/mips/kernel/traps.c 2004-06-11 13:43:00.000000000 -0700 *************** *** 597,615 **** * There is the ancient bug in the MIPS assemblers that the break * code starts left to bit 16 instead to bit 6 in the opcode. * Gas is bug-compatible ... ! */ ! bcode = ((opcode >> 16) & ((1 << 20) - 1)); ! ! /* * (A short test says that IRIX 5.3 sends SIGTRAP for all break * insns, even for break codes that indicate arithmetic failures. * Weird ...) * But should we continue the brokenness??? --macro */ switch (bcode) { ! case 6: ! case 7: ! if (bcode == 7) info.si_code = FPE_INTDIV; else info.si_code = FPE_INTOVF; --- 597,621 ---- * There is the ancient bug in the MIPS assemblers that the break * code starts left to bit 16 instead to bit 6 in the opcode. * Gas is bug-compatible ... ! * * (A short test says that IRIX 5.3 sends SIGTRAP for all break * insns, even for break codes that indicate arithmetic failures. * Weird ...) * But should we continue the brokenness??? --macro + * + * It seems some assemblers (binutils-2.15 for example) assemble + * break correctly. So we check for the break code in either + * position. + * */ + + bcode = ((opcode >> 6) & ((1 << 20) - 1)); switch (bcode) { ! case 0x0006: ! case 0x0007: ! case 0x1800: /* 6 << 10 */ ! case 0x1c00: /* 7 << 10 */ ! if (bcode == 0x7 || bcode == 0x1c00) info.si_code = FPE_INTDIV; else info.si_code = FPE_INTOVF; *************** *** 633,639 **** /* Immediate versions don't provide a code. */ if (!(opcode & OPCODE)) ! tcode = ((opcode >> 6) & ((1 << 20) - 1)); /* * (A short test says that IRIX 5.3 sends SIGTRAP for all trap --- 639,645 ---- /* Immediate versions don't provide a code. */ if (!(opcode & OPCODE)) ! tcode = ((opcode >> 6) & ((1 << 10) - 1)); /* * (A short test says that IRIX 5.3 sends SIGTRAP for all trap