//===--- 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(_ x: T) -> T where T.Magnitude == 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) } %{ # 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) -> ${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: