Skip to content

Commit d56aaf8

Browse files
committed
android: add log2 implementation from Android Support and mulodi4 from compiler_rt, hardcode path to libicu for now
1 parent 0848269 commit d56aaf8

File tree

13 files changed

+1200
-8
lines changed

13 files changed

+1200
-8
lines changed

cmake/modules/AddSwift.cmake

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,12 +162,13 @@ function(_add_variant_link_flags
162162
result)
163163

164164
if("${sdk}" STREQUAL "LINUX")
165-
list(APPEND result "-lpthread" "-ldl")
165+
list(APPEND result "-lpthread" "-ldl" "${BSD_LIBRARIES}")
166166
elseif("${sdk}" STREQUAL "ANDROID")
167167
list(APPEND result
168168
"-ldl"
169-
"-L${SWIFT_ANDROID_NDK_PATH}/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8/thumb"
170-
"${SWIFT_ANDROID_NDK_PATH}/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/thumb/libc++_shared.so")
169+
"-L${SWIFT_ANDROID_NDK_PATH}/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8"
170+
"${SWIFT_ANDROID_NDK_PATH}/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libc++_shared.so"
171+
"-L/home/zhuowei/libiconv-libicu-android/armeabi-v7a")
171172
else()
172173
list(APPEND result "-lobjc")
173174
endif()

stdlib/public/core/CMakeLists.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,7 @@ else()
156156
find_package(ICU REQUIRED COMPONENTS uc i18n)
157157
find_package(BSD REQUIRED)
158158
list(APPEND swift_core_private_link_libraries
159-
${ICU_UC_LIBRARY} ${ICU_I18N_LIBRARY}
160-
${BSD_LIBRARIES})
159+
${ICU_UC_LIBRARY} ${ICU_I18N_LIBRARY})
161160
endif()
162161

163162
option(SWIFT_CHECK_ESSENTIAL_STDLIB

stdlib/public/stubs/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ add_swift_library(swiftStdlibStubs IS_STDLIB IS_STDLIB_CORE
1111
GlobalObjects.cpp
1212
LibcShims.cpp
1313
Stubs.cpp
14+
android_support/Android_log2.cpp
15+
android_support/Android_log2f.cpp
1416
${swift_stubs_objc_sources}
1517
C_COMPILE_FLAGS ${SWIFT_CORE_CXX_FLAGS}
1618
INSTALL_IN_COMPONENT stdlib)

stdlib/public/stubs/LibcShims.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@ static_assert(std::is_same<ssize_t, swift::__swift_ssize_t>::value,
2727
"__swift_ssize_t is wrong");
2828
#endif
2929

30+
#ifdef __ANDROID__
31+
extern "C" {
32+
extern size_t dlmalloc_usable_size(void*);
33+
}
34+
#endif
35+
3036
namespace swift {
3137

3238
void _swift_stdlib_free(void *ptr) { free(ptr); }
@@ -53,11 +59,16 @@ int _swift_stdlib_close(int fd) { return close(fd); }
5359
#if defined(__APPLE__)
5460
#include <malloc/malloc.h>
5561
size_t _swift_stdlib_malloc_size(const void *ptr) { return malloc_size(ptr); }
56-
#elif defined(__GNU_LIBRARY__) || defined(__ANDROID__)
62+
#elif defined(__GNU_LIBRARY__)
5763
#include <malloc.h>
5864
size_t _swift_stdlib_malloc_size(const void *ptr) {
5965
return malloc_usable_size(const_cast<void *>(ptr));
6066
}
67+
#elif defined(__ANDROID__)
68+
// on Android before API 21 malloc_usable_size is exported by this name
69+
size_t _swift_stdlib_malloc_size(const void *ptr) {
70+
return dlmalloc_usable_size(const_cast<void *>(ptr));
71+
}
6172
#else
6273
#error No malloc_size analog known for this platform/libc.
6374
#endif

stdlib/public/stubs/Stubs.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,11 @@
3131
#include "swift/Basic/Lazy.h"
3232

3333
#ifdef __ANDROID__
34+
extern "C" {
3435
#include "getline.inc"
3536
#define getline swift_getline
37+
#include "mulodi4.inc"
38+
}
3639
#endif
3740

3841
static uint64_t uint64ToStringImpl(char *Buffer, uint64_t Value,
@@ -127,11 +130,15 @@ static float swift_strtof_l(const char* a, char** b, locale_t c) {
127130
return strtof(a, b);
128131
}
129132
static long double swift_strtold_l(const char* a, char** b, locale_t c) {
130-
return strtold(a, b);
133+
return strtod(a, b);
134+
}
135+
static long double swift_fmodl(long double a, long double b) {
136+
return fmod(a, b);
131137
}
132138
#define strtod_l swift_strtod_l
133139
#define strtof_l swift_strtof_l
134140
#define strtold_l swift_strtold_l
141+
#define fmodl swift_fmodl
135142
#endif
136143

137144
#if defined(__APPLE__)
@@ -232,7 +239,7 @@ extern "C" long double _swift_fmodl(long double lhs, long double rhs) {
232239
// This implementation is copied here to avoid a new dependency
233240
// on compiler-rt on Linux.
234241
// FIXME: rdar://14883575 Libcompiler_rt omits muloti4
235-
#if __arm64__ || !defined(__APPLE__)
242+
#if __arm64__ || (!defined(__APPLE__) && !defined(__ANDROID__))
236243

237244
typedef int ti_int __attribute__ ((mode (TI)));
238245
extern "C"
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#ifdef __ANDROID__
2+
extern "C" {
3+
#include "e_log2.c"
4+
}
5+
#endif
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#ifdef __ANDROID__
2+
extern "C" {
3+
#include "e_log2f.c"
4+
}
5+
#endif
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
2+
/* @(#)e_log10.c 1.3 95/01/18 */
3+
/*
4+
* ====================================================
5+
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
6+
*
7+
* Developed at SunSoft, a Sun Microsystems, Inc. business.
8+
* Permission to use, copy, modify, and distribute this
9+
* software is freely granted, provided that this notice
10+
* is preserved.
11+
* ====================================================
12+
*/
13+
14+
#include <sys/cdefs.h>
15+
__FBSDID("$FreeBSD$");
16+
17+
/*
18+
* Return the base 2 logarithm of x. See e_log.c and k_log.h for most
19+
* comments.
20+
*
21+
* This reduces x to {k, 1+f} exactly as in e_log.c, then calls the kernel,
22+
* then does the combining and scaling steps
23+
* log2(x) = (f - 0.5*f*f + k_log1p(f)) / ln2 + k
24+
* in not-quite-routine extra precision.
25+
*/
26+
27+
#include <float.h>
28+
29+
#include "math.h"
30+
#include "math_private.h"
31+
#include "k_log.h"
32+
33+
static const double
34+
two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */
35+
ivln2hi = 1.44269504072144627571e+00, /* 0x3ff71547, 0x65200000 */
36+
ivln2lo = 1.67517131648865118353e-10; /* 0x3de705fc, 0x2eefa200 */
37+
38+
static const double zero = 0.0;
39+
static volatile double vzero = 0.0;
40+
41+
double
42+
__ieee754_log2(double x)
43+
{
44+
double f,hfsq,hi,lo,r,val_hi,val_lo,w,y;
45+
int32_t i,k,hx;
46+
u_int32_t lx;
47+
48+
EXTRACT_WORDS(hx,lx,x);
49+
50+
k=0;
51+
if (hx < 0x00100000) { /* x < 2**-1022 */
52+
if (((hx&0x7fffffff)|lx)==0)
53+
return -two54/vzero; /* log(+-0)=-inf */
54+
if (hx<0) return (x-x)/zero; /* log(-#) = NaN */
55+
k -= 54; x *= two54; /* subnormal number, scale up x */
56+
GET_HIGH_WORD(hx,x);
57+
}
58+
if (hx >= 0x7ff00000) return x+x;
59+
if (hx == 0x3ff00000 && lx == 0)
60+
return zero; /* log(1) = +0 */
61+
k += (hx>>20)-1023;
62+
hx &= 0x000fffff;
63+
i = (hx+0x95f64)&0x100000;
64+
SET_HIGH_WORD(x,hx|(i^0x3ff00000)); /* normalize x or x/2 */
65+
k += (i>>20);
66+
y = (double)k;
67+
f = x - 1.0;
68+
hfsq = 0.5*f*f;
69+
r = k_log1p(f);
70+
71+
/*
72+
* f-hfsq must (for args near 1) be evaluated in extra precision
73+
* to avoid a large cancellation when x is near sqrt(2) or 1/sqrt(2).
74+
* This is fairly efficient since f-hfsq only depends on f, so can
75+
* be evaluated in parallel with R. Not combining hfsq with R also
76+
* keeps R small (though not as small as a true `lo' term would be),
77+
* so that extra precision is not needed for terms involving R.
78+
*
79+
* Compiler bugs involving extra precision used to break Dekker's
80+
* theorem for spitting f-hfsq as hi+lo, unless double_t was used
81+
* or the multi-precision calculations were avoided when double_t
82+
* has extra precision. These problems are now automatically
83+
* avoided as a side effect of the optimization of combining the
84+
* Dekker splitting step with the clear-low-bits step.
85+
*
86+
* y must (for args near sqrt(2) and 1/sqrt(2)) be added in extra
87+
* precision to avoid a very large cancellation when x is very near
88+
* these values. Unlike the above cancellations, this problem is
89+
* specific to base 2. It is strange that adding +-1 is so much
90+
* harder than adding +-ln2 or +-log10_2.
91+
*
92+
* This uses Dekker's theorem to normalize y+val_hi, so the
93+
* compiler bugs are back in some configurations, sigh. And I
94+
* don't want to used double_t to avoid them, since that gives a
95+
* pessimization and the support for avoiding the pessimization
96+
* is not yet available.
97+
*
98+
* The multi-precision calculations for the multiplications are
99+
* routine.
100+
*/
101+
hi = f - hfsq;
102+
SET_LOW_WORD(hi,0);
103+
lo = (f - hi) - hfsq + r;
104+
val_hi = hi*ivln2hi;
105+
val_lo = (lo+hi)*ivln2lo + lo*ivln2hi;
106+
107+
/* spadd(val_hi, val_lo, y), except for not using double_t: */
108+
w = y + val_hi;
109+
val_lo += (y - w) + val_hi;
110+
val_hi = w;
111+
112+
return val_lo + val_hi;
113+
}
114+
115+
#if (LDBL_MANT_DIG == 53) && !defined(__le32__) && !defined(__le64__)
116+
#define __weak_reference(sym,alias) \
117+
__asm__(".weak " #alias); \
118+
__asm__(".equ " #alias ", " #sym)
119+
__weak_reference(log2, log2l);
120+
#endif
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*
2+
* ====================================================
3+
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
4+
*
5+
* Developed at SunPro, a Sun Microsystems, Inc. business.
6+
* Permission to use, copy, modify, and distribute this
7+
* software is freely granted, provided that this notice
8+
* is preserved.
9+
* ====================================================
10+
*/
11+
12+
#include <sys/cdefs.h>
13+
__FBSDID("$FreeBSD$");
14+
15+
/*
16+
* Float version of e_log2.c. See the latter for most comments.
17+
*/
18+
19+
#include "math.h"
20+
#include "math_private.h"
21+
#include "k_logf.h"
22+
23+
static const float
24+
two25 = 3.3554432000e+07, /* 0x4c000000 */
25+
ivln2hi = 1.4428710938e+00, /* 0x3fb8b000 */
26+
ivln2lo = -1.7605285393e-04; /* 0xb9389ad4 */
27+
28+
static const float zero = 0.0;
29+
static volatile float vzero = 0.0;
30+
31+
float
32+
__ieee754_log2f(float x)
33+
{
34+
float f,hfsq,hi,lo,r,y;
35+
int32_t i,k,hx;
36+
37+
GET_FLOAT_WORD(hx,x);
38+
39+
k=0;
40+
if (hx < 0x00800000) { /* x < 2**-126 */
41+
if ((hx&0x7fffffff)==0)
42+
return -two25/vzero; /* log(+-0)=-inf */
43+
if (hx<0) return (x-x)/zero; /* log(-#) = NaN */
44+
k -= 25; x *= two25; /* subnormal number, scale up x */
45+
GET_FLOAT_WORD(hx,x);
46+
}
47+
if (hx >= 0x7f800000) return x+x;
48+
if (hx == 0x3f800000)
49+
return zero; /* log(1) = +0 */
50+
k += (hx>>23)-127;
51+
hx &= 0x007fffff;
52+
i = (hx+(0x4afb0d))&0x800000;
53+
SET_FLOAT_WORD(x,hx|(i^0x3f800000)); /* normalize x or x/2 */
54+
k += (i>>23);
55+
y = (float)k;
56+
f = x - (float)1.0;
57+
hfsq = (float)0.5*f*f;
58+
r = k_log1pf(f);
59+
60+
/*
61+
* We no longer need to avoid falling into the multi-precision
62+
* calculations due to compiler bugs breaking Dekker's theorem.
63+
* Keep avoiding this as an optimization. See e_log2.c for more
64+
* details (some details are here only because the optimization
65+
* is not yet available in double precision).
66+
*
67+
* Another compiler bug turned up. With gcc on i386,
68+
* (ivln2lo + ivln2hi) would be evaluated in float precision
69+
* despite runtime evaluations using double precision. So we
70+
* must cast one of its terms to float_t. This makes the whole
71+
* expression have type float_t, so return is forced to waste
72+
* time clobbering its extra precision.
73+
*/
74+
if (sizeof(float_t) > sizeof(float))
75+
return (r - hfsq + f) * ((float_t)ivln2lo + ivln2hi) + y;
76+
77+
hi = f - hfsq;
78+
GET_FLOAT_WORD(hx,hi);
79+
SET_FLOAT_WORD(hi,hx&0xfffff000);
80+
lo = (f - hi) - hfsq + r;
81+
return (lo+hi)*ivln2lo + lo*ivln2hi + hi*ivln2hi + y;
82+
}

0 commit comments

Comments
 (0)