10b57cec5SDimitry Andric //===-- int_lib.h - configuration header for compiler-rt -----------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file is a configuration header for compiler-rt. 100b57cec5SDimitry Andric // This file is not part of the interface of this library. 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #ifndef INT_LIB_H 150b57cec5SDimitry Andric #define INT_LIB_H 160b57cec5SDimitry Andric 170b57cec5SDimitry Andric // Assumption: Signed integral is 2's complement. 180b57cec5SDimitry Andric // Assumption: Right shift of signed negative is arithmetic shift. 190b57cec5SDimitry Andric // Assumption: Endianness is little or big (not mixed). 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric // ABI macro definitions 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric #if __ARM_EABI__ 24*5ffd83dbSDimitry Andric #ifdef COMPILER_RT_ARMHF_TARGET 250b57cec5SDimitry Andric #define COMPILER_RT_ABI 260b57cec5SDimitry Andric #else 270b57cec5SDimitry Andric #define COMPILER_RT_ABI __attribute__((__pcs__("aapcs"))) 280b57cec5SDimitry Andric #endif 290b57cec5SDimitry Andric #else 300b57cec5SDimitry Andric #define COMPILER_RT_ABI 310b57cec5SDimitry Andric #endif 320b57cec5SDimitry Andric 330b57cec5SDimitry Andric #define AEABI_RTABI __attribute__((__pcs__("aapcs"))) 340b57cec5SDimitry Andric 350b57cec5SDimitry Andric #if defined(_MSC_VER) && !defined(__clang__) 360b57cec5SDimitry Andric #define ALWAYS_INLINE __forceinline 370b57cec5SDimitry Andric #define NOINLINE __declspec(noinline) 380b57cec5SDimitry Andric #define NORETURN __declspec(noreturn) 390b57cec5SDimitry Andric #define UNUSED 400b57cec5SDimitry Andric #else 410b57cec5SDimitry Andric #define ALWAYS_INLINE __attribute__((always_inline)) 420b57cec5SDimitry Andric #define NOINLINE __attribute__((noinline)) 430b57cec5SDimitry Andric #define NORETURN __attribute__((noreturn)) 440b57cec5SDimitry Andric #define UNUSED __attribute__((unused)) 450b57cec5SDimitry Andric #endif 460b57cec5SDimitry Andric 470b57cec5SDimitry Andric #define STR(a) #a 480b57cec5SDimitry Andric #define XSTR(a) STR(a) 490b57cec5SDimitry Andric #define SYMBOL_NAME(name) XSTR(__USER_LABEL_PREFIX__) #name 500b57cec5SDimitry Andric 51*5ffd83dbSDimitry Andric #if defined(__ELF__) || defined(__MINGW32__) || defined(__wasm__) || \ 52*5ffd83dbSDimitry Andric defined(_AIX) 530b57cec5SDimitry Andric #define COMPILER_RT_ALIAS(name, aliasname) \ 540b57cec5SDimitry Andric COMPILER_RT_ABI __typeof(name) aliasname __attribute__((__alias__(#name))); 550b57cec5SDimitry Andric #elif defined(__APPLE__) 56*5ffd83dbSDimitry Andric #if defined(VISIBILITY_HIDDEN) 57*5ffd83dbSDimitry Andric #define COMPILER_RT_ALIAS_VISIBILITY(name) \ 58*5ffd83dbSDimitry Andric __asm__(".private_extern " SYMBOL_NAME(name)); 59*5ffd83dbSDimitry Andric #else 60*5ffd83dbSDimitry Andric #define COMPILER_RT_ALIAS_VISIBILITY(name) 61*5ffd83dbSDimitry Andric #endif 620b57cec5SDimitry Andric #define COMPILER_RT_ALIAS(name, aliasname) \ 630b57cec5SDimitry Andric __asm__(".globl " SYMBOL_NAME(aliasname)); \ 64*5ffd83dbSDimitry Andric COMPILER_RT_ALIAS_VISIBILITY(aliasname) \ 650b57cec5SDimitry Andric __asm__(SYMBOL_NAME(aliasname) " = " SYMBOL_NAME(name)); \ 660b57cec5SDimitry Andric COMPILER_RT_ABI __typeof(name) aliasname; 670b57cec5SDimitry Andric #elif defined(_WIN32) 680b57cec5SDimitry Andric #define COMPILER_RT_ALIAS(name, aliasname) 690b57cec5SDimitry Andric #else 700b57cec5SDimitry Andric #error Unsupported target 710b57cec5SDimitry Andric #endif 720b57cec5SDimitry Andric 73*5ffd83dbSDimitry Andric #if defined(__NetBSD__) && (defined(_KERNEL) || defined(_STANDALONE)) 740b57cec5SDimitry Andric // 750b57cec5SDimitry Andric // Kernel and boot environment can't use normal headers, 760b57cec5SDimitry Andric // so use the equivalent system headers. 770b57cec5SDimitry Andric // 780b57cec5SDimitry Andric #include <machine/limits.h> 790b57cec5SDimitry Andric #include <sys/stdint.h> 800b57cec5SDimitry Andric #include <sys/types.h> 810b57cec5SDimitry Andric #else 820b57cec5SDimitry Andric // Include the standard compiler builtin headers we use functionality from. 830b57cec5SDimitry Andric #include <float.h> 840b57cec5SDimitry Andric #include <limits.h> 850b57cec5SDimitry Andric #include <stdbool.h> 860b57cec5SDimitry Andric #include <stdint.h> 870b57cec5SDimitry Andric #endif 880b57cec5SDimitry Andric 890b57cec5SDimitry Andric // Include the commonly used internal type definitions. 900b57cec5SDimitry Andric #include "int_types.h" 910b57cec5SDimitry Andric 920b57cec5SDimitry Andric // Include internal utility function declarations. 930b57cec5SDimitry Andric #include "int_util.h" 940b57cec5SDimitry Andric 95*5ffd83dbSDimitry Andric COMPILER_RT_ABI int __paritysi2(si_int a); 96*5ffd83dbSDimitry Andric COMPILER_RT_ABI int __paritydi2(di_int a); 970b57cec5SDimitry Andric 980b57cec5SDimitry Andric COMPILER_RT_ABI di_int __divdi3(di_int a, di_int b); 990b57cec5SDimitry Andric COMPILER_RT_ABI si_int __divsi3(si_int a, si_int b); 1000b57cec5SDimitry Andric COMPILER_RT_ABI su_int __udivsi3(su_int n, su_int d); 1010b57cec5SDimitry Andric 1020b57cec5SDimitry Andric COMPILER_RT_ABI su_int __udivmodsi4(su_int a, su_int b, su_int *rem); 1030b57cec5SDimitry Andric COMPILER_RT_ABI du_int __udivmoddi4(du_int a, du_int b, du_int *rem); 1040b57cec5SDimitry Andric #ifdef CRT_HAS_128BIT 105*5ffd83dbSDimitry Andric COMPILER_RT_ABI int __clzti2(ti_int a); 1060b57cec5SDimitry Andric COMPILER_RT_ABI tu_int __udivmodti4(tu_int a, tu_int b, tu_int *rem); 1070b57cec5SDimitry Andric #endif 1080b57cec5SDimitry Andric 1090b57cec5SDimitry Andric // Definitions for builtins unavailable on MSVC 1100b57cec5SDimitry Andric #if defined(_MSC_VER) && !defined(__clang__) 1110b57cec5SDimitry Andric #include <intrin.h> 1120b57cec5SDimitry Andric 113*5ffd83dbSDimitry Andric int __inline __builtin_ctz(uint32_t value) { 1140b57cec5SDimitry Andric unsigned long trailing_zero = 0; 1150b57cec5SDimitry Andric if (_BitScanForward(&trailing_zero, value)) 1160b57cec5SDimitry Andric return trailing_zero; 1170b57cec5SDimitry Andric return 32; 1180b57cec5SDimitry Andric } 1190b57cec5SDimitry Andric 120*5ffd83dbSDimitry Andric int __inline __builtin_clz(uint32_t value) { 1210b57cec5SDimitry Andric unsigned long leading_zero = 0; 1220b57cec5SDimitry Andric if (_BitScanReverse(&leading_zero, value)) 1230b57cec5SDimitry Andric return 31 - leading_zero; 1240b57cec5SDimitry Andric return 32; 1250b57cec5SDimitry Andric } 1260b57cec5SDimitry Andric 1270b57cec5SDimitry Andric #if defined(_M_ARM) || defined(_M_X64) 128*5ffd83dbSDimitry Andric int __inline __builtin_clzll(uint64_t value) { 1290b57cec5SDimitry Andric unsigned long leading_zero = 0; 1300b57cec5SDimitry Andric if (_BitScanReverse64(&leading_zero, value)) 1310b57cec5SDimitry Andric return 63 - leading_zero; 1320b57cec5SDimitry Andric return 64; 1330b57cec5SDimitry Andric } 1340b57cec5SDimitry Andric #else 135*5ffd83dbSDimitry Andric int __inline __builtin_clzll(uint64_t value) { 1360b57cec5SDimitry Andric if (value == 0) 1370b57cec5SDimitry Andric return 64; 1380b57cec5SDimitry Andric uint32_t msh = (uint32_t)(value >> 32); 1390b57cec5SDimitry Andric uint32_t lsh = (uint32_t)(value & 0xFFFFFFFF); 1400b57cec5SDimitry Andric if (msh != 0) 1410b57cec5SDimitry Andric return __builtin_clz(msh); 1420b57cec5SDimitry Andric return 32 + __builtin_clz(lsh); 1430b57cec5SDimitry Andric } 1440b57cec5SDimitry Andric #endif 1450b57cec5SDimitry Andric 1460b57cec5SDimitry Andric #define __builtin_clzl __builtin_clzll 1470b57cec5SDimitry Andric #endif // defined(_MSC_VER) && !defined(__clang__) 1480b57cec5SDimitry Andric 1490b57cec5SDimitry Andric #endif // INT_LIB_H 150