Changeset 101609 in vbox
- Timestamp:
- Oct 27, 2023 1:59:06 AM (18 months ago)
- svn:sync-xref-src-repo-rev:
- 159693
- Location:
- trunk
- Files:
-
- 1 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/armv8.h
r101602 r101609 2646 2646 2647 2647 /** 2648 * Converts immS and immR values (to logical instructions) to a 32-bit mask. 2649 * 2650 * @returns The decoded mask. 2651 * @param uImm6SizeLen The immS value from the instruction. (No N part 2652 * here, as that must be zero for instructions 2653 * operating on 32-bit wide registers.) 2654 * @param uImm6Rotations The immR value from the instruction. 2655 */ 2656 DECLEXPORT(uint32_t) Armv8A64ConvertImmRImmS2Mask32(uint32_t uImm6SizeLen, uint32_t uImm6Rotations) 2657 { 2658 Assert(uImm6SizeLen < 64); Assert(uImm6Rotations < 64); 2659 2660 /* Determine the element size. */ 2661 unsigned const cBitsElementLog2 = ASMBitLastSetU32(uImm6SizeLen ^ 0x3f) - 1U; 2662 Assert(cBitsElementLog2 + 1U != 0U); 2663 2664 unsigned const cBitsElement = RT_BIT_32(cBitsElementLog2); 2665 Assert(uImm6Rotations < cBitsElement); 2666 2667 /* Extract the number of bits set to 1: */ 2668 unsigned const cBitsSetTo1 = (uImm6SizeLen & (cBitsElement - 1U)) + 1; 2669 Assert(cBitsSetTo1 < cBitsElement); 2670 uint32_t const uElement = RT_BIT_32(cBitsSetTo1) - 1U; 2671 2672 /* Produce the unrotated pattern. */ 2673 static const uint32_t s_auReplicate[] 2674 = { UINT32_MAX, UINT32_MAX / 3, UINT32_MAX / 15, UINT32_MAX / 255, UINT32_MAX / 65535, 1 }; 2675 uint32_t const uPattern = s_auReplicate[cBitsElementLog2] * uElement; 2676 2677 /* Rotate it and return. */ 2678 return ASMRotateRightU32(uPattern, uImm6Rotations & (cBitsElement - 1U)); 2679 } 2680 2681 2682 /** 2683 * Converts N+immS and immR values (to logical instructions) to a 64-bit mask. 2684 * 2685 * @returns The decoded mask. 2686 * @param uImm7SizeLen The N:immS value from the instruction. 2687 * @param uImm6Rotations The immR value from the instruction. 2688 */ 2689 DECLEXPORT(uint64_t) Armv8A64ConvertImmRImmS2Mask64(uint32_t uImm7SizeLen, uint32_t uImm6Rotations) 2690 { 2691 Assert(uImm7SizeLen < 128); Assert(uImm6Rotations < 64); 2692 2693 /* Determine the element size. */ 2694 unsigned const cBitsElementLog2 = ASMBitLastSetU32(uImm7SizeLen ^ 0x3f) - 1U; 2695 Assert(cBitsElementLog2 + 1U != 0U); 2696 2697 unsigned const cBitsElement = RT_BIT_32(cBitsElementLog2); 2698 Assert(uImm6Rotations < cBitsElement); 2699 2700 /* Extract the number of bits set to 1: */ 2701 unsigned const cBitsSetTo1 = (uImm7SizeLen & (cBitsElement - 1U)) + 1; 2702 Assert(cBitsSetTo1 < cBitsElement); 2703 uint64_t const uElement = RT_BIT_64(cBitsSetTo1) - 1U; 2704 2705 /* Produce the unrotated pattern. */ 2706 static const uint64_t s_auReplicate[] 2707 = { UINT64_MAX, UINT64_MAX / 3, UINT64_MAX / 15, UINT64_MAX / 255, UINT64_MAX / 65535, UINT64_MAX / UINT32_MAX, 1 }; 2708 uint64_t const uPattern = s_auReplicate[cBitsElementLog2] * uElement; 2709 2710 /* Rotate it and return. */ 2711 return ASMRotateRightU64(uPattern, uImm6Rotations & (cBitsElement - 1U)); 2712 } 2713 2714 2715 /** 2716 * Variant of Armv8A64ConvertImmRImmS2Mask64 where the N bit is separate from 2717 * the immS value. 2718 */ 2719 DECLEXPORT(uint64_t) Armv8A64ConvertImmRImmS2Mask64(uint32_t uN, uint32_t uImm6SizeLen, uint32_t uImm6Rotations) 2720 { 2721 return Armv8A64ConvertImmRImmS2Mask64((uN << 6) | uImm6SizeLen, uImm6Rotations); 2722 } 2723 2724 2725 /** 2726 * Helper for Armv8A64MkInstrLogicalImm and friends that tries to convert a 2727 * 32-bit bitmask to a set of immediates for those instructions. 2728 * 2729 * @returns true if successful, false if not. 2730 * @param fMask The mask value to convert. 2731 * @param puImm6SizeLen Where to return the immS part (N is always zero for 2732 * 32-bit wide masks). 2733 * @param puImm6Rotations Where to return the immR. 2734 */ 2735 DECLINLINE(bool) Armv8A64ConvertMask32ToImmRImmS(uint32_t fMask, uint32_t *puImm6SizeLen, uint32_t *puImm6Rotations) 2736 { 2737 /* Fend off 0 and UINT32_MAX as these cannot be represented. */ 2738 if ((uint32_t)(fMask + 1U) <= 1) 2739 return false; 2740 2741 /* Rotate the value will we get all 1s at the bottom and the zeros at the top. */ 2742 unsigned const cRor = ASMCountTrailingZerosU32(fMask); 2743 unsigned const cRol = ASMCountLeadingZerosU32(~fMask); 2744 if (cRor) 2745 fMask = ASMRotateRightU32(fMask, cRor); 2746 else 2747 fMask = ASMRotateLeftU32(fMask, cRol); 2748 Assert(fMask & RT_BIT_32(0)); 2749 Assert(!(fMask & RT_BIT_32(31))); 2750 2751 /* Count the trailing ones and leading zeros. */ 2752 unsigned const cOnes = ASMCountTrailingZerosU32(~fMask); 2753 unsigned const cZeros = ASMCountLeadingZerosU32(fMask); 2754 2755 /* The potential element length is then the sum of the two above. */ 2756 unsigned const cBitsElement = cOnes + cZeros; 2757 if (!RT_IS_POWER_OF_TWO(cBitsElement) || cBitsElement < 2) 2758 return false; 2759 2760 /* Special case: 32 bits element size. Since we're done here. */ 2761 if (cBitsElement == 32) 2762 *puImm6SizeLen = cOnes - 1; 2763 else 2764 { 2765 /* Extract the element bits and check that these are replicated in the whole pattern. */ 2766 uint32_t const uElement = RT_BIT_32(cOnes) - 1U; 2767 unsigned const cBitsElementLog2 = ASMBitFirstSetU32(cBitsElement) - 1; 2768 2769 static const uint32_t s_auReplicate[] 2770 = { UINT32_MAX, UINT32_MAX / 3, UINT32_MAX / 15, UINT32_MAX / 255, UINT32_MAX / 65535, 1 }; 2771 if (s_auReplicate[cBitsElementLog2] * uElement == fMask) 2772 *puImm6SizeLen = (cOnes - 1) | ((0x3e << cBitsElementLog2) & 0x3f); 2773 else 2774 return false; 2775 } 2776 *puImm6Rotations = cRor ? cBitsElement - cRor : cRol; 2777 2778 return true; 2779 } 2780 2781 2782 /** 2783 * Helper for Armv8A64MkInstrLogicalImm and friends that tries to convert a 2784 * 64-bit bitmask to a set of immediates for those instructions. 2785 * 2786 * @returns true if successful, false if not. 2787 * @param fMask The mask value to convert. 2788 * @param puImm7SizeLen Where to return the N:immS part. 2789 * @param puImm6Rotations Where to return the immR. 2790 */ 2791 DECLINLINE(bool) Armv8A64ConvertMask64ToImmRImmS(uint64_t fMask, uint32_t *puImm7SizeLen, uint32_t *puImm6Rotations) 2792 { 2793 /* Fend off 0 and UINT64_MAX as these cannot be represented. */ 2794 if ((uint64_t)(fMask + 1U) <= 1) 2795 return false; 2796 2797 /* Rotate the value will we get all 1s at the bottom and the zeros at the top. */ 2798 unsigned const cRor = ASMCountTrailingZerosU64(fMask); 2799 unsigned const cRol = ASMCountLeadingZerosU64(~fMask); 2800 if (cRor) 2801 fMask = ASMRotateRightU64(fMask, cRor); 2802 else 2803 fMask = ASMRotateLeftU64(fMask, cRol); 2804 Assert(fMask & RT_BIT_64(0)); 2805 Assert(!(fMask & RT_BIT_64(63))); 2806 2807 /* Count the trailing ones and leading zeros. */ 2808 unsigned const cOnes = ASMCountTrailingZerosU64(~fMask); 2809 unsigned const cZeros = ASMCountLeadingZerosU64(fMask); 2810 2811 /* The potential element length is then the sum of the two above. */ 2812 unsigned const cBitsElement = cOnes + cZeros; 2813 if (!RT_IS_POWER_OF_TWO(cBitsElement) || cBitsElement < 2) 2814 return false; 2815 2816 /* Special case: 64 bits element size. Since we're done here. */ 2817 if (cBitsElement == 64) 2818 *puImm7SizeLen = (cOnes - 1) | 0x40 /*N*/; 2819 else 2820 { 2821 /* Extract the element bits and check that these are replicated in the whole pattern. */ 2822 uint64_t const uElement = RT_BIT_64(cOnes) - 1U; 2823 unsigned const cBitsElementLog2 = ASMBitFirstSetU64(cBitsElement) - 1; 2824 2825 static const uint64_t s_auReplicate[] 2826 = { UINT64_MAX, UINT64_MAX / 3, UINT64_MAX / 15, UINT64_MAX / 255, UINT64_MAX / 65535, UINT64_MAX / UINT32_MAX, 1 }; 2827 if (s_auReplicate[cBitsElementLog2] * uElement == fMask) 2828 *puImm7SizeLen = (cOnes - 1) | ((0x3e << cBitsElementLog2) & 0x3f); 2829 else 2830 return false; 2831 } 2832 *puImm6Rotations = cRor ? cBitsElement - cRor : cRol; 2833 2834 return true; 2835 } 2836 2837 2838 /** 2648 2839 * A64: Encodes a logical instruction with an complicated immediate mask. 2840 * 2841 * The @a uImm7SizeLen parameter specifies two things: 2842 * 1. the element size and 2843 * 2. the number of bits set to 1 in the pattern. 2844 * 2845 * The element size is extracted by NOT'ing bits 5:0 (excludes the N bit at the 2846 * top) and using the position of the first bit set as a power of two. 2847 * 2848 * | N | 5 | 4 | 3 | 2 | 1 | 0 | element size | 2849 * |---|---|---|---|---|---|---|--------------| 2850 * | 0 | 1 | 1 | 1 | 1 | 0 | x | 2 bits | 2851 * | 0 | 1 | 1 | 1 | 0 | x | x | 4 bits | 2852 * | 0 | 1 | 1 | 0 | x | x | x | 8 bits | 2853 * | 0 | 1 | 0 | x | x | x | x | 16 bits | 2854 * | 0 | 0 | x | x | x | x | x | 32 bits | 2855 * | 1 | x | x | x | x | x | x | 64 bits | 2856 * 2857 * The 'x' forms the number of 1 bits in the pattern, minus one (i.e. 2858 * there is always one zero bit in the pattern). 2859 * 2860 * The @a uImm6Rotations parameter specifies how many bits to the right, 2861 * the element pattern is rotated. The rotation count must be less than the 2862 * element bit count (size). 2649 2863 * 2650 2864 * @returns The encoded instruction. … … 2654 2868 * @param uImm7SizeLen The size/pattern length. We've combined the 1-bit N 2655 2869 * field at the top of the 6-bit 'imms' field. 2870 * 2656 2871 * @param uImm6Rotations The rotation count. 2657 2872 * @param f64Bit true for 64-bit GPRs, @c false for 32-bit GPRs. … … 2764 2979 uint32_t offFirstBit, uint32_t cBitsWidth, bool f64Bit = true) 2765 2980 { 2766 Assert(cBitsWidth > 0U); Assert(cBitsWidth < (f64Bit ? 64U : 32U)); Assert(offFirstBit < (f64Bit ? 64U : 32U)); RT_NOREF(offFirstBit);2767 return Armv8A64MkInstrBfm(iRegResult, iRegSrc, (uint32_t)-(int32_t) cBitsWidth& (f64Bit ? 0x3f : 0x1f),2981 Assert(cBitsWidth > 0U); Assert(cBitsWidth < (f64Bit ? 64U : 32U)); Assert(offFirstBit < (f64Bit ? 64U : 32U)); 2982 return Armv8A64MkInstrBfm(iRegResult, iRegSrc, (uint32_t)-(int32_t)offFirstBit & (f64Bit ? 0x3f : 0x1f), 2768 2983 cBitsWidth - 1, f64Bit); 2769 2984 } -
trunk/include/iprt/asm.h
r101228 r101609 7756 7756 * The counting starts with the least significate bit, i.e. the zero bit. 7757 7757 * 7758 * @returns Number of le st significant zero bits.7758 * @returns Number of least significant zero bits. 7759 7759 * @returns 32 if all bits are cleared. 7760 7760 * @param u32 Integer to consider. -
trunk/src/VBox/Runtime/testcase/Makefile.kmk
r99960 r101609 67 67 ifndef VBOX_ONLY_VALIDATIONKIT 68 68 PROGRAMS += \ 69 tstRTArmv8 \ 69 70 tstRTAssertCompile \ 70 71 tstRTAvl \ … … 277 278 # Target configs in almost alphabetical order. 278 279 # 280 tstRTArmv8_TEMPLATE = VBoxR3TstExe 281 tstRTArmv8_SOURCES = tstRTArmv8.cpp 279 282 280 283 tstRTAssertCompile_TEMPLATE = VBoxR3TstExe
Note:
See TracChangeset
for help on using the changeset viewer.