From 5a27abab52500f23431b71d9592631b39a4bc84b Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Mon, 30 Jul 2018 03:11:43 +0000 Subject: [PATCH 1/2] switch to 64-bit compilation; add flag for 32-bit --- CHANGELOG.md | 1 + build.rs | 26 ++++++++++++++++++++++---- depend/check_uint128_t.c | 16 ++++++++++++++++ 3 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 depend/check_uint128_t.c diff --git a/CHANGELOG.md b/CHANGELOG.md index e027ac5..bbc9a18 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ * Update `rand` to 0.4 and `gcc` 0.3 to `cc` 1.0. (`rand` 0.5 exists but has a lot of breaking changes and no longer compiles with 1.14.0.) * Remove `PublicKey::combine` from API since it cannot be used with anything else in the API +* Detect whether 64-bit compilation is possible, and do it if we can (big performance improvement) # 0.10.0 - 2018-07-25 diff --git a/build.rs b/build.rs index 29aac07..f257106 100644 --- a/build.rs +++ b/build.rs @@ -24,6 +24,19 @@ extern crate cc; fn main() { + // Check whether we can use 64-bit compilation + #[cfg(target_pointer_width = "64")] + let use_64bit_compilation = { + cc::Build::new().file("depend/check_uint128_t.c") + .cargo_metadata(false) + .try_compile("check_uint128_t") + .is_ok() + }; + #[cfg(not(target_pointer_width = "64"))] + let use_64bit_compilation = false; + + + // Actual build let mut base_config = cc::Build::new(); base_config.include("depend/secp256k1/") .include("depend/secp256k1/include") @@ -35,14 +48,19 @@ fn main() { .define("USE_NUM_NONE", Some("1")) .define("USE_FIELD_INV_BUILTIN", Some("1")) .define("USE_SCALAR_INV_BUILTIN", Some("1")) - // TODO these should use 64-bit variants on 64-bit systems - .define("USE_FIELD_10X26", Some("1")) - .define("USE_SCALAR_8X32", Some("1")) .define("USE_ENDOMORPHISM", Some("1")) - // These all are OK. .define("ENABLE_MODULE_ECDH", Some("1")) .define("ENABLE_MODULE_RECOVERY", Some("1")); + if use_64bit_compilation { + base_config.define("USE_FIELD_5X52", Some("1")) + .define("USE_SCALAR_4X64", Some("1")) + .define("HAVE___INT128", Some("1")); + } else { + base_config.define("USE_FIELD_10X26", Some("1")) + .define("USE_SCALAR_8X32", Some("1")); + } + // secp256k1 base_config.file("depend/secp256k1/contrib/lax_der_parsing.c") .file("depend/secp256k1/src/secp256k1.c") diff --git a/depend/check_uint128_t.c b/depend/check_uint128_t.c new file mode 100644 index 0000000..4d90955 --- /dev/null +++ b/depend/check_uint128_t.c @@ -0,0 +1,16 @@ + +#include + +int main(void) { + __uint128_t var_128; + uint64_t var_64; + + /* Try to shut up "unused variable" warnings */ + var_64 = 100; + var_128 = 100; + if (var_64 == var_128) { + var_64 = 20; + } + return 0; +} + From 5cd45333754bd57d90543dcb1ab25232c6f40381 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Tue, 21 Aug 2018 18:41:42 +0000 Subject: [PATCH 2/2] add warning if uint128_t detection fails --- build.rs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/build.rs b/build.rs index f257106..8175c82 100644 --- a/build.rs +++ b/build.rs @@ -23,14 +23,23 @@ extern crate cc; +use std::io::{self, Write}; + fn main() { // Check whether we can use 64-bit compilation #[cfg(target_pointer_width = "64")] let use_64bit_compilation = { - cc::Build::new().file("depend/check_uint128_t.c") - .cargo_metadata(false) - .try_compile("check_uint128_t") - .is_ok() + let check = cc::Build::new().file("depend/check_uint128_t.c") + .cargo_metadata(false) + .try_compile("check_uint128_t") + .is_ok(); + if !check { + writeln!( + &mut io::stderr(), + "Warning: Compiling in 32-bit mode on a 64-bit architecture due to lack of uint128_t support." + ).expect("print to stderr") + } + check }; #[cfg(not(target_pointer_width = "64"))] let use_64bit_compilation = false;