LLVM 24.0.0git
M68kSubtarget.cpp
Go to the documentation of this file.
1//===-- M68kSubtarget.cpp - M68k Subtarget Information ----------*- 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 implements the M68k specific subclass of TargetSubtargetInfo.
11///
12//===----------------------------------------------------------------------===//
13
14#include "M68kSubtarget.h"
18#include "M68k.h"
19#include "M68kMachineFunction.h"
20#include "M68kRegisterInfo.h"
22#include "M68kTargetMachine.h"
24#include "llvm/IR/Attributes.h"
25#include "llvm/IR/Function.h"
29
30using namespace llvm;
31
32#define DEBUG_TYPE "m68k-subtarget"
33
34#define GET_SUBTARGETINFO_TARGET_DESC
35#define GET_SUBTARGETINFO_CTOR
36#include "M68kGenSubtargetInfo.inc"
37
38#define OPTIONS_STRUCT_DEFS
39#include "M68kOptions.inc"
40
41/// Select the M68k CPU for the given triple and cpu name.
43 if (CPU.empty() || CPU == "generic") {
44 CPU = "M68000";
45 }
46 return CPU;
47}
48
49void M68kSubtarget::anchor() {}
50
52 const M68kTargetMachine &TM)
53 : M68kGenSubtargetInfo(TT, CPU, /*TuneCPU=*/CPU, FS),
54 CLOpts(TM.getCLOpts()), TM(TM),
56 FrameLowering(*this, this->getStackAlignment()), TLInfo(TM, *this),
57 TargetTriple(TT) {
58 TSInfo = std::make_unique<M68kSelectionDAGInfo>();
59
61 Legalizer.reset(new M68kLegalizerInfo(*this));
62
63 auto *RBI = new M68kRegisterBankInfo(*getRegisterInfo());
64 RegBankInfo.reset(RBI);
66}
67
69
73
75 return CallLoweringInfo.get();
76}
77
81
83 return Legalizer.get();
84}
85
87 return RegBankInfo.get();
88}
89
91 return TM.isPositionIndependent();
92}
93
94bool M68kSubtarget::isLegalToCallImmediateAddr() const { return true; }
95
97 StringRef CPU, Triple TT, StringRef FS, const M68kTargetMachine &TM) {
98 std::string CPUName = selectM68kCPU(TT, CPU).str();
99
100 // Parse features string.
101 ParseSubtargetFeatures(CPUName, CPUName, FS);
102
103 // Initialize scheduling itinerary for the specified CPU.
104 InstrItins = getInstrItineraryForCPU(CPUName);
105
106 stackAlignment = 8;
107
108 return *this;
109}
110
111//===----------------------------------------------------------------------===//
112// Code Model
113//
114// Key assumptions:
115// - Whenever possible we use pc-rel encoding since it is smaller(16 bit) than
116// absolute(32 bit).
117// - GOT is reachable within 16 bit offset for both Small and Medium models.
118// - Code section is reachable within 16 bit offset for both models.
119//
120// ---------------------+-------------------------+--------------------------
121// | Small | Medium
122// +-------------------------+------------+-------------
123// | Static | PIC | Static | PIC
124// ---------------------+------------+------------+------------+-------------
125// branch | pc-rel | pc-rel | pc-rel | pc-rel
126// ---------------------+------------+------------+------------+-------------
127// call global | absolute | @PLT | absolute | @PLT
128// ---------------------+------------+------------+------------+-------------
129// call internal | pc-rel | pc-rel | pc-rel | pc-rel
130// ---------------------+------------+------------+------------+-------------
131// data local | pc-rel | pc-rel | ~pc-rel | ^pc-rel
132// ---------------------+------------+------------+------------+-------------
133// data local big* | pc-rel | pc-rel | absolute | @GOTOFF
134// ---------------------+------------+------------+------------+-------------
135// data global | pc-rel | @GOTPCREL | ~pc-rel | @GOTPCREL
136// ---------------------+------------+------------+------------+-------------
137// data global big* | pc-rel | @GOTPCREL | absolute | @GOTPCREL
138// ---------------------+------------+------------+------------+-------------
139// | Large |
140// +-------------------------+
141// | Static | PIC |
142// ---------------------+------------+------------+
143// branch | absolute | pc-rel |
144// ---------------------+------------+------------+
145// call global | absolute | @PLT |
146// ---------------------+------------+------------+
147// call internal | absolute | pc-rel |
148// ---------------------+------------+------------+
149// data local | absolute | @GOTOFF |
150// ---------------------+------------+------------+
151// data local big* | absolute | @GOTOFF |
152// ---------------------+------------+------------+
153// data global | absolute | @GOTOFF |
154// ---------------------+------------+------------+
155// data global big* | absolute | @GOTOFF |
156// ---------------------+------------+------------+
157//
158// * Big data potentially cannot be reached within 16 bit offset and requires
159// special handling for old(x00 and x10) CPUs. Normally these symbols go into
160// separate .ldata section which mapped after normal .data and .text, but I
161// don't really know how this must be done for M68k atm... will try to dig
162// this info out from GCC. For now CPUs prior to M68020 will use static ref
163// for Static Model and @GOT based references for PIC.
164//
165// ~ These are absolute for older CPUs for now.
166// ^ These are @GOTOFF for older CPUs for now.
167//===----------------------------------------------------------------------===//
168
169/// Classify a blockaddress reference for the current subtarget according to how
170/// we should reference it in a non-pcrel context.
172 switch (TM.getCodeModel()) {
173 default:
174 llvm_unreachable("Unsupported code model");
175 case CodeModel::Small:
177 case CodeModel::Medium: {
179 }
180 case CodeModel::Large: {
181 if (isPositionIndependent()) {
183 } else {
185 }
186 }
187 }
188}
189
190unsigned char
192 switch (TM.getCodeModel()) {
193 default:
194 llvm_unreachable("Unsupported code model");
195 case CodeModel::Small:
196 case CodeModel::Kernel: {
198 }
199 case CodeModel::Medium: {
200 if (isPositionIndependent()) {
201 // On M68020 and better we can fit big any data offset into dips field.
202 if (atLeastM68020()) {
204 }
205 // Otherwise we could check the data size and make sure it will fit into
206 // 16 bit offset. For now we will be conservative and go with @GOTOFF
207 return M68kII::MO_GOTOFF;
208 } else {
209 if (atLeastM68020()) {
211 }
213 }
214 }
215 case CodeModel::Large: {
216 if (isPositionIndependent()) {
217 return M68kII::MO_GOTOFF;
218 } else {
220 }
221 }
222 }
223}
224
226 if (TM.shouldAssumeDSOLocal(nullptr))
227 return classifyLocalReference(nullptr);
228
230 return M68kII::MO_GOTPCREL;
231
232 return M68kII::MO_GOT;
233}
234
235unsigned char
239
241 const Module &M) const {
242 if (TM.shouldAssumeDSOLocal(GV))
243 return classifyLocalReference(GV);
244
245 switch (TM.getCodeModel()) {
246 default:
247 llvm_unreachable("Unsupported code model");
248 case CodeModel::Small:
249 case CodeModel::Kernel: {
251 return M68kII::MO_GOTPCREL;
253 }
254 case CodeModel::Medium: {
256 return M68kII::MO_GOTPCREL;
257
258 if (atLeastM68020())
260
262 }
263 case CodeModel::Large: {
265 return M68kII::MO_GOTOFF;
266
268 }
269 }
270}
271
273 if (isPositionIndependent()) {
274 // The only time we want to use GOTOFF(used when with EK_Custom32) is when
275 // the potential delta between the jump target and table base can be larger
276 // than displacement field, which is True for older CPUs(16 bit disp)
277 // in Medium model(can have large data way beyond 16 bit).
278 if ((TM.getCodeModel() == CodeModel::Medium && !atLeastM68020()) ||
279 TM.getCodeModel() == CodeModel::Large)
281
283 }
284
285 // In non-pic modes, just use the address of a block.
287}
288
289unsigned char
293
294unsigned char
296 const Module &M) const {
297 // local always use pc-rel referencing
298 if (TM.shouldAssumeDSOLocal(GV))
299 return M68kII::MO_NO_FLAG;
300
301 // If the function is marked as non-lazy, generate an indirect call
302 // which loads from the GOT directly. This avoids run-time overhead
303 // at the cost of eager binding.
304 auto *F = dyn_cast_or_null<Function>(GV);
305 if (F && F->hasFnAttribute(Attribute::NonLazyBind)) {
306 return M68kII::MO_GOTPCREL;
307 }
308
309 // Ensure that we don't emit PLT relocations when in non-pic modes.
311}
This file contains the simple types necessary to represent the attributes associated with functions a...
This file implements the lowering of LLVM calls to machine code calls for GlobalISel.
This file declares the targeting of the MachineLegalizer class for M68k.
This file declares the M68k specific subclass of MachineFunctionInfo.
This file declares the targeting of the RegisterBankInfo class for M68k.
This file contains the M68k implementation of the TargetRegisterInfo class.
static StringRef selectM68kCPU(Triple TT, StringRef CPU)
Select the M68k CPU for the given triple and cpu name.
This file declares the M68k specific subclass of TargetSubtargetInfo.
This file declares the M68k specific subclass of TargetMachine.
This file contains the entry points for global functions defined in the M68k target library,...
#define F(x, y, z)
Definition MD5.cpp:54
Module * getParent()
Get the module that this global value is contained inside of...
This class provides the information for the target register banks.
Align getStackAlignment() const
TODO this must be controlled by options like -malign-int and -mshort.
unsigned char classifyExternalReference(const Module &M) const
Classify a external variable reference for the current subtarget according to how we should reference...
InstrItineraryData InstrItins
const M68kTargetLowering * getTargetLowering() const override
M68kSubtarget(const Triple &TT, StringRef CPU, StringRef FS, const M68kTargetMachine &_TM)
This constructor initializes the data members to match that of the specified triple.
unsigned char classifyBlockAddressReference() const
Classify a blockaddress reference for the current subtarget according to how we should reference it i...
const LegalizerInfo * getLegalizerInfo() const override
M68kInstrInfo InstrInfo
std::unique_ptr< const SelectionDAGTargetInfo > TSInfo
const RegisterBankInfo * getRegBankInfo() const override
bool isLegalToCallImmediateAddr() const
Return true if the subtarget allows calls to immediate address.
std::unique_ptr< CallLowering > CallLoweringInfo
const SelectionDAGTargetInfo * getSelectionDAGInfo() const override
const M68kOptions & getCLOpts() const
void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS)
Parses features string setting specified subtarget options.
const M68kTargetMachine & TM
M68kTargetLowering TLInfo
unsigned char classifyGlobalReference(const GlobalValue *GV, const Module &M) const
Classify a global variable reference for the current subtarget according to how we should reference i...
const CallLowering * getCallLowering() const override
unsigned getJumpTableEncoding() const
InstructionSelector * getInstructionSelector() const override
~M68kSubtarget() override
std::unique_ptr< RegisterBankInfo > RegBankInfo
unsigned char classifyLocalReference(const GlobalValue *GV) const
Classify a global variable reference for the current subtarget according to how we should reference i...
unsigned stackAlignment
The minimum alignment known to hold of the stack frame on entry to the function and which must be mai...
const M68kRegisterInfo * getRegisterInfo() const override
std::unique_ptr< LegalizerInfo > Legalizer
bool atLeastM68020() const
bool isPositionIndependent() const
M68kSubtarget & initializeSubtargetDependencies(StringRef CPU, Triple TT, StringRef FS, const M68kTargetMachine &TM)
M68kFrameLowering FrameLowering
unsigned char classifyGlobalFunctionReference(const GlobalValue *GV, const Module &M) const
Classify a global function reference for the current subtarget.
std::unique_ptr< InstructionSelector > InstSelector
@ EK_LabelDifference32
EK_LabelDifference32 - Each entry is the address of the block minus the address of the jump table.
@ EK_Custom32
EK_Custom32 - Each entry is a 32-bit value that is custom lowered by the TargetLowering::LowerCustomJ...
@ EK_BlockAddress
EK_BlockAddress - Each entry is a plain address of block, e.g.: .word LBB123.
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
Holds all the information related to register banks.
Targets can subclass this to parameterize the SelectionDAG lowering and instruction selection process...
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
std::string str() const
Get the contents as an std::string.
Definition StringRef.h:222
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ MO_GOTOFF
On a symbol operand this indicates that the immediate is the offset to the location of the symbol nam...
@ MO_PLT
On a symbol operand this indicates that the immediate is offset to the PLT entry of symbol name from ...
@ MO_GOT
On a symbol operand this indicates that the immediate is the offset to the GOT entry for the symbol n...
@ MO_ABSOLUTE_ADDRESS
On a symbol operand this indicates that the immediate is the absolute address of the symbol.
@ MO_GOTPCREL
On a symbol operand this indicates that the immediate is offset to the GOT entry for the symbol name ...
@ MO_PC_RELATIVE_ADDRESS
On a symbol operand this indicates that the immediate is the pc-relative address of the symbol.
This is an optimization pass for GlobalISel generic memory operations.
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
InstructionSelector * createM68kInstructionSelector(const M68kTargetMachine &TM, const M68kSubtarget &Subtarget, const M68kRegisterBankInfo &RBI)