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/M68kInstrInfo.h
35269 views
1
//===-- M68kInstrInfo.h - M68k 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
/// \file
10
/// This file contains the M68k implementation of the TargetInstrInfo class.
11
///
12
//===----------------------------------------------------------------------===//
13
14
#ifndef LLVM_LIB_TARGET_M68K_M68KINSTRINFO_H
15
#define LLVM_LIB_TARGET_M68K_M68KINSTRINFO_H
16
17
#include "M68k.h"
18
#include "M68kRegisterInfo.h"
19
20
#include "MCTargetDesc/M68kBaseInfo.h"
21
22
#include "llvm/CodeGen/MachineInstrBuilder.h"
23
#include "llvm/CodeGen/TargetInstrInfo.h"
24
25
#define GET_INSTRINFO_HEADER
26
#include "M68kGenInstrInfo.inc"
27
28
namespace llvm {
29
30
class M68kSubtarget;
31
32
namespace M68k {
33
// These MUST be kept in sync with codes definitions in M68kInstrInfo.td
34
enum CondCode {
35
COND_T = 0, // True
36
COND_F = 1, // False
37
COND_HI = 2, // High
38
COND_LS = 3, // Less or Same
39
COND_CC = 4, // Carry Clear
40
COND_CS = 5, // Carry Set
41
COND_NE = 6, // Not Equal
42
COND_EQ = 7, // Equal
43
COND_VC = 8, // Overflow Clear
44
COND_VS = 9, // Overflow Set
45
COND_PL = 10, // Plus
46
COND_MI = 11, // Minus
47
COND_GE = 12, // Greater or Equal
48
COND_LT = 13, // Less Than
49
COND_GT = 14, // Greater Than
50
COND_LE = 15, // Less or Equal
51
LAST_VALID_COND = COND_LE,
52
COND_INVALID
53
};
54
55
// FIXME would be nice tablegen to generate these predicates and converters
56
// mb tag based
57
58
static inline M68k::CondCode GetOppositeBranchCondition(M68k::CondCode CC) {
59
switch (CC) {
60
default:
61
llvm_unreachable("Illegal condition code!");
62
case M68k::COND_T:
63
return M68k::COND_F;
64
case M68k::COND_F:
65
return M68k::COND_T;
66
case M68k::COND_HI:
67
return M68k::COND_LS;
68
case M68k::COND_LS:
69
return M68k::COND_HI;
70
case M68k::COND_CC:
71
return M68k::COND_CS;
72
case M68k::COND_CS:
73
return M68k::COND_CC;
74
case M68k::COND_NE:
75
return M68k::COND_EQ;
76
case M68k::COND_EQ:
77
return M68k::COND_NE;
78
case M68k::COND_VC:
79
return M68k::COND_VS;
80
case M68k::COND_VS:
81
return M68k::COND_VC;
82
case M68k::COND_PL:
83
return M68k::COND_MI;
84
case M68k::COND_MI:
85
return M68k::COND_PL;
86
case M68k::COND_GE:
87
return M68k::COND_LT;
88
case M68k::COND_LT:
89
return M68k::COND_GE;
90
case M68k::COND_GT:
91
return M68k::COND_LE;
92
case M68k::COND_LE:
93
return M68k::COND_GT;
94
}
95
}
96
97
static inline unsigned GetCondBranchFromCond(M68k::CondCode CC) {
98
switch (CC) {
99
default:
100
llvm_unreachable("Illegal condition code!");
101
case M68k::COND_EQ:
102
return M68k::Beq8;
103
case M68k::COND_NE:
104
return M68k::Bne8;
105
case M68k::COND_LT:
106
return M68k::Blt8;
107
case M68k::COND_LE:
108
return M68k::Ble8;
109
case M68k::COND_GT:
110
return M68k::Bgt8;
111
case M68k::COND_GE:
112
return M68k::Bge8;
113
case M68k::COND_CS:
114
return M68k::Bcs8;
115
case M68k::COND_LS:
116
return M68k::Bls8;
117
case M68k::COND_HI:
118
return M68k::Bhi8;
119
case M68k::COND_CC:
120
return M68k::Bcc8;
121
case M68k::COND_MI:
122
return M68k::Bmi8;
123
case M68k::COND_PL:
124
return M68k::Bpl8;
125
case M68k::COND_VS:
126
return M68k::Bvs8;
127
case M68k::COND_VC:
128
return M68k::Bvc8;
129
}
130
}
131
132
static inline M68k::CondCode GetCondFromBranchOpc(unsigned Opcode) {
133
switch (Opcode) {
134
default:
135
return M68k::COND_INVALID;
136
case M68k::Beq8:
137
return M68k::COND_EQ;
138
case M68k::Bne8:
139
return M68k::COND_NE;
140
case M68k::Blt8:
141
return M68k::COND_LT;
142
case M68k::Ble8:
143
return M68k::COND_LE;
144
case M68k::Bgt8:
145
return M68k::COND_GT;
146
case M68k::Bge8:
147
return M68k::COND_GE;
148
case M68k::Bcs8:
149
return M68k::COND_CS;
150
case M68k::Bls8:
151
return M68k::COND_LS;
152
case M68k::Bhi8:
153
return M68k::COND_HI;
154
case M68k::Bcc8:
155
return M68k::COND_CC;
156
case M68k::Bmi8:
157
return M68k::COND_MI;
158
case M68k::Bpl8:
159
return M68k::COND_PL;
160
case M68k::Bvs8:
161
return M68k::COND_VS;
162
case M68k::Bvc8:
163
return M68k::COND_VC;
164
}
165
}
166
167
static inline unsigned IsCMP(unsigned Op) {
168
switch (Op) {
169
default:
170
return false;
171
case M68k::CMP8dd:
172
case M68k::CMP8df:
173
case M68k::CMP8di:
174
case M68k::CMP8dj:
175
case M68k::CMP8dp:
176
case M68k::CMP16dr:
177
case M68k::CMP16df:
178
case M68k::CMP16di:
179
case M68k::CMP16dj:
180
case M68k::CMP16dp:
181
return true;
182
}
183
}
184
185
static inline bool IsSETCC(unsigned SETCC) {
186
switch (SETCC) {
187
default:
188
return false;
189
case M68k::SETd8eq:
190
case M68k::SETd8ne:
191
case M68k::SETd8lt:
192
case M68k::SETd8ge:
193
case M68k::SETd8le:
194
case M68k::SETd8gt:
195
case M68k::SETd8cs:
196
case M68k::SETd8cc:
197
case M68k::SETd8ls:
198
case M68k::SETd8hi:
199
case M68k::SETd8pl:
200
case M68k::SETd8mi:
201
case M68k::SETd8vc:
202
case M68k::SETd8vs:
203
case M68k::SETj8eq:
204
case M68k::SETj8ne:
205
case M68k::SETj8lt:
206
case M68k::SETj8ge:
207
case M68k::SETj8le:
208
case M68k::SETj8gt:
209
case M68k::SETj8cs:
210
case M68k::SETj8cc:
211
case M68k::SETj8ls:
212
case M68k::SETj8hi:
213
case M68k::SETj8pl:
214
case M68k::SETj8mi:
215
case M68k::SETj8vc:
216
case M68k::SETj8vs:
217
case M68k::SETp8eq:
218
case M68k::SETp8ne:
219
case M68k::SETp8lt:
220
case M68k::SETp8ge:
221
case M68k::SETp8le:
222
case M68k::SETp8gt:
223
case M68k::SETp8cs:
224
case M68k::SETp8cc:
225
case M68k::SETp8ls:
226
case M68k::SETp8hi:
227
case M68k::SETp8pl:
228
case M68k::SETp8mi:
229
case M68k::SETp8vc:
230
case M68k::SETp8vs:
231
return true;
232
}
233
}
234
235
} // namespace M68k
236
237
class M68kInstrInfo : public M68kGenInstrInfo {
238
virtual void anchor();
239
240
protected:
241
const M68kSubtarget &Subtarget;
242
const M68kRegisterInfo RI;
243
244
public:
245
explicit M68kInstrInfo(const M68kSubtarget &STI);
246
247
static const M68kInstrInfo *create(M68kSubtarget &STI);
248
249
/// TargetInstrInfo is a superset of MRegister info. As such, whenever a
250
/// client has an instance of instruction info, it should always be able to
251
/// get register info as well (through this method).
252
const M68kRegisterInfo &getRegisterInfo() const { return RI; };
253
254
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
255
MachineBasicBlock *&FBB,
256
SmallVectorImpl<MachineOperand> &Cond,
257
bool AllowModify) const override;
258
259
bool AnalyzeBranchImpl(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
260
MachineBasicBlock *&FBB,
261
SmallVectorImpl<MachineOperand> &Cond,
262
bool AllowModify) const;
263
264
unsigned removeBranch(MachineBasicBlock &MBB,
265
int *BytesRemoved = nullptr) const override;
266
267
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
268
MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond,
269
const DebugLoc &DL,
270
int *BytesAdded = nullptr) const override;
271
272
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
273
const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg,
274
bool KillSrc) const override;
275
276
bool getStackSlotRange(const TargetRegisterClass *RC, unsigned SubIdx,
277
unsigned &Size, unsigned &Offset,
278
const MachineFunction &MF) const override;
279
280
void storeRegToStackSlot(MachineBasicBlock &MBB,
281
MachineBasicBlock::iterator MI, Register SrcReg,
282
bool IsKill, int FrameIndex,
283
const TargetRegisterClass *RC,
284
const TargetRegisterInfo *TRI,
285
Register VReg) const override;
286
287
void loadRegFromStackSlot(MachineBasicBlock &MBB,
288
MachineBasicBlock::iterator MI, Register DestReg,
289
int FrameIndex, const TargetRegisterClass *RC,
290
const TargetRegisterInfo *TRI,
291
Register VReg) const override;
292
293
bool expandPostRAPseudo(MachineInstr &MI) const override;
294
295
bool isPCRelRegisterOperandLegal(const MachineOperand &MO) const override;
296
297
/// Add appropriate SExt nodes
298
void AddSExt(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
299
DebugLoc DL, unsigned Reg, MVT From, MVT To) const;
300
301
/// Add appropriate ZExt nodes
302
void AddZExt(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
303
DebugLoc DL, unsigned Reg, MVT From, MVT To) const;
304
305
/// Move immediate to register
306
bool ExpandMOVI(MachineInstrBuilder &MIB, MVT MVTSize) const;
307
308
/// Move across register classes without extension
309
bool ExpandMOVX_RR(MachineInstrBuilder &MIB, MVT MVTDst, MVT MVTSrc) const;
310
311
/// Move from register and extend
312
bool ExpandMOVSZX_RR(MachineInstrBuilder &MIB, bool IsSigned, MVT MVTDst,
313
MVT MVTSrc) const;
314
315
/// Move from memory and extend
316
bool ExpandMOVSZX_RM(MachineInstrBuilder &MIB, bool IsSigned,
317
const MCInstrDesc &Desc, MVT MVTDst, MVT MVTSrc) const;
318
319
/// Push/Pop to/from stack
320
bool ExpandPUSH_POP(MachineInstrBuilder &MIB, const MCInstrDesc &Desc,
321
bool IsPush) const;
322
323
/// Moves to/from CCR
324
bool ExpandCCR(MachineInstrBuilder &MIB, bool IsToCCR) const;
325
326
/// Expand all MOVEM pseudos into real MOVEMs
327
bool ExpandMOVEM(MachineInstrBuilder &MIB, const MCInstrDesc &Desc,
328
bool IsRM) const;
329
330
/// Return a virtual register initialized with the global base register
331
/// value. Output instructions required to initialize the register in the
332
/// function entry block, if necessary.
333
unsigned getGlobalBaseReg(MachineFunction *MF) const;
334
335
std::pair<unsigned, unsigned>
336
decomposeMachineOperandsTargetFlags(unsigned TF) const override;
337
338
ArrayRef<std::pair<unsigned, const char *>>
339
getSerializableDirectMachineOperandTargetFlags() const override;
340
};
341
342
} // namespace llvm
343
344
#endif // LLVM_LIB_TARGET_M68K_M68KINSTRINFO_H
345
346