1//===-- int_lib.h - configuration header for compiler-rt  -----------------===//
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-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file is a configuration header for compiler-rt.
10// This file is not part of the interface of this library.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef INT_LIB_H
15#define INT_LIB_H
16
17// Assumption: Signed integral is 2's complement.
18// Assumption: Right shift of signed negative is arithmetic shift.
19// Assumption: Endianness is little or big (not mixed).
20
21// ABI macro definitions
22
23#if __ARM_EABI__
24#if defined(COMPILER_RT_ARMHF_TARGET) || (!defined(__clang__) && \
25    defined(__GNUC__) && (__GNUC__ < 4 || __GNUC__ == 4 && __GNUC_MINOR__ < 5))
26// The pcs attribute was introduced in GCC 4.5.0
27#define COMPILER_RT_ABI
28#else
29#define COMPILER_RT_ABI __attribute__((__pcs__("aapcs")))
30#endif
31#else
32#define COMPILER_RT_ABI
33#endif
34
35#define AEABI_RTABI __attribute__((__pcs__("aapcs")))
36
37#if defined(_MSC_VER) && !defined(__clang__)
38#define ALWAYS_INLINE __forceinline
39#define NOINLINE __declspec(noinline)
40#define NORETURN __declspec(noreturn)
41#define UNUSED
42#else
43#define ALWAYS_INLINE __attribute__((always_inline))
44#define NOINLINE __attribute__((noinline))
45#define NORETURN __attribute__((noreturn))
46#define UNUSED __attribute__((unused))
47#endif
48
49#define STR(a) #a
50#define XSTR(a) STR(a)
51#define SYMBOL_NAME(name) XSTR(__USER_LABEL_PREFIX__) #name
52
53#if defined(__ELF__) || defined(__MINGW32__) || defined(__wasm__) ||           \
54    defined(_AIX)
55#define COMPILER_RT_ALIAS(name, aliasname) \
56  COMPILER_RT_ABI __typeof(name) aliasname __attribute__((__alias__(#name)));
57#elif defined(__APPLE__)
58#if defined(VISIBILITY_HIDDEN)
59#define COMPILER_RT_ALIAS_VISIBILITY(name) \
60  __asm__(".private_extern " SYMBOL_NAME(name));
61#else
62#define COMPILER_RT_ALIAS_VISIBILITY(name)
63#endif
64#define COMPILER_RT_ALIAS(name, aliasname) \
65  __asm__(".globl " SYMBOL_NAME(aliasname)); \
66  COMPILER_RT_ALIAS_VISIBILITY(aliasname) \
67  __asm__(SYMBOL_NAME(aliasname) " = " SYMBOL_NAME(name)); \
68  COMPILER_RT_ABI __typeof(name) aliasname;
69#elif defined(_WIN32)
70#define COMPILER_RT_ALIAS(name, aliasname)
71#else
72#error Unsupported target
73#endif
74
75#if (defined(__FreeBSD__) || defined(__NetBSD__)) && (defined(_KERNEL) || defined(_STANDALONE))
76//
77// Kernel and boot environment can't use normal headers,
78// so use the equivalent system headers.
79//
80#ifdef __FreeBSD__
81#include <sys/limits.h>
82#else
83#include <machine/limits.h>
84#endif
85#include <sys/stdint.h>
86#include <sys/types.h>
87#else
88// Include the standard compiler builtin headers we use functionality from.
89#include <float.h>
90#include <limits.h>
91#include <stdbool.h>
92#include <stdint.h>
93#endif
94
95// Include the commonly used internal type definitions.
96#include "int_types.h"
97
98// Include internal utility function declarations.
99#include "int_util.h"
100
101COMPILER_RT_ABI int __paritysi2(si_int a);
102COMPILER_RT_ABI int __paritydi2(di_int a);
103
104COMPILER_RT_ABI di_int __divdi3(di_int a, di_int b);
105COMPILER_RT_ABI si_int __divsi3(si_int a, si_int b);
106COMPILER_RT_ABI su_int __udivsi3(su_int n, su_int d);
107
108COMPILER_RT_ABI su_int __udivmodsi4(su_int a, su_int b, su_int *rem);
109COMPILER_RT_ABI du_int __udivmoddi4(du_int a, du_int b, du_int *rem);
110#ifdef CRT_HAS_128BIT
111COMPILER_RT_ABI int __clzti2(ti_int a);
112COMPILER_RT_ABI tu_int __udivmodti4(tu_int a, tu_int b, tu_int *rem);
113#endif
114
115// Definitions for builtins unavailable on MSVC
116#if defined(_MSC_VER) && !defined(__clang__)
117#include <intrin.h>
118
119int __inline __builtin_ctz(uint32_t value) {
120  unsigned long trailing_zero = 0;
121  if (_BitScanForward(&trailing_zero, value))
122    return trailing_zero;
123  return 32;
124}
125
126int __inline __builtin_clz(uint32_t value) {
127  unsigned long leading_zero = 0;
128  if (_BitScanReverse(&leading_zero, value))
129    return 31 - leading_zero;
130  return 32;
131}
132
133#if defined(_M_ARM) || defined(_M_X64)
134int __inline __builtin_clzll(uint64_t value) {
135  unsigned long leading_zero = 0;
136  if (_BitScanReverse64(&leading_zero, value))
137    return 63 - leading_zero;
138  return 64;
139}
140#else
141int __inline __builtin_clzll(uint64_t value) {
142  if (value == 0)
143    return 64;
144  uint32_t msh = (uint32_t)(value >> 32);
145  uint32_t lsh = (uint32_t)(value & 0xFFFFFFFF);
146  if (msh != 0)
147    return __builtin_clz(msh);
148  return 32 + __builtin_clz(lsh);
149}
150#endif
151
152#define __builtin_clzl __builtin_clzll
153#endif // defined(_MSC_VER) && !defined(__clang__)
154
155#endif // INT_LIB_H
156