Line data Source code
1 : #ifndef HEADER_fd_src_ballet_reedsol_fd_reedsol_arith_gfni_h 2 : #define HEADER_fd_src_ballet_reedsol_fd_reedsol_arith_gfni_h 3 : 4 : #ifndef HEADER_fd_src_ballet_reedsol_fd_reedsol_private_h 5 : #error "Do not include this file directly; use fd_reedsol_private.h" 6 : #endif 7 : 8 : #include "../../util/simd/fd_avx.h" 9 : 10 : typedef wb_t gf_t; 11 : 12 6783 : #define GF_WIDTH W_FOOTPRINT 13 : 14 : FD_PROTOTYPES_BEGIN 15 : 16 144704 : #define gf_ldu wb_ldu 17 72352 : #define gf_stu wb_stu 18 191337 : #define gf_zero wb_zero 19 : 20 : extern uchar const fd_reedsol_arith_consts_gfni_mul[] __attribute__((aligned(128))); 21 : 22 2073840 : #define GF_ADD wb_xor 23 : 24 0 : #define GF_OR wb_or 25 : 26 : /* Older versions of GCC have a bug that cause them to think 27 : _mm256_gf2p8affine_epi64_epi8 is a symmetric in the first two 28 : arguments (other than that the second argument can be a memory 29 : address). That's totally incorrect. It was fixed in GCC 10. See 30 : https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92889 for more details. */ 31 : 32 : #if !FD_USING_CLANG 33 : #define GCC_VERSION (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__) 34 : #endif 35 : 36 : #if FD_USING_CLANG || (GCC_VERSION >= 100000) 37 : 38 518720 : #define GF_MUL_VAR( a, c ) (_mm256_gf2p8affine_epi64_epi8( (a), wb_ld( fd_reedsol_arith_consts_gfni_mul + 32*(c) ), 0 )) 39 : 40 : /* c is a compile-time constant: a plain conditional folds while parsing (no statement-expr temporaries) */ 41 264148 : #define GF_MUL( a, c ) ( ((c)==0) ? wb_zero() : ( ((c)==1) ? (a) : GF_MUL_VAR( (a), (c) ) ) ) 42 : 43 : #else 44 : 45 : #define GF_MUL( a, c ) (__extension__({ \ 46 : wb_t _a = (a); \ 47 : int _c = (c); \ 48 : wb_t _product; \ 49 : __asm__( "vgf2p8affineqb $0x0, %[cons], %[vec], %[out]" \ 50 : : [out]"=x" (_product) \ 51 : : [cons]"xm" (wb_ld( fd_reedsol_arith_consts_gfni_mul + 32*_c )), \ 52 : [vec]"x" (_a) ); \ 53 : /* c is known at compile time, so this is not a runtime branch */ \ 54 : (_c==0) ? wb_zero() : ( (_c==1) ? (_a) : _product ); \ 55 : })) 56 : 57 : #define GF_MUL_VAR( a, c ) (__extension__({ \ 58 : wb_t _product; \ 59 : __asm__( "vgf2p8affineqb $0x0, %[cons], %[vec], %[out]" \ 60 : : [out]"=x" (_product) \ 61 : : [cons]"xm" (wb_ld( fd_reedsol_arith_consts_gfni_mul + 32*(c) )), \ 62 : [vec]"x" (a) ); \ 63 : (_product); \ 64 : })) 65 : 66 : #endif 67 : 68 : #define GF_ANY( x ) (0 != _mm256_movemask_epi8( wb_ne( (x), wb_zero() ) )) 69 : 70 : FD_PROTOTYPES_END 71 : 72 : #endif /* HEADER_fd_src_ballet_reedsol_fd_reedsol_arith_gfni_h */