LLVM: lib/Target/AVR/AVRInstrInfo.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
14
20
26
27#define GET_INSTRINFO_CTOR_DTOR
28#include "AVRGenInstrInfo.inc"
29
30namespace llvm {
31
35
39 Register SrcReg, bool KillSrc,
40 bool RenamableDest, bool RenamableSrc) const {
42 unsigned Opc;
43
44 if (AVR::DREGSRegClass.contains(DestReg, SrcReg)) {
45
46
47 if (STI.hasMOVW() && AVR::DREGSMOVWRegClass.contains(DestReg, SrcReg)) {
50 } else {
51 Register DestLo, DestHi, SrcLo, SrcHi;
52
53 TRI.splitReg(DestReg, DestLo, DestHi);
54 TRI.splitReg(SrcReg, SrcLo, SrcHi);
55
56
57
58
59
60
61 if (DestLo == SrcHi) {
66 } else {
71 }
72 }
73 } else {
74 if (AVR::GPR8RegClass.contains(DestReg, SrcReg)) {
75 Opc = AVR::MOVRdRr;
76 } else if (SrcReg == AVR::SP && AVR::DREGSRegClass.contains(DestReg)) {
77 Opc = AVR::SPREAD;
78 } else if (DestReg == AVR::SP && AVR::DREGSRegClass.contains(SrcReg)) {
79 Opc = AVR::SPWRITE;
80 } else {
82 }
83
86 }
87}
88
90 int &FrameIndex) const {
91 switch (MI.getOpcode()) {
92 case AVR::LDDRdPtrQ:
93 case AVR::LDDWRdYQ: {
94 if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
95 MI.getOperand(2).getImm() == 0) {
96 FrameIndex = MI.getOperand(1).getIndex();
97 return MI.getOperand(0).getReg();
98 }
99 break;
100 }
101 default:
102 break;
103 }
104
105 return 0;
106}
107
109 int &FrameIndex) const {
110 switch (MI.getOpcode()) {
111 case AVR::STDPtrQRr:
112 case AVR::STDWPtrQRr: {
113 if (MI.getOperand(0).isFI() && MI.getOperand(1).isImm() &&
114 MI.getOperand(1).getImm() == 0) {
115 FrameIndex = MI.getOperand(0).getIndex();
116 return MI.getOperand(2).getReg();
117 }
118 break;
119 }
120 default:
121 break;
122 }
123
124 return 0;
125}
126
133
135
137
142
143 unsigned Opcode = 0;
144 if (RI.isTypeLegalForClass(*RC, MVT::i8)) {
145 Opcode = AVR::STDPtrQRr;
146 } else if (RI.isTypeLegalForClass(*RC, MVT::i16)) {
147 Opcode = AVR::STDWPtrQRr;
148 } else {
149 llvm_unreachable("Cannot store this register into a stack slot!");
150 }
151
157}
158
161 Register DestReg, int FrameIndex,
167
172
173 unsigned Opcode = 0;
174 if (TRI.isTypeLegalForClass(*RC, MVT::i8)) {
175 Opcode = AVR::LDDRdPtrQ;
176 } else if (TRI.isTypeLegalForClass(*RC, MVT::i16)) {
177
178
179 Opcode = AVR::LDDWRdYQ;
180 } else {
181 llvm_unreachable("Cannot load this register from a stack slot!");
182 }
183
188}
189
191 switch (CC) {
192 default:
195 return get(AVR::BREQk);
197 return get(AVR::BRNEk);
199 return get(AVR::BRGEk);
201 return get(AVR::BRLTk);
203 return get(AVR::BRSHk);
205 return get(AVR::BRLOk);
207 return get(AVR::BRMIk);
209 return get(AVR::BRPLk);
210 }
211}
212
214 switch (Opc) {
215 default:
217 case AVR::BREQk:
219 case AVR::BRNEk:
221 case AVR::BRSHk:
223 case AVR::BRLOk:
225 case AVR::BRMIk:
227 case AVR::BRPLk:
229 case AVR::BRGEk:
231 case AVR::BRLTk:
233 }
234}
235
237 switch (CC) {
238 default:
256 }
257}
258
263 bool AllowModify) const {
264
265
268
269 while (I != MBB.begin()) {
270 --I;
271 if (I->isDebugInstr()) {
272 continue;
273 }
274
275
276
277 if (!isUnpredicatedTerminator(*I)) {
278 break;
279 }
280
281
282
283 if (->getDesc().isBranch()) {
284 return true;
285 }
286
287
288
289 if (I->getOpcode() == AVR::RJMPk) {
290 UnCondBrIter = I;
291
292 if (!AllowModify) {
293 TBB = I->getOperand(0).getMBB();
294 continue;
295 }
296
297
298 MBB.erase(std::next(I), MBB.end());
299
300 Cond.clear();
301 FBB = nullptr;
302
303
304 if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
305 TBB = nullptr;
306 I->eraseFromParent();
308 UnCondBrIter = MBB.end();
309 continue;
310 }
311
312
313 TBB = I->getOperand(0).getMBB();
314 continue;
315 }
316
317
320 return true;
321 }
322
323
324 if (Cond.empty()) {
326 if (AllowModify && UnCondBrIter != MBB.end() &&
327 MBB.isLayoutSuccessor(TargetBB)) {
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
348
350 .addMBB(UnCondBrIter->getOperand(0).getMBB());
353
354 OldInst->eraseFromParent();
355 UnCondBrIter->eraseFromParent();
356
357
358 UnCondBrIter = MBB.end();
360 continue;
361 }
362
363 FBB = TBB;
364 TBB = I->getOperand(0).getMBB();
366 continue;
367 }
368
369
370
373
374
375
376 if (TBB != I->getOperand(0).getMBB()) {
377 return true;
378 }
379
381
382 if (OldBranchCode == BranchCode) {
383 continue;
384 }
385
386 return true;
387 }
388
389 return false;
390}
391
396 const DebugLoc &DL, int *BytesAdded) const {
397 if (BytesAdded)
398 *BytesAdded = 0;
399
400
401 assert(TBB && "insertBranch must not be told to insert a fallthrough");
403 "AVR branch conditions have one component!");
404
405 if (Cond.empty()) {
406 assert(!FBB && "Unconditional branch with multiple successors!");
408 if (BytesAdded)
410 return 1;
411 }
412
413
414 unsigned Count = 0;
417
418 if (BytesAdded)
421
422 if (FBB) {
423
425 if (BytesAdded)
428 }
429
431}
432
434 int *BytesRemoved) const {
435 if (BytesRemoved)
436 *BytesRemoved = 0;
437
439 unsigned Count = 0;
440
441 while (I != MBB.begin()) {
442 --I;
443 if (I->isDebugInstr()) {
444 continue;
445 }
446
447
448 if (I->getOpcode() != AVR::RJMPk &&
450 break;
451 }
452
453
454 if (BytesRemoved)
456 I->eraseFromParent();
459 }
460
462}
463
466 assert(Cond.size() == 1 && "Invalid AVR branch condition!");
467
470
471 return false;
472}
473
475 unsigned Opcode = MI.getOpcode();
476
477 switch (Opcode) {
478
479 default: {
481 return Desc.getSize();
482 }
483 case TargetOpcode::EH_LABEL:
484 case TargetOpcode::IMPLICIT_DEF:
485 case TargetOpcode::KILL:
486 case TargetOpcode::DBG_VALUE:
487 return 0;
488 case TargetOpcode::INLINEASM:
489 case TargetOpcode::INLINEASM_BR: {
494 return TII.getInlineAsmLength(MI.getOperand(0).getSymbolName(),
496 }
497 }
498}
499
502 switch (MI.getOpcode()) {
503 default:
505 case AVR::JMPk:
506 case AVR::CALLk:
507 case AVR::RCALLk:
508 case AVR::RJMPk:
509 case AVR::BREQk:
510 case AVR::BRNEk:
511 case AVR::BRSHk:
512 case AVR::BRLOk:
513 case AVR::BRMIk:
514 case AVR::BRPLk:
515 case AVR::BRGEk:
516 case AVR::BRLTk:
517 return MI.getOperand(0).getMBB();
518 case AVR::BRBSsk:
519 case AVR::BRBCsk:
520 return MI.getOperand(1).getMBB();
521 case AVR::SBRCRrB:
522 case AVR::SBRSRrB:
523 case AVR::SBICAb:
524 case AVR::SBISAb:
526 }
527}
528
530 int64_t BrOffset) const {
531
532 switch (BranchOp) {
533 default:
535 case AVR::JMPk:
536 case AVR::CALLk:
537 return STI.hasJMPCALL();
538 case AVR::RCALLk:
539 case AVR::RJMPk:
540 return isIntN(13, BrOffset);
541 case AVR::BRBSsk:
542 case AVR::BRBCsk:
543 case AVR::BREQk:
544 case AVR::BRNEk:
545 case AVR::BRSHk:
546 case AVR::BRLOk:
547 case AVR::BRMIk:
548 case AVR::BRPLk:
549 case AVR::BRGEk:
550 case AVR::BRLTk:
551 return isIntN(7, BrOffset);
552 }
553}
554
558 const DebugLoc &DL, int64_t BrOffset,
560
561
562
563
564
565 if (STI.hasJMPCALL())
567 else
568
569
570
572}
573
574}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const TargetInstrInfo & TII
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Register const TargetRegisterInfo * TRI
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
Definition AVRInstrInfo.cpp:108
AVRCC::CondCodes getCondFromBranchOpc(unsigned Opc) const
Definition AVRInstrInfo.cpp:213
AVRCC::CondCodes getOppositeCondition(AVRCC::CondCodes CC) const
Definition AVRInstrInfo.cpp:236
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL, Register DestReg, Register SrcReg, bool KillSrc, bool RenamableDest=false, bool RenamableSrc=false) const override
Definition AVRInstrInfo.cpp:36
void insertIndirectBranch(MachineBasicBlock &MBB, MachineBasicBlock &NewDestBB, MachineBasicBlock &RestoreBB, const DebugLoc &DL, int64_t BrOffset, RegScavenger *RS) const override
Definition AVRInstrInfo.cpp:555
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
Definition AVRInstrInfo.cpp:159
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
Definition AVRInstrInfo.cpp:392
MachineBasicBlock * getBranchDestBlock(const MachineInstr &MI) const override
Definition AVRInstrInfo.cpp:501
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify=false) const override
Definition AVRInstrInfo.cpp:259
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
Definition AVRInstrInfo.cpp:127
AVRInstrInfo(const AVRSubtarget &STI)
Definition AVRInstrInfo.cpp:32
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
Definition AVRInstrInfo.cpp:464
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
Definition AVRInstrInfo.cpp:474
bool isBranchOffsetInRange(unsigned BranchOpc, int64_t BrOffset) const override
Definition AVRInstrInfo.cpp:529
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
Definition AVRInstrInfo.cpp:433
Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
Definition AVRInstrInfo.cpp:89
const MCInstrDesc & getBrCond(AVRCC::CondCodes CC) const
Definition AVRInstrInfo.cpp:190
Contains AVR-specific information for each MachineFunction.
void setHasSpills(bool B)
Utilities relating to AVR registers.
A specific AVR target MCU.
A generic AVR implementation.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Describe properties that are true of each instruction in the target description file.
unsigned getOpcode() const
Return the opcode number for this descriptor.
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.
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.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
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.
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.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
CondCodes
AVR specific condition codes.
@ COND_SH
Unsigned same or higher.
@ COND_GE
Greater than or equal.
Contains the AVR backend.
@ Undef
Value of the register doesn't matter.
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.
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
FunctionAddr VTableAddr Count
unsigned getKillRegState(bool B)
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.