10b57cec5SDimitry Andric //===-- SystemZSubtarget.cpp - SystemZ subtarget information --------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "SystemZSubtarget.h" 100b57cec5SDimitry Andric #include "MCTargetDesc/SystemZMCTargetDesc.h" 110b57cec5SDimitry Andric #include "llvm/IR/GlobalValue.h" 125ffd83dbSDimitry Andric #include "llvm/Target/TargetMachine.h" 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric using namespace llvm; 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #define DEBUG_TYPE "systemz-subtarget" 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric #define GET_SUBTARGETINFO_TARGET_DESC 190b57cec5SDimitry Andric #define GET_SUBTARGETINFO_CTOR 200b57cec5SDimitry Andric #include "SystemZGenSubtargetInfo.inc" 210b57cec5SDimitry Andric 220b57cec5SDimitry Andric static cl::opt<bool> UseSubRegLiveness( 230b57cec5SDimitry Andric "systemz-subreg-liveness", 240b57cec5SDimitry Andric cl::desc("Enable subregister liveness tracking for SystemZ (experimental)"), 250b57cec5SDimitry Andric cl::Hidden); 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric // Pin the vtable to this file. 280b57cec5SDimitry Andric void SystemZSubtarget::anchor() {} 290b57cec5SDimitry Andric 300b57cec5SDimitry Andric SystemZSubtarget & 310b57cec5SDimitry Andric SystemZSubtarget::initializeSubtargetDependencies(StringRef CPU, StringRef FS) { 325ffd83dbSDimitry Andric StringRef CPUName = CPU; 330b57cec5SDimitry Andric if (CPUName.empty()) 340b57cec5SDimitry Andric CPUName = "generic"; 350b57cec5SDimitry Andric // Parse features string. 36e8d8bef9SDimitry Andric ParseSubtargetFeatures(CPUName, /*TuneCPU*/ CPUName, FS); 375ffd83dbSDimitry Andric 385ffd83dbSDimitry Andric // -msoft-float implies -mno-vx. 395ffd83dbSDimitry Andric if (HasSoftFloat) 405ffd83dbSDimitry Andric HasVector = false; 415ffd83dbSDimitry Andric 42e8d8bef9SDimitry Andric // -mno-vx implicitly disables all vector-related features. 43e8d8bef9SDimitry Andric if (!HasVector) { 44e8d8bef9SDimitry Andric HasVectorEnhancements1 = false; 45e8d8bef9SDimitry Andric HasVectorEnhancements2 = false; 46e8d8bef9SDimitry Andric HasVectorPackedDecimal = false; 47e8d8bef9SDimitry Andric HasVectorPackedDecimalEnhancement = false; 48*fe6060f1SDimitry Andric HasVectorPackedDecimalEnhancement2 = false; 49e8d8bef9SDimitry Andric } 50e8d8bef9SDimitry Andric 510b57cec5SDimitry Andric return *this; 520b57cec5SDimitry Andric } 530b57cec5SDimitry Andric 54*fe6060f1SDimitry Andric SystemZCallingConventionRegisters * 55*fe6060f1SDimitry Andric SystemZSubtarget::initializeSpecialRegisters() { 56*fe6060f1SDimitry Andric if (isTargetXPLINK64()) 57*fe6060f1SDimitry Andric return new SystemZXPLINK64Registers; 58*fe6060f1SDimitry Andric else if (isTargetELF()) 59*fe6060f1SDimitry Andric return new SystemZELFRegisters; 60*fe6060f1SDimitry Andric else { 61*fe6060f1SDimitry Andric llvm_unreachable("Invalid Calling Convention. Cannot initialize Special " 62*fe6060f1SDimitry Andric "Call Registers!"); 63*fe6060f1SDimitry Andric } 64*fe6060f1SDimitry Andric } 65*fe6060f1SDimitry Andric 660b57cec5SDimitry Andric SystemZSubtarget::SystemZSubtarget(const Triple &TT, const std::string &CPU, 670b57cec5SDimitry Andric const std::string &FS, 680b57cec5SDimitry Andric const TargetMachine &TM) 69e8d8bef9SDimitry Andric : SystemZGenSubtargetInfo(TT, CPU, /*TuneCPU*/ CPU, FS), 70e8d8bef9SDimitry Andric HasDistinctOps(false), HasLoadStoreOnCond(false), HasHighWord(false), 71e8d8bef9SDimitry Andric HasFPExtension(false), HasPopulationCount(false), 72e8d8bef9SDimitry Andric HasMessageSecurityAssist3(false), HasMessageSecurityAssist4(false), 73e8d8bef9SDimitry Andric HasResetReferenceBitsMultiple(false), HasFastSerialization(false), 74e8d8bef9SDimitry Andric HasInterlockedAccess1(false), HasMiscellaneousExtensions(false), 750b57cec5SDimitry Andric HasExecutionHint(false), HasLoadAndTrap(false), 760b57cec5SDimitry Andric HasTransactionalExecution(false), HasProcessorAssist(false), 77*fe6060f1SDimitry Andric HasDFPZonedConversion(false), HasEnhancedDAT2(false), HasVector(false), 78*fe6060f1SDimitry Andric HasLoadStoreOnCond2(false), HasLoadAndZeroRightmostByte(false), 79*fe6060f1SDimitry Andric HasMessageSecurityAssist5(false), HasDFPPackedConversion(false), 800b57cec5SDimitry Andric HasMiscellaneousExtensions2(false), HasGuardedStorage(false), 810b57cec5SDimitry Andric HasMessageSecurityAssist7(false), HasMessageSecurityAssist8(false), 820b57cec5SDimitry Andric HasVectorEnhancements1(false), HasVectorPackedDecimal(false), 83*fe6060f1SDimitry Andric HasInsertReferenceBitsMultiple(false), HasMiscellaneousExtensions3(false), 84*fe6060f1SDimitry Andric HasMessageSecurityAssist9(false), HasVectorEnhancements2(false), 85*fe6060f1SDimitry Andric HasVectorPackedDecimalEnhancement(false), HasEnhancedSort(false), 86*fe6060f1SDimitry Andric HasDeflateConversion(false), HasVectorPackedDecimalEnhancement2(false), 87*fe6060f1SDimitry Andric HasNNPAssist(false), HasBEAREnhancement(false), 88*fe6060f1SDimitry Andric HasResetDATProtection(false), HasProcessorActivityInstrumentation(false), 89*fe6060f1SDimitry Andric HasSoftFloat(false), TargetTriple(TT), 90*fe6060f1SDimitry Andric SpecialRegisters(initializeSpecialRegisters()), 91*fe6060f1SDimitry Andric InstrInfo(initializeSubtargetDependencies(CPU, FS)), TLInfo(TM, *this), 92*fe6060f1SDimitry Andric TSInfo(), FrameLowering() {} 930b57cec5SDimitry Andric 94*fe6060f1SDimitry Andric SystemZSubtarget::~SystemZSubtarget() { delete getSpecialRegisters(); } 950b57cec5SDimitry Andric 960b57cec5SDimitry Andric bool SystemZSubtarget::enableSubRegLiveness() const { 970b57cec5SDimitry Andric return UseSubRegLiveness; 980b57cec5SDimitry Andric } 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric bool SystemZSubtarget::isPC32DBLSymbol(const GlobalValue *GV, 1010b57cec5SDimitry Andric CodeModel::Model CM) const { 1025ffd83dbSDimitry Andric // PC32DBL accesses require the low bit to be clear. 1035ffd83dbSDimitry Andric // 1045ffd83dbSDimitry Andric // FIXME: Explicitly check for functions: the datalayout is currently 1055ffd83dbSDimitry Andric // missing information about function pointers. 1065ffd83dbSDimitry Andric const DataLayout &DL = GV->getParent()->getDataLayout(); 1075ffd83dbSDimitry Andric if (GV->getPointerAlignment(DL) == 1 && !GV->getValueType()->isFunctionTy()) 1080b57cec5SDimitry Andric return false; 1090b57cec5SDimitry Andric 1100b57cec5SDimitry Andric // For the small model, all locally-binding symbols are in range. 1110b57cec5SDimitry Andric if (CM == CodeModel::Small) 1120b57cec5SDimitry Andric return TLInfo.getTargetMachine().shouldAssumeDSOLocal(*GV->getParent(), GV); 1130b57cec5SDimitry Andric 1140b57cec5SDimitry Andric // For Medium and above, assume that the symbol is not within the 4GB range. 1150b57cec5SDimitry Andric // Taking the address of locally-defined text would be OK, but that 1160b57cec5SDimitry Andric // case isn't easy to detect. 1170b57cec5SDimitry Andric return false; 1180b57cec5SDimitry Andric } 119