@@ -21,6 +21,7 @@ TCpuIdResult = record
2121 FHasSHANI: Boolean;
2222 FHasPCLMULQDQ: Boolean;
2323 FHasVPCLMULQDQ: Boolean;
24+ FHasAESNI: Boolean;
2425
2526 strict private
2627 class function CPUHasSSE2 (): Boolean; static;
@@ -29,6 +30,7 @@ TCpuIdResult = record
2930 class function CPUHasSHANI (): Boolean; static;
3031 class function CPUHasPCLMULQDQ (): Boolean; static;
3132 class function CPUHasVPCLMULQDQ (): Boolean; static;
33+ class function CPUHasAESNI (): Boolean; static;
3234
3335 private
3436 class procedure ProbeHardwareAndCache (); static;
@@ -42,6 +44,7 @@ TCpuIdResult = record
4244 class function HasSHANI (): Boolean; static;
4345 class function HasPCLMULQDQ (): Boolean; static;
4446 class function HasVPCLMULQDQ (): Boolean; static;
47+ class function HasAESNI (): Boolean; static;
4548 end ;
4649
4750implementation
@@ -82,6 +85,7 @@ class function TX86SimdFeatures.CPUHasSSSE3(): Boolean;
8285begin
8386{ $IFDEF HASHLIB_X86_SIMD}
8487 CpuIdQuery(1 , 0 , @LCpuId);
88+ // SSSE3: ECX bit 9
8589 Result := (LCpuId.RegECX and (1 shl 9 )) <> 0 ;
8690{ $ELSE}
8791 Result := False;
@@ -98,18 +102,18 @@ class function TX86SimdFeatures.CPUHasAVX2(): Boolean;
98102{ $IFDEF HASHLIB_X86_SIMD}
99103 CpuIdQuery(1 , 0 , @LCpuId);
100104
101- // Check OSXSAVE bit -- OS must support XSAVE/XRSTOR
105+ // OSXSAVE: ECX bit 27 (required for OS AVX state saving)
102106 if (LCpuId.RegECX and (1 shl 27 )) = 0 then
103107 Exit(False);
104108
105- // Check XCR0 for SSE and AVX state saving
109+ // XCR0 bits 1 and 2 must be set for AVX state support
106110 LXcr0 := 0 ;
107111 XGetBvQuery(@LXcr0);
108112 if (UInt32(LXcr0) and $06 ) <> $06 then
109113 Exit(False);
110114
111- // Check AVX2 bit in structured extended feature flags
112115 CpuIdQuery(7 , 0 , @LCpuId);
116+ // AVX2: EBX bit 5
113117 Result := (LCpuId.RegEBX and (1 shl 5 )) <> 0 ;
114118{ $ELSE}
115119 Result := False;
@@ -124,6 +128,7 @@ class function TX86SimdFeatures.CPUHasSHANI(): Boolean;
124128begin
125129{ $IFDEF HASHLIB_X86_SIMD}
126130 CpuIdQuery(7 , 0 , @LCpuId);
131+ // SHA-NI: EBX bit 29
127132 Result := (LCpuId.RegEBX and (1 shl 29 )) <> 0 ;
128133{ $ELSE}
129134 Result := False;
@@ -138,6 +143,7 @@ class function TX86SimdFeatures.CPUHasPCLMULQDQ(): Boolean;
138143begin
139144{ $IFDEF HASHLIB_X86_SIMD}
140145 CpuIdQuery(1 , 0 , @LCpuId);
146+ // PCLMULQDQ: ECX bit 1
141147 Result := (LCpuId.RegECX and (1 shl 1 )) <> 0 ;
142148{ $ELSE}
143149 Result := False;
@@ -152,18 +158,35 @@ class function TX86SimdFeatures.CPUHasVPCLMULQDQ(): Boolean;
152158begin
153159{ $IFDEF HASHLIB_X86_SIMD}
154160 CpuIdQuery(7 , 0 , @LCpuId);
161+ // VPCLMULQDQ: ECX bit 10
155162 Result := (LCpuId.RegECX and (1 shl 10 )) <> 0 ;
156163{ $ELSE}
157164 Result := False;
158165{ $ENDIF}
159166end ;
160167
168+ class function TX86SimdFeatures.CPUHasAESNI (): Boolean;
169+ { $IFDEF HASHLIB_X86_SIMD}
170+ var
171+ LCpuId: TCpuIdResult;
172+ { $ENDIF}
173+ begin
174+ { $IFDEF HASHLIB_X86_SIMD}
175+ CpuIdQuery(1 , 0 , @LCpuId);
176+ // AES-NI: ECX bit 25
177+ Result := (LCpuId.RegECX and (1 shl 25 )) <> 0 ;
178+ { $ELSE}
179+ Result := False;
180+ { $ENDIF}
181+ end ;
182+
161183class procedure TX86SimdFeatures.ProbeHardwareAndCache ();
162184begin
163185 FSimdLevel := TX86SimdLevel.Scalar;
164186 FHasSHANI := False;
165187 FHasPCLMULQDQ := False;
166188 FHasVPCLMULQDQ := False;
189+ FHasAESNI := False;
167190
168191 if CPUHasSSE2() then
169192 begin
@@ -181,6 +204,7 @@ class procedure TX86SimdFeatures.ProbeHardwareAndCache();
181204 end ;
182205
183206 FHasSHANI := CPUHasSHANI();
207+ FHasAESNI := CPUHasAESNI();
184208end ;
185209
186210class procedure TX86SimdFeatures.ApplyBuildOverrides ();
@@ -190,18 +214,21 @@ class procedure TX86SimdFeatures.ApplyBuildOverrides();
190214 FHasSHANI := False;
191215 FHasPCLMULQDQ := False;
192216 FHasVPCLMULQDQ := False;
217+ FHasAESNI := False;
193218{ $ELSEIF DEFINED(HASHLIB_FORCE_SSE2)}
194219 if FSimdLevel > TX86SimdLevel.SSE2 then
195220 FSimdLevel := TX86SimdLevel.SSE2;
196221 FHasSHANI := False;
197222 FHasPCLMULQDQ := False;
198223 FHasVPCLMULQDQ := False;
224+ FHasAESNI := False;
199225{ $ELSEIF DEFINED(HASHLIB_FORCE_SSSE3)}
200226 if FSimdLevel > TX86SimdLevel.SSSE3 then
201227 FSimdLevel := TX86SimdLevel.SSSE3;
202228 FHasSHANI := False;
203229 FHasPCLMULQDQ := False;
204230 FHasVPCLMULQDQ := False;
231+ FHasAESNI := False;
205232{ $IFEND}
206233end ;
207234
@@ -240,6 +267,11 @@ class function TX86SimdFeatures.HasVPCLMULQDQ(): Boolean;
240267 Result := FHasVPCLMULQDQ;
241268end ;
242269
270+ class function TX86SimdFeatures.HasAESNI (): Boolean;
271+ begin
272+ Result := FHasAESNI;
273+ end ;
274+
243275initialization
244276 TX86SimdFeatures.ProbeHardwareAndCache();
245277 TX86SimdFeatures.ApplyBuildOverrides();
0 commit comments