Skip to content

Remove most floating-point/integer intrinsics from the compiler #5724

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

Closed
Closed
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
8 changes: 5 additions & 3 deletions src/libcore/num/f32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use num::NumCast;
use num::strconv;
use num;
use option::Option;
use unstable::intrinsics::floorf32;
use unstable::intrinsics;
use from_str;
use to_str;

Expand Down Expand Up @@ -93,7 +93,6 @@ delegate!(fn ldexp_radix(n: c_float, i: c_int) -> c_float =
cmath::c_float_utils::ldexp_radix)
delegate!(fn sin(n: c_float) -> c_float = cmath::c_float_utils::sin)
delegate!(fn sinh(n: c_float) -> c_float = cmath::c_float_utils::sinh)
delegate!(fn sqrt(n: c_float) -> c_float = cmath::c_float_utils::sqrt)
delegate!(fn tan(n: c_float) -> c_float = cmath::c_float_utils::tan)
delegate!(fn tanh(n: c_float) -> c_float = cmath::c_float_utils::tanh)
delegate!(fn tgamma(n: c_float) -> c_float = cmath::c_float_utils::tgamma)
Expand Down Expand Up @@ -146,7 +145,10 @@ pub fn gt(x: f32, y: f32) -> bool { return x > y; }

/// Returns `x` rounded down
#[inline(always)]
pub fn floor(x: f32) -> f32 { unsafe { floorf32(x) } }
pub fn floor(x: f32) -> f32 { unsafe { intrinsics::llvm::floorf32(x) } }

#[inline(always)]
pub fn sqrt(x: f32) -> f32 { unsafe { intrinsics::llvm::sqrtf32(x) } }

// FIXME (#1999): replace the predicates below with llvm intrinsics or
// calls to the libmath macros in the rust runtime for performance.
Expand Down
8 changes: 5 additions & 3 deletions src/libcore/num/f64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use num::NumCast;
use num::strconv;
use num;
use option::Option;
use unstable::intrinsics::floorf64;
use unstable::intrinsics;
use to_str;
use from_str;

Expand Down Expand Up @@ -94,7 +94,6 @@ delegate!(fn ldexp_radix(n: c_double, i: c_int) -> c_double =
cmath::c_double_utils::ldexp_radix)
delegate!(fn sin(n: c_double) -> c_double = cmath::c_double_utils::sin)
delegate!(fn sinh(n: c_double) -> c_double = cmath::c_double_utils::sinh)
delegate!(fn sqrt(n: c_double) -> c_double = cmath::c_double_utils::sqrt)
delegate!(fn tan(n: c_double) -> c_double = cmath::c_double_utils::tan)
delegate!(fn tanh(n: c_double) -> c_double = cmath::c_double_utils::tanh)
delegate!(fn tgamma(n: c_double) -> c_double = cmath::c_double_utils::tgamma)
Expand Down Expand Up @@ -221,7 +220,10 @@ pub fn is_finite(x: f64) -> bool {

/// Returns `x` rounded down
#[inline(always)]
pub fn floor(x: f64) -> f64 { unsafe { floorf64(x) } }
pub fn floor(x: f64) -> f64 { unsafe { intrinsics::llvm::floorf64(x) } }

#[inline(always)]
pub fn sqrt(x: f64) -> f64 { unsafe { intrinsics::llvm::sqrtf64(x) } }

// FIXME (#1999): add is_normal, is_subnormal, and fpclassify

Expand Down
172 changes: 158 additions & 14 deletions src/libcore/unstable/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,69 +63,213 @@ pub extern "rust-intrinsic" {

pub fn memmove32(dst: *mut u8, src: *u8, size: u32);
pub fn memmove64(dst: *mut u8, src: *u8, size: u64);
}

#[nolink]
pub extern mod llvm {
#[rust_stack]
#[inline(always)]
#[link_name="llvm.sqrt.f32"]
pub fn sqrtf32(x: f32) -> f32;

#[rust_stack]
#[inline(always)]
#[link_name="llvm.sqrt.f64"]
pub fn sqrtf64(x: f64) -> f64;

#[rust_stack]
#[inline(always)]
#[link_name="llvm.powi.f32"]
pub fn powif32(a: f32, x: i32) -> f32;

#[rust_stack]
#[inline(always)]
#[link_name="llvm.powi.f64"]
pub fn powif64(a: f64, x: i32) -> f64;

#[rust_stack]
#[inline(always)]
#[link_name="llvm.sin.f32"]
pub fn sinf32(x: f32) -> f32;

#[rust_stack]
#[inline(always)]
#[link_name="llvm.sin.f64"]
pub fn sinf64(x: f64) -> f64;

#[rust_stack]
#[inline(always)]
#[link_name="llvm.cos.f32"]
pub fn cosf32(x: f32) -> f32;

#[rust_stack]
#[inline(always)]
#[link_name="llvm.cos.f64"]
pub fn cosf64(x: f64) -> f64;

#[rust_stack]
#[inline(always)]
#[link_name="llvm.pow.f32"]
pub fn powf32(a: f32, x: f32) -> f32;

#[rust_stack]
#[inline(always)]
#[link_name="llvm.pow.f64"]
pub fn powf64(a: f64, x: f64) -> f64;

#[rust_stack]
#[inline(always)]
#[link_name="llvm.exp.f32"]
pub fn expf32(x: f32) -> f32;
pub fn expf64(x: f64) -> f64;

pub fn exp2f32(x: f32) -> f32;
pub fn exp2f64(x: f64) -> f64;
#[rust_stack]
#[inline(always)]
#[link_name="llvm.exp.f64"]
pub fn expf64(x: f64) -> f64;

#[rust_stack]
#[inline(always)]
#[link_name="llvm.log.f32"]
pub fn logf32(x: f32) -> f32;

#[rust_stack]
#[inline(always)]
#[link_name="llvm.log.f64"]
pub fn logf64(x: f64) -> f64;

/* NOTE: Do these intrinsics even exist?
pub fn exp2f32(x: f32) -> f32;
pub fn exp2f64(x: f64) -> f64;

pub fn log10f32(x: f32) -> f32;
pub fn log10f64(x: f64) -> f64;

pub fn log2f32(x: f32) -> f32;
pub fn log2f64(x: f64) -> f64;
*/

#[rust_stack]
#[inline(always)]
#[link_name="llvm.fma.f32"]
pub fn fmaf32(a: f32, b: f32, c: f32) -> f32;

#[rust_stack]
#[inline(always)]
#[link_name="llvm.fma.f64"]
pub fn fmaf64(a: f64, b: f64, c: f64) -> f64;

#[rust_stack]
#[inline(always)]
#[link_name="llvm.fabs.f32"]
pub fn fabsf32(x: f32) -> f32;

#[rust_stack]
#[inline(always)]
#[link_name="llvm.fabs.f64"]
pub fn fabsf64(x: f64) -> f64;

#[rust_stack]
#[inline(always)]
#[link_name="llvm.floor.f32"]
pub fn floorf32(x: f32) -> f32;

#[rust_stack]
#[inline(always)]
#[link_name="llvm.floor.f64"]
pub fn floorf64(x: f64) -> f64;

/* NOTE: Needs LLVM 3.3
#[rust_stack]
#[link_name="llvm.ceil.f32"]
pub fn ceilf32(x: f32) -> f32;

#[rust_stack]
#[link_name="llvm.ceil.f64"]
pub fn ceilf64(x: f64) -> f64;

#[rust_stack]
#[link_name="llvm.trunc.f32"]
pub fn truncf32(x: f32) -> f32;

#[rust_stack]
#[link_name="llvm.trunc.f64"]
pub fn truncf64(x: f64) -> f64;
*/

#[rust_stack]
#[inline(always)]
#[link_name="llvm.ctpop.i8"]
pub fn ctpop8(x: i8) -> i8;

#[rust_stack]
#[inline(always)]
#[link_name="llvm.ctpop.i16"]
pub fn ctpop16(x: i16) -> i16;
pub fn ctpop32(x: i32) -> i32;
pub fn ctpop64(x: i64) -> i64;

pub fn ctlz8(x: i8) -> i8;
pub fn ctlz16(x: i16) -> i16;
pub fn ctlz32(x: i32) -> i32;
pub fn ctlz64(x: i64) -> i64;
#[rust_stack]
#[inline(always)]
#[link_name="llvm.ctpop.i32"]
pub fn ctpop32(x: i32) -> i32;

pub fn cttz8(x: i8) -> i8;
pub fn cttz16(x: i16) -> i16;
pub fn cttz32(x: i32) -> i32;
pub fn cttz64(x: i64) -> i64;
#[rust_stack]
#[inline(always)]
#[link_name="llvm.ctpop.i64"]
pub fn ctpop64(x: i64) -> i64;

/* NOTE: Needs i1 constants
#[rust_stack]
#[inline(always)]
#[link_name="llvm.ctlz.i8"]
pub fn ctlz8(x: i8, is_zero_undef: bool) -> i8;

#[rust_stack]
#[inline(always)]
#[link_name="llvm.ctlz.i16"]
pub fn ctlz16(x: i16, is_zero_undef: bool) -> i16;

#[rust_stack]
#[inline(always)]
#[link_name="llvm.ctlz.i32"]
pub fn ctlz32(x: i32, is_zero_undef: bool) -> i32;

#[rust_stack]
#[inline(always)]
#[link_name="llvm.ctlz.i64"]
pub fn ctlz64(x: i64, is_zero_undef: bool) -> i64;

#[rust_stack]
#[inline(always)]
#[link_name="llvm.cttz.i8"]
pub fn cttz8(x: i8, is_zero_undef: bool) -> i8;

#[rust_stack]
#[inline(always)]
#[link_name="llvm.cttz.i16"]
pub fn cttz16(x: i16, is_zero_undef: bool) -> i16;

#[rust_stack]
#[inline(always)]
#[link_name="llvm.cttz.i32"]
pub fn cttz32(x: i32, is_zero_undef: bool) -> i32;

#[rust_stack]
#[inline(always)]
#[link_name="llvm.cttz.i64"]
pub fn cttz64(x: i64, is_zero_undef: bool) -> i64;
*/

#[rust_stack]
#[inline(always)]
#[link_name="llvm.bswap.i16"]
pub fn bswap16(x: i16) -> i16;

#[rust_stack]
#[inline(always)]
#[link_name="llvm.bswap.i32"]
pub fn bswap32(x: i32) -> i32;

#[rust_stack]
#[inline(always)]
#[link_name="llvm.bswap.i64"]
pub fn bswap64(x: i64) -> i64;
}

Loading