Skip to content
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