LLVM 22.0.0git
MSP430InstrInfo.cpp
Go to the documentation of this file.
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 "MSP430Subtarget.h"
19
20using namespace llvm;
21
22#define GET_INSTRINFO_CTOR_DTOR
23#include "MSP430GenInstrInfo.inc"
24
25// Pin the vtable to this file.
26void MSP430InstrInfo::anchor() {}
27
29 : MSP430GenInstrInfo(STI, RI, MSP430::ADJCALLSTACKDOWN,
30 MSP430::ADJCALLSTACKUP),
31 RI() {}
32
35 bool isKill, int FrameIdx, const TargetRegisterClass *RC, Register VReg,
36 MachineInstr::MIFlag Flags) const {
38 if (MI != MBB.end()) DL = MI->getDebugLoc();
39 MachineFunction &MF = *MBB.getParent();
41
45 MFI.getObjectAlign(FrameIdx));
46
47 if (RC == &MSP430::GR16RegClass)
48 BuildMI(MBB, MI, DL, get(MSP430::MOV16mr))
49 .addFrameIndex(FrameIdx).addImm(0)
50 .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
51 else if (RC == &MSP430::GR8RegClass)
52 BuildMI(MBB, MI, DL, get(MSP430::MOV8mr))
53 .addFrameIndex(FrameIdx).addImm(0)
54 .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
55 else
56 llvm_unreachable("Cannot store this register to stack slot!");
57}
58
61 Register DestReg, int FrameIdx,
62 const TargetRegisterClass *RC,
63 Register VReg,
64 MachineInstr::MIFlag Flags) const {
66 if (MI != MBB.end()) DL = MI->getDebugLoc();
67 MachineFunction &MF = *MBB.getParent();
69
73 MFI.getObjectAlign(FrameIdx));
74
75 if (RC == &MSP430::GR16RegClass)
76 BuildMI(MBB, MI, DL, get(MSP430::MOV16rm))
77 .addReg(DestReg, getDefRegState(true)).addFrameIndex(FrameIdx)
78 .addImm(0).addMemOperand(MMO);
79 else if (RC == &MSP430::GR8RegClass)
80 BuildMI(MBB, MI, DL, get(MSP430::MOV8rm))
81 .addReg(DestReg, getDefRegState(true)).addFrameIndex(FrameIdx)
82 .addImm(0).addMemOperand(MMO);
83 else
84 llvm_unreachable("Cannot store this register to stack slot!");
85}
86
89 const DebugLoc &DL, Register DestReg,
90 Register SrcReg, bool KillSrc,
91 bool RenamableDest, bool RenamableSrc) const {
92 unsigned Opc;
93 if (MSP430::GR16RegClass.contains(DestReg, SrcReg))
94 Opc = MSP430::MOV16rr;
95 else if (MSP430::GR8RegClass.contains(DestReg, SrcReg))
96 Opc = MSP430::MOV8rr;
97 else
98 llvm_unreachable("Impossible reg-to-reg copy");
99
100 BuildMI(MBB, I, DL, get(Opc), DestReg)
101 .addReg(SrcReg, getKillRegState(KillSrc));
102}
103
105 int *BytesRemoved) const {
106 assert(!BytesRemoved && "code size not handled");
107
109 unsigned Count = 0;
110
111 while (I != MBB.begin()) {
112 --I;
113 if (I->isDebugInstr())
114 continue;
115 if (I->getOpcode() != MSP430::JMP &&
116 I->getOpcode() != MSP430::JCC &&
117 I->getOpcode() != MSP430::Bi &&
118 I->getOpcode() != MSP430::Br &&
119 I->getOpcode() != MSP430::Bm)
120 break;
121 // Remove the branch.
122 I->eraseFromParent();
123 I = MBB.end();
124 ++Count;
125 }
126
127 return Count;
128}
129
132 assert(Cond.size() == 1 && "Invalid Xbranch condition!");
133
134 MSP430CC::CondCodes CC = static_cast<MSP430CC::CondCodes>(Cond[0].getImm());
135
136 switch (CC) {
137 default: llvm_unreachable("Invalid branch condition!");
138 case MSP430CC::COND_E:
140 break;
142 CC = MSP430CC::COND_E;
143 break;
144 case MSP430CC::COND_L:
146 break;
148 CC = MSP430CC::COND_L;
149 break;
152 break;
155 break;
156 }
157
158 Cond[0].setImm(CC);
159 return false;
160}
161
164 MachineBasicBlock *&FBB,
166 bool AllowModify) const {
167 // Start from the bottom of the block and work up, examining the
168 // terminator instructions.
170 while (I != MBB.begin()) {
171 --I;
172 if (I->isDebugInstr())
173 continue;
174
175 // Working from the bottom, when we see a non-terminator
176 // instruction, we're done.
177 if (!isUnpredicatedTerminator(*I))
178 break;
179
180 // A terminator that isn't a branch can't easily be handled
181 // by this analysis.
182 if (!I->isBranch())
183 return true;
184
185 // Cannot handle indirect branches.
186 if (I->getOpcode() == MSP430::Br ||
187 I->getOpcode() == MSP430::Bm)
188 return true;
189
190 // Handle unconditional branches.
191 if (I->getOpcode() == MSP430::JMP || I->getOpcode() == MSP430::Bi) {
192 if (!AllowModify) {
193 TBB = I->getOperand(0).getMBB();
194 continue;
195 }
196
197 // If the block has any instructions after a JMP, delete them.
198 MBB.erase(std::next(I), MBB.end());
199 Cond.clear();
200 FBB = nullptr;
201
202 // Delete the JMP if it's equivalent to a fall-through.
203 if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
204 TBB = nullptr;
205 I->eraseFromParent();
206 I = MBB.end();
207 continue;
208 }
209
210 // TBB is used to indicate the unconditinal destination.
211 TBB = I->getOperand(0).getMBB();
212 continue;
213 }
214
215 // Handle conditional branches.
216 assert(I->getOpcode() == MSP430::JCC && "Invalid conditional branch");
217 MSP430CC::CondCodes BranchCode =
218 static_cast<MSP430CC::CondCodes>(I->getOperand(1).getImm());
219 if (BranchCode == MSP430CC::COND_INVALID)
220 return true; // Can't handle weird stuff.
221
222 // Working from the bottom, handle the first conditional branch.
223 if (Cond.empty()) {
224 FBB = TBB;
225 TBB = I->getOperand(0).getMBB();
226 Cond.push_back(MachineOperand::CreateImm(BranchCode));
227 continue;
228 }
229
230 // Handle subsequent conditional branches. Only handle the case where all
231 // conditional branches branch to the same destination.
232 assert(Cond.size() == 1);
233 assert(TBB);
234
235 // Only handle the case where all conditional branches branch to
236 // the same destination.
237 if (TBB != I->getOperand(0).getMBB())
238 return true;
239
241 // If the conditions are the same, we can leave them alone.
242 if (OldBranchCode == BranchCode)
243 continue;
244
245 return true;
246 }
247
248 return false;
249}
250
255 const DebugLoc &DL,
256 int *BytesAdded) const {
257 // Shouldn't be a fall through.
258 assert(TBB && "insertBranch must not be told to insert a fallthrough");
259 assert((Cond.size() == 1 || Cond.size() == 0) &&
260 "MSP430 branch conditions have one component!");
261 assert(!BytesAdded && "code size not handled");
262
263 if (Cond.empty()) {
264 // Unconditional branch?
265 assert(!FBB && "Unconditional branch with multiple successors!");
266 BuildMI(&MBB, DL, get(MSP430::JMP)).addMBB(TBB);
267 return 1;
268 }
269
270 // Conditional branch.
271 unsigned Count = 0;
272 BuildMI(&MBB, DL, get(MSP430::JCC)).addMBB(TBB).addImm(Cond[0].getImm());
273 ++Count;
274
275 if (FBB) {
276 // Two-way Conditional branch. Insert the second branch.
277 BuildMI(&MBB, DL, get(MSP430::JMP)).addMBB(FBB);
278 ++Count;
279 }
280 return Count;
281}
282
283/// GetInstSize - Return the number of bytes of code the specified
284/// instruction may be. This returns the maximum number of bytes.
285///
287 const MCInstrDesc &Desc = MI.getDesc();
288
289 switch (Desc.getOpcode()) {
290 case TargetOpcode::CFI_INSTRUCTION:
291 case TargetOpcode::EH_LABEL:
292 case TargetOpcode::IMPLICIT_DEF:
293 case TargetOpcode::KILL:
294 case TargetOpcode::DBG_VALUE:
295 return 0;
296 case TargetOpcode::INLINEASM:
297 case TargetOpcode::INLINEASM_BR: {
298 const MachineFunction *MF = MI.getParent()->getParent();
300 return TII.getInlineAsmLength(MI.getOperand(0).getSymbolName(),
301 *MF->getTarget().getMCAsmInfo());
302 }
303 }
304
305 return Desc.getSize();
306}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition MD5.cpp:57
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition Value.cpp:480
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:41
A debug info location.
Definition DebugLoc.h:124
Describe properties that are true of each instruction in the target description file.
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, Register DestReg, Register SrcReg, bool KillSrc, bool RenamableDest=false, bool RenamableSrc=false) const override
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register DestReg, int FrameIdx, const TargetRegisterClass *RC, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
GetInstSize - Return the number of bytes of code the specified instruction may be.
MSP430InstrInfo(const MSP430Subtarget &STI)
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
MachineInstrBundleIterator< MachineInstr > iterator
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
A description of a memory reference used in the backend.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
static MachineOperand CreateImm(int64_t Val)
Wrapper class representing virtual and physical registers.
Definition Register.h:20
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
TargetInstrInfo - Interface to description of machine instruction set.
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
virtual const TargetInstrInfo * getInstrInfo() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
CondCodes
Definition MSP430.h:22
@ COND_LO
Definition MSP430.h:26
@ COND_L
Definition MSP430.h:28
@ COND_INVALID
Definition MSP430.h:32
@ COND_E
Definition MSP430.h:23
@ COND_GE
Definition MSP430.h:27
@ COND_NE
Definition MSP430.h:24
@ COND_HS
Definition MSP430.h:25
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
Op::Description Desc
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
FunctionAddr VTableAddr Count
Definition InstrProf.h:139
unsigned getDefRegState(bool B)
unsigned getKillRegState(bool B)
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.