LLVM 20.0.0git
XtensaInstrInfo.cpp
Go to the documentation of this file.
1//===- XtensaInstrInfo.cpp - Xtensa Instruction Information ---------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
6// See https://llvm.org/LICENSE.txt for license information.
7// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8//
9//===----------------------------------------------------------------------===//
10//
11// This file contains the Xtensa implementation of the TargetInstrInfo class.
12//
13//===----------------------------------------------------------------------===//
14
15#include "XtensaInstrInfo.h"
18#include "XtensaTargetMachine.h"
24
25#define GET_INSTRINFO_CTOR_DTOR
26#include "XtensaGenInstrInfo.inc"
27
28using namespace llvm;
29
30static const MachineInstrBuilder &
32 MachineInstr *MI = MIB;
33 MachineFunction &MF = *MI->getParent()->getParent();
34 MachineFrameInfo &MFFrame = MF.getFrameInfo();
35 const MCInstrDesc &MCID = MI->getDesc();
37 if (MCID.mayLoad())
39 if (MCID.mayStore())
41 int64_t Offset = 0;
42 Align Alignment = MFFrame.getObjectAlign(FI);
43
46 Flags, MFFrame.getObjectSize(FI), Alignment);
47 return MIB.addFrameIndex(FI).addImm(Offset).addMemOperand(MMO);
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 }
63 return Register();
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 }
75 return Register();
76}
77
78/// Adjust SP by Amount bytes.
79void XtensaInstrInfo::adjustStackPtr(unsigned SP, int64_t Amount,
82 DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
83
84 if (Amount == 0)
85 return;
86
88 const TargetRegisterClass *RC = &Xtensa::ARRegClass;
89
90 // create virtual reg to store immediate
91 unsigned Reg = RegInfo.createVirtualRegister(RC);
92
93 if (isInt<8>(Amount)) { // addi sp, sp, amount
94 BuildMI(MBB, I, DL, get(Xtensa::ADDI), Reg).addReg(SP).addImm(Amount);
95 } else { // Expand immediate that doesn't fit in 8-bit.
96 unsigned Reg1;
97 loadImmediate(MBB, I, &Reg1, Amount);
98 BuildMI(MBB, I, DL, get(Xtensa::ADD), Reg)
99 .addReg(SP)
100 .addReg(Reg1, RegState::Kill);
101 }
102
103 BuildMI(MBB, I, DL, get(Xtensa::OR), SP)
105 .addReg(Reg, RegState::Kill);
106}
107
110 const DebugLoc &DL, MCRegister DestReg,
111 MCRegister SrcReg, bool KillSrc,
112 bool RenamableDest, bool RenamableSrc) const {
113 // The MOV instruction is not present in core ISA,
114 // so use OR instruction.
115 if (Xtensa::ARRegClass.contains(DestReg, SrcReg))
116 BuildMI(MBB, MBBI, DL, get(Xtensa::OR), DestReg)
117 .addReg(SrcReg, getKillRegState(KillSrc))
118 .addReg(SrcReg, getKillRegState(KillSrc));
119 else
120 report_fatal_error("Impossible reg-to-reg copy");
121}
122
125 bool isKill, int FrameIdx, const TargetRegisterClass *RC,
126 const TargetRegisterInfo *TRI, Register VReg,
127 MachineInstr::MIFlag Flags) const {
128 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
129 unsigned LoadOpcode, StoreOpcode;
130 getLoadStoreOpcodes(RC, LoadOpcode, StoreOpcode, FrameIdx);
131 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, get(StoreOpcode))
132 .addReg(SrcReg, getKillRegState(isKill));
133 addFrameReference(MIB, FrameIdx);
134}
135
138 int FrameIdx, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI,
139 Register VReg, MachineInstr::MIFlag Flags) const {
140 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
141 unsigned LoadOpcode, StoreOpcode;
142 getLoadStoreOpcodes(RC, LoadOpcode, StoreOpcode, FrameIdx);
143 addFrameReference(BuildMI(MBB, MBBI, DL, get(LoadOpcode), DestReg), FrameIdx);
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 {
160 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
162 const TargetRegisterClass *RC = &Xtensa::ARRegClass;
163
164 // create virtual reg to store immediate
165 *Reg = RegInfo.createVirtualRegister(RC);
166 if (Value >= -2048 && Value <= 2047) {
167 BuildMI(MBB, MBBI, DL, get(Xtensa::MOVI), *Reg).addImm(Value);
168 } else if (Value >= -32768 && Value <= 32767) {
169 int Low = Value & 0xFF;
170 int High = Value & ~0xFF;
171
172 BuildMI(MBB, MBBI, DL, get(Xtensa::MOVI), *Reg).addImm(Low);
173 BuildMI(MBB, MBBI, DL, get(Xtensa::ADDMI), *Reg).addReg(*Reg).addImm(High);
174 } else if (Value >= -4294967296LL && Value <= 4294967295LL) {
175 // 32 bit arbitrary constant
177 uint64_t UVal = ((uint64_t)Value) & 0xFFFFFFFFLL;
178 const Constant *CVal = ConstantInt::get(
180 false);
181 unsigned Idx = MCP->getConstantPoolIndex(CVal, Align(2U));
182 // MCSymbol MSym
183 BuildMI(MBB, MBBI, DL, get(Xtensa::L32R), *Reg).addConstantPoolIndex(Idx);
184 } else {
185 // use L32R to let assembler load immediate best
186 // TODO replace to L32R
187 report_fatal_error("Unsupported load immediate value");
188 }
189}
190
192 switch (MI.getOpcode()) {
193 case TargetOpcode::INLINEASM: { // Inline Asm: Variable size.
194 const MachineFunction *MF = MI.getParent()->getParent();
195 const char *AsmStr = MI.getOperand(0).getSymbolName();
196 return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo());
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:
257 report_fatal_error("Invalid branch condition!");
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:
290 llvm_unreachable("Unknown branch opcode");
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:
325 llvm_unreachable("Unknown branch opcode");
326 }
327}
328
331 MachineBasicBlock *&FBB,
333 bool AllowModify = false) const {
334 // Most of the code and comments here are boilerplate.
335
336 // Start from the bottom of the block and work up, examining the
337 // terminator instructions.
339 while (I != MBB.begin()) {
340 --I;
341 if (I->isDebugValue())
342 continue;
343
344 // Working from the bottom, when we see a non-terminator instruction, we're
345 // done.
346 if (!isUnpredicatedTerminator(*I))
347 break;
348
349 // A terminator that isn't a branch can't easily be handled by this
350 // analysis.
353 const MachineOperand *ThisTarget;
354 if (!isBranch(I, ThisCond, ThisTarget))
355 return true;
356
357 // Can't handle indirect branches.
358 if (!ThisTarget->isMBB())
359 return true;
360
361 if (ThisCond[0].getImm() == Xtensa::J) {
362 // Handle unconditional branches.
363 if (!AllowModify) {
364 TBB = ThisTarget->getMBB();
365 continue;
366 }
367
368 // If the block has any instructions after a JMP, delete them.
369 while (std::next(I) != MBB.end())
370 std::next(I)->eraseFromParent();
371
372 Cond.clear();
373 FBB = 0;
374
375 // TBB is used to indicate the unconditinal destination.
376 TBB = ThisTarget->getMBB();
377 continue;
378 }
379
380 // Working from the bottom, handle the first conditional branch.
381 if (Cond.empty()) {
382 // FIXME: add X86-style branch swap
383 FBB = TBB;
384 TBB = ThisTarget->getMBB();
385 Cond.push_back(MachineOperand::CreateImm(ThisCond[0].getImm()));
386
387 // push remaining operands
388 for (unsigned int i = 0; i < (I->getNumExplicitOperands() - 1); i++)
389 Cond.push_back(I->getOperand(i));
390
391 continue;
392 }
393
394 // Handle subsequent conditional branches.
395 assert(Cond.size() <= 4);
396 assert(TBB);
397
398 // Only handle the case where all conditional branches branch to the same
399 // destination.
400 if (TBB != ThisTarget->getMBB())
401 return true;
402
403 // If the conditions are the same, we can leave them alone.
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 // Most of the code and comments here are boilerplate.
416 unsigned Count = 0;
417 if (BytesRemoved)
418 *BytesRemoved = 0;
419
420 while (I != MBB.begin()) {
421 --I;
423 Cond.push_back(MachineOperand::CreateImm(0));
424 const MachineOperand *Target;
425 if (!isBranch(I, Cond, Target))
426 break;
427 if (!Target->isMBB())
428 break;
429 // Remove the branch.
430 if (BytesRemoved)
431 *BytesRemoved += getInstSizeInBytes(*I);
432 I->eraseFromParent();
433 I = MBB.end();
434 ++Count;
435 }
436 return Count;
437}
438
441 ArrayRef<MachineOperand> Cond, const DebugLoc &DL, int *BytesAdded) const {
442 unsigned Count = 0;
443 if (BytesAdded)
444 *BytesAdded = 0;
445 if (FBB) {
446 // Need to build two branches then
447 // one to branch to TBB on Cond
448 // and a second one immediately after to unconditionally jump to FBB
449 Count = insertBranchAtInst(MBB, MBB.end(), TBB, Cond, DL, BytesAdded);
450 auto &MI = *BuildMI(&MBB, DL, get(Xtensa::J)).addMBB(FBB);
451 Count++;
452 if (BytesAdded)
453 *BytesAdded += getInstSizeInBytes(MI);
454 return Count;
455 }
456 // This function inserts the branch at the end of the MBB
457 Count += insertBranchAtInst(MBB, MBB.end(), TBB, Cond, DL, BytesAdded);
458 return Count;
459}
460
462 MachineBasicBlock &DestBB,
463 MachineBasicBlock &RestoreBB,
464 const DebugLoc &DL, int64_t BrOffset,
465 RegScavenger *RS) const {
466 assert(RS && "RegScavenger required for long branching");
467 assert(MBB.empty() &&
468 "new block should be inserted for expanding unconditional branch");
469 assert(MBB.pred_size() == 1);
470
474 auto *XtensaFI = MF->getInfo<XtensaMachineFunctionInfo>();
475 MachineBasicBlock *JumpToMBB = &DestBB;
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);
482 auto II = MBB.end();
483
484 // Create l32r without last operand. We will add this operand later when
485 // JumpToMMB will be calculated and placed to the ConstantPool.
486 MachineInstr &L32R = *BuildMI(MBB, II, DL, get(Xtensa::L32R), ScratchReg);
487 BuildMI(MBB, II, DL, get(Xtensa::JX)).addReg(ScratchReg, RegState::Kill);
488
490 Register ScavRegister =
491 RS->scavengeRegisterBackwards(Xtensa::ARRegClass, L32R.getIterator(),
492 /*RestoreAfter=*/false, /*SpAdj=*/0,
493 /*AllowSpill=*/false);
494 if (ScavRegister != Xtensa::NoRegister)
495 RS->setRegUsed(ScavRegister);
496 else {
497 // The case when there is no scavenged register needs special handling.
498 // Pick A8 because it doesn't make a difference
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
507 storeRegToStackSlot(MBB, L32R, ScavRegister, /*IsKill=*/true, FrameIndex,
508 &Xtensa::ARRegClass, &RI, Register());
509 RI.eliminateFrameIndex(std::prev(L32R.getIterator()),
510 /*SpAdj=*/0, /*FIOperandNum=*/1);
511
512 loadRegFromStackSlot(RestoreBB, RestoreBB.end(), ScavRegister, FrameIndex,
513 &Xtensa::ARRegClass, &RI, Register());
514 RI.eliminateFrameIndex(RestoreBB.back(),
515 /*SpAdj=*/0, /*FIOperandNum=*/1);
516 JumpToMBB = &RestoreBB;
517 }
518
520 MF->getFunction().getContext(), JumpToMBB, 0);
521 unsigned Idx = ConstantPool->getConstantPoolIndex(C, Align(4));
523
524 MRI.replaceRegWith(ScratchReg, ScavRegister);
525 MRI.clearVirtRegs();
526}
527
529 MachineBasicBlock &MBB, MachineInstr *I, int64_t offset,
530 ArrayRef<MachineOperand> Cond, DebugLoc DL, int *BytesAdded) const {
531 assert(Cond.size() <= 4 &&
532 "Xtensa branch conditions have less than four components!");
533
534 if (Cond.empty() || (Cond[0].getImm() == Xtensa::J)) {
535 // Unconditional branch
536 MachineInstr *MI = BuildMI(MBB, I, DL, get(Xtensa::J)).addImm(offset);
537 if (BytesAdded && MI)
538 *BytesAdded += getInstSizeInBytes(*MI);
539 return 1;
540 }
541
542 unsigned Count = 0;
543 unsigned BR_C = Cond[0].getImm();
544 MachineInstr *MI = nullptr;
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:
552 MI = BuildMI(MBB, I, DL, get(BR_C))
553 .addImm(offset)
554 .addReg(Cond[1].getReg())
555 .addReg(Cond[2].getReg());
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:
563 MI = BuildMI(MBB, I, DL, get(BR_C))
564 .addImm(offset)
565 .addReg(Cond[1].getReg())
566 .addImm(Cond[2].getImm());
567 break;
568 case Xtensa::BEQZ:
569 case Xtensa::BNEZ:
570 case Xtensa::BLTZ:
571 case Xtensa::BGEZ:
572 MI = BuildMI(MBB, I, DL, get(BR_C)).addImm(offset).addReg(Cond[1].getReg());
573 break;
574 default:
575 llvm_unreachable("Invalid branch type!");
576 }
577 if (BytesAdded && MI)
578 *BytesAdded += getInstSizeInBytes(*MI);
579 ++Count;
580 return Count;
581}
582
587 const DebugLoc &DL,
588 int *BytesAdded) const {
589 // Shouldn't be a fall through.
590 assert(TBB && "InsertBranch must not be told to insert a fallthrough");
591 assert(Cond.size() <= 4 &&
592 "Xtensa branch conditions have less than four components!");
593
594 if (Cond.empty() || (Cond[0].getImm() == Xtensa::J)) {
595 // Unconditional branch
596 MachineInstr *MI = BuildMI(MBB, I, DL, get(Xtensa::J)).addMBB(TBB);
597 if (BytesAdded && MI)
598 *BytesAdded += getInstSizeInBytes(*MI);
599 return 1;
600 }
601
602 unsigned Count = 0;
603 unsigned BR_C = Cond[0].getImm();
604 MachineInstr *MI = nullptr;
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:
612 MI = BuildMI(MBB, I, DL, get(BR_C))
613 .addReg(Cond[1].getReg())
614 .addReg(Cond[2].getReg())
615 .addMBB(TBB);
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:
623 MI = BuildMI(MBB, I, DL, get(BR_C))
624 .addReg(Cond[1].getReg())
625 .addImm(Cond[2].getImm())
626 .addMBB(TBB);
627 break;
628 case Xtensa::BEQZ:
629 case Xtensa::BNEZ:
630 case Xtensa::BLTZ:
631 case Xtensa::BGEZ:
632 MI = BuildMI(MBB, I, DL, get(BR_C)).addReg(Cond[1].getReg()).addMBB(TBB);
633 break;
634 default:
635 report_fatal_error("Invalid branch type!");
636 }
637 if (BytesAdded && MI)
638 *BytesAdded += getInstSizeInBytes(*MI);
639 ++Count;
640 return Count;
641}
642
645 const MachineOperand *&Target) const {
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);
652 Target = &MI->getOperand(0);
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);
661 Target = &MI->getOperand(2);
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);
671 Target = &MI->getOperand(2);
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);
679 Target = &MI->getOperand(1);
680 return true;
681
682 default:
683 assert(!MI->getDesc().isBranch() && "Unknown branch opcode");
684 return false;
685 }
686}
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock & MBB
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
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition: MD5.cpp:58
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 High
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)
Definition: Value.cpp:469
static const MachineInstrBuilder & addFrameReference(const MachineInstrBuilder &MIB, int FI)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
This is an important base class in LLVM.
Definition: Constant.h:42
A debug info location.
Definition: DebugLoc.h:33
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition: Function.cpp:369
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:198
bool mayStore() const
Return true if this instruction could possibly modify memory.
Definition: MCInstrDesc.h:444
bool mayLoad() const
Return true if this instruction could possibly read memory.
Definition: MCInstrDesc.h:438
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
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.
Definition: MachineInstr.h:71
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.
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
void push_back(const T &Elt)
Definition: SmallVector.h:413
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
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.
Definition: Value.h:74
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()
Definition: ilist_node.h:132
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
@ Kill
The last use of a register.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
@ Offset
Definition: DWP.cpp:480
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.
Definition: Error.cpp:167
unsigned getKillRegState(bool B)
bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
Definition: MathExtras.h:262
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.