xref: /aosp_15_r20/external/mesa3d/src/intel/genxml/genX_cl_helpers.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
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