1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
11 NamedIntrinsic intrinsicID;
12 const char* intrinsicName;
16 static const hwIntrinsicInfoArray[] = {
17 #define HARDWARE_INTRINSIC(id, name, isa) {NI_##id, name, InstructionSet_##isa},
18 #include "hwintrinsiclistxarch.h"
21 //------------------------------------------------------------------------
22 // lookupHWIntrinsicISA: map class name to InstructionSet value
25 // className -- class name in System.Runtime.Intrinsics.X86
28 // Id for the ISA class.
30 InstructionSet Compiler::lookupHWIntrinsicISA(const char* className)
32 if (className != nullptr)
34 if (className[0] == 'A')
36 if (strcmp(className, "Aes") == 0)
38 return InstructionSet_AES;
40 else if (strcmp(className, "Avx") == 0)
42 return InstructionSet_AVX;
44 else if (strcmp(className, "Avx2") == 0)
46 return InstructionSet_AVX2;
49 if (className[0] == 'S')
51 if (strcmp(className, "Sse") == 0)
53 return InstructionSet_SSE;
55 else if (strcmp(className, "Sse2") == 0)
57 return InstructionSet_SSE2;
59 else if (strcmp(className, "Sse3") == 0)
61 return InstructionSet_SSE3;
63 else if (strcmp(className, "Ssse3") == 0)
65 return InstructionSet_SSSE3;
67 else if (strcmp(className, "Sse41") == 0)
69 return InstructionSet_SSE41;
71 else if (strcmp(className, "Sse42") == 0)
73 return InstructionSet_SSE42;
77 if (strcmp(className, "Bmi1") == 0)
79 return InstructionSet_BMI1;
81 else if (strcmp(className, "Bmi2") == 0)
83 return InstructionSet_BMI2;
85 else if (strcmp(className, "Fma") == 0)
87 return InstructionSet_FMA;
89 else if (strcmp(className, "Lzcnt") == 0)
91 return InstructionSet_LZCNT;
93 else if (strcmp(className, "Pclmulqdq") == 0)
95 return InstructionSet_PCLMULQDQ;
97 else if (strcmp(className, "Popcnt") == 0)
99 return InstructionSet_POPCNT;
103 JITDUMP("Unsupported ISA.\n");
104 return InstructionSet_ILLEGAL;
107 //------------------------------------------------------------------------
108 // lookupHWIntrinsic: map intrinsic name to named intrinsic value
111 // methodName -- name of the intrinsic function.
112 // isa -- instruction set of the intrinsic.
115 // Id for the hardware intrinsic.
117 // TODO-Throughput: replace sequential search by binary search
118 NamedIntrinsic Compiler::lookupHWIntrinsic(const char* methodName, InstructionSet isa)
120 NamedIntrinsic result = NI_Illegal;
121 if (isa != InstructionSet_ILLEGAL)
123 for (int i = 0; i < NI_HW_INTRINSIC_END - NI_HW_INTRINSIC_START; i++)
125 if (isa == hwIntrinsicInfoArray[i].isa && strcmp(methodName, hwIntrinsicInfoArray[i].intrinsicName) == 0)
127 result = hwIntrinsicInfoArray[i].intrinsicID;
134 //------------------------------------------------------------------------
135 // isaOfHWIntrinsic: map named intrinsic value to its instruction set
138 // intrinsic -- id of the intrinsic function.
141 // instruction set of the intrinsic.
143 InstructionSet Compiler::isaOfHWIntrinsic(NamedIntrinsic intrinsic)
145 assert(intrinsic != NI_Illegal);
146 assert(intrinsic > NI_HW_INTRINSIC_START && intrinsic < NI_HW_INTRINSIC_END);
147 return hwIntrinsicInfoArray[intrinsic - NI_HW_INTRINSIC_START - 1].isa;
150 //------------------------------------------------------------------------
151 // impX86HWIntrinsic: dispatch hardware intrinsics to their own implementation
155 // intrinsic -- id of the intrinsic function.
156 // method -- method handle of the intrinsic function.
157 // sig -- signature of the intrinsic call
160 // the expanded intrinsic.
162 GenTree* Compiler::impX86HWIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig)
164 InstructionSet isa = isaOfHWIntrinsic(intrinsic);
167 case InstructionSet_SSE:
168 return impSSEIntrinsic(intrinsic, method, sig);
169 case InstructionSet_SSE2:
170 return impSSE2Intrinsic(intrinsic, method, sig);
171 case InstructionSet_SSE3:
172 return impSSE3Intrinsic(intrinsic, method, sig);
173 case InstructionSet_SSSE3:
174 return impSSSE3Intrinsic(intrinsic, method, sig);
175 case InstructionSet_SSE41:
176 return impSSE41Intrinsic(intrinsic, method, sig);
177 case InstructionSet_SSE42:
178 return impSSE42Intrinsic(intrinsic, method, sig);
179 case InstructionSet_AVX:
180 return impAVXIntrinsic(intrinsic, method, sig);
181 case InstructionSet_AVX2:
182 return impAVX2Intrinsic(intrinsic, method, sig);
184 case InstructionSet_AES:
185 return impAESIntrinsic(intrinsic, method, sig);
186 case InstructionSet_BMI1:
187 return impBMI1Intrinsic(intrinsic, method, sig);
188 case InstructionSet_BMI2:
189 return impBMI2Intrinsic(intrinsic, method, sig);
190 case InstructionSet_FMA:
191 return impFMAIntrinsic(intrinsic, method, sig);
192 case InstructionSet_LZCNT:
193 return impLZCNTIntrinsic(intrinsic, method, sig);
194 case InstructionSet_PCLMULQDQ:
195 return impPCLMULQDQIntrinsic(intrinsic, method, sig);
196 case InstructionSet_POPCNT:
197 return impPOPCNTIntrinsic(intrinsic, method, sig);
203 GenTree* Compiler::impSSEIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig)
207 case NI_SSE_IsSupported:
208 return gtNewIconNode(compSupports(InstructionSet_SSE));
215 GenTree* Compiler::impSSE2Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig)
219 case NI_SSE2_IsSupported:
220 return gtNewIconNode(compSupports(InstructionSet_SSE2));
227 GenTree* Compiler::impSSE3Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig)
231 case NI_SSE3_IsSupported:
232 return gtNewIconNode(compSupports(InstructionSet_SSE3));
239 GenTree* Compiler::impSSSE3Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig)
243 case NI_SSSE3_IsSupported:
244 return gtNewIconNode(compSupports(InstructionSet_SSSE3));
251 GenTree* Compiler::impSSE41Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig)
255 case NI_SSE41_IsSupported:
256 return gtNewIconNode(compSupports(InstructionSet_SSE41));
263 GenTree* Compiler::impSSE42Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig)
267 case NI_SSE42_IsSupported:
268 return gtNewIconNode(compSupports(InstructionSet_SSE42));
275 GenTree* Compiler::impAVXIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig)
279 case NI_AVX_IsSupported:
280 return gtNewIconNode(compSupports(InstructionSet_AVX));
287 GenTree* Compiler::impAVX2Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig)
291 case NI_AVX2_IsSupported:
292 return gtNewIconNode(compSupports(InstructionSet_AVX2));
299 GenTree* Compiler::impAESIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig)
303 case NI_AES_IsSupported:
304 return gtNewIconNode(compSupports(InstructionSet_AES));
311 GenTree* Compiler::impBMI1Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig)
315 case NI_BMI1_IsSupported:
316 return gtNewIconNode(compSupports(InstructionSet_BMI1));
323 GenTree* Compiler::impBMI2Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig)
327 case NI_BMI2_IsSupported:
328 return gtNewIconNode(compSupports(InstructionSet_BMI2));
335 GenTree* Compiler::impFMAIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig)
339 case NI_FMA_IsSupported:
340 return gtNewIconNode(compSupports(InstructionSet_FMA));
347 GenTree* Compiler::impLZCNTIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig)
351 case NI_LZCNT_IsSupported:
352 return gtNewIconNode(compSupports(InstructionSet_LZCNT));
359 GenTree* Compiler::impPCLMULQDQIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig)
363 case NI_PCLMULQDQ_IsSupported:
364 return gtNewIconNode(compSupports(InstructionSet_PCLMULQDQ));
371 GenTree* Compiler::impPOPCNTIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig)
375 case NI_POPCNT_IsSupported:
376 return gtNewIconNode(compSupports(InstructionSet_POPCNT));
383 #endif // _TARGET_XARCH_