Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/M68k/M68kTargetMachine.cpp
35266 views
1
//===-- M68kTargetMachine.cpp - M68k Target Machine -------------*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
///
9
/// \file
10
/// This file contains implementation for M68k target machine.
11
///
12
//===----------------------------------------------------------------------===//
13
14
#include "M68kTargetMachine.h"
15
#include "M68k.h"
16
#include "M68kMachineFunction.h"
17
#include "M68kSubtarget.h"
18
#include "M68kTargetObjectFile.h"
19
#include "TargetInfo/M68kTargetInfo.h"
20
#include "llvm/CodeGen/GlobalISel/IRTranslator.h"
21
#include "llvm/CodeGen/GlobalISel/InstructionSelect.h"
22
#include "llvm/CodeGen/GlobalISel/Legalizer.h"
23
#include "llvm/CodeGen/GlobalISel/RegBankSelect.h"
24
#include "llvm/CodeGen/Passes.h"
25
#include "llvm/CodeGen/TargetPassConfig.h"
26
#include "llvm/InitializePasses.h"
27
#include "llvm/MC/TargetRegistry.h"
28
#include "llvm/PassRegistry.h"
29
#include <memory>
30
#include <optional>
31
32
using namespace llvm;
33
34
#define DEBUG_TYPE "m68k"
35
36
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeM68kTarget() {
37
RegisterTargetMachine<M68kTargetMachine> X(getTheM68kTarget());
38
auto *PR = PassRegistry::getPassRegistry();
39
initializeGlobalISel(*PR);
40
initializeM68kDAGToDAGISelLegacyPass(*PR);
41
initializeM68kExpandPseudoPass(*PR);
42
initializeM68kGlobalBaseRegPass(*PR);
43
initializeM68kCollapseMOVEMPass(*PR);
44
}
45
46
namespace {
47
48
std::string computeDataLayout(const Triple &TT, StringRef CPU,
49
const TargetOptions &Options) {
50
std::string Ret = "";
51
// M68k is Big Endian
52
Ret += "E";
53
54
// FIXME how to wire it with the used object format?
55
Ret += "-m:e";
56
57
// M68k pointers are always 32 bit wide even for 16-bit CPUs.
58
// The ABI only specifies 16-bit alignment.
59
// On at least the 68020+ with a 32-bit bus, there is a performance benefit
60
// to having 32-bit alignment.
61
Ret += "-p:32:16:32";
62
63
// Bytes do not require special alignment, words are word aligned and
64
// long words are word aligned at minimum.
65
Ret += "-i8:8:8-i16:16:16-i32:16:32";
66
67
// FIXME no floats at the moment
68
69
// The registers can hold 8, 16, 32 bits
70
Ret += "-n8:16:32";
71
72
Ret += "-a:0:16-S16";
73
74
return Ret;
75
}
76
77
Reloc::Model getEffectiveRelocModel(const Triple &TT,
78
std::optional<Reloc::Model> RM) {
79
// If not defined we default to static
80
if (!RM.has_value())
81
return Reloc::Static;
82
83
return *RM;
84
}
85
86
CodeModel::Model getEffectiveCodeModel(std::optional<CodeModel::Model> CM,
87
bool JIT) {
88
if (!CM) {
89
return CodeModel::Small;
90
} else if (CM == CodeModel::Large) {
91
llvm_unreachable("Large code model is not supported");
92
} else if (CM == CodeModel::Kernel) {
93
llvm_unreachable("Kernel code model is not implemented yet");
94
}
95
return CM.value();
96
}
97
} // end anonymous namespace
98
99
M68kTargetMachine::M68kTargetMachine(const Target &T, const Triple &TT,
100
StringRef CPU, StringRef FS,
101
const TargetOptions &Options,
102
std::optional<Reloc::Model> RM,
103
std::optional<CodeModel::Model> CM,
104
CodeGenOptLevel OL, bool JIT)
105
: LLVMTargetMachine(T, computeDataLayout(TT, CPU, Options), TT, CPU, FS,
106
Options, getEffectiveRelocModel(TT, RM),
107
::getEffectiveCodeModel(CM, JIT), OL),
108
TLOF(std::make_unique<M68kELFTargetObjectFile>()),
109
Subtarget(TT, CPU, FS, *this) {
110
initAsmInfo();
111
}
112
113
M68kTargetMachine::~M68kTargetMachine() {}
114
115
const M68kSubtarget *
116
M68kTargetMachine::getSubtargetImpl(const Function &F) const {
117
Attribute CPUAttr = F.getFnAttribute("target-cpu");
118
Attribute FSAttr = F.getFnAttribute("target-features");
119
120
auto CPU = CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU;
121
auto FS = FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;
122
123
auto &I = SubtargetMap[CPU + FS];
124
if (!I) {
125
// This needs to be done before we create a new subtarget since any
126
// creation will depend on the TM and the code generation flags on the
127
// function that reside in TargetOptions.
128
resetTargetOptions(F);
129
I = std::make_unique<M68kSubtarget>(TargetTriple, CPU, FS, *this);
130
}
131
return I.get();
132
}
133
134
MachineFunctionInfo *M68kTargetMachine::createMachineFunctionInfo(
135
BumpPtrAllocator &Allocator, const Function &F,
136
const TargetSubtargetInfo *STI) const {
137
return M68kMachineFunctionInfo::create<M68kMachineFunctionInfo>(Allocator, F,
138
STI);
139
}
140
141
//===----------------------------------------------------------------------===//
142
// Pass Pipeline Configuration
143
//===----------------------------------------------------------------------===//
144
145
namespace {
146
class M68kPassConfig : public TargetPassConfig {
147
public:
148
M68kPassConfig(M68kTargetMachine &TM, PassManagerBase &PM)
149
: TargetPassConfig(TM, PM) {}
150
151
M68kTargetMachine &getM68kTargetMachine() const {
152
return getTM<M68kTargetMachine>();
153
}
154
155
const M68kSubtarget &getM68kSubtarget() const {
156
return *getM68kTargetMachine().getSubtargetImpl();
157
}
158
void addIRPasses() override;
159
bool addIRTranslator() override;
160
bool addLegalizeMachineIR() override;
161
bool addRegBankSelect() override;
162
bool addGlobalInstructionSelect() override;
163
bool addInstSelector() override;
164
void addPreSched2() override;
165
void addPreEmitPass() override;
166
};
167
} // namespace
168
169
TargetPassConfig *M68kTargetMachine::createPassConfig(PassManagerBase &PM) {
170
return new M68kPassConfig(*this, PM);
171
}
172
173
void M68kPassConfig::addIRPasses() {
174
addPass(createAtomicExpandLegacyPass());
175
TargetPassConfig::addIRPasses();
176
}
177
178
bool M68kPassConfig::addInstSelector() {
179
// Install an instruction selector.
180
addPass(createM68kISelDag(getM68kTargetMachine()));
181
addPass(createM68kGlobalBaseRegPass());
182
return false;
183
}
184
185
bool M68kPassConfig::addIRTranslator() {
186
addPass(new IRTranslator());
187
return false;
188
}
189
190
bool M68kPassConfig::addLegalizeMachineIR() {
191
addPass(new Legalizer());
192
return false;
193
}
194
195
bool M68kPassConfig::addRegBankSelect() {
196
addPass(new RegBankSelect());
197
return false;
198
}
199
200
bool M68kPassConfig::addGlobalInstructionSelect() {
201
addPass(new InstructionSelect());
202
return false;
203
}
204
205
void M68kPassConfig::addPreSched2() { addPass(createM68kExpandPseudoPass()); }
206
207
void M68kPassConfig::addPreEmitPass() {
208
addPass(createM68kCollapseMOVEMPass());
209
}
210
211