Add public-test-deps feature for better visibility control
This commit is contained in:
@@ -64,6 +64,10 @@ no-lang-items = []
|
||||
# Only used in the compiler's build system
|
||||
rustc-dep-of-std = ['compiler-builtins', 'core']
|
||||
|
||||
# This makes certain traits and function specializations public that
|
||||
# are not normally public but are required by the `testcrate`
|
||||
public-test-deps = []
|
||||
|
||||
[[example]]
|
||||
name = "intrinsics"
|
||||
required-features = ["compiler-builtins"]
|
||||
|
||||
@@ -11,9 +11,9 @@ pub mod mul;
|
||||
pub mod pow;
|
||||
pub mod sub;
|
||||
|
||||
public_test_dep! {
|
||||
/// Trait for some basic operations on floats
|
||||
#[doc(hidden)]
|
||||
pub trait Float:
|
||||
pub(crate) trait Float:
|
||||
Copy
|
||||
+ core::fmt::Debug
|
||||
+ PartialEq
|
||||
@@ -99,6 +99,7 @@ pub trait Float:
|
||||
/// Returns if `self` is subnormal
|
||||
fn is_subnormal(self) -> bool;
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! float_impl {
|
||||
($ty:ident, $ity:ident, $sity:ident, $expty:ident, $bits:expr, $significand_bits:expr) => {
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
// adding a zero check at the beginning, but `__clzsi2` has a precondition that `x != 0`.
|
||||
// Compilers will insert the check for zero in cases where it is needed.
|
||||
|
||||
public_test_dep! {
|
||||
/// Returns the number of leading binary zeros in `x`.
|
||||
#[doc(hidden)]
|
||||
pub fn usize_leading_zeros_default(x: usize) -> usize {
|
||||
pub(crate) fn usize_leading_zeros_default(x: usize) -> usize {
|
||||
// The basic idea is to test if the higher bits of `x` are zero and bisect the number
|
||||
// of leading zeros. It is possible for all branches of the bisection to use the same
|
||||
// code path by conditionally shifting the higher parts down to let the next bisection
|
||||
@@ -69,15 +69,16 @@ pub fn usize_leading_zeros_default(x: usize) -> usize {
|
||||
// on x86_64, it is slightly faster to use the LUT, but this is probably because of OOO
|
||||
// execution effects. Changing to using a LUT and branching is risky for smaller cores.
|
||||
}
|
||||
}
|
||||
|
||||
// The above method does not compile well on RISC-V (because of the lack of predicated
|
||||
// instructions), producing code with many branches or using an excessively long
|
||||
// branchless solution. This method takes advantage of the set-if-less-than instruction on
|
||||
// RISC-V that allows `(x >= power-of-two) as usize` to be branchless.
|
||||
|
||||
public_test_dep! {
|
||||
/// Returns the number of leading binary zeros in `x`.
|
||||
#[doc(hidden)]
|
||||
pub fn usize_leading_zeros_riscv(x: usize) -> usize {
|
||||
pub(crate) fn usize_leading_zeros_riscv(x: usize) -> usize {
|
||||
let mut x = x;
|
||||
// the number of potential leading zeros
|
||||
let mut z = usize::MAX.count_ones() as usize;
|
||||
@@ -126,6 +127,7 @@ pub fn usize_leading_zeros_riscv(x: usize) -> usize {
|
||||
// If `x != 0` then `x == 1` and subtracts one potential zero from `z`.
|
||||
z - x
|
||||
}
|
||||
}
|
||||
|
||||
intrinsics! {
|
||||
#[maybe_use_optimized_c_shim]
|
||||
|
||||
@@ -11,9 +11,9 @@ pub mod udiv;
|
||||
|
||||
pub use self::leading_zeros::__clzsi2;
|
||||
|
||||
public_test_dep! {
|
||||
/// Trait for some basic operations on integers
|
||||
#[doc(hidden)]
|
||||
pub trait Int:
|
||||
pub(crate) trait Int:
|
||||
Copy
|
||||
+ core::fmt::Debug
|
||||
+ PartialEq
|
||||
@@ -81,6 +81,7 @@ pub trait Int:
|
||||
fn overflowing_add(self, other: Self) -> (Self, bool);
|
||||
fn leading_zeros(self) -> u32;
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! int_impl_common {
|
||||
($ty:ty) => {
|
||||
@@ -255,10 +256,10 @@ int_impl!(i32, u32);
|
||||
int_impl!(i64, u64);
|
||||
int_impl!(i128, u128);
|
||||
|
||||
public_test_dep! {
|
||||
/// Trait for integers twice the bit width of another integer. This is implemented for all
|
||||
/// primitives except for `u8`, because there is not a smaller primitive.
|
||||
#[doc(hidden)]
|
||||
pub trait DInt: Int {
|
||||
pub(crate) trait DInt: Int {
|
||||
/// Integer that is half the bit width of the integer this trait is implemented for
|
||||
type H: HInt<D = Self> + Int;
|
||||
|
||||
@@ -271,11 +272,12 @@ pub trait DInt: Int {
|
||||
/// Constructs an integer using lower and higher half parts
|
||||
fn from_lo_hi(lo: Self::H, hi: Self::H) -> Self;
|
||||
}
|
||||
}
|
||||
|
||||
public_test_dep! {
|
||||
/// Trait for integers half the bit width of another integer. This is implemented for all
|
||||
/// primitives except for `u128`, because it there is not a larger primitive.
|
||||
#[doc(hidden)]
|
||||
pub trait HInt: Int {
|
||||
pub(crate) trait HInt: Int {
|
||||
/// Integer that is double the bit width of the integer this trait is implemented for
|
||||
type D: DInt<H = Self> + Int;
|
||||
|
||||
@@ -291,6 +293,7 @@ pub trait HInt: Int {
|
||||
/// Widening multiplication. This cannot overflow.
|
||||
fn widen_mul(self, rhs: Self) -> Self::D;
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_d_int {
|
||||
($($X:ident $D:ident),*) => {
|
||||
@@ -353,11 +356,12 @@ impl_h_int!(
|
||||
i64 u64 i128
|
||||
);
|
||||
|
||||
public_test_dep! {
|
||||
/// Trait to express (possibly lossy) casting of integers
|
||||
#[doc(hidden)]
|
||||
pub trait CastInto<T: Copy>: Copy {
|
||||
pub(crate) trait CastInto<T: Copy>: Copy {
|
||||
fn cast(self) -> T;
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! cast_into {
|
||||
($ty:ty) => {
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
/// assembly instruction that can divide a 128 bit integer by a 64 bit integer if the quotient fits
|
||||
/// in 64 bits. The 128 bit version of this algorithm would use that fast hardware division to
|
||||
/// construct a full 128 bit by 128 bit division.
|
||||
#[doc(hidden)]
|
||||
#[macro_export]
|
||||
#[allow(unused_macros)]
|
||||
macro_rules! impl_asymmetric {
|
||||
(
|
||||
$fn:ident, // name of the unsigned division function
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
/// predicate instructions. For architectures with predicated instructions, one of the algorithms
|
||||
/// described in the documentation of these functions probably has higher performance, and a custom
|
||||
/// assembly routine should be used instead.
|
||||
#[doc(hidden)]
|
||||
#[macro_export]
|
||||
#[allow(unused_macros)]
|
||||
macro_rules! impl_binary_long {
|
||||
(
|
||||
$fn:ident, // name of the unsigned division function
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
/// binary long division to divide integers larger than what hardware division by itself can do. This
|
||||
/// function is intended for microarchitectures that have division hardware, but not fast enough
|
||||
/// multiplication hardware for `impl_trifecta` to be faster.
|
||||
#[doc(hidden)]
|
||||
#[macro_export]
|
||||
#[allow(unused_macros)]
|
||||
macro_rules! impl_delegate {
|
||||
(
|
||||
$fn:ident, // name of the unsigned division function
|
||||
@@ -186,6 +185,7 @@ macro_rules! impl_delegate {
|
||||
};
|
||||
}
|
||||
|
||||
public_test_dep! {
|
||||
/// Returns `n / d` and sets `*rem = n % d`.
|
||||
///
|
||||
/// This specialization exists because:
|
||||
@@ -193,8 +193,9 @@ macro_rules! impl_delegate {
|
||||
/// so we have to use an old fashioned `&mut u128` argument to return the remainder.
|
||||
/// - 64-bit SPARC does not have u64 * u64 => u128 widening multiplication, which makes the
|
||||
/// delegate algorithm strategy the only reasonably fast way to perform `u128` division.
|
||||
#[doc(hidden)]
|
||||
pub fn u128_divide_sparc(duo: u128, div: u128, rem: &mut u128) -> u128 {
|
||||
// used on SPARC
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn u128_divide_sparc(duo: u128, div: u128, rem: &mut u128) -> u128 {
|
||||
use super::*;
|
||||
let duo_lo = duo as u64;
|
||||
let duo_hi = (duo >> 64) as u64;
|
||||
@@ -315,3 +316,4 @@ pub fn u128_divide_sparc(duo: u128, div: u128, rem: &mut u128) -> u128 {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +53,13 @@ mod binary_long;
|
||||
|
||||
#[macro_use]
|
||||
mod delegate;
|
||||
|
||||
// used on SPARC
|
||||
#[allow(unused_imports)]
|
||||
#[cfg(not(feature = "public-test-deps"))]
|
||||
pub(crate) use self::delegate::u128_divide_sparc;
|
||||
|
||||
#[cfg(feature = "public-test-deps")]
|
||||
pub use self::delegate::u128_divide_sparc;
|
||||
|
||||
#[macro_use]
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/// Creates a function used by some division algorithms to compute the "normalization shift".
|
||||
#[doc(hidden)]
|
||||
#[macro_export]
|
||||
#[allow(unused_macros)]
|
||||
macro_rules! impl_normalization_shift {
|
||||
(
|
||||
$name:ident, // name of the normalization shift function
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
/// larger than the largest hardware integer division supported. These functions use large radix
|
||||
/// division algorithms that require both fast division and very fast widening multiplication on the
|
||||
/// target microarchitecture. Otherwise, `impl_delegate` should be used instead.
|
||||
#[doc(hidden)]
|
||||
#[macro_export]
|
||||
#[allow(unused_macros)]
|
||||
macro_rules! impl_trifecta {
|
||||
(
|
||||
$fn:ident, // name of the unsigned division function
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
pub use int::specialized_div_rem::u128_divide_sparc;
|
||||
use int::specialized_div_rem::*;
|
||||
#[cfg(not(feature = "public-test-deps"))]
|
||||
pub(crate) use int::specialized_div_rem::*;
|
||||
|
||||
#[cfg(feature = "public-test-deps")]
|
||||
pub use int::specialized_div_rem::*;
|
||||
|
||||
intrinsics! {
|
||||
#[maybe_use_optimized_c_shim]
|
||||
|
||||
@@ -1,5 +1,21 @@
|
||||
//! Macros shared throughout the compiler-builtins implementation
|
||||
|
||||
/// Changes the visibility to `pub` if feature "public-test-deps" is set
|
||||
#[cfg(not(feature = "public-test-deps"))]
|
||||
macro_rules! public_test_dep {
|
||||
($(#[$($meta:meta)*])* pub(crate) $ident:ident $($tokens:tt)*) => {
|
||||
$(#[$($meta)*])* pub(crate) $ident $($tokens)*
|
||||
};
|
||||
}
|
||||
|
||||
/// Changes the visibility to `pub` if feature "public-test-deps" is set
|
||||
#[cfg(feature = "public-test-deps")]
|
||||
macro_rules! public_test_dep {
|
||||
{$(#[$($meta:meta)*])* pub(crate) $ident:ident $($tokens:tt)*} => {
|
||||
$(#[$($meta)*])* pub $ident $($tokens)*
|
||||
};
|
||||
}
|
||||
|
||||
/// The "main macro" used for defining intrinsics.
|
||||
///
|
||||
/// The compiler-builtins library is super platform-specific with tons of crazy
|
||||
|
||||
@@ -17,7 +17,7 @@ rand_xoshiro = "0.6"
|
||||
[dependencies.compiler_builtins]
|
||||
path = ".."
|
||||
default-features = false
|
||||
features = ["no-lang-items"]
|
||||
features = ["no-lang-items", "public-test-deps"]
|
||||
|
||||
[target.'cfg(all(target_arch = "arm", not(any(target_env = "gnu", target_env = "musl")), target_os = "linux"))'.dev-dependencies]
|
||||
test = { git = "https://github.com/japaric/utest" }
|
||||
|
||||
Reference in New Issue
Block a user