3 * Copyright © 2007-2019 Advanced Micro Devices, Inc.
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:
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.
23 * The above copyright notice and this permission notice (including the
24 * next paragraph) shall be included in all copies or substantial portions
28 // Coordinate class implementation
29 #include "addrcommon.h"
37 Coordinate::Coordinate()
43 Coordinate::Coordinate(enum Dim dim
, INT_32 n
)
48 VOID
Coordinate::set(enum Dim d
, INT_32 n
)
51 ord
= static_cast<INT_8
>(n
);
54 UINT_32
Coordinate::ison(const UINT_32
*coords
) const
56 UINT_32 bit
= static_cast<UINT_32
>(1ull << static_cast<UINT_32
>(ord
));
58 return (coords
[dim
] & bit
) ? 1 : 0;
61 enum Dim
Coordinate::getdim()
66 INT_8
Coordinate::getord()
71 BOOL_32
Coordinate::operator==(const Coordinate
& b
)
73 return (dim
== b
.dim
) && (ord
== b
.ord
);
76 BOOL_32
Coordinate::operator<(const Coordinate
& b
)
86 if (dim
== DIM_S
|| b
.dim
== DIM_M
)
90 else if (b
.dim
== DIM_S
|| dim
== DIM_M
)
94 else if (ord
== b
.ord
)
107 BOOL_32
Coordinate::operator>(const Coordinate
& b
)
109 BOOL_32 lt
= *this < b
;
110 BOOL_32 eq
= *this == b
;
114 BOOL_32
Coordinate::operator<=(const Coordinate
& b
)
116 return (*this < b
) || (*this == b
);
119 BOOL_32
Coordinate::operator>=(const Coordinate
& b
)
124 BOOL_32
Coordinate::operator!=(const Coordinate
& b
)
126 return !(*this == b
);
129 Coordinate
& Coordinate::operator++(INT_32
)
137 CoordTerm::CoordTerm()
142 VOID
CoordTerm::Clear()
147 VOID
CoordTerm::add(Coordinate
& co
)
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
154 for (i
= 0; i
< num_coords
; i
++)
156 if (m_coord
[i
] == co
)
162 for (UINT_32 j
= num_coords
; j
> i
; j
--)
164 m_coord
[j
] = m_coord
[j
- 1];
174 m_coord
[num_coords
] = co
;
179 VOID
CoordTerm::add(CoordTerm
& cl
)
181 for (UINT_32 i
= 0; i
< cl
.num_coords
; i
++)
187 BOOL_32
CoordTerm::remove(Coordinate
& co
)
189 BOOL_32 remove
= FALSE
;
190 for (UINT_32 i
= 0; i
< num_coords
; i
++)
192 if (m_coord
[i
] == co
)
200 m_coord
[i
] = m_coord
[i
+ 1];
206 BOOL_32
CoordTerm::Exists(Coordinate
& co
)
208 BOOL_32 exists
= FALSE
;
209 for (UINT_32 i
= 0; i
< num_coords
; i
++)
211 if (m_coord
[i
] == co
)
220 VOID
CoordTerm::copyto(CoordTerm
& cl
)
222 cl
.num_coords
= num_coords
;
223 for (UINT_32 i
= 0; i
< num_coords
; i
++)
225 cl
.m_coord
[i
] = m_coord
[i
];
229 UINT_32
CoordTerm::getsize()
234 UINT_32
CoordTerm::getxor(const UINT_32
*coords
) const
237 for (UINT_32 i
= 0; i
< num_coords
; i
++)
239 out
= out
^ m_coord
[i
].ison(coords
);
244 VOID
CoordTerm::getsmallest(Coordinate
& co
)
249 UINT_32
CoordTerm::Filter(INT_8 f
, Coordinate
& co
, UINT_32 start
, enum Dim axis
)
251 for (UINT_32 i
= start
; i
< num_coords
;)
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()))
258 for (UINT_32 j
= i
; j
< num_coords
- 1; j
++)
260 m_coord
[j
] = m_coord
[j
+ 1];
272 Coordinate
& CoordTerm::operator[](UINT_32 i
)
277 BOOL_32
CoordTerm::operator==(const CoordTerm
& b
)
281 if (num_coords
!= b
.num_coords
)
287 for (UINT_32 i
= 0; i
< num_coords
; i
++)
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
])
300 BOOL_32
CoordTerm::operator!=(const CoordTerm
& b
)
302 return !(*this == b
);
305 BOOL_32
CoordTerm::exceedRange(const UINT_32
*ranges
)
307 BOOL_32 exceed
= FALSE
;
308 for (UINT_32 i
= 0; (i
< num_coords
) && (exceed
== FALSE
); i
++)
310 exceed
= ((1u << m_coord
[i
].getord()) <= ranges
[m_coord
[i
].getdim()]);
322 VOID
CoordEq::remove(Coordinate
& co
)
324 for (UINT_32 i
= 0; i
< m_numBits
; i
++)
330 BOOL_32
CoordEq::Exists(Coordinate
& co
)
332 BOOL_32 exists
= FALSE
;
334 for (UINT_32 i
= 0; i
< m_numBits
; i
++)
336 if (m_eq
[i
].Exists(co
))
344 VOID
CoordEq::resize(UINT_32 n
)
348 for (UINT_32 i
= m_numBits
; i
< n
; i
++)
356 UINT_32
CoordEq::getsize()
361 UINT_64
CoordEq::solve(const UINT_32
*coords
) const
364 for (UINT_32 i
= 0; i
< m_numBits
; i
++)
366 out
|= static_cast<UINT_64
>(m_eq
[i
].getxor(coords
)) << i
;
371 VOID
CoordEq::solveAddr(
372 UINT_64 addr
, UINT_32 sliceInM
,
373 UINT_32
*coords
) const
375 UINT_32 BitsValid
[NUM_DIMS
] = {0};
377 CoordEq temp
= *this;
379 memset(coords
, 0, NUM_DIMS
* sizeof(coords
[0]));
381 UINT_32 bitsLeft
= 0;
383 for (UINT_32 i
= 0; i
< temp
.m_numBits
; i
++)
385 UINT_32 termSize
= temp
.m_eq
[i
].getsize();
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();
393 ADDR_ASSERT((ord
< 32) || (bit
== 0));
395 BitsValid
[dim
] |= 1u << ord
;
396 coords
[dim
] |= bit
<< ord
;
398 temp
.m_eq
[i
].Clear();
400 else if (termSize
> 1)
410 coords
[DIM_Z
] = coords
[DIM_M
] / sliceInM
;
411 BitsValid
[DIM_Z
] = 0xffffffff;
418 for (UINT_32 i
= 0; i
< temp
.m_numBits
; i
++)
420 UINT_32 termSize
= temp
.m_eq
[i
].getsize();
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();
428 ADDR_ASSERT((ord
< 32) || (bit
== 0));
429 ADDR_ASSERT(dim
< DIM_S
);
431 BitsValid
[dim
] |= 1u << ord
;
432 coords
[dim
] |= bit
<< ord
;
434 temp
.m_eq
[i
].Clear();
436 else if (termSize
> 1)
438 CoordTerm tmpTerm
= temp
.m_eq
[i
];
440 for (UINT_32 j
= 0; j
< termSize
; j
++)
442 enum Dim dim
= temp
.m_eq
[i
][j
].getdim();
443 INT_8 ord
= temp
.m_eq
[i
][j
].getord();
445 ADDR_ASSERT(dim
< DIM_S
);
447 if (BitsValid
[dim
] & (1u << ord
))
449 UINT_32 v
= (((coords
[dim
] >> ord
) & 1) << i
);
450 addr
^= static_cast<UINT_64
>(v
);
451 tmpTerm
.remove(temp
.m_eq
[i
][j
]);
455 temp
.m_eq
[i
] = tmpTerm
;
460 } while (bitsLeft
> 0);
464 VOID
CoordEq::copy(CoordEq
& o
, UINT_32 start
, UINT_32 num
)
466 o
.m_numBits
= (num
== 0xFFFFFFFF) ? m_numBits
: num
;
467 for (UINT_32 i
= 0; i
< o
.m_numBits
; i
++)
469 m_eq
[start
+ i
].copyto(o
.m_eq
[i
]);
473 VOID
CoordEq::reverse(UINT_32 start
, UINT_32 num
)
475 UINT_32 n
= (num
== 0xFFFFFFFF) ? m_numBits
: num
;
477 for (UINT_32 i
= 0; i
< n
/ 2; i
++)
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
]);
486 VOID
CoordEq::xorin(CoordEq
& x
, UINT_32 start
)
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
++)
491 m_eq
[start
+ i
].add(x
.m_eq
[i
]);
495 UINT_32
CoordEq::Filter(INT_8 f
, Coordinate
& co
, UINT_32 start
, enum Dim axis
)
497 for (UINT_32 i
= start
; i
< m_numBits
;)
499 UINT_32 m
= m_eq
[i
].Filter(f
, co
, 0, axis
);
502 for (UINT_32 j
= i
; j
< m_numBits
- 1; j
++)
504 m_eq
[j
] = m_eq
[j
+ 1];
516 VOID
CoordEq::shift(INT_32 amount
, INT_32 start
)
520 INT_32 numBits
= static_cast<INT_32
>(m_numBits
);
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
)
527 if ((i
+ amount
< start
) || (i
+ amount
>= numBits
))
533 m_eq
[i
+ amount
].copyto(m_eq
[i
]);
539 CoordTerm
& CoordEq::operator[](UINT_32 i
)
544 VOID
CoordEq::mort2d(Coordinate
& c0
, Coordinate
& c1
, UINT_32 start
, UINT_32 end
)
548 ADDR_ASSERT(m_numBits
> 0);
551 for (UINT_32 i
= start
; i
<= end
; i
++)
553 UINT_32 select
= (i
- start
) % 2;
554 Coordinate
& c
= (select
== 0) ? c0
: c1
;
560 VOID
CoordEq::mort3d(Coordinate
& c0
, Coordinate
& c1
, Coordinate
& c2
, UINT_32 start
, UINT_32 end
)
564 ADDR_ASSERT(m_numBits
> 0);
567 for (UINT_32 i
= start
; i
<= end
; i
++)
569 UINT_32 select
= (i
- start
) % 3;
570 Coordinate
& c
= (select
== 0) ? c0
: ((select
== 1) ? c1
: c2
);
576 BOOL_32
CoordEq::operator==(const CoordEq
& b
)
580 if (m_numBits
!= b
.m_numBits
)
586 for (UINT_32 i
= 0; i
< m_numBits
; i
++)
588 if (m_eq
[i
] != b
.m_eq
[i
])
598 BOOL_32
CoordEq::operator!=(const CoordEq
& b
)
600 return !(*this == b
);