Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/SystemZ/SystemZInstrInfo.h
35269 views
1
//===-- SystemZInstrInfo.h - SystemZ instruction 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
// This file contains the SystemZ implementation of the TargetInstrInfo class.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#ifndef LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZINSTRINFO_H
14
#define LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZINSTRINFO_H
15
16
#include "SystemZ.h"
17
#include "SystemZRegisterInfo.h"
18
#include "llvm/ADT/ArrayRef.h"
19
#include "llvm/CodeGen/MachineBasicBlock.h"
20
#include "llvm/CodeGen/MachineFunction.h"
21
#include "llvm/CodeGen/MachineInstrBuilder.h"
22
#include "llvm/CodeGen/TargetInstrInfo.h"
23
#include <cstdint>
24
25
#define GET_INSTRINFO_HEADER
26
#include "SystemZGenInstrInfo.inc"
27
28
namespace llvm {
29
30
class SystemZSubtarget;
31
32
namespace SystemZII {
33
34
enum {
35
// See comments in SystemZInstrFormats.td.
36
SimpleBDXLoad = (1 << 0),
37
SimpleBDXStore = (1 << 1),
38
Has20BitOffset = (1 << 2),
39
HasIndex = (1 << 3),
40
Is128Bit = (1 << 4),
41
AccessSizeMask = (31 << 5),
42
AccessSizeShift = 5,
43
CCValuesMask = (15 << 10),
44
CCValuesShift = 10,
45
CompareZeroCCMaskMask = (15 << 14),
46
CompareZeroCCMaskShift = 14,
47
CCMaskFirst = (1 << 18),
48
CCMaskLast = (1 << 19),
49
IsLogical = (1 << 20),
50
CCIfNoSignedWrap = (1 << 21)
51
};
52
53
static inline unsigned getAccessSize(unsigned int Flags) {
54
return (Flags & AccessSizeMask) >> AccessSizeShift;
55
}
56
57
static inline unsigned getCCValues(unsigned int Flags) {
58
return (Flags & CCValuesMask) >> CCValuesShift;
59
}
60
61
static inline unsigned getCompareZeroCCMask(unsigned int Flags) {
62
return (Flags & CompareZeroCCMaskMask) >> CompareZeroCCMaskShift;
63
}
64
65
// SystemZ MachineOperand target flags.
66
enum {
67
// Masks out the bits for the access model.
68
MO_SYMBOL_MODIFIER = (3 << 0),
69
70
// @GOT (aka @GOTENT)
71
MO_GOT = (1 << 0),
72
73
// @INDNTPOFF
74
MO_INDNTPOFF = (2 << 0)
75
};
76
77
// z/OS XPLink specific: classifies the types of
78
// accesses to the ADA (Associated Data Area).
79
// These enums contains values that overlap with the above MO_ enums,
80
// but that's fine since the above enums are used with ELF,
81
// while these values are used with z/OS.
82
enum {
83
MO_ADA_DATA_SYMBOL_ADDR = 1,
84
MO_ADA_INDIRECT_FUNC_DESC,
85
MO_ADA_DIRECT_FUNC_DESC,
86
};
87
88
// Classifies a branch.
89
enum BranchType {
90
// An instruction that branches on the current value of CC.
91
BranchNormal,
92
93
// An instruction that peforms a 32-bit signed comparison and branches
94
// on the result.
95
BranchC,
96
97
// An instruction that peforms a 32-bit unsigned comparison and branches
98
// on the result.
99
BranchCL,
100
101
// An instruction that peforms a 64-bit signed comparison and branches
102
// on the result.
103
BranchCG,
104
105
// An instruction that peforms a 64-bit unsigned comparison and branches
106
// on the result.
107
BranchCLG,
108
109
// An instruction that decrements a 32-bit register and branches if
110
// the result is nonzero.
111
BranchCT,
112
113
// An instruction that decrements a 64-bit register and branches if
114
// the result is nonzero.
115
BranchCTG,
116
117
// An instruction representing an asm goto statement.
118
AsmGoto
119
};
120
121
// Information about a branch instruction.
122
class Branch {
123
// The target of the branch. In case of INLINEASM_BR, this is nullptr.
124
const MachineOperand *Target;
125
126
public:
127
// The type of the branch.
128
BranchType Type;
129
130
// CCMASK_<N> is set if CC might be equal to N.
131
unsigned CCValid;
132
133
// CCMASK_<N> is set if the branch should be taken when CC == N.
134
unsigned CCMask;
135
136
Branch(BranchType type, unsigned ccValid, unsigned ccMask,
137
const MachineOperand *target)
138
: Target(target), Type(type), CCValid(ccValid), CCMask(ccMask) {}
139
140
bool isIndirect() { return Target != nullptr && Target->isReg(); }
141
bool hasMBBTarget() { return Target != nullptr && Target->isMBB(); }
142
MachineBasicBlock *getMBBTarget() {
143
return hasMBBTarget() ? Target->getMBB() : nullptr;
144
}
145
};
146
147
// Kinds of fused compares in compare-and-* instructions. Together with type
148
// of the converted compare, this identifies the compare-and-*
149
// instruction.
150
enum FusedCompareType {
151
// Relative branch - CRJ etc.
152
CompareAndBranch,
153
154
// Indirect branch, used for return - CRBReturn etc.
155
CompareAndReturn,
156
157
// Indirect branch, used for sibcall - CRBCall etc.
158
CompareAndSibcall,
159
160
// Trap
161
CompareAndTrap
162
};
163
164
} // end namespace SystemZII
165
166
namespace SystemZ {
167
int getTwoOperandOpcode(uint16_t Opcode);
168
int getTargetMemOpcode(uint16_t Opcode);
169
170
// Return a version of comparison CC mask CCMask in which the LT and GT
171
// actions are swapped.
172
unsigned reverseCCMask(unsigned CCMask);
173
174
// Create a new basic block after MBB.
175
MachineBasicBlock *emitBlockAfter(MachineBasicBlock *MBB);
176
// Split MBB after MI and return the new block (the one that contains
177
// instructions after MI).
178
MachineBasicBlock *splitBlockAfter(MachineBasicBlock::iterator MI,
179
MachineBasicBlock *MBB);
180
// Split MBB before MI and return the new block (the one that contains MI).
181
MachineBasicBlock *splitBlockBefore(MachineBasicBlock::iterator MI,
182
MachineBasicBlock *MBB);
183
}
184
185
class SystemZInstrInfo : public SystemZGenInstrInfo {
186
const SystemZRegisterInfo RI;
187
SystemZSubtarget &STI;
188
189
void splitMove(MachineBasicBlock::iterator MI, unsigned NewOpcode) const;
190
void splitAdjDynAlloc(MachineBasicBlock::iterator MI) const;
191
void expandRIPseudo(MachineInstr &MI, unsigned LowOpcode, unsigned HighOpcode,
192
bool ConvertHigh) const;
193
void expandRIEPseudo(MachineInstr &MI, unsigned LowOpcode,
194
unsigned LowOpcodeK, unsigned HighOpcode) const;
195
void expandRXYPseudo(MachineInstr &MI, unsigned LowOpcode,
196
unsigned HighOpcode) const;
197
void expandLOCPseudo(MachineInstr &MI, unsigned LowOpcode,
198
unsigned HighOpcode) const;
199
void expandZExtPseudo(MachineInstr &MI, unsigned LowOpcode,
200
unsigned Size) const;
201
void expandLoadStackGuard(MachineInstr *MI) const;
202
203
MachineInstrBuilder
204
emitGRX32Move(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
205
const DebugLoc &DL, unsigned DestReg, unsigned SrcReg,
206
unsigned LowLowOpcode, unsigned Size, bool KillSrc,
207
bool UndefSrc) const;
208
209
virtual void anchor();
210
211
protected:
212
/// Commutes the operands in the given instruction by changing the operands
213
/// order and/or changing the instruction's opcode and/or the immediate value
214
/// operand.
215
///
216
/// The arguments 'CommuteOpIdx1' and 'CommuteOpIdx2' specify the operands
217
/// to be commuted.
218
///
219
/// Do not call this method for a non-commutable instruction or
220
/// non-commutable operands.
221
/// Even though the instruction is commutable, the method may still
222
/// fail to commute the operands, null pointer is returned in such cases.
223
MachineInstr *commuteInstructionImpl(MachineInstr &MI, bool NewMI,
224
unsigned CommuteOpIdx1,
225
unsigned CommuteOpIdx2) const override;
226
227
public:
228
explicit SystemZInstrInfo(SystemZSubtarget &STI);
229
230
// Override TargetInstrInfo.
231
Register isLoadFromStackSlot(const MachineInstr &MI,
232
int &FrameIndex) const override;
233
Register isStoreToStackSlot(const MachineInstr &MI,
234
int &FrameIndex) const override;
235
bool isStackSlotCopy(const MachineInstr &MI, int &DestFrameIndex,
236
int &SrcFrameIndex) const override;
237
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
238
MachineBasicBlock *&FBB,
239
SmallVectorImpl<MachineOperand> &Cond,
240
bool AllowModify) const override;
241
unsigned removeBranch(MachineBasicBlock &MBB,
242
int *BytesRemoved = nullptr) const override;
243
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
244
MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond,
245
const DebugLoc &DL,
246
int *BytesAdded = nullptr) const override;
247
bool analyzeCompare(const MachineInstr &MI, Register &SrcReg,
248
Register &SrcReg2, int64_t &Mask,
249
int64_t &Value) const override;
250
bool canInsertSelect(const MachineBasicBlock &, ArrayRef<MachineOperand> Cond,
251
Register, Register, Register, int &, int &,
252
int &) const override;
253
void insertSelect(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
254
const DebugLoc &DL, Register DstReg,
255
ArrayRef<MachineOperand> Cond, Register TrueReg,
256
Register FalseReg) const override;
257
MachineInstr *optimizeLoadInstr(MachineInstr &MI,
258
const MachineRegisterInfo *MRI,
259
Register &FoldAsLoadDefReg,
260
MachineInstr *&DefMI) const override;
261
bool foldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, Register Reg,
262
MachineRegisterInfo *MRI) const override;
263
264
bool isPredicable(const MachineInstr &MI) const override;
265
bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles,
266
unsigned ExtraPredCycles,
267
BranchProbability Probability) const override;
268
bool isProfitableToIfCvt(MachineBasicBlock &TMBB,
269
unsigned NumCyclesT, unsigned ExtraPredCyclesT,
270
MachineBasicBlock &FMBB,
271
unsigned NumCyclesF, unsigned ExtraPredCyclesF,
272
BranchProbability Probability) const override;
273
bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCycles,
274
BranchProbability Probability) const override;
275
bool PredicateInstruction(MachineInstr &MI,
276
ArrayRef<MachineOperand> Pred) const override;
277
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
278
const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg,
279
bool KillSrc) const override;
280
void storeRegToStackSlot(MachineBasicBlock &MBB,
281
MachineBasicBlock::iterator MBBI, Register SrcReg,
282
bool isKill, int FrameIndex,
283
const TargetRegisterClass *RC,
284
const TargetRegisterInfo *TRI,
285
Register VReg) const override;
286
void loadRegFromStackSlot(MachineBasicBlock &MBB,
287
MachineBasicBlock::iterator MBBI, Register DestReg,
288
int FrameIdx, const TargetRegisterClass *RC,
289
const TargetRegisterInfo *TRI,
290
Register VReg) const override;
291
MachineInstr *convertToThreeAddress(MachineInstr &MI, LiveVariables *LV,
292
LiveIntervals *LIS) const override;
293
294
bool useMachineCombiner() const override { return true; }
295
bool isAssociativeAndCommutative(const MachineInstr &Inst,
296
bool Invert) const override;
297
std::optional<unsigned> getInverseOpcode(unsigned Opcode) const override;
298
299
MachineInstr *
300
foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI,
301
ArrayRef<unsigned> Ops,
302
MachineBasicBlock::iterator InsertPt, int FrameIndex,
303
LiveIntervals *LIS = nullptr,
304
VirtRegMap *VRM = nullptr) const override;
305
MachineInstr *foldMemoryOperandImpl(
306
MachineFunction &MF, MachineInstr &MI, ArrayRef<unsigned> Ops,
307
MachineBasicBlock::iterator InsertPt, MachineInstr &LoadMI,
308
LiveIntervals *LIS = nullptr) const override;
309
bool expandPostRAPseudo(MachineInstr &MBBI) const override;
310
bool reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const
311
override;
312
313
// Return the SystemZRegisterInfo, which this class owns.
314
const SystemZRegisterInfo &getRegisterInfo() const { return RI; }
315
316
// Return the size in bytes of MI.
317
unsigned getInstSizeInBytes(const MachineInstr &MI) const override;
318
319
// Return true if MI is a conditional or unconditional branch.
320
// When returning true, set Cond to the mask of condition-code
321
// values on which the instruction will branch, and set Target
322
// to the operand that contains the branch target. This target
323
// can be a register or a basic block.
324
SystemZII::Branch getBranchInfo(const MachineInstr &MI) const;
325
326
// Get the load and store opcodes for a given register class.
327
void getLoadStoreOpcodes(const TargetRegisterClass *RC,
328
unsigned &LoadOpcode, unsigned &StoreOpcode) const;
329
330
// Opcode is the opcode of an instruction that has an address operand,
331
// and the caller wants to perform that instruction's operation on an
332
// address that has displacement Offset. Return the opcode of a suitable
333
// instruction (which might be Opcode itself) or 0 if no such instruction
334
// exists. MI may be passed in order to allow examination of physical
335
// register operands (i.e. if a VR32/64 reg ended up as an FP or Vector reg).
336
unsigned getOpcodeForOffset(unsigned Opcode, int64_t Offset,
337
const MachineInstr *MI = nullptr) const;
338
339
// Return true if Opcode has a mapping in 12 <-> 20 bit displacements.
340
bool hasDisplacementPairInsn(unsigned Opcode) const;
341
342
// If Opcode is a load instruction that has a LOAD AND TEST form,
343
// return the opcode for the testing form, otherwise return 0.
344
unsigned getLoadAndTest(unsigned Opcode) const;
345
346
// Return true if ROTATE AND ... SELECTED BITS can be used to select bits
347
// Mask of the R2 operand, given that only the low BitSize bits of Mask are
348
// significant. Set Start and End to the I3 and I4 operands if so.
349
bool isRxSBGMask(uint64_t Mask, unsigned BitSize,
350
unsigned &Start, unsigned &End) const;
351
352
// If Opcode is a COMPARE opcode for which an associated fused COMPARE AND *
353
// operation exists, return the opcode for the latter, otherwise return 0.
354
// MI, if nonnull, is the compare instruction.
355
unsigned getFusedCompare(unsigned Opcode,
356
SystemZII::FusedCompareType Type,
357
const MachineInstr *MI = nullptr) const;
358
359
// Try to find all CC users of the compare instruction (MBBI) and update
360
// all of them to maintain equivalent behavior after swapping the compare
361
// operands. Return false if not all users can be conclusively found and
362
// handled. The compare instruction is *not* changed.
363
bool prepareCompareSwapOperands(MachineBasicBlock::iterator MBBI) const;
364
365
// If Opcode is a LOAD opcode for with an associated LOAD AND TRAP
366
// operation exists, returh the opcode for the latter, otherwise return 0.
367
unsigned getLoadAndTrap(unsigned Opcode) const;
368
369
// Emit code before MBBI in MI to move immediate value Value into
370
// physical register Reg.
371
void loadImmediate(MachineBasicBlock &MBB,
372
MachineBasicBlock::iterator MBBI,
373
unsigned Reg, uint64_t Value) const;
374
375
// Perform target specific instruction verification.
376
bool verifyInstruction(const MachineInstr &MI,
377
StringRef &ErrInfo) const override;
378
379
// Sometimes, it is possible for the target to tell, even without
380
// aliasing information, that two MIs access different memory
381
// addresses. This function returns true if two MIs access different
382
// memory addresses and false otherwise.
383
bool
384
areMemAccessesTriviallyDisjoint(const MachineInstr &MIa,
385
const MachineInstr &MIb) const override;
386
387
bool getConstValDefinedInReg(const MachineInstr &MI, const Register Reg,
388
int64_t &ImmVal) const override;
389
};
390
391
} // end namespace llvm
392
393
#endif // LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZINSTRINFO_H
394
395