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__ 2471daeec7SDimitry Andric #if defined(COMPILER_RT_ARMHF_TARGET) || (!defined(__clang__) && \ 2571daeec7SDimitry Andric defined(__GNUC__) && (__GNUC__ < 4 || __GNUC__ == 4 && __GNUC_MINOR__ < 5)) 2671daeec7SDimitry Andric // The pcs attribute was introduced in GCC 4.5.0 270b57cec5SDimitry Andric #define COMPILER_RT_ABI 280b57cec5SDimitry Andric #else 290b57cec5SDimitry Andric #define COMPILER_RT_ABI __attribute__((__pcs__("aapcs"))) 300b57cec5SDimitry Andric #endif 310b57cec5SDimitry Andric #else 320b57cec5SDimitry Andric #define COMPILER_RT_ABI 330b57cec5SDimitry Andric #endif 340b57cec5SDimitry Andric 350b57cec5SDimitry Andric #define AEABI_RTABI __attribute__((__pcs__("aapcs"))) 360b57cec5SDimitry Andric 370b57cec5SDimitry Andric #if defined(_MSC_VER) && !defined(__clang__) 380b57cec5SDimitry Andric #define ALWAYS_INLINE __forceinline 390b57cec5SDimitry Andric #define NOINLINE __declspec(noinline) 400b57cec5SDimitry Andric #define NORETURN __declspec(noreturn) 410b57cec5SDimitry Andric #define UNUSED 420b57cec5SDimitry Andric #else 430b57cec5SDimitry Andric #define ALWAYS_INLINE __attribute__((always_inline)) 440b57cec5SDimitry Andric #define NOINLINE __attribute__((noinline)) 450b57cec5SDimitry Andric #define NORETURN __attribute__((noreturn)) 460b57cec5SDimitry Andric #define UNUSED __attribute__((unused)) 470b57cec5SDimitry Andric #endif 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric #define STR(a) #a 500b57cec5SDimitry Andric #define XSTR(a) STR(a) 510b57cec5SDimitry Andric #define SYMBOL_NAME(name) XSTR(__USER_LABEL_PREFIX__) #name 520b57cec5SDimitry Andric 535ffd83dbSDimitry Andric #if defined(__ELF__) || defined(__MINGW32__) || defined(__wasm__) || \ 545ffd83dbSDimitry Andric defined(_AIX) 550b57cec5SDimitry Andric #define COMPILER_RT_ALIAS(name, aliasname) \ 560b57cec5SDimitry Andric COMPILER_RT_ABI __typeof(name) aliasname __attribute__((__alias__(#name))); 570b57cec5SDimitry Andric #elif defined(__APPLE__) 585ffd83dbSDimitry Andric #if defined(VISIBILITY_HIDDEN) 595ffd83dbSDimitry Andric #define COMPILER_RT_ALIAS_VISIBILITY(name) \ 605ffd83dbSDimitry Andric __asm__(".private_extern " SYMBOL_NAME(name)); 615ffd83dbSDimitry Andric #else 625ffd83dbSDimitry Andric #define COMPILER_RT_ALIAS_VISIBILITY(name) 635ffd83dbSDimitry Andric #endif 640b57cec5SDimitry Andric #define COMPILER_RT_ALIAS(name, aliasname) \ 650b57cec5SDimitry Andric __asm__(".globl " SYMBOL_NAME(aliasname)); \ 665ffd83dbSDimitry Andric COMPILER_RT_ALIAS_VISIBILITY(aliasname) \ 670b57cec5SDimitry Andric __asm__(SYMBOL_NAME(aliasname) " = " SYMBOL_NAME(name)); \ 680b57cec5SDimitry Andric COMPILER_RT_ABI __typeof(name) aliasname; 690b57cec5SDimitry Andric #elif defined(_WIN32) 700b57cec5SDimitry Andric #define COMPILER_RT_ALIAS(name, aliasname) 710b57cec5SDimitry Andric #else 720b57cec5SDimitry Andric #error Unsupported target 730b57cec5SDimitry Andric #endif 740b57cec5SDimitry Andric 75*dd6565b7SDimitry Andric #if (defined(__FreeBSD__) || defined(__NetBSD__)) && (defined(_KERNEL) || defined(_STANDALONE)) 760b57cec5SDimitry Andric // 770b57cec5SDimitry Andric // Kernel and boot environment can't use normal headers, 780b57cec5SDimitry Andric // so use the equivalent system headers. 790b57cec5SDimitry Andric // 80*dd6565b7SDimitry Andric #ifdef __FreeBSD__ 81*dd6565b7SDimitry Andric #include <sys/limits.h> 82*dd6565b7SDimitry Andric #else 830b57cec5SDimitry Andric #include <machine/limits.h> 84*dd6565b7SDimitry Andric #endif 850b57cec5SDimitry Andric #include <sys/stdint.h> 860b57cec5SDimitry Andric #include <sys/types.h> 870b57cec5SDimitry Andric #else 880b57cec5SDimitry Andric // Include the standard compiler builtin headers we use functionality from. 890b57cec5SDimitry Andric #include <float.h> 900b57cec5SDimitry Andric #include <limits.h> 910b57cec5SDimitry Andric #include <stdbool.h> 920b57cec5SDimitry Andric #include <stdint.h> 930b57cec5SDimitry Andric #endif 940b57cec5SDimitry Andric 950b57cec5SDimitry Andric // Include the commonly used internal type definitions. 960b57cec5SDimitry Andric #include "int_types.h" 970b57cec5SDimitry Andric 980b57cec5SDimitry Andric // Include internal utility function declarations. 990b57cec5SDimitry Andric #include "int_util.h" 1000b57cec5SDimitry Andric 10171daeec7SDimitry Andric /* 10271daeec7SDimitry Andric * Workaround for LLVM bug 11663. Prevent endless recursion in 10371daeec7SDimitry Andric * __c?zdi2(), where calls to __builtin_c?z() are expanded to 10471daeec7SDimitry Andric * __c?zdi2() instead of __c?zsi2(). 10571daeec7SDimitry Andric * 10671daeec7SDimitry Andric * Instead of placing this workaround in c?zdi2.c, put it in this 10771daeec7SDimitry Andric * global header to prevent other C files from making the detour 10871daeec7SDimitry Andric * through __c?zdi2() as well. 10971daeec7SDimitry Andric * 11071daeec7SDimitry Andric * This problem has been observed on FreeBSD for sparc64 and 11171daeec7SDimitry Andric * mips64 with GCC 4.2.1, and for riscv with GCC 5.2.0. 11271daeec7SDimitry Andric * Presumably it's any version of GCC, and targeting an arch that 11371daeec7SDimitry Andric * does not have dedicated bit counting instructions. 11471daeec7SDimitry Andric */ 11571daeec7SDimitry Andric #if defined(__FreeBSD__) && (defined(__sparc64__) || \ 11671daeec7SDimitry Andric defined(__mips_n32) || defined(__mips_n64) || defined(__mips_o64) || \ 11771daeec7SDimitry Andric defined(__riscv)) 11871daeec7SDimitry Andric si_int __clzsi2(si_int); 11971daeec7SDimitry Andric si_int __ctzsi2(si_int); 12071daeec7SDimitry Andric #define __builtin_clz __clzsi2 12171daeec7SDimitry Andric #define __builtin_ctz __ctzsi2 12271daeec7SDimitry Andric #endif /* FreeBSD && (sparc64 || mips_n32 || mips_n64 || mips_o64 || riscv) */ 12371daeec7SDimitry Andric 1245ffd83dbSDimitry Andric COMPILER_RT_ABI int __paritysi2(si_int a); 1255ffd83dbSDimitry Andric COMPILER_RT_ABI int __paritydi2(di_int a); 1260b57cec5SDimitry Andric 1270b57cec5SDimitry Andric COMPILER_RT_ABI di_int __divdi3(di_int a, di_int b); 1280b57cec5SDimitry Andric COMPILER_RT_ABI si_int __divsi3(si_int a, si_int b); 1290b57cec5SDimitry Andric COMPILER_RT_ABI su_int __udivsi3(su_int n, su_int d); 1300b57cec5SDimitry Andric 1310b57cec5SDimitry Andric COMPILER_RT_ABI su_int __udivmodsi4(su_int a, su_int b, su_int *rem); 1320b57cec5SDimitry Andric COMPILER_RT_ABI du_int __udivmoddi4(du_int a, du_int b, du_int *rem); 1330b57cec5SDimitry Andric #ifdef CRT_HAS_128BIT 1345ffd83dbSDimitry Andric COMPILER_RT_ABI int __clzti2(ti_int a); 1350b57cec5SDimitry Andric COMPILER_RT_ABI tu_int __udivmodti4(tu_int a, tu_int b, tu_int *rem); 1360b57cec5SDimitry Andric #endif 1370b57cec5SDimitry Andric 1380b57cec5SDimitry Andric // Definitions for builtins unavailable on MSVC 1390b57cec5SDimitry Andric #if defined(_MSC_VER) && !defined(__clang__) 1400b57cec5SDimitry Andric #include <intrin.h> 1410b57cec5SDimitry Andric 1425ffd83dbSDimitry Andric int __inline __builtin_ctz(uint32_t value) { 1430b57cec5SDimitry Andric unsigned long trailing_zero = 0; 1440b57cec5SDimitry Andric if (_BitScanForward(&trailing_zero, value)) 1450b57cec5SDimitry Andric return trailing_zero; 1460b57cec5SDimitry Andric return 32; 1470b57cec5SDimitry Andric } 1480b57cec5SDimitry Andric 1495ffd83dbSDimitry Andric int __inline __builtin_clz(uint32_t value) { 1500b57cec5SDimitry Andric unsigned long leading_zero = 0; 1510b57cec5SDimitry Andric if (_BitScanReverse(&leading_zero, value)) 1520b57cec5SDimitry Andric return 31 - leading_zero; 1530b57cec5SDimitry Andric return 32; 1540b57cec5SDimitry Andric } 1550b57cec5SDimitry Andric 1560b57cec5SDimitry Andric #if defined(_M_ARM) || defined(_M_X64) 1575ffd83dbSDimitry Andric int __inline __builtin_clzll(uint64_t value) { 1580b57cec5SDimitry Andric unsigned long leading_zero = 0; 1590b57cec5SDimitry Andric if (_BitScanReverse64(&leading_zero, value)) 1600b57cec5SDimitry Andric return 63 - leading_zero; 1610b57cec5SDimitry Andric return 64; 1620b57cec5SDimitry Andric } 1630b57cec5SDimitry Andric #else 1645ffd83dbSDimitry Andric int __inline __builtin_clzll(uint64_t value) { 1650b57cec5SDimitry Andric if (value == 0) 1660b57cec5SDimitry Andric return 64; 1670b57cec5SDimitry Andric uint32_t msh = (uint32_t)(value >> 32); 1680b57cec5SDimitry Andric uint32_t lsh = (uint32_t)(value & 0xFFFFFFFF); 1690b57cec5SDimitry Andric if (msh != 0) 1700b57cec5SDimitry Andric return __builtin_clz(msh); 1710b57cec5SDimitry Andric return 32 + __builtin_clz(lsh); 1720b57cec5SDimitry Andric } 1730b57cec5SDimitry Andric #endif 1740b57cec5SDimitry Andric 1750b57cec5SDimitry Andric #define __builtin_clzl __builtin_clzll 1760b57cec5SDimitry Andric #endif // defined(_MSC_VER) && !defined(__clang__) 1770b57cec5SDimitry Andric 1780b57cec5SDimitry Andric #endif // INT_LIB_H 179