brintos

brintos / llvm-project-archived public Read only

0
0
Text · 23.7 KiB · d7b05ac Raw
744 lines · cpp
1//===- XtensaInstrInfo.cpp - Xtensa Instruction Information ---------------===//2//3//                     The LLVM Compiler Infrastructure4//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-exception8//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_DTOR26#include "XtensaGenInstrInfo.inc"27 28using namespace llvm;29 30static const MachineInstrBuilder &31addFrameReference(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 50XtensaInstrInfo::XtensaInstrInfo(const XtensaSubtarget &STI)51    : XtensaGenInstrInfo(STI, RI, Xtensa::ADJCALLSTACKDOWN,52                         Xtensa::ADJCALLSTACKUP),53      RI(STI), STI(STI) {}54 55Register XtensaInstrInfo::isLoadFromStackSlot(const MachineInstr &MI,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 67Register XtensaInstrInfo::isStoreToStackSlot(const MachineInstr &MI,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.80void XtensaInstrInfo::adjustStackPtr(MCRegister SP, int64_t Amount,81                                     MachineBasicBlock &MBB,82                                     MachineBasicBlock::iterator I) const {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 immediate92  MCRegister Reg = RegInfo.createVirtualRegister(RC);93 94  if (isInt<8>(Amount)) { // addi sp, sp, amount95    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)108        .addReg(Reg, RegState::Kill)109        .addReg(Reg, RegState::Kill);110  }111}112 113void XtensaInstrInfo::copyPhysReg(MachineBasicBlock &MBB,114                                  MachineBasicBlock::iterator MBBI,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  else139    report_fatal_error("Impossible reg-to-reg copy");140 141  BuildMI(MBB, MBBI, DL, get(Opcode), DestReg)142      .addReg(SrcReg, getKillRegState(KillSrc));143}144 145void XtensaInstrInfo::storeRegToStackSlot(146    MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg,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 158void XtensaInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,159                                           MachineBasicBlock::iterator MBBI,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 170void XtensaInstrInfo::getLoadStoreOpcodes(const TargetRegisterClass *RC,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 185void XtensaInstrInfo::loadImmediate(MachineBasicBlock &MBB,186                                    MachineBasicBlock::iterator MBBI,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 immediate193  *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 constant204    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 MSym211    BuildMI(MBB, MBBI, DL, get(Xtensa::L32R), *Reg).addConstantPoolIndex(Idx);212  } else {213    // use L32R to let assembler load immediate best214    // TODO replace to L32R215    report_fatal_error("Unsupported load immediate value");216  }217}218 219unsigned XtensaInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {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 231bool XtensaInstrInfo::reverseBranchCondition(232    SmallVectorImpl<MachineOperand> &Cond) const {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 295MachineBasicBlock *296XtensaInstrInfo::getBranchDestBlock(const MachineInstr &MI) const {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 331bool XtensaInstrInfo::isBranchOffsetInRange(unsigned BranchOp,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 370bool XtensaInstrInfo::analyzeBranch(MachineBasicBlock &MBB,371                                    MachineBasicBlock *&TBB,372                                    MachineBasicBlock *&FBB,373                                    SmallVectorImpl<MachineOperand> &Cond,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 the378  // terminator instructions.379  MachineBasicBlock::iterator I = MBB.end();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're386    // done.387    if (!isUnpredicatedTerminator(*I))388      break;389 390    // A terminator that isn't a branch can't easily be handled by this391    // analysis.392    SmallVector<MachineOperand, 4> ThisCond;393    ThisCond.push_back(MachineOperand::CreateImm(0));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 swap424      FBB = TBB;425      TBB = ThisTarget->getMBB();426      Cond.push_back(MachineOperand::CreateImm(ThisCond[0].getImm()));427 428      // push remaining operands429      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 same440    // 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 453unsigned XtensaInstrInfo::removeBranch(MachineBasicBlock &MBB,454                                       int *BytesRemoved) const {455  // Most of the code and comments here are boilerplate.456  MachineBasicBlock::iterator I = MBB.end();457  unsigned Count = 0;458  if (BytesRemoved)459    *BytesRemoved = 0;460 461  while (I != MBB.begin()) {462    --I;463    SmallVector<MachineOperand, 4> Cond;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 480unsigned XtensaInstrInfo::insertBranch(481    MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB,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 then488    // one to branch to TBB on Cond489    // and a second one immediately after to unconditionally jump to FBB490    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 MBB498  Count += insertBranchAtInst(MBB, MBB.end(), TBB, Cond, DL, BytesAdded);499  return Count;500}501 502void XtensaInstrInfo::insertIndirectBranch(MachineBasicBlock &MBB,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();513  MachineRegisterInfo &MRI = MF->getRegInfo();514  MachineConstantPool *ConstantPool = MF->getConstantPool();515  auto *XtensaFI = MF->getInfo<XtensaMachineFunctionInfo>();516  MachineBasicBlock *JumpToMBB = &DestBB;517 518  if (!isInt<32>(BrOffset))519    report_fatal_error(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 when526  // 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 difference540    ScavRegister = Xtensa::A12;541 542    int FrameIndex = XtensaFI->getBranchRelaxationScratchFrameIndex();543    if (FrameIndex == -1)544      report_fatal_error(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 562  XtensaConstantPoolValue *C = XtensaConstantPoolMBB::Create(563      MF->getFunction().getContext(), JumpToMBB, LabelId);564  unsigned Idx = ConstantPool->getConstantPoolIndex(C, Align(4));565  L32R.addOperand(MachineOperand::CreateCPI(Idx, 0));566 567  MRI.replaceRegWith(ScratchReg, ScavRegister);568  MRI.clearVirtRegs();569}570 571unsigned XtensaInstrInfo::insertConstBranchAtInst(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 branch579    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 630unsigned XtensaInstrInfo::insertBranchAtInst(MachineBasicBlock &MBB,631                                             MachineBasicBlock::iterator I,632                                             MachineBasicBlock *TBB,633                                             ArrayRef<MachineOperand> Cond,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 branch643    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 694bool XtensaInstrInfo::isBranch(const MachineBasicBlock::iterator &MI,695                               SmallVectorImpl<MachineOperand> &Cond,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}744