From 3080360beb7b7aaa658fe08569a84dd9d5c451e5 Mon Sep 17 00:00:00 2001 From: Lokathor Date: Thu, 20 Dec 2018 17:47:57 -0700 Subject: [PATCH 01/11] start of __clzsi2 --- src/arm.rs | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/src/arm.rs b/src/arm.rs index 9e43aec..111e697 100644 --- a/src/arm.rs +++ b/src/arm.rs @@ -233,3 +233,61 @@ pub unsafe extern "aapcs" fn __aeabi_memclr4(dest: *mut u8, n: usize) { pub unsafe extern "aapcs" fn __aeabi_memclr8(dest: *mut u8, n: usize) { __aeabi_memset4(dest, n, 0); } + +#[no_mangle] +#[cfg(any(target_pointer_width = "16", target_pointer_width = "32", target_pointer_width = "64"))] +pub extern "C" fn __clzsi2(mut x: usize) -> usize { + // TODO: const this? Requires const if + let mut y: usize; + let mut n: usize = { + #[cfg(target_pointer_width = "64")] + { + 64 + } + #[cfg(target_pointer_width = "32")] + { + 32 + } + #[cfg(target_pointer_width = "16")] + { + 16 + } + }; + #[cfg(target_pointer_width = "64")] + { + y = x >> 32; + if y != 0 { + n -= 32; + x = y; + } + } + #[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))] + { + y = x >> 16; + if y != 0 { + n -= 16; + x = y; + } + } + y = x >> 8; + if y != 0 { + n -= 8; + x = y; + } + y = x >> 4; + if y != 0 { + n -= 4; + x = y; + } + y = x >> 2; + if y != 0 { + n -= 2; + x = y; + } + y = x >> 1; + if y != 0 { + n - 2 + } else { + n - x + } +} From a74490a75b7dd857ac2ab095bbc49b1ad9f1aaec Mon Sep 17 00:00:00 2001 From: Lokathor Date: Thu, 20 Dec 2018 17:53:10 -0700 Subject: [PATCH 02/11] modify to fit into standard rustfmt output --- src/arm.rs | 94 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 49 insertions(+), 45 deletions(-) diff --git a/src/arm.rs b/src/arm.rs index 111e697..009b1ff 100644 --- a/src/arm.rs +++ b/src/arm.rs @@ -235,59 +235,63 @@ pub unsafe extern "aapcs" fn __aeabi_memclr8(dest: *mut u8, n: usize) { } #[no_mangle] -#[cfg(any(target_pointer_width = "16", target_pointer_width = "32", target_pointer_width = "64"))] +#[cfg(any( + target_pointer_width = "16", + target_pointer_width = "32", + target_pointer_width = "64" +))] pub extern "C" fn __clzsi2(mut x: usize) -> usize { - // TODO: const this? Requires const if - let mut y: usize; - let mut n: usize = { + // TODO: const this? Requires const if + let mut y: usize; + let mut n: usize = { + #[cfg(target_pointer_width = "64")] + { + 64 + } + #[cfg(target_pointer_width = "32")] + { + 32 + } + #[cfg(target_pointer_width = "16")] + { + 16 + } + }; #[cfg(target_pointer_width = "64")] { - 64 + y = x >> 32; + if y != 0 { + n -= 32; + x = y; + } } - #[cfg(target_pointer_width = "32")] + #[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))] { - 32 + y = x >> 16; + if y != 0 { + n -= 16; + x = y; + } } - #[cfg(target_pointer_width = "16")] - { - 16 - } - }; - #[cfg(target_pointer_width = "64")] - { - y = x >> 32; + y = x >> 8; if y != 0 { - n -= 32; - x = y; + n -= 8; + x = y; } - } - #[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))] - { - y = x >> 16; + y = x >> 4; if y != 0 { - n -= 16; - x = y; + n -= 4; + x = y; + } + y = x >> 2; + if y != 0 { + n -= 2; + x = y; + } + y = x >> 1; + if y != 0 { + n - 2 + } else { + n - x } - } - y = x >> 8; - if y != 0 { - n -= 8; - x = y; - } - y = x >> 4; - if y != 0 { - n -= 4; - x = y; - } - y = x >> 2; - if y != 0 { - n -= 2; - x = y; - } - y = x >> 1; - if y != 0 { - n - 2 - } else { - n - x - } } From 4e3fc640dfb0f859d7d85a7ddec6714d8b0c05b8 Mon Sep 17 00:00:00 2001 From: Lokathor Date: Fri, 21 Dec 2018 18:02:12 -0700 Subject: [PATCH 03/11] Move clzi2 into the int module --- src/arm.rs | 62 -------------------------------------------------- src/int/mod.rs | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 62 deletions(-) diff --git a/src/arm.rs b/src/arm.rs index 009b1ff..9e43aec 100644 --- a/src/arm.rs +++ b/src/arm.rs @@ -233,65 +233,3 @@ pub unsafe extern "aapcs" fn __aeabi_memclr4(dest: *mut u8, n: usize) { pub unsafe extern "aapcs" fn __aeabi_memclr8(dest: *mut u8, n: usize) { __aeabi_memset4(dest, n, 0); } - -#[no_mangle] -#[cfg(any( - target_pointer_width = "16", - target_pointer_width = "32", - target_pointer_width = "64" -))] -pub extern "C" fn __clzsi2(mut x: usize) -> usize { - // TODO: const this? Requires const if - let mut y: usize; - let mut n: usize = { - #[cfg(target_pointer_width = "64")] - { - 64 - } - #[cfg(target_pointer_width = "32")] - { - 32 - } - #[cfg(target_pointer_width = "16")] - { - 16 - } - }; - #[cfg(target_pointer_width = "64")] - { - y = x >> 32; - if y != 0 { - n -= 32; - x = y; - } - } - #[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))] - { - y = x >> 16; - if y != 0 { - n -= 16; - x = y; - } - } - y = x >> 8; - if y != 0 { - n -= 8; - x = y; - } - y = x >> 4; - if y != 0 { - n -= 4; - x = y; - } - y = x >> 2; - if y != 0 { - n -= 2; - x = y; - } - y = x >> 1; - if y != 0 { - n - 2 - } else { - n - x - } -} diff --git a/src/int/mod.rs b/src/int/mod.rs index b645b21..11fd49b 100644 --- a/src/int/mod.rs +++ b/src/int/mod.rs @@ -300,3 +300,65 @@ macro_rules! impl_wide_int { impl_wide_int!(u32, u64, 32); impl_wide_int!(u64, u128, 64); + +#[no_mangle] +#[cfg(any( + target_pointer_width = "16", + target_pointer_width = "32", + target_pointer_width = "64" +))] +pub extern "C" fn __clzsi2(mut x: usize) -> usize { + // TODO: const this? Would require const-if + let mut y: usize; + let mut n: usize = { + #[cfg(target_pointer_width = "64")] + { + 64 + } + #[cfg(target_pointer_width = "32")] + { + 32 + } + #[cfg(target_pointer_width = "16")] + { + 16 + } + }; + #[cfg(target_pointer_width = "64")] + { + y = x >> 32; + if y != 0 { + n -= 32; + x = y; + } + } + #[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))] + { + y = x >> 16; + if y != 0 { + n -= 16; + x = y; + } + } + y = x >> 8; + if y != 0 { + n -= 8; + x = y; + } + y = x >> 4; + if y != 0 { + n -= 4; + x = y; + } + y = x >> 2; + if y != 0 { + n -= 2; + x = y; + } + y = x >> 1; + if y != 0 { + n - 2 + } else { + n - x + } +} From e8c09a84f837ad15c06561bda55d5b6c60928ada Mon Sep 17 00:00:00 2001 From: Lokathor Date: Fri, 21 Dec 2018 18:10:45 -0700 Subject: [PATCH 04/11] trying a test case for clzsi2 --- testcrate/build.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/testcrate/build.rs b/testcrate/build.rs index d862e0d..08c14fd 100644 --- a/testcrate/build.rs +++ b/testcrate/build.rs @@ -775,6 +775,12 @@ fn main() { (builtins::int::udiv::__udivmodti4(a, b, Some(&mut r)), r) }"); } + + // count leading zeros + gen(|(a): (usize)| { + Some(a.leading_zeros()) + }, + "builtins::int::__clzsi2(a)"); } macro_rules! gen_float { From c548dc5b344f89227ffaadc2657f90a7544b0200 Mon Sep 17 00:00:00 2001 From: Lokathor Date: Fri, 21 Dec 2018 18:20:59 -0700 Subject: [PATCH 05/11] We can't accept usize directly, i guess accept `MyU64`? --- testcrate/build.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/testcrate/build.rs b/testcrate/build.rs index 08c14fd..0fa2f56 100644 --- a/testcrate/build.rs +++ b/testcrate/build.rs @@ -777,10 +777,12 @@ fn main() { } // count leading zeros - gen(|(a): (usize)| { - Some(a.leading_zeros()) + gen(|a: MyU128| { + Some((a as usize).leading_zeros()) }, - "builtins::int::__clzsi2(a)"); + "{ + builtins::int::__clzsi2(a as usize) + }"); } macro_rules! gen_float { From 1e8904e4242f685dae583655e2109d32b7b0e325 Mon Sep 17 00:00:00 2001 From: Lokathor Date: Fri, 21 Dec 2018 18:21:47 -0700 Subject: [PATCH 06/11] 64, not 128! --- testcrate/build.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testcrate/build.rs b/testcrate/build.rs index 0fa2f56..292d36a 100644 --- a/testcrate/build.rs +++ b/testcrate/build.rs @@ -777,7 +777,7 @@ fn main() { } // count leading zeros - gen(|a: MyU128| { + gen(|a: MyU64| { Some((a as usize).leading_zeros()) }, "{ From 2afedce8cb4169dca7b5b37a22d455b4975bd19c Mon Sep 17 00:00:00 2001 From: Lokathor Date: Fri, 21 Dec 2018 18:36:26 -0700 Subject: [PATCH 07/11] forgot the little `.0` part --- testcrate/build.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testcrate/build.rs b/testcrate/build.rs index 292d36a..1a51054 100644 --- a/testcrate/build.rs +++ b/testcrate/build.rs @@ -778,7 +778,7 @@ fn main() { // count leading zeros gen(|a: MyU64| { - Some((a as usize).leading_zeros()) + Some((a.0 as usize).leading_zeros()) }, "{ builtins::int::__clzsi2(a as usize) From d27966f52c7bf271caa0c2fd792be5d60ac5e956 Mon Sep 17 00:00:00 2001 From: Lokathor Date: Fri, 21 Dec 2018 18:47:03 -0700 Subject: [PATCH 08/11] Rust and LLVM don't spec the same output types --- testcrate/build.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testcrate/build.rs b/testcrate/build.rs index 1a51054..4f10adc 100644 --- a/testcrate/build.rs +++ b/testcrate/build.rs @@ -778,7 +778,7 @@ fn main() { // count leading zeros gen(|a: MyU64| { - Some((a.0 as usize).leading_zeros()) + Some((a.0 as usize).leading_zeros() as usize) }, "{ builtins::int::__clzsi2(a as usize) From 828c5c6d5fc50291c4511ca2561ee540840bbafc Mon Sep 17 00:00:00 2001 From: Lokathor Date: Fri, 21 Dec 2018 18:55:01 -0700 Subject: [PATCH 09/11] Okay we'll process outputs as all u32 --- testcrate/build.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testcrate/build.rs b/testcrate/build.rs index 4f10adc..c18daca 100644 --- a/testcrate/build.rs +++ b/testcrate/build.rs @@ -778,10 +778,10 @@ fn main() { // count leading zeros gen(|a: MyU64| { - Some((a.0 as usize).leading_zeros() as usize) + Some((a.0 as usize).leading_zeros()) }, "{ - builtins::int::__clzsi2(a as usize) + builtins::int::__clzsi2(a as usize) as u32 }"); } From 2e8b85439f194105b86315b96c1e4ff4ae2465e7 Mon Sep 17 00:00:00 2001 From: Lokathor Date: Wed, 2 Jan 2019 18:50:11 -0700 Subject: [PATCH 10/11] Move the test to be a standard test. --- testcrate/build.rs | 8 -------- testcrate/tests/count_leading_zeros.rs | 25 +++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 8 deletions(-) create mode 100644 testcrate/tests/count_leading_zeros.rs diff --git a/testcrate/build.rs b/testcrate/build.rs index c18daca..d862e0d 100644 --- a/testcrate/build.rs +++ b/testcrate/build.rs @@ -775,14 +775,6 @@ fn main() { (builtins::int::udiv::__udivmodti4(a, b, Some(&mut r)), r) }"); } - - // count leading zeros - gen(|a: MyU64| { - Some((a.0 as usize).leading_zeros()) - }, - "{ - builtins::int::__clzsi2(a as usize) as u32 - }"); } macro_rules! gen_float { diff --git a/testcrate/tests/count_leading_zeros.rs b/testcrate/tests/count_leading_zeros.rs new file mode 100644 index 0000000..5596501 --- /dev/null +++ b/testcrate/tests/count_leading_zeros.rs @@ -0,0 +1,25 @@ +#![feature(compiler_builtins_lib)] + +extern crate compiler_builtins; + +use compiler_builtins::int::__clzsi2; + +#[test] +fn __clzsi2_test() { + let mut i: usize = core::usize::MAX; + // Check all values above 0 + while i > 0 { + assert_eq!(__clzsi2(i) as u32, i.leading_zeros()); + i >>= 1; + } + // check 0 also + i = 0; + assert_eq!(__clzsi2(i) as u32, i.leading_zeros()); + // double check for bit patterns that aren't just solid 1s + i = 1; + for _ in 0..63 { + assert_eq!(__clzsi2(i) as u32, i.leading_zeros()); + i <<= 2; + i += 1; + } +} From 9a68e74ebdea558f500be073685d06d5bd6e620f Mon Sep 17 00:00:00 2001 From: Lokathor Date: Fri, 4 Jan 2019 19:17:02 -0700 Subject: [PATCH 11/11] Attempt to use `intrinsics!` --- src/int/mod.rs | 99 ++++++++++++++++++++++++++------------------------ 1 file changed, 51 insertions(+), 48 deletions(-) diff --git a/src/int/mod.rs b/src/int/mod.rs index 11fd49b..52a4227 100644 --- a/src/int/mod.rs +++ b/src/int/mod.rs @@ -301,64 +301,67 @@ macro_rules! impl_wide_int { impl_wide_int!(u32, u64, 32); impl_wide_int!(u64, u128, 64); -#[no_mangle] -#[cfg(any( - target_pointer_width = "16", - target_pointer_width = "32", - target_pointer_width = "64" -))] -pub extern "C" fn __clzsi2(mut x: usize) -> usize { - // TODO: const this? Would require const-if - let mut y: usize; - let mut n: usize = { +intrinsics! { + #[cfg(any( + target_pointer_width = "16", + target_pointer_width = "32", + target_pointer_width = "64" + ))] + pub extern "C" fn __clzsi2(x: usize) -> usize { + // TODO: const this? Would require const-if + // Note(Lokathor): the `intrinsics!` macro can't process mut inputs + let mut x = x; + let mut y: usize; + let mut n: usize = { + #[cfg(target_pointer_width = "64")] + { + 64 + } + #[cfg(target_pointer_width = "32")] + { + 32 + } + #[cfg(target_pointer_width = "16")] + { + 16 + } + }; #[cfg(target_pointer_width = "64")] { - 64 + y = x >> 32; + if y != 0 { + n -= 32; + x = y; + } } - #[cfg(target_pointer_width = "32")] + #[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))] { - 32 + y = x >> 16; + if y != 0 { + n -= 16; + x = y; + } } - #[cfg(target_pointer_width = "16")] - { - 16 - } - }; - #[cfg(target_pointer_width = "64")] - { - y = x >> 32; + y = x >> 8; if y != 0 { - n -= 32; + n -= 8; x = y; } - } - #[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))] - { - y = x >> 16; + y = x >> 4; if y != 0 { - n -= 16; + n -= 4; x = y; } - } - y = x >> 8; - if y != 0 { - n -= 8; - x = y; - } - y = x >> 4; - if y != 0 { - n -= 4; - x = y; - } - y = x >> 2; - if y != 0 { - n -= 2; - x = y; - } - y = x >> 1; - if y != 0 { - n - 2 - } else { - n - x + y = x >> 2; + if y != 0 { + n -= 2; + x = y; + } + y = x >> 1; + if y != 0 { + n - 2 + } else { + n - x + } } }