• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*
3 ************************************************************************************************************************
4 *
5 *  Copyright (C) 2007-2022 Advanced Micro Devices, Inc.  All rights reserved.
6 *
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:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
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
24 *
25 ***********************************************************************************************************************/
26 
27 // Coordinate class implementation
28 #include "addrcommon.h"
29 #include "coord.h"
30 
31 namespace Addr
32 {
33 namespace V2
34 {
35 
Coordinate()36 Coordinate::Coordinate()
37 {
38     dim = DIM_X;
39     ord = 0;
40 }
41 
Coordinate(enum Dim dim,INT_32 n)42 Coordinate::Coordinate(enum Dim dim, INT_32 n)
43 {
44     set(dim, n);
45 }
46 
set(enum Dim d,INT_32 n)47 VOID Coordinate::set(enum Dim d, INT_32 n)
48 {
49     dim = d;
50     ord = static_cast<INT_8>(n);
51 }
52 
ison(const UINT_32 * coords) const53 UINT_32 Coordinate::ison(const UINT_32 *coords) const
54 {
55     UINT_32 bit = static_cast<UINT_32>(1ull << static_cast<UINT_32>(ord));
56 
57     return (coords[dim] & bit) ? 1 : 0;
58 }
59 
getdim()60 enum Dim Coordinate::getdim()
61 {
62     return dim;
63 }
64 
getord()65 INT_8 Coordinate::getord()
66 {
67     return ord;
68 }
69 
operator ==(const Coordinate & b)70 BOOL_32 Coordinate::operator==(const Coordinate& b)
71 {
72     return (dim == b.dim) && (ord == b.ord);
73 }
74 
operator <(const Coordinate & b)75 BOOL_32 Coordinate::operator<(const Coordinate& b)
76 {
77     BOOL_32 ret;
78 
79     if (dim == b.dim)
80     {
81         ret = ord < b.ord;
82     }
83     else
84     {
85         if (dim == DIM_S || b.dim == DIM_M)
86         {
87             ret = TRUE;
88         }
89         else if (b.dim == DIM_S || dim == DIM_M)
90         {
91             ret = FALSE;
92         }
93         else if (ord == b.ord)
94         {
95             ret = dim < b.dim;
96         }
97         else
98         {
99             ret = ord < b.ord;
100         }
101     }
102 
103     return ret;
104 }
105 
operator >(const Coordinate & b)106 BOOL_32 Coordinate::operator>(const Coordinate& b)
107 {
108     BOOL_32 lt = *this < b;
109     BOOL_32 eq = *this == b;
110     return !lt && !eq;
111 }
112 
operator <=(const Coordinate & b)113 BOOL_32 Coordinate::operator<=(const Coordinate& b)
114 {
115     return (*this < b) || (*this == b);
116 }
117 
operator >=(const Coordinate & b)118 BOOL_32 Coordinate::operator>=(const Coordinate& b)
119 {
120     return !(*this < b);
121 }
122 
operator !=(const Coordinate & b)123 BOOL_32 Coordinate::operator!=(const Coordinate& b)
124 {
125     return !(*this == b);
126 }
127 
operator ++(INT_32)128 Coordinate& Coordinate::operator++(INT_32)
129 {
130     ord++;
131     return *this;
132 }
133 
134 // CoordTerm
135 
CoordTerm()136 CoordTerm::CoordTerm()
137 {
138     num_coords = 0;
139 }
140 
Clear()141 VOID CoordTerm::Clear()
142 {
143     num_coords = 0;
144 }
145 
add(Coordinate & co)146 VOID CoordTerm::add(Coordinate& co)
147 {
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
151     UINT_32 i;
152 
153     for (i = 0; i < num_coords; i++)
154     {
155         if (m_coord[i] == co)
156         {
157             break;
158         }
159         if (m_coord[i] > co)
160         {
161             for (UINT_32 j = num_coords; j > i; j--)
162             {
163                 m_coord[j] = m_coord[j - 1];
164             }
165             m_coord[i] = co;
166             num_coords++;
167             break;
168         }
169     }
170 
171     if (i == num_coords)
172     {
173         m_coord[num_coords] = co;
174         num_coords++;
175     }
176 }
177 
add(CoordTerm & cl)178 VOID CoordTerm::add(CoordTerm& cl)
179 {
180     for (UINT_32 i = 0; i < cl.num_coords; i++)
181     {
182         add(cl.m_coord[i]);
183     }
184 }
185 
remove(Coordinate & co)186 BOOL_32 CoordTerm::remove(Coordinate& co)
187 {
188     BOOL_32 remove = FALSE;
189     for (UINT_32 i = 0; i < num_coords; i++)
190     {
191         if (m_coord[i] == co)
192         {
193             remove = TRUE;
194             num_coords--;
195         }
196 
197         if (remove)
198         {
199             m_coord[i] = m_coord[i + 1];
200         }
201     }
202     return remove;
203 }
204 
Exists(Coordinate & co)205 BOOL_32 CoordTerm::Exists(Coordinate& co)
206 {
207     BOOL_32 exists = FALSE;
208     for (UINT_32 i = 0; i < num_coords; i++)
209     {
210         if (m_coord[i] == co)
211         {
212             exists = TRUE;
213             break;
214         }
215     }
216     return exists;
217 }
218 
copyto(CoordTerm & cl)219 VOID CoordTerm::copyto(CoordTerm& cl)
220 {
221     cl.num_coords = num_coords;
222     for (UINT_32 i = 0; i < num_coords; i++)
223     {
224         cl.m_coord[i] = m_coord[i];
225     }
226 }
227 
getsize()228 UINT_32 CoordTerm::getsize()
229 {
230     return num_coords;
231 }
232 
getxor(const UINT_32 * coords) const233 UINT_32 CoordTerm::getxor(const UINT_32 *coords) const
234 {
235     UINT_32 out = 0;
236     for (UINT_32 i = 0; i < num_coords; i++)
237     {
238         out = out ^ m_coord[i].ison(coords);
239     }
240     return out;
241 }
242 
getsmallest(Coordinate & co)243 VOID CoordTerm::getsmallest(Coordinate& co)
244 {
245     co = m_coord[0];
246 }
247 
Filter(INT_8 f,Coordinate & co,UINT_32 start,enum Dim axis)248 UINT_32 CoordTerm::Filter(INT_8 f, Coordinate& co, UINT_32 start, enum Dim axis)
249 {
250     for (UINT_32 i = start;  i < num_coords;)
251     {
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()))
256         {
257             for (UINT_32 j = i; j < num_coords - 1; j++)
258             {
259                 m_coord[j] = m_coord[j + 1];
260             }
261             num_coords--;
262         }
263         else
264         {
265             i++;
266         }
267     }
268     return num_coords;
269 }
270 
operator [](UINT_32 i)271 Coordinate& CoordTerm::operator[](UINT_32 i)
272 {
273     return m_coord[i];
274 }
275 
operator ==(const CoordTerm & b)276 BOOL_32 CoordTerm::operator==(const CoordTerm& b)
277 {
278     BOOL_32 ret = TRUE;
279 
280     if (num_coords != b.num_coords)
281     {
282         ret = FALSE;
283     }
284     else
285     {
286         for (UINT_32 i = 0; i < num_coords; i++)
287         {
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])
290             {
291                 ret = FALSE;
292                 break;
293             }
294         }
295     }
296     return ret;
297 }
298 
operator !=(const CoordTerm & b)299 BOOL_32 CoordTerm::operator!=(const CoordTerm& b)
300 {
301     return !(*this == b);
302 }
303 
exceedRange(const UINT_32 * ranges)304 BOOL_32 CoordTerm::exceedRange(const UINT_32 *ranges)
305 {
306     BOOL_32 exceed = FALSE;
307     for (UINT_32 i = 0; (i < num_coords) && (exceed == FALSE); i++)
308     {
309         exceed = ((1u << m_coord[i].getord()) <= ranges[m_coord[i].getdim()]);
310     }
311 
312     return exceed;
313 }
314 
315 // coordeq
CoordEq()316 CoordEq::CoordEq()
317 {
318     m_numBits = 0;
319 }
320 
remove(Coordinate & co)321 VOID CoordEq::remove(Coordinate& co)
322 {
323     for (UINT_32 i = 0; i < m_numBits; i++)
324     {
325         m_eq[i].remove(co);
326     }
327 }
328 
Exists(Coordinate & co)329 BOOL_32 CoordEq::Exists(Coordinate& co)
330 {
331     BOOL_32 exists = FALSE;
332 
333     for (UINT_32 i = 0; i < m_numBits; i++)
334     {
335         if (m_eq[i].Exists(co))
336         {
337             exists = TRUE;
338         }
339     }
340     return exists;
341 }
342 
resize(UINT_32 n)343 VOID CoordEq::resize(UINT_32 n)
344 {
345     if (n > m_numBits)
346     {
347         for (UINT_32 i = m_numBits; i < n; i++)
348         {
349             m_eq[i].Clear();
350         }
351     }
352     m_numBits = n;
353 }
354 
getsize()355 UINT_32 CoordEq::getsize()
356 {
357     return m_numBits;
358 }
359 
solve(const UINT_32 * coords) const360 UINT_64 CoordEq::solve(const UINT_32 *coords) const
361 {
362     UINT_64 out = 0;
363     for (UINT_32 i = 0; i < m_numBits; i++)
364     {
365         out |= static_cast<UINT_64>(m_eq[i].getxor(coords)) << i;
366     }
367     return out;
368 }
369 
solveAddr(UINT_64 addr,UINT_32 sliceInM,UINT_32 * coords) const370 VOID CoordEq::solveAddr(
371     UINT_64 addr, UINT_32 sliceInM,
372     UINT_32 *coords) const
373 {
374     UINT_32 BitsValid[NUM_DIMS] = {0};
375 
376     CoordEq temp = *this;
377 
378     memset(coords, 0, NUM_DIMS * sizeof(coords[0]));
379 
380     UINT_32 bitsLeft = 0;
381 
382     for (UINT_32 i = 0; i < temp.m_numBits; i++)
383     {
384         UINT_32 termSize = temp.m_eq[i].getsize();
385 
386         if (termSize == 1)
387         {
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();
391 
392             ADDR_ASSERT((ord < 32) || (bit == 0));
393 
394             BitsValid[dim] |= 1u << ord;
395             coords[dim] |= bit << ord;
396 
397             temp.m_eq[i].Clear();
398         }
399         else if (termSize > 1)
400         {
401             bitsLeft++;
402         }
403     }
404 
405     if (bitsLeft > 0)
406     {
407         if (sliceInM != 0)
408         {
409             coords[DIM_Z] = coords[DIM_M] / sliceInM;
410             BitsValid[DIM_Z] = 0xffffffff;
411         }
412 
413         do
414         {
415             bitsLeft = 0;
416 
417             for (UINT_32 i = 0; i < temp.m_numBits; i++)
418             {
419                 UINT_32 termSize = temp.m_eq[i].getsize();
420 
421                 if (termSize == 1)
422                 {
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();
426 
427                     ADDR_ASSERT((ord < 32) || (bit == 0));
428                     ADDR_ASSERT(dim < DIM_S);
429 
430                     BitsValid[dim] |= 1u << ord;
431                     coords[dim] |= bit << ord;
432 
433                     temp.m_eq[i].Clear();
434                 }
435                 else if (termSize > 1)
436                 {
437                     CoordTerm tmpTerm = temp.m_eq[i];
438 
439                     for (UINT_32 j = 0; j < termSize; j++)
440                     {
441                         enum Dim dim = temp.m_eq[i][j].getdim();
442                         INT_8 ord = temp.m_eq[i][j].getord();
443 
444                         ADDR_ASSERT(dim < DIM_S);
445 
446                         if (BitsValid[dim] & (1u << ord))
447                         {
448                             UINT_32 v = (((coords[dim] >> ord) & 1) << i);
449                             addr ^= static_cast<UINT_64>(v);
450                             tmpTerm.remove(temp.m_eq[i][j]);
451                         }
452                     }
453 
454                     temp.m_eq[i] = tmpTerm;
455 
456                     bitsLeft++;
457                 }
458             }
459         } while (bitsLeft > 0);
460     }
461 }
462 
copy(CoordEq & o,UINT_32 start,UINT_32 num)463 VOID CoordEq::copy(CoordEq& o, UINT_32 start, UINT_32 num)
464 {
465     o.m_numBits = (num == 0xFFFFFFFF) ? m_numBits : num;
466     for (UINT_32 i = 0; i < o.m_numBits; i++)
467     {
468         m_eq[start + i].copyto(o.m_eq[i]);
469     }
470 }
471 
reverse(UINT_32 start,UINT_32 num)472 VOID CoordEq::reverse(UINT_32 start, UINT_32 num)
473 {
474     UINT_32 n = (num == 0xFFFFFFFF) ? m_numBits : num;
475 
476     for (UINT_32 i = 0; i < n / 2; i++)
477     {
478         CoordTerm temp;
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]);
482     }
483 }
484 
xorin(CoordEq & x,UINT_32 start)485 VOID CoordEq::xorin(CoordEq& x, UINT_32 start)
486 {
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++)
489     {
490         m_eq[start + i].add(x.m_eq[i]);
491     }
492 }
493 
Filter(INT_8 f,Coordinate & co,UINT_32 start,enum Dim axis)494 UINT_32 CoordEq::Filter(INT_8 f, Coordinate& co, UINT_32 start, enum Dim axis)
495 {
496     for (UINT_32 i = start; i < m_numBits;)
497     {
498         UINT_32 m = m_eq[i].Filter(f, co, 0, axis);
499         if (m == 0)
500         {
501             for (UINT_32 j = i; j < m_numBits - 1; j++)
502             {
503                 m_eq[j] = m_eq[j + 1];
504             }
505             m_numBits--;
506         }
507         else
508         {
509             i++;
510         }
511     }
512     return m_numBits;
513 }
514 
shift(INT_32 amount,INT_32 start)515 VOID CoordEq::shift(INT_32 amount, INT_32 start)
516 {
517     if (amount != 0)
518     {
519         INT_32 numBits = static_cast<INT_32>(m_numBits);
520         amount = -amount;
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)
525         {
526             if ((i + amount < start) || (i + amount >= numBits))
527             {
528                 m_eq[i].Clear();
529             }
530             else
531             {
532                 m_eq[i + amount].copyto(m_eq[i]);
533             }
534         }
535     }
536 }
537 
operator [](UINT_32 i)538 CoordTerm& CoordEq::operator[](UINT_32 i)
539 {
540     return m_eq[i];
541 }
542 
mort2d(Coordinate & c0,Coordinate & c1,UINT_32 start,UINT_32 end)543 VOID CoordEq::mort2d(Coordinate& c0, Coordinate& c1, UINT_32 start, UINT_32 end)
544 {
545     if (end == 0)
546     {
547         ADDR_ASSERT(m_numBits > 0);
548         end = m_numBits - 1;
549     }
550     for (UINT_32 i = start; i <= end; i++)
551     {
552         UINT_32 select = (i - start) % 2;
553         Coordinate& c = (select == 0) ? c0 : c1;
554         m_eq[i].add(c);
555         c++;
556     }
557 }
558 
mort3d(Coordinate & c0,Coordinate & c1,Coordinate & c2,UINT_32 start,UINT_32 end)559 VOID CoordEq::mort3d(Coordinate& c0, Coordinate& c1, Coordinate& c2, UINT_32 start, UINT_32 end)
560 {
561     if (end == 0)
562     {
563         ADDR_ASSERT(m_numBits > 0);
564         end = m_numBits - 1;
565     }
566     for (UINT_32 i = start; i <= end; i++)
567     {
568         UINT_32 select = (i - start) % 3;
569         Coordinate& c = (select == 0) ? c0 : ((select == 1) ? c1 : c2);
570         m_eq[i].add(c);
571         c++;
572     }
573 }
574 
operator ==(const CoordEq & b)575 BOOL_32 CoordEq::operator==(const CoordEq& b)
576 {
577     BOOL_32 ret = TRUE;
578 
579     if (m_numBits != b.m_numBits)
580     {
581         ret = FALSE;
582     }
583     else
584     {
585         for (UINT_32 i = 0; i < m_numBits; i++)
586         {
587             if (m_eq[i] != b.m_eq[i])
588             {
589                 ret = FALSE;
590                 break;
591             }
592         }
593     }
594     return ret;
595 }
596 
operator !=(const CoordEq & b)597 BOOL_32 CoordEq::operator!=(const CoordEq& b)
598 {
599     return !(*this == b);
600 }
601 
602 } // V2
603 } // Addr
604