Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/compiler/x/env/J9CPU.cpp
6004 views
1
/*******************************************************************************
2
* Copyright (c) 2000, 2021 IBM Corp. and others
3
*
4
* This program and the accompanying materials are made available under
5
* the terms of the Eclipse Public License 2.0 which accompanies this
6
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
7
* or the Apache License, Version 2.0 which accompanies this distribution and
8
* is available at https://www.apache.org/licenses/LICENSE-2.0.
9
*
10
* This Source Code may also be made available under the following
11
* Secondary Licenses when the conditions for such availability set
12
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
13
* General Public License, version 2 with the GNU Classpath
14
* Exception [1] and GNU General Public License, version 2 with the
15
* OpenJDK Assembly Exception [2].
16
*
17
* [1] https://www.gnu.org/software/classpath/license.html
18
* [2] http://openjdk.java.net/legal/assembly-exception.html
19
*
20
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
21
*******************************************************************************/
22
23
#include "compile/Compilation.hpp"
24
#include "env/CompilerEnv.hpp"
25
#include "env/CPU.hpp"
26
#include "env/VMJ9.h"
27
#include "x/runtime/X86Runtime.hpp"
28
#include "env/JitConfig.hpp"
29
#include "codegen/CodeGenerator.hpp"
30
#if defined(J9VM_OPT_JITSERVER)
31
#include "control/CompilationRuntime.hpp"
32
#include "control/CompilationThread.hpp"
33
#include "runtime/JITClientSession.hpp"
34
#endif /* defined(J9VM_OPT_JITSERVER) */
35
36
// This is a workaround to avoid J9_PROJECT_SPECIFIC macros in x/env/OMRCPU.cpp
37
// Without this definition, we get an undefined symbol of JITConfig::instance() at runtime
38
TR::JitConfig * TR::JitConfig::instance() { return NULL; }
39
40
TR::CPU
41
J9::X86::CPU::detectRelocatable(OMRPortLibrary * const omrPortLib)
42
{
43
// Sandybridge Architecture is selected to be our default portable processor description
44
const uint32_t customFeatures [] = {OMR_FEATURE_X86_FPU, OMR_FEATURE_X86_CX8, OMR_FEATURE_X86_CMOV,
45
OMR_FEATURE_X86_MMX, OMR_FEATURE_X86_SSE, OMR_FEATURE_X86_SSE2,
46
OMR_FEATURE_X86_SSSE3, OMR_FEATURE_X86_SSE4_1, OMR_FEATURE_X86_POPCNT,
47
OMR_FEATURE_X86_SSE3, OMR_FEATURE_X86_AESNI, OMR_FEATURE_X86_AVX};
48
49
OMRPORT_ACCESS_FROM_OMRPORT(omrPortLib);
50
OMRProcessorDesc customProcessorDescription;
51
memset(customProcessorDescription.features, 0, OMRPORT_SYSINFO_FEATURES_SIZE*sizeof(uint32_t));
52
for (size_t i = 0; i < sizeof(customFeatures)/sizeof(uint32_t); i++)
53
{
54
omrsysinfo_processor_set_feature(&customProcessorDescription, customFeatures[i], TRUE);
55
}
56
57
OMRProcessorDesc hostProcessorDescription;
58
omrsysinfo_get_processor_description(&hostProcessorDescription);
59
60
// Pick the older processor between our hand-picked processor and host processor to be the actual portable processor
61
OMRProcessorDesc portableProcessorDescription;
62
portableProcessorDescription.processor = OMR_PROCESSOR_X86_FIRST;
63
portableProcessorDescription.physicalProcessor = portableProcessorDescription.processor;
64
memset(portableProcessorDescription.features, 0, OMRPORT_SYSINFO_FEATURES_SIZE*sizeof(uint32_t));
65
66
for (size_t i = 0; i < OMRPORT_SYSINFO_FEATURES_SIZE; i++)
67
{
68
portableProcessorDescription.features[i] = hostProcessorDescription.features[i] & customProcessorDescription.features[i];
69
}
70
71
return TR::CPU::customize(portableProcessorDescription);
72
}
73
74
void
75
J9::X86::CPU::enableFeatureMasks()
76
{
77
// Only enable the features that compiler currently uses
78
const uint32_t utilizedFeatures [] = {OMR_FEATURE_X86_FPU, OMR_FEATURE_X86_CX8, OMR_FEATURE_X86_CMOV,
79
OMR_FEATURE_X86_MMX, OMR_FEATURE_X86_SSE, OMR_FEATURE_X86_SSE2,
80
OMR_FEATURE_X86_SSSE3, OMR_FEATURE_X86_SSE4_1, OMR_FEATURE_X86_POPCNT,
81
OMR_FEATURE_X86_AESNI, OMR_FEATURE_X86_OSXSAVE, OMR_FEATURE_X86_AVX,
82
OMR_FEATURE_X86_FMA, OMR_FEATURE_X86_HLE, OMR_FEATURE_X86_RTM,
83
OMR_FEATURE_X86_SSE3};
84
85
memset(_supportedFeatureMasks.features, 0, OMRPORT_SYSINFO_FEATURES_SIZE*sizeof(uint32_t));
86
OMRPORT_ACCESS_FROM_OMRPORT(TR::Compiler->omrPortLib);
87
for (size_t i = 0; i < sizeof(utilizedFeatures)/sizeof(uint32_t); i++)
88
{
89
omrsysinfo_processor_set_feature(&_supportedFeatureMasks, utilizedFeatures[i], TRUE);
90
}
91
_isSupportedFeatureMasksEnabled = true;
92
}
93
94
95
TR_X86CPUIDBuffer *
96
J9::X86::CPU::queryX86TargetCPUID()
97
{
98
static TR_X86CPUIDBuffer buf = { {'U','n','k','n','o','w','n','B','r','a','n','d'} };
99
jitGetCPUID(&buf);
100
return &buf;
101
}
102
103
const char *
104
J9::X86::CPU::getProcessorVendorId()
105
{
106
return self()->getX86ProcessorVendorId();
107
}
108
109
uint32_t
110
J9::X86::CPU::getProcessorSignature()
111
{
112
return self()->getX86ProcessorSignature();
113
}
114
115
bool
116
J9::X86::CPU::hasPopulationCountInstruction()
117
{
118
if ((self()->getX86ProcessorFeatureFlags2() & TR_POPCNT) != 0x00000000)
119
return true;
120
else
121
return false;
122
}
123
124
bool
125
J9::X86::CPU::isCompatible(const OMRProcessorDesc& processorDescription)
126
{
127
for (int i = 0; i < OMRPORT_SYSINFO_FEATURES_SIZE; i++)
128
{
129
// Check to see if the current processor contains all the features that code cache's processor has
130
if ((processorDescription.features[i] & _processorDescription.features[i]) != processorDescription.features[i])
131
return false;
132
}
133
return true;
134
}
135
136
bool
137
J9::X86::CPU::is(OMRProcessorArchitecture p)
138
{
139
static bool disableCPUDetectionTest = feGetEnv("TR_DisableCPUDetectionTest");
140
if (!disableCPUDetectionTest)
141
{
142
TR_ASSERT_FATAL(self()->is_test(p), "Old API and new API did not match: processor type %d\n", p);
143
}
144
145
return _processorDescription.processor == p;
146
}
147
148
bool
149
J9::X86::CPU::supportsFeature(uint32_t feature)
150
{
151
OMRPORT_ACCESS_FROM_OMRPORT(TR::Compiler->omrPortLib);
152
153
static bool disableCPUDetectionTest = feGetEnv("TR_DisableCPUDetectionTest");
154
if (!disableCPUDetectionTest)
155
{
156
TR_ASSERT_FATAL(self()->supports_feature_test(feature), "Old API and new API did not match: processor feature %d\n", feature);
157
TR_ASSERT_FATAL(TRUE == omrsysinfo_processor_has_feature(&_supportedFeatureMasks, feature), "New processor feature usage detected, please add feature %d to _supportedFeatureMasks via TR::CPU::enableFeatureMasks()\n", feature);
158
}
159
160
return TRUE == omrsysinfo_processor_has_feature(&_processorDescription, feature);
161
}
162
163
uint32_t
164
J9::X86::CPU::getX86ProcessorFeatureFlags()
165
{
166
#if defined(J9VM_OPT_JITSERVER)
167
if (auto stream = TR::CompilationInfo::getStream())
168
{
169
auto *vmInfo = TR::compInfoPT->getClientData()->getOrCacheVMInfo(stream);
170
return vmInfo->_processorDescription.features[0];
171
}
172
#endif /* defined(J9VM_OPT_JITSERVER) */
173
return self()->queryX86TargetCPUID()->_featureFlags;
174
}
175
176
uint32_t
177
J9::X86::CPU::getX86ProcessorFeatureFlags2()
178
{
179
#if defined(J9VM_OPT_JITSERVER)
180
if (auto stream = TR::CompilationInfo::getStream())
181
{
182
auto *vmInfo = TR::compInfoPT->getClientData()->getOrCacheVMInfo(stream);
183
return vmInfo->_processorDescription.features[1];
184
}
185
#endif /* defined(J9VM_OPT_JITSERVER) */
186
return self()->queryX86TargetCPUID()->_featureFlags2;
187
}
188
189
uint32_t
190
J9::X86::CPU::getX86ProcessorFeatureFlags8()
191
{
192
#if defined(J9VM_OPT_JITSERVER)
193
if (auto stream = TR::CompilationInfo::getStream())
194
{
195
auto *vmInfo = TR::compInfoPT->getClientData()->getOrCacheVMInfo(stream);
196
return vmInfo->_processorDescription.features[3];
197
}
198
#endif /* defined(J9VM_OPT_JITSERVER) */
199
return self()->queryX86TargetCPUID()->_featureFlags8;
200
}
201
202
bool
203
J9::X86::CPU::is_test(OMRProcessorArchitecture p)
204
{
205
#if defined(J9VM_OPT_JITSERVER)
206
if (TR::CompilationInfo::getStream())
207
return true;
208
#endif /* defined(J9VM_OPT_JITSERVER) */
209
if (TR::comp()->compileRelocatableCode() || TR::comp()->compilePortableCode())
210
return true;
211
212
switch(p)
213
{
214
case OMR_PROCESSOR_X86_INTELWESTMERE:
215
return TR::CodeGenerator::getX86ProcessorInfo().isIntelWestmere() == (_processorDescription.processor == p);
216
case OMR_PROCESSOR_X86_INTELNEHALEM:
217
return TR::CodeGenerator::getX86ProcessorInfo().isIntelNehalem() == (_processorDescription.processor == p);
218
case OMR_PROCESSOR_X86_INTELPENTIUM:
219
return TR::CodeGenerator::getX86ProcessorInfo().isIntelPentium() == (_processorDescription.processor == p);
220
case OMR_PROCESSOR_X86_INTELP6:
221
return TR::CodeGenerator::getX86ProcessorInfo().isIntelP6() == (_processorDescription.processor == p);
222
case OMR_PROCESSOR_X86_INTELPENTIUM4:
223
return TR::CodeGenerator::getX86ProcessorInfo().isIntelPentium4() == (_processorDescription.processor == p);
224
case OMR_PROCESSOR_X86_INTELCORE2:
225
return TR::CodeGenerator::getX86ProcessorInfo().isIntelCore2() == (_processorDescription.processor == p);
226
case OMR_PROCESSOR_X86_INTELTULSA:
227
return TR::CodeGenerator::getX86ProcessorInfo().isIntelTulsa() == (_processorDescription.processor == p);
228
case OMR_PROCESSOR_X86_INTELSANDYBRIDGE:
229
return TR::CodeGenerator::getX86ProcessorInfo().isIntelSandyBridge() == (_processorDescription.processor == p);
230
case OMR_PROCESSOR_X86_INTELIVYBRIDGE:
231
return TR::CodeGenerator::getX86ProcessorInfo().isIntelIvyBridge() == (_processorDescription.processor == p);
232
case OMR_PROCESSOR_X86_INTELHASWELL:
233
return TR::CodeGenerator::getX86ProcessorInfo().isIntelHaswell() == (_processorDescription.processor == p);
234
case OMR_PROCESSOR_X86_INTELBROADWELL:
235
return TR::CodeGenerator::getX86ProcessorInfo().isIntelBroadwell() == (_processorDescription.processor == p);
236
case OMR_PROCESSOR_X86_INTELSKYLAKE:
237
return TR::CodeGenerator::getX86ProcessorInfo().isIntelSkylake() == (_processorDescription.processor == p);
238
case OMR_PROCESSOR_X86_AMDATHLONDURON:
239
return TR::CodeGenerator::getX86ProcessorInfo().isAMDAthlonDuron() == (_processorDescription.processor == p);
240
case OMR_PROCESSOR_X86_AMDOPTERON:
241
return TR::CodeGenerator::getX86ProcessorInfo().isAMDOpteron() == (_processorDescription.processor == p);
242
case OMR_PROCESSOR_X86_AMDFAMILY15H:
243
return TR::CodeGenerator::getX86ProcessorInfo().isAMD15h() == (_processorDescription.processor == p);
244
default:
245
return false;
246
}
247
return false;
248
}
249
250
bool
251
J9::X86::CPU::supports_feature_test(uint32_t feature)
252
{
253
#if defined(J9VM_OPT_JITSERVER)
254
if (TR::CompilationInfo::getStream())
255
return true;
256
#endif /* defined(J9VM_OPT_JITSERVER) */
257
if (TR::comp()->compileRelocatableCode() || TR::comp()->compilePortableCode())
258
return true;
259
260
OMRPORT_ACCESS_FROM_OMRPORT(TR::Compiler->omrPortLib);
261
bool ans = (TRUE == omrsysinfo_processor_has_feature(&_processorDescription, feature));
262
263
switch(feature)
264
{
265
case OMR_FEATURE_X86_OSXSAVE:
266
return TR::CodeGenerator::getX86ProcessorInfo().enabledXSAVE() == ans;
267
case OMR_FEATURE_X86_FPU:
268
return TR::CodeGenerator::getX86ProcessorInfo().hasBuiltInFPU() == ans;
269
case OMR_FEATURE_X86_VME:
270
return TR::CodeGenerator::getX86ProcessorInfo().supportsVirtualModeExtension() == ans;
271
case OMR_FEATURE_X86_DE:
272
return TR::CodeGenerator::getX86ProcessorInfo().supportsDebuggingExtension() == ans;
273
case OMR_FEATURE_X86_PSE:
274
return TR::CodeGenerator::getX86ProcessorInfo().supportsPageSizeExtension() == ans;
275
case OMR_FEATURE_X86_TSC:
276
return TR::CodeGenerator::getX86ProcessorInfo().supportsRDTSCInstruction() == ans;
277
case OMR_FEATURE_X86_MSR:
278
return TR::CodeGenerator::getX86ProcessorInfo().hasModelSpecificRegisters() == ans;
279
case OMR_FEATURE_X86_PAE:
280
return TR::CodeGenerator::getX86ProcessorInfo().supportsPhysicalAddressExtension() == ans;
281
case OMR_FEATURE_X86_MCE:
282
return TR::CodeGenerator::getX86ProcessorInfo().supportsMachineCheckException() == ans;
283
case OMR_FEATURE_X86_CX8:
284
return TR::CodeGenerator::getX86ProcessorInfo().supportsCMPXCHG8BInstruction() == ans;
285
case OMR_FEATURE_X86_CMPXCHG16B:
286
return TR::CodeGenerator::getX86ProcessorInfo().supportsCMPXCHG16BInstruction() == ans;
287
case OMR_FEATURE_X86_APIC:
288
return TR::CodeGenerator::getX86ProcessorInfo().hasAPICHardware() == ans;
289
case OMR_FEATURE_X86_MTRR:
290
return TR::CodeGenerator::getX86ProcessorInfo().hasMemoryTypeRangeRegisters() == ans;
291
case OMR_FEATURE_X86_PGE:
292
return TR::CodeGenerator::getX86ProcessorInfo().supportsPageGlobalFlag() == ans;
293
case OMR_FEATURE_X86_MCA:
294
return TR::CodeGenerator::getX86ProcessorInfo().hasMachineCheckArchitecture() == ans;
295
case OMR_FEATURE_X86_CMOV:
296
return TR::CodeGenerator::getX86ProcessorInfo().supportsCMOVInstructions() == ans;
297
case OMR_FEATURE_X86_PAT:
298
return TR::CodeGenerator::getX86ProcessorInfo().hasPageAttributeTable() == ans;
299
case OMR_FEATURE_X86_PSE_36:
300
return TR::CodeGenerator::getX86ProcessorInfo().has36BitPageSizeExtension() == ans;
301
case OMR_FEATURE_X86_PSN:
302
return TR::CodeGenerator::getX86ProcessorInfo().hasProcessorSerialNumber() == ans;
303
case OMR_FEATURE_X86_CLFSH:
304
return TR::CodeGenerator::getX86ProcessorInfo().supportsCLFLUSHInstruction() == ans;
305
case OMR_FEATURE_X86_DS:
306
return TR::CodeGenerator::getX86ProcessorInfo().supportsDebugTraceStore() == ans;
307
case OMR_FEATURE_X86_ACPI:
308
return TR::CodeGenerator::getX86ProcessorInfo().hasACPIRegisters() == ans;
309
case OMR_FEATURE_X86_MMX:
310
return TR::CodeGenerator::getX86ProcessorInfo().supportsMMXInstructions() == ans;
311
case OMR_FEATURE_X86_FXSR:
312
return TR::CodeGenerator::getX86ProcessorInfo().supportsFastFPSavesRestores() == ans;
313
case OMR_FEATURE_X86_SSE:
314
return TR::CodeGenerator::getX86ProcessorInfo().supportsSSE() == ans;
315
case OMR_FEATURE_X86_SSE2:
316
return TR::CodeGenerator::getX86ProcessorInfo().supportsSSE2() == ans;
317
case OMR_FEATURE_X86_SSE3:
318
return TR::CodeGenerator::getX86ProcessorInfo().supportsSSE3() == ans;
319
case OMR_FEATURE_X86_SSSE3:
320
return TR::CodeGenerator::getX86ProcessorInfo().supportsSSSE3() == ans;
321
case OMR_FEATURE_X86_SSE4_1:
322
return TR::CodeGenerator::getX86ProcessorInfo().supportsSSE4_1() == ans;
323
case OMR_FEATURE_X86_SSE4_2:
324
return TR::CodeGenerator::getX86ProcessorInfo().supportsSSE4_2() == ans;
325
case OMR_FEATURE_X86_PCLMULQDQ:
326
return TR::CodeGenerator::getX86ProcessorInfo().supportsCLMUL() == ans;
327
case OMR_FEATURE_X86_AESNI:
328
return TR::CodeGenerator::getX86ProcessorInfo().supportsAESNI() == ans;
329
case OMR_FEATURE_X86_POPCNT:
330
return TR::CodeGenerator::getX86ProcessorInfo().supportsPOPCNT() == ans;
331
case OMR_FEATURE_X86_SS:
332
return TR::CodeGenerator::getX86ProcessorInfo().supportsSelfSnoop() == ans;
333
case OMR_FEATURE_X86_RTM:
334
return TR::CodeGenerator::getX86ProcessorInfo().supportsTM() == ans;
335
case OMR_FEATURE_X86_HTT:
336
return TR::CodeGenerator::getX86ProcessorInfo().supportsHyperThreading() == ans;
337
case OMR_FEATURE_X86_HLE:
338
return TR::CodeGenerator::getX86ProcessorInfo().supportsHLE() == ans;
339
case OMR_FEATURE_X86_TM:
340
return TR::CodeGenerator::getX86ProcessorInfo().hasThermalMonitor() == ans;
341
case OMR_FEATURE_X86_AVX:
342
return true;
343
default:
344
return false;
345
}
346
return false;
347
}
348
349
350