Skip to content

Add more standard c lib llvm intrinsics. #4067

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 5, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 92 additions & 0 deletions src/librustc/middle/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2369,6 +2369,67 @@ fn declare_intrinsics(llmod: ModuleRef) -> HashMap<~str, ValueRef> {
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);
Expand All @@ -2378,6 +2439,37 @@ fn declare_intrinsics(llmod: ModuleRef) -> HashMap<~str, ValueRef> {
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;
}

Expand Down
160 changes: 159 additions & 1 deletion src/librustc/middle/trans/foreign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -973,7 +973,7 @@ fn trans_intrinsic(ccx: @crate_ctxt, decl: ValueRef, item: @ast::foreign_item,
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);
}
Expand Down Expand Up @@ -1024,6 +1024,164 @@ fn trans_intrinsic(ccx: @crate_ctxt, decl: ValueRef, item: @ast::foreign_item,
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?
Expand Down
9 changes: 9 additions & 0 deletions src/librustc/middle/trans/type_use.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,15 @@ fn type_uses_for(ccx: @crate_ctxt, fn_id: def_id, n_tps: uint)
~"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"
};
Expand Down
Loading