effdc90017e213099c144406879b656ee1a18c21
2 * Copyright © 2017 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"
31 Coordinate::Coordinate()
37 Coordinate::Coordinate(INT_8 c
, UINT_32 n
)
42 VOID
Coordinate::set(INT_8 c
, UINT_32 n
)
45 ord
= static_cast<INT_8
>(n
);
48 UINT_32
Coordinate::ison(UINT_32 x
, UINT_32 y
, UINT_32 z
, UINT_32 s
, UINT_32 m
)
50 UINT_32 bit
= 1 << (UINT_32
)ord
;
55 case 'm': out
= m
& bit
; break;
56 case 's': out
= s
& bit
; break;
57 case 'x': out
= x
& bit
; break;
58 case 'y': out
= y
& bit
; break;
59 case 'z': out
= z
& bit
; break;
61 return (out
!= 0) ? 1 : 0;
64 INT_8
Coordinate::getdim()
69 INT_8
Coordinate::getord()
74 BOOL_32
Coordinate::operator==(const Coordinate
& b
)
76 return (dim
== b
.dim
) && (ord
== b
.ord
);
79 BOOL_32
Coordinate::operator<(const Coordinate
& b
)
89 if (dim
== 's' || b
.dim
== 'm')
93 else if (b
.dim
== 's' || dim
== 'm')
97 else if (ord
== b
.ord
)
110 BOOL_32
Coordinate::operator>(const Coordinate
& b
)
112 BOOL_32 lt
= *this < b
;
113 BOOL_32 eq
= *this == b
;
117 BOOL_32
Coordinate::operator<=(const Coordinate
& b
)
119 return (*this < b
) || (*this == b
);
122 BOOL_32
Coordinate::operator>=(const Coordinate
& b
)
127 BOOL_32
Coordinate::operator!=(const Coordinate
& b
)
129 return !(*this == b
);
132 Coordinate
& Coordinate::operator++(INT_32
)
140 CoordTerm::CoordTerm()
145 VOID
CoordTerm::Clear()
150 VOID
CoordTerm::add(Coordinate
& co
)
152 // This function adds a coordinate INT_32o the list
153 // It will prevent the same coordinate from appearing,
154 // and will keep the list ordered from smallest to largest
157 for (i
= 0; i
< num_coords
; i
++)
159 if (m_coord
[i
] == co
)
165 for (UINT_32 j
= num_coords
; j
> i
; j
--)
167 m_coord
[j
] = m_coord
[j
- 1];
177 m_coord
[num_coords
] = co
;
182 VOID
CoordTerm::add(CoordTerm
& cl
)
184 for (UINT_32 i
= 0; i
< cl
.num_coords
; i
++)
190 BOOL_32
CoordTerm::remove(Coordinate
& co
)
192 BOOL_32 remove
= FALSE
;
193 for (UINT_32 i
= 0; i
< num_coords
; i
++)
195 if (m_coord
[i
] == co
)
203 m_coord
[i
] = m_coord
[i
+ 1];
209 BOOL_32
CoordTerm::Exists(Coordinate
& co
)
211 BOOL_32 exists
= FALSE
;
212 for (UINT_32 i
= 0; i
< num_coords
; i
++)
214 if (m_coord
[i
] == co
)
223 VOID
CoordTerm::copyto(CoordTerm
& cl
)
225 cl
.num_coords
= num_coords
;
226 for (UINT_32 i
= 0; i
< num_coords
; i
++)
228 cl
.m_coord
[i
] = m_coord
[i
];
232 UINT_32
CoordTerm::getsize()
237 UINT_32
CoordTerm::getxor(UINT_32 x
, UINT_32 y
, UINT_32 z
, UINT_32 s
, UINT_32 m
)
240 for (UINT_32 i
= 0; i
< num_coords
; i
++)
242 out
= out
^ m_coord
[i
].ison(x
, y
, z
, s
, m
);
247 VOID
CoordTerm::getsmallest(Coordinate
& co
)
252 UINT_32
CoordTerm::Filter(INT_8 f
, Coordinate
& co
, UINT_32 start
, INT_8 axis
)
254 for (UINT_32 i
= start
; i
< num_coords
;)
256 if (((f
== '<' && m_coord
[i
] < co
) ||
257 (f
== '>' && m_coord
[i
] > co
) ||
258 (f
== '=' && m_coord
[i
] == co
)) &&
259 (axis
== '\0' || axis
== m_coord
[i
].getdim()))
261 for (UINT_32 j
= i
; j
< num_coords
- 1; j
++)
263 m_coord
[j
] = m_coord
[j
+ 1];
275 Coordinate
& CoordTerm::operator[](UINT_32 i
)
280 BOOL_32
CoordTerm::operator==(const CoordTerm
& b
)
284 if (num_coords
!= b
.num_coords
)
290 for (UINT_32 i
= 0; i
< num_coords
; i
++)
292 // Note: the lists will always be in order, so we can compare the two lists at time
293 if (m_coord
[i
] != b
.m_coord
[i
])
303 BOOL_32
CoordTerm::operator!=(const CoordTerm
& b
)
305 return !(*this == b
);
308 BOOL_32
CoordTerm::exceedRange(UINT_32 xRange
, UINT_32 yRange
, UINT_32 zRange
, UINT_32 sRange
)
310 BOOL_32 exceed
= FALSE
;
311 for (UINT_32 i
= 0; (i
< num_coords
) && (exceed
== FALSE
); i
++)
314 switch (m_coord
[i
].getdim())
333 ADDR_ASSERT_ALWAYS();
338 exceed
= ((1u << m_coord
[i
].getord()) <= subject
);
350 VOID
CoordEq::remove(Coordinate
& co
)
352 for (UINT_32 i
= 0; i
< m_numBits
; i
++)
358 BOOL_32
CoordEq::Exists(Coordinate
& co
)
360 BOOL_32 exists
= FALSE
;
362 for (UINT_32 i
= 0; i
< m_numBits
; i
++)
364 if (m_eq
[i
].Exists(co
))
372 VOID
CoordEq::resize(UINT_32 n
)
376 for (UINT_32 i
= m_numBits
; i
< n
; i
++)
384 UINT_32
CoordEq::getsize()
389 UINT_64
CoordEq::solve(UINT_32 x
, UINT_32 y
, UINT_32 z
, UINT_32 s
, UINT_32 m
)
392 for (UINT_32 i
= 0; i
< m_numBits
; i
++)
394 if (m_eq
[i
].getxor(x
, y
, z
, s
, m
) != 0)
402 VOID
CoordEq::solveAddr(
403 UINT_64 addr
, UINT_32 sliceInM
,
404 UINT_32
& x
, UINT_32
& y
, UINT_32
& z
, UINT_32
& s
, UINT_32
& m
)
406 UINT_32 xBitsValid
= 0;
407 UINT_32 yBitsValid
= 0;
408 UINT_32 zBitsValid
= 0;
409 UINT_32 sBitsValid
= 0;
410 UINT_32 mBitsValid
= 0;
412 CoordEq temp
= *this;
414 x
= y
= z
= s
= m
= 0;
416 UINT_32 bitsLeft
= 0;
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 INT_8 dim
= temp
.m_eq
[i
][0].getdim();
426 INT_8 ord
= temp
.m_eq
[i
][0].getord();
428 ADDR_ASSERT((ord
< 32) || (bit
== 0));
433 xBitsValid
|= (1 << ord
);
437 yBitsValid
|= (1 << ord
);
441 zBitsValid
|= (1 << ord
);
445 sBitsValid
|= (1 << ord
);
449 mBitsValid
|= (1 << ord
);
456 temp
.m_eq
[i
].Clear();
458 else if (termSize
> 1)
469 zBitsValid
= 0xffffffff;
476 for (UINT_32 i
= 0; i
< temp
.m_numBits
; i
++)
478 UINT_32 termSize
= temp
.m_eq
[i
].getsize();
482 INT_8 bit
= (addr
>> i
) & 1;
483 INT_8 dim
= temp
.m_eq
[i
][0].getdim();
484 INT_8 ord
= temp
.m_eq
[i
][0].getord();
486 ADDR_ASSERT((ord
< 32) || (bit
== 0));
491 xBitsValid
|= (1 << ord
);
495 yBitsValid
|= (1 << ord
);
499 zBitsValid
|= (1 << ord
);
503 ADDR_ASSERT_ALWAYS();
506 ADDR_ASSERT_ALWAYS();
512 temp
.m_eq
[i
].Clear();
514 else if (termSize
> 1)
516 CoordTerm tmpTerm
= temp
.m_eq
[i
];
518 for (UINT_32 j
= 0; j
< termSize
; j
++)
520 INT_8 dim
= temp
.m_eq
[i
][j
].getdim();
521 INT_8 ord
= temp
.m_eq
[i
][j
].getord();
526 if (xBitsValid
& (1 << ord
))
528 UINT_32 v
= (((x
>> ord
) & 1) << i
);
529 addr
^= static_cast<UINT_64
>(v
);
530 tmpTerm
.remove(temp
.m_eq
[i
][j
]);
534 if (yBitsValid
& (1 << ord
))
536 UINT_32 v
= (((y
>> ord
) & 1) << i
);
537 addr
^= static_cast<UINT_64
>(v
);
538 tmpTerm
.remove(temp
.m_eq
[i
][j
]);
542 if (zBitsValid
& (1 << ord
))
544 UINT_32 v
= (((z
>> ord
) & 1) << i
);
545 addr
^= static_cast<UINT_64
>(v
);
546 tmpTerm
.remove(temp
.m_eq
[i
][j
]);
550 ADDR_ASSERT_ALWAYS();
553 ADDR_ASSERT_ALWAYS();
560 temp
.m_eq
[i
] = tmpTerm
;
565 } while (bitsLeft
> 0);
569 VOID
CoordEq::copy(CoordEq
& o
, UINT_32 start
, UINT_32 num
)
571 o
.m_numBits
= (num
== 0xFFFFFFFF) ? m_numBits
: num
;
572 for (UINT_32 i
= 0; i
< o
.m_numBits
; i
++)
574 m_eq
[start
+ i
].copyto(o
.m_eq
[i
]);
578 VOID
CoordEq::reverse(UINT_32 start
, UINT_32 num
)
580 UINT_32 n
= (num
== 0xFFFFFFFF) ? m_numBits
: num
;
582 for (UINT_32 i
= 0; i
< n
/ 2; i
++)
585 m_eq
[start
+ i
].copyto(temp
);
586 m_eq
[start
+ n
- 1 - i
].copyto(m_eq
[start
+ i
]);
587 temp
.copyto(m_eq
[start
+ n
- 1 - i
]);
591 VOID
CoordEq::xorin(CoordEq
& x
, UINT_32 start
)
593 UINT_32 n
= ((m_numBits
- start
) < x
.m_numBits
) ? (m_numBits
- start
) : x
.m_numBits
;
594 for (UINT_32 i
= 0; i
< n
; i
++)
596 m_eq
[start
+ i
].add(x
.m_eq
[i
]);
600 UINT_32
CoordEq::Filter(INT_8 f
, Coordinate
& co
, UINT_32 start
, INT_8 axis
)
602 for (UINT_32 i
= start
; i
< m_numBits
;)
604 UINT_32 m
= m_eq
[i
].Filter(f
, co
, 0, axis
);
607 for (UINT_32 j
= i
; j
< m_numBits
- 1; j
++)
609 m_eq
[j
] = m_eq
[j
+ 1];
621 VOID
CoordEq::shift(INT_32 amount
, INT_32 start
)
625 INT_32 numBits
= static_cast<INT_32
>(m_numBits
);
627 INT_32 inc
= (amount
< 0) ? -1 : 1;
628 INT_32 i
= (amount
< 0) ? numBits
- 1 : start
;
629 INT_32 end
= (amount
< 0) ? start
- 1 : numBits
;
630 for (; (inc
> 0) ? i
< end
: i
> end
; i
+= inc
)
632 if ((i
+ amount
< start
) || (i
+ amount
>= numBits
))
638 m_eq
[i
+ amount
].copyto(m_eq
[i
]);
644 CoordTerm
& CoordEq::operator[](UINT_32 i
)
649 VOID
CoordEq::mort2d(Coordinate
& c0
, Coordinate
& c1
, UINT_32 start
, UINT_32 end
)
653 ADDR_ASSERT(m_numBits
> 0);
656 for (UINT_32 i
= start
; i
<= end
; i
++)
658 UINT_32 select
= (i
- start
) % 2;
659 Coordinate
& c
= (select
== 0) ? c0
: c1
;
665 VOID
CoordEq::mort3d(Coordinate
& c0
, Coordinate
& c1
, Coordinate
& c2
, UINT_32 start
, UINT_32 end
)
669 ADDR_ASSERT(m_numBits
> 0);
672 for (UINT_32 i
= start
; i
<= end
; i
++)
674 UINT_32 select
= (i
- start
) % 3;
675 Coordinate
& c
= (select
== 0) ? c0
: ((select
== 1) ? c1
: c2
);
681 BOOL_32
CoordEq::operator==(const CoordEq
& b
)
685 if (m_numBits
!= b
.m_numBits
)
691 for (UINT_32 i
= 0; i
< m_numBits
; i
++)
693 if (m_eq
[i
] != b
.m_eq
[i
])
703 BOOL_32
CoordEq::operator!=(const CoordEq
& b
)
705 return !(*this == b
);