blob: 67dd57ff9a933259921f03973ecd61233d4dfba9 [file] [log] [blame]
metzman40132972019-01-09 21:46:09 +00001//===- FuzzerBuiltinsMSVC.h - Internal header for builtins ------*- C++ -* ===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9// Wrapper functions and marcos that use intrinsics instead of builtin functions
10// which cannot be compiled by MSVC.
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_FUZZER_BUILTINS_MSVC_H
14#define LLVM_FUZZER_BUILTINS_MSVC_H
15
16#include "FuzzerDefs.h"
17
18#if LIBFUZZER_MSVC
19#if !defined(_M_ARM) && !defined(_M_X64)
20#error "_BitScanReverse64 unavailable on this platform so MSVC is unsupported."
21#endif
22#include <intrin.h>
23#include <cstdint>
24#include <cstdlib>
25
26// __builtin_return_address() cannot be compiled with MSVC. Use the equivalent
27// from <intrin.h>
28#define GET_CALLER_PC() reinterpret_cast<uintptr_t>(_ReturnAddress())
29
30namespace fuzzer {
31
32inline uint8_t Bswap(uint8_t x) { return x; }
33// Use alternatives to __builtin functions from <stdlib.h> and <intrin.h> on
34// Windows since the builtins are not supported by MSVC.
35inline uint16_t Bswap(uint16_t x) { return _byteswap_ushort(x); }
36inline uint32_t Bswap(uint32_t x) { return _byteswap_ulong(x); }
37inline uint64_t Bswap(uint64_t x) { return _byteswap_uint64(x); }
38
39// The functions below were mostly copied from
40// compiler-rt/lib/builtins/int_lib.h which defines the __builtin functions used
41// outside of Windows.
42inline uint32_t Clzll(uint64_t X) {
43 unsigned long LeadZeroIdx = 0;
44 if (_BitScanReverse64(&LeadZeroIdx, X)) return 63 - LeadZeroIdx;
45 return 64;
46}
47
48inline uint32_t Clz(uint32_t X) {
49 unsigned long LeadZeroIdx = 0;
50 if (_BitScanReverse(&LeadZeroIdx, X)) return 31 - LeadZeroIdx;
51 return 32;
52}
53
54inline int Popcountll(unsigned long long X) { return __popcnt64(X); }
55
56} // namespace fuzzer
57
58#endif // LIBFUZER_MSVC
59#endif // LLVM_FUZZER_BUILTINS_MSVC_H