Skip to content

Commit dfa8a31

Browse files
authored
Merge pull request #15912 from compnerd/compiler-rt
stubs: split up compiler-rt routines
2 parents 0d7ebe0 + 0a1352e commit dfa8a31

File tree

3 files changed

+162
-123
lines changed

3 files changed

+162
-123
lines changed

stdlib/public/stubs/CMakeLists.txt

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ set(swift_stubs_sources
55
KeyPaths.cpp
66
LibcShims.cpp
77
Stubs.cpp
8+
MathStubs.cpp
89
)
910
set(swift_stubs_objc_sources
1011
Availability.mm
@@ -23,15 +24,21 @@ set(swift_stubs_c_compile_flags ${SWIFT_RUNTIME_CORE_CXX_FLAGS})
2324
list(APPEND swift_stubs_c_compile_flags -DswiftCore_EXPORTS)
2425
list(APPEND swift_stubs_c_compile_flags -I${SWIFT_SOURCE_DIR}/include)
2526

26-
add_swift_library(swiftStdlibStubs OBJECT_LIBRARY TARGET_LIBRARY
27-
${swift_stubs_sources}
28-
${swift_stubs_objc_sources}
29-
${swift_stubs_unicode_normalization_sources}
30-
C_COMPILE_FLAGS ${swift_stubs_c_compile_flags}
31-
LINK_FLAGS ${SWIFT_RUNTIME_CORE_LINK_FLAGS}
32-
INSTALL_IN_COMPONENT stdlib)
27+
add_swift_library(swiftStdlibStubs
28+
OBJECT_LIBRARY TARGET_LIBRARY
29+
${swift_stubs_sources}
30+
${swift_stubs_objc_sources}
31+
${swift_stubs_unicode_normalization_sources}
32+
C_COMPILE_FLAGS
33+
${swift_stubs_c_compile_flags}
34+
LINK_FLAGS
35+
${SWIFT_RUNTIME_CORE_LINK_FLAGS}
36+
INSTALL_IN_COMPONENT
37+
stdlib)
3338

3439
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
35-
set_property(SOURCE SwiftNativeNSXXXBaseARC.m APPEND_STRING PROPERTY COMPILE_FLAGS
36-
"-fobjc-arc")
40+
set_property(SOURCE
41+
SwiftNativeNSXXXBaseARC.m
42+
APPEND_STRING PROPERTY COMPILE_FLAGS
43+
"-fobjc-arc")
3744
endif()

stdlib/public/stubs/MathStubs.cpp

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
//===--- MathStubs.cpp - Swift Language Runtime Stubs ---------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// Math stubs for functions which should be defined in the core standard
14+
// library, but are difficult or impossible to write in Swift at the
15+
// moment.
16+
//
17+
//===----------------------------------------------------------------------===//
18+
19+
#include "../SwiftShims/Visibility.h"
20+
21+
#include <climits>
22+
#include <cstdlib>
23+
24+
#if __has_attribute(__mode__)
25+
#define SWIFT_MODE_DI __attribute__((__mode__(DI)))
26+
#define SWIFT_MODE_TI __attribute__((__mode__(TI)))
27+
#else
28+
#define SWIFT_MODE_DI
29+
#define SWIFT_MODE_TI
30+
#endif
31+
32+
typedef int di_int SWIFT_MODE_DI;
33+
typedef int ti_int SWIFT_MODE_TI;
34+
35+
extern "C" {
36+
37+
// Although this builtin is provided by clang rt builtins,
38+
// it isn't provided by libgcc, which is the default
39+
// runtime library on Linux, even when compiling with clang.
40+
// This implementation is copied here to avoid a new dependency
41+
// on compiler-rt on Linux.
42+
// FIXME: rdar://14883575 Libcompiler_rt omits muloti4
43+
#if (defined(__linux__) && defined(__x86_64__)) || \
44+
(defined(__linux__) && defined(__aarch64__)) || \
45+
(defined(__linux__) && defined(__powerpc64__)) || \
46+
(defined(__linux__) && defined(__s390x__)) || \
47+
(defined(__ANDROID__) && defined(__arm64__))
48+
49+
SWIFT_RUNTIME_STDLIB_INTERFACE
50+
ti_int
51+
__muloti4(ti_int a, ti_int b, int* overflow)
52+
{
53+
const int N = (int)(sizeof(ti_int) * CHAR_BIT);
54+
const ti_int MIN = (ti_int)1 << (N-1);
55+
const ti_int MAX = ~MIN;
56+
*overflow = 0;
57+
ti_int result = a * b;
58+
if (a == MIN)
59+
{
60+
if (b != 0 && b != 1)
61+
*overflow = 1;
62+
return result;
63+
}
64+
if (b == MIN)
65+
{
66+
if (a != 0 && a != 1)
67+
*overflow = 1;
68+
return result;
69+
}
70+
ti_int sa = a >> (N - 1);
71+
ti_int abs_a = (a ^ sa) - sa;
72+
ti_int sb = b >> (N - 1);
73+
ti_int abs_b = (b ^ sb) - sb;
74+
if (abs_a < 2 || abs_b < 2)
75+
return result;
76+
if (sa == sb)
77+
{
78+
if (abs_a > MAX / abs_b)
79+
*overflow = 1;
80+
}
81+
else
82+
{
83+
if (abs_a > MIN / -abs_b)
84+
*overflow = 1;
85+
}
86+
return result;
87+
}
88+
89+
#endif
90+
91+
// FIXME: ideally we would have a slow path here for Windows which would be
92+
// lowered to instructions as though MSVC had generated. There does not seem to
93+
// be a MSVC provided multiply with overflow detection that I can see, but this
94+
// avoids an unnecessary dependency on compiler-rt for a single function.
95+
#if (defined(__linux__) && defined(__arm__)) || defined(_WIN32)
96+
97+
// Similar to above, but with mulodi4. Perhaps this is
98+
// something that shouldn't be done, and is a bandaid over
99+
// some other lower-level architecture issue that I'm
100+
// missing. Perhaps relevant bug report:
101+
// FIXME: https://llvm.org/bugs/show_bug.cgi?id=14469
102+
103+
SWIFT_RUNTIME_STDLIB_INTERFACE
104+
di_int
105+
__mulodi4(di_int a, di_int b, int* overflow)
106+
{
107+
const int N = (int)(sizeof(di_int) * CHAR_BIT);
108+
const di_int MIN = (di_int)1 << (N-1);
109+
const di_int MAX = ~MIN;
110+
*overflow = 0;
111+
di_int result = a * b;
112+
if (a == MIN)
113+
{
114+
if (b != 0 && b != 1)
115+
*overflow = 1;
116+
return result;
117+
}
118+
if (b == MIN)
119+
{
120+
if (a != 0 && a != 1)
121+
*overflow = 1;
122+
return result;
123+
}
124+
di_int sa = a >> (N - 1);
125+
di_int abs_a = (a ^ sa) - sa;
126+
di_int sb = b >> (N - 1);
127+
di_int abs_b = (b ^ sb) - sb;
128+
if (abs_a < 2 || abs_b < 2)
129+
return result;
130+
if (sa == sb)
131+
{
132+
if (abs_a > MAX / abs_b)
133+
*overflow = 1;
134+
}
135+
else
136+
{
137+
if (abs_a > MIN / -abs_b)
138+
*overflow = 1;
139+
}
140+
return result;
141+
}
142+
143+
#endif
144+
145+
}
146+

stdlib/public/stubs/Stubs.cpp

Lines changed: 0 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -330,120 +330,6 @@ swift::swift_stdlib_readLine_stdin(unsigned char **LinePtr) {
330330
#endif
331331
}
332332

333-
334-
// Although this builtin is provided by clang rt builtins,
335-
// it isn't provided by libgcc, which is the default
336-
// runtime library on Linux, even when compiling with clang.
337-
// This implementation is copied here to avoid a new dependency
338-
// on compiler-rt on Linux.
339-
// FIXME: rdar://14883575 Libcompiler_rt omits muloti4
340-
#if (defined(__linux__) && defined(__x86_64__)) || \
341-
(defined(__linux__) && defined(__aarch64__)) || \
342-
(defined(__linux__) && defined(__powerpc64__)) || \
343-
(defined(__linux__) && defined(__s390x__)) || \
344-
(defined(__ANDROID__) && defined(__arm64__))
345-
346-
typedef int ti_int __attribute__((__mode__(TI)));
347-
SWIFT_RUNTIME_STDLIB_INTERFACE
348-
ti_int
349-
__muloti4(ti_int a, ti_int b, int* overflow)
350-
{
351-
const int N = (int)(sizeof(ti_int) * CHAR_BIT);
352-
const ti_int MIN = (ti_int)1 << (N-1);
353-
const ti_int MAX = ~MIN;
354-
*overflow = 0;
355-
ti_int result = a * b;
356-
if (a == MIN)
357-
{
358-
if (b != 0 && b != 1)
359-
*overflow = 1;
360-
return result;
361-
}
362-
if (b == MIN)
363-
{
364-
if (a != 0 && a != 1)
365-
*overflow = 1;
366-
return result;
367-
}
368-
ti_int sa = a >> (N - 1);
369-
ti_int abs_a = (a ^ sa) - sa;
370-
ti_int sb = b >> (N - 1);
371-
ti_int abs_b = (b ^ sb) - sb;
372-
if (abs_a < 2 || abs_b < 2)
373-
return result;
374-
if (sa == sb)
375-
{
376-
if (abs_a > MAX / abs_b)
377-
*overflow = 1;
378-
}
379-
else
380-
{
381-
if (abs_a > MIN / -abs_b)
382-
*overflow = 1;
383-
}
384-
return result;
385-
}
386-
387-
#endif
388-
389-
// FIXME: ideally we would have a slow path here for Windows which would be
390-
// lowered to instructions as though MSVC had generated. There does not seem to
391-
// be a MSVC provided multiply with overflow detection that I can see, but this
392-
// avoids an unnecessary dependency on compiler-rt for a single function.
393-
#if (defined(__linux__) && defined(__arm__)) || defined(_WIN32)
394-
// Similar to above, but with mulodi4. Perhaps this is
395-
// something that shouldn't be done, and is a bandaid over
396-
// some other lower-level architecture issue that I'm
397-
// missing. Perhaps relevant bug report:
398-
// FIXME: https://llvm.org/bugs/show_bug.cgi?id=14469
399-
#if __has_attribute(__mode__)
400-
#define SWIFT_MODE_DI __attribute__((__mode__(DI)))
401-
#else
402-
#define SWIFT_MODE_DI
403-
#endif
404-
405-
typedef int di_int SWIFT_MODE_DI;
406-
SWIFT_RUNTIME_STDLIB_INTERFACE
407-
di_int
408-
__mulodi4(di_int a, di_int b, int* overflow)
409-
{
410-
const int N = (int)(sizeof(di_int) * CHAR_BIT);
411-
const di_int MIN = (di_int)1 << (N-1);
412-
const di_int MAX = ~MIN;
413-
*overflow = 0;
414-
di_int result = a * b;
415-
if (a == MIN)
416-
{
417-
if (b != 0 && b != 1)
418-
*overflow = 1;
419-
return result;
420-
}
421-
if (b == MIN)
422-
{
423-
if (a != 0 && a != 1)
424-
*overflow = 1;
425-
return result;
426-
}
427-
di_int sa = a >> (N - 1);
428-
di_int abs_a = (a ^ sa) - sa;
429-
di_int sb = b >> (N - 1);
430-
di_int abs_b = (b ^ sb) - sb;
431-
if (abs_a < 2 || abs_b < 2)
432-
return result;
433-
if (sa == sb)
434-
{
435-
if (abs_a > MAX / abs_b)
436-
*overflow = 1;
437-
}
438-
else
439-
{
440-
if (abs_a > MIN / -abs_b)
441-
*overflow = 1;
442-
}
443-
return result;
444-
}
445-
#endif
446-
447333
#if defined(__CYGWIN__) || defined(_WIN32)
448334
#define strcasecmp _stricmp
449335
#endif

0 commit comments

Comments
 (0)