Actually this got me thinking, since you're right in that integer division should require a manual trap. This took me into OpenBIOS's bundled version of libgcc and __udivmoddi4.c:
__uint128_t __udivmodti4(__uint128_t num, __uint128_t den, __uint128_t *rem_p) { __uint128_t quot = 0, qbit = 1;
if ( den == 0 ) { __divide_error(); return 0; /* If trap returns... */ }
[It seems you showed __udivmodti4 instead -- but the code is much the same].
That's not libgcc code: it is x86 Linux kernel code or klibc or something like that. Libgcc forces a single-precision divide by zero when the double- precision routine divides by zero, so there can be no problem there.
A quick grep of the source shows that __divide_error() is manually set to the unexpected exception trap handler in start.S:
_GLOBAL(__divide_error): trap_error: mflr r3 LOAD_REG_FUNC(r4, unexpected_excep) mtctr r4 bctr
Heh. So actually all we need to do is provide an empty function for __divide_error() and we magically get the behaviour we want. Revised patch to follow shortly.
Or not have a __divide_error at all, which makes it clearer the intent is to have the double precision divide have the same behaviour as single precision on whatever hardware it runs on. Your patch should work though :-)
Segher