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(INT_8 c
, INT_32 n
)
48 VOID
Coordinate::set(INT_8 c
, INT_32 n
)
51 ord
= static_cast<INT_8
>(n
);
54 UINT_32
Coordinate::ison(UINT_32 x
, UINT_32 y
, UINT_32 z
, UINT_32 s
, UINT_32 m
) const
56 UINT_32 bit
= static_cast<UINT_32
>(1ull << static_cast<UINT_32
>(ord
));
61 case 'm': out
= m
& bit
; break;
62 case 's': out
= s
& bit
; break;
63 case 'x': out
= x
& bit
; break;
64 case 'y': out
= y
& bit
; break;
65 case 'z': out
= z
& bit
; break;
67 return (out
!= 0) ? 1 : 0;
70 INT_8
Coordinate::getdim()
75 INT_8
Coordinate::getord()
80 BOOL_32
Coordinate::operator==(const Coordinate
& b
)
82 return (dim
== b
.dim
) && (ord
== b
.ord
);
85 BOOL_32
Coordinate::operator<(const Coordinate
& b
)
95 if (dim
== 's' || b
.dim
== 'm')
99 else if (b
.dim
== 's' || dim
== 'm')
103 else if (ord
== b
.ord
)
116 BOOL_32
Coordinate::operator>(const Coordinate
& b
)
118 BOOL_32 lt
= *this < b
;
119 BOOL_32 eq
= *this == b
;
123 BOOL_32
Coordinate::operator<=(const Coordinate
& b
)
125 return (*this < b
) || (*this == b
);
128 BOOL_32
Coordinate::operator>=(const Coordinate
& b
)
133 BOOL_32
Coordinate::operator!=(const Coordinate
& b
)
135 return !(*this == b
);
138 Coordinate
& Coordinate::operator++(INT_32
)
146 CoordTerm::CoordTerm()
151 VOID
CoordTerm::Clear()
156 VOID
CoordTerm::add(Coordinate
& co
)
158 // This function adds a coordinate INT_32o the list
159 // It will prevent the same coordinate from appearing,
160 // and will keep the list ordered from smallest to largest
163 for (i
= 0; i
< num_coords
; i
++)
165 if (m_coord
[i
] == co
)
171 for (UINT_32 j
= num_coords
; j
> i
; j
--)
173 m_coord
[j
] = m_coord
[j
- 1];
183 m_coord
[num_coords
] = co
;
188 VOID
CoordTerm::add(CoordTerm
& cl
)
190 for (UINT_32 i
= 0; i
< cl
.num_coords
; i
++)
196 BOOL_32
CoordTerm::remove(Coordinate
& co
)
198 BOOL_32 remove
= FALSE
;
199 for (UINT_32 i
= 0; i
< num_coords
; i
++)
201 if (m_coord
[i
] == co
)
209 m_coord
[i
] = m_coord
[i
+ 1];
215 BOOL_32
CoordTerm::Exists(Coordinate
& co
)
217 BOOL_32 exists
= FALSE
;
218 for (UINT_32 i
= 0; i
< num_coords
; i
++)
220 if (m_coord
[i
] == co
)
229 VOID
CoordTerm::copyto(CoordTerm
& cl
)
231 cl
.num_coords
= num_coords
;
232 for (UINT_32 i
= 0; i
< num_coords
; i
++)
234 cl
.m_coord
[i
] = m_coord
[i
];
238 UINT_32
CoordTerm::getsize()
243 UINT_32
CoordTerm::getxor(UINT_32 x
, UINT_32 y
, UINT_32 z
, UINT_32 s
, UINT_32 m
) const
246 for (UINT_32 i
= 0; i
< num_coords
; i
++)
248 out
= out
^ m_coord
[i
].ison(x
, y
, z
, s
, m
);
253 VOID
CoordTerm::getsmallest(Coordinate
& co
)
258 UINT_32
CoordTerm::Filter(INT_8 f
, Coordinate
& co
, UINT_32 start
, INT_8 axis
)
260 for (UINT_32 i
= start
; i
< num_coords
;)
262 if (((f
== '<' && m_coord
[i
] < co
) ||
263 (f
== '>' && m_coord
[i
] > co
) ||
264 (f
== '=' && m_coord
[i
] == co
)) &&
265 (axis
== '\0' || axis
== m_coord
[i
].getdim()))
267 for (UINT_32 j
= i
; j
< num_coords
- 1; j
++)
269 m_coord
[j
] = m_coord
[j
+ 1];
281 Coordinate
& CoordTerm::operator[](UINT_32 i
)
286 BOOL_32
CoordTerm::operator==(const CoordTerm
& b
)
290 if (num_coords
!= b
.num_coords
)
296 for (UINT_32 i
= 0; i
< num_coords
; i
++)
298 // Note: the lists will always be in order, so we can compare the two lists at time
299 if (m_coord
[i
] != b
.m_coord
[i
])
309 BOOL_32
CoordTerm::operator!=(const CoordTerm
& b
)
311 return !(*this == b
);
314 BOOL_32
CoordTerm::exceedRange(UINT_32 xRange
, UINT_32 yRange
, UINT_32 zRange
, UINT_32 sRange
)
316 BOOL_32 exceed
= FALSE
;
317 for (UINT_32 i
= 0; (i
< num_coords
) && (exceed
== FALSE
); i
++)
320 switch (m_coord
[i
].getdim())
339 ADDR_ASSERT_ALWAYS();
344 exceed
= ((1u << m_coord
[i
].getord()) <= subject
);
356 VOID
CoordEq::remove(Coordinate
& co
)
358 for (UINT_32 i
= 0; i
< m_numBits
; i
++)
364 BOOL_32
CoordEq::Exists(Coordinate
& co
)
366 BOOL_32 exists
= FALSE
;
368 for (UINT_32 i
= 0; i
< m_numBits
; i
++)
370 if (m_eq
[i
].Exists(co
))
378 VOID
CoordEq::resize(UINT_32 n
)
382 for (UINT_32 i
= m_numBits
; i
< n
; i
++)
390 UINT_32
CoordEq::getsize()
395 UINT_64
CoordEq::solve(UINT_32 x
, UINT_32 y
, UINT_32 z
, UINT_32 s
, UINT_32 m
) const
398 for (UINT_32 i
= 0; i
< m_numBits
; i
++)
400 if (m_eq
[i
].getxor(x
, y
, z
, s
, m
) != 0)
408 VOID
CoordEq::solveAddr(
409 UINT_64 addr
, UINT_32 sliceInM
,
410 UINT_32
& x
, UINT_32
& y
, UINT_32
& z
, UINT_32
& s
, UINT_32
& m
) const
412 UINT_32 xBitsValid
= 0;
413 UINT_32 yBitsValid
= 0;
414 UINT_32 zBitsValid
= 0;
415 UINT_32 sBitsValid
= 0;
416 UINT_32 mBitsValid
= 0;
418 CoordEq temp
= *this;
420 x
= y
= z
= s
= m
= 0;
422 UINT_32 bitsLeft
= 0;
424 for (UINT_32 i
= 0; i
< temp
.m_numBits
; i
++)
426 UINT_32 termSize
= temp
.m_eq
[i
].getsize();
430 INT_8 bit
= (addr
>> i
) & 1;
431 INT_8 dim
= temp
.m_eq
[i
][0].getdim();
432 INT_8 ord
= temp
.m_eq
[i
][0].getord();
434 ADDR_ASSERT((ord
< 32) || (bit
== 0));
439 xBitsValid
|= (1 << ord
);
443 yBitsValid
|= (1 << ord
);
447 zBitsValid
|= (1 << ord
);
451 sBitsValid
|= (1 << ord
);
455 mBitsValid
|= (1 << ord
);
462 temp
.m_eq
[i
].Clear();
464 else if (termSize
> 1)
475 zBitsValid
= 0xffffffff;
482 for (UINT_32 i
= 0; i
< temp
.m_numBits
; i
++)
484 UINT_32 termSize
= temp
.m_eq
[i
].getsize();
488 INT_8 bit
= (addr
>> i
) & 1;
489 INT_8 dim
= temp
.m_eq
[i
][0].getdim();
490 INT_8 ord
= temp
.m_eq
[i
][0].getord();
492 ADDR_ASSERT((ord
< 32) || (bit
== 0));
497 xBitsValid
|= (1 << ord
);
501 yBitsValid
|= (1 << ord
);
505 zBitsValid
|= (1 << ord
);
509 ADDR_ASSERT_ALWAYS();
512 ADDR_ASSERT_ALWAYS();
518 temp
.m_eq
[i
].Clear();
520 else if (termSize
> 1)
522 CoordTerm tmpTerm
= temp
.m_eq
[i
];
524 for (UINT_32 j
= 0; j
< termSize
; j
++)
526 INT_8 dim
= temp
.m_eq
[i
][j
].getdim();
527 INT_8 ord
= temp
.m_eq
[i
][j
].getord();
532 if (xBitsValid
& (1 << ord
))
534 UINT_32 v
= (((x
>> ord
) & 1) << i
);
535 addr
^= static_cast<UINT_64
>(v
);
536 tmpTerm
.remove(temp
.m_eq
[i
][j
]);
540 if (yBitsValid
& (1 << ord
))
542 UINT_32 v
= (((y
>> ord
) & 1) << i
);
543 addr
^= static_cast<UINT_64
>(v
);
544 tmpTerm
.remove(temp
.m_eq
[i
][j
]);
548 if (zBitsValid
& (1 << ord
))
550 UINT_32 v
= (((z
>> ord
) & 1) << i
);
551 addr
^= static_cast<UINT_64
>(v
);
552 tmpTerm
.remove(temp
.m_eq
[i
][j
]);
556 ADDR_ASSERT_ALWAYS();
559 ADDR_ASSERT_ALWAYS();
566 temp
.m_eq
[i
] = tmpTerm
;
571 } while (bitsLeft
> 0);
575 VOID
CoordEq::copy(CoordEq
& o
, UINT_32 start
, UINT_32 num
)
577 o
.m_numBits
= (num
== 0xFFFFFFFF) ? m_numBits
: num
;
578 for (UINT_32 i
= 0; i
< o
.m_numBits
; i
++)
580 m_eq
[start
+ i
].copyto(o
.m_eq
[i
]);
584 VOID
CoordEq::reverse(UINT_32 start
, UINT_32 num
)
586 UINT_32 n
= (num
== 0xFFFFFFFF) ? m_numBits
: num
;
588 for (UINT_32 i
= 0; i
< n
/ 2; i
++)
591 m_eq
[start
+ i
].copyto(temp
);
592 m_eq
[start
+ n
- 1 - i
].copyto(m_eq
[start
+ i
]);
593 temp
.copyto(m_eq
[start
+ n
- 1 - i
]);
597 VOID
CoordEq::xorin(CoordEq
& x
, UINT_32 start
)
599 UINT_32 n
= ((m_numBits
- start
) < x
.m_numBits
) ? (m_numBits
- start
) : x
.m_numBits
;
600 for (UINT_32 i
= 0; i
< n
; i
++)
602 m_eq
[start
+ i
].add(x
.m_eq
[i
]);
606 UINT_32
CoordEq::Filter(INT_8 f
, Coordinate
& co
, UINT_32 start
, INT_8 axis
)
608 for (UINT_32 i
= start
; i
< m_numBits
;)
610 UINT_32 m
= m_eq
[i
].Filter(f
, co
, 0, axis
);
613 for (UINT_32 j
= i
; j
< m_numBits
- 1; j
++)
615 m_eq
[j
] = m_eq
[j
+ 1];
627 VOID
CoordEq::shift(INT_32 amount
, INT_32 start
)
631 INT_32 numBits
= static_cast<INT_32
>(m_numBits
);
633 INT_32 inc
= (amount
< 0) ? -1 : 1;
634 INT_32 i
= (amount
< 0) ? numBits
- 1 : start
;
635 INT_32 end
= (amount
< 0) ? start
- 1 : numBits
;
636 for (; (inc
> 0) ? i
< end
: i
> end
; i
+= inc
)
638 if ((i
+ amount
< start
) || (i
+ amount
>= numBits
))
644 m_eq
[i
+ amount
].copyto(m_eq
[i
]);
650 CoordTerm
& CoordEq::operator[](UINT_32 i
)
655 VOID
CoordEq::mort2d(Coordinate
& c0
, Coordinate
& c1
, UINT_32 start
, UINT_32 end
)
659 ADDR_ASSERT(m_numBits
> 0);
662 for (UINT_32 i
= start
; i
<= end
; i
++)
664 UINT_32 select
= (i
- start
) % 2;
665 Coordinate
& c
= (select
== 0) ? c0
: c1
;
671 VOID
CoordEq::mort3d(Coordinate
& c0
, Coordinate
& c1
, Coordinate
& c2
, UINT_32 start
, UINT_32 end
)
675 ADDR_ASSERT(m_numBits
> 0);
678 for (UINT_32 i
= start
; i
<= end
; i
++)
680 UINT_32 select
= (i
- start
) % 3;
681 Coordinate
& c
= (select
== 0) ? c0
: ((select
== 1) ? c1
: c2
);
687 BOOL_32
CoordEq::operator==(const CoordEq
& b
)
691 if (m_numBits
!= b
.m_numBits
)
697 for (UINT_32 i
= 0; i
< m_numBits
; i
++)
699 if (m_eq
[i
] != b
.m_eq
[i
])
709 BOOL_32
CoordEq::operator!=(const CoordEq
& b
)
711 return !(*this == b
);