amd/addrlib: fix forgotten char -> enum conversions
[mesa.git] / src / amd / addrlib / src / core / coord.cpp
1
2 /*
3 * Copyright © 2007-2019 Advanced Micro Devices, Inc.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
16 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
18 * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE.
22 *
23 * The above copyright notice and this permission notice (including the
24 * next paragraph) shall be included in all copies or substantial portions
25 * of the Software.
26 */
27
28 // Coordinate class implementation
29 #include "addrcommon.h"
30 #include "coord.h"
31
32 namespace Addr
33 {
34 namespace V2
35 {
36
37 Coordinate::Coordinate()
38 {
39 dim = DIM_X;
40 ord = 0;
41 }
42
43 Coordinate::Coordinate(enum Dim dim, INT_32 n)
44 {
45 set(dim, n);
46 }
47
48 VOID Coordinate::set(enum Dim d, INT_32 n)
49 {
50 dim = d;
51 ord = static_cast<INT_8>(n);
52 }
53
54 UINT_32 Coordinate::ison(const UINT_32 *coords) const
55 {
56 UINT_32 bit = static_cast<UINT_32>(1ull << static_cast<UINT_32>(ord));
57
58 return (coords[dim] & bit) ? 1 : 0;
59 }
60
61 enum Dim Coordinate::getdim()
62 {
63 return dim;
64 }
65
66 INT_8 Coordinate::getord()
67 {
68 return ord;
69 }
70
71 BOOL_32 Coordinate::operator==(const Coordinate& b)
72 {
73 return (dim == b.dim) && (ord == b.ord);
74 }
75
76 BOOL_32 Coordinate::operator<(const Coordinate& b)
77 {
78 BOOL_32 ret;
79
80 if (dim == b.dim)
81 {
82 ret = ord < b.ord;
83 }
84 else
85 {
86 if (dim == DIM_S || b.dim == DIM_M)
87 {
88 ret = TRUE;
89 }
90 else if (b.dim == DIM_S || dim == DIM_M)
91 {
92 ret = FALSE;
93 }
94 else if (ord == b.ord)
95 {
96 ret = dim < b.dim;
97 }
98 else
99 {
100 ret = ord < b.ord;
101 }
102 }
103
104 return ret;
105 }
106
107 BOOL_32 Coordinate::operator>(const Coordinate& b)
108 {
109 BOOL_32 lt = *this < b;
110 BOOL_32 eq = *this == b;
111 return !lt && !eq;
112 }
113
114 BOOL_32 Coordinate::operator<=(const Coordinate& b)
115 {
116 return (*this < b) || (*this == b);
117 }
118
119 BOOL_32 Coordinate::operator>=(const Coordinate& b)
120 {
121 return !(*this < b);
122 }
123
124 BOOL_32 Coordinate::operator!=(const Coordinate& b)
125 {
126 return !(*this == b);
127 }
128
129 Coordinate& Coordinate::operator++(INT_32)
130 {
131 ord++;
132 return *this;
133 }
134
135 // CoordTerm
136
137 CoordTerm::CoordTerm()
138 {
139 num_coords = 0;
140 }
141
142 VOID CoordTerm::Clear()
143 {
144 num_coords = 0;
145 }
146
147 VOID CoordTerm::add(Coordinate& co)
148 {
149 // This function adds a coordinate INT_32o the list
150 // It will prevent the same coordinate from appearing,
151 // and will keep the list ordered from smallest to largest
152 UINT_32 i;
153
154 for (i = 0; i < num_coords; i++)
155 {
156 if (m_coord[i] == co)
157 {
158 break;
159 }
160 if (m_coord[i] > co)
161 {
162 for (UINT_32 j = num_coords; j > i; j--)
163 {
164 m_coord[j] = m_coord[j - 1];
165 }
166 m_coord[i] = co;
167 num_coords++;
168 break;
169 }
170 }
171
172 if (i == num_coords)
173 {
174 m_coord[num_coords] = co;
175 num_coords++;
176 }
177 }
178
179 VOID CoordTerm::add(CoordTerm& cl)
180 {
181 for (UINT_32 i = 0; i < cl.num_coords; i++)
182 {
183 add(cl.m_coord[i]);
184 }
185 }
186
187 BOOL_32 CoordTerm::remove(Coordinate& co)
188 {
189 BOOL_32 remove = FALSE;
190 for (UINT_32 i = 0; i < num_coords; i++)
191 {
192 if (m_coord[i] == co)
193 {
194 remove = TRUE;
195 num_coords--;
196 }
197
198 if (remove)
199 {
200 m_coord[i] = m_coord[i + 1];
201 }
202 }
203 return remove;
204 }
205
206 BOOL_32 CoordTerm::Exists(Coordinate& co)
207 {
208 BOOL_32 exists = FALSE;
209 for (UINT_32 i = 0; i < num_coords; i++)
210 {
211 if (m_coord[i] == co)
212 {
213 exists = TRUE;
214 break;
215 }
216 }
217 return exists;
218 }
219
220 VOID CoordTerm::copyto(CoordTerm& cl)
221 {
222 cl.num_coords = num_coords;
223 for (UINT_32 i = 0; i < num_coords; i++)
224 {
225 cl.m_coord[i] = m_coord[i];
226 }
227 }
228
229 UINT_32 CoordTerm::getsize()
230 {
231 return num_coords;
232 }
233
234 UINT_32 CoordTerm::getxor(const UINT_32 *coords) const
235 {
236 UINT_32 out = 0;
237 for (UINT_32 i = 0; i < num_coords; i++)
238 {
239 out = out ^ m_coord[i].ison(coords);
240 }
241 return out;
242 }
243
244 VOID CoordTerm::getsmallest(Coordinate& co)
245 {
246 co = m_coord[0];
247 }
248
249 UINT_32 CoordTerm::Filter(INT_8 f, Coordinate& co, UINT_32 start, enum Dim axis)
250 {
251 for (UINT_32 i = start; i < num_coords;)
252 {
253 if (((f == '<' && m_coord[i] < co) ||
254 (f == '>' && m_coord[i] > co) ||
255 (f == '=' && m_coord[i] == co)) &&
256 (axis == NUM_DIMS || axis == m_coord[i].getdim()))
257 {
258 for (UINT_32 j = i; j < num_coords - 1; j++)
259 {
260 m_coord[j] = m_coord[j + 1];
261 }
262 num_coords--;
263 }
264 else
265 {
266 i++;
267 }
268 }
269 return num_coords;
270 }
271
272 Coordinate& CoordTerm::operator[](UINT_32 i)
273 {
274 return m_coord[i];
275 }
276
277 BOOL_32 CoordTerm::operator==(const CoordTerm& b)
278 {
279 BOOL_32 ret = TRUE;
280
281 if (num_coords != b.num_coords)
282 {
283 ret = FALSE;
284 }
285 else
286 {
287 for (UINT_32 i = 0; i < num_coords; i++)
288 {
289 // Note: the lists will always be in order, so we can compare the two lists at time
290 if (m_coord[i] != b.m_coord[i])
291 {
292 ret = FALSE;
293 break;
294 }
295 }
296 }
297 return ret;
298 }
299
300 BOOL_32 CoordTerm::operator!=(const CoordTerm& b)
301 {
302 return !(*this == b);
303 }
304
305 BOOL_32 CoordTerm::exceedRange(const UINT_32 *ranges)
306 {
307 BOOL_32 exceed = FALSE;
308 for (UINT_32 i = 0; (i < num_coords) && (exceed == FALSE); i++)
309 {
310 exceed = ((1u << m_coord[i].getord()) <= ranges[m_coord[i].getdim()]);
311 }
312
313 return exceed;
314 }
315
316 // coordeq
317 CoordEq::CoordEq()
318 {
319 m_numBits = 0;
320 }
321
322 VOID CoordEq::remove(Coordinate& co)
323 {
324 for (UINT_32 i = 0; i < m_numBits; i++)
325 {
326 m_eq[i].remove(co);
327 }
328 }
329
330 BOOL_32 CoordEq::Exists(Coordinate& co)
331 {
332 BOOL_32 exists = FALSE;
333
334 for (UINT_32 i = 0; i < m_numBits; i++)
335 {
336 if (m_eq[i].Exists(co))
337 {
338 exists = TRUE;
339 }
340 }
341 return exists;
342 }
343
344 VOID CoordEq::resize(UINT_32 n)
345 {
346 if (n > m_numBits)
347 {
348 for (UINT_32 i = m_numBits; i < n; i++)
349 {
350 m_eq[i].Clear();
351 }
352 }
353 m_numBits = n;
354 }
355
356 UINT_32 CoordEq::getsize()
357 {
358 return m_numBits;
359 }
360
361 UINT_64 CoordEq::solve(const UINT_32 *coords) const
362 {
363 UINT_64 out = 0;
364 for (UINT_32 i = 0; i < m_numBits; i++)
365 {
366 out |= static_cast<UINT_64>(m_eq[i].getxor(coords)) << i;
367 }
368 return out;
369 }
370
371 VOID CoordEq::solveAddr(
372 UINT_64 addr, UINT_32 sliceInM,
373 UINT_32 *coords) const
374 {
375 UINT_32 BitsValid[NUM_DIMS] = {0};
376
377 CoordEq temp = *this;
378
379 memset(coords, 0, NUM_DIMS * sizeof(coords[0]));
380
381 UINT_32 bitsLeft = 0;
382
383 for (UINT_32 i = 0; i < temp.m_numBits; i++)
384 {
385 UINT_32 termSize = temp.m_eq[i].getsize();
386
387 if (termSize == 1)
388 {
389 INT_8 bit = (addr >> i) & 1;
390 enum Dim dim = temp.m_eq[i][0].getdim();
391 INT_8 ord = temp.m_eq[i][0].getord();
392
393 ADDR_ASSERT((ord < 32) || (bit == 0));
394
395 BitsValid[dim] |= 1u << ord;
396 coords[dim] |= bit << ord;
397
398 temp.m_eq[i].Clear();
399 }
400 else if (termSize > 1)
401 {
402 bitsLeft++;
403 }
404 }
405
406 if (bitsLeft > 0)
407 {
408 if (sliceInM != 0)
409 {
410 coords[DIM_Z] = coords[DIM_M] / sliceInM;
411 BitsValid[DIM_Z] = 0xffffffff;
412 }
413
414 do
415 {
416 bitsLeft = 0;
417
418 for (UINT_32 i = 0; i < temp.m_numBits; i++)
419 {
420 UINT_32 termSize = temp.m_eq[i].getsize();
421
422 if (termSize == 1)
423 {
424 INT_8 bit = (addr >> i) & 1;
425 enum Dim dim = temp.m_eq[i][0].getdim();
426 INT_8 ord = temp.m_eq[i][0].getord();
427
428 ADDR_ASSERT((ord < 32) || (bit == 0));
429 ADDR_ASSERT(dim < DIM_S);
430
431 BitsValid[dim] |= 1u << ord;
432 coords[dim] |= bit << ord;
433
434 temp.m_eq[i].Clear();
435 }
436 else if (termSize > 1)
437 {
438 CoordTerm tmpTerm = temp.m_eq[i];
439
440 for (UINT_32 j = 0; j < termSize; j++)
441 {
442 enum Dim dim = temp.m_eq[i][j].getdim();
443 INT_8 ord = temp.m_eq[i][j].getord();
444
445 ADDR_ASSERT(dim < DIM_S);
446
447 if (BitsValid[dim] & (1u << ord))
448 {
449 UINT_32 v = (((coords[dim] >> ord) & 1) << i);
450 addr ^= static_cast<UINT_64>(v);
451 tmpTerm.remove(temp.m_eq[i][j]);
452 }
453 }
454
455 temp.m_eq[i] = tmpTerm;
456
457 bitsLeft++;
458 }
459 }
460 } while (bitsLeft > 0);
461 }
462 }
463
464 VOID CoordEq::copy(CoordEq& o, UINT_32 start, UINT_32 num)
465 {
466 o.m_numBits = (num == 0xFFFFFFFF) ? m_numBits : num;
467 for (UINT_32 i = 0; i < o.m_numBits; i++)
468 {
469 m_eq[start + i].copyto(o.m_eq[i]);
470 }
471 }
472
473 VOID CoordEq::reverse(UINT_32 start, UINT_32 num)
474 {
475 UINT_32 n = (num == 0xFFFFFFFF) ? m_numBits : num;
476
477 for (UINT_32 i = 0; i < n / 2; i++)
478 {
479 CoordTerm temp;
480 m_eq[start + i].copyto(temp);
481 m_eq[start + n - 1 - i].copyto(m_eq[start + i]);
482 temp.copyto(m_eq[start + n - 1 - i]);
483 }
484 }
485
486 VOID CoordEq::xorin(CoordEq& x, UINT_32 start)
487 {
488 UINT_32 n = ((m_numBits - start) < x.m_numBits) ? (m_numBits - start) : x.m_numBits;
489 for (UINT_32 i = 0; i < n; i++)
490 {
491 m_eq[start + i].add(x.m_eq[i]);
492 }
493 }
494
495 UINT_32 CoordEq::Filter(INT_8 f, Coordinate& co, UINT_32 start, enum Dim axis)
496 {
497 for (UINT_32 i = start; i < m_numBits;)
498 {
499 UINT_32 m = m_eq[i].Filter(f, co, 0, axis);
500 if (m == 0)
501 {
502 for (UINT_32 j = i; j < m_numBits - 1; j++)
503 {
504 m_eq[j] = m_eq[j + 1];
505 }
506 m_numBits--;
507 }
508 else
509 {
510 i++;
511 }
512 }
513 return m_numBits;
514 }
515
516 VOID CoordEq::shift(INT_32 amount, INT_32 start)
517 {
518 if (amount != 0)
519 {
520 INT_32 numBits = static_cast<INT_32>(m_numBits);
521 amount = -amount;
522 INT_32 inc = (amount < 0) ? -1 : 1;
523 INT_32 i = (amount < 0) ? numBits - 1 : start;
524 INT_32 end = (amount < 0) ? start - 1 : numBits;
525 for (; (inc > 0) ? i < end : i > end; i += inc)
526 {
527 if ((i + amount < start) || (i + amount >= numBits))
528 {
529 m_eq[i].Clear();
530 }
531 else
532 {
533 m_eq[i + amount].copyto(m_eq[i]);
534 }
535 }
536 }
537 }
538
539 CoordTerm& CoordEq::operator[](UINT_32 i)
540 {
541 return m_eq[i];
542 }
543
544 VOID CoordEq::mort2d(Coordinate& c0, Coordinate& c1, UINT_32 start, UINT_32 end)
545 {
546 if (end == 0)
547 {
548 ADDR_ASSERT(m_numBits > 0);
549 end = m_numBits - 1;
550 }
551 for (UINT_32 i = start; i <= end; i++)
552 {
553 UINT_32 select = (i - start) % 2;
554 Coordinate& c = (select == 0) ? c0 : c1;
555 m_eq[i].add(c);
556 c++;
557 }
558 }
559
560 VOID CoordEq::mort3d(Coordinate& c0, Coordinate& c1, Coordinate& c2, UINT_32 start, UINT_32 end)
561 {
562 if (end == 0)
563 {
564 ADDR_ASSERT(m_numBits > 0);
565 end = m_numBits - 1;
566 }
567 for (UINT_32 i = start; i <= end; i++)
568 {
569 UINT_32 select = (i - start) % 3;
570 Coordinate& c = (select == 0) ? c0 : ((select == 1) ? c1 : c2);
571 m_eq[i].add(c);
572 c++;
573 }
574 }
575
576 BOOL_32 CoordEq::operator==(const CoordEq& b)
577 {
578 BOOL_32 ret = TRUE;
579
580 if (m_numBits != b.m_numBits)
581 {
582 ret = FALSE;
583 }
584 else
585 {
586 for (UINT_32 i = 0; i < m_numBits; i++)
587 {
588 if (m_eq[i] != b.m_eq[i])
589 {
590 ret = FALSE;
591 break;
592 }
593 }
594 }
595 return ret;
596 }
597
598 BOOL_32 CoordEq::operator!=(const CoordEq& b)
599 {
600 return !(*this == b);
601 }
602
603 } // V2
604 } // Addr