/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Copyright 2019 Danny Robson */ #include "rdrand.hpp" using cruft::rand::rdrand; /////////////////////////////////////////////////////////////////////////////// rdrand::rdrand () { ; } //--------------------------------------------------------------------------------------- rdrand::rdrand (std::string const &) : rdrand () { ; } /////////////////////////////////////////////////////////////////////////////// rdrand::result_type rdrand::operator() () { uint64_t res; char success; __asm__ __volatile__ ( "rdrand %0;" "setc %1;" : "=r" (res) , "=qm" (success) ); if (!__builtin_expect(success, 1)) throw std::runtime_error ("no value available for rdrand"); // As long as the u64 we just grabbed is of a type we can truncate then // we'll do just that and return it. static_assert (sizeof (result_type) <= sizeof (res)); static_assert (std::is_signed_v == std::is_signed_v); return static_cast (res); }