1 /* Copyright © 2023 Intel Corporation
2 * SPDX-License-Identifier: MIT
3 */
4
5 #ifndef __GENX_CL_HELPERS_H__
6 #define __GENX_CL_HELPERS_H__
7
8 #define ALWAYS_INLINE inline __attribute__((always_inline))
9 #define UNUSED
10 #define BITFIELD64_MASK(bits) ((1ul << bits) - 1)
11 #define CLAMP( X, MIN, MAX ) ( (X)>(MIN) ? ((X)>(MAX) ? (MAX) : (X)) : (MIN) )
12 #define INT64_MAX (0x7FFFFFFFFFFFFFFFL)
13
14 ALWAYS_INLINE static uint64_t
u_uintN_max(uint32_t bits)15 u_uintN_max(uint32_t bits)
16 {
17 return (1ul << bits) - 1;
18 }
19
20 ALWAYS_INLINE static int64_t
u_intN_max(uint32_t bit_size)21 u_intN_max(uint32_t bit_size)
22 {
23 return INT64_MAX >> (64 - bit_size);
24 }
25
26 ALWAYS_INLINE static int64_t
u_intN_min(uint32_t bit_size)27 u_intN_min(uint32_t bit_size)
28 {
29 /* On 2's compliment platforms, which is every platform Mesa is likely to
30 * every worry about, stdint.h generally calculated INT##_MIN in this
31 * manner.
32 */
33 return (-u_intN_max(bit_size)) - 1;
34 }
35
36 ALWAYS_INLINE static uint64_t
util_bitpack_uint(uint64_t v,uint32_t start,UNUSED uint32_t end)37 util_bitpack_uint(uint64_t v, uint32_t start, UNUSED uint32_t end)
38 {
39 return v << start;
40 }
41
42 ALWAYS_INLINE static uint64_t
util_bitpack_uint_nonzero(uint64_t v,uint32_t start,uint32_t end)43 util_bitpack_uint_nonzero(uint64_t v, uint32_t start, uint32_t end)
44 {
45 return util_bitpack_uint(v, start, end);
46 }
47
48 ALWAYS_INLINE static uint64_t
util_bitpack_sint(int64_t v,uint32_t start,uint32_t end)49 util_bitpack_sint(int64_t v, uint32_t start, uint32_t end)
50 {
51 int32_t bits = end - start + 1;
52
53 uint64_t mask = BITFIELD64_MASK(bits);
54
55 return (v & mask) << start;
56 }
57
58 ALWAYS_INLINE static uint64_t
util_bitpack_sint_nonzero(int64_t v,uint32_t start,uint32_t end)59 util_bitpack_sint_nonzero(int64_t v, uint32_t start, uint32_t end)
60 {
61 return util_bitpack_sint(v, start, end);
62 }
63
64 ALWAYS_INLINE static uint32_t
util_bitpack_float(float v)65 util_bitpack_float(float v)
66 {
67 union { float f; uint32_t dw; } x;
68 x.f = v;
69 return x.dw;
70 }
71
72 ALWAYS_INLINE static uint32_t
util_bitpack_float_nonzero(float v)73 util_bitpack_float_nonzero(float v)
74 {
75 return util_bitpack_float(v);
76 }
77
78 ALWAYS_INLINE static uint64_t
util_bitpack_sfixed(float v,uint32_t start,uint32_t end,uint32_t fract_bits)79 util_bitpack_sfixed(float v, uint32_t start, uint32_t end,
80 uint32_t fract_bits)
81 {
82 float factor = (1 << fract_bits);
83
84 int64_t int_val = round(v * factor);
85 uint64_t mask = ~0ul >> (64 - (end - start + 1));
86
87 return (int_val & mask) << start;
88 }
89
90 ALWAYS_INLINE static uint64_t
util_bitpack_sfixed_clamp(float v,uint32_t start,uint32_t end,uint32_t fract_bits)91 util_bitpack_sfixed_clamp(float v, uint32_t start, uint32_t end,
92 uint32_t fract_bits)
93 {
94 float factor = (1 << fract_bits);
95
96 uint32_t total_bits = end - start + 1;
97 float min = u_intN_min(total_bits) / factor;
98 float max = u_intN_max(total_bits) / factor;
99
100 int64_t int_val = round(CLAMP(v, min, max) * factor);
101 uint64_t mask = ~0ul >> (64 - (end - start + 1));
102
103 return (int_val & mask) << start;
104 }
105
106 ALWAYS_INLINE static uint64_t
util_bitpack_sfixed_nonzero(float v,uint32_t start,uint32_t end,uint32_t fract_bits)107 util_bitpack_sfixed_nonzero(float v, uint32_t start, uint32_t end,
108 uint32_t fract_bits)
109 {
110 return util_bitpack_sfixed(v, start, end, fract_bits);
111 }
112
113 ALWAYS_INLINE static uint64_t
util_bitpack_ufixed(float v,uint32_t start,uint32_t end,uint32_t fract_bits)114 util_bitpack_ufixed(float v, uint32_t start, uint32_t end, uint32_t fract_bits)
115 {
116 float factor = (1 << fract_bits);
117
118 uint64_t uint_val = round(v * factor);
119
120 return uint_val << start;
121 }
122
123 ALWAYS_INLINE static uint64_t
util_bitpack_ufixed_clamp(float v,uint32_t start,uint32_t end,uint32_t fract_bits)124 util_bitpack_ufixed_clamp(float v, uint32_t start, uint32_t end, uint32_t fract_bits)
125 {
126 float factor = (1 << fract_bits);
127
128 int total_bits = end - start + 1;
129 float min = 0.0f;
130 float max = u_uintN_max(total_bits) / factor;
131
132 uint64_t uint_val = round(CLAMP(v, min, max) * factor);
133
134 return uint_val << start;
135 }
136
137 ALWAYS_INLINE static uint64_t
util_bitpack_ufixed_nonzero(float v,uint32_t start,uint32_t end,uint32_t fract_bits)138 util_bitpack_ufixed_nonzero(float v, uint32_t start, uint32_t end,
139 uint32_t fract_bits)
140 {
141 return util_bitpack_ufixed(v, start, end, fract_bits);
142 }
143
144 #ifndef __gen_validate_value
145 #define __gen_validate_value(x)
146 #endif
147
148 #ifndef __intel_field_functions
149 #define __intel_field_functions
150 #endif
151
152 static inline __attribute__((always_inline)) uint64_t
__gen_offset(uint64_t v,UNUSED uint32_t start,UNUSED uint32_t end)153 __gen_offset(uint64_t v, UNUSED uint32_t start, UNUSED uint32_t end)
154 {
155 return v;
156 }
157
158 static inline __attribute__((always_inline)) uint64_t
__gen_offset_nonzero(uint64_t v,uint32_t start,uint32_t end)159 __gen_offset_nonzero(uint64_t v, uint32_t start, uint32_t end)
160 {
161 return __gen_offset(v, start, end);
162 }
163
164 static inline __attribute__((always_inline)) uint64_t
__gen_address(uint64_t address,uint32_t start,uint32_t end)165 __gen_address(uint64_t address,
166 __attribute__((unused)) uint32_t start, uint32_t end)
167 {
168 if (end < 63) {
169 uint32_t shift = 63 - end;
170 return (address << shift) >> shift;
171 } else {
172 return address;
173 }
174 }
175
176 #endif /* __GENX_CL_HELPERS_H__ */
177