^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* muldi3.c extracted from gcc-2.7.2.3/libgcc2.c and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) gcc-2.7.2.3/longlong.h which is: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) /* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) This file is part of GNU CC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) GNU CC is free software; you can redistribute it and/or modify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) it under the terms of the GNU General Public License as published by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) the Free Software Foundation; either version 2, or (at your option)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) any later version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) GNU CC is distributed in the hope that it will be useful,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) but WITHOUT ANY WARRANTY; without even the implied warranty of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) GNU General Public License for more details. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/compiler.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #ifdef CONFIG_CPU_HAS_NO_MULDIV64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define SI_TYPE_SIZE 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define __BITS4 (SI_TYPE_SIZE / 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define __ll_B (1L << (SI_TYPE_SIZE / 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define __ll_lowpart(t) ((USItype) (t) % __ll_B)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define __ll_highpart(t) ((USItype) (t) / __ll_B)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define umul_ppmm(w1, w0, u, v) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) USItype __x0, __x1, __x2, __x3; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) USItype __ul, __vl, __uh, __vh; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) __ul = __ll_lowpart (u); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) __uh = __ll_highpart (u); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) __vl = __ll_lowpart (v); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) __vh = __ll_highpart (v); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) __x0 = (USItype) __ul * __vl; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) __x1 = (USItype) __ul * __vh; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) __x2 = (USItype) __uh * __vl; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) __x3 = (USItype) __uh * __vh; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) __x1 += __ll_highpart (__x0);/* this can't give carry */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) __x1 += __x2; /* but this indeed can */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) if (__x1 < __x2) /* did we get it? */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) __x3 += __ll_B; /* yes, add it in the proper pos. */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) (w1) = __x3 + __ll_highpart (__x1); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define umul_ppmm(w1, w0, u, v) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) __asm__ ("mulu%.l %3,%1:%0" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) : "=d" ((USItype)(w0)), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) "=d" ((USItype)(w1)) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) : "%0" ((USItype)(u)), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) "dmi" ((USItype)(v)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define __umulsidi3(u, v) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) ({DIunion __w; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) umul_ppmm (__w.s.high, __w.s.low, u, v); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) __w.ll; })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) typedef int SItype __mode(SI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) typedef unsigned int USItype __mode(SI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) typedef int DItype __mode(DI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) typedef int word_type __mode(__word__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct DIstruct {SItype high, low;};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) typedef union
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) struct DIstruct s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) DItype ll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) } DIunion;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) DItype
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) __muldi3 (DItype u, DItype v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) DIunion w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) DIunion uu, vv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) uu.ll = u,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) vv.ll = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) w.ll = __umulsidi3 (uu.s.low, vv.s.low);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) + (USItype) uu.s.high * (USItype) vv.s.low);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) return w.ll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) EXPORT_SYMBOL(__muldi3);