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 | |
12 | #ifndef LLVM_FUZZER_BUILTINS_MSVC_H |
13 | #define LLVM_FUZZER_BUILTINS_MSVC_H |
14 | |
15 | #include "FuzzerPlatform.h" |
16 | |
17 | #if LIBFUZZER_MSVC |
18 | #include <intrin.h> |
19 | #include <cstdint> |
20 | #include <cstdlib> |
21 | |
22 | // __builtin_return_address() cannot be compiled with MSVC. Use the equivalent |
23 | // from <intrin.h> |
24 | #define GET_CALLER_PC() _ReturnAddress() |
25 | |
26 | namespace fuzzer { |
27 | |
28 | inline uint8_t Bswap(uint8_t x) { return x; } |
29 | // Use alternatives to __builtin functions from <stdlib.h> and <intrin.h> on |
30 | // Windows since the builtins are not supported by MSVC. |
31 | inline uint16_t Bswap(uint16_t x) { return _byteswap_ushort(x); } |
32 | inline uint32_t Bswap(uint32_t x) { return _byteswap_ulong(x); } |
33 | inline uint64_t Bswap(uint64_t x) { return _byteswap_uint64(x); } |
34 | |
35 | // The functions below were mostly copied from |
36 | // compiler-rt/lib/builtins/int_lib.h which defines the __builtin functions used |
37 | // outside of Windows. |
38 | inline uint32_t Clzll(uint64_t X) { |
39 | unsigned long LeadZeroIdx = 0; |
40 | |
41 | #if !defined(_M_ARM) && !defined(_M_X64) |
42 | // Scan the high 32 bits. |
43 | if (_BitScanReverse(&LeadZeroIdx, static_cast<unsigned long>(X >> 32))) |
44 | return static_cast<int>( |
45 | 63 - (LeadZeroIdx + 32)); // Create a bit offset from the MSB. |
46 | // Scan the low 32 bits. |
47 | if (_BitScanReverse(&LeadZeroIdx, static_cast<unsigned long>(X))) |
48 | return static_cast<int>(63 - LeadZeroIdx); |
49 | |
50 | #else |
51 | if (_BitScanReverse64(&LeadZeroIdx, X)) return 63 - LeadZeroIdx; |
52 | #endif |
53 | return 64; |
54 | } |
55 | |
56 | inline int Popcountll(unsigned long long X) { |
57 | #if !defined(_M_ARM) && !defined(_M_X64) |
58 | return __popcnt(X) + __popcnt(X >> 32); |
59 | #else |
60 | return __popcnt64(X); |
61 | #endif |
62 | } |
63 | |
64 | } // namespace fuzzer |
65 | |
66 | #endif // LIBFUZER_MSVC |
67 | #endif // LLVM_FUZZER_BUILTINS_MSVC_H |
68 | |