Skip to content

Commit e4d7cd7

Browse files
committed
Make floating point intrinsics generic
1 parent 708e319 commit e4d7cd7

File tree

11 files changed

+612
-152
lines changed

11 files changed

+612
-152
lines changed

src/libcore/intrinsics.rs

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,101 +414,198 @@ extern "rust-intrinsic" {
414414
pub fn volatile_store<T>(dst: *mut T, val: T);
415415

416416
/// Returns the square root of an `f32`
417+
#[cfg(stage0)]
417418
pub fn sqrtf32(x: f32) -> f32;
418419
/// Returns the square root of an `f64`
420+
#[cfg(stage0)]
419421
pub fn sqrtf64(x: f64) -> f64;
422+
/// Returns the square root of a floating point type `T`.
423+
#[cfg(not(stage0))]
424+
pub fn sqrt<T>(x: T) -> T;
420425

421426
/// Raises an `f32` to an integer power.
427+
#[cfg(stage0)]
422428
pub fn powif32(a: f32, x: i32) -> f32;
423429
/// Raises an `f64` to an integer power.
430+
#[cfg(stage0)]
424431
pub fn powif64(a: f64, x: i32) -> f64;
432+
/// Raises a floating point to an integer power.
433+
#[cfg(not(stage0))]
434+
pub fn powi<T>(a: T, x: i32) -> T;
425435

426436
/// Returns the sine of an `f32`.
437+
#[cfg(stage0)]
427438
pub fn sinf32(x: f32) -> f32;
428439
/// Returns the sine of an `f64`.
440+
#[cfg(stage0)]
429441
pub fn sinf64(x: f64) -> f64;
442+
/// Returns the sine of a floating point type `T`.
443+
#[cfg(not(stage0))]
444+
pub fn sin<T>(x: T) -> T;
430445

431446
/// Returns the cosine of an `f32`.
447+
#[cfg(stage0)]
432448
pub fn cosf32(x: f32) -> f32;
433449
/// Returns the cosine of an `f64`.
450+
#[cfg(stage0)]
434451
pub fn cosf64(x: f64) -> f64;
452+
/// Returns the cosine of a floating point type `T`.
453+
#[cfg(not(stage0))]
454+
pub fn cos<T>(x: T) -> T;
435455

436456
/// Raises an `f32` to an `f32` power.
457+
#[cfg(stage0)]
437458
pub fn powf32(a: f32, x: f32) -> f32;
438459
/// Raises an `f64` to an `f64` power.
460+
#[cfg(stage0)]
439461
pub fn powf64(a: f64, x: f64) -> f64;
462+
/// Raises floating point of type `T` to a floating point of type `T` power.
463+
#[cfg(not(stage0))]
464+
pub fn pow<T>(a: T, x: T) -> T;
440465

441466
/// Returns the exponential of an `f32`.
467+
#[cfg(stage0)]
442468
pub fn expf32(x: f32) -> f32;
443469
/// Returns the exponential of an `f64`.
470+
#[cfg(stage0)]
444471
pub fn expf64(x: f64) -> f64;
472+
/// Returns the exponential of a foating point of type `T`.
473+
#[cfg(not(stage0))]
474+
pub fn exp<T>(x: T) -> T;
445475

446476
/// Returns 2 raised to the power of an `f32`.
477+
#[cfg(stage0)]
447478
pub fn exp2f32(x: f32) -> f32;
448479
/// Returns 2 raised to the power of an `f64`.
480+
#[cfg(stage0)]
449481
pub fn exp2f64(x: f64) -> f64;
482+
/// Returns 2 raised to the power of a floating point of type `T`.
483+
#[cfg(not(stage0))]
484+
pub fn exp2<T>(x: T) -> T;
450485

451486
/// Returns the natural logarithm of an `f32`.
487+
#[cfg(stage0)]
452488
pub fn logf32(x: f32) -> f32;
453489
/// Returns the natural logarithm of an `f64`.
490+
#[cfg(stage0)]
454491
pub fn logf64(x: f64) -> f64;
492+
/// Returns the natural logarithm of a floating point of type `T`.
493+
#[cfg(not(stage0))]
494+
pub fn log<T>(x: T) -> T;
455495

456496
/// Returns the base 10 logarithm of an `f32`.
497+
#[cfg(stage0)]
457498
pub fn log10f32(x: f32) -> f32;
458499
/// Returns the base 10 logarithm of an `f64`.
500+
#[cfg(stage0)]
459501
pub fn log10f64(x: f64) -> f64;
502+
/// Returns the base 10 logarithm of a foating point of type `T`.
503+
#[cfg(not(stage0))]
504+
pub fn log10<T>(x: T) -> T;
460505

461506
/// Returns the base 2 logarithm of an `f32`.
507+
#[cfg(stage0)]
462508
pub fn log2f32(x: f32) -> f32;
463509
/// Returns the base 2 logarithm of an `f64`.
510+
#[cfg(stage0)]
464511
pub fn log2f64(x: f64) -> f64;
512+
/// Returns the base 2 logarithm of a floating point of type `T`.
513+
#[cfg(not(stage0))]
514+
pub fn log2<T>(x: T) -> T;
465515

466516
/// Returns `a * b + c` for `f32` values.
517+
#[cfg(stage0)]
467518
pub fn fmaf32(a: f32, b: f32, c: f32) -> f32;
468519
/// Returns `a * b + c` for `f64` values.
520+
#[cfg(stage0)]
469521
pub fn fmaf64(a: f64, b: f64, c: f64) -> f64;
522+
/// Returns `a * b + c` for floating point of type `T` values.
523+
#[cfg(not(stage0))]
524+
pub fn fma<T>(a: T, b: T, c: T) -> T;
470525

471526
/// Returns the absolute value of an `f32`.
527+
#[cfg(stage0)]
472528
pub fn fabsf32(x: f32) -> f32;
473529
/// Returns the absolute value of an `f64`.
530+
#[cfg(stage0)]
474531
pub fn fabsf64(x: f64) -> f64;
532+
/// Returns the absolute value of a floating point of type `T`.
533+
#[cfg(not(stage0))]
534+
pub fn fabs<T>(x: T) -> T;
475535

476536
/// Copies the sign from `y` to `x` for `f32` values.
537+
#[cfg(stage0)]
477538
pub fn copysignf32(x: f32, y: f32) -> f32;
478539
/// Copies the sign from `y` to `x` for `f64` values.
540+
#[cfg(stage0)]
479541
pub fn copysignf64(x: f64, y: f64) -> f64;
542+
/// Copies the sign from `y` to `x` for floating point values of type `T.
543+
#[cfg(not(stage0))]
544+
pub fn copysign<T>(x: T, y: T) -> T;
480545

481546
/// Returns the largest integer less than or equal to an `f32`.
547+
#[cfg(stage0)]
482548
pub fn floorf32(x: f32) -> f32;
483549
/// Returns the largest integer less than or equal to an `f64`.
550+
#[cfg(stage0)]
484551
pub fn floorf64(x: f64) -> f64;
552+
/// Returns the largest integer less than or equal to a floating point of type `T`.
553+
#[cfg(not(stage0))]
554+
pub fn floor<T>(x: T) -> T;
485555

486556
/// Returns the smallest integer greater than or equal to an `f32`.
557+
#[cfg(stage0)]
487558
pub fn ceilf32(x: f32) -> f32;
488559
/// Returns the smallest integer greater than or equal to an `f64`.
560+
#[cfg(stage0)]
489561
pub fn ceilf64(x: f64) -> f64;
562+
/// Returns the smallest integer greater than or equal to a floating point of type `T`.
563+
#[cfg(not(stage0))]
564+
pub fn ceil<T>(T: T) -> T;
490565

491566
/// Returns the integer part of an `f32`.
567+
#[cfg(stage0)]
492568
pub fn truncf32(x: f32) -> f32;
493569
/// Returns the integer part of an `f64`.
570+
#[cfg(stage0)]
494571
pub fn truncf64(x: f64) -> f64;
572+
/// Returns the integer part of an `f64`.
573+
#[cfg(not(stage0))]
574+
pub fn trunc<T>(x: T) -> T;
495575

496576
/// Returns the nearest integer to an `f32`. May raise an inexact floating-point exception
497577
/// if the argument is not an integer.
578+
#[cfg(stage0)]
498579
pub fn rintf32(x: f32) -> f32;
499580
/// Returns the nearest integer to an `f64`. May raise an inexact floating-point exception
500581
/// if the argument is not an integer.
582+
#[cfg(stage0)]
501583
pub fn rintf64(x: f64) -> f64;
584+
/// Returns the nearest integer to a floating point of type `T`. May raise an inexact
585+
/// floating-point exception if the argument is not an integer.
586+
#[cfg(not(stage0))]
587+
pub fn rint<T>(x: T) -> T;
502588

503589
/// Returns the nearest integer to an `f32`.
590+
#[cfg(stage0)]
504591
pub fn nearbyintf32(x: f32) -> f32;
505592
/// Returns the nearest integer to an `f64`.
593+
#[cfg(stage0)]
506594
pub fn nearbyintf64(x: f64) -> f64;
595+
/// Returns the nearest integer to a floating point of type `T`.
596+
#[cfg(not(stage0))]
597+
pub fn nearbyint<T>(x: T) -> T;
507598

508599
/// Returns the nearest integer to an `f32`. Rounds half-way cases away from zero.
600+
#[cfg(stage0)]
509601
pub fn roundf32(x: f32) -> f32;
510602
/// Returns the nearest integer to an `f64`. Rounds half-way cases away from zero.
603+
#[cfg(stage0)]
511604
pub fn roundf64(x: f64) -> f64;
605+
/// Returns the nearest integer to a a floating point of type `T`.
606+
/// Rounds half-way cases away from zero.
607+
#[cfg(not(stage0))]
608+
pub fn round<T>(x: T) -> T;
512609

513610
/// Returns the number of bits set in a `u8`.
514611
#[cfg(stage0)]

src/libcore/num/f32.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,23 +219,39 @@ impl Float for f32 {
219219
/// Computes the absolute value of `self`. Returns `Float::nan()` if the
220220
/// number is `Float::nan()`.
221221
#[inline]
222+
#[cfg(stage0)]
222223
fn abs(self) -> f32 {
223224
unsafe { intrinsics::fabsf32(self) }
224225
}
226+
#[inline]
227+
#[cfg(not(stage0))]
228+
fn abs(self) -> f32 {
229+
unsafe { intrinsics::fabs(self) }
230+
}
225231

226232
/// Returns a number that represents the sign of `self`.
227233
///
228234
/// - `1.0` if the number is positive, `+0.0` or `Float::infinity()`
229235
/// - `-1.0` if the number is negative, `-0.0` or `Float::neg_infinity()`
230236
/// - `Float::nan()` if the number is `Float::nan()`
231237
#[inline]
238+
#[cfg(stage0)]
232239
fn signum(self) -> f32 {
233240
if self.is_nan() {
234241
Float::nan()
235242
} else {
236243
unsafe { intrinsics::copysignf32(1.0, self) }
237244
}
238245
}
246+
#[inline]
247+
#[cfg(not(stage0))]
248+
fn signum(self) -> f32 {
249+
if self.is_nan() {
250+
Float::nan()
251+
} else {
252+
unsafe { intrinsics::copysign(1.0, self) }
253+
}
254+
}
239255

240256
/// Returns `true` if `self` is positive, including `+0.0` and
241257
/// `Float::infinity()`.
@@ -256,9 +272,15 @@ impl Float for f32 {
256272
fn recip(self) -> f32 { 1.0 / self }
257273

258274
#[inline]
275+
#[cfg(stage0)]
259276
fn powi(self, n: i32) -> f32 {
260277
unsafe { intrinsics::powif32(self, n) }
261278
}
279+
#[inline]
280+
#[cfg(not(stage0))]
281+
fn powi(self, n: i32) -> f32 {
282+
unsafe { intrinsics::powi(self, n) }
283+
}
262284

263285
/// Converts to degrees, assuming the number is in radians.
264286
#[inline]

src/libcore/num/f64.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,23 +219,39 @@ impl Float for f64 {
219219
/// Computes the absolute value of `self`. Returns `Float::nan()` if the
220220
/// number is `Float::nan()`.
221221
#[inline]
222+
#[cfg(stage0)]
222223
fn abs(self) -> f64 {
223224
unsafe { intrinsics::fabsf64(self) }
224225
}
226+
#[inline]
227+
#[cfg(not(stage0))]
228+
fn abs(self) -> f64 {
229+
unsafe { intrinsics::fabs(self) }
230+
}
225231

226232
/// Returns a number that represents the sign of `self`.
227233
///
228234
/// - `1.0` if the number is positive, `+0.0` or `Float::infinity()`
229235
/// - `-1.0` if the number is negative, `-0.0` or `Float::neg_infinity()`
230236
/// - `Float::nan()` if the number is `Float::nan()`
231237
#[inline]
238+
#[cfg(stage0)]
232239
fn signum(self) -> f64 {
233240
if self.is_nan() {
234241
Float::nan()
235242
} else {
236243
unsafe { intrinsics::copysignf64(1.0, self) }
237244
}
238245
}
246+
#[inline]
247+
#[cfg(not(stage0))]
248+
fn signum(self) -> f64 {
249+
if self.is_nan() {
250+
Float::nan()
251+
} else {
252+
unsafe { intrinsics::copysign(1.0, self) }
253+
}
254+
}
239255

240256
/// Returns `true` if `self` is positive, including `+0.0` and
241257
/// `Float::infinity()`.
@@ -256,9 +272,15 @@ impl Float for f64 {
256272
fn recip(self) -> f64 { 1.0 / self }
257273

258274
#[inline]
275+
#[cfg(stage0)]
259276
fn powi(self, n: i32) -> f64 {
260277
unsafe { intrinsics::powif64(self, n) }
261278
}
279+
#[inline]
280+
#[cfg(not(stage0))]
281+
fn powi(self, n: i32) -> f64 {
282+
unsafe { intrinsics::powi(self, n) }
283+
}
262284

263285
/// Converts to degrees, assuming the number is in radians.
264286
#[inline]

src/librand/lib.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,28 +82,56 @@ trait FloatMath : Sized {
8282

8383
impl FloatMath for f64 {
8484
#[inline]
85+
#[cfg(stage0)]
8586
fn exp(self) -> f64 {
8687
unsafe { intrinsics::expf64(self) }
8788
}
89+
#[inline]
90+
#[cfg(not(stage0))]
91+
fn exp(self) -> f64 {
92+
unsafe { intrinsics::exp(self) }
93+
}
8894

8995
#[inline]
96+
#[cfg(stage0)]
9097
fn ln(self) -> f64 {
9198
unsafe { intrinsics::logf64(self) }
9299
}
100+
#[inline]
101+
#[cfg(not(stage0))]
102+
fn ln(self) -> f64 {
103+
unsafe { intrinsics::log(self) }
104+
}
93105

94106
#[inline]
107+
#[cfg(stage0)]
95108
fn powf(self, n: f64) -> f64 {
96109
unsafe { intrinsics::powf64(self, n) }
97110
}
111+
#[inline]
112+
#[cfg(not(stage0))]
113+
fn powf(self, n: f64) -> f64 {
114+
unsafe { intrinsics::pow(self, n) }
115+
}
98116

99117
#[inline]
118+
#[cfg(stage0)]
100119
fn sqrt(self) -> f64 {
101120
if self < 0.0 {
102121
f64::NAN
103122
} else {
104123
unsafe { intrinsics::sqrtf64(self) }
105124
}
106125
}
126+
#[inline]
127+
#[cfg(not(stage0))]
128+
fn sqrt(self) -> f64 {
129+
if self < 0.0 {
130+
f64::NAN
131+
} else {
132+
unsafe { intrinsics::sqrt(self) }
133+
}
134+
}
107135
}
108136

109137
/// A type that can be randomly generated using an `Rng`.

0 commit comments

Comments
 (0)