source: trunk/lib/builtins.hpp @ 1885

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

MSVC scanword types

File size: 3.5 KB
RevLine 
[1509]1/*
[1528]2    builtin - Compiler dependent builtin function wrappers.
[1509]3
4    Idealized SIMD Operations with SSE versions
[1528]5    Copyright (C) 2011, Robert D. Cameron, Kenneth S. Herdy.
[1509]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
[1528]11#ifndef BUILTINS_HPP_
12#define BUILTINS_HPP_
[1509]13
14#include "config.hpp"
15
[1550]16static IDISA_ALWAYS_INLINE long likely(long x);
17static IDISA_ALWAYS_INLINE long unlikely(long x);
[1509]18
[1528]19#if defined (_MSC_VER)
[1550]20        IDISA_ALWAYS_INLINE long likely(long x) {
[1509]21                return x;
22        }
[1550]23        IDISA_ALWAYS_INLINE long unlikely(long x) {
[1509]24                return x;
25        }
[1528]26
[1860]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
[1528]43#elif defined (__GNUC__)
[1550]44
45        IDISA_ALWAYS_INLINE long likely(long x) {
[1509]46                return __builtin_expect(x, 1);
47        }
[1528]48
[1550]49        IDISA_ALWAYS_INLINE long unlikely(long x) {
[1509]50                return __builtin_expect(x, 0);
51        }
[1528]52
[1860]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
[1509]63#endif
64
[1848]65#include <stdint.h>
66#if defined (_MSC_VER)
67        #include <intrin.h>
68
[1878]69        #ifdef _WIN64
[1885]70        typedef unsigned __int64 scanword_t;
[1848]71        #define ScanForwardIntrinsic _BitScanForward64
72        #define ScanReverseIntrinsic _BitScanReverse64
73        #else
[1885]74        typedef unsigned long scanword_t;
[1848]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
[1853]93        #undef ScanForwardIntrinsic
94        #undef ScanReverseIntrinsic
95
[1848]96#elif defined (__GNUC__)
97
[1862]98        #if __x86_64__ /* 64-bit architecture */
[1848]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
[1856]114                return (uint32_t) ScanReverseIntrinsic((scanword_t) x);
[1848]115        }
116
[1853]117        #undef ScanForwardIntrinsic
118        #undef ScanReverseIntrinsic
119
[1848]120#else
[1850]121# ifndef _MSC_VER
[1848]122  #warning "Neither _MSC_VER nor __GNUC__ defined: scan_forward/backward_zeroes not implemented."
[1850]123# endif
[1848]124#endif
125
[1528]126#endif /* BUILTINS_HPP */
Note: See TracBrowser for help on using the repository browser.