xref: /freebsd/contrib/llvm-project/llvm/lib/Target/SystemZ/SystemZSubtarget.cpp (revision 81ad626541db97eb356e2c1d4a20eb2a26a766ab)
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 
30*81ad6265SDimitry Andric SystemZSubtarget &SystemZSubtarget::initializeSubtargetDependencies(
31*81ad6265SDimitry Andric     StringRef CPU, StringRef TuneCPU, StringRef FS) {
32*81ad6265SDimitry Andric   if (CPU.empty())
33*81ad6265SDimitry Andric     CPU = "generic";
34*81ad6265SDimitry Andric   if (TuneCPU.empty())
35*81ad6265SDimitry Andric     TuneCPU = CPU;
360b57cec5SDimitry Andric   // Parse features string.
37*81ad6265SDimitry Andric   ParseSubtargetFeatures(CPU, TuneCPU, FS);
385ffd83dbSDimitry Andric 
395ffd83dbSDimitry Andric   // -msoft-float implies -mno-vx.
405ffd83dbSDimitry Andric   if (HasSoftFloat)
415ffd83dbSDimitry Andric     HasVector = false;
425ffd83dbSDimitry Andric 
43e8d8bef9SDimitry Andric   // -mno-vx implicitly disables all vector-related features.
44e8d8bef9SDimitry Andric   if (!HasVector) {
45e8d8bef9SDimitry Andric     HasVectorEnhancements1 = false;
46e8d8bef9SDimitry Andric     HasVectorEnhancements2 = false;
47e8d8bef9SDimitry Andric     HasVectorPackedDecimal = false;
48e8d8bef9SDimitry Andric     HasVectorPackedDecimalEnhancement = false;
49fe6060f1SDimitry Andric     HasVectorPackedDecimalEnhancement2 = false;
50e8d8bef9SDimitry Andric   }
51e8d8bef9SDimitry Andric 
520b57cec5SDimitry Andric   return *this;
530b57cec5SDimitry Andric }
540b57cec5SDimitry Andric 
55fe6060f1SDimitry Andric SystemZCallingConventionRegisters *
56fe6060f1SDimitry Andric SystemZSubtarget::initializeSpecialRegisters() {
57fe6060f1SDimitry Andric   if (isTargetXPLINK64())
58fe6060f1SDimitry Andric     return new SystemZXPLINK64Registers;
59fe6060f1SDimitry Andric   else if (isTargetELF())
60fe6060f1SDimitry Andric     return new SystemZELFRegisters;
61fe6060f1SDimitry Andric   else {
62fe6060f1SDimitry Andric     llvm_unreachable("Invalid Calling Convention. Cannot initialize Special "
63fe6060f1SDimitry Andric                      "Call Registers!");
64fe6060f1SDimitry Andric   }
65fe6060f1SDimitry Andric }
66fe6060f1SDimitry Andric 
670b57cec5SDimitry Andric SystemZSubtarget::SystemZSubtarget(const Triple &TT, const std::string &CPU,
68*81ad6265SDimitry Andric                                    const std::string &TuneCPU,
690b57cec5SDimitry Andric                                    const std::string &FS,
700b57cec5SDimitry Andric                                    const TargetMachine &TM)
71*81ad6265SDimitry Andric     : SystemZGenSubtargetInfo(TT, CPU, TuneCPU, FS),
72e8d8bef9SDimitry Andric       HasDistinctOps(false), HasLoadStoreOnCond(false), HasHighWord(false),
73e8d8bef9SDimitry Andric       HasFPExtension(false), HasPopulationCount(false),
74e8d8bef9SDimitry Andric       HasMessageSecurityAssist3(false), HasMessageSecurityAssist4(false),
75e8d8bef9SDimitry Andric       HasResetReferenceBitsMultiple(false), HasFastSerialization(false),
76e8d8bef9SDimitry Andric       HasInterlockedAccess1(false), HasMiscellaneousExtensions(false),
770b57cec5SDimitry Andric       HasExecutionHint(false), HasLoadAndTrap(false),
780b57cec5SDimitry Andric       HasTransactionalExecution(false), HasProcessorAssist(false),
79fe6060f1SDimitry Andric       HasDFPZonedConversion(false), HasEnhancedDAT2(false), HasVector(false),
80fe6060f1SDimitry Andric       HasLoadStoreOnCond2(false), HasLoadAndZeroRightmostByte(false),
81fe6060f1SDimitry Andric       HasMessageSecurityAssist5(false), HasDFPPackedConversion(false),
820b57cec5SDimitry Andric       HasMiscellaneousExtensions2(false), HasGuardedStorage(false),
830b57cec5SDimitry Andric       HasMessageSecurityAssist7(false), HasMessageSecurityAssist8(false),
840b57cec5SDimitry Andric       HasVectorEnhancements1(false), HasVectorPackedDecimal(false),
85fe6060f1SDimitry Andric       HasInsertReferenceBitsMultiple(false), HasMiscellaneousExtensions3(false),
86fe6060f1SDimitry Andric       HasMessageSecurityAssist9(false), HasVectorEnhancements2(false),
87fe6060f1SDimitry Andric       HasVectorPackedDecimalEnhancement(false), HasEnhancedSort(false),
88fe6060f1SDimitry Andric       HasDeflateConversion(false), HasVectorPackedDecimalEnhancement2(false),
89fe6060f1SDimitry Andric       HasNNPAssist(false), HasBEAREnhancement(false),
90fe6060f1SDimitry Andric       HasResetDATProtection(false), HasProcessorActivityInstrumentation(false),
91fe6060f1SDimitry Andric       HasSoftFloat(false), TargetTriple(TT),
92fe6060f1SDimitry Andric       SpecialRegisters(initializeSpecialRegisters()),
93*81ad6265SDimitry Andric       InstrInfo(initializeSubtargetDependencies(CPU, TuneCPU, FS)),
94*81ad6265SDimitry Andric       TLInfo(TM, *this), FrameLowering(SystemZFrameLowering::create(*this)) {}
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