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