Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/MSP430/MSP430InstrInfo.cpp
35268 views
1
//===-- MSP430InstrInfo.cpp - MSP430 Instruction Information --------------===//
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 MSP430 implementation of the TargetInstrInfo class.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "MSP430InstrInfo.h"
14
#include "MSP430.h"
15
#include "MSP430MachineFunctionInfo.h"
16
#include "MSP430TargetMachine.h"
17
#include "llvm/CodeGen/MachineFrameInfo.h"
18
#include "llvm/CodeGen/MachineInstrBuilder.h"
19
#include "llvm/CodeGen/MachineRegisterInfo.h"
20
#include "llvm/IR/Function.h"
21
#include "llvm/MC/TargetRegistry.h"
22
#include "llvm/Support/ErrorHandling.h"
23
24
using namespace llvm;
25
26
#define GET_INSTRINFO_CTOR_DTOR
27
#include "MSP430GenInstrInfo.inc"
28
29
// Pin the vtable to this file.
30
void MSP430InstrInfo::anchor() {}
31
32
MSP430InstrInfo::MSP430InstrInfo(MSP430Subtarget &STI)
33
: MSP430GenInstrInfo(MSP430::ADJCALLSTACKDOWN, MSP430::ADJCALLSTACKUP),
34
RI() {}
35
36
void MSP430InstrInfo::storeRegToStackSlot(
37
MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register SrcReg,
38
bool isKill, int FrameIdx, const TargetRegisterClass *RC,
39
const TargetRegisterInfo *TRI, Register VReg) const {
40
DebugLoc DL;
41
if (MI != MBB.end()) DL = MI->getDebugLoc();
42
MachineFunction &MF = *MBB.getParent();
43
MachineFrameInfo &MFI = MF.getFrameInfo();
44
45
MachineMemOperand *MMO = MF.getMachineMemOperand(
46
MachinePointerInfo::getFixedStack(MF, FrameIdx),
47
MachineMemOperand::MOStore, MFI.getObjectSize(FrameIdx),
48
MFI.getObjectAlign(FrameIdx));
49
50
if (RC == &MSP430::GR16RegClass)
51
BuildMI(MBB, MI, DL, get(MSP430::MOV16mr))
52
.addFrameIndex(FrameIdx).addImm(0)
53
.addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
54
else if (RC == &MSP430::GR8RegClass)
55
BuildMI(MBB, MI, DL, get(MSP430::MOV8mr))
56
.addFrameIndex(FrameIdx).addImm(0)
57
.addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
58
else
59
llvm_unreachable("Cannot store this register to stack slot!");
60
}
61
62
void MSP430InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
63
MachineBasicBlock::iterator MI,
64
Register DestReg, int FrameIdx,
65
const TargetRegisterClass *RC,
66
const TargetRegisterInfo *TRI,
67
Register VReg) const {
68
DebugLoc DL;
69
if (MI != MBB.end()) DL = MI->getDebugLoc();
70
MachineFunction &MF = *MBB.getParent();
71
MachineFrameInfo &MFI = MF.getFrameInfo();
72
73
MachineMemOperand *MMO = MF.getMachineMemOperand(
74
MachinePointerInfo::getFixedStack(MF, FrameIdx),
75
MachineMemOperand::MOLoad, MFI.getObjectSize(FrameIdx),
76
MFI.getObjectAlign(FrameIdx));
77
78
if (RC == &MSP430::GR16RegClass)
79
BuildMI(MBB, MI, DL, get(MSP430::MOV16rm))
80
.addReg(DestReg, getDefRegState(true)).addFrameIndex(FrameIdx)
81
.addImm(0).addMemOperand(MMO);
82
else if (RC == &MSP430::GR8RegClass)
83
BuildMI(MBB, MI, DL, get(MSP430::MOV8rm))
84
.addReg(DestReg, getDefRegState(true)).addFrameIndex(FrameIdx)
85
.addImm(0).addMemOperand(MMO);
86
else
87
llvm_unreachable("Cannot store this register to stack slot!");
88
}
89
90
void MSP430InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
91
MachineBasicBlock::iterator I,
92
const DebugLoc &DL, MCRegister DestReg,
93
MCRegister SrcReg, bool KillSrc) const {
94
unsigned Opc;
95
if (MSP430::GR16RegClass.contains(DestReg, SrcReg))
96
Opc = MSP430::MOV16rr;
97
else if (MSP430::GR8RegClass.contains(DestReg, SrcReg))
98
Opc = MSP430::MOV8rr;
99
else
100
llvm_unreachable("Impossible reg-to-reg copy");
101
102
BuildMI(MBB, I, DL, get(Opc), DestReg)
103
.addReg(SrcReg, getKillRegState(KillSrc));
104
}
105
106
unsigned MSP430InstrInfo::removeBranch(MachineBasicBlock &MBB,
107
int *BytesRemoved) const {
108
assert(!BytesRemoved && "code size not handled");
109
110
MachineBasicBlock::iterator I = MBB.end();
111
unsigned Count = 0;
112
113
while (I != MBB.begin()) {
114
--I;
115
if (I->isDebugInstr())
116
continue;
117
if (I->getOpcode() != MSP430::JMP &&
118
I->getOpcode() != MSP430::JCC &&
119
I->getOpcode() != MSP430::Bi &&
120
I->getOpcode() != MSP430::Br &&
121
I->getOpcode() != MSP430::Bm)
122
break;
123
// Remove the branch.
124
I->eraseFromParent();
125
I = MBB.end();
126
++Count;
127
}
128
129
return Count;
130
}
131
132
bool MSP430InstrInfo::
133
reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
134
assert(Cond.size() == 1 && "Invalid Xbranch condition!");
135
136
MSP430CC::CondCodes CC = static_cast<MSP430CC::CondCodes>(Cond[0].getImm());
137
138
switch (CC) {
139
default: llvm_unreachable("Invalid branch condition!");
140
case MSP430CC::COND_E:
141
CC = MSP430CC::COND_NE;
142
break;
143
case MSP430CC::COND_NE:
144
CC = MSP430CC::COND_E;
145
break;
146
case MSP430CC::COND_L:
147
CC = MSP430CC::COND_GE;
148
break;
149
case MSP430CC::COND_GE:
150
CC = MSP430CC::COND_L;
151
break;
152
case MSP430CC::COND_HS:
153
CC = MSP430CC::COND_LO;
154
break;
155
case MSP430CC::COND_LO:
156
CC = MSP430CC::COND_HS;
157
break;
158
}
159
160
Cond[0].setImm(CC);
161
return false;
162
}
163
164
bool MSP430InstrInfo::analyzeBranch(MachineBasicBlock &MBB,
165
MachineBasicBlock *&TBB,
166
MachineBasicBlock *&FBB,
167
SmallVectorImpl<MachineOperand> &Cond,
168
bool AllowModify) const {
169
// Start from the bottom of the block and work up, examining the
170
// terminator instructions.
171
MachineBasicBlock::iterator I = MBB.end();
172
while (I != MBB.begin()) {
173
--I;
174
if (I->isDebugInstr())
175
continue;
176
177
// Working from the bottom, when we see a non-terminator
178
// instruction, we're done.
179
if (!isUnpredicatedTerminator(*I))
180
break;
181
182
// A terminator that isn't a branch can't easily be handled
183
// by this analysis.
184
if (!I->isBranch())
185
return true;
186
187
// Cannot handle indirect branches.
188
if (I->getOpcode() == MSP430::Br ||
189
I->getOpcode() == MSP430::Bm)
190
return true;
191
192
// Handle unconditional branches.
193
if (I->getOpcode() == MSP430::JMP || I->getOpcode() == MSP430::Bi) {
194
if (!AllowModify) {
195
TBB = I->getOperand(0).getMBB();
196
continue;
197
}
198
199
// If the block has any instructions after a JMP, delete them.
200
MBB.erase(std::next(I), MBB.end());
201
Cond.clear();
202
FBB = nullptr;
203
204
// Delete the JMP if it's equivalent to a fall-through.
205
if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
206
TBB = nullptr;
207
I->eraseFromParent();
208
I = MBB.end();
209
continue;
210
}
211
212
// TBB is used to indicate the unconditinal destination.
213
TBB = I->getOperand(0).getMBB();
214
continue;
215
}
216
217
// Handle conditional branches.
218
assert(I->getOpcode() == MSP430::JCC && "Invalid conditional branch");
219
MSP430CC::CondCodes BranchCode =
220
static_cast<MSP430CC::CondCodes>(I->getOperand(1).getImm());
221
if (BranchCode == MSP430CC::COND_INVALID)
222
return true; // Can't handle weird stuff.
223
224
// Working from the bottom, handle the first conditional branch.
225
if (Cond.empty()) {
226
FBB = TBB;
227
TBB = I->getOperand(0).getMBB();
228
Cond.push_back(MachineOperand::CreateImm(BranchCode));
229
continue;
230
}
231
232
// Handle subsequent conditional branches. Only handle the case where all
233
// conditional branches branch to the same destination.
234
assert(Cond.size() == 1);
235
assert(TBB);
236
237
// Only handle the case where all conditional branches branch to
238
// the same destination.
239
if (TBB != I->getOperand(0).getMBB())
240
return true;
241
242
MSP430CC::CondCodes OldBranchCode = (MSP430CC::CondCodes)Cond[0].getImm();
243
// If the conditions are the same, we can leave them alone.
244
if (OldBranchCode == BranchCode)
245
continue;
246
247
return true;
248
}
249
250
return false;
251
}
252
253
unsigned MSP430InstrInfo::insertBranch(MachineBasicBlock &MBB,
254
MachineBasicBlock *TBB,
255
MachineBasicBlock *FBB,
256
ArrayRef<MachineOperand> Cond,
257
const DebugLoc &DL,
258
int *BytesAdded) const {
259
// Shouldn't be a fall through.
260
assert(TBB && "insertBranch must not be told to insert a fallthrough");
261
assert((Cond.size() == 1 || Cond.size() == 0) &&
262
"MSP430 branch conditions have one component!");
263
assert(!BytesAdded && "code size not handled");
264
265
if (Cond.empty()) {
266
// Unconditional branch?
267
assert(!FBB && "Unconditional branch with multiple successors!");
268
BuildMI(&MBB, DL, get(MSP430::JMP)).addMBB(TBB);
269
return 1;
270
}
271
272
// Conditional branch.
273
unsigned Count = 0;
274
BuildMI(&MBB, DL, get(MSP430::JCC)).addMBB(TBB).addImm(Cond[0].getImm());
275
++Count;
276
277
if (FBB) {
278
// Two-way Conditional branch. Insert the second branch.
279
BuildMI(&MBB, DL, get(MSP430::JMP)).addMBB(FBB);
280
++Count;
281
}
282
return Count;
283
}
284
285
/// GetInstSize - Return the number of bytes of code the specified
286
/// instruction may be. This returns the maximum number of bytes.
287
///
288
unsigned MSP430InstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
289
const MCInstrDesc &Desc = MI.getDesc();
290
291
switch (Desc.getOpcode()) {
292
case TargetOpcode::CFI_INSTRUCTION:
293
case TargetOpcode::EH_LABEL:
294
case TargetOpcode::IMPLICIT_DEF:
295
case TargetOpcode::KILL:
296
case TargetOpcode::DBG_VALUE:
297
return 0;
298
case TargetOpcode::INLINEASM:
299
case TargetOpcode::INLINEASM_BR: {
300
const MachineFunction *MF = MI.getParent()->getParent();
301
const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();
302
return TII.getInlineAsmLength(MI.getOperand(0).getSymbolName(),
303
*MF->getTarget().getMCAsmInfo());
304
}
305
}
306
307
return Desc.getSize();
308
}
309
310