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

Reply via email to