3
************************************************************************************************************************
5
* Copyright (C) 2007-2022 Advanced Micro Devices, Inc. All rights reserved.
7
* Permission is hereby granted, free of charge, to any person obtaining a
8
* copy of this software and associated documentation files (the "Software"),
9
* to deal in the Software without restriction, including without limitation
10
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
11
* and/or sell copies of the Software, and to permit persons to whom the
12
* Software is furnished to do so, subject to the following conditions:
14
* The above copyright notice and this permission notice shall be included in
15
* all copies or substantial portions of the Software.
17
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
21
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
* OTHER DEALINGS IN THE SOFTWARE
25
***********************************************************************************************************************/
27
// Coordinate class implementation
28
#include "addrcommon.h"
36
Coordinate::Coordinate()
42
Coordinate::Coordinate(enum Dim dim, INT_32 n)
47
VOID Coordinate::set(enum Dim d, INT_32 n)
50
ord = static_cast<INT_8>(n);
53
UINT_32 Coordinate::ison(const UINT_32 *coords) const
55
UINT_32 bit = static_cast<UINT_32>(1ull << static_cast<UINT_32>(ord));
57
return (coords[dim] & bit) ? 1 : 0;
60
enum Dim Coordinate::getdim()
65
INT_8 Coordinate::getord()
70
BOOL_32 Coordinate::operator==(const Coordinate& b)
72
return (dim == b.dim) && (ord == b.ord);
75
BOOL_32 Coordinate::operator<(const Coordinate& b)
85
if (dim == DIM_S || b.dim == DIM_M)
89
else if (b.dim == DIM_S || dim == DIM_M)
93
else if (ord == b.ord)
106
BOOL_32 Coordinate::operator>(const Coordinate& b)
108
BOOL_32 lt = *this < b;
109
BOOL_32 eq = *this == b;
113
BOOL_32 Coordinate::operator<=(const Coordinate& b)
115
return (*this < b) || (*this == b);
118
BOOL_32 Coordinate::operator>=(const Coordinate& b)
123
BOOL_32 Coordinate::operator!=(const Coordinate& b)
125
return !(*this == b);
128
Coordinate& Coordinate::operator++(INT_32)
136
CoordTerm::CoordTerm()
141
VOID CoordTerm::Clear()
146
VOID CoordTerm::add(Coordinate& co)
148
// This function adds a coordinate INT_32o the list
149
// It will prevent the same coordinate from appearing,
150
// and will keep the list ordered from smallest to largest
153
for (i = 0; i < num_coords; i++)
155
if (m_coord[i] == co)
161
for (UINT_32 j = num_coords; j > i; j--)
163
m_coord[j] = m_coord[j - 1];
173
m_coord[num_coords] = co;
178
VOID CoordTerm::add(CoordTerm& cl)
180
for (UINT_32 i = 0; i < cl.num_coords; i++)
186
BOOL_32 CoordTerm::remove(Coordinate& co)
188
BOOL_32 remove = FALSE;
189
for (UINT_32 i = 0; i < num_coords; i++)
191
if (m_coord[i] == co)
199
m_coord[i] = m_coord[i + 1];
205
BOOL_32 CoordTerm::Exists(Coordinate& co)
207
BOOL_32 exists = FALSE;
208
for (UINT_32 i = 0; i < num_coords; i++)
210
if (m_coord[i] == co)
219
VOID CoordTerm::copyto(CoordTerm& cl)
221
cl.num_coords = num_coords;
222
for (UINT_32 i = 0; i < num_coords; i++)
224
cl.m_coord[i] = m_coord[i];
228
UINT_32 CoordTerm::getsize()
233
UINT_32 CoordTerm::getxor(const UINT_32 *coords) const
236
for (UINT_32 i = 0; i < num_coords; i++)
238
out = out ^ m_coord[i].ison(coords);
243
VOID CoordTerm::getsmallest(Coordinate& co)
248
UINT_32 CoordTerm::Filter(INT_8 f, Coordinate& co, UINT_32 start, enum Dim axis)
250
for (UINT_32 i = start; i < num_coords;)
252
if (((f == '<' && m_coord[i] < co) ||
253
(f == '>' && m_coord[i] > co) ||
254
(f == '=' && m_coord[i] == co)) &&
255
(axis == NUM_DIMS || axis == m_coord[i].getdim()))
257
for (UINT_32 j = i; j < num_coords - 1; j++)
259
m_coord[j] = m_coord[j + 1];
271
Coordinate& CoordTerm::operator[](UINT_32 i)
276
BOOL_32 CoordTerm::operator==(const CoordTerm& b)
280
if (num_coords != b.num_coords)
286
for (UINT_32 i = 0; i < num_coords; i++)
288
// Note: the lists will always be in order, so we can compare the two lists at time
289
if (m_coord[i] != b.m_coord[i])
299
BOOL_32 CoordTerm::operator!=(const CoordTerm& b)
301
return !(*this == b);
304
BOOL_32 CoordTerm::exceedRange(const UINT_32 *ranges)
306
BOOL_32 exceed = FALSE;
307
for (UINT_32 i = 0; (i < num_coords) && (exceed == FALSE); i++)
309
exceed = ((1u << m_coord[i].getord()) <= ranges[m_coord[i].getdim()]);
321
VOID CoordEq::remove(Coordinate& co)
323
for (UINT_32 i = 0; i < m_numBits; i++)
329
BOOL_32 CoordEq::Exists(Coordinate& co)
331
BOOL_32 exists = FALSE;
333
for (UINT_32 i = 0; i < m_numBits; i++)
335
if (m_eq[i].Exists(co))
343
VOID CoordEq::resize(UINT_32 n)
347
for (UINT_32 i = m_numBits; i < n; i++)
355
UINT_32 CoordEq::getsize()
360
UINT_64 CoordEq::solve(const UINT_32 *coords) const
363
for (UINT_32 i = 0; i < m_numBits; i++)
365
out |= static_cast<UINT_64>(m_eq[i].getxor(coords)) << i;
370
VOID CoordEq::solveAddr(
371
UINT_64 addr, UINT_32 sliceInM,
372
UINT_32 *coords) const
374
UINT_32 BitsValid[NUM_DIMS] = {0};
376
CoordEq temp = *this;
378
memset(coords, 0, NUM_DIMS * sizeof(coords[0]));
380
UINT_32 bitsLeft = 0;
382
for (UINT_32 i = 0; i < temp.m_numBits; i++)
384
UINT_32 termSize = temp.m_eq[i].getsize();
388
INT_8 bit = (addr >> i) & 1;
389
enum Dim dim = temp.m_eq[i][0].getdim();
390
INT_8 ord = temp.m_eq[i][0].getord();
392
ADDR_ASSERT((ord < 32) || (bit == 0));
394
BitsValid[dim] |= 1u << ord;
395
coords[dim] |= bit << ord;
397
temp.m_eq[i].Clear();
399
else if (termSize > 1)
409
coords[DIM_Z] = coords[DIM_M] / sliceInM;
410
BitsValid[DIM_Z] = 0xffffffff;
417
for (UINT_32 i = 0; i < temp.m_numBits; i++)
419
UINT_32 termSize = temp.m_eq[i].getsize();
423
INT_8 bit = (addr >> i) & 1;
424
enum Dim dim = temp.m_eq[i][0].getdim();
425
INT_8 ord = temp.m_eq[i][0].getord();
427
ADDR_ASSERT((ord < 32) || (bit == 0));
428
ADDR_ASSERT(dim < DIM_S);
430
BitsValid[dim] |= 1u << ord;
431
coords[dim] |= bit << ord;
433
temp.m_eq[i].Clear();
435
else if (termSize > 1)
437
CoordTerm tmpTerm = temp.m_eq[i];
439
for (UINT_32 j = 0; j < termSize; j++)
441
enum Dim dim = temp.m_eq[i][j].getdim();
442
INT_8 ord = temp.m_eq[i][j].getord();
444
ADDR_ASSERT(dim < DIM_S);
446
if (BitsValid[dim] & (1u << ord))
448
UINT_32 v = (((coords[dim] >> ord) & 1) << i);
449
addr ^= static_cast<UINT_64>(v);
450
tmpTerm.remove(temp.m_eq[i][j]);
454
temp.m_eq[i] = tmpTerm;
459
} while (bitsLeft > 0);
463
VOID CoordEq::copy(CoordEq& o, UINT_32 start, UINT_32 num)
465
o.m_numBits = (num == 0xFFFFFFFF) ? m_numBits : num;
466
for (UINT_32 i = 0; i < o.m_numBits; i++)
468
m_eq[start + i].copyto(o.m_eq[i]);
472
VOID CoordEq::reverse(UINT_32 start, UINT_32 num)
474
UINT_32 n = (num == 0xFFFFFFFF) ? m_numBits : num;
476
for (UINT_32 i = 0; i < n / 2; i++)
479
m_eq[start + i].copyto(temp);
480
m_eq[start + n - 1 - i].copyto(m_eq[start + i]);
481
temp.copyto(m_eq[start + n - 1 - i]);
485
VOID CoordEq::xorin(CoordEq& x, UINT_32 start)
487
UINT_32 n = ((m_numBits - start) < x.m_numBits) ? (m_numBits - start) : x.m_numBits;
488
for (UINT_32 i = 0; i < n; i++)
490
m_eq[start + i].add(x.m_eq[i]);
494
UINT_32 CoordEq::Filter(INT_8 f, Coordinate& co, UINT_32 start, enum Dim axis)
496
for (UINT_32 i = start; i < m_numBits;)
498
UINT_32 m = m_eq[i].Filter(f, co, 0, axis);
501
for (UINT_32 j = i; j < m_numBits - 1; j++)
503
m_eq[j] = m_eq[j + 1];
515
VOID CoordEq::shift(INT_32 amount, INT_32 start)
519
INT_32 numBits = static_cast<INT_32>(m_numBits);
521
INT_32 inc = (amount < 0) ? -1 : 1;
522
INT_32 i = (amount < 0) ? numBits - 1 : start;
523
INT_32 end = (amount < 0) ? start - 1 : numBits;
524
for (; (inc > 0) ? i < end : i > end; i += inc)
526
if ((i + amount < start) || (i + amount >= numBits))
532
m_eq[i + amount].copyto(m_eq[i]);
538
CoordTerm& CoordEq::operator[](UINT_32 i)
543
VOID CoordEq::mort2d(Coordinate& c0, Coordinate& c1, UINT_32 start, UINT_32 end)
547
ADDR_ASSERT(m_numBits > 0);
550
for (UINT_32 i = start; i <= end; i++)
552
UINT_32 select = (i - start) % 2;
553
Coordinate& c = (select == 0) ? c0 : c1;
559
VOID CoordEq::mort3d(Coordinate& c0, Coordinate& c1, Coordinate& c2, UINT_32 start, UINT_32 end)
563
ADDR_ASSERT(m_numBits > 0);
566
for (UINT_32 i = start; i <= end; i++)
568
UINT_32 select = (i - start) % 3;
569
Coordinate& c = (select == 0) ? c0 : ((select == 1) ? c1 : c2);
575
BOOL_32 CoordEq::operator==(const CoordEq& b)
579
if (m_numBits != b.m_numBits)
585
for (UINT_32 i = 0; i < m_numBits; i++)
587
if (m_eq[i] != b.m_eq[i])
597
BOOL_32 CoordEq::operator!=(const CoordEq& b)
599
return !(*this == b);