4720f643328e6e11779e62710dd678e2476f3e86
[mesa.git] / src / broadcom / cle / v3d_packet_helpers.h
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 #include <stdio.h>
25 #include <stdint.h>
26 #include <stdbool.h>
27 #include <assert.h>
28 #include <math.h>
29
30 #ifdef HAVE_VALGRIND
31 #include <valgrind.h>
32 #include <memcheck.h>
33 #define VG(x) x
34 #ifndef NDEBUG
35 #define __gen_validate_value(x) VALGRIND_CHECK_MEM_IS_DEFINED(&(x), sizeof(x))
36 #endif
37 #else
38 #define VG(x)
39 #endif
40
41 #ifndef __gen_validate_value
42 #define __gen_validate_value(x)
43 #endif
44 /*
45 #ifndef __gen_address_type
46 #error #define __gen_address_type before including this file
47 #endif
48
49 #ifndef __gen_user_data
50 #error #define __gen_combine_address before including this file
51 #endif
52 */
53 union __gen_value {
54 float f;
55 uint32_t dw;
56 };
57
58 static inline uint64_t
59 __gen_mbo(uint32_t start, uint32_t end)
60 {
61 return (~0ull >> (64 - (end - start + 1))) << start;
62 }
63
64 static inline uint64_t
65 __gen_uint(uint64_t v, uint32_t start, uint32_t end)
66 {
67 __gen_validate_value(v);
68
69 #ifndef NDEBUG
70 const int width = end - start + 1;
71 if (width < 64) {
72 const uint64_t max = (1ull << width) - 1;
73 assert(v <= max);
74 }
75 #endif
76
77 return v << start;
78 }
79
80 static inline uint64_t
81 __gen_sint(int64_t v, uint32_t start, uint32_t end)
82 {
83 const int width = end - start + 1;
84
85 __gen_validate_value(v);
86
87 #ifndef NDEBUG
88 if (width < 64) {
89 const int64_t max = (1ll << (width - 1)) - 1;
90 const int64_t min = -(1ll << (width - 1));
91 assert(min <= v && v <= max);
92 }
93 #endif
94
95 const uint64_t mask = ~0ull >> (64 - width);
96
97 return (v & mask) << start;
98 }
99
100 static inline uint64_t
101 __gen_offset(uint64_t v, uint32_t start, uint32_t end)
102 {
103 __gen_validate_value(v);
104 #ifndef NDEBUG
105 uint64_t mask = (~0ull >> (64 - (end - start + 1))) << start;
106
107 assert((v & ~mask) == 0);
108 #endif
109
110 return v;
111 }
112
113 static inline uint32_t
114 __gen_float(float v)
115 {
116 __gen_validate_value(v);
117 return ((union __gen_value) { .f = (v) }).dw;
118 }
119
120 static inline uint64_t
121 __gen_sfixed(float v, uint32_t start, uint32_t end, uint32_t fract_bits)
122 {
123 __gen_validate_value(v);
124
125 const float factor = (1 << fract_bits);
126
127 #ifndef NDEBUG
128 const float max = ((1 << (end - start)) - 1) / factor;
129 const float min = -(1 << (end - start)) / factor;
130 assert(min <= v && v <= max);
131 #endif
132
133 const int64_t int_val = llroundf(v * factor);
134 const uint64_t mask = ~0ull >> (64 - (end - start + 1));
135
136 return (int_val & mask) << start;
137 }
138
139 static inline uint64_t
140 __gen_ufixed(float v, uint32_t start, uint32_t end, uint32_t fract_bits)
141 {
142 __gen_validate_value(v);
143
144 const float factor = (1 << fract_bits);
145
146 #ifndef NDEBUG
147 const float max = ((1 << (end - start + 1)) - 1) / factor;
148 const float min = 0.0f;
149 assert(min <= v && v <= max);
150 #endif
151
152 const uint64_t uint_val = llroundf(v * factor);
153
154 return uint_val << start;
155 }
156
157 static inline uint64_t
158 __gen_unpack_uint(const uint8_t *restrict cl, uint32_t start, uint32_t end)
159 {
160 uint64_t val = 0;
161 const int width = end - start + 1;
162 const uint32_t mask = (width == 32 ? ~0 : (1 << width) - 1 );
163
164 for (int byte = start / 8; byte <= end / 8; byte++) {
165 val |= cl[byte] << ((byte - start / 8) * 8);
166 }
167
168 return (val >> (start % 8)) & mask;
169 }
170
171 static inline uint64_t
172 __gen_unpack_sint(const uint8_t *restrict cl, uint32_t start, uint32_t end)
173 {
174 int size = end - start + 1;
175 int64_t val = __gen_unpack_uint(cl, start, end);
176
177 /* Get the sign bit extended. */
178 return (val << (64 - size)) >> (64 - size);
179 }
180
181 static inline float
182 __gen_unpack_sfixed(const uint8_t *restrict cl, uint32_t start, uint32_t end,
183 uint32_t fractional_size)
184 {
185 int32_t bits = __gen_unpack_sint(cl, start, end);
186 return (float)bits / (1 << fractional_size);
187 }
188
189 static inline float
190 __gen_unpack_ufixed(const uint8_t *restrict cl, uint32_t start, uint32_t end,
191 uint32_t fractional_size)
192 {
193 int32_t bits = __gen_unpack_uint(cl, start, end);
194 return (float)bits / (1 << fractional_size);
195 }
196
197 static inline float
198 __gen_unpack_float(const uint8_t *restrict cl, uint32_t start, uint32_t end)
199 {
200 assert(start % 8 == 0);
201 assert(end - start == 31);
202
203 struct PACKED { float f; } *f = (void *)(cl + (start / 8));
204
205 return f->f;
206 }
207