LLVM 22.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.
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 MCRegister 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 MCRegister 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 if (STI.isWindowedABI()) {
104 BuildMI(MBB, I, DL, get(Xtensa::MOVSP), SP).addReg(Reg, RegState::Kill);
105 } else {
106 BuildMI(MBB, I, DL, get(Xtensa::OR), SP)
108 .addReg(Reg, RegState::Kill);
109 }
110}
111
114 const DebugLoc &DL, Register DestReg,
115 Register SrcReg, bool KillSrc,
116 bool RenamableDest, bool RenamableSrc) const {
117 // The MOV instruction is not present in core ISA,
118 // so use OR instruction.
119 if (Xtensa::ARRegClass.contains(DestReg, SrcReg))
120 BuildMI(MBB, MBBI, DL, get(Xtensa::OR), DestReg)
121 .addReg(SrcReg, getKillRegState(KillSrc))
122 .addReg(SrcReg, getKillRegState(KillSrc));
123 else
124 report_fatal_error("Impossible reg-to-reg copy");
125}
126
129 bool isKill, int FrameIdx, const TargetRegisterClass *RC,
130 const TargetRegisterInfo *TRI, Register VReg,
131 MachineInstr::MIFlag Flags) const {
132 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
133 unsigned LoadOpcode, StoreOpcode;
134 getLoadStoreOpcodes(RC, LoadOpcode, StoreOpcode, FrameIdx);
135 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, get(StoreOpcode))
136 .addReg(SrcReg, getKillRegState(isKill));
137 addFrameReference(MIB, FrameIdx);
138}
139
142 int FrameIdx, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI,
143 Register VReg, MachineInstr::MIFlag Flags) const {
144 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
145 unsigned LoadOpcode, StoreOpcode;
146 getLoadStoreOpcodes(RC, LoadOpcode, StoreOpcode, FrameIdx);
147 addFrameReference(BuildMI(MBB, MBBI, DL, get(LoadOpcode), DestReg), FrameIdx);
148}
149
151 unsigned &LoadOpcode,
152 unsigned &StoreOpcode,
153 int64_t offset) const {
154 if (RC == &Xtensa::ARRegClass) {
155 LoadOpcode = Xtensa::L32I;
156 StoreOpcode = Xtensa::S32I;
157 } else if (RC == &Xtensa::FPRRegClass) {
158 LoadOpcode = Xtensa::LSI;
159 StoreOpcode = Xtensa::SSI;
160 } else {
161 llvm_unreachable("Unsupported regclass to load or store");
162 }
163}
164
167 MCRegister *Reg, int64_t Value) const {
168 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
170 const TargetRegisterClass *RC = &Xtensa::ARRegClass;
171
172 // create virtual reg to store immediate
173 *Reg = RegInfo.createVirtualRegister(RC);
174 if (Value >= -2048 && Value <= 2047) {
175 BuildMI(MBB, MBBI, DL, get(Xtensa::MOVI), *Reg).addImm(Value);
176 } else if (Value >= -32768 && Value <= 32767) {
177 int Low = Value & 0xFF;
178 int High = Value & ~0xFF;
179
180 BuildMI(MBB, MBBI, DL, get(Xtensa::MOVI), *Reg).addImm(Low);
181 BuildMI(MBB, MBBI, DL, get(Xtensa::ADDMI), *Reg).addReg(*Reg).addImm(High);
182 } else if (Value >= -4294967296LL && Value <= 4294967295LL) {
183 // 32 bit arbitrary constant
185 uint64_t UVal = ((uint64_t)Value) & 0xFFFFFFFFLL;
186 const Constant *CVal = ConstantInt::get(
188 false);
189 unsigned Idx = MCP->getConstantPoolIndex(CVal, Align(2U));
190 // MCSymbol MSym
191 BuildMI(MBB, MBBI, DL, get(Xtensa::L32R), *Reg).addConstantPoolIndex(Idx);
192 } else {
193 // use L32R to let assembler load immediate best
194 // TODO replace to L32R
195 report_fatal_error("Unsupported load immediate value");
196 }
197}
198
200 switch (MI.getOpcode()) {
201 case TargetOpcode::INLINEASM: { // Inline Asm: Variable size.
202 const MachineFunction *MF = MI.getParent()->getParent();
203 const char *AsmStr = MI.getOperand(0).getSymbolName();
204 return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo());
205 }
206 default:
207 return MI.getDesc().getSize();
208 }
209}
210
213 assert(Cond.size() <= 4 && "Invalid branch condition!");
214
215 switch (Cond[0].getImm()) {
216 case Xtensa::BEQ:
217 Cond[0].setImm(Xtensa::BNE);
218 return false;
219 case Xtensa::BNE:
220 Cond[0].setImm(Xtensa::BEQ);
221 return false;
222 case Xtensa::BLT:
223 Cond[0].setImm(Xtensa::BGE);
224 return false;
225 case Xtensa::BGE:
226 Cond[0].setImm(Xtensa::BLT);
227 return false;
228 case Xtensa::BLTU:
229 Cond[0].setImm(Xtensa::BGEU);
230 return false;
231 case Xtensa::BGEU:
232 Cond[0].setImm(Xtensa::BLTU);
233 return false;
234 case Xtensa::BEQI:
235 Cond[0].setImm(Xtensa::BNEI);
236 return false;
237 case Xtensa::BNEI:
238 Cond[0].setImm(Xtensa::BEQI);
239 return false;
240 case Xtensa::BGEI:
241 Cond[0].setImm(Xtensa::BLTI);
242 return false;
243 case Xtensa::BLTI:
244 Cond[0].setImm(Xtensa::BGEI);
245 return false;
246 case Xtensa::BGEUI:
247 Cond[0].setImm(Xtensa::BLTUI);
248 return false;
249 case Xtensa::BLTUI:
250 Cond[0].setImm(Xtensa::BGEUI);
251 return false;
252 case Xtensa::BEQZ:
253 Cond[0].setImm(Xtensa::BNEZ);
254 return false;
255 case Xtensa::BNEZ:
256 Cond[0].setImm(Xtensa::BEQZ);
257 return false;
258 case Xtensa::BLTZ:
259 Cond[0].setImm(Xtensa::BGEZ);
260 return false;
261 case Xtensa::BGEZ:
262 Cond[0].setImm(Xtensa::BLTZ);
263 return false;
264 case Xtensa::BF:
265 Cond[0].setImm(Xtensa::BT);
266 return false;
267 case Xtensa::BT:
268 Cond[0].setImm(Xtensa::BF);
269 return false;
270 default:
271 report_fatal_error("Invalid branch condition!");
272 }
273}
274
277 unsigned OpCode = MI.getOpcode();
278 switch (OpCode) {
279 case Xtensa::BR_JT:
280 case Xtensa::JX:
281 return nullptr;
282 case Xtensa::J:
283 return MI.getOperand(0).getMBB();
284 case Xtensa::BEQ:
285 case Xtensa::BNE:
286 case Xtensa::BLT:
287 case Xtensa::BLTU:
288 case Xtensa::BGE:
289 case Xtensa::BGEU:
290 return MI.getOperand(2).getMBB();
291 case Xtensa::BEQI:
292 case Xtensa::BNEI:
293 case Xtensa::BLTI:
294 case Xtensa::BLTUI:
295 case Xtensa::BGEI:
296 case Xtensa::BGEUI:
297 return MI.getOperand(2).getMBB();
298 case Xtensa::BEQZ:
299 case Xtensa::BNEZ:
300 case Xtensa::BLTZ:
301 case Xtensa::BGEZ:
302 return MI.getOperand(1).getMBB();
303 case Xtensa::BT:
304 case Xtensa::BF:
305 return MI.getOperand(1).getMBB();
306 default:
307 llvm_unreachable("Unknown branch opcode");
308 }
309}
310
312 int64_t BrOffset) const {
313 switch (BranchOp) {
314 case Xtensa::J:
315 BrOffset -= 4;
316 return isIntN(18, BrOffset);
317 case Xtensa::JX:
318 return true;
319 case Xtensa::BR_JT:
320 return true;
321 case Xtensa::BEQ:
322 case Xtensa::BNE:
323 case Xtensa::BLT:
324 case Xtensa::BLTU:
325 case Xtensa::BGE:
326 case Xtensa::BGEU:
327 case Xtensa::BEQI:
328 case Xtensa::BNEI:
329 case Xtensa::BLTI:
330 case Xtensa::BLTUI:
331 case Xtensa::BGEI:
332 case Xtensa::BGEUI:
333 BrOffset -= 4;
334 return isIntN(8, BrOffset);
335 case Xtensa::BEQZ:
336 case Xtensa::BNEZ:
337 case Xtensa::BLTZ:
338 case Xtensa::BGEZ:
339 BrOffset -= 4;
340 return isIntN(12, BrOffset);
341 case Xtensa::BT:
342 case Xtensa::BF:
343 BrOffset -= 4;
344 return isIntN(8, BrOffset);
345 default:
346 llvm_unreachable("Unknown branch opcode");
347 }
348}
349
352 MachineBasicBlock *&FBB,
354 bool AllowModify = false) const {
355 // Most of the code and comments here are boilerplate.
356
357 // Start from the bottom of the block and work up, examining the
358 // terminator instructions.
360 while (I != MBB.begin()) {
361 --I;
362 if (I->isDebugValue())
363 continue;
364
365 // Working from the bottom, when we see a non-terminator instruction, we're
366 // done.
367 if (!isUnpredicatedTerminator(*I))
368 break;
369
370 // A terminator that isn't a branch can't easily be handled by this
371 // analysis.
374 const MachineOperand *ThisTarget;
375 if (!isBranch(I, ThisCond, ThisTarget))
376 return true;
377
378 // Can't handle indirect branches.
379 if (!ThisTarget->isMBB())
380 return true;
381
382 if (ThisCond[0].getImm() == Xtensa::J) {
383 // Handle unconditional branches.
384 if (!AllowModify) {
385 TBB = ThisTarget->getMBB();
386 continue;
387 }
388
389 // If the block has any instructions after a JMP, delete them.
390 while (std::next(I) != MBB.end())
391 std::next(I)->eraseFromParent();
392
393 Cond.clear();
394 FBB = 0;
395
396 // TBB is used to indicate the unconditinal destination.
397 TBB = ThisTarget->getMBB();
398 continue;
399 }
400
401 // Working from the bottom, handle the first conditional branch.
402 if (Cond.empty()) {
403 // FIXME: add X86-style branch swap
404 FBB = TBB;
405 TBB = ThisTarget->getMBB();
406 Cond.push_back(MachineOperand::CreateImm(ThisCond[0].getImm()));
407
408 // push remaining operands
409 for (unsigned int i = 0; i < (I->getNumExplicitOperands() - 1); i++)
410 Cond.push_back(I->getOperand(i));
411
412 continue;
413 }
414
415 // Handle subsequent conditional branches.
416 assert(Cond.size() <= 4);
417 assert(TBB);
418
419 // Only handle the case where all conditional branches branch to the same
420 // destination.
421 if (TBB != ThisTarget->getMBB())
422 return true;
423
424 // If the conditions are the same, we can leave them alone.
425 unsigned OldCond = Cond[0].getImm();
426 if (OldCond == ThisCond[0].getImm())
427 continue;
428 }
429
430 return false;
431}
432
434 int *BytesRemoved) const {
435 // Most of the code and comments here are boilerplate.
437 unsigned Count = 0;
438 if (BytesRemoved)
439 *BytesRemoved = 0;
440
441 while (I != MBB.begin()) {
442 --I;
444 Cond.push_back(MachineOperand::CreateImm(0));
445 const MachineOperand *Target;
446 if (!isBranch(I, Cond, Target))
447 break;
448 if (!Target->isMBB())
449 break;
450 // Remove the branch.
451 if (BytesRemoved)
452 *BytesRemoved += getInstSizeInBytes(*I);
453 I->eraseFromParent();
454 I = MBB.end();
455 ++Count;
456 }
457 return Count;
458}
459
462 ArrayRef<MachineOperand> Cond, const DebugLoc &DL, int *BytesAdded) const {
463 unsigned Count = 0;
464 if (BytesAdded)
465 *BytesAdded = 0;
466 if (FBB) {
467 // Need to build two branches then
468 // one to branch to TBB on Cond
469 // and a second one immediately after to unconditionally jump to FBB
470 Count = insertBranchAtInst(MBB, MBB.end(), TBB, Cond, DL, BytesAdded);
471 auto &MI = *BuildMI(&MBB, DL, get(Xtensa::J)).addMBB(FBB);
472 Count++;
473 if (BytesAdded)
474 *BytesAdded += getInstSizeInBytes(MI);
475 return Count;
476 }
477 // This function inserts the branch at the end of the MBB
478 Count += insertBranchAtInst(MBB, MBB.end(), TBB, Cond, DL, BytesAdded);
479 return Count;
480}
481
483 MachineBasicBlock &DestBB,
484 MachineBasicBlock &RestoreBB,
485 const DebugLoc &DL, int64_t BrOffset,
486 RegScavenger *RS) const {
487 assert(RS && "RegScavenger required for long branching");
488 assert(MBB.empty() &&
489 "new block should be inserted for expanding unconditional branch");
490 assert(MBB.pred_size() == 1);
491
495 auto *XtensaFI = MF->getInfo<XtensaMachineFunctionInfo>();
496 MachineBasicBlock *JumpToMBB = &DestBB;
497
498 if (!isInt<32>(BrOffset))
500 "Branch offsets outside of the signed 32-bit range not supported");
501
502 Register ScratchReg = MRI.createVirtualRegister(&Xtensa::ARRegClass);
503 auto II = MBB.end();
504
505 // Create l32r without last operand. We will add this operand later when
506 // JumpToMMB will be calculated and placed to the ConstantPool.
507 MachineInstr &L32R = *BuildMI(MBB, II, DL, get(Xtensa::L32R), ScratchReg);
508 BuildMI(MBB, II, DL, get(Xtensa::JX)).addReg(ScratchReg, RegState::Kill);
509
511 Register ScavRegister =
512 RS->scavengeRegisterBackwards(Xtensa::ARRegClass, L32R.getIterator(),
513 /*RestoreAfter=*/false, /*SpAdj=*/0,
514 /*AllowSpill=*/false);
515 if (ScavRegister != Xtensa::NoRegister)
516 RS->setRegUsed(ScavRegister);
517 else {
518 // The case when there is no scavenged register needs special handling.
519 // Pick A8 because it doesn't make a difference
520 ScavRegister = Xtensa::A12;
521
522 int FrameIndex = XtensaFI->getBranchRelaxationScratchFrameIndex();
523 if (FrameIndex == -1)
525 "Unable to properly handle scavenged register for indirect jump, "
526 "function code size is significantly larger than estimated");
527
528 storeRegToStackSlot(MBB, L32R, ScavRegister, /*IsKill=*/true, FrameIndex,
529 &Xtensa::ARRegClass, &RI, Register());
530 RI.eliminateFrameIndex(std::prev(L32R.getIterator()),
531 /*SpAdj=*/0, /*FIOperandNum=*/1);
532
533 loadRegFromStackSlot(RestoreBB, RestoreBB.end(), ScavRegister, FrameIndex,
534 &Xtensa::ARRegClass, &RI, Register());
535 RI.eliminateFrameIndex(RestoreBB.back(),
536 /*SpAdj=*/0, /*FIOperandNum=*/1);
537 JumpToMBB = &RestoreBB;
538 }
539
540 unsigned LabelId = XtensaFI->createCPLabelId();
541
543 MF->getFunction().getContext(), JumpToMBB, LabelId);
544 unsigned Idx = ConstantPool->getConstantPoolIndex(C, Align(4));
546
547 MRI.replaceRegWith(ScratchReg, ScavRegister);
548 MRI.clearVirtRegs();
549}
550
552 MachineBasicBlock &MBB, MachineInstr *I, int64_t offset,
553 ArrayRef<MachineOperand> Cond, DebugLoc DL, int *BytesAdded) const {
554 assert(Cond.size() <= 4 &&
555 "Xtensa branch conditions have less than four components!");
556
557 if (Cond.empty() || (Cond[0].getImm() == Xtensa::J)) {
558 // Unconditional branch
559 MachineInstr *MI = BuildMI(MBB, I, DL, get(Xtensa::J)).addImm(offset);
560 if (BytesAdded && MI)
561 *BytesAdded += getInstSizeInBytes(*MI);
562 return 1;
563 }
564
565 unsigned Count = 0;
566 unsigned BR_C = Cond[0].getImm();
567 MachineInstr *MI = nullptr;
568 switch (BR_C) {
569 case Xtensa::BEQ:
570 case Xtensa::BNE:
571 case Xtensa::BLT:
572 case Xtensa::BLTU:
573 case Xtensa::BGE:
574 case Xtensa::BGEU:
575 MI = BuildMI(MBB, I, DL, get(BR_C))
576 .addImm(offset)
577 .addReg(Cond[1].getReg())
578 .addReg(Cond[2].getReg());
579 break;
580 case Xtensa::BEQI:
581 case Xtensa::BNEI:
582 case Xtensa::BLTI:
583 case Xtensa::BLTUI:
584 case Xtensa::BGEI:
585 case Xtensa::BGEUI:
586 MI = BuildMI(MBB, I, DL, get(BR_C))
587 .addImm(offset)
588 .addReg(Cond[1].getReg())
589 .addImm(Cond[2].getImm());
590 break;
591 case Xtensa::BEQZ:
592 case Xtensa::BNEZ:
593 case Xtensa::BLTZ:
594 case Xtensa::BGEZ:
595 MI = BuildMI(MBB, I, DL, get(BR_C)).addImm(offset).addReg(Cond[1].getReg());
596 break;
597 case Xtensa::BT:
598 case Xtensa::BF:
599 MI = BuildMI(MBB, I, DL, get(BR_C)).addImm(offset).addReg(Cond[1].getReg());
600 break;
601 default:
602 llvm_unreachable("Invalid branch type!");
603 }
604 if (BytesAdded && MI)
605 *BytesAdded += getInstSizeInBytes(*MI);
606 ++Count;
607 return Count;
608}
609
614 const DebugLoc &DL,
615 int *BytesAdded) const {
616 // Shouldn't be a fall through.
617 assert(TBB && "InsertBranch must not be told to insert a fallthrough");
618 assert(Cond.size() <= 4 &&
619 "Xtensa branch conditions have less than four components!");
620
621 if (Cond.empty() || (Cond[0].getImm() == Xtensa::J)) {
622 // Unconditional branch
623 MachineInstr *MI = BuildMI(MBB, I, DL, get(Xtensa::J)).addMBB(TBB);
624 if (BytesAdded && MI)
625 *BytesAdded += getInstSizeInBytes(*MI);
626 return 1;
627 }
628
629 unsigned Count = 0;
630 unsigned BR_C = Cond[0].getImm();
631 MachineInstr *MI = nullptr;
632 switch (BR_C) {
633 case Xtensa::BEQ:
634 case Xtensa::BNE:
635 case Xtensa::BLT:
636 case Xtensa::BLTU:
637 case Xtensa::BGE:
638 case Xtensa::BGEU:
639 MI = BuildMI(MBB, I, DL, get(BR_C))
640 .addReg(Cond[1].getReg())
641 .addReg(Cond[2].getReg())
642 .addMBB(TBB);
643 break;
644 case Xtensa::BEQI:
645 case Xtensa::BNEI:
646 case Xtensa::BLTI:
647 case Xtensa::BLTUI:
648 case Xtensa::BGEI:
649 case Xtensa::BGEUI:
650 MI = BuildMI(MBB, I, DL, get(BR_C))
651 .addReg(Cond[1].getReg())
652 .addImm(Cond[2].getImm())
653 .addMBB(TBB);
654 break;
655 case Xtensa::BEQZ:
656 case Xtensa::BNEZ:
657 case Xtensa::BLTZ:
658 case Xtensa::BGEZ:
659 MI = BuildMI(MBB, I, DL, get(BR_C)).addReg(Cond[1].getReg()).addMBB(TBB);
660 break;
661 case Xtensa::BT:
662 case Xtensa::BF:
663 MI = BuildMI(MBB, I, DL, get(BR_C)).addReg(Cond[1].getReg()).addMBB(TBB);
664 break;
665 default:
666 report_fatal_error("Invalid branch type!");
667 }
668 if (BytesAdded && MI)
669 *BytesAdded += getInstSizeInBytes(*MI);
670 ++Count;
671 return Count;
672}
673
676 const MachineOperand *&Target) const {
677 unsigned OpCode = MI->getOpcode();
678 switch (OpCode) {
679 case Xtensa::J:
680 case Xtensa::JX:
681 case Xtensa::BR_JT:
682 Cond[0].setImm(OpCode);
683 Target = &MI->getOperand(0);
684 return true;
685 case Xtensa::BEQ:
686 case Xtensa::BNE:
687 case Xtensa::BLT:
688 case Xtensa::BLTU:
689 case Xtensa::BGE:
690 case Xtensa::BGEU:
691 Cond[0].setImm(OpCode);
692 Target = &MI->getOperand(2);
693 return true;
694
695 case Xtensa::BEQI:
696 case Xtensa::BNEI:
697 case Xtensa::BLTI:
698 case Xtensa::BLTUI:
699 case Xtensa::BGEI:
700 case Xtensa::BGEUI:
701 Cond[0].setImm(OpCode);
702 Target = &MI->getOperand(2);
703 return true;
704
705 case Xtensa::BEQZ:
706 case Xtensa::BNEZ:
707 case Xtensa::BLTZ:
708 case Xtensa::BGEZ:
709 Cond[0].setImm(OpCode);
710 Target = &MI->getOperand(1);
711 return true;
712
713 case Xtensa::BT:
714 case Xtensa::BF:
715 Cond[0].setImm(OpCode);
716 Target = &MI->getOperand(1);
717 return true;
718
719 default:
720 assert(!MI->getDesc().isBranch() && "Unknown branch opcode");
721 return false;
722 }
723}
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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 ...
Register 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.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition: Value.cpp:480
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:43
A debug info location.
Definition: DebugLoc.h:124
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition: Function.cpp:359
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:199
bool mayStore() const
Return true if this instruction could possibly modify memory.
Definition: MCInstrDesc.h:446
bool mayLoad() const
Return true if this instruction could possibly read memory.
Definition: MCInstrDesc.h:440
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
unsigned pred_size() const
LLVM_ABI 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:72
LLVM_ABI 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,...
LLVM_ABI 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:574
void push_back(const T &Elt)
Definition: SmallVector.h:414
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
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 LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
LLVM Value Representation.
Definition: Value.h:75
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
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, Register DestReg, Register SrcReg, bool KillSrc, bool RenamableDest=false, bool RenamableSrc=false) const override
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
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
void adjustStackPtr(MCRegister SP, int64_t Amount, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const
Adjust SP by Amount bytes.
Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) 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
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 loadImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, MCRegister *Reg, int64_t Value) 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
bool isWindowedABI() const
self_iterator getIterator()
Definition: ilist_node.h:134
#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:477
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...
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
Definition: SPIRVUtils.cpp:976
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition: Error.cpp:167
unsigned getKillRegState(bool B)
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
Definition: MathExtras.h:257
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.