source: trunk/lib/builtins.hpp @ 1850

Last change on this file since 1850 was 1850, checked in by cameron, 7 years ago

Disable #warning for MSVC

File size: 4.1 KB
Line 
1/*
2    builtin - Compiler dependent builtin function wrappers.
3
4    Idealized SIMD Operations with SSE versions
5    Copyright (C) 2011, Robert D. Cameron, Kenneth S. Herdy.
6    Licensed to the public under the Open Software License 3.0.
7    Licensed to International Characters Inc.
8       under the Academic Free License version 3.0.
9 */
10
11#ifndef BUILTINS_HPP_
12#define BUILTINS_HPP_
13
14#include "config.hpp"
15
16static IDISA_ALWAYS_INLINE long likely(long x);
17static IDISA_ALWAYS_INLINE long unlikely(long x);
18static IDISA_ALWAYS_INLINE unsigned long cfzl(unsigned long x);
19static IDISA_ALWAYS_INLINE unsigned long cbzl(unsigned long x);
20//static IDISA_ALWAYS_INLINE unsigned long cfzll(unsigned long long x);
21//static IDISA_ALWAYS_INLINE unsigned long cbzll(unsigned long long x);
22
23#if defined (_MSC_VER)
24        IDISA_ALWAYS_INLINE long likely(long x) {
25                return x;
26        }
27        IDISA_ALWAYS_INLINE long unlikely(long x) {
28                return x;
29        }
30
31        #include <intrin.h>
32        #pragma intrinsic(_BitScanForward)
33        IDISA_ALWAYS_INLINE unsigned long cfzl(unsigned long x) { // Precondition: x > 0
34                unsigned long zeroes;
35                _BitScanForward(&zeroes, x);
36                return zeroes;
37        }
38
39        IDISA_ALWAYS_INLINE unsigned long cbzl(unsigned long x) {
40                unsigned long zeroes;
41                _BitScanReverse(&zeroes, x);
42                return zeroes;
43        }
44
45//      IDISA_ALWAYS_INLINE unsigned long cfzll(unsigned long long x) { // TODO - test
46//              unsigned __int64 zeroes;
47//              _BitScanForward(&zeroes, x);
48//              return zeroes;
49//      }
50
51//      IDISA_ALWAYS_INLINE unsigned long cbzll(unsigned long long x) { // TODO - test
52//              unsigned __int64 zeroes;
53//              _BitScanReverse(&zeroes, x);
54//              return zeroes;
55//      }
56
57#elif defined (__GNUC__)
58
59        IDISA_ALWAYS_INLINE long likely(long x) {
60                return __builtin_expect(x, 1);
61        }
62
63        IDISA_ALWAYS_INLINE long unlikely(long x) {
64                return __builtin_expect(x, 0);
65        }
66
67        IDISA_ALWAYS_INLINE unsigned long cfzl(unsigned long x) {
68                return __builtin_ctzl(x);
69        }
70
71        IDISA_ALWAYS_INLINE unsigned long cbzl(unsigned long x) {
72                return __builtin_clzl(x);
73        }
74
75//      IDISA_ALWAYS_INLINE unsigned long cfzll(unsigned long long x) {
76//              return __builtin_ctzll(x);
77//      }
78
79//      IDISA_ALWAYS_INLINE unsigned long cbzll(unsigned long long x) {
80//              return __builtin_clzll(x);
81//      }
82
83#endif
84
85#if 0
86        /* Partially refactored to encapsulate 32/64 bit scan distinctions.*/
87#include <stdint.h>
88#if defined (_MSC_VER)
89        #include <intrin.h>
90
91        #ifdef (_WIN64)
92        typedef uint64_t scanword_t;
93        #define ScanForwardIntrinsic _BitScanForward64
94        #define ScanReverseIntrinsic _BitScanReverse64
95        #else
96        typedef uint32_t scanword_t;
97        #define ScanForwardIntrinsic _BitScanForward
98        #define ScanReverseIntrinsic _BitScanReverse
99        #endif
100
101        #pragma intrinsic(ScanForwardIntrinsic)
102        #pragma intrinsic(ScanReverseIntrinsic)
103        IDISA_ALWAYS_INLINE uint32_t scan_forward_zeroes(scanword_t x) { // Precondition: x > 0
104                unsigned long zeroes;
105                ScanForwardIntrinsic(&zeroes, x);
106                return (uint32_t) zeroes;
107        }
108
109        IDISA_ALWAYS_INLINE uint32_t scan_backward_zeroes(scanword_t x) { // Precondition: x > 0
110                unsigned long zeroes;
111                ScanReverseIntrinsic(&zeroes, x);
112                return (uint32_t) zeroes;
113        }
114
115#elif defined (__GNUC__)
116
117        #if UINTPTR_MAX == 0xffffffffffffffff  /* 64-bit architecture */
118        typedef uint64_t scanword_t;
119        #define ScanForwardIntrinsic __builtin_ctzll
120        #define ScanReverseIntrinsic __builtin_clzll
121
122        #else
123        typedef uint32_t scanword_t;
124        #define ScanForwardIntrinsic __builtin_ctzl
125        #define ScanReverseIntrinsic __builtin_clzl
126        #endif
127
128
129        IDISA_ALWAYS_INLINE uint32_t scan_forward_zeroes(scanword_t x) { // Precondition: x > 0
130                return (uint32_t) ScanForwardIntrinsic((scanword_t) x);
131        }
132
133        IDISA_ALWAYS_INLINE uint32_t scan_backward_zeroes(scanword_t x) { // Precondition: x > 0
134                return (uint32_t) ScanBackwardIntrinsic((scanword_t) x);
135        }
136
137#else
138# ifndef _MSC_VER
139  #warning "Neither _MSC_VER nor __GNUC__ defined: scan_forward/backward_zeroes not implemented."
140# endif
141#endif
142
143#endif
144
145#endif /* BUILTINS_HPP */
Note: See TracBrowser for help on using the repository browser.