source: trunk/lib/builtins.hpp @ 1878

Last change on this file since 1878 was 1878, checked in by cameron, 8 years ago

WIN64 ifdef fix

File size: 3.5 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);
18
19#if defined (_MSC_VER)
20        IDISA_ALWAYS_INLINE long likely(long x) {
21                return x;
22        }
23        IDISA_ALWAYS_INLINE long unlikely(long x) {
24                return x;
25        }
26
27        // DEPRECATED - USE scan_forward_zeroes
28        #include <intrin.h>
29        #pragma intrinsic(_BitScanForward)
30        IDISA_ALWAYS_INLINE unsigned long cfzl(unsigned long x) { // Precondition: x > 0
31                unsigned long zeroes;
32                _BitScanForward(&zeroes, x);
33                return zeroes;
34        }
35
36        // DEPRECATED - USE scan_backward_zeroes
37        IDISA_ALWAYS_INLINE unsigned long cbzl(unsigned long x) {
38                unsigned long zeroes;
39                _BitScanReverse(&zeroes, x);
40                return zeroes;
41        }
42
43#elif defined (__GNUC__)
44
45        IDISA_ALWAYS_INLINE long likely(long x) {
46                return __builtin_expect(x, 1);
47        }
48
49        IDISA_ALWAYS_INLINE long unlikely(long x) {
50                return __builtin_expect(x, 0);
51        }
52
53        // DEPRECATED - USE scan_forward_zeroes
54        IDISA_ALWAYS_INLINE unsigned long cfzl(unsigned long x) {
55                return __builtin_ctzl(x);
56        }
57
58        // DEPRECATED - USE scan_backward_zeroes
59        IDISA_ALWAYS_INLINE unsigned long cbzl(unsigned long x) {
60                return __builtin_clzl(x);
61        }
62
63#endif
64
65#include <stdint.h>
66#if defined (_MSC_VER)
67        #include <intrin.h>
68
69        #ifdef _WIN64
70        typedef uint64_t scanword_t;
71        #define ScanForwardIntrinsic _BitScanForward64
72        #define ScanReverseIntrinsic _BitScanReverse64
73        #else
74        typedef uint32_t scanword_t;
75        #define ScanForwardIntrinsic _BitScanForward
76        #define ScanReverseIntrinsic _BitScanReverse
77        #endif
78
79        #pragma intrinsic(ScanForwardIntrinsic)
80        #pragma intrinsic(ScanReverseIntrinsic)
81        IDISA_ALWAYS_INLINE uint32_t scan_forward_zeroes(scanword_t x) { // Precondition: x > 0
82                unsigned long zeroes;
83                ScanForwardIntrinsic(&zeroes, x);
84                return (uint32_t) zeroes;
85        }
86
87        IDISA_ALWAYS_INLINE uint32_t scan_backward_zeroes(scanword_t x) { // Precondition: x > 0
88                unsigned long zeroes;
89                ScanReverseIntrinsic(&zeroes, x);
90                return (uint32_t) zeroes;
91        }
92
93        #undef ScanForwardIntrinsic
94        #undef ScanReverseIntrinsic
95
96#elif defined (__GNUC__)
97
98        #if __x86_64__ /* 64-bit architecture */
99        typedef uint64_t scanword_t;
100        #define ScanForwardIntrinsic __builtin_ctzll
101        #define ScanReverseIntrinsic __builtin_clzll
102
103        #else
104        typedef uint32_t scanword_t;
105        #define ScanForwardIntrinsic __builtin_ctzl
106        #define ScanReverseIntrinsic __builtin_clzl
107        #endif
108
109        IDISA_ALWAYS_INLINE uint32_t scan_forward_zeroes(scanword_t x) { // Precondition: x > 0
110                return (uint32_t) ScanForwardIntrinsic((scanword_t) x);
111        }
112
113        IDISA_ALWAYS_INLINE uint32_t scan_backward_zeroes(scanword_t x) { // Precondition: x > 0
114                return (uint32_t) ScanReverseIntrinsic((scanword_t) x);
115        }
116
117        #undef ScanForwardIntrinsic
118        #undef ScanReverseIntrinsic
119
120#else
121# ifndef _MSC_VER
122  #warning "Neither _MSC_VER nor __GNUC__ defined: scan_forward/backward_zeroes not implemented."
123# endif
124#endif
125
126#endif /* BUILTINS_HPP */
Note: See TracBrowser for help on using the repository browser.