xref: /openbsd-src/lib/libcrypto/bn/arch/amd64/word_clz.S (revision 22787c513b4b59ee1fb13a32326a50f73cd342c1)
15dab377eSjsing// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
211f745e9Sjsing//
311f745e9Sjsing// Permission to use, copy, modify, and/or distribute this software for any
411f745e9Sjsing// purpose with or without fee is hereby granted, provided that the above
511f745e9Sjsing// copyright notice and this permission notice appear in all copies.
611f745e9Sjsing//
711f745e9Sjsing// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
811f745e9Sjsing// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
911f745e9Sjsing// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1011f745e9Sjsing// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1111f745e9Sjsing// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1211f745e9Sjsing// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1311f745e9Sjsing// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
145dab377eSjsing
155dab377eSjsing// ----------------------------------------------------------------------------
165dab377eSjsing// Count leading zero bits in a single word
175dab377eSjsing// Input a; output function return
185dab377eSjsing//
195dab377eSjsing//    extern uint64_t word_clz (uint64_t a);
205dab377eSjsing//
215dab377eSjsing// Standard x86-64 ABI: RDI = a, returns RAX
225dab377eSjsing// Microsoft x64 ABI:   RCX = a, returns RAX
235dab377eSjsing// ----------------------------------------------------------------------------
245dab377eSjsing
258c38c49aSjsing#include "s2n_bignum_internal.h"
265dab377eSjsing
275dab377eSjsing        .intel_syntax noprefix
285dab377eSjsing        S2N_BN_SYM_VISIBILITY_DIRECTIVE(word_clz)
295dab377eSjsing        S2N_BN_SYM_PRIVACY_DIRECTIVE(word_clz)
305dab377eSjsing        .text
315dab377eSjsing
325dab377eSjsingS2N_BN_SYMBOL(word_clz):
33*22787c51Stb	_CET_ENDBR
345dab377eSjsing
355dab377eSjsing#if WINDOWS_ABI
365dab377eSjsing        push    rdi
375dab377eSjsing        push    rsi
385dab377eSjsing        mov     rdi, rcx
395dab377eSjsing#endif
405dab377eSjsing
415dab377eSjsing// First do rax = 63 - bsr(a), which is right except (maybe) for zero inputs
425dab377eSjsing
435dab377eSjsing        bsr     rax, rdi
445dab377eSjsing        xor     rax, 63
455dab377eSjsing
465dab377eSjsing// Force return of 64 in the zero-input case
475dab377eSjsing
485dab377eSjsing        mov     edx, 64
495dab377eSjsing        test    rdi, rdi
505dab377eSjsing        cmove   rax, rdx
515dab377eSjsing
525dab377eSjsing#if WINDOWS_ABI
535dab377eSjsing        pop    rsi
545dab377eSjsing        pop    rdi
555dab377eSjsing#endif
565dab377eSjsing        ret
575dab377eSjsing
585dab377eSjsing#if defined(__linux__) && defined(__ELF__)
595dab377eSjsing.section .note.GNU-stack,"",%progbits
605dab377eSjsing#endif
61