Liu Yu <[EMAIL PROTECTED]> writes: > There are 2 bugs existing in __udiv_qrnnd_c: > > 1. remainder could not be counted correctly > __r1 and __r0 are not adding enough, so I use do..while to replace former if > > 2. the case of overflow of __m are not considered > so I add a couple of lines to handle it > > I found the bugs from Linux kernel, > for PowerPC math-emu use __udiv_qrnnd_c to emulate float div.
Is the kernel code testing UDIV_NEEDS_NORMALIZATION and implementing the normalization required before calling __udiv_qrnnd_c? > I don't know how to trigger __udiv_qrnnd_c in gcc. gcc will use __udiv_qrnnd_c in -lgcc for division and modulos of 64-bit values on processors which can't do that directly and for which there is no alternate implementation in longlong.h. > but if the argument of __udiv_qrnnd_c are like > 0x07fffff8 0x07fffff8 0x00210fff 0xc0000000 0x07fffff8, > the bug will be reproduced. Those arguments to __udiv_qrnnd_c are not valid. For correct operation, the most significant bit of the last argument is required to be 1. UDIV_NEEDS_NORMALIZATION signals this fact. In gcc the required normalization is implemented before calling __udiv_qrnnd_c, in __udivmoddi4 in libgcc2.c. This normalization approach is taken, rather than introducing while loops as you suggest, because the while loops can run for quite a long time on small numbers. Ian