let frameaddress = decl_cdecl_fn(llmod, ~"llvm.frameaddress",
T_fn(T_frameaddress_args,
T_ptr(T_i8())));
+ let sqrtf32 = decl_cdecl_fn(llmod, ~"llvm.sqrt.f32",
+ T_fn(~[T_f32()], T_f32()));
+ let sqrtf64 = decl_cdecl_fn(llmod, ~"llvm.sqrt.f64",
+ T_fn(~[T_f64()], T_f64()));
+ let powif32 = decl_cdecl_fn(llmod, ~"llvm.powi.f32",
+ T_fn(~[T_f32(), T_i32()], T_f32()));
+ let powif64 = decl_cdecl_fn(llmod, ~"llvm.powi.f64",
+ T_fn(~[T_f64(), T_i32()], T_f64()));
+ let sinf32 = decl_cdecl_fn(llmod, ~"llvm.sin.f32",
+ T_fn(~[T_f32()], T_f32()));
+ let sinf64 = decl_cdecl_fn(llmod, ~"llvm.sin.f64",
+ T_fn(~[T_f64()], T_f64()));
+ let cosf32 = decl_cdecl_fn(llmod, ~"llvm.cos.f32",
+ T_fn(~[T_f32()], T_f32()));
+ let cosf64 = decl_cdecl_fn(llmod, ~"llvm.cos.f64",
+ T_fn(~[T_f64()], T_f64()));
+ let powf32 = decl_cdecl_fn(llmod, ~"llvm.pow.f32",
+ T_fn(~[T_f32(), T_f32()], T_f32()));
+ let powf64 = decl_cdecl_fn(llmod, ~"llvm.pow.f64",
+ T_fn(~[T_f64(), T_f64()], T_f64()));
+ let expf32 = decl_cdecl_fn(llmod, ~"llvm.exp.f32",
+ T_fn(~[T_f32()], T_f32()));
+ let expf64 = decl_cdecl_fn(llmod, ~"llvm.exp.f64",
+ T_fn(~[T_f64()], T_f64()));
+ let exp2f32 = decl_cdecl_fn(llmod, ~"llvm.exp2.f32",
+ T_fn(~[T_f32()], T_f32()));
+ let exp2f64 = decl_cdecl_fn(llmod, ~"llvm.exp2.f64",
+ T_fn(~[T_f64()], T_f64()));
+ let logf32 = decl_cdecl_fn(llmod, ~"llvm.log.f32",
+ T_fn(~[T_f32()], T_f32()));
+ let logf64 = decl_cdecl_fn(llmod, ~"llvm.log.f64",
+ T_fn(~[T_f64()], T_f64()));
+ let log10f32 = decl_cdecl_fn(llmod, ~"llvm.log10.f32",
+ T_fn(~[T_f32()], T_f32()));
+ let log10f64 = decl_cdecl_fn(llmod, ~"llvm.log10.f64",
+ T_fn(~[T_f64()], T_f64()));
+ let log2f32 = decl_cdecl_fn(llmod, ~"llvm.log2.f32",
+ T_fn(~[T_f32()], T_f32()));
+ let log2f64 = decl_cdecl_fn(llmod, ~"llvm.log2.f64",
+ T_fn(~[T_f64()], T_f64()));
+ let fmaf32 = decl_cdecl_fn(llmod, ~"llvm.fma.f32",
+ T_fn(~[T_f32(), T_f32(), T_f32()], T_f32()));
+ let fmaf64 = decl_cdecl_fn(llmod, ~"llvm.fma.f64",
+ T_fn(~[T_f64(), T_f64(), T_f64()], T_f64()));
+ let fabsf32 = decl_cdecl_fn(llmod, ~"llvm.fabs.f32",
+ T_fn(~[T_f32()], T_f32()));
+ let fabsf64 = decl_cdecl_fn(llmod, ~"llvm.fabs.f64",
+ T_fn(~[T_f64()], T_f64()));
+ let floorf32 = decl_cdecl_fn(llmod, ~"llvm.floor.f32",
+ T_fn(~[T_f32()], T_f32()));
+ let floorf64 = decl_cdecl_fn(llmod, ~"llvm.floor.f64",
+ T_fn(~[T_f64()], T_f64()));
+ let ceilf32 = decl_cdecl_fn(llmod, ~"llvm.ceil.f32",
+ T_fn(~[T_f32()], T_f32()));
+ let ceilf64 = decl_cdecl_fn(llmod, ~"llvm.ceil.f64",
+ T_fn(~[T_f64()], T_f64()));
+ let truncf32 = decl_cdecl_fn(llmod, ~"llvm.trunc.f32",
+ T_fn(~[T_f32()], T_f32()));
+ let truncf64 = decl_cdecl_fn(llmod, ~"llvm.trunc.f64",
+ T_fn(~[T_f64()], T_f64()));
+
let intrinsics = HashMap();
intrinsics.insert(~"llvm.gcroot", gcroot);
intrinsics.insert(~"llvm.gcread", gcread);
intrinsics.insert(~"llvm.memset.p0i8.i64", memset64);
intrinsics.insert(~"llvm.trap", trap);
intrinsics.insert(~"llvm.frameaddress", frameaddress);
+ intrinsics.insert(~"llvm.sqrt.f32", sqrtf32);
+ intrinsics.insert(~"llvm.sqrt.f64", sqrtf64);
+ intrinsics.insert(~"llvm.powi.f32", powif32);
+ intrinsics.insert(~"llvm.powi.f64", powif64);
+ intrinsics.insert(~"llvm.sin.f32", sinf32);
+ intrinsics.insert(~"llvm.sin.f64", sinf64);
+ intrinsics.insert(~"llvm.cos.f32", cosf32);
+ intrinsics.insert(~"llvm.cos.f64", cosf64);
+ intrinsics.insert(~"llvm.pow.f32", powf32);
+ intrinsics.insert(~"llvm.pow.f64", powf64);
+ intrinsics.insert(~"llvm.exp.f32", expf32);
+ intrinsics.insert(~"llvm.exp.f64", expf64);
+ intrinsics.insert(~"llvm.exp2.f32", exp2f32);
+ intrinsics.insert(~"llvm.exp2.f64", exp2f64);
+ intrinsics.insert(~"llvm.log.f32", logf32);
+ intrinsics.insert(~"llvm.log.f64", logf64);
+ intrinsics.insert(~"llvm.log10.f32", log10f32);
+ intrinsics.insert(~"llvm.log10.f64", log10f64);
+ intrinsics.insert(~"llvm.log2.f32", log2f32);
+ intrinsics.insert(~"llvm.log2.f64", log2f64);
+ intrinsics.insert(~"llvm.fma.f32", fmaf32);
+ intrinsics.insert(~"llvm.fma.f64", fmaf64);
+ intrinsics.insert(~"llvm.fabs.f32", fabsf32);
+ intrinsics.insert(~"llvm.fabs.f64", fabsf64);
+ intrinsics.insert(~"llvm.floor.f32", floorf32);
+ intrinsics.insert(~"llvm.floor.f64", floorf64);
+ intrinsics.insert(~"llvm.ceil.f32", ceilf32);
+ intrinsics.insert(~"llvm.ceil.f64", ceilf64);
+ intrinsics.insert(~"llvm.trunc.f32", truncf32);
+ intrinsics.insert(~"llvm.trunc.f64", truncf64);
+
return intrinsics;
}
let llcast = PointerCast(bcx, llcast, T_ptr(T_i8()));
call_memcpy(bcx, llretptr, llcast, llsize_of(ccx, lltp_ty));
}
- }
+ }
~"addr_of" => {
Store(bcx, get_param(decl, first_real_arg), fcx.llretptr);
}
T_ptr(T_nil()));
Store(bcx, morestack_addr, fcx.llretptr);
}
+ ~"sqrtf32" => {
+ let x = get_param(decl, first_real_arg);
+ let sqrtf = ccx.intrinsics.get(~"llvm.sqrt.f32");
+ Store(bcx, Call(bcx, sqrtf, ~[x]), fcx.llretptr);
+ }
+ ~"sqrtf64" => {
+ let x = get_param(decl, first_real_arg);
+ let sqrtf = ccx.intrinsics.get(~"llvm.sqrt.f64");
+ Store(bcx, Call(bcx, sqrtf, ~[x]), fcx.llretptr);
+ }
+ ~"powif32" => {
+ let a = get_param(decl, first_real_arg);
+ let x = get_param(decl, first_real_arg + 1u);
+ let powif = ccx.intrinsics.get(~"llvm.powi.f32");
+ Store(bcx, Call(bcx, powif, ~[a, x]), fcx.llretptr);
+ }
+ ~"powif64" => {
+ let a = get_param(decl, first_real_arg);
+ let x = get_param(decl, first_real_arg + 1u);
+ let powif = ccx.intrinsics.get(~"llvm.powi.f64");
+ Store(bcx, Call(bcx, powif, ~[a, x]), fcx.llretptr);
+ }
+ ~"sinf32" => {
+ let x = get_param(decl, first_real_arg);
+ let sinf = ccx.intrinsics.get(~"llvm.sin.f32");
+ Store(bcx, Call(bcx, sinf, ~[x]), fcx.llretptr);
+ }
+ ~"sinf64" => {
+ let x = get_param(decl, first_real_arg);
+ let sinf = ccx.intrinsics.get(~"llvm.sin.f64");
+ Store(bcx, Call(bcx, sinf, ~[x]), fcx.llretptr);
+ }
+ ~"cosf32" => {
+ let x = get_param(decl, first_real_arg);
+ let cosf = ccx.intrinsics.get(~"llvm.cos.f32");
+ Store(bcx, Call(bcx, cosf, ~[x]), fcx.llretptr);
+ }
+ ~"cosf64" => {
+ let x = get_param(decl, first_real_arg);
+ let cosf = ccx.intrinsics.get(~"llvm.cos.f64");
+ Store(bcx, Call(bcx, cosf, ~[x]), fcx.llretptr);
+ }
+ ~"powf32" => {
+ let a = get_param(decl, first_real_arg);
+ let x = get_param(decl, first_real_arg + 1u);
+ let powf = ccx.intrinsics.get(~"llvm.pow.f32");
+ Store(bcx, Call(bcx, powf, ~[a, x]), fcx.llretptr);
+ }
+ ~"powf64" => {
+ let a = get_param(decl, first_real_arg);
+ let x = get_param(decl, first_real_arg + 1u);
+ let powf = ccx.intrinsics.get(~"llvm.pow.f64");
+ Store(bcx, Call(bcx, powf, ~[a, x]), fcx.llretptr);
+ }
+ ~"expf32" => {
+ let x = get_param(decl, first_real_arg);
+ let expf = ccx.intrinsics.get(~"llvm.exp.f32");
+ Store(bcx, Call(bcx, expf, ~[x]), fcx.llretptr);
+ }
+ ~"expf64" => {
+ let x = get_param(decl, first_real_arg);
+ let expf = ccx.intrinsics.get(~"llvm.exp.f64");
+ Store(bcx, Call(bcx, expf, ~[x]), fcx.llretptr);
+ }
+ ~"exp2f32" => {
+ let x = get_param(decl, first_real_arg);
+ let exp2f = ccx.intrinsics.get(~"llvm.exp2.f32");
+ Store(bcx, Call(bcx, exp2f, ~[x]), fcx.llretptr);
+ }
+ ~"exp2f64" => {
+ let x = get_param(decl, first_real_arg);
+ let exp2f = ccx.intrinsics.get(~"llvm.exp2.f64");
+ Store(bcx, Call(bcx, exp2f, ~[x]), fcx.llretptr);
+ }
+ ~"logf32" => {
+ let x = get_param(decl, first_real_arg);
+ let logf = ccx.intrinsics.get(~"llvm.log.f32");
+ Store(bcx, Call(bcx, logf, ~[x]), fcx.llretptr);
+ }
+ ~"logf64" => {
+ let x = get_param(decl, first_real_arg);
+ let logf = ccx.intrinsics.get(~"llvm.log.f64");
+ Store(bcx, Call(bcx, logf, ~[x]), fcx.llretptr);
+ }
+ ~"log10f32" => {
+ let x = get_param(decl, first_real_arg);
+ let log10f = ccx.intrinsics.get(~"llvm.log10.f32");
+ Store(bcx, Call(bcx, log10f, ~[x]), fcx.llretptr);
+ }
+ ~"log10f64" => {
+ let x = get_param(decl, first_real_arg);
+ let log10f = ccx.intrinsics.get(~"llvm.log10.f64");
+ Store(bcx, Call(bcx, log10f, ~[x]), fcx.llretptr);
+ }
+ ~"log2f32" => {
+ let x = get_param(decl, first_real_arg);
+ let log2f = ccx.intrinsics.get(~"llvm.log2.f32");
+ Store(bcx, Call(bcx, log2f, ~[x]), fcx.llretptr);
+ }
+ ~"log2f64" => {
+ let x = get_param(decl, first_real_arg);
+ let log2f = ccx.intrinsics.get(~"llvm.log2.f64");
+ Store(bcx, Call(bcx, log2f, ~[x]), fcx.llretptr);
+ }
+ ~"fmaf32" => {
+ let a = get_param(decl, first_real_arg);
+ let b = get_param(decl, first_real_arg + 1u);
+ let c = get_param(decl, first_real_arg + 2u);
+ let fmaf = ccx.intrinsics.get(~"llvm.fma.f32");
+ Store(bcx, Call(bcx, fmaf, ~[a, b, c]), fcx.llretptr);
+ }
+ ~"fmaf64" => {
+ let a = get_param(decl, first_real_arg);
+ let b = get_param(decl, first_real_arg + 1u);
+ let c = get_param(decl, first_real_arg + 2u);
+ let fmaf = ccx.intrinsics.get(~"llvm.fma.f64");
+ Store(bcx, Call(bcx, fmaf, ~[a, b, c]), fcx.llretptr);
+ }
+ ~"fabsf32" => {
+ let x = get_param(decl, first_real_arg);
+ let fabsf = ccx.intrinsics.get(~"llvm.fabs.f32");
+ Store(bcx, Call(bcx, fabsf, ~[x]), fcx.llretptr);
+ }
+ ~"fabsf64" => {
+ let x = get_param(decl, first_real_arg);
+ let fabsf = ccx.intrinsics.get(~"llvm.fabs.f64");
+ Store(bcx, Call(bcx, fabsf, ~[x]), fcx.llretptr);
+ }
+ ~"floorf32" => {
+ let x = get_param(decl, first_real_arg);
+ let floorf = ccx.intrinsics.get(~"llvm.floor.f32");
+ Store(bcx, Call(bcx, floorf, ~[x]), fcx.llretptr);
+ }
+ ~"floorf64" => {
+ let x = get_param(decl, first_real_arg);
+ let floorf = ccx.intrinsics.get(~"llvm.floor.f64");
+ Store(bcx, Call(bcx, floorf, ~[x]), fcx.llretptr);
+ }
+ ~"ceilf32" => {
+ let x = get_param(decl, first_real_arg);
+ let ceilf = ccx.intrinsics.get(~"llvm.ceil.f32");
+ Store(bcx, Call(bcx, ceilf, ~[x]), fcx.llretptr);
+ }
+ ~"ceilf64" => {
+ let x = get_param(decl, first_real_arg);
+ let ceilf = ccx.intrinsics.get(~"llvm.ceil.f64");
+ Store(bcx, Call(bcx, ceilf, ~[x]), fcx.llretptr);
+ }
+ ~"truncf32" => {
+ let x = get_param(decl, first_real_arg);
+ let truncf = ccx.intrinsics.get(~"llvm.trunc.f32");
+ Store(bcx, Call(bcx, truncf, ~[x]), fcx.llretptr);
+ }
+ ~"truncf64" => {
+ let x = get_param(decl, first_real_arg);
+ let truncf = ccx.intrinsics.get(~"llvm.trunc.f64");
+ Store(bcx, Call(bcx, truncf, ~[x]), fcx.llretptr);
+ }
_ => {
// Could we make this an enum rather than a string? does it get
// checked earlier?
~"visit_tydesc" | ~"forget" | ~"addr_of" |
~"frame_address" | ~"morestack_addr" => 0,
+ ~"sqrtf32" | ~"sqrtf64" | ~"powif32" | ~"powif64" |
+ ~"sinf32" | ~"sinf64" | ~"cosf32" | ~"cosf64" |
+ ~"powf32" | ~"powf64" | ~"expf32" | ~"expf64" |
+ ~"exp2f32" | ~"exp2f64" | ~"logf32" | ~"logf64" |
+ ~"log10f32"| ~"log10f64"| ~"log2f32" | ~"log2f64" |
+ ~"fmaf32" | ~"fmaf64" | ~"fabsf32" | ~"fabsf64" |
+ ~"floorf32"| ~"floorf64"| ~"ceilf32" | ~"ceilf64" |
+ ~"truncf32"| ~"truncf64" => 0,
+
// would be cool to make these an enum instead of strings!
_ => fail ~"unknown intrinsic in type_use"
};
~"morestack_addr" => {
(0u, ~[], ty::mk_nil_ptr(tcx))
}
+
+ ~"sqrtf32" => {
+ (0u, ~[arg(ast::by_copy, ty::mk_f32(tcx))],
+ ty::mk_f32(tcx))
+ }
+ ~"sqrtf64" => {
+ (0u, ~[arg(ast::by_copy, ty::mk_f64(tcx))],
+ ty::mk_f64(tcx))
+ }
+ ~"powif32" => {
+ (0u, ~[arg(ast::by_copy, ty::mk_f32(tcx)),
+ arg(ast::by_copy, ty::mk_i32(tcx))],
+ ty::mk_f32(tcx))
+ }
+ ~"powif64" => {
+ (0u, ~[arg(ast::by_copy, ty::mk_f64(tcx)),
+ arg(ast::by_copy, ty::mk_i32(tcx))],
+ ty::mk_f64(tcx))
+ }
+ ~"sinf32" => {
+ (0u, ~[arg(ast::by_copy, ty::mk_f32(tcx))],
+ ty::mk_f32(tcx))
+ }
+ ~"sinf64" => {
+ (0u, ~[arg(ast::by_copy, ty::mk_f64(tcx))],
+ ty::mk_f64(tcx))
+ }
+ ~"cosf32" => {
+ (0u, ~[arg(ast::by_copy, ty::mk_f32(tcx))],
+ ty::mk_f32(tcx))
+ }
+ ~"cosf64" => {
+ (0u, ~[arg(ast::by_copy, ty::mk_f64(tcx))],
+ ty::mk_f64(tcx))
+ }
+ ~"powf32" => {
+ (0u, ~[arg(ast::by_copy, ty::mk_f32(tcx)),
+ arg(ast::by_copy, ty::mk_f32(tcx))],
+ ty::mk_f32(tcx))
+ }
+ ~"powf64" => {
+ (0u, ~[arg(ast::by_copy, ty::mk_f64(tcx)),
+ arg(ast::by_copy, ty::mk_f64(tcx))],
+ ty::mk_f64(tcx))
+ }
+ ~"expf32" => {
+ (0u, ~[arg(ast::by_copy, ty::mk_f32(tcx))],
+ ty::mk_f32(tcx))
+ }
+ ~"expf64" => {
+ (0u, ~[arg(ast::by_copy, ty::mk_f64(tcx))],
+ ty::mk_f64(tcx))
+ }
+ ~"exp2f32" => {
+ (0u, ~[arg(ast::by_copy, ty::mk_f32(tcx))],
+ ty::mk_f32(tcx))
+ }
+ ~"exp2f64" => {
+ (0u, ~[arg(ast::by_copy, ty::mk_f64(tcx))],
+ ty::mk_f64(tcx))
+ }
+ ~"logf32" => {
+ (0u, ~[arg(ast::by_copy, ty::mk_f32(tcx))],
+ ty::mk_f32(tcx))
+ }
+ ~"logf64" => {
+ (0u, ~[arg(ast::by_copy, ty::mk_f64(tcx))],
+ ty::mk_f64(tcx))
+ }
+ ~"log10f32" => {
+ (0u, ~[arg(ast::by_copy, ty::mk_f32(tcx))],
+ ty::mk_f32(tcx))
+ }
+ ~"log10f64" => {
+ (0u, ~[arg(ast::by_copy, ty::mk_f64(tcx))],
+ ty::mk_f64(tcx))
+ }
+ ~"log2f32" => {
+ (0u, ~[arg(ast::by_copy, ty::mk_f32(tcx))],
+ ty::mk_f32(tcx))
+ }
+ ~"log2f64" => {
+ (0u, ~[arg(ast::by_copy, ty::mk_f64(tcx))],
+ ty::mk_f64(tcx))
+ }
+ ~"fmaf32" => {
+ (0u, ~[arg(ast::by_copy, ty::mk_f32(tcx)),
+ arg(ast::by_copy, ty::mk_f32(tcx)),
+ arg(ast::by_copy, ty::mk_f32(tcx))],
+ ty::mk_f32(tcx))
+ }
+ ~"fmaf64" => {
+ (0u, ~[arg(ast::by_copy, ty::mk_f64(tcx)),
+ arg(ast::by_copy, ty::mk_f64(tcx)),
+ arg(ast::by_copy, ty::mk_f64(tcx))],
+ ty::mk_f64(tcx))
+ }
+ ~"fabsf32" => {
+ (0u, ~[arg(ast::by_copy, ty::mk_f32(tcx))],
+ ty::mk_f32(tcx))
+ }
+ ~"fabsf64" => {
+ (0u, ~[arg(ast::by_copy, ty::mk_f64(tcx))],
+ ty::mk_f64(tcx))
+ }
+ ~"floorf32" => {
+ (0u, ~[arg(ast::by_copy, ty::mk_f32(tcx))],
+ ty::mk_f32(tcx))
+ }
+ ~"floorf64" => {
+ (0u, ~[arg(ast::by_copy, ty::mk_f64(tcx))],
+ ty::mk_f64(tcx))
+ }
+ ~"ceilf32" => {
+ (0u, ~[arg(ast::by_copy, ty::mk_f32(tcx))],
+ ty::mk_f32(tcx))
+ }
+ ~"ceilf64" => {
+ (0u, ~[arg(ast::by_copy, ty::mk_f64(tcx))],
+ ty::mk_f64(tcx))
+ }
+ ~"truncf32" => {
+ (0u, ~[arg(ast::by_copy, ty::mk_f32(tcx))],
+ ty::mk_f32(tcx))
+ }
+ ~"truncf64" => {
+ (0u, ~[arg(ast::by_copy, ty::mk_f64(tcx))],
+ ty::mk_f64(tcx))
+ }
+
other => {
tcx.sess.span_err(it.span, ~"unrecognized intrinsic function: `" +
other + ~"`");
--- /dev/null
+#[abi = "rust-intrinsic"]
+extern mod rusti {
+ fn sqrtf32(x: f32) -> f32;
+ fn sqrtf64(x: f64) -> f64;
+ fn powif32(a: f32, x: i32) -> f32;
+ fn powif64(a: f64, x: i32) -> f64;
+ fn sinf32(x: f32) -> f32;
+ fn sinf64(x: f64) -> f64;
+ fn cosf32(x: f32) -> f32;
+ fn cosf64(x: f64) -> f64;
+ fn powf32(a: f32, x: f32) -> f32;
+ fn powf64(a: f64, x: f64) -> f64;
+ fn expf32(x: f32) -> f32;
+ fn expf64(x: f64) -> f64;
+ fn exp2f32(x: f32) -> f32;
+ fn exp2f64(x: f64) -> f64;
+ fn logf32(x: f32) -> f32;
+ fn logf64(x: f64) -> f64;
+ fn log10f32(x: f32) -> f32;
+ fn log10f64(x: f64) -> f64;
+ fn log2f32(x: f32) -> f32;
+ fn log2f64(x: f64) -> f64;
+ fn fmaf32(a: f32, b: f32, c: f32) -> f32;
+ fn fmaf64(a: f64, b: f64, c: f64) -> f64;
+ fn fabsf32(x: f32) -> f32;
+ fn fabsf64(x: f64) -> f64;
+ fn floorf32(x: f32) -> f32;
+ fn floorf64(x: f64) -> f64;
+ fn ceilf32(x: f32) -> f32;
+ fn ceilf64(x: f64) -> f64;
+ fn truncf32(x: f32) -> f32;
+ fn truncf64(x: f64) -> f64;
+}
+
+fn main() {
+
+ use rusti::*;
+
+ assert(sqrtf32(64f32) == 8f32);
+ assert(sqrtf64(64f64) == 8f64);
+
+ assert(powif32(25f32, -2i32) == 0.0016f32);
+ assert(powif64(23.2f64, 2i32) == 538.24f64);
+
+ assert(sinf32(0f32) == 0f32);
+ assert(sinf64(f64::consts::pi / 2f64) == 1f64);
+
+ assert(cosf32(0f32) == 1f32);
+ assert(cosf64(f64::consts::pi * 2f64) == 1f64);
+
+ assert(powf32(25f32, -2f32) == 0.0016f32);
+ assert(powf64(400f64, 0.5f64) == 20f64);
+
+ assert(expf32(1f32) == f32::consts::e);
+ assert(expf64(1f64) == f64::consts::e);
+
+ assert(exp2f32(10f32) == 1024f32);
+ assert(exp2f64(50f64) == 1125899906842624f64);
+
+ assert(logf32(f32::consts::e) == 1f32);
+ assert(logf64(1f64) == 0f64);
+
+ assert(log10f32(10f32) == 1f32);
+ assert(log10f64(f64::consts::e) == f64::consts::log10_e);
+
+ assert(log2f32(8f32) == 3f32);
+ assert(log2f64(f64::consts::e) == f64::consts::log2_e);
+
+ assert(fmaf32(1.0f32, 2.0f32, 5.0f32) == 7.0f32);
+ assert(fmaf64(0.0f64, -2.0f64, f64::consts::e) == f64::consts::e);
+
+ assert(fabsf32(-1.0f32) == 1.0f32);
+ assert(fabsf64(34.2f64) == 34.2f64);
+
+ assert(floorf32(3.8f32) == 3.0f32);
+ assert(floorf64(-1.1f64) == -2.0f64);
+
+ // Causes linker error
+ // undefined reference to llvm.ceil.f32/64
+ //assert(ceilf32(-2.3f32) == -2.0f32);
+ //assert(ceilf64(3.8f64) == 4.0f64);
+
+ // Causes linker error
+ // undefined reference to llvm.trunc.f32/64
+ //assert(truncf32(0.1f32) == 0.0f32);
+ //assert(truncf64(-0.1f64) == 0.0f64);
+
+}