# MUSL: On musl systems, libm is empty. The entire library is already included in libc. # The empty library is only available for POSIX compatibility. We don't need to link it. # # Interpreter: On GNU systems, libm.so is typically a GNU ld script which adds # the actual library file to the load path. `Crystal::Loader` does not support # ld scripts yet. So we just skip that for now. The libm symbols are still # available in the interpreter. {% if (flag?(:linux) && !flag?(:musl) && !flag?(:interpreted)) || flag?(:bsd) || flag?(:solaris) %} @[Link("m")] {% end %} lib LibM # LLVM standard C library intrinsics {% if flag?(:interpreted) %} @[Primitive(:interpreter_libm_ceil_f32)] {% end %} fun ceil_f32 = "llvm.ceil.f32"(value : Float32) : Float32 {% if flag?(:interpreted) %} @[Primitive(:interpreter_libm_ceil_f64)] {% end %} fun ceil_f64 = "llvm.ceil.f64"(value : Float64) : Float64 {% if flag?(:interpreted) %} @[Primitive(:interpreter_libm_copysign_f32)] {% end %} fun copysign_f32 = "llvm.copysign.f32"(magnitude : Float32, sign : Float32) : Float32 {% if flag?(:interpreted) %} @[Primitive(:interpreter_libm_copysign_f64)] {% end %} fun copysign_f64 = "llvm.copysign.f64"(magnitude : Float64, sign : Float64) : Float64 {% if flag?(:interpreted) %} @[Primitive(:interpreter_libm_cos_f32)] {% end %} fun cos_f32 = "llvm.cos.f32"(value : Float32) : Float32 {% if flag?(:interpreted) %} @[Primitive(:interpreter_libm_cos_f64)] {% end %} fun cos_f64 = "llvm.cos.f64"(value : Float64) : Float64 {% if flag?(:interpreted) %} @[Primitive(:interpreter_libm_exp_f32)] {% end %} fun exp_f32 = "llvm.exp.f32"(value : Float32) : Float32 {% if flag?(:interpreted) %} @[Primitive(:interpreter_libm_exp_f64)] {% end %} fun exp_f64 = "llvm.exp.f64"(value : Float64) : Float64 {% if flag?(:interpreted) %} @[Primitive(:interpreter_libm_exp2_f32)] {% end %} fun exp2_f32 = "llvm.exp2.f32"(value : Float32) : Float32 {% if flag?(:interpreted) %} @[Primitive(:interpreter_libm_exp2_f64)] {% end %} fun exp2_f64 = "llvm.exp2.f64"(value : Float64) : Float64 {% if flag?(:interpreted) %} @[Primitive(:interpreter_libm_floor_f32)] {% end %} fun floor_f32 = "llvm.floor.f32"(value : Float32) : Float32 {% if flag?(:interpreted) %} @[Primitive(:interpreter_libm_floor_f64)] {% end %} fun floor_f64 = "llvm.floor.f64"(value : Float64) : Float64 {% if flag?(:interpreted) %} @[Primitive(:interpreter_libm_fma_f32)] {% end %} fun fma_f32 = "llvm.fma.f32"(value1 : Float32, value2 : Float32, value3 : Float32) : Float32 {% if flag?(:interpreted) %} @[Primitive(:interpreter_libm_fma_f64)] {% end %} fun fma_f64 = "llvm.fma.f64"(value1 : Float64, value2 : Float64, value3 : Float64) : Float64 {% if flag?(:interpreted) %} @[Primitive(:interpreter_libm_log_f32)] {% end %} fun log_f32 = "llvm.log.f32"(value : Float32) : Float32 {% if flag?(:interpreted) %} @[Primitive(:interpreter_libm_log_f64)] {% end %} fun log_f64 = "llvm.log.f64"(value : Float64) : Float64 {% if flag?(:interpreted) %} @[Primitive(:interpreter_libm_log2_f32)] {% end %} fun log2_f32 = "llvm.log2.f32"(value : Float32) : Float32 {% if flag?(:interpreted) %} @[Primitive(:interpreter_libm_log2_f64)] {% end %} fun log2_f64 = "llvm.log2.f64"(value : Float64) : Float64 {% if flag?(:interpreted) %} @[Primitive(:interpreter_libm_log10_f32)] {% end %} fun log10_f32 = "llvm.log10.f32"(value : Float32) : Float32 {% if flag?(:interpreted) %} @[Primitive(:interpreter_libm_log10_f64)] {% end %} fun log10_f64 = "llvm.log10.f64"(value : Float64) : Float64 {% if flag?(:interpreted) %} @[Primitive(:interpreter_libm_min_f32)] {% end %} fun min_f32 = "llvm.minnum.f32"(value1 : Float32, value2 : Float32) : Float32 {% if flag?(:interpreted) %} @[Primitive(:interpreter_libm_min_f64)] {% end %} fun min_f64 = "llvm.minnum.f64"(value1 : Float64, value2 : Float64) : Float64 {% if flag?(:interpreted) %} @[Primitive(:interpreter_libm_max_f32)] {% end %} fun max_f32 = "llvm.maxnum.f32"(value1 : Float32, value2 : Float32) : Float32 {% if flag?(:interpreted) %} @[Primitive(:interpreter_libm_max_f64)] {% end %} fun max_f64 = "llvm.maxnum.f64"(value1 : Float64, value2 : Float64) : Float64 {% if flag?(:interpreted) %} @[Primitive(:interpreter_libm_pow_f32)] {% end %} fun pow_f32 = "llvm.pow.f32"(value : Float32, power : Float32) : Float32 {% if flag?(:interpreted) %} @[Primitive(:interpreter_libm_pow_f64)] {% end %} fun pow_f64 = "llvm.pow.f64"(value : Float64, power : Float64) : Float64 {% if flag?(:win32) %} {% elsif flag?(:interpreted) %} @[Primitive(:interpreter_libm_powi_f32)] fun powi_f32 = "llvm.powi.f32"(value : Float32, power : Int32) : Float32 @[Primitive(:interpreter_libm_powi_f64)] fun powi_f64 = "llvm.powi.f64"(value : Float64, power : Int32) : Float64 {% elsif compare_versions(Crystal::LLVM_VERSION, "13.0.0") < 0 %} fun powi_f32 = "llvm.powi.f32"(value : Float32, power : Int32) : Float32 fun powi_f64 = "llvm.powi.f64"(value : Float64, power : Int32) : Float64 {% else %} fun powi_f32 = "llvm.powi.f32.i32"(value : Float32, power : Int32) : Float32 fun powi_f64 = "llvm.powi.f64.i32"(value : Float64, power : Int32) : Float64 {% end %} {% if flag?(:interpreted) %} @[Primitive(:interpreter_libm_round_f32)] {% end %} fun round_f32 = "llvm.round.f32"(value : Float32) : Float32 {% if flag?(:interpreted) %} @[Primitive(:interpreter_libm_round_f64)] {% end %} fun round_f64 = "llvm.round.f64"(value : Float64) : Float64 {% if flag?(:interpreted) %} @[Primitive(:interpreter_libm_rint_f32)] {% end %} fun rint_f32 = "llvm.rint.f32"(value : Float32) : Float32 {% if flag?(:interpreted) %} @[Primitive(:interpreter_libm_rint_f64)] {% end %} fun rint_f64 = "llvm.rint.f64"(value : Float64) : Float64 {% if flag?(:interpreted) %} @[Primitive(:interpreter_libm_sin_f32)] {% end %} fun sin_f32 = "llvm.sin.f32"(value : Float32) : Float32 {% if flag?(:interpreted) %} @[Primitive(:interpreter_libm_sin_f64)] {% end %} fun sin_f64 = "llvm.sin.f64"(value : Float64) : Float64 {% if flag?(:interpreted) %} @[Primitive(:interpreter_libm_sqrt_f32)] {% end %} fun sqrt_f32 = "llvm.sqrt.f32"(value : Float32) : Float32 {% if flag?(:interpreted) %} @[Primitive(:interpreter_libm_sqrt_f64)] {% end %} fun sqrt_f64 = "llvm.sqrt.f64"(value : Float64) : Float64 {% if flag?(:interpreted) %} @[Primitive(:interpreter_libm_trunc_f32)] {% end %} fun trunc_f32 = "llvm.trunc.f32"(value : Float32) : Float32 {% if flag?(:interpreted) %} @[Primitive(:interpreter_libm_trunc_f64)] {% end %} fun trunc_f64 = "llvm.trunc.f64"(value : Float64) : Float64 # libm functions fun acos_f32 = acosf(value : Float32) : Float32 fun acos_f64 = acos(value : Float64) : Float64 fun acosh_f32 = acoshf(value : Float32) : Float32 fun acosh_f64 = acosh(value : Float64) : Float64 fun asin_f32 = asinf(value : Float32) : Float32 fun asin_f64 = asin(value : Float64) : Float64 fun asinh_f32 = asinhf(value : Float32) : Float32 fun asinh_f64 = asinh(value : Float64) : Float64 fun atan2_f32 = atan2f(value1 : Float32, value2 : Float32) : Float32 fun atan2_f64 = atan2(value1 : Float64, value2 : Float64) : Float64 fun atan_f32 = atanf(value : Float32) : Float32 fun atan_f64 = atan(value : Float64) : Float64 fun atanh_f32 = atanhf(value : Float32) : Float32 fun atanh_f64 = atanh(value : Float64) : Float64 {% if flag?(:win32) %} fun besselj0_f64 = _j0(value : Float64) : Float64 fun besselj1_f64 = _j1(value : Float64) : Float64 fun besselj_f64 = _jn(value1 : Int32, value2 : Float64) : Float64 fun bessely0_f64 = _y0(value : Float64) : Float64 fun bessely1_f64 = _y1(value : Float64) : Float64 fun bessely_f64 = _yn(value1 : Int32, value2 : Float64) : Float64 {% else %} fun besselj0_f32 = j0f(value : Float32) : Float32 fun besselj0_f64 = j0(value : Float64) : Float64 fun besselj1_f32 = j1f(value : Float32) : Float32 fun besselj1_f64 = j1(value : Float64) : Float64 fun besselj_f32 = jnf(value1 : Int32, value2 : Float32) : Float32 fun besselj_f64 = jn(value1 : Int32, value2 : Float64) : Float64 fun bessely0_f32 = y0f(value : Float32) : Float32 fun bessely0_f64 = y0(value : Float64) : Float64 fun bessely1_f32 = y1f(value : Float32) : Float32 fun bessely1_f64 = y1(value : Float64) : Float64 fun bessely_f32 = ynf(value1 : Int32, value2 : Float32) : Float32 fun bessely_f64 = yn(value1 : Int32, value2 : Float64) : Float64 {% end %} fun cbrt_f32 = cbrtf(value : Float32) : Float32 fun cbrt_f64 = cbrt(value : Float64) : Float64 fun cosh_f32 = coshf(value : Float32) : Float32 fun cosh_f64 = cosh(value : Float64) : Float64 fun erfc_f32 = erfcf(value : Float32) : Float32 fun erfc_f64 = erfc(value : Float64) : Float64 fun erf_f32 = erff(value : Float32) : Float32 fun erf_f64 = erf(value : Float64) : Float64 fun expm1_f32 = expm1f(value : Float32) : Float32 fun expm1_f64 = expm1(value : Float64) : Float64 {% unless flag?(:win32) %} fun frexp_f32 = frexpf(value : Float32, exp : Int32*) : Float32 {% end %} fun frexp_f64 = frexp(value : Float64, exp : Int32*) : Float64 fun gamma_f32 = lgammaf(value : Float32) : Float32 fun gamma_f64 = lgamma(value : Float64) : Float64 {% if flag?(:win32) %} fun hypot_f32 = _hypotf(value1 : Float32, value2 : Float32) : Float32 {% else %} fun hypot_f32 = hypotf(value1 : Float32, value2 : Float32) : Float32 {% end %} fun hypot_f64 = hypot(value1 : Float64, value2 : Float64) : Float64 fun ilogb_f32 = ilogbf(value : Float32) : Int32 fun ilogb_f64 = ilogb(value : Float64) : Int32 {% unless flag?(:win32) %} fun ldexp_f32 = ldexpf(value1 : Float32, value2 : Int32) : Float32 {% end %} fun ldexp_f64 = ldexp(value1 : Float64, value2 : Int32) : Float64 fun log1p_f32 = log1pf(value : Float32) : Float32 fun log1p_f64 = log1p(value : Float64) : Float64 fun logb_f32 = logbf(value : Float32) : Float32 fun logb_f64 = logb(value : Float64) : Float64 fun nextafter_f32 = nextafterf(from : Float32, to : Float32) : Float32 fun nextafter_f64 = nextafter(from : Float64, to : Float64) : Float64 fun scalbln_f32 = scalblnf(value1 : Float32, value2 : Int64) : Float32 fun scalbln_f64 = scalbln(value1 : Float64, value2 : Int64) : Float64 fun scalbn_f32 = scalbnf(value1 : Float32, value2 : Int32) : Float32 fun scalbn_f64 = scalbn(value1 : Float64, value2 : Int32) : Float64 fun sinh_f32 = sinhf(value : Float32) : Float32 fun sinh_f64 = sinh(value : Float64) : Float64 fun tan_f32 = tanf(value : Float32) : Float32 fun tan_f64 = tan(value : Float64) : Float64 fun tanh_f32 = tanhf(value : Float32) : Float32 fun tanh_f64 = tanh(value : Float64) : Float64 fun tgamma_f32 = tgammaf(value : Float32) : Float32 fun tgamma_f64 = tgamma(value : Float64) : Float64 end