LLVM 23.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, unsigned SubReg,
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 case TargetOpcode::BUNDLE:
227 return getInstBundleSize(MI);
228 default:
229 return MI.getDesc().getSize();
230 }
231}
232
235 assert(Cond.size() <= 4 && "Invalid branch condition!");
236
237 switch (Cond[0].getImm()) {
238 case Xtensa::BEQ:
239 Cond[0].setImm(Xtensa::BNE);
240 return false;
241 case Xtensa::BNE:
242 Cond[0].setImm(Xtensa::BEQ);
243 return false;
244 case Xtensa::BLT:
245 Cond[0].setImm(Xtensa::BGE);
246 return false;
247 case Xtensa::BGE:
248 Cond[0].setImm(Xtensa::BLT);
249 return false;
250 case Xtensa::BLTU:
251 Cond[0].setImm(Xtensa::BGEU);
252 return false;
253 case Xtensa::BGEU:
254 Cond[0].setImm(Xtensa::BLTU);
255 return false;
256 case Xtensa::BEQI:
257 Cond[0].setImm(Xtensa::BNEI);
258 return false;
259 case Xtensa::BNEI:
260 Cond[0].setImm(Xtensa::BEQI);
261 return false;
262 case Xtensa::BGEI:
263 Cond[0].setImm(Xtensa::BLTI);
264 return false;
265 case Xtensa::BLTI:
266 Cond[0].setImm(Xtensa::BGEI);
267 return false;
268 case Xtensa::BGEUI:
269 Cond[0].setImm(Xtensa::BLTUI);
270 return false;
271 case Xtensa::BLTUI:
272 Cond[0].setImm(Xtensa::BGEUI);
273 return false;
274 case Xtensa::BEQZ:
275 Cond[0].setImm(Xtensa::BNEZ);
276 return false;
277 case Xtensa::BNEZ:
278 Cond[0].setImm(Xtensa::BEQZ);
279 return false;
280 case Xtensa::BLTZ:
281 Cond[0].setImm(Xtensa::BGEZ);
282 return false;
283 case Xtensa::BGEZ:
284 Cond[0].setImm(Xtensa::BLTZ);
285 return false;
286 case Xtensa::BF:
287 Cond[0].setImm(Xtensa::BT);
288 return false;
289 case Xtensa::BT:
290 Cond[0].setImm(Xtensa::BF);
291 return false;
292 default:
293 report_fatal_error("Invalid branch condition!");
294 }
295}
296
299 unsigned OpCode = MI.getOpcode();
300 switch (OpCode) {
301 case Xtensa::BR_JT:
302 case Xtensa::JX:
303 return nullptr;
304 case Xtensa::J:
305 return MI.getOperand(0).getMBB();
306 case Xtensa::BEQ:
307 case Xtensa::BNE:
308 case Xtensa::BLT:
309 case Xtensa::BLTU:
310 case Xtensa::BGE:
311 case Xtensa::BGEU:
312 return MI.getOperand(2).getMBB();
313 case Xtensa::BEQI:
314 case Xtensa::BNEI:
315 case Xtensa::BLTI:
316 case Xtensa::BLTUI:
317 case Xtensa::BGEI:
318 case Xtensa::BGEUI:
319 return MI.getOperand(2).getMBB();
320 case Xtensa::BEQZ:
321 case Xtensa::BNEZ:
322 case Xtensa::BLTZ:
323 case Xtensa::BGEZ:
324 return MI.getOperand(1).getMBB();
325 case Xtensa::BT:
326 case Xtensa::BF:
327 return MI.getOperand(1).getMBB();
328 default:
329 llvm_unreachable("Unknown branch opcode");
330 }
331}
332
334 int64_t BrOffset) const {
335 switch (BranchOp) {
336 case Xtensa::J:
337 BrOffset -= 4;
338 return isIntN(18, BrOffset);
339 case Xtensa::JX:
340 return true;
341 case Xtensa::BR_JT:
342 return true;
343 case Xtensa::BEQ:
344 case Xtensa::BNE:
345 case Xtensa::BLT:
346 case Xtensa::BLTU:
347 case Xtensa::BGE:
348 case Xtensa::BGEU:
349 case Xtensa::BEQI:
350 case Xtensa::BNEI:
351 case Xtensa::BLTI:
352 case Xtensa::BLTUI:
353 case Xtensa::BGEI:
354 case Xtensa::BGEUI:
355 BrOffset -= 4;
356 return isIntN(8, BrOffset);
357 case Xtensa::BEQZ:
358 case Xtensa::BNEZ:
359 case Xtensa::BLTZ:
360 case Xtensa::BGEZ:
361 BrOffset -= 4;
362 return isIntN(12, BrOffset);
363 case Xtensa::BT:
364 case Xtensa::BF:
365 BrOffset -= 4;
366 return isIntN(8, BrOffset);
367 default:
368 llvm_unreachable("Unknown branch opcode");
369 }
370}
371
374 MachineBasicBlock *&FBB,
376 bool AllowModify = false) const {
377 // Most of the code and comments here are boilerplate.
378
379 // Start from the bottom of the block and work up, examining the
380 // terminator instructions.
382 while (I != MBB.begin()) {
383 --I;
384 if (I->isDebugValue())
385 continue;
386
387 // Working from the bottom, when we see a non-terminator instruction, we're
388 // done.
389 if (!isUnpredicatedTerminator(*I))
390 break;
391
392 // A terminator that isn't a branch can't easily be handled by this
393 // analysis.
396 const MachineOperand *ThisTarget;
397 if (!isBranch(I, ThisCond, ThisTarget))
398 return true;
399
400 // Can't handle indirect branches.
401 if (!ThisTarget->isMBB())
402 return true;
403
404 if (ThisCond[0].getImm() == Xtensa::J) {
405 // Handle unconditional branches.
406 if (!AllowModify) {
407 TBB = ThisTarget->getMBB();
408 continue;
409 }
410
411 // If the block has any instructions after a JMP, delete them.
412 while (std::next(I) != MBB.end())
413 std::next(I)->eraseFromParent();
414
415 Cond.clear();
416 FBB = 0;
417
418 // TBB is used to indicate the unconditinal destination.
419 TBB = ThisTarget->getMBB();
420 continue;
421 }
422
423 // Working from the bottom, handle the first conditional branch.
424 if (Cond.empty()) {
425 // FIXME: add X86-style branch swap
426 FBB = TBB;
427 TBB = ThisTarget->getMBB();
428 Cond.push_back(MachineOperand::CreateImm(ThisCond[0].getImm()));
429
430 // push remaining operands
431 for (unsigned int i = 0; i < (I->getNumExplicitOperands() - 1); i++)
432 Cond.push_back(I->getOperand(i));
433
434 continue;
435 }
436
437 // Handle subsequent conditional branches.
438 assert(Cond.size() <= 4);
439 assert(TBB);
440
441 // Only handle the case where all conditional branches branch to the same
442 // destination.
443 if (TBB != ThisTarget->getMBB())
444 return true;
445
446 // If the conditions are the same, we can leave them alone.
447 unsigned OldCond = Cond[0].getImm();
448 if (OldCond == ThisCond[0].getImm())
449 continue;
450 }
451
452 return false;
453}
454
456 int *BytesRemoved) const {
457 // Most of the code and comments here are boilerplate.
459 unsigned Count = 0;
460 if (BytesRemoved)
461 *BytesRemoved = 0;
462
463 while (I != MBB.begin()) {
464 --I;
466 Cond.push_back(MachineOperand::CreateImm(0));
467 const MachineOperand *Target;
468 if (!isBranch(I, Cond, Target))
469 break;
470 if (!Target->isMBB())
471 break;
472 // Remove the branch.
473 if (BytesRemoved)
474 *BytesRemoved += getInstSizeInBytes(*I);
475 I->eraseFromParent();
476 I = MBB.end();
477 ++Count;
478 }
479 return Count;
480}
481
484 ArrayRef<MachineOperand> Cond, const DebugLoc &DL, int *BytesAdded) const {
485 unsigned Count = 0;
486 if (BytesAdded)
487 *BytesAdded = 0;
488 if (FBB) {
489 // Need to build two branches then
490 // one to branch to TBB on Cond
491 // and a second one immediately after to unconditionally jump to FBB
492 Count = insertBranchAtInst(MBB, MBB.end(), TBB, Cond, DL, BytesAdded);
493 auto &MI = *BuildMI(&MBB, DL, get(Xtensa::J)).addMBB(FBB);
494 Count++;
495 if (BytesAdded)
496 *BytesAdded += getInstSizeInBytes(MI);
497 return Count;
498 }
499 // This function inserts the branch at the end of the MBB
500 Count += insertBranchAtInst(MBB, MBB.end(), TBB, Cond, DL, BytesAdded);
501 return Count;
502}
503
505 MachineBasicBlock &DestBB,
506 MachineBasicBlock &RestoreBB,
507 const DebugLoc &DL, int64_t BrOffset,
508 RegScavenger *RS) const {
509 assert(RS && "RegScavenger required for long branching");
510 assert(MBB.empty() &&
511 "new block should be inserted for expanding unconditional branch");
512 assert(MBB.pred_size() == 1);
513
514 MachineFunction *MF = MBB.getParent();
515 MachineRegisterInfo &MRI = MF->getRegInfo();
517 auto *XtensaFI = MF->getInfo<XtensaMachineFunctionInfo>();
518 MachineBasicBlock *JumpToMBB = &DestBB;
519
520 if (!isInt<32>(BrOffset))
522 "Branch offsets outside of the signed 32-bit range not supported");
523
524 Register ScratchReg = MRI.createVirtualRegister(&Xtensa::ARRegClass);
525 auto II = MBB.end();
526
527 // Create l32r without last operand. We will add this operand later when
528 // JumpToMMB will be calculated and placed to the ConstantPool.
529 MachineInstr &L32R = *BuildMI(MBB, II, DL, get(Xtensa::L32R), ScratchReg);
530 BuildMI(MBB, II, DL, get(Xtensa::JX)).addReg(ScratchReg, RegState::Kill);
531
532 RS->enterBasicBlockEnd(MBB);
533 Register ScavRegister =
534 RS->scavengeRegisterBackwards(Xtensa::ARRegClass, L32R.getIterator(),
535 /*RestoreAfter=*/false, /*SpAdj=*/0,
536 /*AllowSpill=*/false);
537 if (ScavRegister != Xtensa::NoRegister)
538 RS->setRegUsed(ScavRegister);
539 else {
540 // The case when there is no scavenged register needs special handling.
541 // Pick A8 because it doesn't make a difference
542 ScavRegister = Xtensa::A12;
543
544 int FrameIndex = XtensaFI->getBranchRelaxationScratchFrameIndex();
545 if (FrameIndex == -1)
547 "Unable to properly handle scavenged register for indirect jump, "
548 "function code size is significantly larger than estimated");
549
550 storeRegToStackSlot(MBB, L32R, ScavRegister, /*IsKill=*/true, FrameIndex,
551 &Xtensa::ARRegClass, Register());
552 RI.eliminateFrameIndex(std::prev(L32R.getIterator()),
553 /*SpAdj=*/0, /*FIOperandNum=*/1);
554
555 loadRegFromStackSlot(RestoreBB, RestoreBB.end(), ScavRegister, FrameIndex,
556 &Xtensa::ARRegClass, Register());
557 RI.eliminateFrameIndex(RestoreBB.back(),
558 /*SpAdj=*/0, /*FIOperandNum=*/1);
559 JumpToMBB = &RestoreBB;
560 }
561
562 unsigned LabelId = XtensaFI->createCPLabelId();
563
565 MF->getFunction().getContext(), JumpToMBB, LabelId);
566 unsigned Idx = ConstantPool->getConstantPoolIndex(C, Align(4));
568
569 MRI.replaceRegWith(ScratchReg, ScavRegister);
570 MRI.clearVirtRegs();
571}
572
574 MachineBasicBlock &MBB, MachineInstr *I, int64_t offset,
575 ArrayRef<MachineOperand> Cond, DebugLoc DL, int *BytesAdded) const {
576 assert(Cond.size() <= 4 &&
577 "Xtensa branch conditions have less than four components!");
578
579 if (Cond.empty() || (Cond[0].getImm() == Xtensa::J)) {
580 // Unconditional branch
581 MachineInstr *MI = BuildMI(MBB, I, DL, get(Xtensa::J)).addImm(offset);
582 if (BytesAdded && MI)
583 *BytesAdded += getInstSizeInBytes(*MI);
584 return 1;
585 }
586
587 unsigned Count = 0;
588 unsigned BR_C = Cond[0].getImm();
589 MachineInstr *MI = nullptr;
590 switch (BR_C) {
591 case Xtensa::BEQ:
592 case Xtensa::BNE:
593 case Xtensa::BLT:
594 case Xtensa::BLTU:
595 case Xtensa::BGE:
596 case Xtensa::BGEU:
597 MI = BuildMI(MBB, I, DL, get(BR_C))
598 .addImm(offset)
599 .addReg(Cond[1].getReg())
600 .addReg(Cond[2].getReg());
601 break;
602 case Xtensa::BEQI:
603 case Xtensa::BNEI:
604 case Xtensa::BLTI:
605 case Xtensa::BLTUI:
606 case Xtensa::BGEI:
607 case Xtensa::BGEUI:
608 MI = BuildMI(MBB, I, DL, get(BR_C))
609 .addImm(offset)
610 .addReg(Cond[1].getReg())
611 .addImm(Cond[2].getImm());
612 break;
613 case Xtensa::BEQZ:
614 case Xtensa::BNEZ:
615 case Xtensa::BLTZ:
616 case Xtensa::BGEZ:
617 MI = BuildMI(MBB, I, DL, get(BR_C)).addImm(offset).addReg(Cond[1].getReg());
618 break;
619 case Xtensa::BT:
620 case Xtensa::BF:
621 MI = BuildMI(MBB, I, DL, get(BR_C)).addImm(offset).addReg(Cond[1].getReg());
622 break;
623 default:
624 llvm_unreachable("Invalid branch type!");
625 }
626 if (BytesAdded && MI)
627 *BytesAdded += getInstSizeInBytes(*MI);
628 ++Count;
629 return Count;
630}
631
636 const DebugLoc &DL,
637 int *BytesAdded) const {
638 // Shouldn't be a fall through.
639 assert(TBB && "InsertBranch must not be told to insert a fallthrough");
640 assert(Cond.size() <= 4 &&
641 "Xtensa branch conditions have less than four components!");
642
643 if (Cond.empty() || (Cond[0].getImm() == Xtensa::J)) {
644 // Unconditional branch
645 MachineInstr *MI = BuildMI(MBB, I, DL, get(Xtensa::J)).addMBB(TBB);
646 if (BytesAdded && MI)
647 *BytesAdded += getInstSizeInBytes(*MI);
648 return 1;
649 }
650
651 unsigned Count = 0;
652 unsigned BR_C = Cond[0].getImm();
653 MachineInstr *MI = nullptr;
654 switch (BR_C) {
655 case Xtensa::BEQ:
656 case Xtensa::BNE:
657 case Xtensa::BLT:
658 case Xtensa::BLTU:
659 case Xtensa::BGE:
660 case Xtensa::BGEU:
661 MI = BuildMI(MBB, I, DL, get(BR_C))
662 .addReg(Cond[1].getReg())
663 .addReg(Cond[2].getReg())
664 .addMBB(TBB);
665 break;
666 case Xtensa::BEQI:
667 case Xtensa::BNEI:
668 case Xtensa::BLTI:
669 case Xtensa::BLTUI:
670 case Xtensa::BGEI:
671 case Xtensa::BGEUI:
672 MI = BuildMI(MBB, I, DL, get(BR_C))
673 .addReg(Cond[1].getReg())
674 .addImm(Cond[2].getImm())
675 .addMBB(TBB);
676 break;
677 case Xtensa::BEQZ:
678 case Xtensa::BNEZ:
679 case Xtensa::BLTZ:
680 case Xtensa::BGEZ:
681 MI = BuildMI(MBB, I, DL, get(BR_C)).addReg(Cond[1].getReg()).addMBB(TBB);
682 break;
683 case Xtensa::BT:
684 case Xtensa::BF:
685 MI = BuildMI(MBB, I, DL, get(BR_C)).addReg(Cond[1].getReg()).addMBB(TBB);
686 break;
687 default:
688 report_fatal_error("Invalid branch type!");
689 }
690 if (BytesAdded && MI)
691 *BytesAdded += getInstSizeInBytes(*MI);
692 ++Count;
693 return Count;
694}
695
698 const MachineOperand *&Target) const {
699 unsigned OpCode = MI->getOpcode();
700 switch (OpCode) {
701 case Xtensa::J:
702 case Xtensa::JX:
703 case Xtensa::BR_JT:
704 Cond[0].setImm(OpCode);
705 Target = &MI->getOperand(0);
706 return true;
707 case Xtensa::BEQ:
708 case Xtensa::BNE:
709 case Xtensa::BLT:
710 case Xtensa::BLTU:
711 case Xtensa::BGE:
712 case Xtensa::BGEU:
713 Cond[0].setImm(OpCode);
714 Target = &MI->getOperand(2);
715 return true;
716
717 case Xtensa::BEQI:
718 case Xtensa::BNEI:
719 case Xtensa::BLTI:
720 case Xtensa::BLTUI:
721 case Xtensa::BGEI:
722 case Xtensa::BGEUI:
723 Cond[0].setImm(OpCode);
724 Target = &MI->getOperand(2);
725 return true;
726
727 case Xtensa::BEQZ:
728 case Xtensa::BNEZ:
729 case Xtensa::BLTZ:
730 case Xtensa::BGEZ:
731 Cond[0].setImm(OpCode);
732 Target = &MI->getOperand(1);
733 return true;
734
735 case Xtensa::BT:
736 case Xtensa::BF:
737 Cond[0].setImm(OpCode);
738 Target = &MI->getOperand(1);
739 return true;
740
741 default:
742 assert(!MI->getDesc().isBranch() && "Unknown branch opcode");
743 return false;
744 }
745}
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:483
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:123
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition Function.cpp:358
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 & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
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 & 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,...
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
LLVM_ABI void clearVirtRegs()
clearVirtRegs - Remove all virtual registers (after physreg assignment).
LLVM_ABI void replaceRegWith(Register FromReg, Register ToReg)
replaceRegWith - Replace all instances of FromReg with ToReg in the machine function.
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:313
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
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
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIdx, const TargetRegisterClass *RC, Register VReg, unsigned SubReg=0, 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
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
@ Kill
The last use of a register.
constexpr RegState getKillRegState(bool B)
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:163
FunctionAddr VTableAddr Count
Definition InstrProf.h:139
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.