source: trunk/lib/builtins.hpp @ 4027

Last change on this file since 4027 was 3392, checked in by cameron, 6 years ago

Return int rather than uint32_t saves a conversion

File size: 2.8 KB
RevLine 
[1950]1#ifndef BUILTINS_HPP_
2#define BUILTINS_HPP_
3
4/*=============================================================================
[1528]5    builtin - Compiler dependent builtin function wrappers.
[1509]6
[1528]7    Copyright (C) 2011, Robert D. Cameron, Kenneth S. Herdy.
[1509]8    Licensed to the public under the Open Software License 3.0.
9    Licensed to International Characters Inc.
[2594]10       under the Academic Free License version 3.0.
[1950]11=============================================================================*/
[1509]12
13#include "config.hpp"
14
[1550]15static IDISA_ALWAYS_INLINE long likely(long x);
16static IDISA_ALWAYS_INLINE long unlikely(long x);
[1509]17
[1528]18#if defined (_MSC_VER)
[1550]19        IDISA_ALWAYS_INLINE long likely(long x) {
[1509]20                return x;
21        }
[1550]22        IDISA_ALWAYS_INLINE long unlikely(long x) {
[1509]23                return x;
24        }
[1528]25
26#elif defined (__GNUC__)
[1550]27
28        IDISA_ALWAYS_INLINE long likely(long x) {
[1509]29                return __builtin_expect(x, 1);
30        }
[1528]31
[1550]32        IDISA_ALWAYS_INLINE long unlikely(long x) {
[1509]33                return __builtin_expect(x, 0);
34        }
[1528]35
[1509]36#endif
37
[1848]38#include <stdint.h>
39#if defined (_MSC_VER)
40        #include <intrin.h>
41
[2220]42        #ifdef _M_X64
[2594]43        typedef unsigned __int64 ScanWord;
[1848]44        #define ScanForwardIntrinsic _BitScanForward64
45        #define ScanReverseIntrinsic _BitScanReverse64
46        #else
[2594]47        typedef unsigned __int32 ScanWord;
[1848]48        #define ScanForwardIntrinsic _BitScanForward
49        #define ScanReverseIntrinsic _BitScanReverse
50        #endif
51
52        #pragma intrinsic(ScanForwardIntrinsic)
53        #pragma intrinsic(ScanReverseIntrinsic)
[2594]54        IDISA_ALWAYS_INLINE uint32_t scan_forward_zeroes(ScanWord x) { // Precondition: x != 0
[1848]55                unsigned long zeroes;
56                ScanForwardIntrinsic(&zeroes, x);
57                return (uint32_t) zeroes;
58        }
59
[2594]60        IDISA_ALWAYS_INLINE uint32_t scan_backward_zeroes(ScanWord x) { // Precondition: x != 0
[1904]61                unsigned long pos;
[1905]62                ScanReverseIntrinsic(&pos, x);
[2594]63                return (uint32_t) (8* sizeof(ScanWord) - pos - 1);
[1848]64        }
65
[1853]66        #undef ScanForwardIntrinsic
67        #undef ScanReverseIntrinsic
68
[1848]69#elif defined (__GNUC__)
70
[1862]71        #if __x86_64__ /* 64-bit architecture */
[2594]72        typedef uint64_t ScanWord;
[1848]73        #define ScanForwardIntrinsic __builtin_ctzll
74        #define ScanReverseIntrinsic __builtin_clzll
75
76        #else
[2594]77        typedef uint32_t ScanWord;
[1848]78        #define ScanForwardIntrinsic __builtin_ctzl
79        #define ScanReverseIntrinsic __builtin_clzl
80        #endif
81
[3392]82        IDISA_ALWAYS_INLINE int scan_forward_zeroes(ScanWord x) { // Precondition: x != 0
83                return ScanForwardIntrinsic((ScanWord) x);
[1848]84        }
85
[3392]86        IDISA_ALWAYS_INLINE int scan_backward_zeroes(ScanWord x) { // Precondition: x != 0
87                return ScanReverseIntrinsic((ScanWord) x);
[1848]88        }
89
[1853]90        #undef ScanForwardIntrinsic
91        #undef ScanReverseIntrinsic
92
[1848]93#else
94  #warning "Neither _MSC_VER nor __GNUC__ defined: scan_forward/backward_zeroes not implemented."
95#endif
96
[1950]97#endif // BUILTINS_HPP
Note: See TracBrowser for help on using the repository browser.