• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24 #ifndef UTIL_BITPACK_HELPERS_H
25 #define UTIL_BITPACK_HELPERS_H
26 
27 #ifndef __OPENCL_VERSION__
28 #include <math.h>
29 #include <stdbool.h>
30 
31 #include "util/macros.h"
32 #include "util/u_math.h"
33 
34 #ifdef HAVE_VALGRIND
35 #include <valgrind.h>
36 #include <memcheck.h>
37 #ifndef NDEBUG
38 #define util_bitpack_validate_value(x) \
39    VALGRIND_CHECK_MEM_IS_DEFINED(&(x), sizeof(x))
40 #endif
41 #endif
42 #else
43 #include "compiler/libcl/libcl.h"
44 #endif
45 
46 #ifndef util_bitpack_validate_value
47 #define util_bitpack_validate_value(x)
48 #endif
49 
50 ALWAYS_INLINE static uint64_t
util_bitpack_ones(uint32_t start,uint32_t end)51 util_bitpack_ones(uint32_t start, uint32_t end)
52 {
53    return (UINT64_MAX >> (64 - (end - start + 1))) << start;
54 }
55 
56 ALWAYS_INLINE static uint64_t
util_bitpack_uint(uint64_t v,uint32_t start,UNUSED uint32_t end)57 util_bitpack_uint(uint64_t v, uint32_t start, UNUSED uint32_t end)
58 {
59    util_bitpack_validate_value(v);
60 
61 #ifndef NDEBUG
62    const int bits = end - start + 1;
63    if (bits < 64) {
64       const uint64_t max = u_uintN_max(bits);
65       assert(v <= max);
66    }
67 #endif
68 
69    return v << start;
70 }
71 
72 ALWAYS_INLINE static uint64_t
util_bitpack_uint_nonzero(uint64_t v,uint32_t start,uint32_t end)73 util_bitpack_uint_nonzero(uint64_t v, uint32_t start, uint32_t end)
74 {
75    assert(v != 0ull);
76    return util_bitpack_uint(v, start, end);
77 }
78 
79 ALWAYS_INLINE static uint64_t
util_bitpack_sint(int64_t v,uint32_t start,uint32_t end)80 util_bitpack_sint(int64_t v, uint32_t start, uint32_t end)
81 {
82    const int bits = end - start + 1;
83 
84    util_bitpack_validate_value(v);
85 
86 #ifndef NDEBUG
87    if (bits < 64) {
88       const int64_t min = u_intN_min(bits);
89       const int64_t max = u_intN_max(bits);
90       assert(min <= v && v <= max);
91    }
92 #endif
93 
94    const uint64_t mask = BITFIELD64_MASK(bits);
95 
96    return (v & mask) << start;
97 }
98 
99 ALWAYS_INLINE static uint64_t
util_bitpack_sint_nonzero(int64_t v,uint32_t start,uint32_t end)100 util_bitpack_sint_nonzero(int64_t v, uint32_t start, uint32_t end)
101 {
102    assert(v != 0ll);
103    return util_bitpack_sint(v, start, end);
104 }
105 
106 ALWAYS_INLINE static uint32_t
util_bitpack_float(float v)107 util_bitpack_float(float v)
108 {
109    util_bitpack_validate_value(v);
110    union { float f; uint32_t dw; } x;
111    x.f = v;
112    return x.dw;
113 }
114 
115 ALWAYS_INLINE static uint32_t
util_bitpack_float_nonzero(float v)116 util_bitpack_float_nonzero(float v)
117 {
118    assert(v != 0.0f);
119    return util_bitpack_float(v);
120 }
121 
122 ALWAYS_INLINE static uint64_t
util_bitpack_sfixed(float v,uint32_t start,uint32_t end,uint32_t fract_bits)123 util_bitpack_sfixed(float v, uint32_t start, uint32_t end,
124                     uint32_t fract_bits)
125 {
126    util_bitpack_validate_value(v);
127 
128    const float factor = (1 << fract_bits);
129 
130 #ifndef NDEBUG
131    const int total_bits = end - start + 1;
132    const float min = u_intN_min(total_bits) / factor;
133    const float max = u_intN_max(total_bits) / factor;
134    assert(min <= v && v <= max);
135 #endif
136 
137    const int64_t int_val = llroundf(v * factor);
138    const uint64_t mask = UINT64_MAX >> (64 - (end - start + 1));
139 
140    return (int_val & mask) << start;
141 }
142 
143 ALWAYS_INLINE static uint64_t
util_bitpack_sfixed_clamp(float v,uint32_t start,uint32_t end,uint32_t fract_bits)144 util_bitpack_sfixed_clamp(float v, uint32_t start, uint32_t end,
145                           uint32_t fract_bits)
146 {
147    util_bitpack_validate_value(v);
148 
149    const float factor = (1 << fract_bits);
150 
151    const int total_bits = end - start + 1;
152    const float min = u_intN_min(total_bits) / factor;
153    const float max = u_intN_max(total_bits) / factor;
154 
155    const int64_t int_val = llroundf(CLAMP(v, min, max) * factor);
156    const uint64_t mask = UINT64_MAX >> (64 - (end - start + 1));
157 
158    return (int_val & mask) << start;
159 }
160 
161 ALWAYS_INLINE static uint64_t
util_bitpack_sfixed_nonzero(float v,uint32_t start,uint32_t end,uint32_t fract_bits)162 util_bitpack_sfixed_nonzero(float v, uint32_t start, uint32_t end,
163                             uint32_t fract_bits)
164 {
165    assert(v != 0.0f);
166    return util_bitpack_sfixed(v, start, end, fract_bits);
167 }
168 
169 ALWAYS_INLINE static uint64_t
util_bitpack_ufixed(float v,uint32_t start,ASSERTED uint32_t end,uint32_t fract_bits)170 util_bitpack_ufixed(float v, uint32_t start, ASSERTED uint32_t end,
171                     uint32_t fract_bits)
172 {
173    util_bitpack_validate_value(v);
174 
175    const float factor = (1 << fract_bits);
176 
177 #ifndef NDEBUG
178    const int total_bits = end - start + 1;
179    const float min = 0.0f;
180    const float max = u_uintN_max(total_bits) / factor;
181    assert(min <= v && v <= max);
182 #endif
183 
184    const uint64_t uint_val = llroundf(v * factor);
185 
186    return uint_val << start;
187 }
188 
189 ALWAYS_INLINE static uint64_t
util_bitpack_ufixed_clamp(float v,uint32_t start,ASSERTED uint32_t end,uint32_t fract_bits)190 util_bitpack_ufixed_clamp(float v, uint32_t start, ASSERTED uint32_t end,
191                           uint32_t fract_bits)
192 {
193    util_bitpack_validate_value(v);
194 
195    const float factor = (1 << fract_bits);
196 
197    const int total_bits = end - start + 1;
198    const float min = 0.0f;
199    const float max = u_uintN_max(total_bits) / factor;
200 
201    const uint64_t uint_val = llroundf(CLAMP(v, min, max) * factor);
202 
203    return uint_val << start;
204 }
205 
206 ALWAYS_INLINE static uint64_t
util_bitpack_ufixed_nonzero(float v,uint32_t start,uint32_t end,uint32_t fract_bits)207 util_bitpack_ufixed_nonzero(float v, uint32_t start, uint32_t end,
208                             uint32_t fract_bits)
209 {
210    assert(v != 0.0f);
211    return util_bitpack_ufixed(v, start, end, fract_bits);
212 }
213 
214 #endif /* UTIL_BITPACK_HELPERS_H */
215