| //===--- tgmath.swift.gyb -------------------------------------*- swift -*-===// |
| // |
| // This source file is part of the Swift.org open source project |
| // |
| // Copyright (c) 2014 - 2017 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, 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, 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) |
| % 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) |
| // 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) |
| % 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) |
| % 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) |
| % 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) |
| % 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) |
| % 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) |
| % end |
| @available(swift, deprecated: 4.2, message: |
| "use ${T}(nan: ${T}.RawSignificand) instead.") |
| @_transparent |
| 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: |