Home | History | Annotate | Download | only in builtins
      1 /* ===-- int_lib.h - configuration header for compiler-rt  -----------------===
      2  *
      3  *                     The LLVM Compiler Infrastructure
      4  *
      5  * This file is dual licensed under the MIT and the University of Illinois Open
      6  * Source Licenses. See LICENSE.TXT for details.
      7  *
      8  * ===----------------------------------------------------------------------===
      9  *
     10  * This file is a configuration header for compiler-rt.
     11  * This file is not part of the interface of this library.
     12  *
     13  * ===----------------------------------------------------------------------===
     14  */
     15 
     16 /*
     17  * Portions copyright (c) 2017, ARM Limited and Contributors.
     18  * All rights reserved.
     19  */
     20 
     21 #ifndef INT_LIB_H
     22 #define INT_LIB_H
     23 
     24 /* Assumption: Signed integral is 2's complement. */
     25 /* Assumption: Right shift of signed negative is arithmetic shift. */
     26 /* Assumption: Endianness is little or big (not mixed). */
     27 
     28 #if defined(__ELF__)
     29 #define FNALIAS(alias_name, original_name) \
     30   void alias_name() __attribute__((alias(#original_name)))
     31 #else
     32 #define FNALIAS(alias, name) _Pragma("GCC error(\"alias unsupported on this file format\")")
     33 #endif
     34 
     35 /* ABI macro definitions */
     36 
     37 #if __ARM_EABI__
     38 # define ARM_EABI_FNALIAS(aeabi_name, name)         \
     39   void __aeabi_##aeabi_name() __attribute__((alias("__" #name)));
     40 # ifdef COMPILER_RT_ARMHF_TARGET
     41 #   define COMPILER_RT_ABI
     42 # else
     43 #   define COMPILER_RT_ABI __attribute__((pcs("aapcs")))
     44 # endif
     45 #else
     46 # define ARM_EABI_FNALIAS(aeabi_name, name)
     47 # define COMPILER_RT_ABI
     48 #endif
     49 
     50 #ifdef _MSC_VER
     51 #define ALWAYS_INLINE __forceinline
     52 #define NOINLINE __declspec(noinline)
     53 #define NORETURN __declspec(noreturn)
     54 #define UNUSED
     55 #else
     56 #define ALWAYS_INLINE __attribute__((always_inline))
     57 #define NOINLINE __attribute__((noinline))
     58 #define NORETURN __attribute__((noreturn))
     59 #define UNUSED __attribute__((unused))
     60 #endif
     61 
     62 /*
     63  * Kernel and boot environment can't use normal headers,
     64  * so use the equivalent system headers.
     65  */
     66 #  include <sys/limits.h>
     67 #  include <sys/stdint.h>
     68 #  include <sys/types.h>
     69 
     70 /* Include the commonly used internal type definitions. */
     71 #include "int_types.h"
     72 
     73 COMPILER_RT_ABI si_int __paritysi2(si_int a);
     74 COMPILER_RT_ABI si_int __paritydi2(di_int a);
     75 
     76 COMPILER_RT_ABI di_int __divdi3(di_int a, di_int b);
     77 COMPILER_RT_ABI si_int __divsi3(si_int a, si_int b);
     78 COMPILER_RT_ABI su_int __udivsi3(su_int n, su_int d);
     79 
     80 COMPILER_RT_ABI su_int __udivmodsi4(su_int a, su_int b, su_int* rem);
     81 COMPILER_RT_ABI du_int __udivmoddi4(du_int a, du_int b, du_int* rem);
     82 #ifdef CRT_HAS_128BIT
     83 COMPILER_RT_ABI si_int __clzti2(ti_int a);
     84 COMPILER_RT_ABI tu_int __udivmodti4(tu_int a, tu_int b, tu_int* rem);
     85 #endif
     86 
     87 /* Definitions for builtins unavailable on MSVC */
     88 #if defined(_MSC_VER) && !defined(__clang__)
     89 #include <intrin.h>
     90 
     91 uint32_t __inline __builtin_ctz(uint32_t value) {
     92   unsigned long trailing_zero = 0;
     93   if (_BitScanForward(&trailing_zero, value))
     94     return trailing_zero;
     95   return 32;
     96 }
     97 
     98 uint32_t __inline __builtin_clz(uint32_t value) {
     99   unsigned long leading_zero = 0;
    100   if (_BitScanReverse(&leading_zero, value))
    101     return 31 - leading_zero;
    102   return 32;
    103 }
    104 
    105 #if defined(_M_ARM) || defined(_M_X64)
    106 uint32_t __inline __builtin_clzll(uint64_t value) {
    107   unsigned long leading_zero = 0;
    108   if (_BitScanReverse64(&leading_zero, value))
    109     return 63 - leading_zero;
    110   return 64;
    111 }
    112 #else
    113 uint32_t __inline __builtin_clzll(uint64_t value) {
    114   if (value == 0)
    115     return 64;
    116   uint32_t msh = (uint32_t)(value >> 32);
    117   uint32_t lsh = (uint32_t)(value & 0xFFFFFFFF);
    118   if (msh != 0)
    119     return __builtin_clz(msh);
    120   return 32 + __builtin_clz(lsh);
    121 }
    122 #endif
    123 
    124 #define __builtin_clzl __builtin_clzll
    125 #endif /* defined(_MSC_VER) && !defined(__clang__) */
    126 
    127 #endif /* INT_LIB_H */
    128