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" 11*06c3fb27SDimitry Andric #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 120b57cec5SDimitry Andric #include "llvm/IR/GlobalValue.h" 135ffd83dbSDimitry Andric #include "llvm/Target/TargetMachine.h" 140b57cec5SDimitry Andric 150b57cec5SDimitry Andric using namespace llvm; 160b57cec5SDimitry Andric 170b57cec5SDimitry Andric #define DEBUG_TYPE "systemz-subtarget" 180b57cec5SDimitry Andric 190b57cec5SDimitry Andric #define GET_SUBTARGETINFO_TARGET_DESC 200b57cec5SDimitry Andric #define GET_SUBTARGETINFO_CTOR 210b57cec5SDimitry Andric #include "SystemZGenSubtargetInfo.inc" 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric static cl::opt<bool> UseSubRegLiveness( 240b57cec5SDimitry Andric "systemz-subreg-liveness", 250b57cec5SDimitry Andric cl::desc("Enable subregister liveness tracking for SystemZ (experimental)"), 260b57cec5SDimitry Andric cl::Hidden); 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric // Pin the vtable to this file. 290b57cec5SDimitry Andric void SystemZSubtarget::anchor() {} 300b57cec5SDimitry Andric 3181ad6265SDimitry Andric SystemZSubtarget &SystemZSubtarget::initializeSubtargetDependencies( 3281ad6265SDimitry Andric StringRef CPU, StringRef TuneCPU, StringRef FS) { 3381ad6265SDimitry Andric if (CPU.empty()) 3481ad6265SDimitry Andric CPU = "generic"; 3581ad6265SDimitry Andric if (TuneCPU.empty()) 3681ad6265SDimitry Andric TuneCPU = CPU; 370b57cec5SDimitry Andric // Parse features string. 3881ad6265SDimitry Andric ParseSubtargetFeatures(CPU, TuneCPU, FS); 395ffd83dbSDimitry Andric 405ffd83dbSDimitry Andric // -msoft-float implies -mno-vx. 415ffd83dbSDimitry Andric if (HasSoftFloat) 425ffd83dbSDimitry Andric HasVector = false; 435ffd83dbSDimitry Andric 44e8d8bef9SDimitry Andric // -mno-vx implicitly disables all vector-related features. 45e8d8bef9SDimitry Andric if (!HasVector) { 46e8d8bef9SDimitry Andric HasVectorEnhancements1 = false; 47e8d8bef9SDimitry Andric HasVectorEnhancements2 = false; 48e8d8bef9SDimitry Andric HasVectorPackedDecimal = false; 49e8d8bef9SDimitry Andric HasVectorPackedDecimalEnhancement = false; 50fe6060f1SDimitry Andric HasVectorPackedDecimalEnhancement2 = false; 51e8d8bef9SDimitry Andric } 52e8d8bef9SDimitry Andric 530b57cec5SDimitry Andric return *this; 540b57cec5SDimitry Andric } 550b57cec5SDimitry Andric 56fe6060f1SDimitry Andric SystemZCallingConventionRegisters * 57fe6060f1SDimitry Andric SystemZSubtarget::initializeSpecialRegisters() { 58fe6060f1SDimitry Andric if (isTargetXPLINK64()) 59fe6060f1SDimitry Andric return new SystemZXPLINK64Registers; 60fe6060f1SDimitry Andric else if (isTargetELF()) 61fe6060f1SDimitry Andric return new SystemZELFRegisters; 62fe6060f1SDimitry Andric else { 63fe6060f1SDimitry Andric llvm_unreachable("Invalid Calling Convention. Cannot initialize Special " 64fe6060f1SDimitry Andric "Call Registers!"); 65fe6060f1SDimitry Andric } 66fe6060f1SDimitry Andric } 67fe6060f1SDimitry Andric 680b57cec5SDimitry Andric SystemZSubtarget::SystemZSubtarget(const Triple &TT, const std::string &CPU, 6981ad6265SDimitry Andric const std::string &TuneCPU, 700b57cec5SDimitry Andric const std::string &FS, 710b57cec5SDimitry Andric const TargetMachine &TM) 72bdd1243dSDimitry Andric : SystemZGenSubtargetInfo(TT, CPU, TuneCPU, FS), TargetTriple(TT), 73fe6060f1SDimitry Andric SpecialRegisters(initializeSpecialRegisters()), 7481ad6265SDimitry Andric InstrInfo(initializeSubtargetDependencies(CPU, TuneCPU, FS)), 7581ad6265SDimitry Andric TLInfo(TM, *this), FrameLowering(SystemZFrameLowering::create(*this)) {} 760b57cec5SDimitry Andric 770b57cec5SDimitry Andric bool SystemZSubtarget::enableSubRegLiveness() const { 780b57cec5SDimitry Andric return UseSubRegLiveness; 790b57cec5SDimitry Andric } 800b57cec5SDimitry Andric 81*06c3fb27SDimitry Andric bool SystemZSubtarget::isAddressedViaADA(const GlobalValue *GV) const { 82*06c3fb27SDimitry Andric if (const auto *GO = dyn_cast<GlobalObject>(GV)) { 83*06c3fb27SDimitry Andric // A R/O variable is placed in code section. If the R/O variable has as 84*06c3fb27SDimitry Andric // least two byte alignment, then generated code can use relative 85*06c3fb27SDimitry Andric // instructions to address the variable. Otherwise, use the ADA to address 86*06c3fb27SDimitry Andric // the variable. 87*06c3fb27SDimitry Andric if (GO->getAlignment() & 0x1) { 88*06c3fb27SDimitry Andric return true; 89*06c3fb27SDimitry Andric } 90*06c3fb27SDimitry Andric 91*06c3fb27SDimitry Andric // getKindForGlobal only works with definitions 92*06c3fb27SDimitry Andric if (GO->isDeclaration()) { 93*06c3fb27SDimitry Andric return true; 94*06c3fb27SDimitry Andric } 95*06c3fb27SDimitry Andric 96*06c3fb27SDimitry Andric // check AvailableExternallyLinkage here as getKindForGlobal() asserts 97*06c3fb27SDimitry Andric if (GO->hasAvailableExternallyLinkage()) { 98*06c3fb27SDimitry Andric return true; 99*06c3fb27SDimitry Andric } 100*06c3fb27SDimitry Andric 101*06c3fb27SDimitry Andric SectionKind GOKind = TargetLoweringObjectFile::getKindForGlobal( 102*06c3fb27SDimitry Andric GO, TLInfo.getTargetMachine()); 103*06c3fb27SDimitry Andric if (!GOKind.isReadOnly()) { 104*06c3fb27SDimitry Andric return true; 105*06c3fb27SDimitry Andric } 106*06c3fb27SDimitry Andric 107*06c3fb27SDimitry Andric return false; // R/O variable with multiple of 2 byte alignment 108*06c3fb27SDimitry Andric } 109*06c3fb27SDimitry Andric return true; 110*06c3fb27SDimitry Andric } 111*06c3fb27SDimitry Andric 1120b57cec5SDimitry Andric bool SystemZSubtarget::isPC32DBLSymbol(const GlobalValue *GV, 1130b57cec5SDimitry Andric CodeModel::Model CM) const { 114*06c3fb27SDimitry Andric if (isTargetzOS()) 115*06c3fb27SDimitry Andric return !isAddressedViaADA(GV); 116*06c3fb27SDimitry Andric 1175ffd83dbSDimitry Andric // PC32DBL accesses require the low bit to be clear. 1185ffd83dbSDimitry Andric // 1195ffd83dbSDimitry Andric // FIXME: Explicitly check for functions: the datalayout is currently 1205ffd83dbSDimitry Andric // missing information about function pointers. 1215ffd83dbSDimitry Andric const DataLayout &DL = GV->getParent()->getDataLayout(); 1225ffd83dbSDimitry Andric if (GV->getPointerAlignment(DL) == 1 && !GV->getValueType()->isFunctionTy()) 1230b57cec5SDimitry Andric return false; 1240b57cec5SDimitry Andric 1250b57cec5SDimitry Andric // For the small model, all locally-binding symbols are in range. 1260b57cec5SDimitry Andric if (CM == CodeModel::Small) 1270b57cec5SDimitry Andric return TLInfo.getTargetMachine().shouldAssumeDSOLocal(*GV->getParent(), GV); 1280b57cec5SDimitry Andric 1290b57cec5SDimitry Andric // For Medium and above, assume that the symbol is not within the 4GB range. 1300b57cec5SDimitry Andric // Taking the address of locally-defined text would be OK, but that 1310b57cec5SDimitry Andric // case isn't easy to detect. 1320b57cec5SDimitry Andric return false; 1330b57cec5SDimitry Andric } 134