Path: blob/master/runtime/compiler/x/env/J9CPU.cpp
6004 views
/*******************************************************************************1* Copyright (c) 2000, 2021 IBM Corp. and others2*3* This program and the accompanying materials are made available under4* the terms of the Eclipse Public License 2.0 which accompanies this5* distribution and is available at https://www.eclipse.org/legal/epl-2.0/6* or the Apache License, Version 2.0 which accompanies this distribution and7* is available at https://www.apache.org/licenses/LICENSE-2.0.8*9* This Source Code may also be made available under the following10* Secondary Licenses when the conditions for such availability set11* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU12* General Public License, version 2 with the GNU Classpath13* Exception [1] and GNU General Public License, version 2 with the14* OpenJDK Assembly Exception [2].15*16* [1] https://www.gnu.org/software/classpath/license.html17* [2] http://openjdk.java.net/legal/assembly-exception.html18*19* 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-exception20*******************************************************************************/2122#include "compile/Compilation.hpp"23#include "env/CompilerEnv.hpp"24#include "env/CPU.hpp"25#include "env/VMJ9.h"26#include "x/runtime/X86Runtime.hpp"27#include "env/JitConfig.hpp"28#include "codegen/CodeGenerator.hpp"29#if defined(J9VM_OPT_JITSERVER)30#include "control/CompilationRuntime.hpp"31#include "control/CompilationThread.hpp"32#include "runtime/JITClientSession.hpp"33#endif /* defined(J9VM_OPT_JITSERVER) */3435// This is a workaround to avoid J9_PROJECT_SPECIFIC macros in x/env/OMRCPU.cpp36// Without this definition, we get an undefined symbol of JITConfig::instance() at runtime37TR::JitConfig * TR::JitConfig::instance() { return NULL; }3839TR::CPU40J9::X86::CPU::detectRelocatable(OMRPortLibrary * const omrPortLib)41{42// Sandybridge Architecture is selected to be our default portable processor description43const uint32_t customFeatures [] = {OMR_FEATURE_X86_FPU, OMR_FEATURE_X86_CX8, OMR_FEATURE_X86_CMOV,44OMR_FEATURE_X86_MMX, OMR_FEATURE_X86_SSE, OMR_FEATURE_X86_SSE2,45OMR_FEATURE_X86_SSSE3, OMR_FEATURE_X86_SSE4_1, OMR_FEATURE_X86_POPCNT,46OMR_FEATURE_X86_SSE3, OMR_FEATURE_X86_AESNI, OMR_FEATURE_X86_AVX};4748OMRPORT_ACCESS_FROM_OMRPORT(omrPortLib);49OMRProcessorDesc customProcessorDescription;50memset(customProcessorDescription.features, 0, OMRPORT_SYSINFO_FEATURES_SIZE*sizeof(uint32_t));51for (size_t i = 0; i < sizeof(customFeatures)/sizeof(uint32_t); i++)52{53omrsysinfo_processor_set_feature(&customProcessorDescription, customFeatures[i], TRUE);54}5556OMRProcessorDesc hostProcessorDescription;57omrsysinfo_get_processor_description(&hostProcessorDescription);5859// Pick the older processor between our hand-picked processor and host processor to be the actual portable processor60OMRProcessorDesc portableProcessorDescription;61portableProcessorDescription.processor = OMR_PROCESSOR_X86_FIRST;62portableProcessorDescription.physicalProcessor = portableProcessorDescription.processor;63memset(portableProcessorDescription.features, 0, OMRPORT_SYSINFO_FEATURES_SIZE*sizeof(uint32_t));6465for (size_t i = 0; i < OMRPORT_SYSINFO_FEATURES_SIZE; i++)66{67portableProcessorDescription.features[i] = hostProcessorDescription.features[i] & customProcessorDescription.features[i];68}6970return TR::CPU::customize(portableProcessorDescription);71}7273void74J9::X86::CPU::enableFeatureMasks()75{76// Only enable the features that compiler currently uses77const uint32_t utilizedFeatures [] = {OMR_FEATURE_X86_FPU, OMR_FEATURE_X86_CX8, OMR_FEATURE_X86_CMOV,78OMR_FEATURE_X86_MMX, OMR_FEATURE_X86_SSE, OMR_FEATURE_X86_SSE2,79OMR_FEATURE_X86_SSSE3, OMR_FEATURE_X86_SSE4_1, OMR_FEATURE_X86_POPCNT,80OMR_FEATURE_X86_AESNI, OMR_FEATURE_X86_OSXSAVE, OMR_FEATURE_X86_AVX,81OMR_FEATURE_X86_FMA, OMR_FEATURE_X86_HLE, OMR_FEATURE_X86_RTM,82OMR_FEATURE_X86_SSE3};8384memset(_supportedFeatureMasks.features, 0, OMRPORT_SYSINFO_FEATURES_SIZE*sizeof(uint32_t));85OMRPORT_ACCESS_FROM_OMRPORT(TR::Compiler->omrPortLib);86for (size_t i = 0; i < sizeof(utilizedFeatures)/sizeof(uint32_t); i++)87{88omrsysinfo_processor_set_feature(&_supportedFeatureMasks, utilizedFeatures[i], TRUE);89}90_isSupportedFeatureMasksEnabled = true;91}929394TR_X86CPUIDBuffer *95J9::X86::CPU::queryX86TargetCPUID()96{97static TR_X86CPUIDBuffer buf = { {'U','n','k','n','o','w','n','B','r','a','n','d'} };98jitGetCPUID(&buf);99return &buf;100}101102const char *103J9::X86::CPU::getProcessorVendorId()104{105return self()->getX86ProcessorVendorId();106}107108uint32_t109J9::X86::CPU::getProcessorSignature()110{111return self()->getX86ProcessorSignature();112}113114bool115J9::X86::CPU::hasPopulationCountInstruction()116{117if ((self()->getX86ProcessorFeatureFlags2() & TR_POPCNT) != 0x00000000)118return true;119else120return false;121}122123bool124J9::X86::CPU::isCompatible(const OMRProcessorDesc& processorDescription)125{126for (int i = 0; i < OMRPORT_SYSINFO_FEATURES_SIZE; i++)127{128// Check to see if the current processor contains all the features that code cache's processor has129if ((processorDescription.features[i] & _processorDescription.features[i]) != processorDescription.features[i])130return false;131}132return true;133}134135bool136J9::X86::CPU::is(OMRProcessorArchitecture p)137{138static bool disableCPUDetectionTest = feGetEnv("TR_DisableCPUDetectionTest");139if (!disableCPUDetectionTest)140{141TR_ASSERT_FATAL(self()->is_test(p), "Old API and new API did not match: processor type %d\n", p);142}143144return _processorDescription.processor == p;145}146147bool148J9::X86::CPU::supportsFeature(uint32_t feature)149{150OMRPORT_ACCESS_FROM_OMRPORT(TR::Compiler->omrPortLib);151152static bool disableCPUDetectionTest = feGetEnv("TR_DisableCPUDetectionTest");153if (!disableCPUDetectionTest)154{155TR_ASSERT_FATAL(self()->supports_feature_test(feature), "Old API and new API did not match: processor feature %d\n", feature);156TR_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);157}158159return TRUE == omrsysinfo_processor_has_feature(&_processorDescription, feature);160}161162uint32_t163J9::X86::CPU::getX86ProcessorFeatureFlags()164{165#if defined(J9VM_OPT_JITSERVER)166if (auto stream = TR::CompilationInfo::getStream())167{168auto *vmInfo = TR::compInfoPT->getClientData()->getOrCacheVMInfo(stream);169return vmInfo->_processorDescription.features[0];170}171#endif /* defined(J9VM_OPT_JITSERVER) */172return self()->queryX86TargetCPUID()->_featureFlags;173}174175uint32_t176J9::X86::CPU::getX86ProcessorFeatureFlags2()177{178#if defined(J9VM_OPT_JITSERVER)179if (auto stream = TR::CompilationInfo::getStream())180{181auto *vmInfo = TR::compInfoPT->getClientData()->getOrCacheVMInfo(stream);182return vmInfo->_processorDescription.features[1];183}184#endif /* defined(J9VM_OPT_JITSERVER) */185return self()->queryX86TargetCPUID()->_featureFlags2;186}187188uint32_t189J9::X86::CPU::getX86ProcessorFeatureFlags8()190{191#if defined(J9VM_OPT_JITSERVER)192if (auto stream = TR::CompilationInfo::getStream())193{194auto *vmInfo = TR::compInfoPT->getClientData()->getOrCacheVMInfo(stream);195return vmInfo->_processorDescription.features[3];196}197#endif /* defined(J9VM_OPT_JITSERVER) */198return self()->queryX86TargetCPUID()->_featureFlags8;199}200201bool202J9::X86::CPU::is_test(OMRProcessorArchitecture p)203{204#if defined(J9VM_OPT_JITSERVER)205if (TR::CompilationInfo::getStream())206return true;207#endif /* defined(J9VM_OPT_JITSERVER) */208if (TR::comp()->compileRelocatableCode() || TR::comp()->compilePortableCode())209return true;210211switch(p)212{213case OMR_PROCESSOR_X86_INTELWESTMERE:214return TR::CodeGenerator::getX86ProcessorInfo().isIntelWestmere() == (_processorDescription.processor == p);215case OMR_PROCESSOR_X86_INTELNEHALEM:216return TR::CodeGenerator::getX86ProcessorInfo().isIntelNehalem() == (_processorDescription.processor == p);217case OMR_PROCESSOR_X86_INTELPENTIUM:218return TR::CodeGenerator::getX86ProcessorInfo().isIntelPentium() == (_processorDescription.processor == p);219case OMR_PROCESSOR_X86_INTELP6:220return TR::CodeGenerator::getX86ProcessorInfo().isIntelP6() == (_processorDescription.processor == p);221case OMR_PROCESSOR_X86_INTELPENTIUM4:222return TR::CodeGenerator::getX86ProcessorInfo().isIntelPentium4() == (_processorDescription.processor == p);223case OMR_PROCESSOR_X86_INTELCORE2:224return TR::CodeGenerator::getX86ProcessorInfo().isIntelCore2() == (_processorDescription.processor == p);225case OMR_PROCESSOR_X86_INTELTULSA:226return TR::CodeGenerator::getX86ProcessorInfo().isIntelTulsa() == (_processorDescription.processor == p);227case OMR_PROCESSOR_X86_INTELSANDYBRIDGE:228return TR::CodeGenerator::getX86ProcessorInfo().isIntelSandyBridge() == (_processorDescription.processor == p);229case OMR_PROCESSOR_X86_INTELIVYBRIDGE:230return TR::CodeGenerator::getX86ProcessorInfo().isIntelIvyBridge() == (_processorDescription.processor == p);231case OMR_PROCESSOR_X86_INTELHASWELL:232return TR::CodeGenerator::getX86ProcessorInfo().isIntelHaswell() == (_processorDescription.processor == p);233case OMR_PROCESSOR_X86_INTELBROADWELL:234return TR::CodeGenerator::getX86ProcessorInfo().isIntelBroadwell() == (_processorDescription.processor == p);235case OMR_PROCESSOR_X86_INTELSKYLAKE:236return TR::CodeGenerator::getX86ProcessorInfo().isIntelSkylake() == (_processorDescription.processor == p);237case OMR_PROCESSOR_X86_AMDATHLONDURON:238return TR::CodeGenerator::getX86ProcessorInfo().isAMDAthlonDuron() == (_processorDescription.processor == p);239case OMR_PROCESSOR_X86_AMDOPTERON:240return TR::CodeGenerator::getX86ProcessorInfo().isAMDOpteron() == (_processorDescription.processor == p);241case OMR_PROCESSOR_X86_AMDFAMILY15H:242return TR::CodeGenerator::getX86ProcessorInfo().isAMD15h() == (_processorDescription.processor == p);243default:244return false;245}246return false;247}248249bool250J9::X86::CPU::supports_feature_test(uint32_t feature)251{252#if defined(J9VM_OPT_JITSERVER)253if (TR::CompilationInfo::getStream())254return true;255#endif /* defined(J9VM_OPT_JITSERVER) */256if (TR::comp()->compileRelocatableCode() || TR::comp()->compilePortableCode())257return true;258259OMRPORT_ACCESS_FROM_OMRPORT(TR::Compiler->omrPortLib);260bool ans = (TRUE == omrsysinfo_processor_has_feature(&_processorDescription, feature));261262switch(feature)263{264case OMR_FEATURE_X86_OSXSAVE:265return TR::CodeGenerator::getX86ProcessorInfo().enabledXSAVE() == ans;266case OMR_FEATURE_X86_FPU:267return TR::CodeGenerator::getX86ProcessorInfo().hasBuiltInFPU() == ans;268case OMR_FEATURE_X86_VME:269return TR::CodeGenerator::getX86ProcessorInfo().supportsVirtualModeExtension() == ans;270case OMR_FEATURE_X86_DE:271return TR::CodeGenerator::getX86ProcessorInfo().supportsDebuggingExtension() == ans;272case OMR_FEATURE_X86_PSE:273return TR::CodeGenerator::getX86ProcessorInfo().supportsPageSizeExtension() == ans;274case OMR_FEATURE_X86_TSC:275return TR::CodeGenerator::getX86ProcessorInfo().supportsRDTSCInstruction() == ans;276case OMR_FEATURE_X86_MSR:277return TR::CodeGenerator::getX86ProcessorInfo().hasModelSpecificRegisters() == ans;278case OMR_FEATURE_X86_PAE:279return TR::CodeGenerator::getX86ProcessorInfo().supportsPhysicalAddressExtension() == ans;280case OMR_FEATURE_X86_MCE:281return TR::CodeGenerator::getX86ProcessorInfo().supportsMachineCheckException() == ans;282case OMR_FEATURE_X86_CX8:283return TR::CodeGenerator::getX86ProcessorInfo().supportsCMPXCHG8BInstruction() == ans;284case OMR_FEATURE_X86_CMPXCHG16B:285return TR::CodeGenerator::getX86ProcessorInfo().supportsCMPXCHG16BInstruction() == ans;286case OMR_FEATURE_X86_APIC:287return TR::CodeGenerator::getX86ProcessorInfo().hasAPICHardware() == ans;288case OMR_FEATURE_X86_MTRR:289return TR::CodeGenerator::getX86ProcessorInfo().hasMemoryTypeRangeRegisters() == ans;290case OMR_FEATURE_X86_PGE:291return TR::CodeGenerator::getX86ProcessorInfo().supportsPageGlobalFlag() == ans;292case OMR_FEATURE_X86_MCA:293return TR::CodeGenerator::getX86ProcessorInfo().hasMachineCheckArchitecture() == ans;294case OMR_FEATURE_X86_CMOV:295return TR::CodeGenerator::getX86ProcessorInfo().supportsCMOVInstructions() == ans;296case OMR_FEATURE_X86_PAT:297return TR::CodeGenerator::getX86ProcessorInfo().hasPageAttributeTable() == ans;298case OMR_FEATURE_X86_PSE_36:299return TR::CodeGenerator::getX86ProcessorInfo().has36BitPageSizeExtension() == ans;300case OMR_FEATURE_X86_PSN:301return TR::CodeGenerator::getX86ProcessorInfo().hasProcessorSerialNumber() == ans;302case OMR_FEATURE_X86_CLFSH:303return TR::CodeGenerator::getX86ProcessorInfo().supportsCLFLUSHInstruction() == ans;304case OMR_FEATURE_X86_DS:305return TR::CodeGenerator::getX86ProcessorInfo().supportsDebugTraceStore() == ans;306case OMR_FEATURE_X86_ACPI:307return TR::CodeGenerator::getX86ProcessorInfo().hasACPIRegisters() == ans;308case OMR_FEATURE_X86_MMX:309return TR::CodeGenerator::getX86ProcessorInfo().supportsMMXInstructions() == ans;310case OMR_FEATURE_X86_FXSR:311return TR::CodeGenerator::getX86ProcessorInfo().supportsFastFPSavesRestores() == ans;312case OMR_FEATURE_X86_SSE:313return TR::CodeGenerator::getX86ProcessorInfo().supportsSSE() == ans;314case OMR_FEATURE_X86_SSE2:315return TR::CodeGenerator::getX86ProcessorInfo().supportsSSE2() == ans;316case OMR_FEATURE_X86_SSE3:317return TR::CodeGenerator::getX86ProcessorInfo().supportsSSE3() == ans;318case OMR_FEATURE_X86_SSSE3:319return TR::CodeGenerator::getX86ProcessorInfo().supportsSSSE3() == ans;320case OMR_FEATURE_X86_SSE4_1:321return TR::CodeGenerator::getX86ProcessorInfo().supportsSSE4_1() == ans;322case OMR_FEATURE_X86_SSE4_2:323return TR::CodeGenerator::getX86ProcessorInfo().supportsSSE4_2() == ans;324case OMR_FEATURE_X86_PCLMULQDQ:325return TR::CodeGenerator::getX86ProcessorInfo().supportsCLMUL() == ans;326case OMR_FEATURE_X86_AESNI:327return TR::CodeGenerator::getX86ProcessorInfo().supportsAESNI() == ans;328case OMR_FEATURE_X86_POPCNT:329return TR::CodeGenerator::getX86ProcessorInfo().supportsPOPCNT() == ans;330case OMR_FEATURE_X86_SS:331return TR::CodeGenerator::getX86ProcessorInfo().supportsSelfSnoop() == ans;332case OMR_FEATURE_X86_RTM:333return TR::CodeGenerator::getX86ProcessorInfo().supportsTM() == ans;334case OMR_FEATURE_X86_HTT:335return TR::CodeGenerator::getX86ProcessorInfo().supportsHyperThreading() == ans;336case OMR_FEATURE_X86_HLE:337return TR::CodeGenerator::getX86ProcessorInfo().supportsHLE() == ans;338case OMR_FEATURE_X86_TM:339return TR::CodeGenerator::getX86ProcessorInfo().hasThermalMonitor() == ans;340case OMR_FEATURE_X86_AVX:341return true;342default:343return false;344}345return false;346}347348349350