68 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8// Wrapper functions and marcos that use intrinsics instead of builtin functions9// which cannot be compiled by MSVC.10//===----------------------------------------------------------------------===//11 12#ifndef LLVM_FUZZER_BUILTINS_MSVC_H13#define LLVM_FUZZER_BUILTINS_MSVC_H14 15#include "FuzzerPlatform.h"16 17#if LIBFUZZER_MSVC18#include <intrin.h>19#include <cstdint>20#include <cstdlib>21 22// __builtin_return_address() cannot be compiled with MSVC. Use the equivalent23// from <intrin.h>24#define GET_CALLER_PC() _ReturnAddress()25 26namespace fuzzer {27 28inline uint8_t Bswap(uint8_t x) { return x; }29// Use alternatives to __builtin functions from <stdlib.h> and <intrin.h> on30// Windows since the builtins are not supported by MSVC.31inline uint16_t Bswap(uint16_t x) { return _byteswap_ushort(x); }32inline uint32_t Bswap(uint32_t x) { return _byteswap_ulong(x); }33inline uint64_t Bswap(uint64_t x) { return _byteswap_uint64(x); }34 35// The functions below were mostly copied from36// compiler-rt/lib/builtins/int_lib.h which defines the __builtin functions used37// outside of Windows.38inline 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#else51 if (_BitScanReverse64(&LeadZeroIdx, X)) return 63 - LeadZeroIdx;52#endif53 return 64;54}55 56inline int Popcountll(unsigned long long X) {57#if !defined(_M_ARM) && !defined(_M_X64)58 return __popcnt(X) + __popcnt(X >> 32);59#else60 return __popcnt64(X);61#endif62}63 64} // namespace fuzzer65 66#endif // LIBFUZER_MSVC67#endif // LLVM_FUZZER_BUILTINS_MSVC_H68