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