2 * Copyright © 2007-2019 Advanced Micro Devices, Inc.
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
15 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
17 * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 * USE OR OTHER DEALINGS IN THE SOFTWARE.
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
27 // Coordinate class implementation
28 #include "addrcommon.h"
36 Coordinate::Coordinate()
42 Coordinate::Coordinate(INT_8 c
, INT_32 n
)
47 VOID
Coordinate::set(INT_8 c
, INT_32 n
)
50 ord
= static_cast<INT_8
>(n
);
53 UINT_32
Coordinate::ison(UINT_32 x
, UINT_32 y
, UINT_32 z
, UINT_32 s
, UINT_32 m
) const
55 UINT_32 bit
= static_cast<UINT_32
>(1ull << static_cast<UINT_32
>(ord
));
60 case 'm': out
= m
& bit
; break;
61 case 's': out
= s
& bit
; break;
62 case 'x': out
= x
& bit
; break;
63 case 'y': out
= y
& bit
; break;
64 case 'z': out
= z
& bit
; break;
66 return (out
!= 0) ? 1 : 0;
69 INT_8
Coordinate::getdim()
74 INT_8
Coordinate::getord()
79 BOOL_32
Coordinate::operator==(const Coordinate
& b
)
81 return (dim
== b
.dim
) && (ord
== b
.ord
);
84 BOOL_32
Coordinate::operator<(const Coordinate
& b
)
94 if (dim
== 's' || b
.dim
== 'm')
98 else if (b
.dim
== 's' || dim
== 'm')
102 else if (ord
== b
.ord
)
115 BOOL_32
Coordinate::operator>(const Coordinate
& b
)
117 BOOL_32 lt
= *this < b
;
118 BOOL_32 eq
= *this == b
;
122 BOOL_32
Coordinate::operator<=(const Coordinate
& b
)
124 return (*this < b
) || (*this == b
);
127 BOOL_32
Coordinate::operator>=(const Coordinate
& b
)
132 BOOL_32
Coordinate::operator!=(const Coordinate
& b
)
134 return !(*this == b
);
137 Coordinate
& Coordinate::operator++(INT_32
)
145 CoordTerm::CoordTerm()
150 VOID
CoordTerm::Clear()
155 VOID
CoordTerm::add(Coordinate
& co
)
157 // This function adds a coordinate INT_32o the list
158 // It will prevent the same coordinate from appearing,
159 // and will keep the list ordered from smallest to largest
162 for (i
= 0; i
< num_coords
; i
++)
164 if (m_coord
[i
] == co
)
170 for (UINT_32 j
= num_coords
; j
> i
; j
--)
172 m_coord
[j
] = m_coord
[j
- 1];
182 m_coord
[num_coords
] = co
;
187 VOID
CoordTerm::add(CoordTerm
& cl
)
189 for (UINT_32 i
= 0; i
< cl
.num_coords
; i
++)
195 BOOL_32
CoordTerm::remove(Coordinate
& co
)
197 BOOL_32 remove
= FALSE
;
198 for (UINT_32 i
= 0; i
< num_coords
; i
++)
200 if (m_coord
[i
] == co
)
208 m_coord
[i
] = m_coord
[i
+ 1];
214 BOOL_32
CoordTerm::Exists(Coordinate
& co
)
216 BOOL_32 exists
= FALSE
;
217 for (UINT_32 i
= 0; i
< num_coords
; i
++)
219 if (m_coord
[i
] == co
)
228 VOID
CoordTerm::copyto(CoordTerm
& cl
)
230 cl
.num_coords
= num_coords
;
231 for (UINT_32 i
= 0; i
< num_coords
; i
++)
233 cl
.m_coord
[i
] = m_coord
[i
];
237 UINT_32
CoordTerm::getsize()
242 UINT_32
CoordTerm::getxor(UINT_32 x
, UINT_32 y
, UINT_32 z
, UINT_32 s
, UINT_32 m
) const
245 for (UINT_32 i
= 0; i
< num_coords
; i
++)
247 out
= out
^ m_coord
[i
].ison(x
, y
, z
, s
, m
);
252 VOID
CoordTerm::getsmallest(Coordinate
& co
)
257 UINT_32
CoordTerm::Filter(INT_8 f
, Coordinate
& co
, UINT_32 start
, INT_8 axis
)
259 for (UINT_32 i
= start
; i
< num_coords
;)
261 if (((f
== '<' && m_coord
[i
] < co
) ||
262 (f
== '>' && m_coord
[i
] > co
) ||
263 (f
== '=' && m_coord
[i
] == co
)) &&
264 (axis
== '\0' || axis
== m_coord
[i
].getdim()))
266 for (UINT_32 j
= i
; j
< num_coords
- 1; j
++)
268 m_coord
[j
] = m_coord
[j
+ 1];
280 Coordinate
& CoordTerm::operator[](UINT_32 i
)
285 BOOL_32
CoordTerm::operator==(const CoordTerm
& b
)
289 if (num_coords
!= b
.num_coords
)
295 for (UINT_32 i
= 0; i
< num_coords
; i
++)
297 // Note: the lists will always be in order, so we can compare the two lists at time
298 if (m_coord
[i
] != b
.m_coord
[i
])
308 BOOL_32
CoordTerm::operator!=(const CoordTerm
& b
)
310 return !(*this == b
);
313 BOOL_32
CoordTerm::exceedRange(UINT_32 xRange
, UINT_32 yRange
, UINT_32 zRange
, UINT_32 sRange
)
315 BOOL_32 exceed
= FALSE
;
316 for (UINT_32 i
= 0; (i
< num_coords
) && (exceed
== FALSE
); i
++)
319 switch (m_coord
[i
].getdim())
338 ADDR_ASSERT_ALWAYS();
343 exceed
= ((1u << m_coord
[i
].getord()) <= subject
);
355 VOID
CoordEq::remove(Coordinate
& co
)
357 for (UINT_32 i
= 0; i
< m_numBits
; i
++)
363 BOOL_32
CoordEq::Exists(Coordinate
& co
)
365 BOOL_32 exists
= FALSE
;
367 for (UINT_32 i
= 0; i
< m_numBits
; i
++)
369 if (m_eq
[i
].Exists(co
))
377 VOID
CoordEq::resize(UINT_32 n
)
381 for (UINT_32 i
= m_numBits
; i
< n
; i
++)
389 UINT_32
CoordEq::getsize()
394 UINT_64
CoordEq::solve(UINT_32 x
, UINT_32 y
, UINT_32 z
, UINT_32 s
, UINT_32 m
) const
397 for (UINT_32 i
= 0; i
< m_numBits
; i
++)
399 if (m_eq
[i
].getxor(x
, y
, z
, s
, m
) != 0)
407 VOID
CoordEq::solveAddr(
408 UINT_64 addr
, UINT_32 sliceInM
,
409 UINT_32
& x
, UINT_32
& y
, UINT_32
& z
, UINT_32
& s
, UINT_32
& m
) const
411 UINT_32 xBitsValid
= 0;
412 UINT_32 yBitsValid
= 0;
413 UINT_32 zBitsValid
= 0;
414 UINT_32 sBitsValid
= 0;
415 UINT_32 mBitsValid
= 0;
417 CoordEq temp
= *this;
419 x
= y
= z
= s
= m
= 0;
421 UINT_32 bitsLeft
= 0;
423 for (UINT_32 i
= 0; i
< temp
.m_numBits
; i
++)
425 UINT_32 termSize
= temp
.m_eq
[i
].getsize();
429 INT_8 bit
= (addr
>> i
) & 1;
430 INT_8 dim
= temp
.m_eq
[i
][0].getdim();
431 INT_8 ord
= temp
.m_eq
[i
][0].getord();
433 ADDR_ASSERT((ord
< 32) || (bit
== 0));
438 xBitsValid
|= (1 << ord
);
442 yBitsValid
|= (1 << ord
);
446 zBitsValid
|= (1 << ord
);
450 sBitsValid
|= (1 << ord
);
454 mBitsValid
|= (1 << ord
);
461 temp
.m_eq
[i
].Clear();
463 else if (termSize
> 1)
474 zBitsValid
= 0xffffffff;
481 for (UINT_32 i
= 0; i
< temp
.m_numBits
; i
++)
483 UINT_32 termSize
= temp
.m_eq
[i
].getsize();
487 INT_8 bit
= (addr
>> i
) & 1;
488 INT_8 dim
= temp
.m_eq
[i
][0].getdim();
489 INT_8 ord
= temp
.m_eq
[i
][0].getord();
491 ADDR_ASSERT((ord
< 32) || (bit
== 0));
496 xBitsValid
|= (1 << ord
);
500 yBitsValid
|= (1 << ord
);
504 zBitsValid
|= (1 << ord
);
508 ADDR_ASSERT_ALWAYS();
511 ADDR_ASSERT_ALWAYS();
517 temp
.m_eq
[i
].Clear();
519 else if (termSize
> 1)
521 CoordTerm tmpTerm
= temp
.m_eq
[i
];
523 for (UINT_32 j
= 0; j
< termSize
; j
++)
525 INT_8 dim
= temp
.m_eq
[i
][j
].getdim();
526 INT_8 ord
= temp
.m_eq
[i
][j
].getord();
531 if (xBitsValid
& (1 << ord
))
533 UINT_32 v
= (((x
>> ord
) & 1) << i
);
534 addr
^= static_cast<UINT_64
>(v
);
535 tmpTerm
.remove(temp
.m_eq
[i
][j
]);
539 if (yBitsValid
& (1 << ord
))
541 UINT_32 v
= (((y
>> ord
) & 1) << i
);
542 addr
^= static_cast<UINT_64
>(v
);
543 tmpTerm
.remove(temp
.m_eq
[i
][j
]);
547 if (zBitsValid
& (1 << ord
))
549 UINT_32 v
= (((z
>> ord
) & 1) << i
);
550 addr
^= static_cast<UINT_64
>(v
);
551 tmpTerm
.remove(temp
.m_eq
[i
][j
]);
555 ADDR_ASSERT_ALWAYS();
558 ADDR_ASSERT_ALWAYS();
565 temp
.m_eq
[i
] = tmpTerm
;
570 } while (bitsLeft
> 0);
574 VOID
CoordEq::copy(CoordEq
& o
, UINT_32 start
, UINT_32 num
)
576 o
.m_numBits
= (num
== 0xFFFFFFFF) ? m_numBits
: num
;
577 for (UINT_32 i
= 0; i
< o
.m_numBits
; i
++)
579 m_eq
[start
+ i
].copyto(o
.m_eq
[i
]);
583 VOID
CoordEq::reverse(UINT_32 start
, UINT_32 num
)
585 UINT_32 n
= (num
== 0xFFFFFFFF) ? m_numBits
: num
;
587 for (UINT_32 i
= 0; i
< n
/ 2; i
++)
590 m_eq
[start
+ i
].copyto(temp
);
591 m_eq
[start
+ n
- 1 - i
].copyto(m_eq
[start
+ i
]);
592 temp
.copyto(m_eq
[start
+ n
- 1 - i
]);
596 VOID
CoordEq::xorin(CoordEq
& x
, UINT_32 start
)
598 UINT_32 n
= ((m_numBits
- start
) < x
.m_numBits
) ? (m_numBits
- start
) : x
.m_numBits
;
599 for (UINT_32 i
= 0; i
< n
; i
++)
601 m_eq
[start
+ i
].add(x
.m_eq
[i
]);
605 UINT_32
CoordEq::Filter(INT_8 f
, Coordinate
& co
, UINT_32 start
, INT_8 axis
)
607 for (UINT_32 i
= start
; i
< m_numBits
;)
609 UINT_32 m
= m_eq
[i
].Filter(f
, co
, 0, axis
);
612 for (UINT_32 j
= i
; j
< m_numBits
- 1; j
++)
614 m_eq
[j
] = m_eq
[j
+ 1];
626 VOID
CoordEq::shift(INT_32 amount
, INT_32 start
)
630 INT_32 numBits
= static_cast<INT_32
>(m_numBits
);
632 INT_32 inc
= (amount
< 0) ? -1 : 1;
633 INT_32 i
= (amount
< 0) ? numBits
- 1 : start
;
634 INT_32 end
= (amount
< 0) ? start
- 1 : numBits
;
635 for (; (inc
> 0) ? i
< end
: i
> end
; i
+= inc
)
637 if ((i
+ amount
< start
) || (i
+ amount
>= numBits
))
643 m_eq
[i
+ amount
].copyto(m_eq
[i
]);
649 CoordTerm
& CoordEq::operator[](UINT_32 i
)
654 VOID
CoordEq::mort2d(Coordinate
& c0
, Coordinate
& c1
, UINT_32 start
, UINT_32 end
)
658 ADDR_ASSERT(m_numBits
> 0);
661 for (UINT_32 i
= start
; i
<= end
; i
++)
663 UINT_32 select
= (i
- start
) % 2;
664 Coordinate
& c
= (select
== 0) ? c0
: c1
;
670 VOID
CoordEq::mort3d(Coordinate
& c0
, Coordinate
& c1
, Coordinate
& c2
, UINT_32 start
, UINT_32 end
)
674 ADDR_ASSERT(m_numBits
> 0);
677 for (UINT_32 i
= start
; i
<= end
; i
++)
679 UINT_32 select
= (i
- start
) % 3;
680 Coordinate
& c
= (select
== 0) ? c0
: ((select
== 1) ? c1
: c2
);
686 BOOL_32
CoordEq::operator==(const CoordEq
& b
)
690 if (m_numBits
!= b
.m_numBits
)
696 for (UINT_32 i
= 0; i
< m_numBits
; i
++)
698 if (m_eq
[i
] != b
.m_eq
[i
])
708 BOOL_32
CoordEq::operator!=(const CoordEq
& b
)
710 return !(*this == b
);