LLVM  16.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 "GISel/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"
27 #include "llvm/MC/TargetRegistry.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), TM(TM), TSInfo(),
54  InstrInfo(initializeSubtargetDependencies(CPU, TT, FS, TM)),
55  FrameLowering(*this, this->getStackAlignment()), TLInfo(TM, *this),
56  TargetTriple(TT) {
58  Legalizer.reset(new M68kLegalizerInfo(*this));
59 
60  auto *RBI = new M68kRegisterBankInfo(*getRegisterInfo());
61  RegBankInfo.reset(RBI);
62  InstSelector.reset(createM68kInstructionSelector(TM, *this, *RBI));
63 }
64 
66  return CallLoweringInfo.get();
67 }
68 
70  return InstSelector.get();
71 }
72 
74  return Legalizer.get();
75 }
76 
78  return RegBankInfo.get();
79 }
80 
82  return TM.isPositionIndependent();
83 }
84 
85 bool M68kSubtarget::isLegalToCallImmediateAddr() const { return true; }
86 
87 bool M68kSubtarget::abiUsesSoftFloat() const { return true; }
88 
90  StringRef CPU, Triple TT, StringRef FS, const M68kTargetMachine &TM) {
91  std::string CPUName = selectM68kCPU(TT, CPU).str();
92 
93  // Parse features string.
94  ParseSubtargetFeatures(CPUName, CPUName, FS);
95 
96  // Initialize scheduling itinerary for the specified CPU.
97  InstrItins = getInstrItineraryForCPU(CPUName);
98 
99  stackAlignment = 8;
100 
101  return *this;
102 }
103 
104 //===----------------------------------------------------------------------===//
105 // Code Model
106 //
107 // Key assumptions:
108 // - Whenever possible we use pc-rel encoding since it is smaller(16 bit) than
109 // absolute(32 bit).
110 // - GOT is reachable within 16 bit offset for both Small and Medium models.
111 // - Code section is reachable within 16 bit offset for both models.
112 //
113 // ---------------------+-------------------------+--------------------------
114 // | Small | Medium
115 // +-------------------------+------------+-------------
116 // | Static | PIC | Static | PIC
117 // ---------------------+------------+------------+------------+-------------
118 // branch | pc-rel | pc-rel | pc-rel | pc-rel
119 // ---------------------+------------+------------+------------+-------------
120 // call global | @PLT | @PLT | @PLT | @PLT
121 // ---------------------+------------+------------+------------+-------------
122 // call internal | pc-rel | pc-rel | pc-rel | pc-rel
123 // ---------------------+------------+------------+------------+-------------
124 // data local | pc-rel | pc-rel | ~pc-rel | ^pc-rel
125 // ---------------------+------------+------------+------------+-------------
126 // data local big* | pc-rel | pc-rel | absolute | @GOTOFF
127 // ---------------------+------------+------------+------------+-------------
128 // data global | pc-rel | @GOTPCREL | ~pc-rel | @GOTPCREL
129 // ---------------------+------------+------------+------------+-------------
130 // data global big* | pc-rel | @GOTPCREL | absolute | @GOTPCREL
131 // ---------------------+------------+------------+------------+-------------
132 //
133 // * Big data potentially cannot be reached within 16 bit offset and requires
134 // special handling for old(x00 and x10) CPUs. Normally these symbols go into
135 // separate .ldata section which mapped after normal .data and .text, but I
136 // don't really know how this must be done for M68k atm... will try to dig
137 // this info out from GCC. For now CPUs prior to M68020 will use static ref
138 // for Static Model and @GOT based references for PIC.
139 //
140 // ~ These are absolute for older CPUs for now.
141 // ^ These are @GOTOFF for older CPUs for now.
142 //===----------------------------------------------------------------------===//
143 
144 /// Classify a blockaddress reference for the current subtarget according to how
145 /// we should reference it in a non-pcrel context.
147  // Unless we start to support Large Code Model branching is always pc-rel
149 }
150 
151 unsigned char
153  switch (TM.getCodeModel()) {
154  default:
155  llvm_unreachable("Unsupported code model");
156  case CodeModel::Small:
157  case CodeModel::Kernel: {
159  }
160  case CodeModel::Medium: {
161  if (isPositionIndependent()) {
162  // On M68020 and better we can fit big any data offset into dips field.
163  if (atLeastM68020()) {
165  }
166  // Otherwise we could check the data size and make sure it will fit into
167  // 16 bit offset. For now we will be conservative and go with @GOTOFF
168  return M68kII::MO_GOTOFF;
169  } else {
170  if (atLeastM68020()) {
172  }
174  }
175  }
176  }
177 }
178 
179 unsigned char M68kSubtarget::classifyExternalReference(const Module &M) const {
180  if (TM.shouldAssumeDSOLocal(M, nullptr))
181  return classifyLocalReference(nullptr);
182 
183  if (isPositionIndependent())
184  return M68kII::MO_GOTPCREL;
185 
186  return M68kII::MO_GOT;
187 }
188 
189 unsigned char
191  return classifyGlobalReference(GV, *GV->getParent());
192 }
193 
195  const Module &M) const {
196  if (TM.shouldAssumeDSOLocal(M, GV))
197  return classifyLocalReference(GV);
198 
199  switch (TM.getCodeModel()) {
200  default:
201  llvm_unreachable("Unsupported code model");
202  case CodeModel::Small:
203  case CodeModel::Kernel: {
204  if (isPositionIndependent())
205  return M68kII::MO_GOTPCREL;
207  }
208  case CodeModel::Medium: {
209  if (isPositionIndependent())
210  return M68kII::MO_GOTPCREL;
211 
212  if (atLeastM68020())
214 
216  }
217  }
218 }
219 
221  if (isPositionIndependent()) {
222  // The only time we want to use GOTOFF(used when with EK_Custom32) is when
223  // the potential delta between the jump target and table base can be larger
224  // than displacement field, which is True for older CPUs(16 bit disp)
225  // in Medium model(can have large data way beyond 16 bit).
228 
230  }
231 
232  // In non-pic modes, just use the address of a block.
234 }
235 
236 unsigned char
238  return classifyGlobalFunctionReference(GV, *GV->getParent());
239 }
240 
241 unsigned char
243  const Module &M) const {
244  // local always use pc-rel referencing
245  if (TM.shouldAssumeDSOLocal(M, GV))
246  return M68kII::MO_NO_FLAG;
247 
248  // If the function is marked as non-lazy, generate an indirect call
249  // which loads from the GOT directly. This avoids run-time overhead
250  // at the cost of eager binding.
251  auto *F = dyn_cast_or_null<Function>(GV);
252  if (F && F->hasFnAttribute(Attribute::NonLazyBind)) {
253  return M68kII::MO_GOTPCREL;
254  }
255 
256  // otherwise linker will figure this out
257  return M68kII::MO_PLT;
258 }
llvm::M68kSubtarget::isPositionIndependent
bool isPositionIndependent() const
Definition: M68kSubtarget.cpp:81
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
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
M68kTargetMachine.h
llvm::M68kSubtarget::abiUsesSoftFloat
bool abiUsesSoftFloat() const
Definition: M68kSubtarget.cpp:87
llvm::CodeModel::Medium
@ Medium
Definition: CodeGen.h:28
ErrorHandling.h
llvm::Triple
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
llvm::M68kSubtarget::getRegBankInfo
const RegisterBankInfo * getRegBankInfo() const override
Definition: M68kSubtarget.cpp:77
llvm::X86AS::FS
@ FS
Definition: X86.h:200
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:158
llvm::M68kSubtarget::getRegisterInfo
const M68kRegisterInfo * getRegisterInfo() const override
Definition: M68kSubtarget.h:154
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:55
M68k.h
CommandLine.h
llvm::M68kSubtarget::getCallLowering
const CallLowering * getCallLowering() const override
Definition: M68kSubtarget.cpp:65
InstrInfo
return InstrInfo
Definition: RISCVInsertVSETVLI.cpp:850
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:146
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:36
llvm::M68kSubtarget::RegBankInfo
std::unique_ptr< RegisterBankInfo > RegBankInfo
Definition: M68kSubtarget.h:171
llvm::CodeModel::Small
@ Small
Definition: CodeGen.h:28
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:41
llvm::M68kSubtarget
Definition: M68kSubtarget.h:44
M68kRegisterBankInfo.h
llvm::StringRef::empty
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:134
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:428
llvm::M68kSubtarget::TM
const M68kTargetMachine & TM
Definition: M68kSubtarget.h:61
llvm::GlobalValue::getParent
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:650
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:70
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:169
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
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:50
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:143
llvm::M68kSubtarget::getLegalizerInfo
const LegalizerInfo * getLegalizerInfo() const override
Definition: M68kSubtarget.cpp:73
llvm::TargetMachine::shouldAssumeDSOLocal
bool shouldAssumeDSOLocal(const Module &M, const GlobalValue *GV) const
Definition: TargetMachine.cpp:88
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:242
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:152
selectM68kCPU
static StringRef selectM68kCPU(Triple TT, StringRef CPU)
Select the M68k CPU for the given triple and cpu name.
Definition: M68kSubtarget.cpp:42
llvm::M68kSubtarget::isLegalToCallImmediateAddr
bool isLegalToCallImmediateAddr() const
Return true if the subtarget allows calls to immediate address.
Definition: M68kSubtarget.cpp:85
Function.h
M68kMachineFunction.h
llvm::M68kCallLowering
Definition: M68kCallLowering.h:27
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:69
llvm::M68kSubtarget::getJumpTableEncoding
unsigned getJumpTableEncoding() const
Definition: M68kSubtarget.cpp:220
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:1182
llvm::StringRef::str
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:221
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::TargetMachine::getCodeModel
CodeModel::Model getCodeModel() const
Returns the code model.
Definition: TargetMachine.h:225
llvm::M68kSubtarget::initializeSubtargetDependencies
M68kSubtarget & initializeSubtargetDependencies(StringRef CPU, Triple TT, StringRef FS, const M68kTargetMachine &TM)
Definition: M68kSubtarget.cpp:89
llvm::M68kSubtarget::CallLoweringInfo
std::unique_ptr< CallLowering > CallLoweringInfo
Definition: M68kSubtarget.h:168
M68kCallLowering.h
llvm::M68kSubtarget::atLeastM68020
bool atLeastM68020() const
Definition: M68kSubtarget.h:86
TargetRegistry.h
llvm::CallLowering
Definition: CallLowering.h:44
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:179
M68kGenSubtargetInfo
llvm::M68kSubtarget::InstrItins
InstrItineraryData InstrItins
Definition: M68kSubtarget.h:56
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:194