annotate libhsail-rt/rt/bitstring.c @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* bitstring.c -- Builtins for HSAIL bitstring instructions.
kono
parents:
diff changeset
2
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3 Copyright (C) 2015-2020 Free Software Foundation, Inc.
111
kono
parents:
diff changeset
4 Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
kono
parents:
diff changeset
5 for General Processor Tech.
kono
parents:
diff changeset
6
kono
parents:
diff changeset
7 Permission is hereby granted, free of charge, to any person obtaining a
kono
parents:
diff changeset
8 copy of this software and associated documentation files
kono
parents:
diff changeset
9 (the "Software"), to deal in the Software without restriction, including
kono
parents:
diff changeset
10 without limitation the rights to use, copy, modify, merge, publish,
kono
parents:
diff changeset
11 distribute, sublicense, and/or sell copies of the Software, and to
kono
parents:
diff changeset
12 permit persons to whom the Software is furnished to do so, subject to
kono
parents:
diff changeset
13 the following conditions:
kono
parents:
diff changeset
14
kono
parents:
diff changeset
15 The above copyright notice and this permission notice shall be included
kono
parents:
diff changeset
16 in all copies or substantial portions of the Software.
kono
parents:
diff changeset
17
kono
parents:
diff changeset
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
kono
parents:
diff changeset
19 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
kono
parents:
diff changeset
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
kono
parents:
diff changeset
21 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
kono
parents:
diff changeset
22 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
kono
parents:
diff changeset
23 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
kono
parents:
diff changeset
24 USE OR OTHER DEALINGS IN THE SOFTWARE.
kono
parents:
diff changeset
25 */
kono
parents:
diff changeset
26
kono
parents:
diff changeset
27 #include <stdint.h>
kono
parents:
diff changeset
28 #include <limits.h>
kono
parents:
diff changeset
29
kono
parents:
diff changeset
30 #define BITEXTRACT(DEST_TYPE, SRC0, SRC1, SRC2) \
kono
parents:
diff changeset
31 uint32_t offset = SRC1 & (sizeof (DEST_TYPE) * 8 - 1); \
kono
parents:
diff changeset
32 uint32_t width = SRC2 & (sizeof (DEST_TYPE) * 8 - 1); \
kono
parents:
diff changeset
33 if (width == 0) \
kono
parents:
diff changeset
34 return 0; \
kono
parents:
diff changeset
35 else \
kono
parents:
diff changeset
36 return (SRC0 << (sizeof (DEST_TYPE) * 8 - width - offset)) \
kono
parents:
diff changeset
37 >> (sizeof (DEST_TYPE) * 8 - width)
kono
parents:
diff changeset
38
kono
parents:
diff changeset
39 uint32_t
kono
parents:
diff changeset
40 __hsail_bitextract_u32 (uint32_t src0, uint32_t src1, uint32_t src2)
kono
parents:
diff changeset
41 {
kono
parents:
diff changeset
42 BITEXTRACT (uint32_t, src0, src1, src2);
kono
parents:
diff changeset
43 }
kono
parents:
diff changeset
44
kono
parents:
diff changeset
45 int32_t
kono
parents:
diff changeset
46 __hsail_bitextract_s32 (int32_t src0, uint32_t src1, uint32_t src2)
kono
parents:
diff changeset
47 {
kono
parents:
diff changeset
48 BITEXTRACT (int32_t, src0, src1, src2);
kono
parents:
diff changeset
49 }
kono
parents:
diff changeset
50
kono
parents:
diff changeset
51 uint64_t
kono
parents:
diff changeset
52 __hsail_bitextract_u64 (uint64_t src0, uint32_t src1, uint32_t src2)
kono
parents:
diff changeset
53 {
kono
parents:
diff changeset
54 BITEXTRACT (uint64_t, src0, src1, src2);
kono
parents:
diff changeset
55 }
kono
parents:
diff changeset
56
kono
parents:
diff changeset
57 int64_t
kono
parents:
diff changeset
58 __hsail_bitextract_s64 (int64_t src0, uint32_t src1, uint32_t src2)
kono
parents:
diff changeset
59 {
kono
parents:
diff changeset
60 BITEXTRACT (int64_t, src0, src1, src2);
kono
parents:
diff changeset
61 }
kono
parents:
diff changeset
62
kono
parents:
diff changeset
63 #define BITINSERT(DEST_TYPE, SRC0, SRC1, SRC2, SRC3) \
kono
parents:
diff changeset
64 uint32_t offset = SRC2 & (sizeof (DEST_TYPE) * 8 - 1); \
kono
parents:
diff changeset
65 uint32_t width = SRC3 & (sizeof (DEST_TYPE) * 8 - 1); \
kono
parents:
diff changeset
66 DEST_TYPE mask = ((DEST_TYPE) 1 << width) - 1; \
kono
parents:
diff changeset
67 return (SRC0 & ~(mask << offset)) | ((SRC1 & mask) << offset)
kono
parents:
diff changeset
68
kono
parents:
diff changeset
69 uint32_t
kono
parents:
diff changeset
70 __hsail_bitinsert_u32 (uint32_t src0, uint32_t src1, uint32_t src2,
kono
parents:
diff changeset
71 uint32_t src3)
kono
parents:
diff changeset
72 {
kono
parents:
diff changeset
73 BITINSERT (uint32_t, src0, src1, src2, src3);
kono
parents:
diff changeset
74 }
kono
parents:
diff changeset
75
kono
parents:
diff changeset
76 int64_t
kono
parents:
diff changeset
77 __hsail_bitinsert_u64 (uint64_t src0, uint64_t src1, uint32_t src2,
kono
parents:
diff changeset
78 uint32_t src3)
kono
parents:
diff changeset
79 {
kono
parents:
diff changeset
80 BITINSERT (uint64_t, src0, src1, src2, src3);
kono
parents:
diff changeset
81 }
kono
parents:
diff changeset
82
kono
parents:
diff changeset
83 #define BITMASK(DEST_TYPE, SRC0, SRC1) \
kono
parents:
diff changeset
84 uint32_t offset = SRC0 & (sizeof (DEST_TYPE) * 8 - 1); \
kono
parents:
diff changeset
85 uint32_t width = SRC1 & (sizeof (DEST_TYPE) * 8 - 1); \
kono
parents:
diff changeset
86 DEST_TYPE mask = ((DEST_TYPE) 1 << width) - 1; \
kono
parents:
diff changeset
87 return mask << offset
kono
parents:
diff changeset
88
kono
parents:
diff changeset
89 uint32_t
kono
parents:
diff changeset
90 __hsail_bitmask_u32 (uint32_t src0, uint32_t src1)
kono
parents:
diff changeset
91 {
kono
parents:
diff changeset
92 BITMASK (uint32_t, src0, src1);
kono
parents:
diff changeset
93 }
kono
parents:
diff changeset
94
kono
parents:
diff changeset
95 uint64_t
kono
parents:
diff changeset
96 __hsail_bitmask_u64 (uint32_t src0, uint32_t src1)
kono
parents:
diff changeset
97 {
kono
parents:
diff changeset
98 BITMASK (uint64_t, src0, src1);
kono
parents:
diff changeset
99 }
kono
parents:
diff changeset
100
kono
parents:
diff changeset
101 /* The dummy, but readable version from
kono
parents:
diff changeset
102 http://graphics.stanford.edu/~seander/bithacks.html#BitReverseObvious
kono
parents:
diff changeset
103 This (also) often maps to a single instruction in DSPs. */
kono
parents:
diff changeset
104
kono
parents:
diff changeset
105 #define BITREV(DEST_TYPE, SRC) \
kono
parents:
diff changeset
106 DEST_TYPE v = SRC; \
kono
parents:
diff changeset
107 DEST_TYPE r = v; \
kono
parents:
diff changeset
108 int s = sizeof (SRC) * CHAR_BIT - 1; \
kono
parents:
diff changeset
109 \
kono
parents:
diff changeset
110 for (v >>= 1; v; v >>= 1) \
kono
parents:
diff changeset
111 { \
kono
parents:
diff changeset
112 r <<= 1; \
kono
parents:
diff changeset
113 r |= v & 1; \
kono
parents:
diff changeset
114 s--; \
kono
parents:
diff changeset
115 } \
kono
parents:
diff changeset
116 return r << s
kono
parents:
diff changeset
117
kono
parents:
diff changeset
118 uint32_t
kono
parents:
diff changeset
119 __hsail_bitrev_u32 (uint32_t src0)
kono
parents:
diff changeset
120 {
kono
parents:
diff changeset
121 BITREV (uint32_t, src0);
kono
parents:
diff changeset
122 }
kono
parents:
diff changeset
123
kono
parents:
diff changeset
124 uint64_t
kono
parents:
diff changeset
125 __hsail_bitrev_u64 (uint64_t src0)
kono
parents:
diff changeset
126 {
kono
parents:
diff changeset
127 BITREV (uint64_t, src0);
kono
parents:
diff changeset
128 }
kono
parents:
diff changeset
129
kono
parents:
diff changeset
130 uint32_t
kono
parents:
diff changeset
131 __hsail_bitselect_u32 (uint32_t src0, uint32_t src1, uint32_t src2)
kono
parents:
diff changeset
132 {
kono
parents:
diff changeset
133 return (src1 & src0) | (src2 & ~src0);
kono
parents:
diff changeset
134 }
kono
parents:
diff changeset
135
kono
parents:
diff changeset
136 uint64_t
kono
parents:
diff changeset
137 __hsail_bitselect_u64 (uint64_t src0, uint64_t src1, uint64_t src2)
kono
parents:
diff changeset
138 {
kono
parents:
diff changeset
139 return (src1 & src0) | (src2 & ~src0);
kono
parents:
diff changeset
140 }
kono
parents:
diff changeset
141
kono
parents:
diff changeset
142 /* Due to the defined behavior with 0, we cannot use the gcc builtin
kono
parents:
diff changeset
143 __builtin_clz* () directly. __builtin_ffs () has defined behavior, but
kono
parents:
diff changeset
144 returns 0 while HSAIL requires to return -1. */
kono
parents:
diff changeset
145
kono
parents:
diff changeset
146 uint32_t
kono
parents:
diff changeset
147 __hsail_firstbit_u32 (uint32_t src0)
kono
parents:
diff changeset
148 {
kono
parents:
diff changeset
149 if (src0 == 0)
kono
parents:
diff changeset
150 return -1;
kono
parents:
diff changeset
151 return __builtin_clz (src0);
kono
parents:
diff changeset
152 }
kono
parents:
diff changeset
153
kono
parents:
diff changeset
154 uint32_t
kono
parents:
diff changeset
155 __hsail_firstbit_s32 (int32_t src0)
kono
parents:
diff changeset
156 {
kono
parents:
diff changeset
157 uint32_t converted = src0 >= 0 ? src0 : ~src0;
kono
parents:
diff changeset
158 return __hsail_firstbit_u32 (converted);
kono
parents:
diff changeset
159 }
kono
parents:
diff changeset
160
kono
parents:
diff changeset
161 uint32_t
kono
parents:
diff changeset
162 __hsail_firstbit_u64 (uint64_t src0)
kono
parents:
diff changeset
163 {
kono
parents:
diff changeset
164 if (src0 == 0)
kono
parents:
diff changeset
165 return -1;
kono
parents:
diff changeset
166 return __builtin_clzl (src0);
kono
parents:
diff changeset
167 }
kono
parents:
diff changeset
168
kono
parents:
diff changeset
169 uint32_t
kono
parents:
diff changeset
170 __hsail_firstbit_s64 (int64_t src0)
kono
parents:
diff changeset
171 {
kono
parents:
diff changeset
172 uint64_t converted = src0 >= 0 ? src0 : ~src0;
kono
parents:
diff changeset
173 return __hsail_firstbit_u64 (converted);
kono
parents:
diff changeset
174 }
kono
parents:
diff changeset
175
kono
parents:
diff changeset
176 uint32_t
kono
parents:
diff changeset
177 __hsail_lastbit_u32 (uint32_t src0)
kono
parents:
diff changeset
178 {
kono
parents:
diff changeset
179 if (src0 == 0)
kono
parents:
diff changeset
180 return -1;
kono
parents:
diff changeset
181 return __builtin_ctz (src0);
kono
parents:
diff changeset
182 }
kono
parents:
diff changeset
183
kono
parents:
diff changeset
184 uint32_t
kono
parents:
diff changeset
185 __hsail_lastbit_u64 (uint64_t src0)
kono
parents:
diff changeset
186 {
kono
parents:
diff changeset
187 if (src0 == 0)
kono
parents:
diff changeset
188 return -1;
kono
parents:
diff changeset
189 return __builtin_ctzl (src0);
kono
parents:
diff changeset
190 }