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