Skip to content

Commit

Permalink
Improve fd_uint256_cmp
Browse files Browse the repository at this point in the history
  • Loading branch information
riptl committed Nov 29, 2024
1 parent 2bc30f0 commit 465395b
Showing 1 changed file with 28 additions and 8 deletions.
36 changes: 28 additions & 8 deletions src/ballet/bigint/fd_uint256.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@

#include "../fd_ballet_base.h"

#if FD_HAS_AVX
#include "../../util/simd/fd_avx.h"
#endif

/* Align at most at 32 bytes.
This way a struct containing multiple fd_uint256_t doesn't waste space
(e.g., on avx512 FD_ALIGNED would be 64, causing each fd_uint256_t to
Expand Down Expand Up @@ -52,16 +56,32 @@ fd_uint256_eq( fd_uint256_t const * a,
&& ( a->limbs[3] == b->limbs[3] );
}

/* fd_uint256_cmp returns 0 is a == b, -1 if a < b, 1 if a > b. */
static inline int
/* fd_uint256_cmp returns 0 is a == b, arbitrary negative int if a < b,
arbitrary positive int if a > b. */

static inline long
fd_uint256_cmp( fd_uint256_t const * a,
fd_uint256_t const * b ) {
for( int i=3; i>=0; i-- ) {
if( a->limbs[i] != b->limbs[i] ) {
return a->limbs[i] > b->limbs[i] ? 1 : -1;
}
}
return 0;
# if FD_HAS_AVX && defined(__LZCNT__)

wu_t va = wb_ld( a->buf );
wu_t vb = wb_ld( b->buf );
uint lt_mask = (uint)_mm256_movemask_epi8( wu_lt( va, vb ) );
uint gt_mask = (uint)_mm256_movemask_epi8( wu_gt( va, vb ) );
int lt_prio = (int)( _lzcnt_u32( lt_mask ) );
int gt_prio = (int)( _lzcnt_u32( gt_mask ) );
return lt_prio - gt_prio;

# else

ulong c;
ulong d0 = __builtin_subcl( a->limbs[0], b->limbs[0], 0, &c );
ulong d1 = __builtin_subcl( a->limbs[1], b->limbs[1], c, &c );
ulong d2 = __builtin_subcl( a->limbs[2], b->limbs[2], c, &c );
ulong d3 = __builtin_subcl( a->limbs[3], b->limbs[3], c, &c );
return c ? -1 : !!(d0|d1|d2|d3);

# endif
}

/* fd_uint256_bit returns the i-th bit of a.
Expand Down

0 comments on commit 465395b

Please sign in to comment.