1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
//===-- SystemZSubtarget.cpp - SystemZ subtarget information --------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "SystemZSubtarget.h"
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/Target/TargetMachine.h"
using namespace llvm;
#define DEBUG_TYPE "systemz-subtarget"
#define GET_SUBTARGETINFO_TARGET_DESC
#define GET_SUBTARGETINFO_CTOR
#include "SystemZGenSubtargetInfo.inc"
static cl::opt<bool> UseSubRegLiveness(
"systemz-subreg-liveness",
cl::desc("Enable subregister liveness tracking for SystemZ (experimental)"),
cl::Hidden);
// Pin the vtable to this file.
void SystemZSubtarget::anchor() {}
SystemZSubtarget &SystemZSubtarget::initializeSubtargetDependencies(
StringRef CPU, StringRef TuneCPU, StringRef FS) {
if (CPU.empty())
CPU = "generic";
if (TuneCPU.empty())
TuneCPU = CPU;
// Parse features string.
ParseSubtargetFeatures(CPU, TuneCPU, FS);
// -msoft-float implies -mno-vx.
if (HasSoftFloat)
HasVector = false;
// -mno-vx implicitly disables all vector-related features.
if (!HasVector) {
HasVectorEnhancements1 = false;
HasVectorEnhancements2 = false;
HasVectorEnhancements3 = false;
HasVectorPackedDecimal = false;
HasVectorPackedDecimalEnhancement = false;
HasVectorPackedDecimalEnhancement2 = false;
HasVectorPackedDecimalEnhancement3 = false;
}
return *this;
}
SystemZCallingConventionRegisters *
SystemZSubtarget::initializeSpecialRegisters() {
if (isTargetXPLINK64())
return new SystemZXPLINK64Registers;
else if (isTargetELF())
return new SystemZELFRegisters;
llvm_unreachable("Invalid Calling Convention. Cannot initialize Special "
"Call Registers!");
}
SystemZSubtarget::SystemZSubtarget(const Triple &TT, const std::string &CPU,
const std::string &TuneCPU,
const std::string &FS,
const TargetMachine &TM)
: SystemZGenSubtargetInfo(TT, CPU, TuneCPU, FS), TargetTriple(TT),
SpecialRegisters(initializeSpecialRegisters()),
InstrInfo(initializeSubtargetDependencies(CPU, TuneCPU, FS)),
TLInfo(TM, *this), FrameLowering(SystemZFrameLowering::create(*this)) {}
bool SystemZSubtarget::enableSubRegLiveness() const {
return UseSubRegLiveness;
}
bool SystemZSubtarget::isAddressedViaADA(const GlobalValue *GV) const {
if (const auto *GO = dyn_cast<GlobalObject>(GV)) {
// A R/O variable is placed in code section. If the R/O variable has as
// least two byte alignment, then generated code can use relative
// instructions to address the variable. Otherwise, use the ADA to address
// the variable.
if (auto *GV = dyn_cast<GlobalVariable>(GO))
if (GV->getAlign() && (*GV->getAlign()).value() & 0x1)
return true;
// getKindForGlobal only works with definitions
if (GO->isDeclaration()) {
return true;
}
// check AvailableExternallyLinkage here as getKindForGlobal() asserts
if (GO->hasAvailableExternallyLinkage()) {
return true;
}
SectionKind GOKind = TargetLoweringObjectFile::getKindForGlobal(
GO, TLInfo.getTargetMachine());
if (!GOKind.isReadOnly()) {
return true;
}
return false; // R/O variable with multiple of 2 byte alignment
}
return true;
}
bool SystemZSubtarget::isPC32DBLSymbol(const GlobalValue *GV,
CodeModel::Model CM) const {
if (isTargetzOS())
return !isAddressedViaADA(GV);
// PC32DBL accesses require the low bit to be clear.
//
// FIXME: Explicitly check for functions: the datalayout is currently
// missing information about function pointers.
const DataLayout &DL = GV->getDataLayout();
if (GV->getPointerAlignment(DL) == 1 && !GV->getValueType()->isFunctionTy())
return false;
// For the small model, all locally-binding symbols are in range.
if (CM == CodeModel::Small)
return TLInfo.getTargetMachine().shouldAssumeDSOLocal(GV);
// For Medium and above, assume that the symbol is not within the 4GB range.
// Taking the address of locally-defined text would be OK, but that
// case isn't easy to detect.
return false;
}
|