LLVM: lib/Target/ARC/ARCInstrInfo.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
23
24using namespace llvm;
25
26#define GET_INSTRINFO_CTOR_DTOR
27#include "ARCGenInstrInfo.inc"
28
29#define DEBUG_TYPE "arc-inst-info"
30
37
42
43
44void ARCInstrInfo::anchor() {}
45
47 : ARCGenInstrInfo(ARC::ADJCALLSTACKDOWN, ARC::ADJCALLSTACKUP), RI(ST) {}
48
50 return Op.isImm() && Op.getImm() == 0;
51}
52
53static bool isLoad(int Opcode) {
54 return Opcode == ARC::LD_rs9 || Opcode == ARC::LDH_rs9 ||
55 Opcode == ARC::LDB_rs9;
56}
57
59 return Opcode == ARC::ST_rs9 || Opcode == ARC::STH_rs9 ||
60 Opcode == ARC::STB_rs9;
61}
62
63
64
65
66
67
69 int &FrameIndex) const {
70 int Opcode = MI.getOpcode();
72 if ((MI.getOperand(1).isFI()) &&
73 (MI.getOperand(2).isImm()) &&
75 FrameIndex = MI.getOperand(1).getIndex();
76 return MI.getOperand(0).getReg();
77 }
78 }
79 return 0;
80}
81
82
83
84
85
86
88 int &FrameIndex) const {
89 int Opcode = MI.getOpcode();
91 if ((MI.getOperand(1).isFI()) &&
92 (MI.getOperand(2).isImm()) &&
94 FrameIndex = MI.getOperand(1).getIndex();
95 return MI.getOperand(0).getReg();
96 }
97 }
98 return 0;
99}
100
101
103 switch (CC) {
104 default:
134 }
135}
136
138
140 return Opc == ARC::BRcc_rr_p || Opc == ARC::BRcc_ru6_p;
141}
142
143static bool isJumpOpcode(int Opc) { return Opc == ARC::J; }
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
174 bool AllowModify) const {
175 TBB = FBB = nullptr;
178 return false;
179 --I;
180
181 while (isPredicated(*I) || I->isTerminator() || I->isDebugValue()) {
182
183
184
185 bool CantAnalyze = false;
186
187
188 while (I->isDebugInstr() || ->isTerminator()) {
190 return false;
191 --I;
192 }
193
195
196
197 CantAnalyze = true;
199 TBB = I->getOperand(0).getMBB();
201
202 if (.empty())
203 return true;
204
205 assert(!FBB && "FBB should have been null.");
206 FBB = TBB;
207 TBB = I->getOperand(0).getMBB();
208 Cond.push_back(I->getOperand(1));
209 Cond.push_back(I->getOperand(2));
210 Cond.push_back(I->getOperand(3));
211 } else if (I->isReturn()) {
212
213 CantAnalyze = !isPredicated(*I);
214 } else {
215
216 return true;
217 }
218
219
220
223
224
225 Cond.clear();
226 FBB = nullptr;
227
228
229
230 if (AllowModify) {
234 ++DI;
236 }
237 }
238 }
239
240 if (CantAnalyze)
241 return true;
242
244 return false;
245
246 --I;
247 }
248
249
250
251 return false;
252}
253
255 int *BytesRemoved) const {
256 assert(!BytesRemoved && "Code size not handled");
259 return 0;
260
263 return 0;
264
265
266 I->eraseFromParent();
267
269
271 return 1;
272 --I;
274 return 1;
275
276
277 I->eraseFromParent();
278 return 2;
279}
280
285 bool RenamableDest, bool RenamableSrc) const {
287 "Only GPR32 src copy supported.");
289 "Only GPR32 dest copy supported.");
292}
293
302
307
308 assert(MMO && "Couldn't get MachineMemOperand for store to stack.");
309 assert(TRI->getSpillSize(*RC) == 4 &&
310 "Only support 4-byte stores to stack now.");
311 assert(ARC::GPR32RegClass.hasSubClassEq(RC) &&
312 "Only support GPR32 stores to stack now.");
314 << " to FrameIndex=" << FrameIndex << "\n");
320}
321
324 Register DestReg, int FrameIndex,
336
337 assert(MMO && "Couldn't get MachineMemOperand for store to stack.");
338 assert(TRI->getSpillSize(*RC) == 4 &&
339 "Only support 4-byte loads from stack now.");
340 assert(ARC::GPR32RegClass.hasSubClassEq(RC) &&
341 "Only support GPR32 stores to stack now.");
343 << " from FrameIndex=" << FrameIndex << "\n");
349}
350
351
354 assert((Cond.size() == 3) && "Invalid ARC branch condition!");
356 return false;
357}
358
364 if (isInt<12>(Value)) {
368 }
370}
371
376 const DebugLoc &DL, int *BytesAdded) const {
377 assert(!BytesAdded && "Code size not handled.");
378
379
380 assert(TBB && "insertBranch must not be told to insert a fallthrough");
382 "ARC branch conditions have two components!");
383
384 if (Cond.empty()) {
386 return 1;
387 }
388 int BccOpc = Cond[1].isImm() ? ARC::BRcc_ru6_p : ARC::BRcc_rr_p;
391 for (unsigned i = 0; i < 3; i++) {
393 }
394
395
396 if (!FBB) {
397 return 1;
398 }
399
400
402 return 2;
403}
404
406 if (MI.isInlineAsm()) {
408 const char *AsmStr = MI.getOperand(0).getSymbolName();
410 }
411 return MI.getDesc().getSize();
412}
413
418}
419
424}
425
427 unsigned &BasePos,
428 unsigned &OffsetPos) const {
429 if (.mayLoad() &&
.mayStore())
430 return false;
431
432 BasePos = 1;
433 OffsetPos = 2;
434
436 BasePos++;
437 OffsetPos++;
438 }
439
440 if (.getOperand(BasePos).isReg() ||
.getOperand(OffsetPos).isImm())
441 return false;
442
443 return true;
444}
static bool isLoad(int Opcode)
static ARCCC::CondCode getOppositeBranchCondition(ARCCC::CondCode CC)
Return the inverse of passed condition, i.e. turning COND_E to COND_NE.
static bool isStore(int Opcode)
static bool isZeroImm(const MachineOperand &Op)
static bool isJumpOpcode(int Opc)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
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)
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &, int *BytesAdded=nullptr) const override
virtual bool getBaseAndOffsetPosition(const MachineInstr &MI, unsigned &BasePos, unsigned &OffsetPos) const override
bool isPostIncrement(const MachineInstr &MI) const override
Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
If the specified machine instruction is a direct store to a stack slot, return the virtual or physica...
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
Analyze the branching code at the end of MBB, returning true if it cannot be understood (e....
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register SrcReg, bool IsKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
MachineBasicBlock::iterator loadImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned Reg, uint64_t Value) const
ARCInstrInfo(const ARCSubtarget &)
bool isPreIncrement(const MachineInstr &MI) const
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &, MCRegister DestReg, MCRegister SrcReg, bool KillSrc, bool RenamableDest=false, bool RenamableSrc=false) const override
Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
If the specified machine instruction is a direct load from a stack slot, return the virtual or physic...
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
Return the inverse opcode of the specified Branch instruction.
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
This class represents an Operation in the Expression.
Describe properties that are true of each instruction in the target description file.
Wrapper class representing physical registers. Should be passed by value.
DebugLoc findDebugLoc(instr_iterator MBBI)
Find the next valid DebugLoc starting at MBBI, skipping any debug instructions.
iterator getLastNonDebugInstr(bool SkipPseudoOp=true)
Returns an iterator to the last non-debug instruction in the basic block, or end().
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
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.
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 & add(const MachineOperand &MO) const
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
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
Representation of each machine instruction.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
A description of a memory reference used in the backend.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
MachineOperand class - Representation of each machine instruction operand.
Wrapper class representing virtual and physical registers.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
LLVM Value Representation.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ Define
Register definition.
This is an optimization pass for GlobalISel generic memory operations.
static bool isCondBranchOpcode(int Opc)
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)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
unsigned getKillRegState(bool B)
static bool isUncondBranchOpcode(int Opc)
Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.