LLVM  14.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"
15 #include "GlSel/M68kCallLowering.h"
18 
19 #include "M68k.h"
20 #include "M68kMachineFunction.h"
21 #include "M68kRegisterInfo.h"
22 #include "M68kTargetMachine.h"
23 
25 #include "llvm/IR/Attributes.h"
26 #include "llvm/IR/Function.h"
30 
31 using namespace llvm;
32 
33 #define DEBUG_TYPE "m68k-subtarget"
34 
35 #define GET_SUBTARGETINFO_TARGET_DESC
36 #define GET_SUBTARGETINFO_CTOR
37 #include "M68kGenSubtargetInfo.inc"
38 
39 extern bool FixGlobalBaseReg;
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 
49 void M68kSubtarget::anchor() {}
50 
52  const M68kTargetMachine &TM)
53  : M68kGenSubtargetInfo(TT, CPU, /*TuneCPU*/ CPU, FS),
54  UserReservedRegister(M68k::NUM_TARGET_REGS), TM(TM), TSInfo(),
55  InstrInfo(initializeSubtargetDependencies(CPU, TT, FS, TM)),
56  FrameLowering(*this, this->getStackAlignment()), TLInfo(TM, *this),
57  TargetTriple(TT) {
59  Legalizer.reset(new M68kLegalizerInfo(*this));
60 
61  auto *RBI = new M68kRegisterBankInfo(*getRegisterInfo());
62  RegBankInfo.reset(RBI);
63  InstSelector.reset(createM68kInstructionSelector(TM, *this, *RBI));
64 }
65 
67  return CallLoweringInfo.get();
68 }
69 
71  return InstSelector.get();
72 }
73 
75  return Legalizer.get();
76 }
77 
79  return RegBankInfo.get();
80 }
81 
83  return TM.isPositionIndependent();
84 }
85 
86 bool M68kSubtarget::isLegalToCallImmediateAddr() const { return true; }
87 
88 bool M68kSubtarget::abiUsesSoftFloat() const { return true; }
89 
91  StringRef CPU, Triple TT, StringRef FS, const M68kTargetMachine &TM) {
92  std::string CPUName = selectM68kCPU(TT, CPU).str();
93 
94  // Parse features string.
95  ParseSubtargetFeatures(CPUName, CPUName, FS);
96 
97  // Initialize scheduling itinerary for the specified CPU.
98  InstrItins = getInstrItineraryForCPU(CPUName);
99 
100  stackAlignment = 8;
101 
102  return *this;
103 }
104 
105 //===----------------------------------------------------------------------===//
106 // Code Model
107 //
108 // Key assumptions:
109 // - Whenever possible we use pc-rel encoding since it is smaller(16 bit) than
110 // absolute(32 bit).
111 // - GOT is reachable within 16 bit offset for both Small and Medium models.
112 // - Code section is reachable within 16 bit offset for both models.
113 //
114 // ---------------------+-------------------------+--------------------------
115 // | Small | Medium
116 // +-------------------------+------------+-------------
117 // | Static | PIC | Static | PIC
118 // ---------------------+------------+------------+------------+-------------
119 // branch | pc-rel | pc-rel | pc-rel | pc-rel
120 // ---------------------+------------+------------+------------+-------------
121 // call global | @PLT | @PLT | @PLT | @PLT
122 // ---------------------+------------+------------+------------+-------------
123 // call internal | pc-rel | pc-rel | pc-rel | pc-rel
124 // ---------------------+------------+------------+------------+-------------
125 // data local | pc-rel | pc-rel | ~pc-rel | ^pc-rel
126 // ---------------------+------------+------------+------------+-------------
127 // data local big* | pc-rel | pc-rel | absolute | @GOTOFF
128 // ---------------------+------------+------------+------------+-------------
129 // data global | pc-rel | @GOTPCREL | ~pc-rel | @GOTPCREL
130 // ---------------------+------------+------------+------------+-------------
131 // data global big* | pc-rel | @GOTPCREL | absolute | @GOTPCREL
132 // ---------------------+------------+------------+------------+-------------
133 //
134 // * Big data potentially cannot be reached within 16 bit offset and requires
135 // special handling for old(x00 and x10) CPUs. Normally these symbols go into
136 // separate .ldata section which mapped after normal .data and .text, but I
137 // don't really know how this must be done for M68k atm... will try to dig
138 // this info out from GCC. For now CPUs prior to M68020 will use static ref
139 // for Static Model and @GOT based references for PIC.
140 //
141 // ~ These are absolute for older CPUs for now.
142 // ^ These are @GOTOFF for older CPUs for now.
143 //===----------------------------------------------------------------------===//
144 
145 /// Classify a blockaddress reference for the current subtarget according to how
146 /// we should reference it in a non-pcrel context.
148  // Unless we start to support Large Code Model branching is always pc-rel
150 }
151 
152 unsigned char
154  switch (TM.getCodeModel()) {
155  default:
156  llvm_unreachable("Unsupported code model");
157  case CodeModel::Small:
158  case CodeModel::Kernel: {
160  }
161  case CodeModel::Medium: {
162  if (isPositionIndependent()) {
163  // On M68020 and better we can fit big any data offset into dips field.
164  if (atLeastM68020()) {
166  }
167  // Otherwise we could check the data size and make sure it will fit into
168  // 16 bit offset. For now we will be conservative and go with @GOTOFF
169  return M68kII::MO_GOTOFF;
170  } else {
171  if (atLeastM68020()) {
173  }
175  }
176  }
177  }
178 }
179 
180 unsigned char M68kSubtarget::classifyExternalReference(const Module &M) const {
181  if (TM.shouldAssumeDSOLocal(M, nullptr))
182  return classifyLocalReference(nullptr);
183 
184  if (isPositionIndependent())
185  return M68kII::MO_GOTPCREL;
186 
187  return M68kII::MO_GOT;
188 }
189 
190 unsigned char
192  return classifyGlobalReference(GV, *GV->getParent());
193 }
194 
196  const Module &M) const {
197  if (TM.shouldAssumeDSOLocal(M, GV))
198  return classifyLocalReference(GV);
199 
200  switch (TM.getCodeModel()) {
201  default:
202  llvm_unreachable("Unsupported code model");
203  case CodeModel::Small:
204  case CodeModel::Kernel: {
205  if (isPositionIndependent())
206  return M68kII::MO_GOTPCREL;
208  }
209  case CodeModel::Medium: {
210  if (isPositionIndependent())
211  return M68kII::MO_GOTPCREL;
212 
213  if (atLeastM68020())
215 
217  }
218  }
219 }
220 
222  if (isPositionIndependent()) {
223  // The only time we want to use GOTOFF(used when with EK_Custom32) is when
224  // the potential delta between the jump target and table base can be larger
225  // than displacement field, which is True for older CPUs(16 bit disp)
226  // in Medium model(can have large data way beyond 16 bit).
229 
231  }
232 
233  // In non-pic modes, just use the address of a block.
235 }
236 
237 unsigned char
239  return classifyGlobalFunctionReference(GV, *GV->getParent());
240 }
241 
242 unsigned char
244  const Module &M) const {
245  // local always use pc-rel referencing
246  if (TM.shouldAssumeDSOLocal(M, GV))
247  return M68kII::MO_NO_FLAG;
248 
249  // If the function is marked as non-lazy, generate an indirect call
250  // which loads from the GOT directly. This avoids run-time overhead
251  // at the cost of eager binding.
252  auto *F = dyn_cast_or_null<Function>(GV);
253  if (F && F->hasFnAttribute(Attribute::NonLazyBind)) {
254  return M68kII::MO_GOTPCREL;
255  }
256 
257  // otherwise linker will figure this out
258  return M68kII::MO_PLT;
259 }
llvm::M68kSubtarget::isPositionIndependent
bool isPositionIndependent() const
Definition: M68kSubtarget.cpp:82
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
llvm::M68kTargetMachine
Definition: M68kTargetMachine.h:29
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::StringRef::empty
LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:153
M68kTargetMachine.h
llvm::M68kSubtarget::abiUsesSoftFloat
bool abiUsesSoftFloat() const
Definition: M68kSubtarget.cpp:88
llvm::CodeModel::Medium
@ Medium
Definition: CodeGen.h:28
ErrorHandling.h
llvm::Triple
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:45
llvm::M68kSubtarget::getRegBankInfo
const RegisterBankInfo * getRegBankInfo() const override
Definition: M68kSubtarget.cpp:78
MachineJumpTableInfo.h
llvm::M68kII::MO_PLT
@ MO_PLT
On a symbol operand this indicates that the immediate is offset to the PLT entry of symbol name from ...
Definition: M68kBaseInfo.h:114
llvm::MachineJumpTableInfo::EK_BlockAddress
@ EK_BlockAddress
EK_BlockAddress - Each entry is a plain address of block, e.g.
Definition: MachineJumpTableInfo.h:49
llvm::M68kII::MO_GOT
@ MO_GOT
On a symbol operand this indicates that the immediate is the offset to the GOT entry for the symbol n...
Definition: M68kBaseInfo.h:96
llvm::M68kSubtarget::getTargetLowering
const M68kTargetLowering * getTargetLowering() const override
Definition: M68kSubtarget.h:159
llvm::M68kSubtarget::getRegisterInfo
const M68kRegisterInfo * getRegisterInfo() const override
Definition: M68kSubtarget.h:155
llvm::CodeModel::Kernel
@ Kernel
Definition: CodeGen.h:28
llvm::M68kII::MO_PC_RELATIVE_ADDRESS
@ MO_PC_RELATIVE_ADDRESS
On a symbol operand this indicates that the immediate is the pc-relative address of the symbol.
Definition: M68kBaseInfo.h:90
llvm::MachineJumpTableInfo::EK_Custom32
@ EK_Custom32
EK_Custom32 - Each entry is a 32-bit value that is custom lowered by the TargetLowering::LowerCustomJ...
Definition: MachineJumpTableInfo.h:76
F
#define F(x, y, z)
Definition: MD5.cpp:56
M68k.h
CommandLine.h
llvm::M68kSubtarget::getCallLowering
const CallLowering * getCallLowering() const override
Definition: M68kSubtarget.cpp:66
llvm::M68kSubtarget::classifyBlockAddressReference
unsigned char classifyBlockAddressReference() const
Classify a blockaddress reference for the current subtarget according to how we should reference it i...
Definition: M68kSubtarget.cpp:147
llvm::M68kII::MO_GOTOFF
@ MO_GOTOFF
On a symbol operand this indicates that the immediate is the offset to the location of the symbol nam...
Definition: M68kBaseInfo.h:102
llvm::Legalizer
Definition: Legalizer.h:31
llvm::M68kSubtarget::RegBankInfo
std::unique_ptr< RegisterBankInfo > RegBankInfo
Definition: M68kSubtarget.h:172
llvm::CodeModel::Small
@ Small
Definition: CodeGen.h:28
llvm::StringRef::str
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:245
llvm::MachineJumpTableInfo::EK_LabelDifference32
@ EK_LabelDifference32
EK_LabelDifference32 - Each entry is the address of the block minus the address of the jump table.
Definition: MachineJumpTableInfo.h:68
llvm::TargetMachine::isPositionIndependent
bool isPositionIndependent() const
Definition: TargetMachine.cpp:44
llvm::M68kSubtarget
Definition: M68kSubtarget.h:45
M68kRegisterBankInfo.h
FixGlobalBaseReg
bool FixGlobalBaseReg
llvm::RegisterBankInfo
Holds all the information related to register banks.
Definition: RegisterBankInfo.h:39
llvm::GlobalValue
Definition: GlobalValue.h:44
llvm::InstructionSelector
Provides the logic to select generic machine instructions.
Definition: InstructionSelector.h:423
llvm::M68kSubtarget::TM
const M68kTargetMachine & TM
Definition: M68kSubtarget.h:62
llvm::GlobalValue::getParent
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:572
llvm::M68kSubtarget::stackAlignment
unsigned stackAlignment
The minimum alignment known to hold of the stack frame on entry to the function and which must be mai...
Definition: M68kSubtarget.h:71
llvm::M68kRegisterBankInfo
This class provides the information for the target register banks.
Definition: M68kRegisterBankInfo.h:34
llvm::M68kSubtarget::InstSelector
std::unique_ptr< InstructionSelector > InstSelector
Definition: M68kSubtarget.h:170
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
llvm::M68kII::MO_ABSOLUTE_ADDRESS
@ MO_ABSOLUTE_ADDRESS
On a symbol operand this indicates that the immediate is the absolute address of the symbol.
Definition: M68kBaseInfo.h:86
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
this
Analysis the ScalarEvolution expression for r is this
Definition: README.txt:8
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:136
llvm::M68kSubtarget::getLegalizerInfo
const LegalizerInfo * getLegalizerInfo() const override
Definition: M68kSubtarget.cpp:74
llvm::TargetMachine::shouldAssumeDSOLocal
bool shouldAssumeDSOLocal(const Module &M, const GlobalValue *GV) const
Definition: TargetMachine.cpp:94
llvm::M68kSubtarget::classifyGlobalFunctionReference
unsigned char classifyGlobalFunctionReference(const GlobalValue *GV, const Module &M) const
Classify a global function reference for the current subtarget.
Definition: M68kSubtarget.cpp:243
llvm::M68kSubtarget::M68kSubtarget
M68kSubtarget(const Triple &TT, StringRef CPU, StringRef FS, const M68kTargetMachine &_TM)
This constructor initializes the data members to match that of the specified triple.
Definition: M68kSubtarget.cpp:51
Attributes.h
llvm::M68kSubtarget::classifyLocalReference
unsigned char classifyLocalReference(const GlobalValue *GV) const
Classify a global variable reference for the current subtarget according to how we should reference i...
Definition: M68kSubtarget.cpp:153
selectM68kCPU
static StringRef selectM68kCPU(Triple TT, StringRef CPU)
Select the M68k CPU for the given triple and cpu name.
Definition: M68kSubtarget.cpp:42
llvm::X86AS::FS
@ FS
Definition: X86.h:188
llvm::M68kSubtarget::isLegalToCallImmediateAddr
bool isLegalToCallImmediateAddr() const
Return true if the subtarget allows calls to immediate address.
Definition: M68kSubtarget.cpp:86
Function.h
M68kMachineFunction.h
llvm::TargetMachine::getCodeModel
CodeModel::Model getCodeModel() const
Returns the code model.
Definition: TargetMachine.cpp:74
llvm::M68kCallLowering
Definition: M68kCallLowering.h:26
llvm::M68kLegalizerInfo
This struct provides the information for the target register banks.
Definition: M68kLegalizerInfo.h:24
llvm::M68kSubtarget::getInstructionSelector
InstructionSelector * getInstructionSelector() const override
Definition: M68kSubtarget.cpp:70
llvm::M68kSubtarget::getJumpTableEncoding
unsigned getJumpTableEncoding() const
Definition: M68kSubtarget.cpp:221
M68kSubtarget.h
M68kRegisterInfo.h
M68kLegalizerInfo.h
llvm::createM68kInstructionSelector
InstructionSelector * createM68kInstructionSelector(const M68kTargetMachine &TM, const M68kSubtarget &Subtarget, const M68kRegisterBankInfo &RBI)
Definition: M68kInstructionSelector.cpp:85
llvm::M68kII::MO_GOTPCREL
@ MO_GOTPCREL
On a symbol operand this indicates that the immediate is offset to the GOT entry for the symbol name ...
Definition: M68kBaseInfo.h:108
llvm::M68kII::MO_NO_FLAG
@ MO_NO_FLAG
Definition: M68kBaseInfo.h:82
llvm::LegalizerInfo
Definition: LegalizerInfo.h:1110
TM
const char LLVMTargetMachineRef TM
Definition: PassBuilderBindings.cpp:47
llvm::M68kSubtarget::ParseSubtargetFeatures
void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS)
Parses features string setting specified subtarget options.
llvm::M68kSubtarget::initializeSubtargetDependencies
M68kSubtarget & initializeSubtargetDependencies(StringRef CPU, Triple TT, StringRef FS, const M68kTargetMachine &TM)
Definition: M68kSubtarget.cpp:90
llvm::M68kSubtarget::CallLoweringInfo
std::unique_ptr< CallLowering > CallLoweringInfo
Definition: M68kSubtarget.h:169
M68kCallLowering.h
llvm::M68kSubtarget::atLeastM68020
bool atLeastM68020() const
Definition: M68kSubtarget.h:87
TargetRegistry.h
llvm::CallLowering
Definition: CallLowering.h:43
llvm::M68kSubtarget::classifyExternalReference
unsigned char classifyExternalReference(const Module &M) const
Classify a external variable reference for the current subtarget according to how we should reference...
Definition: M68kSubtarget.cpp:180
M68kGenSubtargetInfo
llvm::M68kSubtarget::InstrItins
InstrItineraryData InstrItins
Definition: M68kSubtarget.h:57
llvm::M68kSubtarget::classifyGlobalReference
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...
Definition: M68kSubtarget.cpp:195