1// -*- C++ -*-
2//===----------------------- support/win32/support.h ----------------------===//
3//
4//                     The LLVM Compiler Infrastructure
5//
6// This file is dual licensed under the MIT and the University of Illinois Open
7// Source Licenses. See LICENSE.TXT for details.
8//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP_SUPPORT_WIN32_SUPPORT_H
12#define _LIBCPP_SUPPORT_WIN32_SUPPORT_H
13
14// Functions and constants used in libc++ that
15// are missing from the Windows C library.
16
17#include <wchar.h> // mbstate_t
18#include <cstdarg> // va_ macros
19// "builtins" not implemented here for Clang or GCC as they provide
20// implementations. Assuming required for elsewhere else, certainly MSVC.
21#if defined(_LIBCPP_MSVC)
22#include <intrin.h>
23#endif
24#if defined(_LIBCPP_MSVCRT)
25#include <xlocinfo.h>
26#endif
27#define swprintf _snwprintf
28#define vswprintf _vsnwprintf
29
30#ifndef NOMINMAX
31#define NOMINMAX
32#endif
33
34extern "C" {
35
36int vasprintf(char **sptr, const char *__restrict fmt, va_list ap);
37int asprintf(char **sptr, const char *__restrict fmt, ...);
38size_t mbsnrtowcs(wchar_t *__restrict dst, const char **__restrict src,
39                  size_t nmc, size_t len, mbstate_t *__restrict ps);
40size_t wcsnrtombs(char *__restrict dst, const wchar_t **__restrict src,
41                  size_t nwc, size_t len, mbstate_t *__restrict ps);
42}
43
44#if defined(_LIBCPP_MSVCRT)
45#define snprintf _snprintf
46#define atoll _atoi64
47#define strtoll _strtoi64
48#define strtoull _strtoui64
49#define wcstoll _wcstoi64
50#define wcstoull _wcstoui64
51_LIBCPP_ALWAYS_INLINE float strtof(const char *nptr, char **endptr)
52{
53  return _Stof(nptr, endptr, 0);
54}
55_LIBCPP_ALWAYS_INLINE double strtod(const char *nptr, char **endptr)
56{
57  return _Stod(nptr, endptr, 0);
58}
59_LIBCPP_ALWAYS_INLINE long double strtold(const char *nptr, char **endptr)
60{
61  return _Stold(nptr, endptr, 0);
62}
63
64#define _Exit _exit
65#endif
66
67#if defined(_LIBCPP_MSVC)
68
69// Bit builtin's make these assumptions when calling _BitScanForward/Reverse
70// etc. These assumptions are expected to be true for Win32/Win64 which this
71// file supports.
72static_assert(sizeof(unsigned long long) == 8, "");
73static_assert(sizeof(unsigned long) == 4, "");
74static_assert(sizeof(unsigned int) == 4, "");
75
76_LIBCPP_ALWAYS_INLINE int __builtin_popcount(unsigned int x)
77{
78  // Binary: 0101...
79  static const unsigned int m1 = 0x55555555;
80  // Binary: 00110011..
81  static const unsigned int m2 = 0x33333333;
82  // Binary:  4 zeros,  4 ones ...
83  static const unsigned int m4 = 0x0f0f0f0f;
84  // The sum of 256 to the power of 0,1,2,3...
85  static const unsigned int h01 = 0x01010101;
86  // Put count of each 2 bits into those 2 bits.
87  x -= (x >> 1) & m1;
88  // Put count of each 4 bits into those 4 bits.
89  x = (x & m2) + ((x >> 2) & m2);
90  // Put count of each 8 bits into those 8 bits.
91  x = (x + (x >> 4)) & m4;
92  // Returns left 8 bits of x + (x<<8) + (x<<16) + (x<<24).
93  return (x * h01) >> 24;
94}
95
96_LIBCPP_ALWAYS_INLINE int __builtin_popcountl(unsigned long x)
97{
98  return __builtin_popcount(static_cast<int>(x));
99}
100
101_LIBCPP_ALWAYS_INLINE int __builtin_popcountll(unsigned long long x)
102{
103  // Binary: 0101...
104  static const unsigned long long m1 = 0x5555555555555555;
105  // Binary: 00110011..
106  static const unsigned long long m2 = 0x3333333333333333;
107  // Binary:  4 zeros,  4 ones ...
108  static const unsigned long long m4 = 0x0f0f0f0f0f0f0f0f;
109  // The sum of 256 to the power of 0,1,2,3...
110  static const unsigned long long h01 = 0x0101010101010101;
111  // Put count of each 2 bits into those 2 bits.
112  x -= (x >> 1) & m1;
113  // Put count of each 4 bits into those 4 bits.
114  x = (x & m2) + ((x >> 2) & m2);
115  // Put count of each 8 bits into those 8 bits.
116  x = (x + (x >> 4)) & m4;
117  // Returns left 8 bits of x + (x<<8) + (x<<16) + (x<<24) + ...
118  return static_cast<int>((x * h01) >> 56);
119}
120
121// Returns the number of trailing 0-bits in x, starting at the least significant
122// bit position. If x is 0, the result is undefined.
123_LIBCPP_ALWAYS_INLINE int __builtin_ctzll(unsigned long long mask)
124{
125  unsigned long where;
126// Search from LSB to MSB for first set bit.
127// Returns zero if no set bit is found.
128#if defined(_WIN64)
129  if (_BitScanForward64(&where, mask))
130    return static_cast<int>(where);
131#elif defined(_WIN32)
132  // Win32 doesn't have _BitScanForward64 so emulate it with two 32 bit calls.
133  // Scan the Low Word.
134  if (_BitScanForward(&where, static_cast<unsigned long>(mask)))
135    return static_cast<int>(where);
136  // Scan the High Word.
137  if (_BitScanForward(&where, static_cast<unsigned long>(mask >> 32)))
138    return static_cast<int>(where + 32); // Create a bit offset from the LSB.
139#else
140#error "Implementation of __builtin_ctzll required"
141#endif
142  return 64;
143}
144
145_LIBCPP_ALWAYS_INLINE int __builtin_ctzl(unsigned long mask)
146{
147  unsigned long where;
148  // Search from LSB to MSB for first set bit.
149  // Returns zero if no set bit is found.
150  if (_BitScanForward(&where, mask))
151    return static_cast<int>(where);
152  return 32;
153}
154
155_LIBCPP_ALWAYS_INLINE int __builtin_ctz(unsigned int mask)
156{
157  // Win32 and Win64 expectations.
158  static_assert(sizeof(mask) == 4, "");
159  static_assert(sizeof(unsigned long) == 4, "");
160  return __builtin_ctzl(static_cast<unsigned long>(mask));
161}
162
163// Returns the number of leading 0-bits in x, starting at the most significant
164// bit position. If x is 0, the result is undefined.
165_LIBCPP_ALWAYS_INLINE int __builtin_clzll(unsigned long long mask)
166{
167  unsigned long where;
168// BitScanReverse scans from MSB to LSB for first set bit.
169// Returns 0 if no set bit is found.
170#if defined(_WIN64)
171  if (_BitScanReverse64(&where, mask))
172    return static_cast<int>(63 - where);
173#elif defined(_WIN32)
174  // Scan the high 32 bits.
175  if (_BitScanReverse(&where, static_cast<unsigned long>(mask >> 32)))
176    return static_cast<int>(63 -
177                            (where + 32)); // Create a bit offset from the MSB.
178  // Scan the low 32 bits.
179  if (_BitScanReverse(&where, static_cast<unsigned long>(mask)))
180    return static_cast<int>(63 - where);
181#else
182#error "Implementation of __builtin_clzll required"
183#endif
184  return 64; // Undefined Behavior.
185}
186
187_LIBCPP_ALWAYS_INLINE int __builtin_clzl(unsigned long mask)
188{
189  unsigned long where;
190  // Search from LSB to MSB for first set bit.
191  // Returns zero if no set bit is found.
192  if (_BitScanReverse(&where, mask))
193    return static_cast<int>(31 - where);
194  return 32; // Undefined Behavior.
195}
196
197_LIBCPP_ALWAYS_INLINE int __builtin_clz(unsigned int x)
198{
199  return __builtin_clzl(x);
200}
201#endif // _LIBCPP_MSVC
202
203#endif // _LIBCPP_SUPPORT_WIN32_SUPPORT_H
204