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(STI, RI, Xtensa::ADJCALLSTACKDOWN,
52 Xtensa::ADJCALLSTACKUP),
53 RI(STI), STI(STI) {}
54
56 int &FrameIndex) const {
57 if (MI.getOpcode() == Xtensa::L32I) {
58 if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
59 MI.getOperand(2).getImm() == 0) {
60 FrameIndex = MI.getOperand(1).getIndex();
61 return MI.getOperand(0).getReg();
62 }
63 }
64 return Register();
65}
66
68 int &FrameIndex) const {
69 if (MI.getOpcode() == Xtensa::S32I) {
70 if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
71 MI.getOperand(2).getImm() == 0) {
72 FrameIndex = MI.getOperand(1).getIndex();
73 return MI.getOperand(0).getReg();
74 }
75 }
76 return Register();
77}
78
79/// Adjust SP by Amount bytes.
83 DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
84
85 if (Amount == 0)
86 return;
87
88 MachineRegisterInfo &RegInfo = MBB.getParent()->getRegInfo();
89 const TargetRegisterClass *RC = &Xtensa::ARRegClass;
90
91 // create virtual reg to store immediate
92 MCRegister Reg = RegInfo.createVirtualRegister(RC);
93
94 if (isInt<8>(Amount)) { // addi sp, sp, amount
95 BuildMI(MBB, I, DL, get(Xtensa::ADDI), Reg).addReg(SP).addImm(Amount);
96 } else { // Expand immediate that doesn't fit in 8-bit.
97 MCRegister Reg1;
98 loadImmediate(MBB, I, &Reg1, Amount);
99 BuildMI(MBB, I, DL, get(Xtensa::ADD), Reg)
100 .addReg(SP)
101 .addReg(Reg1, RegState::Kill);
102 }
103
104 if (STI.isWindowedABI()) {
105 BuildMI(MBB, I, DL, get(Xtensa::MOVSP), SP).addReg(Reg, RegState::Kill);
106 } else {
107 BuildMI(MBB, I, DL, get(Xtensa::OR), SP)
109 .addReg(Reg, RegState::Kill);
110 }
111}
112
115 const DebugLoc &DL, Register DestReg,
116 Register SrcReg, bool KillSrc,
117 bool RenamableDest, bool RenamableSrc) const {
118 unsigned Opcode;
119
120 // The MOV instruction is not present in core ISA for AR registers,
121 // so use OR instruction.
122 if (Xtensa::ARRegClass.contains(DestReg, SrcReg)) {
123 BuildMI(MBB, MBBI, DL, get(Xtensa::OR), DestReg)
124 .addReg(SrcReg, getKillRegState(KillSrc))
125 .addReg(SrcReg, getKillRegState(KillSrc));
126 return;
127 }
128
129 if (STI.hasSingleFloat() && Xtensa::FPRRegClass.contains(SrcReg) &&
130 Xtensa::FPRRegClass.contains(DestReg))
131 Opcode = Xtensa::MOV_S;
132 else if (STI.hasSingleFloat() && Xtensa::FPRRegClass.contains(SrcReg) &&
133 Xtensa::ARRegClass.contains(DestReg))
134 Opcode = Xtensa::RFR;
135 else if (STI.hasSingleFloat() && Xtensa::ARRegClass.contains(SrcReg) &&
136 Xtensa::FPRRegClass.contains(DestReg))
137 Opcode = Xtensa::WFR;
138 else
139 report_fatal_error("Impossible reg-to-reg copy");
140
141 BuildMI(MBB, MBBI, DL, get(Opcode), DestReg)
142 .addReg(SrcReg, getKillRegState(KillSrc));
143}
144
147 bool isKill, int FrameIdx, const TargetRegisterClass *RC,
148
149 Register VReg, MachineInstr::MIFlag Flags) const {
150 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
151 unsigned LoadOpcode, StoreOpcode;
152 getLoadStoreOpcodes(RC, LoadOpcode, StoreOpcode, FrameIdx);
153 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, get(StoreOpcode))
154 .addReg(SrcReg, getKillRegState(isKill));
155 addFrameReference(MIB, FrameIdx);
156}
157
160 Register DestReg, int FrameIdx,
161 const TargetRegisterClass *RC,
162 Register VReg,
163 MachineInstr::MIFlag Flags) const {
164 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
165 unsigned LoadOpcode, StoreOpcode;
166 getLoadStoreOpcodes(RC, LoadOpcode, StoreOpcode, FrameIdx);
167 addFrameReference(BuildMI(MBB, MBBI, DL, get(LoadOpcode), DestReg), FrameIdx);
168}
169
171 unsigned &LoadOpcode,
172 unsigned &StoreOpcode,
173 int64_t offset) const {
174 if (RC == &Xtensa::ARRegClass) {
175 LoadOpcode = Xtensa::L32I;
176 StoreOpcode = Xtensa::S32I;
177 } else if (RC == &Xtensa::FPRRegClass) {
178 LoadOpcode = Xtensa::LSI;
179 StoreOpcode = Xtensa::SSI;
180 } else {
181 llvm_unreachable("Unsupported regclass to load or store");
182 }
183}
184
187 MCRegister *Reg, int64_t Value) const {
188 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
189 MachineRegisterInfo &RegInfo = MBB.getParent()->getRegInfo();
190 const TargetRegisterClass *RC = &Xtensa::ARRegClass;
191
192 // create virtual reg to store immediate
193 *Reg = RegInfo.createVirtualRegister(RC);
194 if (Value >= -2048 && Value <= 2047) {
195 BuildMI(MBB, MBBI, DL, get(Xtensa::MOVI), *Reg).addImm(Value);
196 } else if (Value >= -32768 && Value <= 32767) {
197 int Low = Value & 0xFF;
198 int High = Value & ~0xFF;
199
200 BuildMI(MBB, MBBI, DL, get(Xtensa::MOVI), *Reg).addImm(Low);
201 BuildMI(MBB, MBBI, DL, get(Xtensa::ADDMI), *Reg).addReg(*Reg).addImm(High);
202 } else if (Value >= -4294967296LL && Value <= 4294967295LL) {
203 // 32 bit arbitrary constant
204 MachineConstantPool *MCP = MBB.getParent()->getConstantPool();
205 uint64_t UVal = ((uint64_t)Value) & 0xFFFFFFFFLL;
206 const Constant *CVal = ConstantInt::get(
207 Type::getInt32Ty(MBB.getParent()->getFunction().getContext()), UVal,
208 false);
209 unsigned Idx = MCP->getConstantPoolIndex(CVal, Align(2U));
210 // MCSymbol MSym
211 BuildMI(MBB, MBBI, DL, get(Xtensa::L32R), *Reg).addConstantPoolIndex(Idx);
212 } else {
213 // use L32R to let assembler load immediate best
214 // TODO replace to L32R
215 report_fatal_error("Unsupported load immediate value");
216 }
217}
218
220 switch (MI.getOpcode()) {
221 case TargetOpcode::INLINEASM: { // Inline Asm: Variable size.
222 const MachineFunction *MF = MI.getParent()->getParent();
223 const char *AsmStr = MI.getOperand(0).getSymbolName();
224 return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo());
225 }
226 default:
227 return MI.getDesc().getSize();
228 }
229}
230
233 assert(Cond.size() <= 4 && "Invalid branch condition!");
234
235 switch (Cond[0].getImm()) {
236 case Xtensa::BEQ:
237 Cond[0].setImm(Xtensa::BNE);
238 return false;
239 case Xtensa::BNE:
240 Cond[0].setImm(Xtensa::BEQ);
241 return false;
242 case Xtensa::BLT:
243 Cond[0].setImm(Xtensa::BGE);
244 return false;
245 case Xtensa::BGE:
246 Cond[0].setImm(Xtensa::BLT);
247 return false;
248 case Xtensa::BLTU:
249 Cond[0].setImm(Xtensa::BGEU);
250 return false;
251 case Xtensa::BGEU:
252 Cond[0].setImm(Xtensa::BLTU);
253 return false;
254 case Xtensa::BEQI:
255 Cond[0].setImm(Xtensa::BNEI);
256 return false;
257 case Xtensa::BNEI:
258 Cond[0].setImm(Xtensa::BEQI);
259 return false;
260 case Xtensa::BGEI:
261 Cond[0].setImm(Xtensa::BLTI);
262 return false;
263 case Xtensa::BLTI:
264 Cond[0].setImm(Xtensa::BGEI);
265 return false;
266 case Xtensa::BGEUI:
267 Cond[0].setImm(Xtensa::BLTUI);
268 return false;
269 case Xtensa::BLTUI:
270 Cond[0].setImm(Xtensa::BGEUI);
271 return false;
272 case Xtensa::BEQZ:
273 Cond[0].setImm(Xtensa::BNEZ);
274 return false;
275 case Xtensa::BNEZ:
276 Cond[0].setImm(Xtensa::BEQZ);
277 return false;
278 case Xtensa::BLTZ:
279 Cond[0].setImm(Xtensa::BGEZ);
280 return false;
281 case Xtensa::BGEZ:
282 Cond[0].setImm(Xtensa::BLTZ);
283 return false;
284 case Xtensa::BF:
285 Cond[0].setImm(Xtensa::BT);
286 return false;
287 case Xtensa::BT:
288 Cond[0].setImm(Xtensa::BF);
289 return false;
290 default:
291 report_fatal_error("Invalid branch condition!");
292 }
293}
294
297 unsigned OpCode = MI.getOpcode();
298 switch (OpCode) {
299 case Xtensa::BR_JT:
300 case Xtensa::JX:
301 return nullptr;
302 case Xtensa::J:
303 return MI.getOperand(0).getMBB();
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 return MI.getOperand(2).getMBB();
311 case Xtensa::BEQI:
312 case Xtensa::BNEI:
313 case Xtensa::BLTI:
314 case Xtensa::BLTUI:
315 case Xtensa::BGEI:
316 case Xtensa::BGEUI:
317 return MI.getOperand(2).getMBB();
318 case Xtensa::BEQZ:
319 case Xtensa::BNEZ:
320 case Xtensa::BLTZ:
321 case Xtensa::BGEZ:
322 return MI.getOperand(1).getMBB();
323 case Xtensa::BT:
324 case Xtensa::BF:
325 return MI.getOperand(1).getMBB();
326 default:
327 llvm_unreachable("Unknown branch opcode");
328 }
329}
330
332 int64_t BrOffset) const {
333 switch (BranchOp) {
334 case Xtensa::J:
335 BrOffset -= 4;
336 return isIntN(18, BrOffset);
337 case Xtensa::JX:
338 return true;
339 case Xtensa::BR_JT:
340 return true;
341 case Xtensa::BEQ:
342 case Xtensa::BNE:
343 case Xtensa::BLT:
344 case Xtensa::BLTU:
345 case Xtensa::BGE:
346 case Xtensa::BGEU:
347 case Xtensa::BEQI:
348 case Xtensa::BNEI:
349 case Xtensa::BLTI:
350 case Xtensa::BLTUI:
351 case Xtensa::BGEI:
352 case Xtensa::BGEUI:
353 BrOffset -= 4;
354 return isIntN(8, BrOffset);
355 case Xtensa::BEQZ:
356 case Xtensa::BNEZ:
357 case Xtensa::BLTZ:
358 case Xtensa::BGEZ:
359 BrOffset -= 4;
360 return isIntN(12, BrOffset);
361 case Xtensa::BT:
362 case Xtensa::BF:
363 BrOffset -= 4;
364 return isIntN(8, BrOffset);
365 default:
366 llvm_unreachable("Unknown branch opcode");
367 }
368}
369
372 MachineBasicBlock *&FBB,
374 bool AllowModify = false) const {
375 // Most of the code and comments here are boilerplate.
376
377 // Start from the bottom of the block and work up, examining the
378 // terminator instructions.
380 while (I != MBB.begin()) {
381 --I;
382 if (I->isDebugValue())
383 continue;
384
385 // Working from the bottom, when we see a non-terminator instruction, we're
386 // done.
387 if (!isUnpredicatedTerminator(*I))
388 break;
389
390 // A terminator that isn't a branch can't easily be handled by this
391 // analysis.
394 const MachineOperand *ThisTarget;
395 if (!isBranch(I, ThisCond, ThisTarget))
396 return true;
397
398 // Can't handle indirect branches.
399 if (!ThisTarget->isMBB())
400 return true;
401
402 if (ThisCond[0].getImm() == Xtensa::J) {
403 // Handle unconditional branches.
404 if (!AllowModify) {
405 TBB = ThisTarget->getMBB();
406 continue;
407 }
408
409 // If the block has any instructions after a JMP, delete them.
410 while (std::next(I) != MBB.end())
411 std::next(I)->eraseFromParent();
412
413 Cond.clear();
414 FBB = 0;
415
416 // TBB is used to indicate the unconditinal destination.
417 TBB = ThisTarget->getMBB();
418 continue;
419 }
420
421 // Working from the bottom, handle the first conditional branch.
422 if (Cond.empty()) {
423 // FIXME: add X86-style branch swap
424 FBB = TBB;
425 TBB = ThisTarget->getMBB();
426 Cond.push_back(MachineOperand::CreateImm(ThisCond[0].getImm()));
427
428 // push remaining operands
429 for (unsigned int i = 0; i < (I->getNumExplicitOperands() - 1); i++)
430 Cond.push_back(I->getOperand(i));
431
432 continue;
433 }
434
435 // Handle subsequent conditional branches.
436 assert(Cond.size() <= 4);
437 assert(TBB);
438
439 // Only handle the case where all conditional branches branch to the same
440 // destination.
441 if (TBB != ThisTarget->getMBB())
442 return true;
443
444 // If the conditions are the same, we can leave them alone.
445 unsigned OldCond = Cond[0].getImm();
446 if (OldCond == ThisCond[0].getImm())
447 continue;
448 }
449
450 return false;
451}
452
454 int *BytesRemoved) const {
455 // Most of the code and comments here are boilerplate.
457 unsigned Count = 0;
458 if (BytesRemoved)
459 *BytesRemoved = 0;
460
461 while (I != MBB.begin()) {
462 --I;
464 Cond.push_back(MachineOperand::CreateImm(0));
465 const MachineOperand *Target;
466 if (!isBranch(I, Cond, Target))
467 break;
468 if (!Target->isMBB())
469 break;
470 // Remove the branch.
471 if (BytesRemoved)
472 *BytesRemoved += getInstSizeInBytes(*I);
473 I->eraseFromParent();
474 I = MBB.end();
475 ++Count;
476 }
477 return Count;
478}
479
482 ArrayRef<MachineOperand> Cond, const DebugLoc &DL, int *BytesAdded) const {
483 unsigned Count = 0;
484 if (BytesAdded)
485 *BytesAdded = 0;
486 if (FBB) {
487 // Need to build two branches then
488 // one to branch to TBB on Cond
489 // and a second one immediately after to unconditionally jump to FBB
490 Count = insertBranchAtInst(MBB, MBB.end(), TBB, Cond, DL, BytesAdded);
491 auto &MI = *BuildMI(&MBB, DL, get(Xtensa::J)).addMBB(FBB);
492 Count++;
493 if (BytesAdded)
494 *BytesAdded += getInstSizeInBytes(MI);
495 return Count;
496 }
497 // This function inserts the branch at the end of the MBB
498 Count += insertBranchAtInst(MBB, MBB.end(), TBB, Cond, DL, BytesAdded);
499 return Count;
500}
501
503 MachineBasicBlock &DestBB,
504 MachineBasicBlock &RestoreBB,
505 const DebugLoc &DL, int64_t BrOffset,
506 RegScavenger *RS) const {
507 assert(RS && "RegScavenger required for long branching");
508 assert(MBB.empty() &&
509 "new block should be inserted for expanding unconditional branch");
510 assert(MBB.pred_size() == 1);
511
512 MachineFunction *MF = MBB.getParent();
515 auto *XtensaFI = MF->getInfo<XtensaMachineFunctionInfo>();
516 MachineBasicBlock *JumpToMBB = &DestBB;
517
518 if (!isInt<32>(BrOffset))
520 "Branch offsets outside of the signed 32-bit range not supported");
521
522 Register ScratchReg = MRI.createVirtualRegister(&Xtensa::ARRegClass);
523 auto II = MBB.end();
524
525 // Create l32r without last operand. We will add this operand later when
526 // JumpToMMB will be calculated and placed to the ConstantPool.
527 MachineInstr &L32R = *BuildMI(MBB, II, DL, get(Xtensa::L32R), ScratchReg);
528 BuildMI(MBB, II, DL, get(Xtensa::JX)).addReg(ScratchReg, RegState::Kill);
529
530 RS->enterBasicBlockEnd(MBB);
531 Register ScavRegister =
532 RS->scavengeRegisterBackwards(Xtensa::ARRegClass, L32R.getIterator(),
533 /*RestoreAfter=*/false, /*SpAdj=*/0,
534 /*AllowSpill=*/false);
535 if (ScavRegister != Xtensa::NoRegister)
536 RS->setRegUsed(ScavRegister);
537 else {
538 // The case when there is no scavenged register needs special handling.
539 // Pick A8 because it doesn't make a difference
540 ScavRegister = Xtensa::A12;
541
542 int FrameIndex = XtensaFI->getBranchRelaxationScratchFrameIndex();
543 if (FrameIndex == -1)
545 "Unable to properly handle scavenged register for indirect jump, "
546 "function code size is significantly larger than estimated");
547
548 storeRegToStackSlot(MBB, L32R, ScavRegister, /*IsKill=*/true, FrameIndex,
549 &Xtensa::ARRegClass, Register());
550 RI.eliminateFrameIndex(std::prev(L32R.getIterator()),
551 /*SpAdj=*/0, /*FIOperandNum=*/1);
552
553 loadRegFromStackSlot(RestoreBB, RestoreBB.end(), ScavRegister, FrameIndex,
554 &Xtensa::ARRegClass, Register());
555 RI.eliminateFrameIndex(RestoreBB.back(),
556 /*SpAdj=*/0, /*FIOperandNum=*/1);
557 JumpToMBB = &RestoreBB;
558 }
559
560 unsigned LabelId = XtensaFI->createCPLabelId();
561
563 MF->getFunction().getContext(), JumpToMBB, LabelId);
564 unsigned Idx = ConstantPool->getConstantPoolIndex(C, Align(4));
566
567 MRI.replaceRegWith(ScratchReg, ScavRegister);
568 MRI.clearVirtRegs();
569}
570
572 MachineBasicBlock &MBB, MachineInstr *I, int64_t offset,
573 ArrayRef<MachineOperand> Cond, DebugLoc DL, int *BytesAdded) const {
574 assert(Cond.size() <= 4 &&
575 "Xtensa branch conditions have less than four components!");
576
577 if (Cond.empty() || (Cond[0].getImm() == Xtensa::J)) {
578 // Unconditional branch
579 MachineInstr *MI = BuildMI(MBB, I, DL, get(Xtensa::J)).addImm(offset);
580 if (BytesAdded && MI)
581 *BytesAdded += getInstSizeInBytes(*MI);
582 return 1;
583 }
584
585 unsigned Count = 0;
586 unsigned BR_C = Cond[0].getImm();
587 MachineInstr *MI = nullptr;
588 switch (BR_C) {
589 case Xtensa::BEQ:
590 case Xtensa::BNE:
591 case Xtensa::BLT:
592 case Xtensa::BLTU:
593 case Xtensa::BGE:
594 case Xtensa::BGEU:
595 MI = BuildMI(MBB, I, DL, get(BR_C))
596 .addImm(offset)
597 .addReg(Cond[1].getReg())
598 .addReg(Cond[2].getReg());
599 break;
600 case Xtensa::BEQI:
601 case Xtensa::BNEI:
602 case Xtensa::BLTI:
603 case Xtensa::BLTUI:
604 case Xtensa::BGEI:
605 case Xtensa::BGEUI:
606 MI = BuildMI(MBB, I, DL, get(BR_C))
607 .addImm(offset)
608 .addReg(Cond[1].getReg())
609 .addImm(Cond[2].getImm());
610 break;
611 case Xtensa::BEQZ:
612 case Xtensa::BNEZ:
613 case Xtensa::BLTZ:
614 case Xtensa::BGEZ:
615 MI = BuildMI(MBB, I, DL, get(BR_C)).addImm(offset).addReg(Cond[1].getReg());
616 break;
617 case Xtensa::BT:
618 case Xtensa::BF:
619 MI = BuildMI(MBB, I, DL, get(BR_C)).addImm(offset).addReg(Cond[1].getReg());
620 break;
621 default:
622 llvm_unreachable("Invalid branch type!");
623 }
624 if (BytesAdded && MI)
625 *BytesAdded += getInstSizeInBytes(*MI);
626 ++Count;
627 return Count;
628}
629
634 const DebugLoc &DL,
635 int *BytesAdded) const {
636 // Shouldn't be a fall through.
637 assert(TBB && "InsertBranch must not be told to insert a fallthrough");
638 assert(Cond.size() <= 4 &&
639 "Xtensa branch conditions have less than four components!");
640
641 if (Cond.empty() || (Cond[0].getImm() == Xtensa::J)) {
642 // Unconditional branch
643 MachineInstr *MI = BuildMI(MBB, I, DL, get(Xtensa::J)).addMBB(TBB);
644 if (BytesAdded && MI)
645 *BytesAdded += getInstSizeInBytes(*MI);
646 return 1;
647 }
648
649 unsigned Count = 0;
650 unsigned BR_C = Cond[0].getImm();
651 MachineInstr *MI = nullptr;
652 switch (BR_C) {
653 case Xtensa::BEQ:
654 case Xtensa::BNE:
655 case Xtensa::BLT:
656 case Xtensa::BLTU:
657 case Xtensa::BGE:
658 case Xtensa::BGEU:
659 MI = BuildMI(MBB, I, DL, get(BR_C))
660 .addReg(Cond[1].getReg())
661 .addReg(Cond[2].getReg())
662 .addMBB(TBB);
663 break;
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 MI = BuildMI(MBB, I, DL, get(BR_C))
671 .addReg(Cond[1].getReg())
672 .addImm(Cond[2].getImm())
673 .addMBB(TBB);
674 break;
675 case Xtensa::BEQZ:
676 case Xtensa::BNEZ:
677 case Xtensa::BLTZ:
678 case Xtensa::BGEZ:
679 MI = BuildMI(MBB, I, DL, get(BR_C)).addReg(Cond[1].getReg()).addMBB(TBB);
680 break;
681 case Xtensa::BT:
682 case Xtensa::BF:
683 MI = BuildMI(MBB, I, DL, get(BR_C)).addReg(Cond[1].getReg()).addMBB(TBB);
684 break;
685 default:
686 report_fatal_error("Invalid branch type!");
687 }
688 if (BytesAdded && MI)
689 *BytesAdded += getInstSizeInBytes(*MI);
690 ++Count;
691 return Count;
692}
693
696 const MachineOperand *&Target) const {
697 unsigned OpCode = MI->getOpcode();
698 switch (OpCode) {
699 case Xtensa::J:
700 case Xtensa::JX:
701 case Xtensa::BR_JT:
702 Cond[0].setImm(OpCode);
703 Target = &MI->getOperand(0);
704 return true;
705 case Xtensa::BEQ:
706 case Xtensa::BNE:
707 case Xtensa::BLT:
708 case Xtensa::BLTU:
709 case Xtensa::BGE:
710 case Xtensa::BGEU:
711 Cond[0].setImm(OpCode);
712 Target = &MI->getOperand(2);
713 return true;
714
715 case Xtensa::BEQI:
716 case Xtensa::BNEI:
717 case Xtensa::BLTI:
718 case Xtensa::BLTUI:
719 case Xtensa::BGEI:
720 case Xtensa::BGEUI:
721 Cond[0].setImm(OpCode);
722 Target = &MI->getOperand(2);
723 return true;
724
725 case Xtensa::BEQZ:
726 case Xtensa::BNEZ:
727 case Xtensa::BLTZ:
728 case Xtensa::BGEZ:
729 Cond[0].setImm(OpCode);
730 Target = &MI->getOperand(1);
731 return true;
732
733 case Xtensa::BT:
734 case Xtensa::BF:
735 Cond[0].setImm(OpCode);
736 Target = &MI->getOperand(1);
737 return true;
738
739 default:
740 assert(!MI->getDesc().isBranch() && "Unknown branch opcode");
741 return false;
742 }
743}
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition MD5.cpp:57
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
Promote Memory to Register
Definition Mem2Reg.cpp:110
static MCRegister 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
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
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.
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
MachineInstrBundleIterator< MachineInstr > iterator
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.
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,...
Wrapper class representing virtual and physical registers.
Definition Register.h:20
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.
Target - Wrapper for Target specific information.
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
Definition Type.cpp:296
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
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
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIdx, const TargetRegisterClass *RC, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
unsigned insertConstBranchAtInst(MachineBasicBlock &MBB, MachineInstr *I, int64_t offset, ArrayRef< MachineOperand > Cond, DebugLoc DL, int *BytesAdded) const
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
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
self_iterator getIterator()
Definition ilist_node.h:123
#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.
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
Definition Threading.h:280
@ Offset
Definition DWP.cpp:532
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:165
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)
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
FunctionAddr VTableAddr Count
Definition InstrProf.h:139
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:248
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.