1/****************************************************************************
2* Copyright (C) 2014-2015 Intel Corporation.   All Rights Reserved.
3*
4* Permission is hereby granted, free of charge, to any person obtaining a
5* copy of this software and associated documentation files (the "Software"),
6* to deal in the Software without restriction, including without limitation
7* the rights to use, copy, modify, merge, publish, distribute, sublicense,
8* and/or sell copies of the Software, and to permit persons to whom the
9* Software is furnished to do so, subject to the following conditions:
10*
11* The above copyright notice and this permission notice (including the next
12* paragraph) shall be included in all copies or substantial portions of the
13* Software.
14*
15* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21* IN THE SOFTWARE.
22****************************************************************************/
23
24#ifndef __SWR_OS_H__
25#define __SWR_OS_H__
26
27#include <cstddef>
28#include "core/knobs.h"
29
30#if (defined(FORCE_WINDOWS) || defined(_WIN32)) && !defined(FORCE_LINUX)
31
32#define SWR_API __cdecl
33
34#ifndef NOMINMAX
35#define NOMINMAX
36#include <windows.h>
37#undef NOMINMAX
38#else
39#include <windows.h>
40#endif
41#include <intrin.h>
42#include <cstdint>
43
44#if defined(MemoryFence)
45// Windows.h defines MemoryFence as _mm_mfence, but this conflicts with llvm::sys::MemoryFence
46#undef MemoryFence
47#endif
48
49#define OSALIGN(RWORD, WIDTH) __declspec(align(WIDTH)) RWORD
50#define THREAD __declspec(thread)
51#define INLINE __forceinline
52#define DEBUGBREAK __debugbreak()
53
54#define PRAGMA_WARNING_PUSH_DISABLE(...) \
55    __pragma(warning(push));\
56    __pragma(warning(disable:__VA_ARGS__));
57
58#define PRAGMA_WARNING_POP() __pragma(warning(pop))
59
60static inline void *AlignedMalloc(size_t _Size, size_t _Alignment)
61{
62    return _aligned_malloc(_Size, _Alignment);
63}
64
65static inline void AlignedFree(void* p)
66{
67    return _aligned_free(p);
68}
69
70#if defined(_WIN64)
71#define BitScanReverseSizeT BitScanReverse64
72#define BitScanForwardSizeT BitScanForward64
73#define _mm_popcount_sizeT _mm_popcnt_u64
74#else
75#define BitScanReverseSizeT BitScanReverse
76#define BitScanForwardSizeT BitScanForward
77#define _mm_popcount_sizeT _mm_popcnt_u32
78#endif
79
80#elif defined(__APPLE__) || defined(FORCE_LINUX) || defined(__linux__) || defined(__gnu_linux__)
81
82#define SWR_API
83
84#include <stdlib.h>
85#include <string.h>
86#include <x86intrin.h>
87#include <stdint.h>
88#include <sys/types.h>
89#include <unistd.h>
90#include <sys/stat.h>
91#include <stdio.h>
92#include <limits.h>
93
94typedef void            VOID;
95typedef void*           LPVOID;
96typedef int             INT;
97typedef unsigned int    UINT;
98typedef void*           HANDLE;
99typedef int             LONG;
100typedef unsigned int    DWORD;
101
102#undef FALSE
103#define FALSE 0
104
105#undef TRUE
106#define TRUE 1
107
108#define MAX_PATH PATH_MAX
109
110#define OSALIGN(RWORD, WIDTH) RWORD __attribute__((aligned(WIDTH)))
111#define THREAD __thread
112#ifndef INLINE
113#define INLINE __inline
114#endif
115#define DEBUGBREAK asm ("int $3")
116
117#if !defined(__CYGWIN__)
118
119#ifndef __cdecl
120#define __cdecl
121#endif
122#ifndef __stdcall
123#define __stdcall
124#endif
125
126#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
127    #define __declspec(x)           __declspec_##x
128    #define __declspec_align(y)     __attribute__((aligned(y)))
129    #define __declspec_deprecated   __attribute__((deprecated))
130    #define __declspec_dllexport
131    #define __declspec_dllimport
132    #define __declspec_noinline     __attribute__((__noinline__))
133    #define __declspec_nothrow      __attribute__((nothrow))
134    #define __declspec_novtable
135    #define __declspec_thread       __thread
136#else
137    #define __declspec(X)
138#endif
139
140#endif
141
142#define GCC_VERSION (__GNUC__ * 10000 \
143                     + __GNUC_MINOR__ * 100 \
144                     + __GNUC_PATCHLEVEL__)
145
146#if !defined(__clang__) && (__GNUC__) && (GCC_VERSION < 40500)
147inline
148uint64_t __rdtsc()
149{
150    long low, high;
151    asm volatile("rdtsc" : "=a"(low), "=d"(high));
152    return (low | ((uint64_t)high << 32));
153}
154#endif
155
156#if !defined( __clang__) && !defined(__INTEL_COMPILER)
157// Intrinsic not defined in gcc
158static INLINE
159void _mm256_storeu2_m128i(__m128i *hi, __m128i *lo, __m256i a)
160{
161    _mm_storeu_si128((__m128i*)lo, _mm256_castsi256_si128(a));
162    _mm_storeu_si128((__m128i*)hi, _mm256_extractf128_si256(a, 0x1));
163}
164#endif
165
166inline
167unsigned char _BitScanForward(unsigned long *Index, unsigned long Mask)
168{
169    *Index = __builtin_ctz(Mask);
170    return (Mask != 0);
171}
172
173inline
174unsigned char _BitScanForward(unsigned int *Index, unsigned int Mask)
175{
176    *Index = __builtin_ctz(Mask);
177    return (Mask != 0);
178}
179
180inline
181unsigned char _BitScanReverse(unsigned long *Index, unsigned long Mask)
182{
183    *Index = __builtin_clz(Mask);
184    return (Mask != 0);
185}
186
187inline
188unsigned char _BitScanReverse(unsigned int *Index, unsigned int Mask)
189{
190    *Index = __builtin_clz(Mask);
191    return (Mask != 0);
192}
193
194inline
195void *AlignedMalloc(unsigned int size, unsigned int alignment)
196{
197    void *ret;
198    if (posix_memalign(&ret, alignment, size))
199    {
200        return NULL;
201    }
202    return ret;
203}
204
205inline
206unsigned char _bittest(const LONG *a, LONG b)
207{
208    return ((*(unsigned *)(a) & (1 << b)) != 0);
209}
210
211static inline
212void AlignedFree(void* p)
213{
214    free(p);
215}
216
217#define _countof(a) (sizeof(a)/sizeof(*(a)))
218
219#define sprintf_s sprintf
220#define strcpy_s(dst,size,src) strncpy(dst,src,size)
221#define GetCurrentProcessId getpid
222pid_t gettid(void);
223#define GetCurrentThreadId gettid
224
225#define CreateDirectory(name, pSecurity) mkdir(name, 0777)
226
227#define InterlockedCompareExchange(Dest, Exchange, Comparand) __sync_val_compare_and_swap(Dest, Comparand, Exchange)
228#define InterlockedExchangeAdd(Addend, Value) __sync_fetch_and_add(Addend, Value)
229#define InterlockedDecrement(Append) __sync_sub_and_fetch(Append, 1)
230#define InterlockedDecrement64(Append) __sync_sub_and_fetch(Append, 1)
231#define InterlockedIncrement(Append) __sync_add_and_fetch(Append, 1)
232#define InterlockedAdd(Addend, Value) __sync_add_and_fetch(Addend, Value)
233#define InterlockedAdd64(Addend, Value) __sync_add_and_fetch(Addend, Value)
234#define _ReadWriteBarrier() asm volatile("" ::: "memory")
235
236#define PRAGMA_WARNING_PUSH_DISABLE(...)
237#define PRAGMA_WARNING_POP()
238
239#else
240
241#error Unsupported OS/system.
242
243#endif
244
245// Universal types
246typedef uint8_t     KILOBYTE[1024];
247typedef KILOBYTE    MEGABYTE[1024];
248typedef MEGABYTE    GIGABYTE[1024];
249
250#define OSALIGNLINE(RWORD) OSALIGN(RWORD, 64)
251#define OSALIGNSIMD(RWORD) OSALIGN(RWORD, KNOB_SIMD_BYTES)
252#if ENABLE_AVX512_SIMD16
253#define OSALIGNSIMD16(RWORD) OSALIGN(RWORD, KNOB_SIMD16_BYTES)
254#endif
255
256#include "common/swr_assert.h"
257
258#ifdef __GNUC__
259#define ATTR_UNUSED __attribute__((unused))
260#else
261#define ATTR_UNUSED
262#endif
263
264#endif//__SWR_OS_H__
265