LLVM: lib/Target/Xtensa/XtensaInstrInfo.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
24
25#define GET_INSTRINFO_CTOR_DTOR
26#include "XtensaGenInstrInfo.inc"
27
28using namespace llvm;
29
43
48}
49
51 : XtensaGenInstrInfo(Xtensa::ADJCALLSTACKDOWN, Xtensa::ADJCALLSTACKUP),
52 RI(STI), STI(STI) {}
53
55 int &FrameIndex) const {
56 if (MI.getOpcode() == Xtensa::L32I) {
57 if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
58 MI.getOperand(2).getImm() == 0) {
59 FrameIndex = MI.getOperand(1).getIndex();
60 return MI.getOperand(0).getReg();
61 }
62 }
64}
65
67 int &FrameIndex) const {
68 if (MI.getOpcode() == Xtensa::S32I) {
69 if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
70 MI.getOperand(2).getImm() == 0) {
71 FrameIndex = MI.getOperand(1).getIndex();
72 return MI.getOperand(0).getReg();
73 }
74 }
76}
77
78
83
84 if (Amount == 0)
85 return;
86
89
90
92
93 if (isInt<8>(Amount)) {
95 } else {
96 unsigned Reg1;
101 }
102
106}
107
112 bool RenamableDest, bool RenamableSrc) const {
113
114
115 if (Xtensa::ARRegClass.contains(DestReg, SrcReg))
119 else
121}
122
129 unsigned LoadOpcode, StoreOpcode;
134}
135
141 unsigned LoadOpcode, StoreOpcode;
144}
145
147 unsigned &LoadOpcode,
148 unsigned &StoreOpcode,
149 int64_t offset) const {
150 assert((RC == &Xtensa::ARRegClass) &&
151 "Unsupported regclass to load or store");
152
153 LoadOpcode = Xtensa::L32I;
154 StoreOpcode = Xtensa::S32I;
155}
156
159 unsigned *Reg, int64_t Value) const {
163
164
166 if (Value >= -2048 && Value <= 2047) {
168 } else if (Value >= -32768 && Value <= 32767) {
171
174 } else if (Value >= -4294967296LL && Value <= 4294967295LL) {
175
178 const Constant *CVal = ConstantInt::get(
180 false);
182
184 } else {
185
186
188 }
189}
190
192 switch (MI.getOpcode()) {
193 case TargetOpcode::INLINEASM: {
195 const char *AsmStr = MI.getOperand(0).getSymbolName();
197 }
198 default:
199 return MI.getDesc().getSize();
200 }
201}
202
205 assert(Cond.size() <= 4 && "Invalid branch condition!");
206
207 switch (Cond[0].getImm()) {
208 case Xtensa::BEQ:
209 Cond[0].setImm(Xtensa::BNE);
210 return false;
211 case Xtensa::BNE:
212 Cond[0].setImm(Xtensa::BEQ);
213 return false;
214 case Xtensa::BLT:
215 Cond[0].setImm(Xtensa::BGE);
216 return false;
217 case Xtensa::BGE:
218 Cond[0].setImm(Xtensa::BLT);
219 return false;
220 case Xtensa::BLTU:
221 Cond[0].setImm(Xtensa::BGEU);
222 return false;
223 case Xtensa::BGEU:
224 Cond[0].setImm(Xtensa::BLTU);
225 return false;
226 case Xtensa::BEQI:
227 Cond[0].setImm(Xtensa::BNEI);
228 return false;
229 case Xtensa::BNEI:
230 Cond[0].setImm(Xtensa::BEQI);
231 return false;
232 case Xtensa::BGEI:
233 Cond[0].setImm(Xtensa::BLTI);
234 return false;
235 case Xtensa::BLTI:
236 Cond[0].setImm(Xtensa::BGEI);
237 return false;
238 case Xtensa::BGEUI:
239 Cond[0].setImm(Xtensa::BLTUI);
240 return false;
241 case Xtensa::BLTUI:
242 Cond[0].setImm(Xtensa::BGEUI);
243 return false;
244 case Xtensa::BEQZ:
245 Cond[0].setImm(Xtensa::BNEZ);
246 return false;
247 case Xtensa::BNEZ:
248 Cond[0].setImm(Xtensa::BEQZ);
249 return false;
250 case Xtensa::BLTZ:
251 Cond[0].setImm(Xtensa::BGEZ);
252 return false;
253 case Xtensa::BGEZ:
254 Cond[0].setImm(Xtensa::BLTZ);
255 return false;
256 default:
258 }
259}
260
263 unsigned OpCode = MI.getOpcode();
264 switch (OpCode) {
265 case Xtensa::BR_JT:
266 case Xtensa::JX:
267 return nullptr;
268 case Xtensa::J:
269 return MI.getOperand(0).getMBB();
270 case Xtensa::BEQ:
271 case Xtensa::BNE:
272 case Xtensa::BLT:
273 case Xtensa::BLTU:
274 case Xtensa::BGE:
275 case Xtensa::BGEU:
276 return MI.getOperand(2).getMBB();
277 case Xtensa::BEQI:
278 case Xtensa::BNEI:
279 case Xtensa::BLTI:
280 case Xtensa::BLTUI:
281 case Xtensa::BGEI:
282 case Xtensa::BGEUI:
283 return MI.getOperand(2).getMBB();
284 case Xtensa::BEQZ:
285 case Xtensa::BNEZ:
286 case Xtensa::BLTZ:
287 case Xtensa::BGEZ:
288 return MI.getOperand(1).getMBB();
289 default:
291 }
292}
293
295 int64_t BrOffset) const {
296 switch (BranchOp) {
297 case Xtensa::J:
298 BrOffset -= 4;
299 return isIntN(18, BrOffset);
300 case Xtensa::JX:
301 return true;
302 case Xtensa::BR_JT:
303 return true;
304 case Xtensa::BEQ:
305 case Xtensa::BNE:
306 case Xtensa::BLT:
307 case Xtensa::BLTU:
308 case Xtensa::BGE:
309 case Xtensa::BGEU:
310 case Xtensa::BEQI:
311 case Xtensa::BNEI:
312 case Xtensa::BLTI:
313 case Xtensa::BLTUI:
314 case Xtensa::BGEI:
315 case Xtensa::BGEUI:
316 BrOffset -= 4;
317 return isIntN(8, BrOffset);
318 case Xtensa::BEQZ:
319 case Xtensa::BNEZ:
320 case Xtensa::BLTZ:
321 case Xtensa::BGEZ:
322 BrOffset -= 4;
323 return isIntN(12, BrOffset);
324 default:
326 }
327}
328
333 bool AllowModify = false) const {
334
335
336
337
340 --I;
341 if (I->isDebugValue())
342 continue;
343
344
345
346 if (!isUnpredicatedTerminator(*I))
347 break;
348
349
350
354 if ((I, ThisCond, ThisTarget))
355 return true;
356
357
358 if (!ThisTarget->isMBB())
359 return true;
360
361 if (ThisCond[0].getImm() == Xtensa::J) {
362
363 if (!AllowModify) {
365 continue;
366 }
367
368
369 while (std::next(I) != MBB.end())
371
372 Cond.clear();
373 FBB = 0;
374
375
377 continue;
378 }
379
380
381 if (Cond.empty()) {
382
383 FBB = TBB;
386
387
388 for (unsigned int i = 0; i < (I->getNumExplicitOperands() - 1); i++)
389 Cond.push_back(I->getOperand(i));
390
391 continue;
392 }
393
394
397
398
399
401 return true;
402
403
404 unsigned OldCond = Cond[0].getImm();
405 if (OldCond == ThisCond[0].getImm())
406 continue;
407 }
408
409 return false;
410}
411
413 int *BytesRemoved) const {
414
416 unsigned Count = 0;
417 if (BytesRemoved)
418 *BytesRemoved = 0;
419
421 --I;
426 break;
427 if (->isMBB())
428 break;
429
430 if (BytesRemoved)
432 I->eraseFromParent();
434 ++Count;
435 }
436 return Count;
437}
438
442 unsigned Count = 0;
443 if (BytesAdded)
444 *BytesAdded = 0;
445 if (FBB) {
446
447
448
451 Count++;
452 if (BytesAdded)
454 return Count;
455 }
456
458 return Count;
459}
460
464 const DebugLoc &DL, int64_t BrOffset,
466 assert(RS && "RegScavenger required for long branching");
468 "new block should be inserted for expanding unconditional branch");
470
476
477 if (!isInt<32>(BrOffset))
479 "Branch offsets outside of the signed 32-bit range not supported");
480
481 Register ScratchReg = MRI.createVirtualRegister(&Xtensa::ARRegClass);
483
484
485
488
492 false, 0,
493 false);
494 if (ScavRegister != Xtensa::NoRegister)
496 else {
497
498
499 ScavRegister = Xtensa::A12;
500
501 int FrameIndex = XtensaFI->getBranchRelaxationScratchFrameIndex();
502 if (FrameIndex == -1)
504 "Unable to properly handle scavenged register for indirect jump, "
505 "function code size is significantly larger than estimated");
506
508 &Xtensa::ARRegClass, &RI, Register());
510 0, 1);
511
513 &Xtensa::ARRegClass, &RI, Register());
515 0, 1);
516 JumpToMBB = &RestoreBB;
517 }
518
523
524 MRI.replaceRegWith(ScratchReg, ScavRegister);
525 MRI.clearVirtRegs();
526}
527
532 "Xtensa branch conditions have less than four components!");
533
534 if (Cond.empty() || (Cond[0].getImm() == Xtensa::J)) {
535
537 if (BytesAdded && MI)
539 return 1;
540 }
541
542 unsigned Count = 0;
543 unsigned BR_C = Cond[0].getImm();
545 switch (BR_C) {
546 case Xtensa::BEQ:
547 case Xtensa::BNE:
548 case Xtensa::BLT:
549 case Xtensa::BLTU:
550 case Xtensa::BGE:
551 case Xtensa::BGEU:
556 break;
557 case Xtensa::BEQI:
558 case Xtensa::BNEI:
559 case Xtensa::BLTI:
560 case Xtensa::BLTUI:
561 case Xtensa::BGEI:
562 case Xtensa::BGEUI:
567 break;
568 case Xtensa::BEQZ:
569 case Xtensa::BNEZ:
570 case Xtensa::BLTZ:
571 case Xtensa::BGEZ:
573 break;
574 default:
576 }
577 if (BytesAdded && MI)
579 ++Count;
580 return Count;
581}
582
588 int *BytesAdded) const {
589
590 assert(TBB && "InsertBranch must not be told to insert a fallthrough");
592 "Xtensa branch conditions have less than four components!");
593
594 if (Cond.empty() || (Cond[0].getImm() == Xtensa::J)) {
595
597 if (BytesAdded && MI)
599 return 1;
600 }
601
602 unsigned Count = 0;
603 unsigned BR_C = Cond[0].getImm();
605 switch (BR_C) {
606 case Xtensa::BEQ:
607 case Xtensa::BNE:
608 case Xtensa::BLT:
609 case Xtensa::BLTU:
610 case Xtensa::BGE:
611 case Xtensa::BGEU:
616 break;
617 case Xtensa::BEQI:
618 case Xtensa::BNEI:
619 case Xtensa::BLTI:
620 case Xtensa::BLTUI:
621 case Xtensa::BGEI:
622 case Xtensa::BGEUI:
627 break;
628 case Xtensa::BEQZ:
629 case Xtensa::BNEZ:
630 case Xtensa::BLTZ:
631 case Xtensa::BGEZ:
633 break;
634 default:
636 }
637 if (BytesAdded && MI)
639 ++Count;
640 return Count;
641}
642
646 unsigned OpCode = MI->getOpcode();
647 switch (OpCode) {
648 case Xtensa::J:
649 case Xtensa::JX:
650 case Xtensa::BR_JT:
651 Cond[0].setImm(OpCode);
653 return true;
654 case Xtensa::BEQ:
655 case Xtensa::BNE:
656 case Xtensa::BLT:
657 case Xtensa::BLTU:
658 case Xtensa::BGE:
659 case Xtensa::BGEU:
660 Cond[0].setImm(OpCode);
662 return true;
663
664 case Xtensa::BEQI:
665 case Xtensa::BNEI:
666 case Xtensa::BLTI:
667 case Xtensa::BLTUI:
668 case Xtensa::BGEI:
669 case Xtensa::BGEUI:
670 Cond[0].setImm(OpCode);
672 return true;
673
674 case Xtensa::BEQZ:
675 case Xtensa::BNEZ:
676 case Xtensa::BLTZ:
677 case Xtensa::BGEZ:
678 Cond[0].setImm(OpCode);
680 return true;
681
682 default:
683 assert(->getDesc().isBranch() && "Unknown branch opcode");
684 return false;
685 }
686}
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
unsigned const TargetRegisterInfo * TRI
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
uint64_t IntrinsicInst * II
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
This file declares the machine register scavenger class.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
static const MachineInstrBuilder & addFrameReference(const MachineInstrBuilder &MIB, int FI)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
This is an important base class in LLVM.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Describe properties that are true of each instruction in the target description file.
bool mayStore() const
Return true if this instruction could possibly modify memory.
bool mayLoad() const
Return true if this instruction could possibly read memory.
Wrapper class representing physical registers. Should be passed by value.
unsigned pred_size() const
void eraseFromParent()
This method unlinks 'this' from the containing function and deletes it.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
The MachineConstantPool class keeps track of constants referenced by a function which must be spilled...
unsigned getConstantPoolIndex(const Constant *C, Align Alignment)
getConstantPoolIndex - Create a new entry in the constant pool or return an existing one.
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.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
MachineConstantPool * getConstantPool()
getConstantPool - Return the constant pool 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 & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned TargetFlags=0) 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.
void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
A description of a memory reference used in the backend.
Flags
Flags values. These may be or'd together.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
MachineOperand class - Representation of each machine instruction operand.
MachineBasicBlock * getMBB() const
static MachineOperand CreateImm(int64_t Val)
static MachineOperand CreateCPI(unsigned Idx, int Offset, unsigned TargetFlags=0)
bool isMBB() const
isMBB - Tests if this is a MO_MachineBasicBlock operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
void enterBasicBlockEnd(MachineBasicBlock &MBB)
Start tracking liveness from the end of basic block MBB.
void setRegUsed(Register Reg, LaneBitmask LaneMask=LaneBitmask::getAll())
Tell the scavenger a register is used.
Register scavengeRegisterBackwards(const TargetRegisterClass &RC, MachineBasicBlock::iterator To, bool RestoreAfter, int SPAdj, bool AllowSpill=true)
Make a register of the specific register class available from the current position backwards to the p...
Wrapper class representing virtual and physical registers.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Target - Wrapper for Target specific information.
static IntegerType * getInt32Ty(LLVMContext &C)
LLVM Value Representation.
static XtensaConstantPoolMBB * Create(LLVMContext &C, const MachineBasicBlock *M, unsigned ID)
XtensaConstantPoolValue - Xtensa specific constantpool value.
bool isBranch(const MachineBasicBlock::iterator &MI, SmallVectorImpl< MachineOperand > &Cond, const MachineOperand *&Target) const
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
bool isBranchOffsetInRange(unsigned BranchOpc, int64_t BrOffset) const override
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIdx, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
void loadImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned *Reg, int64_t Value) const
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
void insertIndirectBranch(MachineBasicBlock &MBB, MachineBasicBlock &DestBB, MachineBasicBlock &RestoreBB, const DebugLoc &DL, int64_t BrOffset=0, RegScavenger *RS=nullptr) const override
Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg, bool KillSrc, bool RenamableDest=false, bool RenamableSrc=false) const override
unsigned insertConstBranchAtInst(MachineBasicBlock &MBB, MachineInstr *I, int64_t offset, ArrayRef< MachineOperand > Cond, DebugLoc DL, int *BytesAdded) const
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
void adjustStackPtr(unsigned SP, int64_t Amount, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const
Adjust SP by Amount bytes.
unsigned insertBranchAtInst(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, MachineBasicBlock *TBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded) const
MachineBasicBlock * getBranchDestBlock(const MachineInstr &MI) const override
XtensaInstrInfo(const XtensaSubtarget &STI)
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
void getLoadStoreOpcodes(const TargetRegisterClass *RC, unsigned &LoadOpcode, unsigned &StoreOpcode, int64_t offset) const
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
bool eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, unsigned FIOperandNum, RegScavenger *RS=nullptr) const override
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
@ Kill
The last use of a register.
This is an optimization pass for GlobalISel generic memory operations.
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
static const MachineInstrBuilder & addFrameReference(const MachineInstrBuilder &MIB, int FI, int Offset=0, bool mem=true)
addFrameReference - This function is used to add a reference to the base of an abstract object on the...
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
unsigned getKillRegState(bool B)
bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
This struct is a compact representation of a valid (non-zero power of two) alignment.
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.