xref: /llvm-project/llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp (revision f7d8336a2fb4fad4a6efe5af9b0a10ddd970f6d3)
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"
16 #include "XtensaConstantPoolValue.h"
17 #include "XtensaMachineFunctionInfo.h"
18 #include "XtensaTargetMachine.h"
19 #include "llvm/CodeGen/MachineConstantPool.h"
20 #include "llvm/CodeGen/MachineFrameInfo.h"
21 #include "llvm/CodeGen/MachineInstrBuilder.h"
22 #include "llvm/CodeGen/MachineRegisterInfo.h"
23 #include "llvm/CodeGen/RegisterScavenging.h"
24 
25 #define GET_INSTRINFO_CTOR_DTOR
26 #include "XtensaGenInstrInfo.inc"
27 
28 using namespace llvm;
29 
30 static const MachineInstrBuilder &
31 addFrameReference(const MachineInstrBuilder &MIB, int FI) {
32   MachineInstr *MI = MIB;
33   MachineFunction &MF = *MI->getParent()->getParent();
34   MachineFrameInfo &MFFrame = MF.getFrameInfo();
35   const MCInstrDesc &MCID = MI->getDesc();
36   MachineMemOperand::Flags Flags = MachineMemOperand::MONone;
37   if (MCID.mayLoad())
38     Flags |= MachineMemOperand::MOLoad;
39   if (MCID.mayStore())
40     Flags |= MachineMemOperand::MOStore;
41   int64_t Offset = 0;
42   Align Alignment = MFFrame.getObjectAlign(FI);
43 
44   MachineMemOperand *MMO =
45       MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(MF, FI, Offset),
46                               Flags, MFFrame.getObjectSize(FI), Alignment);
47   return MIB.addFrameIndex(FI).addImm(Offset).addMemOperand(MMO);
48 }
49 
50 XtensaInstrInfo::XtensaInstrInfo(const XtensaSubtarget &STI)
51     : XtensaGenInstrInfo(Xtensa::ADJCALLSTACKDOWN, Xtensa::ADJCALLSTACKUP),
52       RI(STI), STI(STI) {}
53 
54 Register XtensaInstrInfo::isLoadFromStackSlot(const MachineInstr &MI,
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 
66 Register XtensaInstrInfo::isStoreToStackSlot(const MachineInstr &MI,
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.
79 void XtensaInstrInfo::adjustStackPtr(unsigned SP, int64_t Amount,
80                                      MachineBasicBlock &MBB,
81                                      MachineBasicBlock::iterator I) const {
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   unsigned Reg = RegInfo.createVirtualRegister(RC);
92 
93   if (isInt<8>(Amount)) { // addi sp, sp, amount
94     BuildMI(MBB, I, DL, get(Xtensa::ADDI), Reg).addReg(SP).addImm(Amount);
95   } else { // Expand immediate that doesn't fit in 8-bit.
96     unsigned Reg1;
97     loadImmediate(MBB, I, &Reg1, Amount);
98     BuildMI(MBB, I, DL, get(Xtensa::ADD), Reg)
99         .addReg(SP)
100         .addReg(Reg1, RegState::Kill);
101   }
102 
103   BuildMI(MBB, I, DL, get(Xtensa::OR), SP)
104       .addReg(Reg, RegState::Kill)
105       .addReg(Reg, RegState::Kill);
106 }
107 
108 void XtensaInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
109                                   MachineBasicBlock::iterator MBBI,
110                                   const DebugLoc &DL, MCRegister DestReg,
111                                   MCRegister SrcReg, bool KillSrc,
112                                   bool RenamableDest, bool RenamableSrc) const {
113   // The MOV instruction is not present in core ISA,
114   // so use OR instruction.
115   if (Xtensa::ARRegClass.contains(DestReg, SrcReg))
116     BuildMI(MBB, MBBI, DL, get(Xtensa::OR), DestReg)
117         .addReg(SrcReg, getKillRegState(KillSrc))
118         .addReg(SrcReg, getKillRegState(KillSrc));
119   else
120     report_fatal_error("Impossible reg-to-reg copy");
121 }
122 
123 void XtensaInstrInfo::storeRegToStackSlot(
124     MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg,
125     bool isKill, int FrameIdx, const TargetRegisterClass *RC,
126     const TargetRegisterInfo *TRI, Register VReg,
127     MachineInstr::MIFlag Flags) const {
128   DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
129   unsigned LoadOpcode, StoreOpcode;
130   getLoadStoreOpcodes(RC, LoadOpcode, StoreOpcode, FrameIdx);
131   MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, get(StoreOpcode))
132                                 .addReg(SrcReg, getKillRegState(isKill));
133   addFrameReference(MIB, FrameIdx);
134 }
135 
136 void XtensaInstrInfo::loadRegFromStackSlot(
137     MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg,
138     int FrameIdx, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI,
139     Register VReg, MachineInstr::MIFlag Flags) const {
140   DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
141   unsigned LoadOpcode, StoreOpcode;
142   getLoadStoreOpcodes(RC, LoadOpcode, StoreOpcode, FrameIdx);
143   addFrameReference(BuildMI(MBB, MBBI, DL, get(LoadOpcode), DestReg), FrameIdx);
144 }
145 
146 void XtensaInstrInfo::getLoadStoreOpcodes(const TargetRegisterClass *RC,
147                                           unsigned &LoadOpcode,
148                                           unsigned &StoreOpcode,
149                                           int64_t offset) const {
150   assert((RC == &Xtensa::ARRegClass) &&
151          "Unsupported regclass to load or store");
152 
153   LoadOpcode = Xtensa::L32I;
154   StoreOpcode = Xtensa::S32I;
155 }
156 
157 void XtensaInstrInfo::loadImmediate(MachineBasicBlock &MBB,
158                                     MachineBasicBlock::iterator MBBI,
159                                     unsigned *Reg, int64_t Value) const {
160   DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
161   MachineRegisterInfo &RegInfo = MBB.getParent()->getRegInfo();
162   const TargetRegisterClass *RC = &Xtensa::ARRegClass;
163 
164   // create virtual reg to store immediate
165   *Reg = RegInfo.createVirtualRegister(RC);
166   if (Value >= -2048 && Value <= 2047) {
167     BuildMI(MBB, MBBI, DL, get(Xtensa::MOVI), *Reg).addImm(Value);
168   } else if (Value >= -32768 && Value <= 32767) {
169     int Low = Value & 0xFF;
170     int High = Value & ~0xFF;
171 
172     BuildMI(MBB, MBBI, DL, get(Xtensa::MOVI), *Reg).addImm(Low);
173     BuildMI(MBB, MBBI, DL, get(Xtensa::ADDMI), *Reg).addReg(*Reg).addImm(High);
174   } else if (Value >= -4294967296LL && Value <= 4294967295LL) {
175     // 32 bit arbitrary constant
176     MachineConstantPool *MCP = MBB.getParent()->getConstantPool();
177     uint64_t UVal = ((uint64_t)Value) & 0xFFFFFFFFLL;
178     const Constant *CVal = ConstantInt::get(
179         Type::getInt32Ty(MBB.getParent()->getFunction().getContext()), UVal,
180         false);
181     unsigned Idx = MCP->getConstantPoolIndex(CVal, Align(2U));
182     //	MCSymbol MSym
183     BuildMI(MBB, MBBI, DL, get(Xtensa::L32R), *Reg).addConstantPoolIndex(Idx);
184   } else {
185     // use L32R to let assembler load immediate best
186     // TODO replace to L32R
187     report_fatal_error("Unsupported load immediate value");
188   }
189 }
190 
191 unsigned XtensaInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
192   switch (MI.getOpcode()) {
193   case TargetOpcode::INLINEASM: { // Inline Asm: Variable size.
194     const MachineFunction *MF = MI.getParent()->getParent();
195     const char *AsmStr = MI.getOperand(0).getSymbolName();
196     return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo());
197   }
198   default:
199     return MI.getDesc().getSize();
200   }
201 }
202 
203 bool XtensaInstrInfo::reverseBranchCondition(
204     SmallVectorImpl<MachineOperand> &Cond) const {
205   assert(Cond.size() <= 4 && "Invalid branch condition!");
206 
207   switch (Cond[0].getImm()) {
208   case Xtensa::BEQ:
209     Cond[0].setImm(Xtensa::BNE);
210     return false;
211   case Xtensa::BNE:
212     Cond[0].setImm(Xtensa::BEQ);
213     return false;
214   case Xtensa::BLT:
215     Cond[0].setImm(Xtensa::BGE);
216     return false;
217   case Xtensa::BGE:
218     Cond[0].setImm(Xtensa::BLT);
219     return false;
220   case Xtensa::BLTU:
221     Cond[0].setImm(Xtensa::BGEU);
222     return false;
223   case Xtensa::BGEU:
224     Cond[0].setImm(Xtensa::BLTU);
225     return false;
226   case Xtensa::BEQI:
227     Cond[0].setImm(Xtensa::BNEI);
228     return false;
229   case Xtensa::BNEI:
230     Cond[0].setImm(Xtensa::BEQI);
231     return false;
232   case Xtensa::BGEI:
233     Cond[0].setImm(Xtensa::BLTI);
234     return false;
235   case Xtensa::BLTI:
236     Cond[0].setImm(Xtensa::BGEI);
237     return false;
238   case Xtensa::BGEUI:
239     Cond[0].setImm(Xtensa::BLTUI);
240     return false;
241   case Xtensa::BLTUI:
242     Cond[0].setImm(Xtensa::BGEUI);
243     return false;
244   case Xtensa::BEQZ:
245     Cond[0].setImm(Xtensa::BNEZ);
246     return false;
247   case Xtensa::BNEZ:
248     Cond[0].setImm(Xtensa::BEQZ);
249     return false;
250   case Xtensa::BLTZ:
251     Cond[0].setImm(Xtensa::BGEZ);
252     return false;
253   case Xtensa::BGEZ:
254     Cond[0].setImm(Xtensa::BLTZ);
255     return false;
256   default:
257     report_fatal_error("Invalid branch condition!");
258   }
259 }
260 
261 MachineBasicBlock *
262 XtensaInstrInfo::getBranchDestBlock(const MachineInstr &MI) const {
263   unsigned OpCode = MI.getOpcode();
264   switch (OpCode) {
265   case Xtensa::BR_JT:
266   case Xtensa::JX:
267     return nullptr;
268   case Xtensa::J:
269     return MI.getOperand(0).getMBB();
270   case Xtensa::BEQ:
271   case Xtensa::BNE:
272   case Xtensa::BLT:
273   case Xtensa::BLTU:
274   case Xtensa::BGE:
275   case Xtensa::BGEU:
276     return MI.getOperand(2).getMBB();
277   case Xtensa::BEQI:
278   case Xtensa::BNEI:
279   case Xtensa::BLTI:
280   case Xtensa::BLTUI:
281   case Xtensa::BGEI:
282   case Xtensa::BGEUI:
283     return MI.getOperand(2).getMBB();
284   case Xtensa::BEQZ:
285   case Xtensa::BNEZ:
286   case Xtensa::BLTZ:
287   case Xtensa::BGEZ:
288     return MI.getOperand(1).getMBB();
289   default:
290     llvm_unreachable("Unknown branch opcode");
291   }
292 }
293 
294 bool XtensaInstrInfo::isBranchOffsetInRange(unsigned BranchOp,
295                                             int64_t BrOffset) const {
296   switch (BranchOp) {
297   case Xtensa::J:
298     BrOffset -= 4;
299     return isIntN(18, BrOffset);
300   case Xtensa::JX:
301     return true;
302   case Xtensa::BR_JT:
303     return true;
304   case Xtensa::BEQ:
305   case Xtensa::BNE:
306   case Xtensa::BLT:
307   case Xtensa::BLTU:
308   case Xtensa::BGE:
309   case Xtensa::BGEU:
310   case Xtensa::BEQI:
311   case Xtensa::BNEI:
312   case Xtensa::BLTI:
313   case Xtensa::BLTUI:
314   case Xtensa::BGEI:
315   case Xtensa::BGEUI:
316     BrOffset -= 4;
317     return isIntN(8, BrOffset);
318   case Xtensa::BEQZ:
319   case Xtensa::BNEZ:
320   case Xtensa::BLTZ:
321   case Xtensa::BGEZ:
322     BrOffset -= 4;
323     return isIntN(12, BrOffset);
324   default:
325     llvm_unreachable("Unknown branch opcode");
326   }
327 }
328 
329 bool XtensaInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
330                                     MachineBasicBlock *&TBB,
331                                     MachineBasicBlock *&FBB,
332                                     SmallVectorImpl<MachineOperand> &Cond,
333                                     bool AllowModify = false) const {
334   // Most of the code and comments here are boilerplate.
335 
336   // Start from the bottom of the block and work up, examining the
337   // terminator instructions.
338   MachineBasicBlock::iterator I = MBB.end();
339   while (I != MBB.begin()) {
340     --I;
341     if (I->isDebugValue())
342       continue;
343 
344     // Working from the bottom, when we see a non-terminator instruction, we're
345     // done.
346     if (!isUnpredicatedTerminator(*I))
347       break;
348 
349     // A terminator that isn't a branch can't easily be handled by this
350     // analysis.
351     SmallVector<MachineOperand, 4> ThisCond;
352     ThisCond.push_back(MachineOperand::CreateImm(0));
353     const MachineOperand *ThisTarget;
354     if (!isBranch(I, ThisCond, ThisTarget))
355       return true;
356 
357     // Can't handle indirect branches.
358     if (!ThisTarget->isMBB())
359       return true;
360 
361     if (ThisCond[0].getImm() == Xtensa::J) {
362       // Handle unconditional branches.
363       if (!AllowModify) {
364         TBB = ThisTarget->getMBB();
365         continue;
366       }
367 
368       // If the block has any instructions after a JMP, delete them.
369       while (std::next(I) != MBB.end())
370         std::next(I)->eraseFromParent();
371 
372       Cond.clear();
373       FBB = 0;
374 
375       // TBB is used to indicate the unconditinal destination.
376       TBB = ThisTarget->getMBB();
377       continue;
378     }
379 
380     // Working from the bottom, handle the first conditional branch.
381     if (Cond.empty()) {
382       // FIXME: add X86-style branch swap
383       FBB = TBB;
384       TBB = ThisTarget->getMBB();
385       Cond.push_back(MachineOperand::CreateImm(ThisCond[0].getImm()));
386 
387       // push remaining operands
388       for (unsigned int i = 0; i < (I->getNumExplicitOperands() - 1); i++)
389         Cond.push_back(I->getOperand(i));
390 
391       continue;
392     }
393 
394     // Handle subsequent conditional branches.
395     assert(Cond.size() <= 4);
396     assert(TBB);
397 
398     // Only handle the case where all conditional branches branch to the same
399     // destination.
400     if (TBB != ThisTarget->getMBB())
401       return true;
402 
403     // If the conditions are the same, we can leave them alone.
404     unsigned OldCond = Cond[0].getImm();
405     if (OldCond == ThisCond[0].getImm())
406       continue;
407   }
408 
409   return false;
410 }
411 
412 unsigned XtensaInstrInfo::removeBranch(MachineBasicBlock &MBB,
413                                        int *BytesRemoved) const {
414   // Most of the code and comments here are boilerplate.
415   MachineBasicBlock::iterator I = MBB.end();
416   unsigned Count = 0;
417   if (BytesRemoved)
418     *BytesRemoved = 0;
419 
420   while (I != MBB.begin()) {
421     --I;
422     SmallVector<MachineOperand, 4> Cond;
423     Cond.push_back(MachineOperand::CreateImm(0));
424     const MachineOperand *Target;
425     if (!isBranch(I, Cond, Target))
426       break;
427     if (!Target->isMBB())
428       break;
429     // Remove the branch.
430     if (BytesRemoved)
431       *BytesRemoved += getInstSizeInBytes(*I);
432     I->eraseFromParent();
433     I = MBB.end();
434     ++Count;
435   }
436   return Count;
437 }
438 
439 unsigned XtensaInstrInfo::insertBranch(
440     MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB,
441     ArrayRef<MachineOperand> Cond, const DebugLoc &DL, int *BytesAdded) const {
442   unsigned Count = 0;
443   if (BytesAdded)
444     *BytesAdded = 0;
445   if (FBB) {
446     // Need to build two branches then
447     // one to branch to TBB on Cond
448     // and a second one immediately after to unconditionally jump to FBB
449     Count = insertBranchAtInst(MBB, MBB.end(), TBB, Cond, DL, BytesAdded);
450     auto &MI = *BuildMI(&MBB, DL, get(Xtensa::J)).addMBB(FBB);
451     Count++;
452     if (BytesAdded)
453       *BytesAdded += getInstSizeInBytes(MI);
454     return Count;
455   }
456   // This function inserts the branch at the end of the MBB
457   Count += insertBranchAtInst(MBB, MBB.end(), TBB, Cond, DL, BytesAdded);
458   return Count;
459 }
460 
461 void XtensaInstrInfo::insertIndirectBranch(MachineBasicBlock &MBB,
462                                            MachineBasicBlock &DestBB,
463                                            MachineBasicBlock &RestoreBB,
464                                            const DebugLoc &DL, int64_t BrOffset,
465                                            RegScavenger *RS) const {
466   assert(RS && "RegScavenger required for long branching");
467   assert(MBB.empty() &&
468          "new block should be inserted for expanding unconditional branch");
469   assert(MBB.pred_size() == 1);
470 
471   MachineFunction *MF = MBB.getParent();
472   MachineRegisterInfo &MRI = MF->getRegInfo();
473   MachineConstantPool *ConstantPool = MF->getConstantPool();
474   auto *XtensaFI = MF->getInfo<XtensaMachineFunctionInfo>();
475   MachineBasicBlock *JumpToMBB = &DestBB;
476 
477   if (!isInt<32>(BrOffset))
478     report_fatal_error(
479         "Branch offsets outside of the signed 32-bit range not supported");
480 
481   Register ScratchReg = MRI.createVirtualRegister(&Xtensa::ARRegClass);
482   auto II = MBB.end();
483 
484   // Create l32r without last operand. We will add this operand later when
485   // JumpToMMB will be calculated and placed to the ConstantPool.
486   MachineInstr &L32R = *BuildMI(MBB, II, DL, get(Xtensa::L32R), ScratchReg);
487   BuildMI(MBB, II, DL, get(Xtensa::JX)).addReg(ScratchReg, RegState::Kill);
488 
489   RS->enterBasicBlockEnd(MBB);
490   Register ScavRegister =
491       RS->scavengeRegisterBackwards(Xtensa::ARRegClass, L32R.getIterator(),
492                                     /*RestoreAfter=*/false, /*SpAdj=*/0,
493                                     /*AllowSpill=*/false);
494   if (ScavRegister != Xtensa::NoRegister)
495     RS->setRegUsed(ScavRegister);
496   else {
497     // The case when there is no scavenged register needs special handling.
498     // Pick A8 because it doesn't make a difference
499     ScavRegister = Xtensa::A12;
500 
501     int FrameIndex = XtensaFI->getBranchRelaxationScratchFrameIndex();
502     if (FrameIndex == -1)
503       report_fatal_error(
504           "Unable to properly handle scavenged register for indirect jump, "
505           "function code size is significantly larger than estimated");
506 
507     storeRegToStackSlot(MBB, L32R, ScavRegister, /*IsKill=*/true, FrameIndex,
508                         &Xtensa::ARRegClass, &RI, Register());
509     RI.eliminateFrameIndex(std::prev(L32R.getIterator()),
510                            /*SpAdj=*/0, /*FIOperandNum=*/1);
511 
512     loadRegFromStackSlot(RestoreBB, RestoreBB.end(), ScavRegister, FrameIndex,
513                          &Xtensa::ARRegClass, &RI, Register());
514     RI.eliminateFrameIndex(RestoreBB.back(),
515                            /*SpAdj=*/0, /*FIOperandNum=*/1);
516     JumpToMBB = &RestoreBB;
517   }
518 
519   XtensaConstantPoolValue *C = XtensaConstantPoolMBB::Create(
520       MF->getFunction().getContext(), JumpToMBB, 0);
521   unsigned Idx = ConstantPool->getConstantPoolIndex(C, Align(4));
522   L32R.addOperand(MachineOperand::CreateCPI(Idx, 0));
523 
524   MRI.replaceRegWith(ScratchReg, ScavRegister);
525   MRI.clearVirtRegs();
526 }
527 
528 unsigned XtensaInstrInfo::insertConstBranchAtInst(
529     MachineBasicBlock &MBB, MachineInstr *I, int64_t offset,
530     ArrayRef<MachineOperand> Cond, DebugLoc DL, int *BytesAdded) const {
531   assert(Cond.size() <= 4 &&
532          "Xtensa branch conditions have less than four components!");
533 
534   if (Cond.empty() || (Cond[0].getImm() == Xtensa::J)) {
535     // Unconditional branch
536     MachineInstr *MI = BuildMI(MBB, I, DL, get(Xtensa::J)).addImm(offset);
537     if (BytesAdded && MI)
538       *BytesAdded += getInstSizeInBytes(*MI);
539     return 1;
540   }
541 
542   unsigned Count = 0;
543   unsigned BR_C = Cond[0].getImm();
544   MachineInstr *MI = nullptr;
545   switch (BR_C) {
546   case Xtensa::BEQ:
547   case Xtensa::BNE:
548   case Xtensa::BLT:
549   case Xtensa::BLTU:
550   case Xtensa::BGE:
551   case Xtensa::BGEU:
552     MI = BuildMI(MBB, I, DL, get(BR_C))
553              .addImm(offset)
554              .addReg(Cond[1].getReg())
555              .addReg(Cond[2].getReg());
556     break;
557   case Xtensa::BEQI:
558   case Xtensa::BNEI:
559   case Xtensa::BLTI:
560   case Xtensa::BLTUI:
561   case Xtensa::BGEI:
562   case Xtensa::BGEUI:
563     MI = BuildMI(MBB, I, DL, get(BR_C))
564              .addImm(offset)
565              .addReg(Cond[1].getReg())
566              .addImm(Cond[2].getImm());
567     break;
568   case Xtensa::BEQZ:
569   case Xtensa::BNEZ:
570   case Xtensa::BLTZ:
571   case Xtensa::BGEZ:
572     MI = BuildMI(MBB, I, DL, get(BR_C)).addImm(offset).addReg(Cond[1].getReg());
573     break;
574   default:
575     llvm_unreachable("Invalid branch type!");
576   }
577   if (BytesAdded && MI)
578     *BytesAdded += getInstSizeInBytes(*MI);
579   ++Count;
580   return Count;
581 }
582 
583 unsigned XtensaInstrInfo::insertBranchAtInst(MachineBasicBlock &MBB,
584                                              MachineBasicBlock::iterator I,
585                                              MachineBasicBlock *TBB,
586                                              ArrayRef<MachineOperand> Cond,
587                                              const DebugLoc &DL,
588                                              int *BytesAdded) const {
589   // Shouldn't be a fall through.
590   assert(TBB && "InsertBranch must not be told to insert a fallthrough");
591   assert(Cond.size() <= 4 &&
592          "Xtensa branch conditions have less than four components!");
593 
594   if (Cond.empty() || (Cond[0].getImm() == Xtensa::J)) {
595     // Unconditional branch
596     MachineInstr *MI = BuildMI(MBB, I, DL, get(Xtensa::J)).addMBB(TBB);
597     if (BytesAdded && MI)
598       *BytesAdded += getInstSizeInBytes(*MI);
599     return 1;
600   }
601 
602   unsigned Count = 0;
603   unsigned BR_C = Cond[0].getImm();
604   MachineInstr *MI = nullptr;
605   switch (BR_C) {
606   case Xtensa::BEQ:
607   case Xtensa::BNE:
608   case Xtensa::BLT:
609   case Xtensa::BLTU:
610   case Xtensa::BGE:
611   case Xtensa::BGEU:
612     MI = BuildMI(MBB, I, DL, get(BR_C))
613              .addReg(Cond[1].getReg())
614              .addReg(Cond[2].getReg())
615              .addMBB(TBB);
616     break;
617   case Xtensa::BEQI:
618   case Xtensa::BNEI:
619   case Xtensa::BLTI:
620   case Xtensa::BLTUI:
621   case Xtensa::BGEI:
622   case Xtensa::BGEUI:
623     MI = BuildMI(MBB, I, DL, get(BR_C))
624              .addReg(Cond[1].getReg())
625              .addImm(Cond[2].getImm())
626              .addMBB(TBB);
627     break;
628   case Xtensa::BEQZ:
629   case Xtensa::BNEZ:
630   case Xtensa::BLTZ:
631   case Xtensa::BGEZ:
632     MI = BuildMI(MBB, I, DL, get(BR_C)).addReg(Cond[1].getReg()).addMBB(TBB);
633     break;
634   default:
635     report_fatal_error("Invalid branch type!");
636   }
637   if (BytesAdded && MI)
638     *BytesAdded += getInstSizeInBytes(*MI);
639   ++Count;
640   return Count;
641 }
642 
643 bool XtensaInstrInfo::isBranch(const MachineBasicBlock::iterator &MI,
644                                SmallVectorImpl<MachineOperand> &Cond,
645                                const MachineOperand *&Target) const {
646   unsigned OpCode = MI->getOpcode();
647   switch (OpCode) {
648   case Xtensa::J:
649   case Xtensa::JX:
650   case Xtensa::BR_JT:
651     Cond[0].setImm(OpCode);
652     Target = &MI->getOperand(0);
653     return true;
654   case Xtensa::BEQ:
655   case Xtensa::BNE:
656   case Xtensa::BLT:
657   case Xtensa::BLTU:
658   case Xtensa::BGE:
659   case Xtensa::BGEU:
660     Cond[0].setImm(OpCode);
661     Target = &MI->getOperand(2);
662     return true;
663 
664   case Xtensa::BEQI:
665   case Xtensa::BNEI:
666   case Xtensa::BLTI:
667   case Xtensa::BLTUI:
668   case Xtensa::BGEI:
669   case Xtensa::BGEUI:
670     Cond[0].setImm(OpCode);
671     Target = &MI->getOperand(2);
672     return true;
673 
674   case Xtensa::BEQZ:
675   case Xtensa::BNEZ:
676   case Xtensa::BLTZ:
677   case Xtensa::BGEZ:
678     Cond[0].setImm(OpCode);
679     Target = &MI->getOperand(1);
680     return true;
681 
682   default:
683     assert(!MI->getDesc().isBranch() && "Unknown branch opcode");
684     return false;
685   }
686 }
687