amd/addrlib: update Mesa's copy of addrlib
[mesa.git] / src / amd / addrlib / src / core / addrcommon.h
1 /*
2 * Copyright © 2007-2018 Advanced Micro Devices, Inc.
3 * All Rights Reserved.
4 *
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:
12 *
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.
21 *
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
24 * of the Software.
25 */
26
27 /**
28 ****************************************************************************************************
29 * @file addrcommon.h
30 * @brief Contains the helper function and constants.
31 ****************************************************************************************************
32 */
33
34 #ifndef __ADDR_COMMON_H__
35 #define __ADDR_COMMON_H__
36
37 #include "addrinterface.h"
38
39 #include <stdlib.h>
40 #include <string.h>
41 #include <assert.h>
42
43 #if !defined(DEBUG)
44 #ifdef NDEBUG
45 #define DEBUG 0
46 #else
47 #define DEBUG 1
48 #endif
49 #endif
50
51 ////////////////////////////////////////////////////////////////////////////////////////////////////
52 // Platform specific debug break defines
53 ////////////////////////////////////////////////////////////////////////////////////////////////////
54 #if DEBUG
55 #if defined(__GNUC__)
56 #define ADDR_DBG_BREAK() assert(false)
57 #elif defined(__APPLE__)
58 #define ADDR_DBG_BREAK() { IOPanic("");}
59 #else
60 #define ADDR_DBG_BREAK() { __debugbreak(); }
61 #endif
62 #else
63 #define ADDR_DBG_BREAK()
64 #endif
65 ////////////////////////////////////////////////////////////////////////////////////////////////////
66
67 ////////////////////////////////////////////////////////////////////////////////////////////////////
68 // Debug assertions used in AddrLib
69 ////////////////////////////////////////////////////////////////////////////////////////////////////
70 #if defined(_WIN32) && (_MSC_VER >= 1400)
71 #define ADDR_ANALYSIS_ASSUME(expr) __analysis_assume(expr)
72 #else
73 #define ADDR_ANALYSIS_ASSUME(expr) do { (void)(expr); } while (0)
74 #endif
75
76 #define ADDR_ASSERT(__e) assert(__e)
77 #define ADDR_ASSERT_ALWAYS() ADDR_DBG_BREAK()
78 #define ADDR_UNHANDLED_CASE() ADDR_ASSERT(!"Unhandled case")
79 #define ADDR_NOT_IMPLEMENTED() ADDR_ASSERT(!"Not implemented");
80 ////////////////////////////////////////////////////////////////////////////////////////////////////
81
82 ////////////////////////////////////////////////////////////////////////////////////////////////////
83 // Debug print macro from legacy address library
84 ////////////////////////////////////////////////////////////////////////////////////////////////////
85 #if DEBUG
86
87 #define ADDR_PRNT(a) Object::DebugPrint a
88
89 /// @brief Macro for reporting informational messages
90 /// @ingroup util
91 ///
92 /// This macro optionally prints an informational message to stdout.
93 /// The first parameter is a condition -- if it is true, nothing is done.
94 /// The second pararmeter MUST be a parenthesis-enclosed list of arguments,
95 /// starting with a string. This is passed to printf() or an equivalent
96 /// in order to format the informational message. For example,
97 /// ADDR_INFO(0, ("test %d",3) ); prints out "test 3".
98 ///
99 #define ADDR_INFO(cond, a) \
100 { if (!(cond)) { ADDR_PRNT(a); } }
101
102 /// @brief Macro for reporting error warning messages
103 /// @ingroup util
104 ///
105 /// This macro optionally prints an error warning message to stdout,
106 /// followed by the file name and line number where the macro was called.
107 /// The first parameter is a condition -- if it is true, nothing is done.
108 /// The second pararmeter MUST be a parenthesis-enclosed list of arguments,
109 /// starting with a string. This is passed to printf() or an equivalent
110 /// in order to format the informational message. For example,
111 /// ADDR_WARN(0, ("test %d",3) ); prints out "test 3" followed by
112 /// a second line with the file name and line number.
113 ///
114 #define ADDR_WARN(cond, a) \
115 { if (!(cond)) \
116 { ADDR_PRNT(a); \
117 ADDR_PRNT((" WARNING in file %s, line %d\n", __FILE__, __LINE__)); \
118 } }
119
120 /// @brief Macro for reporting fatal error conditions
121 /// @ingroup util
122 ///
123 /// This macro optionally stops execution of the current routine
124 /// after printing an error warning message to stdout,
125 /// followed by the file name and line number where the macro was called.
126 /// The first parameter is a condition -- if it is true, nothing is done.
127 /// The second pararmeter MUST be a parenthesis-enclosed list of arguments,
128 /// starting with a string. This is passed to printf() or an equivalent
129 /// in order to format the informational message. For example,
130 /// ADDR_EXIT(0, ("test %d",3) ); prints out "test 3" followed by
131 /// a second line with the file name and line number, then stops execution.
132 ///
133 #define ADDR_EXIT(cond, a) \
134 { if (!(cond)) \
135 { ADDR_PRNT(a); ADDR_DBG_BREAK();\
136 } }
137
138 #else // DEBUG
139
140 #define ADDRDPF 1 ? (void)0 : (void)
141
142 #define ADDR_PRNT(a)
143
144 #define ADDR_DBG_BREAK()
145
146 #define ADDR_INFO(cond, a)
147
148 #define ADDR_WARN(cond, a)
149
150 #define ADDR_EXIT(cond, a)
151
152 #endif // DEBUG
153 ////////////////////////////////////////////////////////////////////////////////////////////////////
154
155 #define ADDR_C_ASSERT(__e) typedef char __ADDR_C_ASSERT__[(__e) ? 1 : -1]
156
157 namespace Addr
158 {
159
160 namespace V1
161 {
162 ////////////////////////////////////////////////////////////////////////////////////////////////////
163 // Common constants
164 ////////////////////////////////////////////////////////////////////////////////////////////////////
165 static const UINT_32 MicroTileWidth = 8; ///< Micro tile width, for 1D and 2D tiling
166 static const UINT_32 MicroTileHeight = 8; ///< Micro tile height, for 1D and 2D tiling
167 static const UINT_32 ThickTileThickness = 4; ///< Micro tile thickness, for THICK modes
168 static const UINT_32 XThickTileThickness = 8; ///< Extra thick tiling thickness
169 static const UINT_32 PowerSaveTileBytes = 64; ///< Nuber of bytes per tile for power save 64
170 static const UINT_32 CmaskCacheBits = 1024; ///< Number of bits for CMASK cache
171 static const UINT_32 CmaskElemBits = 4; ///< Number of bits for CMASK element
172 static const UINT_32 HtileCacheBits = 16384; ///< Number of bits for HTILE cache 512*32
173
174 static const UINT_32 MicroTilePixels = MicroTileWidth * MicroTileHeight;
175
176 static const INT_32 TileIndexInvalid = TILEINDEX_INVALID;
177 static const INT_32 TileIndexLinearGeneral = TILEINDEX_LINEAR_GENERAL;
178 static const INT_32 TileIndexNoMacroIndex = -3;
179
180 } // V1
181
182 namespace V2
183 {
184 ////////////////////////////////////////////////////////////////////////////////////////////////////
185 // Common constants
186 ////////////////////////////////////////////////////////////////////////////////////////////////////
187 static const UINT_32 MaxSurfaceHeight = 16384;
188
189 } // V2
190
191 ////////////////////////////////////////////////////////////////////////////////////////////////////
192 // Common macros
193 ////////////////////////////////////////////////////////////////////////////////////////////////////
194 #define BITS_PER_BYTE 8
195 #define BITS_TO_BYTES(x) ( ((x) + (BITS_PER_BYTE-1)) / BITS_PER_BYTE )
196 #define BYTES_TO_BITS(x) ( (x) * BITS_PER_BYTE )
197
198 /// Helper macros to select a single bit from an int (undefined later in section)
199 #define _BIT(v,b) (((v) >> (b) ) & 1)
200
201 /**
202 ****************************************************************************************************
203 * @brief Enums to identify AddrLib type
204 ****************************************************************************************************
205 */
206 enum LibClass
207 {
208 BASE_ADDRLIB = 0x0,
209 R600_ADDRLIB = 0x6,
210 R800_ADDRLIB = 0x8,
211 SI_ADDRLIB = 0xa,
212 CI_ADDRLIB = 0xb,
213 AI_ADDRLIB = 0xd,
214 };
215
216 /**
217 ****************************************************************************************************
218 * ChipFamily
219 *
220 * @brief
221 * Neutral enums that specifies chip family.
222 *
223 ****************************************************************************************************
224 */
225 enum ChipFamily
226 {
227 ADDR_CHIP_FAMILY_IVLD, ///< Invalid family
228 ADDR_CHIP_FAMILY_R6XX,
229 ADDR_CHIP_FAMILY_R7XX,
230 ADDR_CHIP_FAMILY_R8XX,
231 ADDR_CHIP_FAMILY_NI,
232 ADDR_CHIP_FAMILY_SI,
233 ADDR_CHIP_FAMILY_CI,
234 ADDR_CHIP_FAMILY_VI,
235 ADDR_CHIP_FAMILY_AI,
236 };
237
238 /**
239 ****************************************************************************************************
240 * ConfigFlags
241 *
242 * @brief
243 * This structure is used to set configuration flags.
244 ****************************************************************************************************
245 */
246 union ConfigFlags
247 {
248 struct
249 {
250 /// These flags are set up internally thru AddrLib::Create() based on ADDR_CREATE_FLAGS
251 UINT_32 optimalBankSwap : 1; ///< New bank tiling for RV770 only
252 UINT_32 noCubeMipSlicesPad : 1; ///< Disables faces padding for cubemap mipmaps
253 UINT_32 fillSizeFields : 1; ///< If clients fill size fields in all input and
254 /// output structure
255 UINT_32 ignoreTileInfo : 1; ///< Don't use tile info structure
256 UINT_32 useTileIndex : 1; ///< Make tileIndex field in input valid
257 UINT_32 useCombinedSwizzle : 1; ///< Use combined swizzle
258 UINT_32 checkLast2DLevel : 1; ///< Check the last 2D mip sub level
259 UINT_32 useHtileSliceAlign : 1; ///< Do htile single slice alignment
260 UINT_32 allowLargeThickTile : 1; ///< Allow 64*thickness*bytesPerPixel > rowSize
261 UINT_32 disableLinearOpt : 1; ///< Disallow tile modes to be optimized to linear
262 UINT_32 use32bppFor422Fmt : 1; ///< View 422 formats as 32 bits per pixel element
263 UINT_32 reserved : 21; ///< Reserved bits for future use
264 };
265
266 UINT_32 value;
267 };
268
269 ////////////////////////////////////////////////////////////////////////////////////////////////////
270 // Misc helper functions
271 ////////////////////////////////////////////////////////////////////////////////////////////////////
272
273 /**
274 ****************************************************************************************************
275 * AddrXorReduce
276 *
277 * @brief
278 * Xor the right-side numberOfBits bits of x.
279 ****************************************************************************************************
280 */
281 static inline UINT_32 XorReduce(
282 UINT_32 x,
283 UINT_32 numberOfBits)
284 {
285 UINT_32 i;
286 UINT_32 result = x & 1;
287
288 for (i=1; i<numberOfBits; i++)
289 {
290 result ^= ((x>>i) & 1);
291 }
292
293 return result;
294 }
295
296 /**
297 ****************************************************************************************************
298 * IsPow2
299 *
300 * @brief
301 * Check if the size (UINT_32) is pow 2
302 ****************************************************************************************************
303 */
304 static inline UINT_32 IsPow2(
305 UINT_32 dim) ///< [in] dimension of miplevel
306 {
307 ADDR_ASSERT(dim > 0);
308 return !(dim & (dim - 1));
309 }
310
311 /**
312 ****************************************************************************************************
313 * IsPow2
314 *
315 * @brief
316 * Check if the size (UINT_64) is pow 2
317 ****************************************************************************************************
318 */
319 static inline UINT_64 IsPow2(
320 UINT_64 dim) ///< [in] dimension of miplevel
321 {
322 ADDR_ASSERT(dim > 0);
323 return !(dim & (dim - 1));
324 }
325
326 /**
327 ****************************************************************************************************
328 * ByteAlign
329 *
330 * @brief
331 * Align UINT_32 "x" to "align" alignment, "align" should be power of 2
332 ****************************************************************************************************
333 */
334 static inline UINT_32 PowTwoAlign(
335 UINT_32 x,
336 UINT_32 align)
337 {
338 //
339 // Assert that x is a power of two.
340 //
341 ADDR_ASSERT(IsPow2(align));
342 return (x + (align - 1)) & (~(align - 1));
343 }
344
345 /**
346 ****************************************************************************************************
347 * ByteAlign
348 *
349 * @brief
350 * Align UINT_64 "x" to "align" alignment, "align" should be power of 2
351 ****************************************************************************************************
352 */
353 static inline UINT_64 PowTwoAlign(
354 UINT_64 x,
355 UINT_64 align)
356 {
357 //
358 // Assert that x is a power of two.
359 //
360 ADDR_ASSERT(IsPow2(align));
361 return (x + (align - 1)) & (~(align - 1));
362 }
363
364 /**
365 ****************************************************************************************************
366 * Min
367 *
368 * @brief
369 * Get the min value between two unsigned values
370 ****************************************************************************************************
371 */
372 static inline UINT_32 Min(
373 UINT_32 value1,
374 UINT_32 value2)
375 {
376 return ((value1 < (value2)) ? (value1) : value2);
377 }
378
379 /**
380 ****************************************************************************************************
381 * Min
382 *
383 * @brief
384 * Get the min value between two signed values
385 ****************************************************************************************************
386 */
387 static inline INT_32 Min(
388 INT_32 value1,
389 INT_32 value2)
390 {
391 return ((value1 < (value2)) ? (value1) : value2);
392 }
393
394 /**
395 ****************************************************************************************************
396 * Max
397 *
398 * @brief
399 * Get the max value between two unsigned values
400 ****************************************************************************************************
401 */
402 static inline UINT_32 Max(
403 UINT_32 value1,
404 UINT_32 value2)
405 {
406 return ((value1 > (value2)) ? (value1) : value2);
407 }
408
409 /**
410 ****************************************************************************************************
411 * Max
412 *
413 * @brief
414 * Get the max value between two signed values
415 ****************************************************************************************************
416 */
417 static inline INT_32 Max(
418 INT_32 value1,
419 INT_32 value2)
420 {
421 return ((value1 > (value2)) ? (value1) : value2);
422 }
423
424 /**
425 ****************************************************************************************************
426 * NextPow2
427 *
428 * @brief
429 * Compute the mipmap's next level dim size
430 ****************************************************************************************************
431 */
432 static inline UINT_32 NextPow2(
433 UINT_32 dim) ///< [in] dimension of miplevel
434 {
435 UINT_32 newDim = 1;
436
437 if (dim > 0x7fffffff)
438 {
439 ADDR_ASSERT_ALWAYS();
440 newDim = 0x80000000;
441 }
442 else
443 {
444 while (newDim < dim)
445 {
446 newDim <<= 1;
447 }
448 }
449
450 return newDim;
451 }
452
453 /**
454 ****************************************************************************************************
455 * Log2NonPow2
456 *
457 * @brief
458 * Compute log of base 2 no matter the target is power of 2 or not
459 ****************************************************************************************************
460 */
461 static inline UINT_32 Log2NonPow2(
462 UINT_32 x) ///< [in] the value should calculate log based 2
463 {
464 UINT_32 y;
465
466 y = 0;
467 while (x > 1)
468 {
469 x >>= 1;
470 y++;
471 }
472
473 return y;
474 }
475
476 /**
477 ****************************************************************************************************
478 * Log2
479 *
480 * @brief
481 * Compute log of base 2
482 ****************************************************************************************************
483 */
484 static inline UINT_32 Log2(
485 UINT_32 x) ///< [in] the value should calculate log based 2
486 {
487 // Assert that x is a power of two.
488 ADDR_ASSERT(IsPow2(x));
489
490 return Log2NonPow2(x);
491 }
492
493 /**
494 ****************************************************************************************************
495 * QLog2
496 *
497 * @brief
498 * Compute log of base 2 quickly (<= 16)
499 ****************************************************************************************************
500 */
501 static inline UINT_32 QLog2(
502 UINT_32 x) ///< [in] the value should calculate log based 2
503 {
504 ADDR_ASSERT(x <= 16);
505
506 UINT_32 y = 0;
507
508 switch (x)
509 {
510 case 1:
511 y = 0;
512 break;
513 case 2:
514 y = 1;
515 break;
516 case 4:
517 y = 2;
518 break;
519 case 8:
520 y = 3;
521 break;
522 case 16:
523 y = 4;
524 break;
525 default:
526 ADDR_ASSERT_ALWAYS();
527 }
528
529 return y;
530 }
531
532 /**
533 ****************************************************************************************************
534 * SafeAssign
535 *
536 * @brief
537 * NULL pointer safe assignment
538 ****************************************************************************************************
539 */
540 static inline VOID SafeAssign(
541 UINT_32* pLVal, ///< [in] Pointer to left val
542 UINT_32 rVal) ///< [in] Right value
543 {
544 if (pLVal)
545 {
546 *pLVal = rVal;
547 }
548 }
549
550 /**
551 ****************************************************************************************************
552 * SafeAssign
553 *
554 * @brief
555 * NULL pointer safe assignment for 64bit values
556 ****************************************************************************************************
557 */
558 static inline VOID SafeAssign(
559 UINT_64* pLVal, ///< [in] Pointer to left val
560 UINT_64 rVal) ///< [in] Right value
561 {
562 if (pLVal)
563 {
564 *pLVal = rVal;
565 }
566 }
567
568 /**
569 ****************************************************************************************************
570 * SafeAssign
571 *
572 * @brief
573 * NULL pointer safe assignment for AddrTileMode
574 ****************************************************************************************************
575 */
576 static inline VOID SafeAssign(
577 AddrTileMode* pLVal, ///< [in] Pointer to left val
578 AddrTileMode rVal) ///< [in] Right value
579 {
580 if (pLVal)
581 {
582 *pLVal = rVal;
583 }
584 }
585
586 /**
587 ****************************************************************************************************
588 * RoundHalf
589 *
590 * @brief
591 * return (x + 1) / 2
592 ****************************************************************************************************
593 */
594 static inline UINT_32 RoundHalf(
595 UINT_32 x) ///< [in] input value
596 {
597 ADDR_ASSERT(x != 0);
598
599 #if 1
600 return (x >> 1) + (x & 1);
601 #else
602 return (x + 1) >> 1;
603 #endif
604 }
605
606 /**
607 ****************************************************************************************************
608 * SumGeo
609 *
610 * @brief
611 * Calculate sum of a geometric progression whose ratio is 1/2
612 ****************************************************************************************************
613 */
614 static inline UINT_32 SumGeo(
615 UINT_32 base, ///< [in] First term in the geometric progression
616 UINT_32 num) ///< [in] Number of terms to be added into sum
617 {
618 ADDR_ASSERT(base > 0);
619
620 UINT_32 sum = 0;
621 UINT_32 i = 0;
622 for (; (i < num) && (base > 1); i++)
623 {
624 sum += base;
625 base = RoundHalf(base);
626 }
627 sum += num - i;
628
629 return sum;
630 }
631
632 /**
633 ****************************************************************************************************
634 * GetBit
635 *
636 * @brief
637 * Extract bit N value (0 or 1) of a UINT32 value.
638 ****************************************************************************************************
639 */
640 static inline UINT_32 GetBit(
641 UINT_32 u32, ///< [in] UINT32 value
642 UINT_32 pos) ///< [in] bit position from LSB, valid range is [0..31]
643 {
644 ADDR_ASSERT(pos <= 31);
645
646 return (u32 >> pos) & 0x1;
647 }
648
649 /**
650 ****************************************************************************************************
651 * GetBits
652 *
653 * @brief
654 * Copy 'bitsNum' bits from src start from srcStartPos into destination from dstStartPos
655 * srcStartPos: 0~31 for UINT_32
656 * bitsNum : 1~32 for UINT_32
657 * srcStartPos: 0~31 for UINT_32
658 * src start position
659 * |
660 * src : b[31] b[30] b[29] ... ... ... ... ... ... ... ... b[end]..b[beg] ... b[1] b[0]
661 * || Bits num || copy length || Bits num ||
662 * dst : b[31] b[30] b[29] ... b[end]..b[beg] ... ... ... ... ... ... ... ... b[1] b[0]
663 * |
664 * dst start position
665 ****************************************************************************************************
666 */
667 static inline UINT_32 GetBits(
668 UINT_32 src,
669 UINT_32 srcStartPos,
670 UINT_32 bitsNum,
671 UINT_32 dstStartPos)
672 {
673 ADDR_ASSERT((srcStartPos < 32) && (dstStartPos < 32) && (bitsNum > 0));
674 ADDR_ASSERT((bitsNum + dstStartPos <= 32) && (bitsNum + srcStartPos <= 32));
675
676 return ((src >> srcStartPos) << (32 - bitsNum)) >> (32 - bitsNum - dstStartPos);
677 }
678
679 /**
680 ****************************************************************************************************
681 * MortonGen2d
682 *
683 * @brief
684 * Generate 2D Morton interleave code with num lowest bits in each channel
685 ****************************************************************************************************
686 */
687 static inline UINT_32 MortonGen2d(
688 UINT_32 x, ///< [in] First channel
689 UINT_32 y, ///< [in] Second channel
690 UINT_32 num) ///< [in] Number of bits extracted from each channel
691 {
692 UINT_32 mort = 0;
693
694 for (UINT_32 i = 0; i < num; i++)
695 {
696 mort |= (GetBit(y, i) << (2 * i));
697 mort |= (GetBit(x, i) << (2 * i + 1));
698 }
699
700 return mort;
701 }
702
703 /**
704 ****************************************************************************************************
705 * MortonGen3d
706 *
707 * @brief
708 * Generate 3D Morton interleave code with num lowest bits in each channel
709 ****************************************************************************************************
710 */
711 static inline UINT_32 MortonGen3d(
712 UINT_32 x, ///< [in] First channel
713 UINT_32 y, ///< [in] Second channel
714 UINT_32 z, ///< [in] Third channel
715 UINT_32 num) ///< [in] Number of bits extracted from each channel
716 {
717 UINT_32 mort = 0;
718
719 for (UINT_32 i = 0; i < num; i++)
720 {
721 mort |= (GetBit(z, i) << (3 * i));
722 mort |= (GetBit(y, i) << (3 * i + 1));
723 mort |= (GetBit(x, i) << (3 * i + 2));
724 }
725
726 return mort;
727 }
728
729 /**
730 ****************************************************************************************************
731 * ReverseBitVector
732 *
733 * @brief
734 * Return reversed lowest num bits of v: v[0]v[1]...v[num-2]v[num-1]
735 ****************************************************************************************************
736 */
737 static inline UINT_32 ReverseBitVector(
738 UINT_32 v, ///< [in] Reverse operation base value
739 UINT_32 num) ///< [in] Number of bits used in reverse operation
740 {
741 UINT_32 reverse = 0;
742
743 for (UINT_32 i = 0; i < num; i++)
744 {
745 reverse |= (GetBit(v, num - 1 - i) << i);
746 }
747
748 return reverse;
749 }
750
751 /**
752 ****************************************************************************************************
753 * FoldXor2d
754 *
755 * @brief
756 * Xor bit vector v[num-1]v[num-2]...v[1]v[0] with v[num]v[num+1]...v[2*num-2]v[2*num-1]
757 ****************************************************************************************************
758 */
759 static inline UINT_32 FoldXor2d(
760 UINT_32 v, ///< [in] Xor operation base value
761 UINT_32 num) ///< [in] Number of bits used in fold xor operation
762 {
763 return (v & ((1 << num) - 1)) ^ ReverseBitVector(v >> num, num);
764 }
765
766 /**
767 ****************************************************************************************************
768 * DeMort
769 *
770 * @brief
771 * Return v[0] | v[2] | v[4] | v[6]... | v[2*num - 2]
772 ****************************************************************************************************
773 */
774 static inline UINT_32 DeMort(
775 UINT_32 v, ///< [in] DeMort operation base value
776 UINT_32 num) ///< [in] Number of bits used in fold DeMort operation
777 {
778 UINT_32 d = 0;
779
780 for (UINT_32 i = 0; i < num; i++)
781 {
782 d |= ((v & (1 << (i << 1))) >> i);
783 }
784
785 return d;
786 }
787
788 /**
789 ****************************************************************************************************
790 * FoldXor3d
791 *
792 * @brief
793 * v[0]...v[num-1] ^ v[3*num-1]v[3*num-3]...v[num+2]v[num] ^ v[3*num-2]...v[num+1]v[num-1]
794 ****************************************************************************************************
795 */
796 static inline UINT_32 FoldXor3d(
797 UINT_32 v, ///< [in] Xor operation base value
798 UINT_32 num) ///< [in] Number of bits used in fold xor operation
799 {
800 UINT_32 t = v & ((1 << num) - 1);
801 t ^= ReverseBitVector(DeMort(v >> num, num), num);
802 t ^= ReverseBitVector(DeMort(v >> (num + 1), num), num);
803
804 return t;
805 }
806
807 /**
808 ****************************************************************************************************
809 * InitChannel
810 *
811 * @brief
812 * Set channel initialization value via a return value
813 ****************************************************************************************************
814 */
815 static inline ADDR_CHANNEL_SETTING InitChannel(
816 UINT_32 valid, ///< [in] valid setting
817 UINT_32 channel, ///< [in] channel setting
818 UINT_32 index) ///< [in] index setting
819 {
820 ADDR_CHANNEL_SETTING t;
821 t.valid = valid;
822 t.channel = channel;
823 t.index = index;
824
825 return t;
826 }
827
828 /**
829 ****************************************************************************************************
830 * InitChannel
831 *
832 * @brief
833 * Set channel initialization value via channel pointer
834 ****************************************************************************************************
835 */
836 static inline VOID InitChannel(
837 UINT_32 valid, ///< [in] valid setting
838 UINT_32 channel, ///< [in] channel setting
839 UINT_32 index, ///< [in] index setting
840 ADDR_CHANNEL_SETTING *pChanSet) ///< [out] channel setting to be initialized
841 {
842 pChanSet->valid = valid;
843 pChanSet->channel = channel;
844 pChanSet->index = index;
845 }
846
847 /**
848 ****************************************************************************************************
849 * InitChannel
850 *
851 * @brief
852 * Set channel initialization value via another channel
853 ****************************************************************************************************
854 */
855 static inline VOID InitChannel(
856 ADDR_CHANNEL_SETTING *pChanDst, ///< [in] channel setting to be copied from
857 ADDR_CHANNEL_SETTING *pChanSrc) ///< [out] channel setting to be initialized
858 {
859 pChanDst->valid = pChanSrc->valid;
860 pChanDst->channel = pChanSrc->channel;
861 pChanDst->index = pChanSrc->index;
862 }
863
864 /**
865 ****************************************************************************************************
866 * GetMaxValidChannelIndex
867 *
868 * @brief
869 * Get max valid index for a specific channel
870 ****************************************************************************************************
871 */
872 static inline UINT_32 GetMaxValidChannelIndex(
873 const ADDR_CHANNEL_SETTING *pChanSet, ///< [in] channel setting to be initialized
874 UINT_32 searchCount,///< [in] number of channel setting to be searched
875 UINT_32 channel) ///< [in] channel to be searched
876 {
877 UINT_32 index = 0;
878
879 for (UINT_32 i = 0; i < searchCount; i++)
880 {
881 if (pChanSet[i].valid && (pChanSet[i].channel == channel))
882 {
883 index = Max(index, static_cast<UINT_32>(pChanSet[i].index));
884 }
885 }
886
887 return index;
888 }
889
890 /**
891 ****************************************************************************************************
892 * GetCoordActiveMask
893 *
894 * @brief
895 * Get bit mask which indicates which positions in the equation match the target coord
896 ****************************************************************************************************
897 */
898 static inline UINT_32 GetCoordActiveMask(
899 const ADDR_CHANNEL_SETTING *pChanSet, ///< [in] channel setting to be initialized
900 UINT_32 searchCount,///< [in] number of channel setting to be searched
901 UINT_32 channel, ///< [in] channel to be searched
902 UINT_32 index) ///< [in] index to be searched
903 {
904 UINT_32 mask = 0;
905
906 for (UINT_32 i = 0; i < searchCount; i++)
907 {
908 if ((pChanSet[i].valid == TRUE) &&
909 (pChanSet[i].channel == channel) &&
910 (pChanSet[i].index == index))
911 {
912 mask |= (1 << i);
913 }
914 }
915
916 return mask;
917 }
918
919 } // Addr
920
921 #endif // __ADDR_COMMON_H__
922