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