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