LLVM 20.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"
18
19using namespace llvm;
20
21#define GET_INSTRINFO_CTOR_DTOR
22#include "MSP430GenInstrInfo.inc"
23
24// Pin the vtable to this file.
25void MSP430InstrInfo::anchor() {}
26
28 : MSP430GenInstrInfo(MSP430::ADJCALLSTACKDOWN, MSP430::ADJCALLSTACKUP),
29 RI() {}
30
33 bool isKill, int FrameIdx, const TargetRegisterClass *RC,
34 const TargetRegisterInfo *TRI, Register VReg) const {
36 if (MI != MBB.end()) DL = MI->getDebugLoc();
39
43 MFI.getObjectAlign(FrameIdx));
44
45 if (RC == &MSP430::GR16RegClass)
46 BuildMI(MBB, MI, DL, get(MSP430::MOV16mr))
47 .addFrameIndex(FrameIdx).addImm(0)
48 .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
49 else if (RC == &MSP430::GR8RegClass)
50 BuildMI(MBB, MI, DL, get(MSP430::MOV8mr))
51 .addFrameIndex(FrameIdx).addImm(0)
52 .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
53 else
54 llvm_unreachable("Cannot store this register to stack slot!");
55}
56
59 Register DestReg, int FrameIdx,
60 const TargetRegisterClass *RC,
62 Register VReg) const {
64 if (MI != MBB.end()) DL = MI->getDebugLoc();
67
71 MFI.getObjectAlign(FrameIdx));
72
73 if (RC == &MSP430::GR16RegClass)
74 BuildMI(MBB, MI, DL, get(MSP430::MOV16rm))
75 .addReg(DestReg, getDefRegState(true)).addFrameIndex(FrameIdx)
76 .addImm(0).addMemOperand(MMO);
77 else if (RC == &MSP430::GR8RegClass)
78 BuildMI(MBB, MI, DL, get(MSP430::MOV8rm))
79 .addReg(DestReg, getDefRegState(true)).addFrameIndex(FrameIdx)
80 .addImm(0).addMemOperand(MMO);
81 else
82 llvm_unreachable("Cannot store this register to stack slot!");
83}
84
87 const DebugLoc &DL, MCRegister DestReg,
88 MCRegister SrcReg, bool KillSrc,
89 bool RenamableDest, bool RenamableSrc) const {
90 unsigned Opc;
91 if (MSP430::GR16RegClass.contains(DestReg, SrcReg))
92 Opc = MSP430::MOV16rr;
93 else if (MSP430::GR8RegClass.contains(DestReg, SrcReg))
94 Opc = MSP430::MOV8rr;
95 else
96 llvm_unreachable("Impossible reg-to-reg copy");
97
98 BuildMI(MBB, I, DL, get(Opc), DestReg)
99 .addReg(SrcReg, getKillRegState(KillSrc));
100}
101
103 int *BytesRemoved) const {
104 assert(!BytesRemoved && "code size not handled");
105
107 unsigned Count = 0;
108
109 while (I != MBB.begin()) {
110 --I;
111 if (I->isDebugInstr())
112 continue;
113 if (I->getOpcode() != MSP430::JMP &&
114 I->getOpcode() != MSP430::JCC &&
115 I->getOpcode() != MSP430::Bi &&
116 I->getOpcode() != MSP430::Br &&
117 I->getOpcode() != MSP430::Bm)
118 break;
119 // Remove the branch.
120 I->eraseFromParent();
121 I = MBB.end();
122 ++Count;
123 }
124
125 return Count;
126}
127
130 assert(Cond.size() == 1 && "Invalid Xbranch condition!");
131
132 MSP430CC::CondCodes CC = static_cast<MSP430CC::CondCodes>(Cond[0].getImm());
133
134 switch (CC) {
135 default: llvm_unreachable("Invalid branch condition!");
136 case MSP430CC::COND_E:
138 break;
141 break;
142 case MSP430CC::COND_L:
144 break;
147 break;
150 break;
153 break;
154 }
155
156 Cond[0].setImm(CC);
157 return false;
158}
159
162 MachineBasicBlock *&FBB,
164 bool AllowModify) const {
165 // Start from the bottom of the block and work up, examining the
166 // terminator instructions.
168 while (I != MBB.begin()) {
169 --I;
170 if (I->isDebugInstr())
171 continue;
172
173 // Working from the bottom, when we see a non-terminator
174 // instruction, we're done.
175 if (!isUnpredicatedTerminator(*I))
176 break;
177
178 // A terminator that isn't a branch can't easily be handled
179 // by this analysis.
180 if (!I->isBranch())
181 return true;
182
183 // Cannot handle indirect branches.
184 if (I->getOpcode() == MSP430::Br ||
185 I->getOpcode() == MSP430::Bm)
186 return true;
187
188 // Handle unconditional branches.
189 if (I->getOpcode() == MSP430::JMP || I->getOpcode() == MSP430::Bi) {
190 if (!AllowModify) {
191 TBB = I->getOperand(0).getMBB();
192 continue;
193 }
194
195 // If the block has any instructions after a JMP, delete them.
196 MBB.erase(std::next(I), MBB.end());
197 Cond.clear();
198 FBB = nullptr;
199
200 // Delete the JMP if it's equivalent to a fall-through.
201 if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
202 TBB = nullptr;
203 I->eraseFromParent();
204 I = MBB.end();
205 continue;
206 }
207
208 // TBB is used to indicate the unconditinal destination.
209 TBB = I->getOperand(0).getMBB();
210 continue;
211 }
212
213 // Handle conditional branches.
214 assert(I->getOpcode() == MSP430::JCC && "Invalid conditional branch");
215 MSP430CC::CondCodes BranchCode =
216 static_cast<MSP430CC::CondCodes>(I->getOperand(1).getImm());
217 if (BranchCode == MSP430CC::COND_INVALID)
218 return true; // Can't handle weird stuff.
219
220 // Working from the bottom, handle the first conditional branch.
221 if (Cond.empty()) {
222 FBB = TBB;
223 TBB = I->getOperand(0).getMBB();
224 Cond.push_back(MachineOperand::CreateImm(BranchCode));
225 continue;
226 }
227
228 // Handle subsequent conditional branches. Only handle the case where all
229 // conditional branches branch to the same destination.
230 assert(Cond.size() == 1);
231 assert(TBB);
232
233 // Only handle the case where all conditional branches branch to
234 // the same destination.
235 if (TBB != I->getOperand(0).getMBB())
236 return true;
237
238 MSP430CC::CondCodes OldBranchCode = (MSP430CC::CondCodes)Cond[0].getImm();
239 // If the conditions are the same, we can leave them alone.
240 if (OldBranchCode == BranchCode)
241 continue;
242
243 return true;
244 }
245
246 return false;
247}
248
253 const DebugLoc &DL,
254 int *BytesAdded) const {
255 // Shouldn't be a fall through.
256 assert(TBB && "insertBranch must not be told to insert a fallthrough");
257 assert((Cond.size() == 1 || Cond.size() == 0) &&
258 "MSP430 branch conditions have one component!");
259 assert(!BytesAdded && "code size not handled");
260
261 if (Cond.empty()) {
262 // Unconditional branch?
263 assert(!FBB && "Unconditional branch with multiple successors!");
264 BuildMI(&MBB, DL, get(MSP430::JMP)).addMBB(TBB);
265 return 1;
266 }
267
268 // Conditional branch.
269 unsigned Count = 0;
270 BuildMI(&MBB, DL, get(MSP430::JCC)).addMBB(TBB).addImm(Cond[0].getImm());
271 ++Count;
272
273 if (FBB) {
274 // Two-way Conditional branch. Insert the second branch.
275 BuildMI(&MBB, DL, get(MSP430::JMP)).addMBB(FBB);
276 ++Count;
277 }
278 return Count;
279}
280
281/// GetInstSize - Return the number of bytes of code the specified
282/// instruction may be. This returns the maximum number of bytes.
283///
285 const MCInstrDesc &Desc = MI.getDesc();
286
287 switch (Desc.getOpcode()) {
288 case TargetOpcode::CFI_INSTRUCTION:
289 case TargetOpcode::EH_LABEL:
290 case TargetOpcode::IMPLICIT_DEF:
291 case TargetOpcode::KILL:
292 case TargetOpcode::DBG_VALUE:
293 return 0;
294 case TargetOpcode::INLINEASM:
295 case TargetOpcode::INLINEASM_BR: {
296 const MachineFunction *MF = MI.getParent()->getParent();
298 return TII.getInlineAsmLength(MI.getOperand(0).getSymbolName(),
299 *MF->getTarget().getMCAsmInfo());
300 }
301 }
302
303 return Desc.getSize();
304}
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition: MD5.cpp:58
unsigned const TargetRegisterInfo * TRI
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition: Value.cpp:469
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:33
unsigned getInlineAsmLength(const char *Str, const MCAsmInfo &MAI, const TargetSubtargetInfo *STI=nullptr) const override
Measure the specified inline asm to determine an approximation of its length.
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:198
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
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
MSP430InstrInfo(MSP430Subtarget &STI)
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register DestReg, int FrameIdx, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) const override
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
GetInstSize - Return the number of bytes of code the specified instruction may be.
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg, bool KillSrc, bool RenamableDest=false, bool RenamableSrc=false) const override
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, const TargetRegisterInfo *TRI, Register VReg) const override
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
bool isLayoutSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB will be emitted immediately after this block, such that if this bloc...
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
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.
Definition: MachineInstr.h:69
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:19
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:573
TargetInstrInfo - Interface to description of machine instruction set.
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
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.
Definition: AddressRanges.h:18
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
unsigned getDefRegState(bool B)
unsigned getKillRegState(bool B)
Description of the encoding of one expression Op.
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.