FuzzerBuiltinsMsvc.h 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. //===- FuzzerBuiltinsMSVC.h - Internal header for builtins ------*- C++ -* ===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. // Wrapper functions and marcos that use intrinsics instead of builtin functions
  9. // which cannot be compiled by MSVC.
  10. //===----------------------------------------------------------------------===//
  11. #ifndef LLVM_FUZZER_BUILTINS_MSVC_H
  12. #define LLVM_FUZZER_BUILTINS_MSVC_H
  13. #include "FuzzerPlatform.h"
  14. #if LIBFUZZER_MSVC
  15. #include <intrin.h>
  16. #include <cstdint>
  17. #include <cstdlib>
  18. // __builtin_return_address() cannot be compiled with MSVC. Use the equivalent
  19. // from <intrin.h>
  20. #define GET_CALLER_PC() _ReturnAddress()
  21. namespace fuzzer {
  22. inline uint8_t Bswap(uint8_t x) { return x; }
  23. // Use alternatives to __builtin functions from <stdlib.h> and <intrin.h> on
  24. // Windows since the builtins are not supported by MSVC.
  25. inline uint16_t Bswap(uint16_t x) { return _byteswap_ushort(x); }
  26. inline uint32_t Bswap(uint32_t x) { return _byteswap_ulong(x); }
  27. inline uint64_t Bswap(uint64_t x) { return _byteswap_uint64(x); }
  28. // The functions below were mostly copied from
  29. // compiler-rt/lib/builtins/int_lib.h which defines the __builtin functions used
  30. // outside of Windows.
  31. inline uint32_t Clzll(uint64_t X) {
  32. unsigned long LeadZeroIdx = 0;
  33. #if !defined(_M_ARM) && !defined(_M_X64)
  34. // Scan the high 32 bits.
  35. if (_BitScanReverse(&LeadZeroIdx, static_cast<unsigned long>(X >> 32)))
  36. return static_cast<int>(
  37. 63 - (LeadZeroIdx + 32)); // Create a bit offset from the MSB.
  38. // Scan the low 32 bits.
  39. if (_BitScanReverse(&LeadZeroIdx, static_cast<unsigned long>(X)))
  40. return static_cast<int>(63 - LeadZeroIdx);
  41. #else
  42. if (_BitScanReverse64(&LeadZeroIdx, X)) return 63 - LeadZeroIdx;
  43. #endif
  44. return 64;
  45. }
  46. inline int Popcountll(unsigned long long X) {
  47. #if !defined(_M_ARM) && !defined(_M_X64)
  48. return __popcnt(X) + __popcnt(X >> 32);
  49. #else
  50. return __popcnt64(X);
  51. #endif
  52. }
  53. } // namespace fuzzer
  54. #endif // LIBFUZER_MSVC
  55. #endif // LLVM_FUZZER_BUILTINS_MSVC_H