Skip to content

Commit

Permalink
Support 64-bit limbs on no-asm platforms
Browse files Browse the repository at this point in the history
Currently, platforms without assembler support always use 32-bit limbs,
but the Rust bindings always assume 64-bit limbs.  This breaks on
big-endian platforms like our IBM Z (s390x).

This patch enables 64-bit limbs on 64-bit platforms even if there is
no hand-written assembler, by using a 128-bit integer type in the
C implementation (this is an extension that is widely supported on
64-bit platforms with GCC or LLVM).

This fixes the broken Rust bindings on IBM Z, and also improves
performance by a factor or 3 or more, because compiler-generated
code handling __int128 already uses the 64x64->128 multiply
instruction our ISA provides.

To improve performance of compiler-generated code a bit more, this
also switches to the -O3 optimization level, which helps with
unrolling of the Montgomery multiply core loop.
  • Loading branch information
uweigand committed Mar 4, 2022
1 parent f2380d2 commit 0333c0e
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 3 deletions.
6 changes: 5 additions & 1 deletion bindings/rust/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,11 @@ fn main() {
.flag_if_supported("-Wno-unused-function")
.flag_if_supported("-Wno-unused-command-line-argument");
if !cfg!(debug_assertions) {
cc.opt_level(2);
if target_arch.eq("s390x") {
cc.opt_level(3);
} else {
cc.opt_level(2);
}
}
cc.files(&file_vec).compile("libblst.a");

Expand Down
2 changes: 2 additions & 0 deletions src/no_asm.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

#if LIMB_T_BITS==32
typedef unsigned long long llimb_t;
#else
typedef unsigned __int128 llimb_t;
#endif

#if defined(__clang__)
Expand Down
6 changes: 4 additions & 2 deletions src/vect.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ typedef unsigned long long limb_t;
typedef unsigned __int64 limb_t;
# define LIMB_T_BITS 64

#elif defined(__BLST_NO_ASM__) || defined(__wasm64__)
#elif defined(__wasm64__)
typedef unsigned int limb_t;
# define LIMB_T_BITS 32
# ifndef __BLST_NO_ASM__
Expand All @@ -31,8 +31,10 @@ typedef unsigned long limb_t;
# define LIMB_T_BITS 64
# else
# define LIMB_T_BITS 32
# define __BLST_NO_ASM__
# endif
# ifndef __BLST_NO_ASM__
# define __BLST_NO_ASM__
# endif
#endif

/*
Expand Down

0 comments on commit 0333c0e

Please sign in to comment.