MIPS: Avoid DIVU in `__div64_32' is result would be zero
authorMaciej W. Rozycki <macro@orcam.me.uk>
Tue, 20 Apr 2021 02:50:48 +0000 (04:50 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 22 May 2021 08:40:33 +0000 (10:40 +0200)
commit c1d337d45ec0a802299688e17d568c4e3a585895 upstream.

We already check the high part of the divident against zero to avoid the
costly DIVU instruction in that case, needed to reduce the high part of
the divident, so we may well check against the divisor instead and set
the high part of the quotient to zero right away.  We need to treat the
high part the divident in that case though as the remainder that would
be calculated by the DIVU instruction we avoided.

This has passed correctness verification with test_div64 and reduced the
module's average execution time down to 1.0445s and 0.2619s from 1.0668s
and 0.2629s respectively for an R3400 CPU @40MHz and a 5Kc CPU @160MHz.

Signed-off-by: Maciej W. Rozycki <macro@orcam.me.uk>
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/mips/include/asm/div64.h

index b252300e299dd1d54eaf090aba49c24e09fd6c60..a882a7bdf63e60bf798bfbd8bbd2f1bb39ffdabc 100644 (file)
                                                                        \
        __high = __div >> 32;                                           \
        __low = __div;                                                  \
-       __upper = __high;                                               \
                                                                        \
-       if (__high) {                                                   \
+       if (__high < __radix) {                                         \
+               __upper = __high;                                       \
+               __high = 0;                                             \
+       } else {                                                        \
                __asm__("divu   $0, %z1, %z2"                           \
                : "=x" (__modquot)                                      \
                : "Jr" (__high), "Jr" (__radix));                       \