10b57cec5SDimitry Andric /*===---- rdseedintrin.h - RDSEED intrinsics -------------------------------===
20b57cec5SDimitry Andric *
30b57cec5SDimitry Andric * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric * See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric *
70b57cec5SDimitry Andric *===-----------------------------------------------------------------------===
80b57cec5SDimitry Andric */
90b57cec5SDimitry Andric
10*06c3fb27SDimitry Andric #ifndef __IMMINTRIN_H
11*06c3fb27SDimitry Andric #error "Never use <rdseedintrin.h> directly; include <immintrin.h> instead."
120b57cec5SDimitry Andric #endif
130b57cec5SDimitry Andric
140b57cec5SDimitry Andric #ifndef __RDSEEDINTRIN_H
150b57cec5SDimitry Andric #define __RDSEEDINTRIN_H
160b57cec5SDimitry Andric
170b57cec5SDimitry Andric /* Define the default attributes for the functions in this file. */
180b57cec5SDimitry Andric #define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("rdseed")))
190b57cec5SDimitry Andric
20*06c3fb27SDimitry Andric /// Stores a hardware-generated 16-bit random value in the memory at \a __p.
21*06c3fb27SDimitry Andric ///
22*06c3fb27SDimitry Andric /// The random number generator complies with NIST SP800-90B and SP800-90C.
23*06c3fb27SDimitry Andric ///
24*06c3fb27SDimitry Andric /// \code{.operation}
25*06c3fb27SDimitry Andric /// IF HW_NRND_GEN.ready == 1
26*06c3fb27SDimitry Andric /// Store16(__p, HW_NRND_GEN.data)
27*06c3fb27SDimitry Andric /// result := 1
28*06c3fb27SDimitry Andric /// ELSE
29*06c3fb27SDimitry Andric /// Store16(__p, 0)
30*06c3fb27SDimitry Andric /// result := 0
31*06c3fb27SDimitry Andric /// END
32*06c3fb27SDimitry Andric /// \endcode
33*06c3fb27SDimitry Andric ///
34*06c3fb27SDimitry Andric /// \headerfile <immintrin.h>
35*06c3fb27SDimitry Andric ///
36*06c3fb27SDimitry Andric /// This intrinsic corresponds to the \c RDSEED instruction.
37*06c3fb27SDimitry Andric ///
38*06c3fb27SDimitry Andric /// \param __p
39*06c3fb27SDimitry Andric /// Pointer to memory for storing the 16-bit random number.
40*06c3fb27SDimitry Andric /// \returns 1 if a random number was generated, 0 if not.
410b57cec5SDimitry Andric static __inline__ int __DEFAULT_FN_ATTRS
_rdseed16_step(unsigned short * __p)420b57cec5SDimitry Andric _rdseed16_step(unsigned short *__p)
430b57cec5SDimitry Andric {
4481ad6265SDimitry Andric return (int) __builtin_ia32_rdseed16_step(__p);
450b57cec5SDimitry Andric }
460b57cec5SDimitry Andric
47*06c3fb27SDimitry Andric /// Stores a hardware-generated 32-bit random value in the memory at \a __p.
48*06c3fb27SDimitry Andric ///
49*06c3fb27SDimitry Andric /// The random number generator complies with NIST SP800-90B and SP800-90C.
50*06c3fb27SDimitry Andric ///
51*06c3fb27SDimitry Andric /// \code{.operation}
52*06c3fb27SDimitry Andric /// IF HW_NRND_GEN.ready == 1
53*06c3fb27SDimitry Andric /// Store32(__p, HW_NRND_GEN.data)
54*06c3fb27SDimitry Andric /// result := 1
55*06c3fb27SDimitry Andric /// ELSE
56*06c3fb27SDimitry Andric /// Store32(__p, 0)
57*06c3fb27SDimitry Andric /// result := 0
58*06c3fb27SDimitry Andric /// END
59*06c3fb27SDimitry Andric /// \endcode
60*06c3fb27SDimitry Andric ///
61*06c3fb27SDimitry Andric /// \headerfile <immintrin.h>
62*06c3fb27SDimitry Andric ///
63*06c3fb27SDimitry Andric /// This intrinsic corresponds to the \c RDSEED instruction.
64*06c3fb27SDimitry Andric ///
65*06c3fb27SDimitry Andric /// \param __p
66*06c3fb27SDimitry Andric /// Pointer to memory for storing the 32-bit random number.
67*06c3fb27SDimitry Andric /// \returns 1 if a random number was generated, 0 if not.
680b57cec5SDimitry Andric static __inline__ int __DEFAULT_FN_ATTRS
_rdseed32_step(unsigned int * __p)690b57cec5SDimitry Andric _rdseed32_step(unsigned int *__p)
700b57cec5SDimitry Andric {
7181ad6265SDimitry Andric return (int) __builtin_ia32_rdseed32_step(__p);
720b57cec5SDimitry Andric }
730b57cec5SDimitry Andric
740b57cec5SDimitry Andric #ifdef __x86_64__
75*06c3fb27SDimitry Andric /// Stores a hardware-generated 64-bit random value in the memory at \a __p.
76*06c3fb27SDimitry Andric ///
77*06c3fb27SDimitry Andric /// The random number generator complies with NIST SP800-90B and SP800-90C.
78*06c3fb27SDimitry Andric ///
79*06c3fb27SDimitry Andric /// \code{.operation}
80*06c3fb27SDimitry Andric /// IF HW_NRND_GEN.ready == 1
81*06c3fb27SDimitry Andric /// Store64(__p, HW_NRND_GEN.data)
82*06c3fb27SDimitry Andric /// result := 1
83*06c3fb27SDimitry Andric /// ELSE
84*06c3fb27SDimitry Andric /// Store64(__p, 0)
85*06c3fb27SDimitry Andric /// result := 0
86*06c3fb27SDimitry Andric /// END
87*06c3fb27SDimitry Andric /// \endcode
88*06c3fb27SDimitry Andric ///
89*06c3fb27SDimitry Andric /// \headerfile <immintrin.h>
90*06c3fb27SDimitry Andric ///
91*06c3fb27SDimitry Andric /// This intrinsic corresponds to the \c RDSEED instruction.
92*06c3fb27SDimitry Andric ///
93*06c3fb27SDimitry Andric /// \param __p
94*06c3fb27SDimitry Andric /// Pointer to memory for storing the 64-bit random number.
95*06c3fb27SDimitry Andric /// \returns 1 if a random number was generated, 0 if not.
960b57cec5SDimitry Andric static __inline__ int __DEFAULT_FN_ATTRS
_rdseed64_step(unsigned long long * __p)970b57cec5SDimitry Andric _rdseed64_step(unsigned long long *__p)
980b57cec5SDimitry Andric {
9981ad6265SDimitry Andric return (int) __builtin_ia32_rdseed64_step(__p);
1000b57cec5SDimitry Andric }
1010b57cec5SDimitry Andric #endif
1020b57cec5SDimitry Andric
1030b57cec5SDimitry Andric #undef __DEFAULT_FN_ATTRS
1040b57cec5SDimitry Andric
1050b57cec5SDimitry Andric #endif /* __RDSEEDINTRIN_H */
106