-
Notifications
You must be signed in to change notification settings - Fork 10.5k
/
Copy pathtgmath.swift.gyb
365 lines (307 loc) · 10.2 KB
/
tgmath.swift.gyb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
//===--- tgmath.swift.gyb -------------------------------------*- swift -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
import SwiftShims
// Generic functions implementable directly on FloatingPoint.
@_transparent
@available(swift, deprecated: 4.2/*, obsoleted: 5.1*/, renamed: "abs")
public func fabs<T: FloatingPoint>(_ x: T) -> T {
return x.magnitude
}
@_transparent
public func sqrt<T: FloatingPoint>(_ x: T) -> T {
return x.squareRoot()
}
@_transparent
public func fma<T: FloatingPoint>(_ x: T, _ y: T, _ z: T) -> T {
return z.addingProduct(x, y)
}
@_transparent
public func remainder<T: FloatingPoint>(_ x: T, _ y: T) -> T {
return x.remainder(dividingBy: y)
}
@_transparent
public func fmod<T: FloatingPoint>(_ x: T, _ y: T) -> T {
return x.truncatingRemainder(dividingBy: y)
}
@_transparent
public func ceil<T: FloatingPoint>(_ x: T) -> T {
return x.rounded(.up)
}
@_transparent
public func floor<T: FloatingPoint>(_ x: T) -> T {
return x.rounded(.down)
}
@_transparent
public func round<T: FloatingPoint>(_ x: T) -> T {
return x.rounded()
}
@_transparent
public func trunc<T: FloatingPoint>(_ x: T) -> T {
return x.rounded(.towardZero)
}
@_transparent
public func scalbn<T: FloatingPoint>(_ x: T, _ n : Int) -> T {
return T(sign: .plus, exponent: T.Exponent(n), significand: x)
}
@_transparent
public func modf<T: FloatingPoint>(_ x: T) -> (T, T) {
// inf/NaN: return canonicalized x, fractional part zero.
guard x.isFinite else { return (x+0, 0) }
let integral = trunc(x)
let fractional = x - integral
return (integral, fractional)
}
@_transparent
public func frexp<T: BinaryFloatingPoint>(_ x: T) -> (T, Int) {
guard x.isFinite else { return (x+0, 0) }
guard x != 0 else { return (x, 0) }
// The C stdlib `frexp` uses a different notion of significand / exponent
// than IEEE 754, so we need to adjust them by a factor of two.
return (x.significand / 2, Int(x.exponent + 1))
}
%for T in ['Float','Double']:
@available(swift, deprecated: 4.2, renamed: "scalbn")
@_transparent
public func ldexp(_ x: ${T}, _ n : Int) -> ${T} {
return ${T}(sign: .plus, exponent: n, significand: x)
}
%end
// Floating-point properties that are exposed as functions in the C math
// library. Mark those function names unavailable and direct users to the
// properties instead.
@available(*, unavailable, message: "use the floatingPointClass property.")
public func fpclassify<T: FloatingPoint>(_ value: T) -> Int { fatalError() }
@available(*, unavailable, message: "use the isNormal property.")
public func isnormal<T: FloatingPoint>(_ value: T) -> Bool { fatalError() }
@available(*, unavailable, message: "use the isFinite property.")
public func isfinite<T: FloatingPoint>(_ value: T) -> Bool { fatalError() }
@available(*, unavailable, message: "use the isInfinite property.")
public func isinf<T: FloatingPoint>(_ value: T) -> Bool { fatalError() }
@available(*, unavailable, message: "use the isNaN property.")
public func isnan<T: FloatingPoint>(_ value: T) -> Bool { fatalError() }
@available(*, unavailable, message: "use the sign property.")
public func signbit<T: FloatingPoint>(_ value: T) -> Int { fatalError() }
@available(swift, deprecated: 4.2/*, obsoleted: 5.1*/, message: "use the exponent property.")
public func ilogb<T: BinaryFloatingPoint>(_ x: T) -> Int {
return Int(x.exponent)
}
%{
# Don't need 64-bit (Double/CDouble) overlays. The ordinary C imports work fine.
overlayFloatBits = [32, 80]
allFloatBits = [32, 64, 80]
def floatName(bits):
if bits == 32:
return 'Float'
if bits == 64:
return 'Double'
if bits == 80:
return 'Float80'
def cFloatName(bits):
if bits == 32:
return 'CFloat'
if bits == 64:
return 'CDouble'
if bits == 80:
return 'CLongDouble'
def cFuncSuffix(bits):
if bits == 32:
return 'f'
if bits == 64:
return ''
if bits == 80:
return 'l'
# Each of the following lists is ordered to match math.h
# (T) -> T
# These functions do not have a corresponding LLVM intrinsic
UnaryFunctions = [
'acos', 'asin', 'atan', 'tan',
'acosh', 'asinh', 'atanh', 'cosh', 'sinh', 'tanh',
'expm1',
'log1p', 'logb',
'cbrt', 'erf', 'erfc', 'tgamma',
]
# These functions have a corresponding LLVM intrinsic
# We call this intrinsic via the Builtin method so keep this list in
# sync with core/BuiltinMath.swift.gyb
UnaryIntrinsicFunctions = [
'cos', 'sin',
'exp', 'exp2',
'log', 'log10', 'log2',
'nearbyint', 'rint',
]
# (T, T) -> T
BinaryFunctions = [
'atan2', 'hypot', 'pow',
'copysign', 'nextafter', 'fdim', 'fmax', 'fmin'
]
# These functions have special implementations.
OtherFunctions = [
'scalbn', 'lgamma', 'remquo', 'nan', 'jn', 'yn'
]
# These functions are imported correctly as-is.
OkayFunctions = ['j0', 'j1', 'y0', 'y1']
# These functions are not supported for various reasons.
UnhandledFunctions = [
'math_errhandling', 'scalbln',
'lrint', 'lround', 'llrint', 'llround', 'nexttoward',
'isgreater', 'isgreaterequal', 'isless', 'islessequal',
'islessgreater', 'isunordered', '__exp10',
'__sincos', '__cospi', '__sinpi', '__tanpi', '__sincospi'
]
def AllFloatTypes():
for bits in allFloatBits:
yield floatName(bits), cFloatName(bits), cFuncSuffix(bits)
def OverlayFloatTypes():
for bits in overlayFloatBits:
yield floatName(bits), cFloatName(bits), cFuncSuffix(bits)
def TypedUnaryFunctions():
for ufunc in UnaryFunctions:
for bits in overlayFloatBits:
yield floatName(bits), cFloatName(bits), cFuncSuffix(bits), ufunc
def TypedUnaryIntrinsicFunctions():
for ufunc in UnaryIntrinsicFunctions:
for bits in allFloatBits:
yield floatName(bits), ufunc
def TypedBinaryFunctions():
for bfunc in BinaryFunctions:
for bits in overlayFloatBits:
yield floatName(bits), cFloatName(bits), cFuncSuffix(bits), bfunc
}%
// Unary functions
// Note these do not have a corresponding LLVM intrinsic
% for T, CT, f, ufunc in TypedUnaryFunctions():
% if T == 'Float80':
#if (arch(i386) || arch(x86_64)) && !(os(Windows) || os(Android) || ($Embedded && !os(Linux) && !(os(macOS) || os(iOS) || os(watchOS) || os(tvOS))))
% end
@_transparent
public func ${ufunc}(_ x: ${T}) -> ${T} {
return ${T}(${ufunc}${f}(${CT}(x)))
}
% if T == 'Float80':
#endif
% end
% end
#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) || os(visionOS)
// Unary intrinsic functions
// Note these have a corresponding LLVM intrinsic
% for T, ufunc in TypedUnaryIntrinsicFunctions():
% if T == 'Float80':
#if (arch(i386) || arch(x86_64)) && !(os(Windows) || os(Android) || ($Embedded && !os(Linux) && !(os(macOS) || os(iOS) || os(watchOS) || os(tvOS))))
% end
@_transparent
public func ${ufunc}(_ x: ${T}) -> ${T} {
return _${ufunc}(x)
}
% if T == 'Float80':
#endif
% end
% end
#else
// FIXME: As of now, we cannot declare 64-bit (Double/CDouble) overlays here.
// Since CoreFoundation also exports libc functions, they will conflict with
// Swift overlays when building Foundation. For now, just like normal
// UnaryFunctions, we define overlays only for OverlayFloatTypes.
% for ufunc in UnaryIntrinsicFunctions:
% for T, CT, f in OverlayFloatTypes():
% if T == 'Float80':
#if (arch(i386) || arch(x86_64)) && !(os(Windows) || os(Android) || ($Embedded && !os(Linux) && !(os(macOS) || os(iOS) || os(watchOS) || os(tvOS))))
% end
@_transparent
public func ${ufunc}(_ x: ${T}) -> ${T} {
return ${T}(${ufunc}${f}(${CT}(x)))
}
% if T == 'Float80':
#endif
% end
% end
% end
#endif
// Binary functions
% for T, CT, f, bfunc in TypedBinaryFunctions():
% if T == 'Float80':
#if (arch(i386) || arch(x86_64)) && !(os(Windows) || os(Android) || ($Embedded && !os(Linux) && !(os(macOS) || os(iOS) || os(watchOS) || os(tvOS))))
% end
@_transparent
public func ${bfunc}(_ lhs: ${T}, _ rhs: ${T}) -> ${T} {
return ${T}(${bfunc}${f}(${CT}(lhs), ${CT}(rhs)))
}
% if T == 'Float80':
#endif
% end
% end
% # This is AllFloatTypes not OverlayFloatTypes because of the tuple return.
% for T, CT, f in AllFloatTypes():
% if T == 'Float80':
#if (arch(i386) || arch(x86_64)) && !(os(Windows) || os(Android) || os(OpenBSD) || ($Embedded && !os(Linux) && !(os(macOS) || os(iOS) || os(watchOS) || os(tvOS))))
% else:
// lgamma not available on Windows, apparently?
#if !os(Windows)
% end
@_transparent
public func lgamma(_ x: ${T}) -> (${T}, Int) {
var sign = Int32(0)
let value = lgamma${f}_r(${CT}(x), &sign)
return (${T}(value), Int(sign))
}
#endif
% end
% # This is AllFloatTypes not OverlayFloatTypes because of the tuple return.
% for T, CT, f in AllFloatTypes():
% if T == 'Float80':
#if (arch(i386) || arch(x86_64)) && !(os(Windows) || os(Android) || ($Embedded && !os(Linux) && !(os(macOS) || os(iOS) || os(watchOS) || os(tvOS))))
% end
@_transparent
public func remquo(_ x: ${T}, _ y: ${T}) -> (${T}, Int) {
var quo = Int32(0)
let rem = remquo${f}(${CT}(x), ${CT}(y), &quo)
return (${T}(rem), Int(quo))
}
% if T == 'Float80':
#endif
% end
% end
% for T, CT, f in OverlayFloatTypes():
% if T == 'Float80':
#if (arch(i386) || arch(x86_64)) && !(os(Windows) || os(Android) || ($Embedded && !os(Linux) && !(os(macOS) || os(iOS) || os(watchOS) || os(tvOS))))
% end
@available(swift, deprecated: 4.2/*, obsoleted: 5.1*/, message:
"use ${T}(nan: ${T}.RawSignificand).")
@_transparent
@_unavailableInEmbedded
public func nan(_ tag: String) -> ${T} {
return ${T}(nan${f}(tag))
}
% if T == 'Float80':
#endif
% end
% end
% # These C functions only support double. The overlay fixes the Int parameter.
@_transparent
public func jn(_ n: Int, _ x: Double) -> Double {
#if os(Windows)
return _jn(Int32(n), x)
#else
return jn(Int32(n), x)
#endif
}
@_transparent
public func yn(_ n: Int, _ x: Double) -> Double {
#if os(Windows)
return _yn(Int32(n), x)
#else
return yn(Int32(n), x)
#endif
}
% end
// ${'Local Variables'}:
// eval: (read-only-mode 1)
// End: