//===--- 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(_ x: T) -> T { return x.magnitude } @_transparent public func sqrt(_ x: T) -> T { return x.squareRoot() } @_transparent public func fma(_ x: T, _ y: T, _ z: T) -> T { return z.addingProduct(x, y) } @_transparent public func remainder(_ x: T, _ y: T) -> T { return x.remainder(dividingBy: y) } @_transparent public func fmod(_ x: T, _ y: T) -> T { return x.truncatingRemainder(dividingBy: y) } @_transparent public func ceil(_ x: T) -> T { return x.rounded(.up) } @_transparent public func floor(_ x: T) -> T { return x.rounded(.down) } @_transparent public func round(_ x: T) -> T { return x.rounded() } @_transparent public func trunc(_ x: T) -> T { return x.rounded(.towardZero) } @_transparent public func scalbn(_ x: T, _ n : Int) -> T { return T(sign: .plus, exponent: T.Exponent(n), significand: x) } @_transparent public func modf(_ 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(_ 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(_ value: T) -> Int { fatalError() } @available(*, unavailable, message: "use the isNormal property.") public func isnormal(_ value: T) -> Bool { fatalError() } @available(*, unavailable, message: "use the isFinite property.") public func isfinite(_ value: T) -> Bool { fatalError() } @available(*, unavailable, message: "use the isInfinite property.") public func isinf(_ value: T) -> Bool { fatalError() } @available(*, unavailable, message: "use the isNaN property.") public func isnan(_ value: T) -> Bool { fatalError() } @available(*, unavailable, message: "use the sign property.") public func signbit(_ value: T) -> Int { fatalError() } @available(swift, deprecated: 4.2/*, obsoleted: 5.1*/, message: "use the exponent property.") public func ilogb(_ 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: