4
4
5
5
using System . Runtime . CompilerServices ;
6
6
using System . Runtime . InteropServices ;
7
+ using System . Runtime . Intrinsics . Arm ;
7
8
using System . Runtime . Intrinsics . X86 ;
8
9
9
10
#if SYSTEM_PRIVATE_CORELIB
@@ -61,6 +62,11 @@ public static int LeadingZeroCount(uint value)
61
62
return ( int ) Lzcnt . LeadingZeroCount ( value ) ;
62
63
}
63
64
65
+ if ( ArmBase . IsSupported )
66
+ {
67
+ return ArmBase . LeadingZeroCount ( value ) ;
68
+ }
69
+
64
70
// Unguarded fallback contract is 0->31
65
71
if ( value == 0 )
66
72
{
@@ -85,6 +91,11 @@ public static int LeadingZeroCount(ulong value)
85
91
return ( int ) Lzcnt . X64 . LeadingZeroCount ( value ) ;
86
92
}
87
93
94
+ if ( ArmBase . Arm64 . IsSupported )
95
+ {
96
+ return ArmBase . Arm64 . LeadingZeroCount ( value ) ;
97
+ }
98
+
88
99
uint hi = ( uint ) ( value >> 32 ) ;
89
100
90
101
if ( hi == 0 )
@@ -104,6 +115,12 @@ public static int LeadingZeroCount(ulong value)
104
115
[ CLSCompliant ( false ) ]
105
116
public static int Log2 ( uint value )
106
117
{
118
+ // Enforce conventional contract 0->0 (Log(0) is undefined)
119
+ if ( value == 0 )
120
+ {
121
+ return 0 ;
122
+ }
123
+
107
124
// value lzcnt actual expected
108
125
// ..0000 32 0 0 (by convention, guard clause)
109
126
// ..0001 31 31-31 0
@@ -113,16 +130,15 @@ public static int Log2(uint value)
113
130
// 1000.. 0 31-0 31
114
131
if ( Lzcnt . IsSupported )
115
132
{
116
- // Enforce conventional contract 0->0 (Log(0) is undefined)
117
- if ( value == 0 )
118
- {
119
- return 0 ;
120
- }
121
-
122
133
// LZCNT contract is 0->32
123
134
return 31 - ( int ) Lzcnt . LeadingZeroCount ( value ) ;
124
135
}
125
136
137
+ if ( ArmBase . IsSupported )
138
+ {
139
+ return 31 - ArmBase . LeadingZeroCount ( value ) ;
140
+ }
141
+
126
142
// Fallback contract is 0->0
127
143
return Log2SoftwareFallback ( value ) ;
128
144
}
@@ -136,18 +152,23 @@ public static int Log2(uint value)
136
152
[ CLSCompliant ( false ) ]
137
153
public static int Log2 ( ulong value )
138
154
{
139
- if ( Lzcnt . X64 . IsSupported )
155
+ // Enforce conventional contract 0->0 (Log(0) is undefined)
156
+ if ( value == 0 )
140
157
{
141
- // Enforce conventional contract 0->0 (Log(0) is undefined)
142
- if ( value == 0 )
143
- {
144
- return 0 ;
145
- }
158
+ return 0 ;
159
+ }
146
160
161
+ if ( Lzcnt . X64 . IsSupported )
162
+ {
147
163
// LZCNT contract is 0->64
148
164
return 63 - ( int ) Lzcnt . X64 . LeadingZeroCount ( value ) ;
149
165
}
150
166
167
+ if ( ArmBase . Arm64 . IsSupported )
168
+ {
169
+ return 63 - ArmBase . Arm64 . LeadingZeroCount ( value ) ;
170
+ }
171
+
151
172
uint hi = ( uint ) ( value >> 32 ) ;
152
173
153
174
if ( hi == 0 )
@@ -275,6 +296,11 @@ public static int TrailingZeroCount(uint value)
275
296
return ( int ) Bmi1 . TrailingZeroCount ( value ) ;
276
297
}
277
298
299
+ if ( ArmBase . IsSupported )
300
+ {
301
+ return ArmBase . LeadingZeroCount ( ArmBase . ReverseElementBits ( value ) ) ;
302
+ }
303
+
278
304
// Unguarded fallback contract is 0->0
279
305
if ( value == 0 )
280
306
{
@@ -313,6 +339,10 @@ public static int TrailingZeroCount(ulong value)
313
339
return ( int ) Bmi1 . X64 . TrailingZeroCount ( value ) ;
314
340
}
315
341
342
+ if ( ArmBase . Arm64 . IsSupported )
343
+ {
344
+ return ArmBase . Arm64 . LeadingZeroCount ( ArmBase . Arm64 . ReverseElementBits ( value ) ) ;
345
+ }
316
346
uint lo = ( uint ) value ;
317
347
318
348
if ( lo == 0 )
0 commit comments