| //===--- 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 |
| public func fabs<T: FloatingPoint>(_ x: T) -> T |
| where T.Magnitude == 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) |
| } |
| |
| %{ |
| |
| # Don't need 64-bit (Double/CDouble) overlays. The ordinary C imports work fine. |
| # FIXME: need 80-bit (Float80/long double) versions when long double is imported |
| 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 = [ |
| 'fpclassify', |
| 'isnormal', 'isfinite', 'isinf', 'isnan', 'signbit', |
| 'modf', 'ldexp', 'frexp', 'ilogb', '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(): |
| @_transparent |
| public func ${ufunc}(_ x: ${T}) -> ${T} { |
| return ${T}(${ufunc}${f}(${CT}(x))) |
| } |
| |
| % end |
| |
| #if os(OSX) || os(iOS) || os(tvOS) || os(watchOS) |
| // Unary intrinsic functions |
| // Note these have a corresponding LLVM intrinsic |
| % for T, ufunc in TypedUnaryIntrinsicFunctions(): |
| @_transparent |
| public func ${ufunc}(_ x: ${T}) -> ${T} { |
| return _${ufunc}(x) |
| } |
| |
| % 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(): |
| @_transparent |
| public func ${ufunc}(_ x: ${T}) -> ${T} { |
| return ${T}(${ufunc}${f}(${CT}(x))) |
| } |
| |
| % end |
| % end |
| #endif |
| |
| // Binary functions |
| |
| % for T, CT, f, bfunc in TypedBinaryFunctions(): |
| @_transparent |
| public func ${bfunc}(_ lhs: ${T}, _ rhs: ${T}) -> ${T} { |
| return ${T}(${bfunc}${f}(${CT}(lhs), ${CT}(rhs))) |
| } |
| |
| % end |
| |
| // Other functions |
| % for T, CT, f in AllFloatTypes(): |
| @available(*, deprecated, message: "use the floatingPointClass property.") |
| public func fpclassify(_ value: ${T}) -> Int { |
| %if T == 'Double': |
| #if os(Linux) || os(Haiku) |
| return Int(__fpclassify(CDouble(value))) |
| #elseif os(Windows) |
| return Int(_dclass(CDouble(value))) |
| #else |
| return Int(__fpclassifyd(CDouble(value))) |
| #endif |
| %else: |
| #if os(Windows) |
| return Int(_${f}dclass(${CT}(value))) |
| #else |
| return Int(__fpclassify${f}(${CT}(value))) |
| #endif |
| %end |
| } |
| |
| @available(*, unavailable, message: "use the isNormal property.") |
| public func isnormal(_ value: ${T}) -> Bool { return value.isNormal } |
| |
| @available(*, unavailable, message: "use the isFinite property.") |
| public func isfinite(_ value: ${T}) -> Bool { return value.isFinite } |
| |
| @available(*, unavailable, message: "use the isInfinite property.") |
| public func isinf(_ value: ${T}) -> Bool { return value.isInfinite } |
| |
| @available(*, unavailable, message: "use the isNaN property.") |
| public func isnan(_ value: ${T}) -> Bool { return value.isNaN } |
| |
| @available(*, unavailable, message: "use the sign property.") |
| public func signbit(_ value: ${T}) -> Int { return value.sign.rawValue } |
| |
| % end |
| |
| % # These are AllFloatTypes not OverlayFloatTypes because of the tuple return. |
| % for T, CT, f in AllFloatTypes(): |
| @_transparent |
| public func modf(_ value: ${T}) -> (${T}, ${T}) { |
| var ipart = ${CT}(0) |
| let fpart = modf${f}(${CT}(value), &ipart) |
| return (${T}(ipart), ${T}(fpart)) |
| } |
| |
| % end |
| |
| % # This is AllFloatTypes not OverlayFloatTypes because of the Int parameter. |
| % for T, CT, f in AllFloatTypes(): |
| @_transparent |
| public func ldexp(_ x: ${T}, _ n: Int) -> ${T} { |
| return ${T}(ldexp${f}(${CT}(x), Int32(n))) |
| } |
| |
| % end |
| |
| % # This is AllFloatTypes not OverlayFloatTypes because of the tuple return. |
| % for T, CT, f in AllFloatTypes(): |
| @_transparent |
| public func frexp(_ value: ${T}) -> (${T}, Int) { |
| var exp = Int32(0) |
| let frac = frexp${f}(${CT}(value), &exp) |
| return (${T}(frac), Int(exp)) |
| } |
| |
| % end |
| |
| % # This is AllFloatTypes not OverlayFloatTypes because of the Int return. |
| % for T, CT, f in AllFloatTypes(): |
| @_transparent |
| public func ilogb(_ x: ${T}) -> Int { |
| return Int(ilogb${f}(${CT}(x)) as Int32) |
| } |
| |
| % end |
| |
| % # This is AllFloatTypes not OverlayFloatTypes because of the Int parameter. |
| % for T, CT, f in AllFloatTypes(): |
| @_transparent |
| public func scalbn(_ x: ${T}, _ n: Int) -> ${T} { |
| return ${T}(scalbn${f}(${CT}(x), Int32(n))) |
| } |
| |
| % end |
| |
| % # This is AllFloatTypes not OverlayFloatTypes because of the tuple return. |
| % for T, CT, f in AllFloatTypes(): |
| #if os(Linux) || os(FreeBSD) || os(PS4) || os(Android) || os(Cygwin) || os(Haiku) |
| @_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)) |
| } |
| #elseif os(Windows) |
| // TODO(compnerd): implement |
| #else |
| % # On Darwin platforms the real lgamma_r is not imported |
| % # because it hides behind macro _REENTRANT. |
| % # This is not @transparent because _stdlib_lgamma() is not public. |
| public func lgamma(_ x: ${T}) -> (${T}, Int) { |
| var sign = Int32(0) |
| let value = withUnsafeMutablePointer(to: &sign) { |
| (signp: UnsafeMutablePointer<Int32>) -> ${CT} in |
| return _stdlib_lgamma${f}_r(${CT}(x), signp) |
| } |
| return (${T}(value), Int(sign)) |
| } |
| #endif |
| |
| % end |
| |
| % # This is AllFloatTypes not OverlayFloatTypes because of the tuple return. |
| % for T, CT, f in AllFloatTypes(): |
| @_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)) |
| } |
| |
| % end |
| |
| % for T, CT, f in OverlayFloatTypes(): |
| @_transparent |
| public func nan(_ tag: String) -> ${T} { |
| return ${T}(nan${f}(tag)) |
| } |
| |
| % 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: |