Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
stenzek
GitHub Repository: stenzek/duckstation
Path: blob/master/dep/vixl/src/compiler-intrinsics-vixl.cc
4253 views
1
// Copyright 2015, VIXL authors
2
// All rights reserved.
3
//
4
// Redistribution and use in source and binary forms, with or without
5
// modification, are permitted provided that the following conditions are met:
6
//
7
// * Redistributions of source code must retain the above copyright notice,
8
// this list of conditions and the following disclaimer.
9
// * Redistributions in binary form must reproduce the above copyright notice,
10
// this list of conditions and the following disclaimer in the documentation
11
// and/or other materials provided with the distribution.
12
// * Neither the name of ARM Limited nor the names of its contributors may be
13
// used to endorse or promote products derived from this software without
14
// specific prior written permission.
15
//
16
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27
#include "compiler-intrinsics-vixl.h"
28
29
#include "utils-vixl.h"
30
31
namespace vixl {
32
33
34
int CountLeadingSignBitsFallBack(int64_t value, int width) {
35
VIXL_ASSERT(IsPowerOf2(width) && (width <= 64));
36
if (width < 64) VIXL_ASSERT(IsIntN(width, value));
37
if (value >= 0) {
38
return CountLeadingZeros(value, width) - 1;
39
} else {
40
return CountLeadingZeros(~value, width) - 1;
41
}
42
}
43
44
45
int CountLeadingZerosFallBack(uint64_t value, int width) {
46
VIXL_ASSERT(IsPowerOf2(width) && (width <= 64));
47
if (value == 0) {
48
return width;
49
}
50
int count = 0;
51
value = value << (64 - width);
52
if ((value & UINT64_C(0xffffffff00000000)) == 0) {
53
count += 32;
54
value = value << 32;
55
}
56
if ((value & UINT64_C(0xffff000000000000)) == 0) {
57
count += 16;
58
value = value << 16;
59
}
60
if ((value & UINT64_C(0xff00000000000000)) == 0) {
61
count += 8;
62
value = value << 8;
63
}
64
if ((value & UINT64_C(0xf000000000000000)) == 0) {
65
count += 4;
66
value = value << 4;
67
}
68
if ((value & UINT64_C(0xc000000000000000)) == 0) {
69
count += 2;
70
value = value << 2;
71
}
72
if ((value & UINT64_C(0x8000000000000000)) == 0) {
73
count += 1;
74
}
75
count += (value == 0);
76
return count;
77
}
78
79
80
int CountSetBitsFallBack(uint64_t value, int width) {
81
VIXL_ASSERT(IsPowerOf2(width) && (width <= 64));
82
83
// Mask out unused bits to ensure that they are not counted.
84
value &= (UINT64_C(0xffffffffffffffff) >> (64 - width));
85
86
// Add up the set bits.
87
// The algorithm works by adding pairs of bit fields together iteratively,
88
// where the size of each bit field doubles each time.
89
// An example for an 8-bit value:
90
// Bits: h g f e d c b a
91
// \ | \ | \ | \ |
92
// value = h+g f+e d+c b+a
93
// \ | \ |
94
// value = h+g+f+e d+c+b+a
95
// \ |
96
// value = h+g+f+e+d+c+b+a
97
const uint64_t kMasks[] = {
98
UINT64_C(0x5555555555555555),
99
UINT64_C(0x3333333333333333),
100
UINT64_C(0x0f0f0f0f0f0f0f0f),
101
UINT64_C(0x00ff00ff00ff00ff),
102
UINT64_C(0x0000ffff0000ffff),
103
UINT64_C(0x00000000ffffffff),
104
};
105
106
for (unsigned i = 0; i < (sizeof(kMasks) / sizeof(kMasks[0])); i++) {
107
int shift = 1 << i;
108
value = ((value >> shift) & kMasks[i]) + (value & kMasks[i]);
109
}
110
111
return static_cast<int>(value);
112
}
113
114
115
int CountTrailingZerosFallBack(uint64_t value, int width) {
116
VIXL_ASSERT(IsPowerOf2(width) && (width <= 64));
117
int count = 0;
118
value = value << (64 - width);
119
if ((value & UINT64_C(0xffffffff)) == 0) {
120
count += 32;
121
value = value >> 32;
122
}
123
if ((value & 0xffff) == 0) {
124
count += 16;
125
value = value >> 16;
126
}
127
if ((value & 0xff) == 0) {
128
count += 8;
129
value = value >> 8;
130
}
131
if ((value & 0xf) == 0) {
132
count += 4;
133
value = value >> 4;
134
}
135
if ((value & 0x3) == 0) {
136
count += 2;
137
value = value >> 2;
138
}
139
if ((value & 0x1) == 0) {
140
count += 1;
141
}
142
count += (value == 0);
143
return count - (64 - width);
144
}
145
146
147
} // namespace vixl
148
149