Skip to content

Commit 0a1352e

Browse files
committed
stubs: split up compiler-rt routines
Move the duplicated compiler-rt support routines into its own source file. This will need to be expanded for Windows. As on Linux, there are certain builtin routines which are not available from the standard runtime and need to be augmented for now.
1 parent 28fb34d commit 0a1352e

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)