|
1 | 1 | diff --git a/stdlib/public/runtime/Float16Support.cpp b/stdlib/public/runtime/Float16Support.cpp |
2 | | -index 817739d4cdf..b1896a4e364 100644 |
| 2 | +index 817739d4cdf..046327e491b 100644 |
3 | 3 | --- a/stdlib/public/runtime/Float16Support.cpp |
4 | 4 | +++ b/stdlib/public/runtime/Float16Support.cpp |
5 | | -@@ -29,7 +29,7 @@ |
| 5 | +@@ -15,6 +15,7 @@ |
| 6 | + // __gnu_h2f_ieee |
| 7 | + // __gnu_f2h_ieee |
| 8 | + // __truncdfhf2 |
| 9 | ++// __multi3 |
| 10 | + // |
| 11 | + // On Darwin platforms, these are provided by the host compiler-rt, but we |
| 12 | + // can't depend on that everywhere, so we have to provide them in the Swift |
| 13 | +@@ -27,9 +28,65 @@ |
| 14 | + // |
| 15 | + //===----------------------------------------------------------------------===// |
6 | 16 |
|
| 17 | ++ #include "../SwiftShims/Visibility.h" |
| 18 | ++ #include <endian.h> |
| 19 | ++ #include <stdint.h> |
| 20 | ++ #include <climits> |
| 21 | ++ |
| 22 | ++ // PowerPC 32-bit Glibc does not provide __multi3 |
| 23 | ++ #if defined(__powerpc__) |
| 24 | ++ |
| 25 | ++ typedef int int128_t __attribute__((mode(TI))); |
| 26 | ++ typedef unsigned int uint128_t __attribute__((mode(TI))); |
| 27 | ++ |
| 28 | ++ typedef union { |
| 29 | ++ int128_t all; |
| 30 | ++ struct { |
| 31 | ++ #if __BYTE_ORDER == __LITTLE_ENDIAN |
| 32 | ++ uint64_t low; |
| 33 | ++ int64_t high; |
| 34 | ++ #else |
| 35 | ++ int64_t high; |
| 36 | ++ uint64_t low; |
| 37 | ++ #endif |
| 38 | ++ } s; |
| 39 | ++ } twords; |
| 40 | ++ |
| 41 | ++ SWIFT_RUNTIME_EXPORT int64_t __mulddi3(uint64_t a, uint64_t b) { |
| 42 | ++ twords r; |
| 43 | ++ const int bits_in_dword_2 = (int)(sizeof(int64_t) * CHAR_BIT) / 2; |
| 44 | ++ const uint64_t lower_mask = (uint64_t)~0 >> bits_in_dword_2; |
| 45 | ++ r.s.low = (a & lower_mask) * (b & lower_mask); |
| 46 | ++ uint64_t t = r.s.low >> bits_in_dword_2; |
| 47 | ++ r.s.low &= lower_mask; |
| 48 | ++ t += (a >> bits_in_dword_2) * (b & lower_mask); |
| 49 | ++ r.s.low += (t & lower_mask) << bits_in_dword_2; |
| 50 | ++ r.s.high = t >> bits_in_dword_2; |
| 51 | ++ t = r.s.low >> bits_in_dword_2; |
| 52 | ++ r.s.low &= lower_mask; |
| 53 | ++ t += (b >> bits_in_dword_2) * (a & lower_mask); |
| 54 | ++ r.s.low += (t & lower_mask) << bits_in_dword_2; |
| 55 | ++ r.s.high += t >> bits_in_dword_2; |
| 56 | ++ r.s.high += (a >> bits_in_dword_2) * (b >> bits_in_dword_2); |
| 57 | ++ return r.all; |
| 58 | ++ } |
| 59 | ++ |
| 60 | ++ SWIFT_RUNTIME_EXPORT int64_t __multi3(int128_t a, int128_t b) { |
| 61 | ++ twords x; |
| 62 | ++ x.all = a; |
| 63 | ++ twords y; |
| 64 | ++ y.all = b; |
| 65 | ++ twords r; |
| 66 | ++ r.all = __mulddi3(x.s.low, y.s.low); |
| 67 | ++ r.s.high += x.s.high * y.s.low + x.s.low * y.s.high; |
| 68 | ++ return r.all; |
| 69 | ++ } |
| 70 | ++ |
| 71 | ++ #endif |
| 72 | ++ |
7 | 73 | // Android NDK <r21 do not provide `__aeabi_d2h` in the compiler runtime, |
8 | 74 | // provide shims in that case. |
9 | 75 | -#if (defined(__ANDROID__) && defined(__ARM_ARCH_7A__) && defined(__ARM_EABI__)) || \ |
10 | | -+#if ((defined(__ANDROID__) || defined(__linux__)) && (defined(__arm__) || (defined(__riscv) && __riscv_xlen == 64) || (defined(__powerpc64__) && defined(__LITTLE_ENDIAN__)))) || \ |
| 76 | ++#if ((defined(__ANDROID__) || defined(__linux__)) && (defined(__arm__) || (defined(__riscv) && __riscv_xlen == 64) || defined(__powerpc__) || (defined(__powerpc64__) && defined(__LITTLE_ENDIAN__)))) || \ |
11 | 77 | ((defined(__i386__) || defined(__i686__) || defined(__x86_64__)) && !defined(__APPLE__)) |
12 | 78 |
|
13 | 79 | #include "../SwiftShims/Visibility.h" |
0 commit comments