brintos

brintos / llvm-project-archived public Read only

0
0
Text · 167.7 KiB · 7682af4 Raw
4810 lines · cpp
1//===- HexagonInstrInfo.cpp - Hexagon Instruction Information -------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file contains the Hexagon implementation of the TargetInstrInfo class.10//11//===----------------------------------------------------------------------===//12 13#include "HexagonInstrInfo.h"14#include "HexagonFrameLowering.h"15#include "HexagonHazardRecognizer.h"16#include "HexagonRegisterInfo.h"17#include "HexagonSubtarget.h"18#include "llvm/ADT/ArrayRef.h"19#include "llvm/ADT/SmallPtrSet.h"20#include "llvm/ADT/SmallVector.h"21#include "llvm/ADT/StringExtras.h"22#include "llvm/ADT/StringRef.h"23#include "llvm/CodeGen/DFAPacketizer.h"24#include "llvm/CodeGen/LiveIntervals.h"25#include "llvm/CodeGen/LivePhysRegs.h"26#include "llvm/CodeGen/MachineBasicBlock.h"27#include "llvm/CodeGen/MachineBranchProbabilityInfo.h"28#include "llvm/CodeGen/MachineFrameInfo.h"29#include "llvm/CodeGen/MachineFunction.h"30#include "llvm/CodeGen/MachineInstr.h"31#include "llvm/CodeGen/MachineInstrBuilder.h"32#include "llvm/CodeGen/MachineInstrBundle.h"33#include "llvm/CodeGen/MachineMemOperand.h"34#include "llvm/CodeGen/MachineOperand.h"35#include "llvm/CodeGen/MachineRegisterInfo.h"36#include "llvm/CodeGen/ScheduleDAG.h"37#include "llvm/CodeGen/TargetInstrInfo.h"38#include "llvm/CodeGen/TargetOpcodes.h"39#include "llvm/CodeGen/TargetRegisterInfo.h"40#include "llvm/CodeGen/TargetSubtargetInfo.h"41#include "llvm/CodeGenTypes/MachineValueType.h"42#include "llvm/IR/DebugLoc.h"43#include "llvm/IR/GlobalVariable.h"44#include "llvm/MC/MCAsmInfo.h"45#include "llvm/MC/MCInstBuilder.h"46#include "llvm/MC/MCInstrDesc.h"47#include "llvm/MC/MCInstrItineraries.h"48#include "llvm/Support/BranchProbability.h"49#include "llvm/Support/CommandLine.h"50#include "llvm/Support/Debug.h"51#include "llvm/Support/ErrorHandling.h"52#include "llvm/Support/MathExtras.h"53#include "llvm/Support/raw_ostream.h"54#include "llvm/Target/TargetMachine.h"55#include <cassert>56#include <cctype>57#include <cstdint>58#include <cstring>59#include <iterator>60#include <optional>61#include <string>62#include <utility>63 64using namespace llvm;65 66#define DEBUG_TYPE "hexagon-instrinfo"67 68#define GET_INSTRINFO_CTOR_DTOR69#define GET_INSTRMAP_INFO70#include "HexagonDepTimingClasses.h"71#include "HexagonGenDFAPacketizer.inc"72#include "HexagonGenInstrInfo.inc"73 74cl::opt<bool> ScheduleInlineAsm("hexagon-sched-inline-asm", cl::Hidden,75  cl::init(false), cl::desc("Do not consider inline-asm a scheduling/"76                            "packetization boundary."));77 78static cl::opt<bool> EnableBranchPrediction("hexagon-enable-branch-prediction",79  cl::Hidden, cl::init(true), cl::desc("Enable branch prediction"));80 81static cl::opt<bool> DisableNVSchedule(82    "disable-hexagon-nv-schedule", cl::Hidden,83    cl::desc("Disable schedule adjustment for new value stores."));84 85static cl::opt<bool> EnableTimingClassLatency(86  "enable-timing-class-latency", cl::Hidden, cl::init(false),87  cl::desc("Enable timing class latency"));88 89static cl::opt<bool> EnableALUForwarding(90  "enable-alu-forwarding", cl::Hidden, cl::init(true),91  cl::desc("Enable vec alu forwarding"));92 93static cl::opt<bool> EnableACCForwarding(94  "enable-acc-forwarding", cl::Hidden, cl::init(true),95  cl::desc("Enable vec acc forwarding"));96 97static cl::opt<bool> BranchRelaxAsmLarge("branch-relax-asm-large",98                                         cl::init(true), cl::Hidden,99                                         cl::desc("branch relax asm"));100 101static cl::opt<bool>102    UseDFAHazardRec("dfa-hazard-rec", cl::init(true), cl::Hidden,103                    cl::desc("Use the DFA based hazard recognizer."));104 105/// Constants for Hexagon instructions.106const int Hexagon_MEMW_OFFSET_MAX = 4095;107const int Hexagon_MEMW_OFFSET_MIN = -4096;108const int Hexagon_MEMD_OFFSET_MAX = 8191;109const int Hexagon_MEMD_OFFSET_MIN = -8192;110const int Hexagon_MEMH_OFFSET_MAX = 2047;111const int Hexagon_MEMH_OFFSET_MIN = -2048;112const int Hexagon_MEMB_OFFSET_MAX = 1023;113const int Hexagon_MEMB_OFFSET_MIN = -1024;114const int Hexagon_ADDI_OFFSET_MAX = 32767;115const int Hexagon_ADDI_OFFSET_MIN = -32768;116 117// Pin the vtable to this file.118void HexagonInstrInfo::anchor() {}119 120HexagonInstrInfo::HexagonInstrInfo(const HexagonSubtarget &ST)121    : HexagonGenInstrInfo(ST, RegInfo, Hexagon::ADJCALLSTACKDOWN,122                          Hexagon::ADJCALLSTACKUP),123      RegInfo(ST.getHwMode()), Subtarget(ST) {}124 125namespace llvm {126namespace HexagonFUnits {127  bool isSlot0Only(unsigned units);128}129}130 131static bool isIntRegForSubInst(Register Reg) {132  return (Reg >= Hexagon::R0 && Reg <= Hexagon::R7) ||133         (Reg >= Hexagon::R16 && Reg <= Hexagon::R23);134}135 136static bool isDblRegForSubInst(Register Reg, const HexagonRegisterInfo &HRI) {137  return isIntRegForSubInst(HRI.getSubReg(Reg, Hexagon::isub_lo)) &&138         isIntRegForSubInst(HRI.getSubReg(Reg, Hexagon::isub_hi));139}140 141/// Calculate number of instructions excluding the debug instructions.142static unsigned nonDbgMICount(MachineBasicBlock::const_instr_iterator MIB,143                              MachineBasicBlock::const_instr_iterator MIE) {144  unsigned Count = 0;145  for (; MIB != MIE; ++MIB) {146    if (!MIB->isDebugInstr())147      ++Count;148  }149  return Count;150}151 152// Check if the A2_tfrsi instruction is cheap or not. If the operand has153// to be constant-extendend it is not cheap since it occupies two slots154// in a packet.155bool HexagonInstrInfo::isAsCheapAsAMove(const MachineInstr &MI) const {156  // Enable the following steps only at Os/Oz157  if (!(MI.getMF()->getFunction().hasOptSize()))158    return MI.isAsCheapAsAMove();159 160  if (MI.getOpcode() == Hexagon::A2_tfrsi) {161    auto Op = MI.getOperand(1);162    // If the instruction has a global address as operand, it is not cheap163    // since the operand will be constant extended.164    if (Op.isGlobal())165      return false;166    // If the instruction has an operand of size > 16bits, its will be167    // const-extended and hence, it is not cheap.168    if (Op.isImm()) {169      int64_t Imm = Op.getImm();170      if (!isInt<16>(Imm))171        return false;172    }173  }174  return MI.isAsCheapAsAMove();175}176 177// Do not sink floating point instructions that updates USR register.178// Example:179//    feclearexcept180//    F2_conv_w2sf181//    fetestexcept182// MachineSink sinks F2_conv_w2sf and we are not able to catch exceptions.183// TODO: On some of these floating point instructions, USR is marked as Use.184// In reality, these instructions also Def the USR. If USR is marked as Def,185// some of the assumptions in assembler packetization are broken.186bool HexagonInstrInfo::shouldSink(const MachineInstr &MI) const {187  // Assumption: A floating point instruction that reads the USR will write188  // the USR as well.189  if (isFloat(MI) && MI.hasRegisterImplicitUseOperand(Hexagon::USR))190    return false;191  return true;192}193 194/// Find the hardware loop instruction used to set-up the specified loop.195/// On Hexagon, we have two instructions used to set-up the hardware loop196/// (LOOP0, LOOP1) with corresponding endloop (ENDLOOP0, ENDLOOP1) instructions197/// to indicate the end of a loop.198MachineInstr *HexagonInstrInfo::findLoopInstr(MachineBasicBlock *BB,199      unsigned EndLoopOp, MachineBasicBlock *TargetBB,200      SmallPtrSet<MachineBasicBlock *, 8> &Visited) const {201  unsigned LOOPi;202  unsigned LOOPr;203  if (EndLoopOp == Hexagon::ENDLOOP0) {204    LOOPi = Hexagon::J2_loop0i;205    LOOPr = Hexagon::J2_loop0r;206  } else { // EndLoopOp == Hexagon::EndLOOP1207    LOOPi = Hexagon::J2_loop1i;208    LOOPr = Hexagon::J2_loop1r;209  }210 211  // The loop set-up instruction will be in a predecessor block212  for (MachineBasicBlock *PB : BB->predecessors()) {213    // If this has been visited, already skip it.214    if (!Visited.insert(PB).second)215      continue;216    if (PB == BB)217      continue;218    for (MachineInstr &I : llvm::reverse(PB->instrs())) {219      unsigned Opc = I.getOpcode();220      if (Opc == LOOPi || Opc == LOOPr)221        return &I;222      // We've reached a different loop, which means the loop01 has been223      // removed.224      if (Opc == EndLoopOp && I.getOperand(0).getMBB() != TargetBB)225        return nullptr;226    }227    // Check the predecessors for the LOOP instruction.228    if (MachineInstr *Loop = findLoopInstr(PB, EndLoopOp, TargetBB, Visited))229      return Loop;230  }231  return nullptr;232}233 234/// Gather register def/uses from MI.235/// This treats possible (predicated) defs as actually happening ones236/// (conservatively).237static inline void parseOperands(const MachineInstr &MI,238      SmallVectorImpl<Register> &Defs, SmallVectorImpl<Register> &Uses) {239  Defs.clear();240  Uses.clear();241 242  for (const MachineOperand &MO : MI.operands()) {243    if (!MO.isReg())244      continue;245 246    Register Reg = MO.getReg();247    if (!Reg)248      continue;249 250    if (MO.isUse())251      Uses.push_back(MO.getReg());252 253    if (MO.isDef())254      Defs.push_back(MO.getReg());255  }256}257 258// Position dependent, so check twice for swap.259static bool isDuplexPairMatch(unsigned Ga, unsigned Gb) {260  switch (Ga) {261  case HexagonII::HSIG_None:262  default:263    return false;264  case HexagonII::HSIG_L1:265    return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_A);266  case HexagonII::HSIG_L2:267    return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||268            Gb == HexagonII::HSIG_A);269  case HexagonII::HSIG_S1:270    return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||271            Gb == HexagonII::HSIG_S1 || Gb == HexagonII::HSIG_A);272  case HexagonII::HSIG_S2:273    return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||274            Gb == HexagonII::HSIG_S1 || Gb == HexagonII::HSIG_S2 ||275            Gb == HexagonII::HSIG_A);276  case HexagonII::HSIG_A:277    return (Gb == HexagonII::HSIG_A);278  case HexagonII::HSIG_Compound:279    return (Gb == HexagonII::HSIG_Compound);280  }281  return false;282}283 284/// isLoadFromStackSlot - If the specified machine instruction is a direct285/// load from a stack slot, return the virtual or physical register number of286/// the destination along with the FrameIndex of the loaded stack slot.  If287/// not, return 0.  This predicate must return 0 if the instruction has288/// any side effects other than loading from the stack slot.289Register HexagonInstrInfo::isLoadFromStackSlot(const MachineInstr &MI,290                                               int &FrameIndex) const {291  switch (MI.getOpcode()) {292    default:293      break;294    case Hexagon::L2_loadri_io:295    case Hexagon::L2_loadrd_io:296    case Hexagon::V6_vL32b_ai:297    case Hexagon::V6_vL32b_nt_ai:298    case Hexagon::V6_vL32Ub_ai:299    case Hexagon::LDriw_pred:300    case Hexagon::LDriw_ctr:301    case Hexagon::PS_vloadrq_ai:302    case Hexagon::PS_vloadrw_ai:303    case Hexagon::PS_vloadrw_nt_ai: {304      const MachineOperand OpFI = MI.getOperand(1);305      if (!OpFI.isFI())306        return 0;307      const MachineOperand OpOff = MI.getOperand(2);308      if (!OpOff.isImm() || OpOff.getImm() != 0)309        return 0;310      FrameIndex = OpFI.getIndex();311      return MI.getOperand(0).getReg();312    }313 314    case Hexagon::L2_ploadrit_io:315    case Hexagon::L2_ploadrif_io:316    case Hexagon::L2_ploadrdt_io:317    case Hexagon::L2_ploadrdf_io: {318      const MachineOperand OpFI = MI.getOperand(2);319      if (!OpFI.isFI())320        return 0;321      const MachineOperand OpOff = MI.getOperand(3);322      if (!OpOff.isImm() || OpOff.getImm() != 0)323        return 0;324      FrameIndex = OpFI.getIndex();325      return MI.getOperand(0).getReg();326    }327  }328 329  return 0;330}331 332/// isStoreToStackSlot - If the specified machine instruction is a direct333/// store to a stack slot, return the virtual or physical register number of334/// the source reg along with the FrameIndex of the loaded stack slot.  If335/// not, return 0.  This predicate must return 0 if the instruction has336/// any side effects other than storing to the stack slot.337Register HexagonInstrInfo::isStoreToStackSlot(const MachineInstr &MI,338                                              int &FrameIndex) const {339  switch (MI.getOpcode()) {340    default:341      break;342    case Hexagon::S2_storerb_io:343    case Hexagon::S2_storerh_io:344    case Hexagon::S2_storeri_io:345    case Hexagon::S2_storerd_io:346    case Hexagon::V6_vS32b_ai:347    case Hexagon::V6_vS32Ub_ai:348    case Hexagon::STriw_pred:349    case Hexagon::STriw_ctr:350    case Hexagon::PS_vstorerq_ai:351    case Hexagon::PS_vstorerw_ai: {352      const MachineOperand &OpFI = MI.getOperand(0);353      if (!OpFI.isFI())354        return 0;355      const MachineOperand &OpOff = MI.getOperand(1);356      if (!OpOff.isImm() || OpOff.getImm() != 0)357        return 0;358      FrameIndex = OpFI.getIndex();359      return MI.getOperand(2).getReg();360    }361 362    case Hexagon::S2_pstorerbt_io:363    case Hexagon::S2_pstorerbf_io:364    case Hexagon::S2_pstorerht_io:365    case Hexagon::S2_pstorerhf_io:366    case Hexagon::S2_pstorerit_io:367    case Hexagon::S2_pstorerif_io:368    case Hexagon::S2_pstorerdt_io:369    case Hexagon::S2_pstorerdf_io: {370      const MachineOperand &OpFI = MI.getOperand(1);371      if (!OpFI.isFI())372        return 0;373      const MachineOperand &OpOff = MI.getOperand(2);374      if (!OpOff.isImm() || OpOff.getImm() != 0)375        return 0;376      FrameIndex = OpFI.getIndex();377      return MI.getOperand(3).getReg();378    }379  }380 381  return 0;382}383 384/// This function checks if the instruction or bundle of instructions385/// has load from stack slot and returns frameindex and machine memory386/// operand of that instruction if true.387bool HexagonInstrInfo::hasLoadFromStackSlot(388    const MachineInstr &MI,389    SmallVectorImpl<const MachineMemOperand *> &Accesses) const {390  if (MI.isBundle()) {391    const MachineBasicBlock *MBB = MI.getParent();392    MachineBasicBlock::const_instr_iterator MII = MI.getIterator();393    for (++MII; MII != MBB->instr_end() && MII->isInsideBundle(); ++MII)394      if (TargetInstrInfo::hasLoadFromStackSlot(*MII, Accesses))395        return true;396    return false;397  }398 399  return TargetInstrInfo::hasLoadFromStackSlot(MI, Accesses);400}401 402/// This function checks if the instruction or bundle of instructions403/// has store to stack slot and returns frameindex and machine memory404/// operand of that instruction if true.405bool HexagonInstrInfo::hasStoreToStackSlot(406    const MachineInstr &MI,407    SmallVectorImpl<const MachineMemOperand *> &Accesses) const {408  if (MI.isBundle()) {409    const MachineBasicBlock *MBB = MI.getParent();410    MachineBasicBlock::const_instr_iterator MII = MI.getIterator();411    for (++MII; MII != MBB->instr_end() && MII->isInsideBundle(); ++MII)412      if (TargetInstrInfo::hasStoreToStackSlot(*MII, Accesses))413        return true;414    return false;415  }416 417  return TargetInstrInfo::hasStoreToStackSlot(MI, Accesses);418}419 420/// This function can analyze one/two way branching only and should (mostly) be421/// called by target independent side.422/// First entry is always the opcode of the branching instruction, except when423/// the Cond vector is supposed to be empty, e.g., when analyzeBranch fails, a424/// BB with only unconditional jump. Subsequent entries depend upon the opcode,425/// e.g. Jump_c p will have426/// Cond[0] = Jump_c427/// Cond[1] = p428/// HW-loop ENDLOOP:429/// Cond[0] = ENDLOOP430/// Cond[1] = MBB431/// New value jump:432/// Cond[0] = Hexagon::CMPEQri_f_Jumpnv_t_V4 -- specific opcode433/// Cond[1] = R434/// Cond[2] = Imm435bool HexagonInstrInfo::analyzeBranch(MachineBasicBlock &MBB,436                                     MachineBasicBlock *&TBB,437                                     MachineBasicBlock *&FBB,438                                     SmallVectorImpl<MachineOperand> &Cond,439                                     bool AllowModify) const {440  TBB = nullptr;441  FBB = nullptr;442  Cond.clear();443 444  // If the block has no terminators, it just falls into the block after it.445  MachineBasicBlock::instr_iterator I = MBB.instr_end();446  if (I == MBB.instr_begin())447    return false;448 449  // A basic block may looks like this:450  //451  //  [   insn452  //     EH_LABEL453  //      insn454  //      insn455  //      insn456  //     EH_LABEL457  //      insn     ]458  //459  // It has two succs but does not have a terminator460  // Don't know how to handle it.461  do {462    --I;463    if (I->isEHLabel())464      // Don't analyze EH branches.465      return true;466  } while (I != MBB.instr_begin());467 468  I = MBB.instr_end();469  --I;470 471  while (I->isDebugInstr()) {472    if (I == MBB.instr_begin())473      return false;474    --I;475  }476 477  bool JumpToBlock = I->getOpcode() == Hexagon::J2_jump &&478                     I->getOperand(0).isMBB();479  // Delete the J2_jump if it's equivalent to a fall-through.480  if (AllowModify && JumpToBlock &&481      MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {482    LLVM_DEBUG(dbgs() << "\nErasing the jump to successor block\n";);483    I->eraseFromParent();484    I = MBB.instr_end();485    if (I == MBB.instr_begin())486      return false;487    --I;488  }489  if (!isUnpredicatedTerminator(*I))490    return false;491 492  // Get the last instruction in the block.493  MachineInstr *LastInst = &*I;494  MachineInstr *SecondLastInst = nullptr;495  // Find one more terminator if present.496  while (true) {497    if (&*I != LastInst && !I->isBundle() && isUnpredicatedTerminator(*I)) {498      if (!SecondLastInst)499        SecondLastInst = &*I;500      else501        // This is a third branch.502        return true;503    }504    if (I == MBB.instr_begin())505      break;506    --I;507  }508 509  int LastOpcode = LastInst->getOpcode();510  int SecLastOpcode = SecondLastInst ? SecondLastInst->getOpcode() : 0;511  // If the branch target is not a basic block, it could be a tail call.512  // (It is, if the target is a function.)513  if (LastOpcode == Hexagon::J2_jump && !LastInst->getOperand(0).isMBB())514    return true;515  if (SecLastOpcode == Hexagon::J2_jump &&516      !SecondLastInst->getOperand(0).isMBB())517    return true;518 519  bool LastOpcodeHasJMP_c = PredOpcodeHasJMP_c(LastOpcode);520  bool LastOpcodeHasNVJump = isNewValueJump(*LastInst);521 522  if (LastOpcodeHasJMP_c && !LastInst->getOperand(1).isMBB())523    return true;524 525  // If there is only one terminator instruction, process it.526  if (LastInst && !SecondLastInst) {527    if (LastOpcode == Hexagon::J2_jump) {528      TBB = LastInst->getOperand(0).getMBB();529      return false;530    }531    if (isEndLoopN(LastOpcode)) {532      TBB = LastInst->getOperand(0).getMBB();533      Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode()));534      Cond.push_back(LastInst->getOperand(0));535      return false;536    }537    if (LastOpcodeHasJMP_c) {538      TBB = LastInst->getOperand(1).getMBB();539      Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode()));540      Cond.push_back(LastInst->getOperand(0));541      return false;542    }543    // Only supporting rr/ri versions of new-value jumps.544    if (LastOpcodeHasNVJump && (LastInst->getNumExplicitOperands() == 3)) {545      TBB = LastInst->getOperand(2).getMBB();546      Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode()));547      Cond.push_back(LastInst->getOperand(0));548      Cond.push_back(LastInst->getOperand(1));549      return false;550    }551    LLVM_DEBUG(dbgs() << "\nCant analyze " << printMBBReference(MBB)552                      << " with one jump\n";);553    // Otherwise, don't know what this is.554    return true;555  }556 557  bool SecLastOpcodeHasJMP_c = PredOpcodeHasJMP_c(SecLastOpcode);558  bool SecLastOpcodeHasNVJump = isNewValueJump(*SecondLastInst);559  if (SecLastOpcodeHasJMP_c && (LastOpcode == Hexagon::J2_jump)) {560    if (!SecondLastInst->getOperand(1).isMBB())561      return true;562    TBB =  SecondLastInst->getOperand(1).getMBB();563    Cond.push_back(MachineOperand::CreateImm(SecondLastInst->getOpcode()));564    Cond.push_back(SecondLastInst->getOperand(0));565    FBB = LastInst->getOperand(0).getMBB();566    return false;567  }568 569  // Only supporting rr/ri versions of new-value jumps.570  if (SecLastOpcodeHasNVJump &&571      (SecondLastInst->getNumExplicitOperands() == 3) &&572      (LastOpcode == Hexagon::J2_jump)) {573    TBB = SecondLastInst->getOperand(2).getMBB();574    Cond.push_back(MachineOperand::CreateImm(SecondLastInst->getOpcode()));575    Cond.push_back(SecondLastInst->getOperand(0));576    Cond.push_back(SecondLastInst->getOperand(1));577    FBB = LastInst->getOperand(0).getMBB();578    return false;579  }580 581  // If the block ends with two Hexagon:JMPs, handle it.  The second one is not582  // executed, so remove it.583  if (SecLastOpcode == Hexagon::J2_jump && LastOpcode == Hexagon::J2_jump) {584    TBB = SecondLastInst->getOperand(0).getMBB();585    I = LastInst->getIterator();586    if (AllowModify)587      I->eraseFromParent();588    return false;589  }590 591  // If the block ends with an ENDLOOP, and J2_jump, handle it.592  if (isEndLoopN(SecLastOpcode) && LastOpcode == Hexagon::J2_jump) {593    TBB = SecondLastInst->getOperand(0).getMBB();594    Cond.push_back(MachineOperand::CreateImm(SecondLastInst->getOpcode()));595    Cond.push_back(SecondLastInst->getOperand(0));596    FBB = LastInst->getOperand(0).getMBB();597    return false;598  }599  LLVM_DEBUG(dbgs() << "\nCant analyze " << printMBBReference(MBB)600                    << " with two jumps";);601  // Otherwise, can't handle this.602  return true;603}604 605unsigned HexagonInstrInfo::removeBranch(MachineBasicBlock &MBB,606                                        int *BytesRemoved) const {607  assert(!BytesRemoved && "code size not handled");608 609  LLVM_DEBUG(dbgs() << "\nRemoving branches out of " << printMBBReference(MBB));610  MachineBasicBlock::iterator I = MBB.end();611  unsigned Count = 0;612  while (I != MBB.begin()) {613    --I;614    if (I->isDebugInstr())615      continue;616    // Only removing branches from end of MBB.617    if (!I->isBranch())618      return Count;619    if (Count && (I->getOpcode() == Hexagon::J2_jump))620      llvm_unreachable("Malformed basic block: unconditional branch not last");621    MBB.erase(&MBB.back());622    I = MBB.end();623    ++Count;624  }625  return Count;626}627 628unsigned HexagonInstrInfo::insertBranch(MachineBasicBlock &MBB,629                                        MachineBasicBlock *TBB,630                                        MachineBasicBlock *FBB,631                                        ArrayRef<MachineOperand> Cond,632                                        const DebugLoc &DL,633                                        int *BytesAdded) const {634  unsigned BOpc   = Hexagon::J2_jump;635  unsigned BccOpc = Hexagon::J2_jumpt;636  assert(validateBranchCond(Cond) && "Invalid branching condition");637  assert(TBB && "insertBranch must not be told to insert a fallthrough");638  assert(!BytesAdded && "code size not handled");639 640  // Check if reverseBranchCondition has asked to reverse this branch641  // If we want to reverse the branch an odd number of times, we want642  // J2_jumpf.643  if (!Cond.empty() && Cond[0].isImm())644    BccOpc = Cond[0].getImm();645 646  if (!FBB) {647    if (Cond.empty()) {648      // Due to a bug in TailMerging/CFG Optimization, we need to add a649      // special case handling of a predicated jump followed by an650      // unconditional jump. If not, Tail Merging and CFG Optimization go651      // into an infinite loop.652      MachineBasicBlock *NewTBB, *NewFBB;653      SmallVector<MachineOperand, 4> Cond;654      auto Term = MBB.getFirstTerminator();655      if (Term != MBB.end() && isPredicated(*Term) &&656          !analyzeBranch(MBB, NewTBB, NewFBB, Cond, false) &&657          MachineFunction::iterator(NewTBB) == ++MBB.getIterator()) {658        reverseBranchCondition(Cond);659        removeBranch(MBB);660        return insertBranch(MBB, TBB, nullptr, Cond, DL);661      }662      BuildMI(&MBB, DL, get(BOpc)).addMBB(TBB);663    } else if (isEndLoopN(Cond[0].getImm())) {664      int EndLoopOp = Cond[0].getImm();665      assert(Cond[1].isMBB());666      // Since we're adding an ENDLOOP, there better be a LOOP instruction.667      // Check for it, and change the BB target if needed.668      SmallPtrSet<MachineBasicBlock *, 8> VisitedBBs;669      MachineInstr *Loop = findLoopInstr(TBB, EndLoopOp, Cond[1].getMBB(),670                                         VisitedBBs);671      assert(Loop != nullptr && "Inserting an ENDLOOP without a LOOP");672      Loop->getOperand(0).setMBB(TBB);673      // Add the ENDLOOP after the finding the LOOP0.674      BuildMI(&MBB, DL, get(EndLoopOp)).addMBB(TBB);675    } else if (isNewValueJump(Cond[0].getImm())) {676      assert((Cond.size() == 3) && "Only supporting rr/ri version of nvjump");677      // New value jump678      // (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset)679      // (ins IntRegs:$src1, u5Imm:$src2, brtarget:$offset)680      unsigned Flags1 = getUndefRegState(Cond[1].isUndef());681      LLVM_DEBUG(dbgs() << "\nInserting NVJump for "682                        << printMBBReference(MBB););683      if (Cond[2].isReg()) {684        unsigned Flags2 = getUndefRegState(Cond[2].isUndef());685        BuildMI(&MBB, DL, get(BccOpc)).addReg(Cond[1].getReg(), Flags1).686          addReg(Cond[2].getReg(), Flags2).addMBB(TBB);687      } else if(Cond[2].isImm()) {688        BuildMI(&MBB, DL, get(BccOpc)).addReg(Cond[1].getReg(), Flags1).689          addImm(Cond[2].getImm()).addMBB(TBB);690      } else691        llvm_unreachable("Invalid condition for branching");692    } else {693      assert((Cond.size() == 2) && "Malformed cond vector");694      const MachineOperand &RO = Cond[1];695      unsigned Flags = getUndefRegState(RO.isUndef());696      BuildMI(&MBB, DL, get(BccOpc)).addReg(RO.getReg(), Flags).addMBB(TBB);697    }698    return 1;699  }700  assert((!Cond.empty()) &&701         "Cond. cannot be empty when multiple branchings are required");702  assert((!isNewValueJump(Cond[0].getImm())) &&703         "NV-jump cannot be inserted with another branch");704  // Special case for hardware loops.  The condition is a basic block.705  if (isEndLoopN(Cond[0].getImm())) {706    int EndLoopOp = Cond[0].getImm();707    assert(Cond[1].isMBB());708    // Since we're adding an ENDLOOP, there better be a LOOP instruction.709    // Check for it, and change the BB target if needed.710    SmallPtrSet<MachineBasicBlock *, 8> VisitedBBs;711    MachineInstr *Loop = findLoopInstr(TBB, EndLoopOp, Cond[1].getMBB(),712                                       VisitedBBs);713    assert(Loop != nullptr && "Inserting an ENDLOOP without a LOOP");714    Loop->getOperand(0).setMBB(TBB);715    // Add the ENDLOOP after the finding the LOOP0.716    BuildMI(&MBB, DL, get(EndLoopOp)).addMBB(TBB);717  } else {718    const MachineOperand &RO = Cond[1];719    unsigned Flags = getUndefRegState(RO.isUndef());720    BuildMI(&MBB, DL, get(BccOpc)).addReg(RO.getReg(), Flags).addMBB(TBB);721  }722  BuildMI(&MBB, DL, get(BOpc)).addMBB(FBB);723 724  return 2;725}726 727namespace {728class HexagonPipelinerLoopInfo : public TargetInstrInfo::PipelinerLoopInfo {729  MachineInstr *Loop, *EndLoop;730  MachineFunction *MF;731  const HexagonInstrInfo *TII;732  int64_t TripCount;733  Register LoopCount;734  DebugLoc DL;735 736public:737  HexagonPipelinerLoopInfo(MachineInstr *Loop, MachineInstr *EndLoop)738      : Loop(Loop), EndLoop(EndLoop), MF(Loop->getParent()->getParent()),739        TII(MF->getSubtarget<HexagonSubtarget>().getInstrInfo()),740        DL(Loop->getDebugLoc()) {741    // Inspect the Loop instruction up-front, as it may be deleted when we call742    // createTripCountGreaterCondition.743    TripCount = Loop->getOpcode() == Hexagon::J2_loop0r744                    ? -1745                    : Loop->getOperand(1).getImm();746    if (TripCount == -1)747      LoopCount = Loop->getOperand(1).getReg();748  }749 750  bool shouldIgnoreForPipelining(const MachineInstr *MI) const override {751    // Only ignore the terminator.752    return MI == EndLoop;753  }754 755  std::optional<bool> createTripCountGreaterCondition(756      int TC, MachineBasicBlock &MBB,757      SmallVectorImpl<MachineOperand> &Cond) override {758    if (TripCount == -1) {759      // Check if we're done with the loop.760      Register Done = TII->createVR(MF, MVT::i1);761      MachineInstr *NewCmp = BuildMI(&MBB, DL,762                                     TII->get(Hexagon::C2_cmpgtui), Done)763                                 .addReg(LoopCount)764                                 .addImm(TC);765      Cond.push_back(MachineOperand::CreateImm(Hexagon::J2_jumpf));766      Cond.push_back(NewCmp->getOperand(0));767      return {};768    }769 770    return TripCount > TC;771  }772 773  void setPreheader(MachineBasicBlock *NewPreheader) override {774    NewPreheader->splice(NewPreheader->getFirstTerminator(), Loop->getParent(),775                         Loop);776  }777 778  void adjustTripCount(int TripCountAdjust) override {779    // If the loop trip count is a compile-time value, then just change the780    // value.781    if (Loop->getOpcode() == Hexagon::J2_loop0i ||782        Loop->getOpcode() == Hexagon::J2_loop1i) {783      int64_t TripCount = Loop->getOperand(1).getImm() + TripCountAdjust;784      assert(TripCount > 0 && "Can't create an empty or negative loop!");785      Loop->getOperand(1).setImm(TripCount);786      return;787    }788 789    // The loop trip count is a run-time value. We generate code to subtract790    // one from the trip count, and update the loop instruction.791    Register LoopCount = Loop->getOperand(1).getReg();792    Register NewLoopCount = TII->createVR(MF, MVT::i32);793    BuildMI(*Loop->getParent(), Loop, Loop->getDebugLoc(),794            TII->get(Hexagon::A2_addi), NewLoopCount)795        .addReg(LoopCount)796        .addImm(TripCountAdjust);797    Loop->getOperand(1).setReg(NewLoopCount);798  }799 800  void disposed(LiveIntervals *LIS) override {801    if (LIS)802      LIS->RemoveMachineInstrFromMaps(*Loop);803    Loop->eraseFromParent();804  }805};806} // namespace807 808std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo>809HexagonInstrInfo::analyzeLoopForPipelining(MachineBasicBlock *LoopBB) const {810  // We really "analyze" only hardware loops right now.811  MachineBasicBlock::iterator I = LoopBB->getFirstTerminator();812 813  if (I != LoopBB->end() && isEndLoopN(I->getOpcode())) {814    SmallPtrSet<MachineBasicBlock *, 8> VisitedBBs;815    MachineInstr *LoopInst = findLoopInstr(816        LoopBB, I->getOpcode(), I->getOperand(0).getMBB(), VisitedBBs);817    if (LoopInst)818      return std::make_unique<HexagonPipelinerLoopInfo>(LoopInst, &*I);819  }820  return nullptr;821}822 823bool HexagonInstrInfo::isProfitableToIfCvt(MachineBasicBlock &MBB,824      unsigned NumCycles, unsigned ExtraPredCycles,825      BranchProbability Probability) const {826  return nonDbgBBSize(&MBB) <= 3;827}828 829bool HexagonInstrInfo::isProfitableToIfCvt(MachineBasicBlock &TMBB,830      unsigned NumTCycles, unsigned ExtraTCycles, MachineBasicBlock &FMBB,831      unsigned NumFCycles, unsigned ExtraFCycles, BranchProbability Probability)832      const {833  return nonDbgBBSize(&TMBB) <= 3 && nonDbgBBSize(&FMBB) <= 3;834}835 836bool HexagonInstrInfo::isProfitableToDupForIfCvt(MachineBasicBlock &MBB,837      unsigned NumInstrs, BranchProbability Probability) const {838  return NumInstrs <= 4;839}840 841static void getLiveInRegsAt(LivePhysRegs &Regs, const MachineInstr &MI) {842  SmallVector<std::pair<MCPhysReg, const MachineOperand*>,2> Clobbers;843  const MachineBasicBlock &B = *MI.getParent();844  Regs.addLiveIns(B);845  auto E = MachineBasicBlock::const_iterator(MI.getIterator());846  for (auto I = B.begin(); I != E; ++I) {847    Clobbers.clear();848    Regs.stepForward(*I, Clobbers);849  }850}851 852static void getLiveOutRegsAt(LivePhysRegs &Regs, const MachineInstr &MI) {853  const MachineBasicBlock &B = *MI.getParent();854  Regs.addLiveOuts(B);855  auto E = ++MachineBasicBlock::const_iterator(MI.getIterator()).getReverse();856  for (auto I = B.rbegin(); I != E; ++I)857    Regs.stepBackward(*I);858}859 860void HexagonInstrInfo::copyPhysReg(MachineBasicBlock &MBB,861                                   MachineBasicBlock::iterator I,862                                   const DebugLoc &DL, Register DestReg,863                                   Register SrcReg, bool KillSrc,864                                   bool RenamableDest,865                                   bool RenamableSrc) const {866  const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();867  unsigned KillFlag = getKillRegState(KillSrc);868 869  if (Hexagon::IntRegsRegClass.contains(SrcReg, DestReg)) {870    BuildMI(MBB, I, DL, get(Hexagon::A2_tfr), DestReg)871      .addReg(SrcReg, KillFlag);872    return;873  }874  if (Hexagon::DoubleRegsRegClass.contains(SrcReg, DestReg)) {875    BuildMI(MBB, I, DL, get(Hexagon::A2_tfrp), DestReg)876      .addReg(SrcReg, KillFlag);877    return;878  }879  if (Hexagon::PredRegsRegClass.contains(SrcReg, DestReg)) {880    // Map Pd = Ps to Pd = or(Ps, Ps).881    BuildMI(MBB, I, DL, get(Hexagon::C2_or), DestReg)882      .addReg(SrcReg).addReg(SrcReg, KillFlag);883    return;884  }885  if (Hexagon::CtrRegsRegClass.contains(DestReg) &&886      Hexagon::IntRegsRegClass.contains(SrcReg)) {887    BuildMI(MBB, I, DL, get(Hexagon::A2_tfrrcr), DestReg)888      .addReg(SrcReg, KillFlag);889    return;890  }891  if (Hexagon::IntRegsRegClass.contains(DestReg) &&892      Hexagon::CtrRegsRegClass.contains(SrcReg)) {893    BuildMI(MBB, I, DL, get(Hexagon::A2_tfrcrr), DestReg)894      .addReg(SrcReg, KillFlag);895    return;896  }897  if (Hexagon::ModRegsRegClass.contains(DestReg) &&898      Hexagon::IntRegsRegClass.contains(SrcReg)) {899    BuildMI(MBB, I, DL, get(Hexagon::A2_tfrrcr), DestReg)900      .addReg(SrcReg, KillFlag);901    return;902  }903  if (Hexagon::PredRegsRegClass.contains(SrcReg) &&904      Hexagon::IntRegsRegClass.contains(DestReg)) {905    BuildMI(MBB, I, DL, get(Hexagon::C2_tfrpr), DestReg)906      .addReg(SrcReg, KillFlag);907    return;908  }909  if (Hexagon::IntRegsRegClass.contains(SrcReg) &&910      Hexagon::PredRegsRegClass.contains(DestReg)) {911    BuildMI(MBB, I, DL, get(Hexagon::C2_tfrrp), DestReg)912      .addReg(SrcReg, KillFlag);913    return;914  }915  if (Hexagon::PredRegsRegClass.contains(SrcReg) &&916      Hexagon::IntRegsRegClass.contains(DestReg)) {917    BuildMI(MBB, I, DL, get(Hexagon::C2_tfrpr), DestReg)918      .addReg(SrcReg, KillFlag);919    return;920  }921  if (Hexagon::HvxVRRegClass.contains(SrcReg, DestReg)) {922    BuildMI(MBB, I, DL, get(Hexagon::V6_vassign), DestReg).923      addReg(SrcReg, KillFlag);924    return;925  }926  if (Hexagon::HvxWRRegClass.contains(SrcReg, DestReg)) {927    LivePhysRegs LiveAtMI(HRI);928    getLiveInRegsAt(LiveAtMI, *I);929    Register SrcLo = HRI.getSubReg(SrcReg, Hexagon::vsub_lo);930    Register SrcHi = HRI.getSubReg(SrcReg, Hexagon::vsub_hi);931    unsigned UndefLo = getUndefRegState(!LiveAtMI.contains(SrcLo));932    unsigned UndefHi = getUndefRegState(!LiveAtMI.contains(SrcHi));933    BuildMI(MBB, I, DL, get(Hexagon::V6_vcombine), DestReg)934      .addReg(SrcHi, KillFlag | UndefHi)935      .addReg(SrcLo, KillFlag | UndefLo);936    return;937  }938  if (Hexagon::HvxQRRegClass.contains(SrcReg, DestReg)) {939    BuildMI(MBB, I, DL, get(Hexagon::V6_pred_and), DestReg)940      .addReg(SrcReg)941      .addReg(SrcReg, KillFlag);942    return;943  }944  if (Hexagon::HvxQRRegClass.contains(SrcReg) &&945      Hexagon::HvxVRRegClass.contains(DestReg)) {946    llvm_unreachable("Unimplemented pred to vec");947    return;948  }949  if (Hexagon::HvxQRRegClass.contains(DestReg) &&950      Hexagon::HvxVRRegClass.contains(SrcReg)) {951    llvm_unreachable("Unimplemented vec to pred");952    return;953  }954 955#ifndef NDEBUG956  // Show the invalid registers to ease debugging.957  dbgs() << "Invalid registers for copy in " << printMBBReference(MBB) << ": "958         << printReg(DestReg, &HRI) << " = " << printReg(SrcReg, &HRI) << '\n';959#endif960  llvm_unreachable("Unimplemented");961}962 963void HexagonInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,964                                           MachineBasicBlock::iterator I,965                                           Register SrcReg, bool isKill, int FI,966                                           const TargetRegisterClass *RC,967                                           Register VReg,968                                           MachineInstr::MIFlag Flags) const {969  DebugLoc DL = MBB.findDebugLoc(I);970  MachineFunction &MF = *MBB.getParent();971  MachineFrameInfo &MFI = MF.getFrameInfo();972  unsigned KillFlag = getKillRegState(isKill);973 974  MachineMemOperand *MMO = MF.getMachineMemOperand(975      MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOStore,976      MFI.getObjectSize(FI), MFI.getObjectAlign(FI));977 978  if (Hexagon::IntRegsRegClass.hasSubClassEq(RC)) {979    BuildMI(MBB, I, DL, get(Hexagon::S2_storeri_io))980      .addFrameIndex(FI).addImm(0)981      .addReg(SrcReg, KillFlag).addMemOperand(MMO);982  } else if (Hexagon::DoubleRegsRegClass.hasSubClassEq(RC)) {983    BuildMI(MBB, I, DL, get(Hexagon::S2_storerd_io))984      .addFrameIndex(FI).addImm(0)985      .addReg(SrcReg, KillFlag).addMemOperand(MMO);986  } else if (Hexagon::PredRegsRegClass.hasSubClassEq(RC)) {987    BuildMI(MBB, I, DL, get(Hexagon::STriw_pred))988      .addFrameIndex(FI).addImm(0)989      .addReg(SrcReg, KillFlag).addMemOperand(MMO);990  } else if (Hexagon::ModRegsRegClass.hasSubClassEq(RC)) {991    BuildMI(MBB, I, DL, get(Hexagon::STriw_ctr))992      .addFrameIndex(FI).addImm(0)993      .addReg(SrcReg, KillFlag).addMemOperand(MMO);994  } else if (Hexagon::HvxQRRegClass.hasSubClassEq(RC)) {995    BuildMI(MBB, I, DL, get(Hexagon::PS_vstorerq_ai))996      .addFrameIndex(FI).addImm(0)997      .addReg(SrcReg, KillFlag).addMemOperand(MMO);998  } else if (Hexagon::HvxVRRegClass.hasSubClassEq(RC)) {999    BuildMI(MBB, I, DL, get(Hexagon::PS_vstorerv_ai))1000      .addFrameIndex(FI).addImm(0)1001      .addReg(SrcReg, KillFlag).addMemOperand(MMO);1002  } else if (Hexagon::HvxWRRegClass.hasSubClassEq(RC)) {1003    BuildMI(MBB, I, DL, get(Hexagon::PS_vstorerw_ai))1004      .addFrameIndex(FI).addImm(0)1005      .addReg(SrcReg, KillFlag).addMemOperand(MMO);1006  } else {1007    llvm_unreachable("Unimplemented");1008  }1009}1010 1011void HexagonInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,1012                                            MachineBasicBlock::iterator I,1013                                            Register DestReg, int FI,1014                                            const TargetRegisterClass *RC,1015                                            Register VReg,1016                                            MachineInstr::MIFlag Flags) const {1017  DebugLoc DL = MBB.findDebugLoc(I);1018  MachineFunction &MF = *MBB.getParent();1019  MachineFrameInfo &MFI = MF.getFrameInfo();1020 1021  MachineMemOperand *MMO = MF.getMachineMemOperand(1022      MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOLoad,1023      MFI.getObjectSize(FI), MFI.getObjectAlign(FI));1024 1025  if (Hexagon::IntRegsRegClass.hasSubClassEq(RC)) {1026    BuildMI(MBB, I, DL, get(Hexagon::L2_loadri_io), DestReg)1027      .addFrameIndex(FI).addImm(0).addMemOperand(MMO);1028  } else if (Hexagon::DoubleRegsRegClass.hasSubClassEq(RC)) {1029    BuildMI(MBB, I, DL, get(Hexagon::L2_loadrd_io), DestReg)1030      .addFrameIndex(FI).addImm(0).addMemOperand(MMO);1031  } else if (Hexagon::PredRegsRegClass.hasSubClassEq(RC)) {1032    BuildMI(MBB, I, DL, get(Hexagon::LDriw_pred), DestReg)1033      .addFrameIndex(FI).addImm(0).addMemOperand(MMO);1034  } else if (Hexagon::ModRegsRegClass.hasSubClassEq(RC)) {1035    BuildMI(MBB, I, DL, get(Hexagon::LDriw_ctr), DestReg)1036      .addFrameIndex(FI).addImm(0).addMemOperand(MMO);1037  } else if (Hexagon::HvxQRRegClass.hasSubClassEq(RC)) {1038    BuildMI(MBB, I, DL, get(Hexagon::PS_vloadrq_ai), DestReg)1039      .addFrameIndex(FI).addImm(0).addMemOperand(MMO);1040  } else if (Hexagon::HvxVRRegClass.hasSubClassEq(RC)) {1041    BuildMI(MBB, I, DL, get(Hexagon::PS_vloadrv_ai), DestReg)1042      .addFrameIndex(FI).addImm(0).addMemOperand(MMO);1043  } else if (Hexagon::HvxWRRegClass.hasSubClassEq(RC)) {1044    BuildMI(MBB, I, DL, get(Hexagon::PS_vloadrw_ai), DestReg)1045      .addFrameIndex(FI).addImm(0).addMemOperand(MMO);1046  } else {1047    llvm_unreachable("Can't store this register to stack slot");1048  }1049}1050 1051/// expandPostRAPseudo - This function is called for all pseudo instructions1052/// that remain after register allocation. Many pseudo instructions are1053/// created to help register allocation. This is the place to convert them1054/// into real instructions. The target can edit MI in place, or it can insert1055/// new instructions and erase MI. The function should return true if1056/// anything was changed.1057bool HexagonInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {1058  MachineBasicBlock &MBB = *MI.getParent();1059  MachineFunction &MF = *MBB.getParent();1060  MachineRegisterInfo &MRI = MF.getRegInfo();1061  const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();1062  LivePhysRegs LiveIn(HRI), LiveOut(HRI);1063  DebugLoc DL = MI.getDebugLoc();1064  unsigned Opc = MI.getOpcode();1065 1066  auto RealCirc = [&](unsigned Opc, bool HasImm, unsigned MxOp) {1067    Register Mx = MI.getOperand(MxOp).getReg();1068    Register CSx = (Mx == Hexagon::M0 ? Hexagon::CS0 : Hexagon::CS1);1069    BuildMI(MBB, MI, DL, get(Hexagon::A2_tfrrcr), CSx)1070        .add(MI.getOperand((HasImm ? 5 : 4)));1071    auto MIB = BuildMI(MBB, MI, DL, get(Opc)).add(MI.getOperand(0))1072        .add(MI.getOperand(1)).add(MI.getOperand(2)).add(MI.getOperand(3));1073    if (HasImm)1074      MIB.add(MI.getOperand(4));1075    MIB.addReg(CSx, RegState::Implicit);1076    MBB.erase(MI);1077    return true;1078  };1079 1080  auto UseAligned = [&](const MachineInstr &MI, Align NeedAlign) {1081    if (MI.memoperands().empty())1082      return false;1083    return all_of(MI.memoperands(), [NeedAlign](const MachineMemOperand *MMO) {1084      return MMO->getAlign() >= NeedAlign;1085    });1086  };1087 1088  switch (Opc) {1089    case Hexagon::PS_call_instrprof_custom: {1090      auto Op0 = MI.getOperand(0);1091      assert(Op0.isGlobal() &&1092             "First operand must be a global containing handler name.");1093      const GlobalValue *NameVar = Op0.getGlobal();1094      const GlobalVariable *GV = dyn_cast<GlobalVariable>(NameVar);1095      auto *Arr = cast<ConstantDataArray>(GV->getInitializer());1096      StringRef NameStr = Arr->isCString() ? Arr->getAsCString() : Arr->getAsString();1097 1098      MachineOperand &Op1 = MI.getOperand(1);1099      // Set R0 with the imm value to be passed to the custom profiling handler.1100      BuildMI(MBB, MI, DL, get(Hexagon::A2_tfrsi), Hexagon::R0)1101        .addImm(Op1.getImm());1102      // The call to the custom handler is being treated as a special one as the1103      // callee is responsible for saving and restoring all the registers1104      // (including caller saved registers) it needs to modify. This is1105      // done to reduce the impact of instrumentation on the code being1106      // instrumented/profiled.1107      // NOTE: R14, R15 and R28 are reserved for PLT handling. These registers1108      // are in the Def list of the Hexagon::PS_call_instrprof_custom and1109      // therefore will be handled appropriately duing register allocation.1110 1111      // TODO: It may be a good idea to add a separate pseudo instruction for1112      // static relocation which doesn't need to reserve r14, r15 and r28.1113 1114      auto MIB = BuildMI(MBB, MI, DL, get(Hexagon::J2_call))1115                 .addUse(Hexagon::R0, RegState::Implicit|RegState::InternalRead)1116                 .addDef(Hexagon::R29, RegState::ImplicitDefine)1117                 .addDef(Hexagon::R30, RegState::ImplicitDefine)1118                 .addDef(Hexagon::R14, RegState::ImplicitDefine)1119                 .addDef(Hexagon::R15, RegState::ImplicitDefine)1120                 .addDef(Hexagon::R28, RegState::ImplicitDefine);1121      const char *cstr = MF.createExternalSymbolName(NameStr);1122      MIB.addExternalSymbol(cstr);1123      MBB.erase(MI);1124      return true;1125    }1126    case TargetOpcode::COPY: {1127      MachineOperand &MD = MI.getOperand(0);1128      MachineOperand &MS = MI.getOperand(1);1129      MachineBasicBlock::iterator MBBI = MI.getIterator();1130      if (MD.getReg() != MS.getReg() && !MS.isUndef()) {1131        copyPhysReg(MBB, MI, DL, MD.getReg(), MS.getReg(), MS.isKill());1132        std::prev(MBBI)->copyImplicitOps(*MBB.getParent(), MI);1133      }1134      MBB.erase(MBBI);1135      return true;1136    }1137    case Hexagon::PS_aligna:1138      BuildMI(MBB, MI, DL, get(Hexagon::A2_andir), MI.getOperand(0).getReg())1139          .addReg(HRI.getFrameRegister())1140          .addImm(-MI.getOperand(1).getImm());1141      MBB.erase(MI);1142      return true;1143    case Hexagon::V6_vassignp: {1144      Register SrcReg = MI.getOperand(1).getReg();1145      Register DstReg = MI.getOperand(0).getReg();1146      Register SrcLo = HRI.getSubReg(SrcReg, Hexagon::vsub_lo);1147      Register SrcHi = HRI.getSubReg(SrcReg, Hexagon::vsub_hi);1148      getLiveInRegsAt(LiveIn, MI);1149      unsigned UndefLo = getUndefRegState(!LiveIn.contains(SrcLo));1150      unsigned UndefHi = getUndefRegState(!LiveIn.contains(SrcHi));1151      unsigned Kill = getKillRegState(MI.getOperand(1).isKill());1152      BuildMI(MBB, MI, DL, get(Hexagon::V6_vcombine), DstReg)1153          .addReg(SrcHi, UndefHi)1154          .addReg(SrcLo, Kill | UndefLo);1155      MBB.erase(MI);1156      return true;1157    }1158    case Hexagon::V6_lo: {1159      Register SrcReg = MI.getOperand(1).getReg();1160      Register DstReg = MI.getOperand(0).getReg();1161      Register SrcSubLo = HRI.getSubReg(SrcReg, Hexagon::vsub_lo);1162      copyPhysReg(MBB, MI, DL, DstReg, SrcSubLo, MI.getOperand(1).isKill());1163      MBB.erase(MI);1164      MRI.clearKillFlags(SrcSubLo);1165      return true;1166    }1167    case Hexagon::V6_hi: {1168      Register SrcReg = MI.getOperand(1).getReg();1169      Register DstReg = MI.getOperand(0).getReg();1170      Register SrcSubHi = HRI.getSubReg(SrcReg, Hexagon::vsub_hi);1171      copyPhysReg(MBB, MI, DL, DstReg, SrcSubHi, MI.getOperand(1).isKill());1172      MBB.erase(MI);1173      MRI.clearKillFlags(SrcSubHi);1174      return true;1175    }1176    case Hexagon::PS_vloadrv_ai: {1177      Register DstReg = MI.getOperand(0).getReg();1178      const MachineOperand &BaseOp = MI.getOperand(1);1179      assert(BaseOp.getSubReg() == 0);1180      int Offset = MI.getOperand(2).getImm();1181      Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);1182      unsigned NewOpc = UseAligned(MI, NeedAlign) ? Hexagon::V6_vL32b_ai1183                                                  : Hexagon::V6_vL32Ub_ai;1184      BuildMI(MBB, MI, DL, get(NewOpc), DstReg)1185          .addReg(BaseOp.getReg(), getRegState(BaseOp))1186          .addImm(Offset)1187          .cloneMemRefs(MI);1188      MBB.erase(MI);1189      return true;1190    }1191    case Hexagon::PS_vloadrw_ai: {1192      Register DstReg = MI.getOperand(0).getReg();1193      const MachineOperand &BaseOp = MI.getOperand(1);1194      assert(BaseOp.getSubReg() == 0);1195      int Offset = MI.getOperand(2).getImm();1196      unsigned VecOffset = HRI.getSpillSize(Hexagon::HvxVRRegClass);1197      Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);1198      unsigned NewOpc = UseAligned(MI, NeedAlign) ? Hexagon::V6_vL32b_ai1199                                                  : Hexagon::V6_vL32Ub_ai;1200      BuildMI(MBB, MI, DL, get(NewOpc),1201              HRI.getSubReg(DstReg, Hexagon::vsub_lo))1202          .addReg(BaseOp.getReg(), getRegState(BaseOp) & ~RegState::Kill)1203          .addImm(Offset)1204          .cloneMemRefs(MI);1205      BuildMI(MBB, MI, DL, get(NewOpc),1206              HRI.getSubReg(DstReg, Hexagon::vsub_hi))1207          .addReg(BaseOp.getReg(), getRegState(BaseOp))1208          .addImm(Offset + VecOffset)1209          .cloneMemRefs(MI);1210      MBB.erase(MI);1211      return true;1212    }1213    case Hexagon::PS_vstorerv_ai: {1214      const MachineOperand &SrcOp = MI.getOperand(2);1215      assert(SrcOp.getSubReg() == 0);1216      const MachineOperand &BaseOp = MI.getOperand(0);1217      assert(BaseOp.getSubReg() == 0);1218      int Offset = MI.getOperand(1).getImm();1219      Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);1220      unsigned NewOpc = UseAligned(MI, NeedAlign) ? Hexagon::V6_vS32b_ai1221                                                  : Hexagon::V6_vS32Ub_ai;1222      BuildMI(MBB, MI, DL, get(NewOpc))1223          .addReg(BaseOp.getReg(), getRegState(BaseOp))1224          .addImm(Offset)1225          .addReg(SrcOp.getReg(), getRegState(SrcOp))1226          .cloneMemRefs(MI);1227      MBB.erase(MI);1228      return true;1229    }1230    case Hexagon::PS_vstorerw_ai: {1231      Register SrcReg = MI.getOperand(2).getReg();1232      const MachineOperand &BaseOp = MI.getOperand(0);1233      assert(BaseOp.getSubReg() == 0);1234      int Offset = MI.getOperand(1).getImm();1235      unsigned VecOffset = HRI.getSpillSize(Hexagon::HvxVRRegClass);1236      Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);1237      unsigned NewOpc = UseAligned(MI, NeedAlign) ? Hexagon::V6_vS32b_ai1238                                                  : Hexagon::V6_vS32Ub_ai;1239      BuildMI(MBB, MI, DL, get(NewOpc))1240          .addReg(BaseOp.getReg(), getRegState(BaseOp) & ~RegState::Kill)1241          .addImm(Offset)1242          .addReg(HRI.getSubReg(SrcReg, Hexagon::vsub_lo))1243          .cloneMemRefs(MI);1244      BuildMI(MBB, MI, DL, get(NewOpc))1245          .addReg(BaseOp.getReg(), getRegState(BaseOp))1246          .addImm(Offset + VecOffset)1247          .addReg(HRI.getSubReg(SrcReg, Hexagon::vsub_hi))1248          .cloneMemRefs(MI);1249      MBB.erase(MI);1250      return true;1251    }1252    case Hexagon::PS_true: {1253      Register Reg = MI.getOperand(0).getReg();1254      BuildMI(MBB, MI, DL, get(Hexagon::C2_orn), Reg)1255        .addReg(Reg, RegState::Undef)1256        .addReg(Reg, RegState::Undef);1257      MBB.erase(MI);1258      return true;1259    }1260    case Hexagon::PS_false: {1261      Register Reg = MI.getOperand(0).getReg();1262      BuildMI(MBB, MI, DL, get(Hexagon::C2_andn), Reg)1263        .addReg(Reg, RegState::Undef)1264        .addReg(Reg, RegState::Undef);1265      MBB.erase(MI);1266      return true;1267    }1268    case Hexagon::PS_qtrue: {1269      BuildMI(MBB, MI, DL, get(Hexagon::V6_veqw), MI.getOperand(0).getReg())1270        .addReg(Hexagon::V0, RegState::Undef)1271        .addReg(Hexagon::V0, RegState::Undef);1272      MBB.erase(MI);1273      return true;1274    }1275    case Hexagon::PS_qfalse: {1276      BuildMI(MBB, MI, DL, get(Hexagon::V6_vgtw), MI.getOperand(0).getReg())1277        .addReg(Hexagon::V0, RegState::Undef)1278        .addReg(Hexagon::V0, RegState::Undef);1279      MBB.erase(MI);1280      return true;1281    }1282    case Hexagon::PS_vdd0: {1283      Register Vd = MI.getOperand(0).getReg();1284      BuildMI(MBB, MI, DL, get(Hexagon::V6_vsubw_dv), Vd)1285        .addReg(Vd, RegState::Undef)1286        .addReg(Vd, RegState::Undef);1287      MBB.erase(MI);1288      return true;1289    }1290    case Hexagon::PS_vmulw: {1291      // Expand a 64-bit vector multiply into 2 32-bit scalar multiplies.1292      Register DstReg = MI.getOperand(0).getReg();1293      Register Src1Reg = MI.getOperand(1).getReg();1294      Register Src2Reg = MI.getOperand(2).getReg();1295      Register Src1SubHi = HRI.getSubReg(Src1Reg, Hexagon::isub_hi);1296      Register Src1SubLo = HRI.getSubReg(Src1Reg, Hexagon::isub_lo);1297      Register Src2SubHi = HRI.getSubReg(Src2Reg, Hexagon::isub_hi);1298      Register Src2SubLo = HRI.getSubReg(Src2Reg, Hexagon::isub_lo);1299      BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::M2_mpyi),1300              HRI.getSubReg(DstReg, Hexagon::isub_hi))1301          .addReg(Src1SubHi)1302          .addReg(Src2SubHi);1303      BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::M2_mpyi),1304              HRI.getSubReg(DstReg, Hexagon::isub_lo))1305          .addReg(Src1SubLo)1306          .addReg(Src2SubLo);1307      MBB.erase(MI);1308      MRI.clearKillFlags(Src1SubHi);1309      MRI.clearKillFlags(Src1SubLo);1310      MRI.clearKillFlags(Src2SubHi);1311      MRI.clearKillFlags(Src2SubLo);1312      return true;1313    }1314    case Hexagon::PS_vmulw_acc: {1315      // Expand 64-bit vector multiply with addition into 2 scalar multiplies.1316      Register DstReg = MI.getOperand(0).getReg();1317      Register Src1Reg = MI.getOperand(1).getReg();1318      Register Src2Reg = MI.getOperand(2).getReg();1319      Register Src3Reg = MI.getOperand(3).getReg();1320      Register Src1SubHi = HRI.getSubReg(Src1Reg, Hexagon::isub_hi);1321      Register Src1SubLo = HRI.getSubReg(Src1Reg, Hexagon::isub_lo);1322      Register Src2SubHi = HRI.getSubReg(Src2Reg, Hexagon::isub_hi);1323      Register Src2SubLo = HRI.getSubReg(Src2Reg, Hexagon::isub_lo);1324      Register Src3SubHi = HRI.getSubReg(Src3Reg, Hexagon::isub_hi);1325      Register Src3SubLo = HRI.getSubReg(Src3Reg, Hexagon::isub_lo);1326      BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::M2_maci),1327              HRI.getSubReg(DstReg, Hexagon::isub_hi))1328          .addReg(Src1SubHi)1329          .addReg(Src2SubHi)1330          .addReg(Src3SubHi);1331      BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::M2_maci),1332              HRI.getSubReg(DstReg, Hexagon::isub_lo))1333          .addReg(Src1SubLo)1334          .addReg(Src2SubLo)1335          .addReg(Src3SubLo);1336      MBB.erase(MI);1337      MRI.clearKillFlags(Src1SubHi);1338      MRI.clearKillFlags(Src1SubLo);1339      MRI.clearKillFlags(Src2SubHi);1340      MRI.clearKillFlags(Src2SubLo);1341      MRI.clearKillFlags(Src3SubHi);1342      MRI.clearKillFlags(Src3SubLo);1343      return true;1344    }1345    case Hexagon::PS_pselect: {1346      const MachineOperand &Op0 = MI.getOperand(0);1347      const MachineOperand &Op1 = MI.getOperand(1);1348      const MachineOperand &Op2 = MI.getOperand(2);1349      const MachineOperand &Op3 = MI.getOperand(3);1350      Register Rd = Op0.getReg();1351      Register Pu = Op1.getReg();1352      Register Rs = Op2.getReg();1353      Register Rt = Op3.getReg();1354      DebugLoc DL = MI.getDebugLoc();1355      unsigned K1 = getKillRegState(Op1.isKill());1356      unsigned K2 = getKillRegState(Op2.isKill());1357      unsigned K3 = getKillRegState(Op3.isKill());1358      if (Rd != Rs)1359        BuildMI(MBB, MI, DL, get(Hexagon::A2_tfrpt), Rd)1360          .addReg(Pu, (Rd == Rt) ? K1 : 0)1361          .addReg(Rs, K2);1362      if (Rd != Rt)1363        BuildMI(MBB, MI, DL, get(Hexagon::A2_tfrpf), Rd)1364          .addReg(Pu, K1)1365          .addReg(Rt, K3);1366      MBB.erase(MI);1367      return true;1368    }1369    case Hexagon::PS_vselect: {1370      const MachineOperand &Op0 = MI.getOperand(0);1371      const MachineOperand &Op1 = MI.getOperand(1);1372      const MachineOperand &Op2 = MI.getOperand(2);1373      const MachineOperand &Op3 = MI.getOperand(3);1374      getLiveOutRegsAt(LiveOut, MI);1375      bool IsDestLive = !LiveOut.available(MRI, Op0.getReg());1376      Register PReg = Op1.getReg();1377      assert(Op1.getSubReg() == 0);1378      unsigned PState = getRegState(Op1);1379 1380      if (Op0.getReg() != Op2.getReg()) {1381        unsigned S = Op0.getReg() != Op3.getReg() ? PState & ~RegState::Kill1382                                                  : PState;1383        auto T = BuildMI(MBB, MI, DL, get(Hexagon::V6_vcmov))1384                     .add(Op0)1385                     .addReg(PReg, S)1386                     .add(Op2);1387        if (IsDestLive)1388          T.addReg(Op0.getReg(), RegState::Implicit);1389        IsDestLive = true;1390      }1391      if (Op0.getReg() != Op3.getReg()) {1392        auto T = BuildMI(MBB, MI, DL, get(Hexagon::V6_vncmov))1393                     .add(Op0)1394                     .addReg(PReg, PState)1395                     .add(Op3);1396        if (IsDestLive)1397          T.addReg(Op0.getReg(), RegState::Implicit);1398      }1399      MBB.erase(MI);1400      return true;1401    }1402    case Hexagon::PS_wselect: {1403      MachineOperand &Op0 = MI.getOperand(0);1404      MachineOperand &Op1 = MI.getOperand(1);1405      MachineOperand &Op2 = MI.getOperand(2);1406      MachineOperand &Op3 = MI.getOperand(3);1407      getLiveOutRegsAt(LiveOut, MI);1408      bool IsDestLive = !LiveOut.available(MRI, Op0.getReg());1409      Register PReg = Op1.getReg();1410      assert(Op1.getSubReg() == 0);1411      unsigned PState = getRegState(Op1);1412 1413      if (Op0.getReg() != Op2.getReg()) {1414        unsigned S = Op0.getReg() != Op3.getReg() ? PState & ~RegState::Kill1415                                                  : PState;1416        Register SrcLo = HRI.getSubReg(Op2.getReg(), Hexagon::vsub_lo);1417        Register SrcHi = HRI.getSubReg(Op2.getReg(), Hexagon::vsub_hi);1418        auto T = BuildMI(MBB, MI, DL, get(Hexagon::V6_vccombine))1419                     .add(Op0)1420                     .addReg(PReg, S)1421                     .addReg(SrcHi)1422                     .addReg(SrcLo);1423        if (IsDestLive)1424          T.addReg(Op0.getReg(), RegState::Implicit);1425        IsDestLive = true;1426      }1427      if (Op0.getReg() != Op3.getReg()) {1428        Register SrcLo = HRI.getSubReg(Op3.getReg(), Hexagon::vsub_lo);1429        Register SrcHi = HRI.getSubReg(Op3.getReg(), Hexagon::vsub_hi);1430        auto T = BuildMI(MBB, MI, DL, get(Hexagon::V6_vnccombine))1431                     .add(Op0)1432                     .addReg(PReg, PState)1433                     .addReg(SrcHi)1434                     .addReg(SrcLo);1435        if (IsDestLive)1436          T.addReg(Op0.getReg(), RegState::Implicit);1437      }1438      MBB.erase(MI);1439      return true;1440    }1441 1442    case Hexagon::PS_crash: {1443      // Generate a misaligned load that is guaranteed to cause a crash.1444      class CrashPseudoSourceValue : public PseudoSourceValue {1445      public:1446        CrashPseudoSourceValue(const TargetMachine &TM)1447            : PseudoSourceValue(TargetCustom, TM) {}1448 1449        bool isConstant(const MachineFrameInfo *) const override {1450          return false;1451        }1452        bool isAliased(const MachineFrameInfo *) const override {1453          return false;1454        }1455        bool mayAlias(const MachineFrameInfo *) const override {1456          return false;1457        }1458        void printCustom(raw_ostream &OS) const override {1459          OS << "MisalignedCrash";1460        }1461      };1462 1463      static const CrashPseudoSourceValue CrashPSV(MF.getTarget());1464      MachineMemOperand *MMO = MF.getMachineMemOperand(1465          MachinePointerInfo(&CrashPSV),1466          MachineMemOperand::MOLoad | MachineMemOperand::MOVolatile, 8,1467          Align(1));1468      BuildMI(MBB, MI, DL, get(Hexagon::PS_loadrdabs), Hexagon::D13)1469        .addImm(0xBADC0FEE)  // Misaligned load.1470        .addMemOperand(MMO);1471      MBB.erase(MI);1472      return true;1473    }1474 1475    case Hexagon::PS_tailcall_i:1476      MI.setDesc(get(Hexagon::J2_jump));1477      return true;1478    case Hexagon::PS_tailcall_r:1479    case Hexagon::PS_jmpret:1480      MI.setDesc(get(Hexagon::J2_jumpr));1481      return true;1482    case Hexagon::PS_jmprett:1483      MI.setDesc(get(Hexagon::J2_jumprt));1484      return true;1485    case Hexagon::PS_jmpretf:1486      MI.setDesc(get(Hexagon::J2_jumprf));1487      return true;1488    case Hexagon::PS_jmprettnewpt:1489      MI.setDesc(get(Hexagon::J2_jumprtnewpt));1490      return true;1491    case Hexagon::PS_jmpretfnewpt:1492      MI.setDesc(get(Hexagon::J2_jumprfnewpt));1493      return true;1494    case Hexagon::PS_jmprettnew:1495      MI.setDesc(get(Hexagon::J2_jumprtnew));1496      return true;1497    case Hexagon::PS_jmpretfnew:1498      MI.setDesc(get(Hexagon::J2_jumprfnew));1499      return true;1500 1501    case Hexagon::PS_loadrub_pci:1502      return RealCirc(Hexagon::L2_loadrub_pci, /*HasImm*/true,  /*MxOp*/4);1503    case Hexagon::PS_loadrb_pci:1504      return RealCirc(Hexagon::L2_loadrb_pci,  /*HasImm*/true,  /*MxOp*/4);1505    case Hexagon::PS_loadruh_pci:1506      return RealCirc(Hexagon::L2_loadruh_pci, /*HasImm*/true,  /*MxOp*/4);1507    case Hexagon::PS_loadrh_pci:1508      return RealCirc(Hexagon::L2_loadrh_pci,  /*HasImm*/true,  /*MxOp*/4);1509    case Hexagon::PS_loadri_pci:1510      return RealCirc(Hexagon::L2_loadri_pci,  /*HasImm*/true,  /*MxOp*/4);1511    case Hexagon::PS_loadrd_pci:1512      return RealCirc(Hexagon::L2_loadrd_pci,  /*HasImm*/true,  /*MxOp*/4);1513    case Hexagon::PS_loadrub_pcr:1514      return RealCirc(Hexagon::L2_loadrub_pcr, /*HasImm*/false, /*MxOp*/3);1515    case Hexagon::PS_loadrb_pcr:1516      return RealCirc(Hexagon::L2_loadrb_pcr,  /*HasImm*/false, /*MxOp*/3);1517    case Hexagon::PS_loadruh_pcr:1518      return RealCirc(Hexagon::L2_loadruh_pcr, /*HasImm*/false, /*MxOp*/3);1519    case Hexagon::PS_loadrh_pcr:1520      return RealCirc(Hexagon::L2_loadrh_pcr,  /*HasImm*/false, /*MxOp*/3);1521    case Hexagon::PS_loadri_pcr:1522      return RealCirc(Hexagon::L2_loadri_pcr,  /*HasImm*/false, /*MxOp*/3);1523    case Hexagon::PS_loadrd_pcr:1524      return RealCirc(Hexagon::L2_loadrd_pcr,  /*HasImm*/false, /*MxOp*/3);1525    case Hexagon::PS_storerb_pci:1526      return RealCirc(Hexagon::S2_storerb_pci, /*HasImm*/true,  /*MxOp*/3);1527    case Hexagon::PS_storerh_pci:1528      return RealCirc(Hexagon::S2_storerh_pci, /*HasImm*/true,  /*MxOp*/3);1529    case Hexagon::PS_storerf_pci:1530      return RealCirc(Hexagon::S2_storerf_pci, /*HasImm*/true,  /*MxOp*/3);1531    case Hexagon::PS_storeri_pci:1532      return RealCirc(Hexagon::S2_storeri_pci, /*HasImm*/true,  /*MxOp*/3);1533    case Hexagon::PS_storerd_pci:1534      return RealCirc(Hexagon::S2_storerd_pci, /*HasImm*/true,  /*MxOp*/3);1535    case Hexagon::PS_storerb_pcr:1536      return RealCirc(Hexagon::S2_storerb_pcr, /*HasImm*/false, /*MxOp*/2);1537    case Hexagon::PS_storerh_pcr:1538      return RealCirc(Hexagon::S2_storerh_pcr, /*HasImm*/false, /*MxOp*/2);1539    case Hexagon::PS_storerf_pcr:1540      return RealCirc(Hexagon::S2_storerf_pcr, /*HasImm*/false, /*MxOp*/2);1541    case Hexagon::PS_storeri_pcr:1542      return RealCirc(Hexagon::S2_storeri_pcr, /*HasImm*/false, /*MxOp*/2);1543    case Hexagon::PS_storerd_pcr:1544      return RealCirc(Hexagon::S2_storerd_pcr, /*HasImm*/false, /*MxOp*/2);1545  }1546 1547  return false;1548}1549 1550MachineBasicBlock::instr_iterator1551HexagonInstrInfo::expandVGatherPseudo(MachineInstr &MI) const {1552  MachineBasicBlock &MBB = *MI.getParent();1553  const DebugLoc &DL = MI.getDebugLoc();1554  unsigned Opc = MI.getOpcode();1555  MachineBasicBlock::iterator First;1556 1557  switch (Opc) {1558  case Hexagon::V6_vgather_vscatter_mh_pseudo:1559    // This is mainly a place holder. It will be extended.1560    First = BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermh))1561                .add(MI.getOperand(2))1562                .add(MI.getOperand(3))1563                .add(MI.getOperand(4));1564    BuildMI(MBB, MI, DL, get(Hexagon::V6_vscattermh))1565        .add(MI.getOperand(2))1566        .add(MI.getOperand(3))1567        .add(MI.getOperand(4))1568        .addReg(Hexagon::VTMP);1569    MBB.erase(MI);1570    return First.getInstrIterator();1571  case Hexagon::V6_vgathermh_pseudo:1572    First = BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermh))1573                .add(MI.getOperand(2))1574                .add(MI.getOperand(3))1575                .add(MI.getOperand(4));1576    BuildMI(MBB, MI, DL, get(Hexagon::V6_vS32b_new_ai))1577        .add(MI.getOperand(0))1578        .addImm(MI.getOperand(1).getImm())1579        .addReg(Hexagon::VTMP);1580    MBB.erase(MI);1581    return First.getInstrIterator();1582 1583  case Hexagon::V6_vgathermw_pseudo:1584    First = BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermw))1585                .add(MI.getOperand(2))1586                .add(MI.getOperand(3))1587                .add(MI.getOperand(4));1588    BuildMI(MBB, MI, DL, get(Hexagon::V6_vS32b_new_ai))1589        .add(MI.getOperand(0))1590        .addImm(MI.getOperand(1).getImm())1591        .addReg(Hexagon::VTMP);1592    MBB.erase(MI);1593    return First.getInstrIterator();1594 1595  case Hexagon::V6_vgathermhw_pseudo:1596    First = BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermhw))1597                .add(MI.getOperand(2))1598                .add(MI.getOperand(3))1599                .add(MI.getOperand(4));1600    BuildMI(MBB, MI, DL, get(Hexagon::V6_vS32b_new_ai))1601        .add(MI.getOperand(0))1602        .addImm(MI.getOperand(1).getImm())1603        .addReg(Hexagon::VTMP);1604    MBB.erase(MI);1605    return First.getInstrIterator();1606 1607  case Hexagon::V6_vgathermhq_pseudo:1608    First = BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermhq))1609                .add(MI.getOperand(2))1610                .add(MI.getOperand(3))1611                .add(MI.getOperand(4))1612                .add(MI.getOperand(5));1613    BuildMI(MBB, MI, DL, get(Hexagon::V6_vS32b_new_ai))1614        .add(MI.getOperand(0))1615        .addImm(MI.getOperand(1).getImm())1616        .addReg(Hexagon::VTMP);1617    MBB.erase(MI);1618    return First.getInstrIterator();1619 1620  case Hexagon::V6_vgathermwq_pseudo:1621    First = BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermwq))1622                .add(MI.getOperand(2))1623                .add(MI.getOperand(3))1624                .add(MI.getOperand(4))1625                .add(MI.getOperand(5));1626    BuildMI(MBB, MI, DL, get(Hexagon::V6_vS32b_new_ai))1627        .add(MI.getOperand(0))1628        .addImm(MI.getOperand(1).getImm())1629        .addReg(Hexagon::VTMP);1630    MBB.erase(MI);1631    return First.getInstrIterator();1632 1633  case Hexagon::V6_vgathermhwq_pseudo:1634    First = BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermhwq))1635                .add(MI.getOperand(2))1636                .add(MI.getOperand(3))1637                .add(MI.getOperand(4))1638                .add(MI.getOperand(5));1639    BuildMI(MBB, MI, DL, get(Hexagon::V6_vS32b_new_ai))1640        .add(MI.getOperand(0))1641        .addImm(MI.getOperand(1).getImm())1642        .addReg(Hexagon::VTMP);1643    MBB.erase(MI);1644    return First.getInstrIterator();1645  }1646 1647  return MI.getIterator();1648}1649 1650// We indicate that we want to reverse the branch by1651// inserting the reversed branching opcode.1652bool HexagonInstrInfo::reverseBranchCondition(1653      SmallVectorImpl<MachineOperand> &Cond) const {1654  if (Cond.empty())1655    return true;1656  assert(Cond[0].isImm() && "First entry in the cond vector not imm-val");1657  unsigned opcode = Cond[0].getImm();1658  //unsigned temp;1659  assert(get(opcode).isBranch() && "Should be a branching condition.");1660  if (isEndLoopN(opcode))1661    return true;1662  unsigned NewOpcode = getInvertedPredicatedOpcode(opcode);1663  Cond[0].setImm(NewOpcode);1664  return false;1665}1666 1667void HexagonInstrInfo::insertNoop(MachineBasicBlock &MBB,1668      MachineBasicBlock::iterator MI) const {1669  DebugLoc DL;1670  BuildMI(MBB, MI, DL, get(Hexagon::A2_nop));1671}1672 1673bool HexagonInstrInfo::isPostIncrement(const MachineInstr &MI) const {1674  return getAddrMode(MI) == HexagonII::PostInc;1675}1676 1677// Returns true if an instruction is predicated irrespective of the predicate1678// sense. For example, all of the following will return true.1679// if (p0) R1 = add(R2, R3)1680// if (!p0) R1 = add(R2, R3)1681// if (p0.new) R1 = add(R2, R3)1682// if (!p0.new) R1 = add(R2, R3)1683// Note: New-value stores are not included here as in the current1684// implementation, we don't need to check their predicate sense.1685bool HexagonInstrInfo::isPredicated(const MachineInstr &MI) const {1686  const uint64_t F = MI.getDesc().TSFlags;1687  return (F >> HexagonII::PredicatedPos) & HexagonII::PredicatedMask;1688}1689 1690bool HexagonInstrInfo::PredicateInstruction(1691    MachineInstr &MI, ArrayRef<MachineOperand> Cond) const {1692  if (Cond.empty() || isNewValueJump(Cond[0].getImm()) ||1693      isEndLoopN(Cond[0].getImm())) {1694    LLVM_DEBUG(dbgs() << "\nCannot predicate:"; MI.dump(););1695    return false;1696  }1697  int Opc = MI.getOpcode();1698  assert (isPredicable(MI) && "Expected predicable instruction");1699  bool invertJump = predOpcodeHasNot(Cond);1700 1701  // We have to predicate MI "in place", i.e. after this function returns,1702  // MI will need to be transformed into a predicated form. To avoid com-1703  // plicated manipulations with the operands (handling tied operands,1704  // etc.), build a new temporary instruction, then overwrite MI with it.1705 1706  MachineBasicBlock &B = *MI.getParent();1707  DebugLoc DL = MI.getDebugLoc();1708  unsigned PredOpc = getCondOpcode(Opc, invertJump);1709  MachineInstrBuilder T = BuildMI(B, MI, DL, get(PredOpc));1710  unsigned NOp = 0, NumOps = MI.getNumOperands();1711  while (NOp < NumOps) {1712    MachineOperand &Op = MI.getOperand(NOp);1713    if (!Op.isReg() || !Op.isDef() || Op.isImplicit())1714      break;1715    T.add(Op);1716    NOp++;1717  }1718 1719  Register PredReg;1720  unsigned PredRegPos, PredRegFlags;1721  bool GotPredReg = getPredReg(Cond, PredReg, PredRegPos, PredRegFlags);1722  (void)GotPredReg;1723  assert(GotPredReg);1724  T.addReg(PredReg, PredRegFlags);1725  while (NOp < NumOps)1726    T.add(MI.getOperand(NOp++));1727 1728  MI.setDesc(get(PredOpc));1729  while (unsigned n = MI.getNumOperands())1730    MI.removeOperand(n-1);1731  for (unsigned i = 0, n = T->getNumOperands(); i < n; ++i)1732    MI.addOperand(T->getOperand(i));1733 1734  MachineBasicBlock::instr_iterator TI = T->getIterator();1735  B.erase(TI);1736 1737  MachineRegisterInfo &MRI = B.getParent()->getRegInfo();1738  MRI.clearKillFlags(PredReg);1739  return true;1740}1741 1742bool HexagonInstrInfo::SubsumesPredicate(ArrayRef<MachineOperand> Pred1,1743      ArrayRef<MachineOperand> Pred2) const {1744  // TODO: Fix this1745  return false;1746}1747 1748bool HexagonInstrInfo::ClobbersPredicate(MachineInstr &MI,1749                                         std::vector<MachineOperand> &Pred,1750                                         bool SkipDead) const {1751  const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();1752 1753  for (const MachineOperand &MO : MI.operands()) {1754    if (MO.isReg()) {1755      if (!MO.isDef())1756        continue;1757      const TargetRegisterClass* RC = HRI.getMinimalPhysRegClass(MO.getReg());1758      if (RC == &Hexagon::PredRegsRegClass) {1759        Pred.push_back(MO);1760        return true;1761      }1762      continue;1763    } else if (MO.isRegMask()) {1764      for (Register PR : Hexagon::PredRegsRegClass) {1765        if (!MI.modifiesRegister(PR, &HRI))1766          continue;1767        Pred.push_back(MO);1768        return true;1769      }1770    }1771  }1772  return false;1773}1774 1775bool HexagonInstrInfo::isPredicable(const MachineInstr &MI) const {1776  if (!MI.getDesc().isPredicable())1777    return false;1778 1779  if (MI.isCall() || isTailCall(MI)) {1780    if (!Subtarget.usePredicatedCalls())1781      return false;1782  }1783 1784  // HVX loads are not predicable on v60, but are on v62.1785  if (!Subtarget.hasV62Ops()) {1786    switch (MI.getOpcode()) {1787      case Hexagon::V6_vL32b_ai:1788      case Hexagon::V6_vL32b_pi:1789      case Hexagon::V6_vL32b_ppu:1790      case Hexagon::V6_vL32b_cur_ai:1791      case Hexagon::V6_vL32b_cur_pi:1792      case Hexagon::V6_vL32b_cur_ppu:1793      case Hexagon::V6_vL32b_nt_ai:1794      case Hexagon::V6_vL32b_nt_pi:1795      case Hexagon::V6_vL32b_nt_ppu:1796      case Hexagon::V6_vL32b_tmp_ai:1797      case Hexagon::V6_vL32b_tmp_pi:1798      case Hexagon::V6_vL32b_tmp_ppu:1799      case Hexagon::V6_vL32b_nt_cur_ai:1800      case Hexagon::V6_vL32b_nt_cur_pi:1801      case Hexagon::V6_vL32b_nt_cur_ppu:1802      case Hexagon::V6_vL32b_nt_tmp_ai:1803      case Hexagon::V6_vL32b_nt_tmp_pi:1804      case Hexagon::V6_vL32b_nt_tmp_ppu:1805        return false;1806    }1807  }1808  return true;1809}1810 1811bool HexagonInstrInfo::isSchedulingBoundary(const MachineInstr &MI,1812                                            const MachineBasicBlock *MBB,1813                                            const MachineFunction &MF) const {1814  // Debug info is never a scheduling boundary. It's necessary to be explicit1815  // due to the special treatment of IT instructions below, otherwise a1816  // dbg_value followed by an IT will result in the IT instruction being1817  // considered a scheduling hazard, which is wrong. It should be the actual1818  // instruction preceding the dbg_value instruction(s), just like it is1819  // when debug info is not present.1820  if (MI.isDebugInstr())1821    return false;1822 1823  // Throwing call is a boundary.1824  if (MI.isCall()) {1825    // Don't mess around with no return calls.1826    if (doesNotReturn(MI))1827      return true;1828    // If any of the block's successors is a landing pad, this could be a1829    // throwing call.1830    for (auto *I : MBB->successors())1831      if (I->isEHPad())1832        return true;1833  }1834 1835  // Terminators and labels can't be scheduled around.1836  if (MI.getDesc().isTerminator() || MI.isPosition())1837    return true;1838 1839  // INLINEASM_BR can jump to another block1840  if (MI.getOpcode() == TargetOpcode::INLINEASM_BR)1841    return true;1842 1843  if (MI.isInlineAsm() && !ScheduleInlineAsm)1844    return true;1845 1846  return false;1847}1848 1849/// Measure the specified inline asm to determine an approximation of its1850/// length.1851/// Comments (which run till the next SeparatorString or newline) do not1852/// count as an instruction.1853/// Any other non-whitespace text is considered an instruction, with1854/// multiple instructions separated by SeparatorString or newlines.1855/// Variable-length instructions are not handled here; this function1856/// may be overloaded in the target code to do that.1857/// Hexagon counts the number of ##'s and adjust for that many1858/// constant exenders.1859unsigned HexagonInstrInfo::getInlineAsmLength(const char *Str,1860                                              const MCAsmInfo &MAI,1861                                              const TargetSubtargetInfo *STI) const {1862  StringRef AStr(Str);1863  // Count the number of instructions in the asm.1864  bool atInsnStart = true;1865  unsigned Length = 0;1866  const unsigned MaxInstLength = MAI.getMaxInstLength(STI);1867  for (; *Str; ++Str) {1868    if (*Str == '\n' || strncmp(Str, MAI.getSeparatorString(),1869                                strlen(MAI.getSeparatorString())) == 0)1870      atInsnStart = true;1871    if (atInsnStart && !isSpace(static_cast<unsigned char>(*Str))) {1872      Length += MaxInstLength;1873      atInsnStart = false;1874    }1875    if (atInsnStart && strncmp(Str, MAI.getCommentString().data(),1876                               MAI.getCommentString().size()) == 0)1877      atInsnStart = false;1878  }1879 1880  // Add to size number of constant extenders seen * 4.1881  StringRef Occ("##");1882  Length += AStr.count(Occ)*4;1883  return Length;1884}1885 1886ScheduleHazardRecognizer*1887HexagonInstrInfo::CreateTargetPostRAHazardRecognizer(1888      const InstrItineraryData *II, const ScheduleDAG *DAG) const {1889  if (UseDFAHazardRec)1890    return new HexagonHazardRecognizer(II, this, Subtarget);1891  return TargetInstrInfo::CreateTargetPostRAHazardRecognizer(II, DAG);1892}1893 1894/// For a comparison instruction, return the source registers in1895/// \p SrcReg and \p SrcReg2 if having two register operands, and the value it1896/// compares against in CmpValue. Return true if the comparison instruction1897/// can be analyzed.1898bool HexagonInstrInfo::analyzeCompare(const MachineInstr &MI, Register &SrcReg,1899                                      Register &SrcReg2, int64_t &Mask,1900                                      int64_t &Value) const {1901  unsigned Opc = MI.getOpcode();1902 1903  // Set mask and the first source register.1904  switch (Opc) {1905    case Hexagon::C2_cmpeq:1906    case Hexagon::C2_cmpeqp:1907    case Hexagon::C2_cmpgt:1908    case Hexagon::C2_cmpgtp:1909    case Hexagon::C2_cmpgtu:1910    case Hexagon::C2_cmpgtup:1911    case Hexagon::C4_cmpneq:1912    case Hexagon::C4_cmplte:1913    case Hexagon::C4_cmplteu:1914    case Hexagon::C2_cmpeqi:1915    case Hexagon::C2_cmpgti:1916    case Hexagon::C2_cmpgtui:1917    case Hexagon::C4_cmpneqi:1918    case Hexagon::C4_cmplteui:1919    case Hexagon::C4_cmpltei:1920      SrcReg = MI.getOperand(1).getReg();1921      Mask = ~0;1922      break;1923    case Hexagon::A4_cmpbeq:1924    case Hexagon::A4_cmpbgt:1925    case Hexagon::A4_cmpbgtu:1926    case Hexagon::A4_cmpbeqi:1927    case Hexagon::A4_cmpbgti:1928    case Hexagon::A4_cmpbgtui:1929      SrcReg = MI.getOperand(1).getReg();1930      Mask = 0xFF;1931      break;1932    case Hexagon::A4_cmpheq:1933    case Hexagon::A4_cmphgt:1934    case Hexagon::A4_cmphgtu:1935    case Hexagon::A4_cmpheqi:1936    case Hexagon::A4_cmphgti:1937    case Hexagon::A4_cmphgtui:1938      SrcReg = MI.getOperand(1).getReg();1939      Mask = 0xFFFF;1940      break;1941  }1942 1943  // Set the value/second source register.1944  switch (Opc) {1945    case Hexagon::C2_cmpeq:1946    case Hexagon::C2_cmpeqp:1947    case Hexagon::C2_cmpgt:1948    case Hexagon::C2_cmpgtp:1949    case Hexagon::C2_cmpgtu:1950    case Hexagon::C2_cmpgtup:1951    case Hexagon::A4_cmpbeq:1952    case Hexagon::A4_cmpbgt:1953    case Hexagon::A4_cmpbgtu:1954    case Hexagon::A4_cmpheq:1955    case Hexagon::A4_cmphgt:1956    case Hexagon::A4_cmphgtu:1957    case Hexagon::C4_cmpneq:1958    case Hexagon::C4_cmplte:1959    case Hexagon::C4_cmplteu:1960      SrcReg2 = MI.getOperand(2).getReg();1961      Value = 0;1962      return true;1963 1964    case Hexagon::C2_cmpeqi:1965    case Hexagon::C2_cmpgtui:1966    case Hexagon::C2_cmpgti:1967    case Hexagon::C4_cmpneqi:1968    case Hexagon::C4_cmplteui:1969    case Hexagon::C4_cmpltei:1970    case Hexagon::A4_cmpbeqi:1971    case Hexagon::A4_cmpbgti:1972    case Hexagon::A4_cmpbgtui:1973    case Hexagon::A4_cmpheqi:1974    case Hexagon::A4_cmphgti:1975    case Hexagon::A4_cmphgtui: {1976      SrcReg2 = 0;1977      const MachineOperand &Op2 = MI.getOperand(2);1978      if (!Op2.isImm())1979        return false;1980      Value = MI.getOperand(2).getImm();1981      return true;1982    }1983  }1984 1985  return false;1986}1987 1988unsigned HexagonInstrInfo::getInstrLatency(const InstrItineraryData *ItinData,1989                                           const MachineInstr &MI,1990                                           unsigned *PredCost) const {1991  return getInstrTimingClassLatency(ItinData, MI);1992}1993 1994DFAPacketizer *HexagonInstrInfo::CreateTargetScheduleState(1995    const TargetSubtargetInfo &STI) const {1996  const InstrItineraryData *II = STI.getInstrItineraryData();1997  return static_cast<const HexagonSubtarget&>(STI).createDFAPacketizer(II);1998}1999 2000// Inspired by this pair:2001//  %r13 = L2_loadri_io %r29, 136; mem:LD4[FixedStack0]2002//  S2_storeri_io %r29, 132, killed %r1; flags:  mem:ST4[FixedStack1]2003// Currently AA considers the addresses in these instructions to be aliasing.2004bool HexagonInstrInfo::areMemAccessesTriviallyDisjoint(2005    const MachineInstr &MIa, const MachineInstr &MIb) const {2006  if (MIa.hasUnmodeledSideEffects() || MIb.hasUnmodeledSideEffects() ||2007      MIa.hasOrderedMemoryRef() || MIb.hasOrderedMemoryRef())2008    return false;2009 2010  // Instructions that are pure loads, not loads and stores like memops are not2011  // dependent.2012  if (MIa.mayLoad() && !isMemOp(MIa) && MIb.mayLoad() && !isMemOp(MIb))2013    return true;2014 2015  // Get the base register in MIa.2016  unsigned BasePosA, OffsetPosA;2017  if (!getBaseAndOffsetPosition(MIa, BasePosA, OffsetPosA))2018    return false;2019  const MachineOperand &BaseA = MIa.getOperand(BasePosA);2020  Register BaseRegA = BaseA.getReg();2021  unsigned BaseSubA = BaseA.getSubReg();2022 2023  // Get the base register in MIb.2024  unsigned BasePosB, OffsetPosB;2025  if (!getBaseAndOffsetPosition(MIb, BasePosB, OffsetPosB))2026    return false;2027  const MachineOperand &BaseB = MIb.getOperand(BasePosB);2028  Register BaseRegB = BaseB.getReg();2029  unsigned BaseSubB = BaseB.getSubReg();2030 2031  if (BaseRegA != BaseRegB || BaseSubA != BaseSubB)2032    return false;2033 2034  // Get the access sizes.2035  unsigned SizeA = getMemAccessSize(MIa);2036  unsigned SizeB = getMemAccessSize(MIb);2037 2038  // Get the offsets. Handle immediates only for now.2039  const MachineOperand &OffA = MIa.getOperand(OffsetPosA);2040  const MachineOperand &OffB = MIb.getOperand(OffsetPosB);2041  if (!MIa.getOperand(OffsetPosA).isImm() ||2042      !MIb.getOperand(OffsetPosB).isImm())2043    return false;2044  int OffsetA = isPostIncrement(MIa) ? 0 : OffA.getImm();2045  int OffsetB = isPostIncrement(MIb) ? 0 : OffB.getImm();2046 2047  // This is a mem access with the same base register and known offsets from it.2048  // Reason about it.2049  if (OffsetA > OffsetB) {2050    uint64_t OffDiff = (uint64_t)((int64_t)OffsetA - (int64_t)OffsetB);2051    return SizeB <= OffDiff;2052  }2053  if (OffsetA < OffsetB) {2054    uint64_t OffDiff = (uint64_t)((int64_t)OffsetB - (int64_t)OffsetA);2055    return SizeA <= OffDiff;2056  }2057 2058  return false;2059}2060 2061/// If the instruction is an increment of a constant value, return the amount.2062bool HexagonInstrInfo::getIncrementValue(const MachineInstr &MI,2063      int &Value) const {2064  if (isPostIncrement(MI)) {2065    unsigned BasePos = 0, OffsetPos = 0;2066    if (!getBaseAndOffsetPosition(MI, BasePos, OffsetPos))2067      return false;2068    const MachineOperand &OffsetOp = MI.getOperand(OffsetPos);2069    if (OffsetOp.isImm()) {2070      Value = OffsetOp.getImm();2071      return true;2072    }2073  } else if (MI.getOpcode() == Hexagon::A2_addi) {2074    const MachineOperand &AddOp = MI.getOperand(2);2075    if (AddOp.isImm()) {2076      Value = AddOp.getImm();2077      return true;2078    }2079  }2080 2081  return false;2082}2083 2084std::pair<unsigned, unsigned>2085HexagonInstrInfo::decomposeMachineOperandsTargetFlags(unsigned TF) const {2086  return std::make_pair(TF & ~HexagonII::MO_Bitmasks,2087                        TF & HexagonII::MO_Bitmasks);2088}2089 2090ArrayRef<std::pair<unsigned, const char*>>2091HexagonInstrInfo::getSerializableDirectMachineOperandTargetFlags() const {2092  using namespace HexagonII;2093 2094  static const std::pair<unsigned, const char*> Flags[] = {2095    {MO_PCREL,  "hexagon-pcrel"},2096    {MO_GOT,    "hexagon-got"},2097    {MO_LO16,   "hexagon-lo16"},2098    {MO_HI16,   "hexagon-hi16"},2099    {MO_GPREL,  "hexagon-gprel"},2100    {MO_GDGOT,  "hexagon-gdgot"},2101    {MO_GDPLT,  "hexagon-gdplt"},2102    {MO_IE,     "hexagon-ie"},2103    {MO_IEGOT,  "hexagon-iegot"},2104    {MO_TPREL,  "hexagon-tprel"}2105  };2106  return ArrayRef(Flags);2107}2108 2109ArrayRef<std::pair<unsigned, const char*>>2110HexagonInstrInfo::getSerializableBitmaskMachineOperandTargetFlags() const {2111  using namespace HexagonII;2112 2113  static const std::pair<unsigned, const char*> Flags[] = {2114    {HMOTF_ConstExtended, "hexagon-ext"}2115  };2116  return ArrayRef(Flags);2117}2118 2119Register HexagonInstrInfo::createVR(MachineFunction *MF, MVT VT) const {2120  MachineRegisterInfo &MRI = MF->getRegInfo();2121  const TargetRegisterClass *TRC;2122  if (VT == MVT::i1) {2123    TRC = &Hexagon::PredRegsRegClass;2124  } else if (VT == MVT::i32 || VT == MVT::f32) {2125    TRC = &Hexagon::IntRegsRegClass;2126  } else if (VT == MVT::i64 || VT == MVT::f64) {2127    TRC = &Hexagon::DoubleRegsRegClass;2128  } else {2129    llvm_unreachable("Cannot handle this register class");2130  }2131 2132  Register NewReg = MRI.createVirtualRegister(TRC);2133  return NewReg;2134}2135 2136bool HexagonInstrInfo::isAbsoluteSet(const MachineInstr &MI) const {2137  return (getAddrMode(MI) == HexagonII::AbsoluteSet);2138}2139 2140bool HexagonInstrInfo::isAccumulator(const MachineInstr &MI) const {2141  const uint64_t F = MI.getDesc().TSFlags;2142  return((F >> HexagonII::AccumulatorPos) & HexagonII::AccumulatorMask);2143}2144 2145bool HexagonInstrInfo::isBaseImmOffset(const MachineInstr &MI) const {2146  return getAddrMode(MI) == HexagonII::BaseImmOffset;2147}2148 2149bool HexagonInstrInfo::isComplex(const MachineInstr &MI) const {2150  return !isTC1(MI) && !isTC2Early(MI) && !MI.getDesc().mayLoad() &&2151         !MI.getDesc().mayStore() &&2152         MI.getDesc().getOpcode() != Hexagon::S2_allocframe &&2153         MI.getDesc().getOpcode() != Hexagon::L2_deallocframe &&2154         !isMemOp(MI) && !MI.isBranch() && !MI.isReturn() && !MI.isCall();2155}2156 2157// Return true if the instruction is a compound branch instruction.2158bool HexagonInstrInfo::isCompoundBranchInstr(const MachineInstr &MI) const {2159  return getType(MI) == HexagonII::TypeCJ && MI.isBranch();2160}2161 2162// TODO: In order to have isExtendable for fpimm/f32Ext, we need to handle2163// isFPImm and later getFPImm as well.2164bool HexagonInstrInfo::isConstExtended(const MachineInstr &MI) const {2165  const uint64_t F = MI.getDesc().TSFlags;2166  unsigned isExtended = (F >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask;2167  if (isExtended) // Instruction must be extended.2168    return true;2169 2170  unsigned isExtendable =2171    (F >> HexagonII::ExtendablePos) & HexagonII::ExtendableMask;2172  if (!isExtendable)2173    return false;2174 2175  if (MI.isCall())2176    return false;2177 2178  short ExtOpNum = getCExtOpNum(MI);2179  const MachineOperand &MO = MI.getOperand(ExtOpNum);2180  // Use MO operand flags to determine if MO2181  // has the HMOTF_ConstExtended flag set.2182  if (MO.getTargetFlags() & HexagonII::HMOTF_ConstExtended)2183    return true;2184  // If this is a Machine BB address we are talking about, and it is2185  // not marked as extended, say so.2186  if (MO.isMBB())2187    return false;2188 2189  // We could be using an instruction with an extendable immediate and shoehorn2190  // a global address into it. If it is a global address it will be constant2191  // extended. We do this for COMBINE.2192  if (MO.isGlobal() || MO.isSymbol() || MO.isBlockAddress() ||2193      MO.isJTI() || MO.isCPI() || MO.isFPImm())2194    return true;2195 2196  // If the extendable operand is not 'Immediate' type, the instruction should2197  // have 'isExtended' flag set.2198  assert(MO.isImm() && "Extendable operand must be Immediate type");2199 2200  int64_t Value = MO.getImm();2201  if ((F >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask) {2202    int32_t SValue = Value;2203    int32_t MinValue = getMinValue(MI);2204    int32_t MaxValue = getMaxValue(MI);2205    return SValue < MinValue || SValue > MaxValue;2206  }2207  uint32_t UValue = Value;2208  uint32_t MinValue = getMinValue(MI);2209  uint32_t MaxValue = getMaxValue(MI);2210  return UValue < MinValue || UValue > MaxValue;2211}2212 2213bool HexagonInstrInfo::isDeallocRet(const MachineInstr &MI) const {2214  switch (MI.getOpcode()) {2215  case Hexagon::L4_return:2216  case Hexagon::L4_return_t:2217  case Hexagon::L4_return_f:2218  case Hexagon::L4_return_tnew_pnt:2219  case Hexagon::L4_return_fnew_pnt:2220  case Hexagon::L4_return_tnew_pt:2221  case Hexagon::L4_return_fnew_pt:2222    return true;2223  }2224  return false;2225}2226 2227// Return true when ConsMI uses a register defined by ProdMI.2228bool HexagonInstrInfo::isDependent(const MachineInstr &ProdMI,2229      const MachineInstr &ConsMI) const {2230  if (!ProdMI.getDesc().getNumDefs())2231    return false;2232  const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();2233 2234  SmallVector<Register, 4> DefsA;2235  SmallVector<Register, 4> DefsB;2236  SmallVector<Register, 8> UsesA;2237  SmallVector<Register, 8> UsesB;2238 2239  parseOperands(ProdMI, DefsA, UsesA);2240  parseOperands(ConsMI, DefsB, UsesB);2241 2242  for (auto &RegA : DefsA)2243    for (auto &RegB : UsesB) {2244      // True data dependency.2245      if (RegA == RegB)2246        return true;2247 2248      if (RegA.isPhysical() && llvm::is_contained(HRI.subregs(RegA), RegB))2249        return true;2250 2251      if (RegB.isPhysical() && llvm::is_contained(HRI.subregs(RegB), RegA))2252        return true;2253    }2254 2255  return false;2256}2257 2258// Returns true if the instruction is already a .cur.2259bool HexagonInstrInfo::isDotCurInst(const MachineInstr &MI) const {2260  switch (MI.getOpcode()) {2261  case Hexagon::V6_vL32b_cur_pi:2262  case Hexagon::V6_vL32b_cur_ai:2263    return true;2264  }2265  return false;2266}2267 2268// Returns true, if any one of the operands is a dot new2269// insn, whether it is predicated dot new or register dot new.2270bool HexagonInstrInfo::isDotNewInst(const MachineInstr &MI) const {2271  if (isNewValueInst(MI) || (isPredicated(MI) && isPredicatedNew(MI)))2272    return true;2273 2274  return false;2275}2276 2277/// Symmetrical. See if these two instructions are fit for duplex pair.2278bool HexagonInstrInfo::isDuplexPair(const MachineInstr &MIa,2279      const MachineInstr &MIb) const {2280  HexagonII::SubInstructionGroup MIaG = getDuplexCandidateGroup(MIa);2281  HexagonII::SubInstructionGroup MIbG = getDuplexCandidateGroup(MIb);2282  return (isDuplexPairMatch(MIaG, MIbG) || isDuplexPairMatch(MIbG, MIaG));2283}2284 2285bool HexagonInstrInfo::isEndLoopN(unsigned Opcode) const {2286  return (Opcode == Hexagon::ENDLOOP0 ||2287          Opcode == Hexagon::ENDLOOP1);2288}2289 2290bool HexagonInstrInfo::isExpr(unsigned OpType) const {2291  switch(OpType) {2292  case MachineOperand::MO_MachineBasicBlock:2293  case MachineOperand::MO_GlobalAddress:2294  case MachineOperand::MO_ExternalSymbol:2295  case MachineOperand::MO_JumpTableIndex:2296  case MachineOperand::MO_ConstantPoolIndex:2297  case MachineOperand::MO_BlockAddress:2298    return true;2299  default:2300    return false;2301  }2302}2303 2304bool HexagonInstrInfo::isExtendable(const MachineInstr &MI) const {2305  const MCInstrDesc &MID = MI.getDesc();2306  const uint64_t F = MID.TSFlags;2307  if ((F >> HexagonII::ExtendablePos) & HexagonII::ExtendableMask)2308    return true;2309 2310  // TODO: This is largely obsolete now. Will need to be removed2311  // in consecutive patches.2312  switch (MI.getOpcode()) {2313    // PS_fi and PS_fia remain special cases.2314    case Hexagon::PS_fi:2315    case Hexagon::PS_fia:2316      return true;2317    default:2318      return false;2319  }2320  return  false;2321}2322 2323// This returns true in two cases:2324// - The OP code itself indicates that this is an extended instruction.2325// - One of MOs has been marked with HMOTF_ConstExtended flag.2326bool HexagonInstrInfo::isExtended(const MachineInstr &MI) const {2327  // First check if this is permanently extended op code.2328  const uint64_t F = MI.getDesc().TSFlags;2329  if ((F >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask)2330    return true;2331  // Use MO operand flags to determine if one of MI's operands2332  // has HMOTF_ConstExtended flag set.2333  for (const MachineOperand &MO : MI.operands())2334    if (MO.getTargetFlags() & HexagonII::HMOTF_ConstExtended)2335      return true;2336  return  false;2337}2338 2339bool HexagonInstrInfo::isFloat(const MachineInstr &MI) const {2340  unsigned Opcode = MI.getOpcode();2341  const uint64_t F = get(Opcode).TSFlags;2342  return (F >> HexagonII::FPPos) & HexagonII::FPMask;2343}2344 2345// No V60 HVX VMEM with A_INDIRECT.2346bool HexagonInstrInfo::isHVXMemWithAIndirect(const MachineInstr &I,2347      const MachineInstr &J) const {2348  if (!isHVXVec(I))2349    return false;2350  if (!I.mayLoad() && !I.mayStore())2351    return false;2352  return J.isIndirectBranch() || isIndirectCall(J) || isIndirectL4Return(J);2353}2354 2355bool HexagonInstrInfo::isIndirectCall(const MachineInstr &MI) const {2356  switch (MI.getOpcode()) {2357  case Hexagon::J2_callr:2358  case Hexagon::J2_callrf:2359  case Hexagon::J2_callrt:2360  case Hexagon::PS_call_nr:2361    return true;2362  }2363  return false;2364}2365 2366bool HexagonInstrInfo::isIndirectL4Return(const MachineInstr &MI) const {2367  switch (MI.getOpcode()) {2368  case Hexagon::L4_return:2369  case Hexagon::L4_return_t:2370  case Hexagon::L4_return_f:2371  case Hexagon::L4_return_fnew_pnt:2372  case Hexagon::L4_return_fnew_pt:2373  case Hexagon::L4_return_tnew_pnt:2374  case Hexagon::L4_return_tnew_pt:2375    return true;2376  }2377  return false;2378}2379 2380bool HexagonInstrInfo::isJumpR(const MachineInstr &MI) const {2381  switch (MI.getOpcode()) {2382  case Hexagon::J2_jumpr:2383  case Hexagon::J2_jumprt:2384  case Hexagon::J2_jumprf:2385  case Hexagon::J2_jumprtnewpt:2386  case Hexagon::J2_jumprfnewpt:2387  case Hexagon::J2_jumprtnew:2388  case Hexagon::J2_jumprfnew:2389    return true;2390  }2391  return false;2392}2393 2394// Return true if a given MI can accommodate given offset.2395// Use abs estimate as oppose to the exact number.2396// TODO: This will need to be changed to use MC level2397// definition of instruction extendable field size.2398bool HexagonInstrInfo::isJumpWithinBranchRange(const MachineInstr &MI,2399      unsigned offset) const {2400  // This selection of jump instructions matches to that what2401  // analyzeBranch can parse, plus NVJ.2402  if (isNewValueJump(MI)) // r9:22403    return isInt<11>(offset);2404 2405  switch (MI.getOpcode()) {2406  // Still missing Jump to address condition on register value.2407  default:2408    return false;2409  case Hexagon::J2_jump: // bits<24> dst; // r22:22410  case Hexagon::J2_call:2411  case Hexagon::PS_call_nr:2412    return isInt<24>(offset);2413  case Hexagon::J2_jumpt: //bits<17> dst; // r15:22414  case Hexagon::J2_jumpf:2415  case Hexagon::J2_jumptnew:2416  case Hexagon::J2_jumptnewpt:2417  case Hexagon::J2_jumpfnew:2418  case Hexagon::J2_jumpfnewpt:2419  case Hexagon::J2_callt:2420  case Hexagon::J2_callf:2421    return isInt<17>(offset);2422  case Hexagon::J2_loop0i:2423  case Hexagon::J2_loop0iext:2424  case Hexagon::J2_loop0r:2425  case Hexagon::J2_loop0rext:2426  case Hexagon::J2_loop1i:2427  case Hexagon::J2_loop1iext:2428  case Hexagon::J2_loop1r:2429  case Hexagon::J2_loop1rext:2430    return isInt<9>(offset);2431  // TODO: Add all the compound branches here. Can we do this in Relation model?2432  case Hexagon::J4_cmpeqi_tp0_jump_nt:2433  case Hexagon::J4_cmpeqi_tp1_jump_nt:2434  case Hexagon::J4_cmpeqn1_tp0_jump_nt:2435  case Hexagon::J4_cmpeqn1_tp1_jump_nt:2436    return isInt<11>(offset);2437  }2438}2439 2440bool HexagonInstrInfo::isLateSourceInstr(const MachineInstr &MI) const {2441  // Instructions with iclass A_CVI_VX and attribute A_CVI_LATE uses a multiply2442  // resource, but all operands can be received late like an ALU instruction.2443  return getType(MI) == HexagonII::TypeCVI_VX_LATE;2444}2445 2446bool HexagonInstrInfo::isLoopN(const MachineInstr &MI) const {2447  unsigned Opcode = MI.getOpcode();2448  return Opcode == Hexagon::J2_loop0i    ||2449         Opcode == Hexagon::J2_loop0r    ||2450         Opcode == Hexagon::J2_loop0iext ||2451         Opcode == Hexagon::J2_loop0rext ||2452         Opcode == Hexagon::J2_loop1i    ||2453         Opcode == Hexagon::J2_loop1r    ||2454         Opcode == Hexagon::J2_loop1iext ||2455         Opcode == Hexagon::J2_loop1rext;2456}2457 2458bool HexagonInstrInfo::isMemOp(const MachineInstr &MI) const {2459  switch (MI.getOpcode()) {2460    default: return false;2461    case Hexagon::L4_iadd_memopw_io:2462    case Hexagon::L4_isub_memopw_io:2463    case Hexagon::L4_add_memopw_io:2464    case Hexagon::L4_sub_memopw_io:2465    case Hexagon::L4_and_memopw_io:2466    case Hexagon::L4_or_memopw_io:2467    case Hexagon::L4_iadd_memoph_io:2468    case Hexagon::L4_isub_memoph_io:2469    case Hexagon::L4_add_memoph_io:2470    case Hexagon::L4_sub_memoph_io:2471    case Hexagon::L4_and_memoph_io:2472    case Hexagon::L4_or_memoph_io:2473    case Hexagon::L4_iadd_memopb_io:2474    case Hexagon::L4_isub_memopb_io:2475    case Hexagon::L4_add_memopb_io:2476    case Hexagon::L4_sub_memopb_io:2477    case Hexagon::L4_and_memopb_io:2478    case Hexagon::L4_or_memopb_io:2479    case Hexagon::L4_ior_memopb_io:2480    case Hexagon::L4_ior_memoph_io:2481    case Hexagon::L4_ior_memopw_io:2482    case Hexagon::L4_iand_memopb_io:2483    case Hexagon::L4_iand_memoph_io:2484    case Hexagon::L4_iand_memopw_io:2485    return true;2486  }2487  return false;2488}2489 2490bool HexagonInstrInfo::isNewValue(const MachineInstr &MI) const {2491  const uint64_t F = MI.getDesc().TSFlags;2492  return (F >> HexagonII::NewValuePos) & HexagonII::NewValueMask;2493}2494 2495bool HexagonInstrInfo::isNewValue(unsigned Opcode) const {2496  const uint64_t F = get(Opcode).TSFlags;2497  return (F >> HexagonII::NewValuePos) & HexagonII::NewValueMask;2498}2499 2500bool HexagonInstrInfo::isNewValueInst(const MachineInstr &MI) const {2501  return isNewValueJump(MI) || isNewValueStore(MI);2502}2503 2504bool HexagonInstrInfo::isNewValueJump(const MachineInstr &MI) const {2505  return isNewValue(MI) && MI.isBranch();2506}2507 2508bool HexagonInstrInfo::isNewValueJump(unsigned Opcode) const {2509  return isNewValue(Opcode) && get(Opcode).isBranch() && isPredicated(Opcode);2510}2511 2512bool HexagonInstrInfo::isNewValueStore(const MachineInstr &MI) const {2513  const uint64_t F = MI.getDesc().TSFlags;2514  return (F >> HexagonII::NVStorePos) & HexagonII::NVStoreMask;2515}2516 2517bool HexagonInstrInfo::isNewValueStore(unsigned Opcode) const {2518  const uint64_t F = get(Opcode).TSFlags;2519  return (F >> HexagonII::NVStorePos) & HexagonII::NVStoreMask;2520}2521 2522// Returns true if a particular operand is extendable for an instruction.2523bool HexagonInstrInfo::isOperandExtended(const MachineInstr &MI,2524    unsigned OperandNum) const {2525  const uint64_t F = MI.getDesc().TSFlags;2526  return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask)2527          == OperandNum;2528}2529 2530bool HexagonInstrInfo::isPredicatedNew(const MachineInstr &MI) const {2531  const uint64_t F = MI.getDesc().TSFlags;2532  assert(isPredicated(MI));2533  return (F >> HexagonII::PredicatedNewPos) & HexagonII::PredicatedNewMask;2534}2535 2536bool HexagonInstrInfo::isPredicatedNew(unsigned Opcode) const {2537  const uint64_t F = get(Opcode).TSFlags;2538  assert(isPredicated(Opcode));2539  return (F >> HexagonII::PredicatedNewPos) & HexagonII::PredicatedNewMask;2540}2541 2542bool HexagonInstrInfo::isPredicatedTrue(const MachineInstr &MI) const {2543  const uint64_t F = MI.getDesc().TSFlags;2544  return !((F >> HexagonII::PredicatedFalsePos) &2545           HexagonII::PredicatedFalseMask);2546}2547 2548bool HexagonInstrInfo::isPredicatedTrue(unsigned Opcode) const {2549  const uint64_t F = get(Opcode).TSFlags;2550  // Make sure that the instruction is predicated.2551  assert((F>> HexagonII::PredicatedPos) & HexagonII::PredicatedMask);2552  return !((F >> HexagonII::PredicatedFalsePos) &2553           HexagonII::PredicatedFalseMask);2554}2555 2556bool HexagonInstrInfo::isPredicated(unsigned Opcode) const {2557  const uint64_t F = get(Opcode).TSFlags;2558  return (F >> HexagonII::PredicatedPos) & HexagonII::PredicatedMask;2559}2560 2561bool HexagonInstrInfo::isPredicateLate(unsigned Opcode) const {2562  const uint64_t F = get(Opcode).TSFlags;2563  return (F >> HexagonII::PredicateLatePos) & HexagonII::PredicateLateMask;2564}2565 2566bool HexagonInstrInfo::isPredictedTaken(unsigned Opcode) const {2567  const uint64_t F = get(Opcode).TSFlags;2568  assert(get(Opcode).isBranch() &&2569         (isPredicatedNew(Opcode) || isNewValue(Opcode)));2570  return (F >> HexagonII::TakenPos) & HexagonII::TakenMask;2571}2572 2573bool HexagonInstrInfo::isSaveCalleeSavedRegsCall(const MachineInstr &MI) const {2574  return MI.getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4 ||2575         MI.getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4_EXT ||2576         MI.getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4_PIC ||2577         MI.getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4_EXT_PIC;2578}2579 2580bool HexagonInstrInfo::isSignExtendingLoad(const MachineInstr &MI) const {2581  switch (MI.getOpcode()) {2582  // Byte2583  case Hexagon::L2_loadrb_io:2584  case Hexagon::L4_loadrb_ur:2585  case Hexagon::L4_loadrb_ap:2586  case Hexagon::L2_loadrb_pr:2587  case Hexagon::L2_loadrb_pbr:2588  case Hexagon::L2_loadrb_pi:2589  case Hexagon::L2_loadrb_pci:2590  case Hexagon::L2_loadrb_pcr:2591  case Hexagon::L2_loadbsw2_io:2592  case Hexagon::L4_loadbsw2_ur:2593  case Hexagon::L4_loadbsw2_ap:2594  case Hexagon::L2_loadbsw2_pr:2595  case Hexagon::L2_loadbsw2_pbr:2596  case Hexagon::L2_loadbsw2_pi:2597  case Hexagon::L2_loadbsw2_pci:2598  case Hexagon::L2_loadbsw2_pcr:2599  case Hexagon::L2_loadbsw4_io:2600  case Hexagon::L4_loadbsw4_ur:2601  case Hexagon::L4_loadbsw4_ap:2602  case Hexagon::L2_loadbsw4_pr:2603  case Hexagon::L2_loadbsw4_pbr:2604  case Hexagon::L2_loadbsw4_pi:2605  case Hexagon::L2_loadbsw4_pci:2606  case Hexagon::L2_loadbsw4_pcr:2607  case Hexagon::L4_loadrb_rr:2608  case Hexagon::L2_ploadrbt_io:2609  case Hexagon::L2_ploadrbt_pi:2610  case Hexagon::L2_ploadrbf_io:2611  case Hexagon::L2_ploadrbf_pi:2612  case Hexagon::L2_ploadrbtnew_io:2613  case Hexagon::L2_ploadrbfnew_io:2614  case Hexagon::L4_ploadrbt_rr:2615  case Hexagon::L4_ploadrbf_rr:2616  case Hexagon::L4_ploadrbtnew_rr:2617  case Hexagon::L4_ploadrbfnew_rr:2618  case Hexagon::L2_ploadrbtnew_pi:2619  case Hexagon::L2_ploadrbfnew_pi:2620  case Hexagon::L4_ploadrbt_abs:2621  case Hexagon::L4_ploadrbf_abs:2622  case Hexagon::L4_ploadrbtnew_abs:2623  case Hexagon::L4_ploadrbfnew_abs:2624  case Hexagon::L2_loadrbgp:2625  // Half2626  case Hexagon::L2_loadrh_io:2627  case Hexagon::L4_loadrh_ur:2628  case Hexagon::L4_loadrh_ap:2629  case Hexagon::L2_loadrh_pr:2630  case Hexagon::L2_loadrh_pbr:2631  case Hexagon::L2_loadrh_pi:2632  case Hexagon::L2_loadrh_pci:2633  case Hexagon::L2_loadrh_pcr:2634  case Hexagon::L4_loadrh_rr:2635  case Hexagon::L2_ploadrht_io:2636  case Hexagon::L2_ploadrht_pi:2637  case Hexagon::L2_ploadrhf_io:2638  case Hexagon::L2_ploadrhf_pi:2639  case Hexagon::L2_ploadrhtnew_io:2640  case Hexagon::L2_ploadrhfnew_io:2641  case Hexagon::L4_ploadrht_rr:2642  case Hexagon::L4_ploadrhf_rr:2643  case Hexagon::L4_ploadrhtnew_rr:2644  case Hexagon::L4_ploadrhfnew_rr:2645  case Hexagon::L2_ploadrhtnew_pi:2646  case Hexagon::L2_ploadrhfnew_pi:2647  case Hexagon::L4_ploadrht_abs:2648  case Hexagon::L4_ploadrhf_abs:2649  case Hexagon::L4_ploadrhtnew_abs:2650  case Hexagon::L4_ploadrhfnew_abs:2651  case Hexagon::L2_loadrhgp:2652    return true;2653  default:2654    return false;2655  }2656}2657 2658bool HexagonInstrInfo::isSolo(const MachineInstr &MI) const {2659  const uint64_t F = MI.getDesc().TSFlags;2660  return (F >> HexagonII::SoloPos) & HexagonII::SoloMask;2661}2662 2663bool HexagonInstrInfo::isSpillPredRegOp(const MachineInstr &MI) const {2664  switch (MI.getOpcode()) {2665  case Hexagon::STriw_pred:2666  case Hexagon::LDriw_pred:2667    return true;2668  default:2669    return false;2670  }2671}2672 2673bool HexagonInstrInfo::isTailCall(const MachineInstr &MI) const {2674  if (!MI.isBranch())2675    return false;2676 2677  for (auto &Op : MI.operands())2678    if (Op.isGlobal() || Op.isSymbol())2679      return true;2680  return false;2681}2682 2683// Returns true when SU has a timing class TC1.2684bool HexagonInstrInfo::isTC1(const MachineInstr &MI) const {2685  unsigned SchedClass = MI.getDesc().getSchedClass();2686  return is_TC1(SchedClass);2687}2688 2689bool HexagonInstrInfo::isTC2(const MachineInstr &MI) const {2690  unsigned SchedClass = MI.getDesc().getSchedClass();2691  return is_TC2(SchedClass);2692}2693 2694bool HexagonInstrInfo::isTC2Early(const MachineInstr &MI) const {2695  unsigned SchedClass = MI.getDesc().getSchedClass();2696  return is_TC2early(SchedClass);2697}2698 2699bool HexagonInstrInfo::isTC4x(const MachineInstr &MI) const {2700  unsigned SchedClass = MI.getDesc().getSchedClass();2701  return is_TC4x(SchedClass);2702}2703 2704// Schedule this ASAP.2705bool HexagonInstrInfo::isToBeScheduledASAP(const MachineInstr &MI1,2706      const MachineInstr &MI2) const {2707  if (mayBeCurLoad(MI1)) {2708    // if (result of SU is used in Next) return true;2709    Register DstReg = MI1.getOperand(0).getReg();2710    int N = MI2.getNumOperands();2711    for (int I = 0; I < N; I++)2712      if (MI2.getOperand(I).isReg() && DstReg == MI2.getOperand(I).getReg())2713        return true;2714  }2715  if (mayBeNewStore(MI2))2716    if (MI2.getOpcode() == Hexagon::V6_vS32b_pi)2717      if (MI1.getOperand(0).isReg() && MI2.getOperand(3).isReg() &&2718          MI1.getOperand(0).getReg() == MI2.getOperand(3).getReg())2719        return true;2720  return false;2721}2722 2723bool HexagonInstrInfo::isHVXVec(const MachineInstr &MI) const {2724  const uint64_t V = getType(MI);2725  return HexagonII::TypeCVI_FIRST <= V && V <= HexagonII::TypeCVI_LAST;2726}2727 2728// Check if the Offset is a valid auto-inc imm by Load/Store Type.2729bool HexagonInstrInfo::isValidAutoIncImm(const EVT VT, int Offset) const {2730  int Size = VT.getSizeInBits() / 8;2731  if (Offset % Size != 0)2732    return false;2733  int Count = Offset / Size;2734 2735  switch (VT.getSimpleVT().SimpleTy) {2736    // For scalars the auto-inc is s42737    case MVT::i8:2738    case MVT::i16:2739    case MVT::i32:2740    case MVT::i64:2741    case MVT::f32:2742    case MVT::f64:2743    case MVT::v2i16:2744    case MVT::v2i32:2745    case MVT::v4i8:2746    case MVT::v4i16:2747    case MVT::v8i8:2748      return isInt<4>(Count);2749    // For HVX vectors the auto-inc is s32750    case MVT::v64i8:2751    case MVT::v32i16:2752    case MVT::v16i32:2753    case MVT::v8i64:2754    case MVT::v128i8:2755    case MVT::v64i16:2756    case MVT::v32i32:2757    case MVT::v16i64:2758      return isInt<3>(Count);2759    default:2760      break;2761  }2762 2763  llvm_unreachable("Not an valid type!");2764}2765 2766bool HexagonInstrInfo::isValidOffset(unsigned Opcode, int Offset,2767      const TargetRegisterInfo *TRI, bool Extend) const {2768  // This function is to check whether the "Offset" is in the correct range of2769  // the given "Opcode". If "Offset" is not in the correct range, "A2_addi" is2770  // inserted to calculate the final address. Due to this reason, the function2771  // assumes that the "Offset" has correct alignment.2772  // We used to assert if the offset was not properly aligned, however,2773  // there are cases where a misaligned pointer recast can cause this2774  // problem, and we need to allow for it. The front end warns of such2775  // misaligns with respect to load size.2776  switch (Opcode) {2777  case Hexagon::PS_vstorerq_ai:2778  case Hexagon::PS_vstorerv_ai:2779  case Hexagon::PS_vstorerw_ai:2780  case Hexagon::PS_vstorerw_nt_ai:2781  case Hexagon::PS_vloadrq_ai:2782  case Hexagon::PS_vloadrv_ai:2783  case Hexagon::PS_vloadrw_ai:2784  case Hexagon::PS_vloadrw_nt_ai:2785  case Hexagon::V6_vL32b_ai:2786  case Hexagon::V6_vS32b_ai:2787  case Hexagon::V6_vS32b_pred_ai:2788  case Hexagon::V6_vS32b_npred_ai:2789  case Hexagon::V6_vS32b_qpred_ai:2790  case Hexagon::V6_vS32b_nqpred_ai:2791  case Hexagon::V6_vS32b_new_ai:2792  case Hexagon::V6_vS32b_new_pred_ai:2793  case Hexagon::V6_vS32b_new_npred_ai:2794  case Hexagon::V6_vS32b_nt_pred_ai:2795  case Hexagon::V6_vS32b_nt_npred_ai:2796  case Hexagon::V6_vS32b_nt_new_ai:2797  case Hexagon::V6_vS32b_nt_new_pred_ai:2798  case Hexagon::V6_vS32b_nt_new_npred_ai:2799  case Hexagon::V6_vS32b_nt_qpred_ai:2800  case Hexagon::V6_vS32b_nt_nqpred_ai:2801  case Hexagon::V6_vL32b_nt_ai:2802  case Hexagon::V6_vS32b_nt_ai:2803  case Hexagon::V6_vL32Ub_ai:2804  case Hexagon::V6_vS32Ub_ai:2805  case Hexagon::V6_vL32b_cur_ai:2806  case Hexagon::V6_vL32b_tmp_ai:2807  case Hexagon::V6_vL32b_pred_ai:2808  case Hexagon::V6_vL32b_npred_ai:2809  case Hexagon::V6_vL32b_cur_pred_ai:2810  case Hexagon::V6_vL32b_cur_npred_ai:2811  case Hexagon::V6_vL32b_tmp_pred_ai:2812  case Hexagon::V6_vL32b_tmp_npred_ai:2813  case Hexagon::V6_vL32b_nt_cur_ai:2814  case Hexagon::V6_vL32b_nt_tmp_ai:2815  case Hexagon::V6_vL32b_nt_pred_ai:2816  case Hexagon::V6_vL32b_nt_npred_ai:2817  case Hexagon::V6_vL32b_nt_cur_pred_ai:2818  case Hexagon::V6_vL32b_nt_cur_npred_ai:2819  case Hexagon::V6_vL32b_nt_tmp_pred_ai:2820  case Hexagon::V6_vL32b_nt_tmp_npred_ai:2821  case Hexagon::V6_vS32Ub_npred_ai:2822  case Hexagon::V6_vgathermh_pseudo:2823  case Hexagon::V6_vgather_vscatter_mh_pseudo:2824  case Hexagon::V6_vgathermw_pseudo:2825  case Hexagon::V6_vgathermhw_pseudo:2826  case Hexagon::V6_vgathermhq_pseudo:2827  case Hexagon::V6_vgathermwq_pseudo:2828  case Hexagon::V6_vgathermhwq_pseudo: {2829    unsigned VectorSize = TRI->getSpillSize(Hexagon::HvxVRRegClass);2830    assert(isPowerOf2_32(VectorSize));2831    if (Offset & (VectorSize-1))2832      return false;2833    return isInt<4>(Offset >> Log2_32(VectorSize));2834  }2835 2836  case Hexagon::J2_loop0i:2837  case Hexagon::J2_loop1i:2838    return isUInt<10>(Offset);2839 2840  case Hexagon::S4_storeirb_io:2841  case Hexagon::S4_storeirbt_io:2842  case Hexagon::S4_storeirbf_io:2843    return isUInt<6>(Offset);2844 2845  case Hexagon::S4_storeirh_io:2846  case Hexagon::S4_storeirht_io:2847  case Hexagon::S4_storeirhf_io:2848    return isShiftedUInt<6,1>(Offset);2849 2850  case Hexagon::S4_storeiri_io:2851  case Hexagon::S4_storeirit_io:2852  case Hexagon::S4_storeirif_io:2853    return isShiftedUInt<6,2>(Offset);2854  // Handle these two compare instructions that are not extendable.2855  case Hexagon::A4_cmpbeqi:2856    return isUInt<8>(Offset);2857  case Hexagon::A4_cmpbgti:2858    return isInt<8>(Offset);2859  }2860 2861  if (Extend)2862    return true;2863 2864  switch (Opcode) {2865  case Hexagon::L2_loadri_io:2866  case Hexagon::S2_storeri_io:2867    return (Offset >= Hexagon_MEMW_OFFSET_MIN) &&2868      (Offset <= Hexagon_MEMW_OFFSET_MAX);2869 2870  case Hexagon::L2_loadrd_io:2871  case Hexagon::S2_storerd_io:2872    return (Offset >= Hexagon_MEMD_OFFSET_MIN) &&2873      (Offset <= Hexagon_MEMD_OFFSET_MAX);2874 2875  case Hexagon::L2_loadrh_io:2876  case Hexagon::L2_loadruh_io:2877  case Hexagon::S2_storerh_io:2878  case Hexagon::S2_storerf_io:2879    return (Offset >= Hexagon_MEMH_OFFSET_MIN) &&2880      (Offset <= Hexagon_MEMH_OFFSET_MAX);2881 2882  case Hexagon::L2_loadrb_io:2883  case Hexagon::L2_loadrub_io:2884  case Hexagon::S2_storerb_io:2885    return (Offset >= Hexagon_MEMB_OFFSET_MIN) &&2886      (Offset <= Hexagon_MEMB_OFFSET_MAX);2887 2888  case Hexagon::A2_addi:2889    return (Offset >= Hexagon_ADDI_OFFSET_MIN) &&2890      (Offset <= Hexagon_ADDI_OFFSET_MAX);2891 2892  case Hexagon::L4_iadd_memopw_io:2893  case Hexagon::L4_isub_memopw_io:2894  case Hexagon::L4_add_memopw_io:2895  case Hexagon::L4_sub_memopw_io:2896  case Hexagon::L4_iand_memopw_io:2897  case Hexagon::L4_ior_memopw_io:2898  case Hexagon::L4_and_memopw_io:2899  case Hexagon::L4_or_memopw_io:2900    return (0 <= Offset && Offset <= 255);2901 2902  case Hexagon::L4_iadd_memoph_io:2903  case Hexagon::L4_isub_memoph_io:2904  case Hexagon::L4_add_memoph_io:2905  case Hexagon::L4_sub_memoph_io:2906  case Hexagon::L4_iand_memoph_io:2907  case Hexagon::L4_ior_memoph_io:2908  case Hexagon::L4_and_memoph_io:2909  case Hexagon::L4_or_memoph_io:2910    return (0 <= Offset && Offset <= 127);2911 2912  case Hexagon::L4_iadd_memopb_io:2913  case Hexagon::L4_isub_memopb_io:2914  case Hexagon::L4_add_memopb_io:2915  case Hexagon::L4_sub_memopb_io:2916  case Hexagon::L4_iand_memopb_io:2917  case Hexagon::L4_ior_memopb_io:2918  case Hexagon::L4_and_memopb_io:2919  case Hexagon::L4_or_memopb_io:2920    return (0 <= Offset && Offset <= 63);2921 2922  // LDriw_xxx and STriw_xxx are pseudo operations, so it has to take offset of2923  // any size. Later pass knows how to handle it.2924  case Hexagon::STriw_pred:2925  case Hexagon::LDriw_pred:2926  case Hexagon::STriw_ctr:2927  case Hexagon::LDriw_ctr:2928    return true;2929 2930  case Hexagon::PS_fi:2931  case Hexagon::PS_fia:2932  case Hexagon::INLINEASM:2933    return true;2934 2935  case Hexagon::L2_ploadrbt_io:2936  case Hexagon::L2_ploadrbf_io:2937  case Hexagon::L2_ploadrubt_io:2938  case Hexagon::L2_ploadrubf_io:2939  case Hexagon::S2_pstorerbt_io:2940  case Hexagon::S2_pstorerbf_io:2941    return isUInt<6>(Offset);2942 2943  case Hexagon::L2_ploadrht_io:2944  case Hexagon::L2_ploadrhf_io:2945  case Hexagon::L2_ploadruht_io:2946  case Hexagon::L2_ploadruhf_io:2947  case Hexagon::S2_pstorerht_io:2948  case Hexagon::S2_pstorerhf_io:2949    return isShiftedUInt<6,1>(Offset);2950 2951  case Hexagon::L2_ploadrit_io:2952  case Hexagon::L2_ploadrif_io:2953  case Hexagon::S2_pstorerit_io:2954  case Hexagon::S2_pstorerif_io:2955    return isShiftedUInt<6,2>(Offset);2956 2957  case Hexagon::L2_ploadrdt_io:2958  case Hexagon::L2_ploadrdf_io:2959  case Hexagon::S2_pstorerdt_io:2960  case Hexagon::S2_pstorerdf_io:2961    return isShiftedUInt<6,3>(Offset);2962 2963  case Hexagon::L2_loadbsw2_io:2964  case Hexagon::L2_loadbzw2_io:2965    return isShiftedInt<11,1>(Offset);2966 2967  case Hexagon::L2_loadbsw4_io:2968  case Hexagon::L2_loadbzw4_io:2969    return isShiftedInt<11,2>(Offset);2970  } // switch2971 2972  dbgs() << "Failed Opcode is : " << Opcode << " (" << getName(Opcode)2973         << ")\n";2974  llvm_unreachable("No offset range is defined for this opcode. "2975                   "Please define it in the above switch statement!");2976}2977 2978bool HexagonInstrInfo::isVecAcc(const MachineInstr &MI) const {2979  return isHVXVec(MI) && isAccumulator(MI);2980}2981 2982bool HexagonInstrInfo::isVecALU(const MachineInstr &MI) const {2983  const uint64_t F = get(MI.getOpcode()).TSFlags;2984  const uint64_t V = ((F >> HexagonII::TypePos) & HexagonII::TypeMask);2985  return2986    V == HexagonII::TypeCVI_VA         ||2987    V == HexagonII::TypeCVI_VA_DV;2988}2989 2990bool HexagonInstrInfo::isVecUsableNextPacket(const MachineInstr &ProdMI,2991      const MachineInstr &ConsMI) const {2992  if (EnableACCForwarding && isVecAcc(ProdMI) && isVecAcc(ConsMI))2993    return true;2994 2995  if (EnableALUForwarding && (isVecALU(ConsMI) || isLateSourceInstr(ConsMI)))2996    return true;2997 2998  if (mayBeNewStore(ConsMI))2999    return true;3000 3001  return false;3002}3003 3004bool HexagonInstrInfo::isZeroExtendingLoad(const MachineInstr &MI) const {3005  switch (MI.getOpcode()) {3006  // Byte3007  case Hexagon::L2_loadrub_io:3008  case Hexagon::L4_loadrub_ur:3009  case Hexagon::L4_loadrub_ap:3010  case Hexagon::L2_loadrub_pr:3011  case Hexagon::L2_loadrub_pbr:3012  case Hexagon::L2_loadrub_pi:3013  case Hexagon::L2_loadrub_pci:3014  case Hexagon::L2_loadrub_pcr:3015  case Hexagon::L2_loadbzw2_io:3016  case Hexagon::L4_loadbzw2_ur:3017  case Hexagon::L4_loadbzw2_ap:3018  case Hexagon::L2_loadbzw2_pr:3019  case Hexagon::L2_loadbzw2_pbr:3020  case Hexagon::L2_loadbzw2_pi:3021  case Hexagon::L2_loadbzw2_pci:3022  case Hexagon::L2_loadbzw2_pcr:3023  case Hexagon::L2_loadbzw4_io:3024  case Hexagon::L4_loadbzw4_ur:3025  case Hexagon::L4_loadbzw4_ap:3026  case Hexagon::L2_loadbzw4_pr:3027  case Hexagon::L2_loadbzw4_pbr:3028  case Hexagon::L2_loadbzw4_pi:3029  case Hexagon::L2_loadbzw4_pci:3030  case Hexagon::L2_loadbzw4_pcr:3031  case Hexagon::L4_loadrub_rr:3032  case Hexagon::L2_ploadrubt_io:3033  case Hexagon::L2_ploadrubt_pi:3034  case Hexagon::L2_ploadrubf_io:3035  case Hexagon::L2_ploadrubf_pi:3036  case Hexagon::L2_ploadrubtnew_io:3037  case Hexagon::L2_ploadrubfnew_io:3038  case Hexagon::L4_ploadrubt_rr:3039  case Hexagon::L4_ploadrubf_rr:3040  case Hexagon::L4_ploadrubtnew_rr:3041  case Hexagon::L4_ploadrubfnew_rr:3042  case Hexagon::L2_ploadrubtnew_pi:3043  case Hexagon::L2_ploadrubfnew_pi:3044  case Hexagon::L4_ploadrubt_abs:3045  case Hexagon::L4_ploadrubf_abs:3046  case Hexagon::L4_ploadrubtnew_abs:3047  case Hexagon::L4_ploadrubfnew_abs:3048  case Hexagon::L2_loadrubgp:3049  // Half3050  case Hexagon::L2_loadruh_io:3051  case Hexagon::L4_loadruh_ur:3052  case Hexagon::L4_loadruh_ap:3053  case Hexagon::L2_loadruh_pr:3054  case Hexagon::L2_loadruh_pbr:3055  case Hexagon::L2_loadruh_pi:3056  case Hexagon::L2_loadruh_pci:3057  case Hexagon::L2_loadruh_pcr:3058  case Hexagon::L4_loadruh_rr:3059  case Hexagon::L2_ploadruht_io:3060  case Hexagon::L2_ploadruht_pi:3061  case Hexagon::L2_ploadruhf_io:3062  case Hexagon::L2_ploadruhf_pi:3063  case Hexagon::L2_ploadruhtnew_io:3064  case Hexagon::L2_ploadruhfnew_io:3065  case Hexagon::L4_ploadruht_rr:3066  case Hexagon::L4_ploadruhf_rr:3067  case Hexagon::L4_ploadruhtnew_rr:3068  case Hexagon::L4_ploadruhfnew_rr:3069  case Hexagon::L2_ploadruhtnew_pi:3070  case Hexagon::L2_ploadruhfnew_pi:3071  case Hexagon::L4_ploadruht_abs:3072  case Hexagon::L4_ploadruhf_abs:3073  case Hexagon::L4_ploadruhtnew_abs:3074  case Hexagon::L4_ploadruhfnew_abs:3075  case Hexagon::L2_loadruhgp:3076    return true;3077  default:3078    return false;3079  }3080}3081 3082// Add latency to instruction.3083bool HexagonInstrInfo::addLatencyToSchedule(const MachineInstr &MI1,3084      const MachineInstr &MI2) const {3085  if (isHVXVec(MI1) && isHVXVec(MI2))3086    if (!isVecUsableNextPacket(MI1, MI2))3087      return true;3088  return false;3089}3090 3091/// Get the base register and byte offset of a load/store instr.3092bool HexagonInstrInfo::getMemOperandsWithOffsetWidth(3093    const MachineInstr &LdSt, SmallVectorImpl<const MachineOperand *> &BaseOps,3094    int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width,3095    const TargetRegisterInfo *TRI) const {3096  OffsetIsScalable = false;3097  const MachineOperand *BaseOp = getBaseAndOffset(LdSt, Offset, Width);3098  if (!BaseOp || !BaseOp->isReg())3099    return false;3100  BaseOps.push_back(BaseOp);3101  return true;3102}3103 3104/// Can these instructions execute at the same time in a bundle.3105bool HexagonInstrInfo::canExecuteInBundle(const MachineInstr &First,3106      const MachineInstr &Second) const {3107  if (Second.mayStore() && First.getOpcode() == Hexagon::S2_allocframe) {3108    const MachineOperand &Op = Second.getOperand(0);3109    if (Op.isReg() && Op.isUse() && Op.getReg() == Hexagon::R29)3110      return true;3111  }3112  if (DisableNVSchedule)3113    return false;3114  if (mayBeNewStore(Second)) {3115    // Make sure the definition of the first instruction is the value being3116    // stored.3117    const MachineOperand &Stored =3118      Second.getOperand(Second.getNumOperands() - 1);3119    if (!Stored.isReg())3120      return false;3121    for (unsigned i = 0, e = First.getNumOperands(); i < e; ++i) {3122      const MachineOperand &Op = First.getOperand(i);3123      if (Op.isReg() && Op.isDef() && Op.getReg() == Stored.getReg())3124        return true;3125    }3126  }3127  return false;3128}3129 3130bool HexagonInstrInfo::doesNotReturn(const MachineInstr &CallMI) const {3131  unsigned Opc = CallMI.getOpcode();3132  return Opc == Hexagon::PS_call_nr || Opc == Hexagon::PS_callr_nr;3133}3134 3135bool HexagonInstrInfo::hasEHLabel(const MachineBasicBlock *B) const {3136  for (auto &I : *B)3137    if (I.isEHLabel())3138      return true;3139  return false;3140}3141 3142// Returns true if an instruction can be converted into a non-extended3143// equivalent instruction.3144bool HexagonInstrInfo::hasNonExtEquivalent(const MachineInstr &MI) const {3145  short NonExtOpcode;3146  // Check if the instruction has a register form that uses register in place3147  // of the extended operand, if so return that as the non-extended form.3148  if (Hexagon::getRegForm(MI.getOpcode()) >= 0)3149    return true;3150 3151  if (MI.getDesc().mayLoad() || MI.getDesc().mayStore()) {3152    // Check addressing mode and retrieve non-ext equivalent instruction.3153 3154    switch (getAddrMode(MI)) {3155    case HexagonII::Absolute:3156      // Load/store with absolute addressing mode can be converted into3157      // base+offset mode.3158      NonExtOpcode = Hexagon::changeAddrMode_abs_io(MI.getOpcode());3159      break;3160    case HexagonII::BaseImmOffset:3161      // Load/store with base+offset addressing mode can be converted into3162      // base+register offset addressing mode. However left shift operand should3163      // be set to 0.3164      NonExtOpcode = Hexagon::changeAddrMode_io_rr(MI.getOpcode());3165      break;3166    case HexagonII::BaseLongOffset:3167      NonExtOpcode = Hexagon::changeAddrMode_ur_rr(MI.getOpcode());3168      break;3169    default:3170      return false;3171    }3172    if (NonExtOpcode < 0)3173      return false;3174    return true;3175  }3176  return false;3177}3178 3179bool HexagonInstrInfo::hasPseudoInstrPair(const MachineInstr &MI) const {3180  return Hexagon::getRealHWInstr(MI.getOpcode(),3181                                 Hexagon::InstrType_Pseudo) >= 0;3182}3183 3184bool HexagonInstrInfo::hasUncondBranch(const MachineBasicBlock *B)3185      const {3186  MachineBasicBlock::const_iterator I = B->getFirstTerminator(), E = B->end();3187  while (I != E) {3188    if (I->isBarrier())3189      return true;3190    ++I;3191  }3192  return false;3193}3194 3195// Returns true, if a LD insn can be promoted to a cur load.3196bool HexagonInstrInfo::mayBeCurLoad(const MachineInstr &MI) const {3197  const uint64_t F = MI.getDesc().TSFlags;3198  return ((F >> HexagonII::mayCVLoadPos) & HexagonII::mayCVLoadMask) &&3199         Subtarget.hasV60Ops();3200}3201 3202// Returns true, if a ST insn can be promoted to a new-value store.3203bool HexagonInstrInfo::mayBeNewStore(const MachineInstr &MI) const {3204  if (MI.mayStore() && !Subtarget.useNewValueStores())3205    return false;3206 3207  const uint64_t F = MI.getDesc().TSFlags;3208  return (F >> HexagonII::mayNVStorePos) & HexagonII::mayNVStoreMask;3209}3210 3211bool HexagonInstrInfo::producesStall(const MachineInstr &ProdMI,3212      const MachineInstr &ConsMI) const {3213  // There is no stall when ProdMI is not a V60 vector.3214  if (!isHVXVec(ProdMI))3215    return false;3216 3217  // There is no stall when ProdMI and ConsMI are not dependent.3218  if (!isDependent(ProdMI, ConsMI))3219    return false;3220 3221  // When Forward Scheduling is enabled, there is no stall if ProdMI and ConsMI3222  // are scheduled in consecutive packets.3223  if (isVecUsableNextPacket(ProdMI, ConsMI))3224    return false;3225 3226  return true;3227}3228 3229bool HexagonInstrInfo::producesStall(const MachineInstr &MI,3230      MachineBasicBlock::const_instr_iterator BII) const {3231  // There is no stall when I is not a V60 vector.3232  if (!isHVXVec(MI))3233    return false;3234 3235  MachineBasicBlock::const_instr_iterator MII = BII;3236  MachineBasicBlock::const_instr_iterator MIE = MII->getParent()->instr_end();3237 3238  if (!MII->isBundle())3239    return producesStall(*MII, MI);3240 3241  for (++MII; MII != MIE && MII->isInsideBundle(); ++MII) {3242    const MachineInstr &J = *MII;3243    if (producesStall(J, MI))3244      return true;3245  }3246  return false;3247}3248 3249bool HexagonInstrInfo::predCanBeUsedAsDotNew(const MachineInstr &MI,3250      Register PredReg) const {3251  for (const MachineOperand &MO : MI.operands()) {3252    // Predicate register must be explicitly defined.3253    if (MO.isRegMask() && MO.clobbersPhysReg(PredReg))3254      return false;3255    if (MO.isReg() && MO.isDef() && MO.isImplicit() && (MO.getReg() == PredReg))3256      return false;3257  }3258 3259  // Instruction that produce late predicate cannot be used as sources of3260  // dot-new.3261  switch (MI.getOpcode()) {3262    case Hexagon::A4_addp_c:3263    case Hexagon::A4_subp_c:3264    case Hexagon::A4_tlbmatch:3265    case Hexagon::A5_ACS:3266    case Hexagon::F2_sfinvsqrta:3267    case Hexagon::F2_sfrecipa:3268    case Hexagon::J2_endloop0:3269    case Hexagon::J2_endloop01:3270    case Hexagon::J2_ploop1si:3271    case Hexagon::J2_ploop1sr:3272    case Hexagon::J2_ploop2si:3273    case Hexagon::J2_ploop2sr:3274    case Hexagon::J2_ploop3si:3275    case Hexagon::J2_ploop3sr:3276    case Hexagon::S2_cabacdecbin:3277    case Hexagon::S2_storew_locked:3278    case Hexagon::S4_stored_locked:3279      return false;3280  }3281  return true;3282}3283 3284bool HexagonInstrInfo::PredOpcodeHasJMP_c(unsigned Opcode) const {3285  return Opcode == Hexagon::J2_jumpt      ||3286         Opcode == Hexagon::J2_jumptpt    ||3287         Opcode == Hexagon::J2_jumpf      ||3288         Opcode == Hexagon::J2_jumpfpt    ||3289         Opcode == Hexagon::J2_jumptnew   ||3290         Opcode == Hexagon::J2_jumpfnew   ||3291         Opcode == Hexagon::J2_jumptnewpt ||3292         Opcode == Hexagon::J2_jumpfnewpt;3293}3294 3295bool HexagonInstrInfo::predOpcodeHasNot(ArrayRef<MachineOperand> Cond) const {3296  if (Cond.empty() || !isPredicated(Cond[0].getImm()))3297    return false;3298  return !isPredicatedTrue(Cond[0].getImm());3299}3300 3301unsigned HexagonInstrInfo::getAddrMode(const MachineInstr &MI) const {3302  const uint64_t F = MI.getDesc().TSFlags;3303  return (F >> HexagonII::AddrModePos) & HexagonII::AddrModeMask;3304}3305 3306// Returns the base register in a memory access (load/store). The offset is3307// returned in Offset and the access size is returned in AccessSize.3308// If the base operand has a subregister or the offset field does not contain3309// an immediate value, return nullptr.3310MachineOperand *3311HexagonInstrInfo::getBaseAndOffset(const MachineInstr &MI, int64_t &Offset,3312                                   LocationSize &AccessSize) const {3313  // Return if it is not a base+offset type instruction or a MemOp.3314  if (getAddrMode(MI) != HexagonII::BaseImmOffset &&3315      getAddrMode(MI) != HexagonII::BaseLongOffset && !isMemOp(MI) &&3316      !isPostIncrement(MI))3317    return nullptr;3318 3319  AccessSize = LocationSize::precise(getMemAccessSize(MI));3320 3321  unsigned BasePos = 0, OffsetPos = 0;3322  if (!getBaseAndOffsetPosition(MI, BasePos, OffsetPos))3323    return nullptr;3324 3325  // Post increment updates its EA after the mem access,3326  // so we need to treat its offset as zero.3327  if (isPostIncrement(MI)) {3328    Offset = 0;3329  } else {3330    const MachineOperand &OffsetOp = MI.getOperand(OffsetPos);3331    if (!OffsetOp.isImm())3332      return nullptr;3333    Offset = OffsetOp.getImm();3334  }3335 3336  const MachineOperand &BaseOp = MI.getOperand(BasePos);3337  if (BaseOp.getSubReg() != 0)3338    return nullptr;3339  return &const_cast<MachineOperand&>(BaseOp);3340}3341 3342/// Return the position of the base and offset operands for this instruction.3343bool HexagonInstrInfo::getBaseAndOffsetPosition(const MachineInstr &MI,3344      unsigned &BasePos, unsigned &OffsetPos) const {3345  if (!isAddrModeWithOffset(MI) && !isPostIncrement(MI))3346    return false;3347 3348  // Deal with memops first.3349  if (isMemOp(MI)) {3350    BasePos = 0;3351    OffsetPos = 1;3352  } else if (MI.mayStore()) {3353    BasePos = 0;3354    OffsetPos = 1;3355  } else if (MI.mayLoad()) {3356    BasePos = 1;3357    OffsetPos = 2;3358  } else3359    return false;3360 3361  if (isPredicated(MI)) {3362    BasePos++;3363    OffsetPos++;3364  }3365  if (isPostIncrement(MI)) {3366    BasePos++;3367    OffsetPos++;3368  }3369 3370  if (!MI.getOperand(BasePos).isReg() || !MI.getOperand(OffsetPos).isImm())3371    return false;3372 3373  return true;3374}3375 3376// Inserts branching instructions in reverse order of their occurrence.3377// e.g. jump_t t1 (i1)3378// jump t2        (i2)3379// Jumpers = {i2, i1}3380SmallVector<MachineInstr*, 2> HexagonInstrInfo::getBranchingInstrs(3381      MachineBasicBlock& MBB) const {3382  SmallVector<MachineInstr*, 2> Jumpers;3383  // If the block has no terminators, it just falls into the block after it.3384  MachineBasicBlock::instr_iterator I = MBB.instr_end();3385  if (I == MBB.instr_begin())3386    return Jumpers;3387 3388  // A basic block may looks like this:3389  //3390  //  [   insn3391  //     EH_LABEL3392  //      insn3393  //      insn3394  //      insn3395  //     EH_LABEL3396  //      insn     ]3397  //3398  // It has two succs but does not have a terminator3399  // Don't know how to handle it.3400  do {3401    --I;3402    if (I->isEHLabel())3403      return Jumpers;3404  } while (I != MBB.instr_begin());3405 3406  I = MBB.instr_end();3407  --I;3408 3409  while (I->isDebugInstr()) {3410    if (I == MBB.instr_begin())3411      return Jumpers;3412    --I;3413  }3414  if (!isUnpredicatedTerminator(*I))3415    return Jumpers;3416 3417  // Get the last instruction in the block.3418  MachineInstr *LastInst = &*I;3419  Jumpers.push_back(LastInst);3420  MachineInstr *SecondLastInst = nullptr;3421  // Find one more terminator if present.3422  do {3423    if (&*I != LastInst && !I->isBundle() && isUnpredicatedTerminator(*I)) {3424      if (!SecondLastInst) {3425        SecondLastInst = &*I;3426        Jumpers.push_back(SecondLastInst);3427      } else // This is a third branch.3428        return Jumpers;3429    }3430    if (I == MBB.instr_begin())3431      break;3432    --I;3433  } while (true);3434  return Jumpers;3435}3436 3437// Returns Operand Index for the constant extended instruction.3438unsigned HexagonInstrInfo::getCExtOpNum(const MachineInstr &MI) const {3439  const uint64_t F = MI.getDesc().TSFlags;3440  return (F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask;3441}3442 3443// See if instruction could potentially be a duplex candidate.3444// If so, return its group. Zero otherwise.3445HexagonII::CompoundGroup HexagonInstrInfo::getCompoundCandidateGroup(3446      const MachineInstr &MI) const {3447  Register DstReg, SrcReg, Src1Reg, Src2Reg;3448 3449  switch (MI.getOpcode()) {3450  default:3451    return HexagonII::HCG_None;3452  //3453  // Compound pairs.3454  // "p0=cmp.eq(Rs16,Rt16); if (p0.new) jump:nt #r9:2"3455  // "Rd16=#U6 ; jump #r9:2"3456  // "Rd16=Rs16 ; jump #r9:2"3457  //3458  case Hexagon::C2_cmpeq:3459  case Hexagon::C2_cmpgt:3460  case Hexagon::C2_cmpgtu:3461    DstReg = MI.getOperand(0).getReg();3462    Src1Reg = MI.getOperand(1).getReg();3463    Src2Reg = MI.getOperand(2).getReg();3464    if (Hexagon::PredRegsRegClass.contains(DstReg) &&3465        (Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&3466        isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg))3467      return HexagonII::HCG_A;3468    break;3469  case Hexagon::C2_cmpeqi:3470  case Hexagon::C2_cmpgti:3471  case Hexagon::C2_cmpgtui:3472    // P0 = cmp.eq(Rs,#u2)3473    DstReg = MI.getOperand(0).getReg();3474    SrcReg = MI.getOperand(1).getReg();3475    if (Hexagon::PredRegsRegClass.contains(DstReg) &&3476        (Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&3477        isIntRegForSubInst(SrcReg) && MI.getOperand(2).isImm() &&3478        ((isUInt<5>(MI.getOperand(2).getImm())) ||3479         (MI.getOperand(2).getImm() == -1)))3480      return HexagonII::HCG_A;3481    break;3482  case Hexagon::A2_tfr:3483    // Rd = Rs3484    DstReg = MI.getOperand(0).getReg();3485    SrcReg = MI.getOperand(1).getReg();3486    if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg))3487      return HexagonII::HCG_A;3488    break;3489  case Hexagon::A2_tfrsi:3490    // Rd = #u63491    // Do not test for #u6 size since the const is getting extended3492    // regardless and compound could be formed.3493    DstReg = MI.getOperand(0).getReg();3494    if (isIntRegForSubInst(DstReg))3495      return HexagonII::HCG_A;3496    break;3497  case Hexagon::S2_tstbit_i:3498    DstReg = MI.getOperand(0).getReg();3499    Src1Reg = MI.getOperand(1).getReg();3500    if (Hexagon::PredRegsRegClass.contains(DstReg) &&3501        (Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&3502        MI.getOperand(2).isImm() &&3503        isIntRegForSubInst(Src1Reg) && (MI.getOperand(2).getImm() == 0))3504      return HexagonII::HCG_A;3505    break;3506  // The fact that .new form is used pretty much guarantees3507  // that predicate register will match. Nevertheless,3508  // there could be some false positives without additional3509  // checking.3510  case Hexagon::J2_jumptnew:3511  case Hexagon::J2_jumpfnew:3512  case Hexagon::J2_jumptnewpt:3513  case Hexagon::J2_jumpfnewpt:3514    Src1Reg = MI.getOperand(0).getReg();3515    if (Hexagon::PredRegsRegClass.contains(Src1Reg) &&3516        (Hexagon::P0 == Src1Reg || Hexagon::P1 == Src1Reg))3517      return HexagonII::HCG_B;3518    break;3519  // Transfer and jump:3520  // Rd=#U6 ; jump #r9:23521  // Rd=Rs ; jump #r9:23522  // Do not test for jump range here.3523  case Hexagon::J2_jump:3524  case Hexagon::RESTORE_DEALLOC_RET_JMP_V4:3525  case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC:3526    return HexagonII::HCG_C;3527  }3528 3529  return HexagonII::HCG_None;3530}3531 3532// Returns -1 when there is no opcode found.3533unsigned HexagonInstrInfo::getCompoundOpcode(const MachineInstr &GA,3534      const MachineInstr &GB) const {3535  assert(getCompoundCandidateGroup(GA) == HexagonII::HCG_A);3536  assert(getCompoundCandidateGroup(GB) == HexagonII::HCG_B);3537  if ((GA.getOpcode() != Hexagon::C2_cmpeqi) ||3538      (GB.getOpcode() != Hexagon::J2_jumptnew))3539    return -1u;3540  Register DestReg = GA.getOperand(0).getReg();3541  if (!GB.readsRegister(DestReg, /*TRI=*/nullptr))3542    return -1u;3543  if (DestReg != Hexagon::P0 && DestReg != Hexagon::P1)3544    return -1u;3545  // The value compared against must be either u5 or -1.3546  const MachineOperand &CmpOp = GA.getOperand(2);3547  if (!CmpOp.isImm())3548    return -1u;3549  int V = CmpOp.getImm();3550  if (V == -1)3551    return DestReg == Hexagon::P0 ? Hexagon::J4_cmpeqn1_tp0_jump_nt3552                                  : Hexagon::J4_cmpeqn1_tp1_jump_nt;3553  if (!isUInt<5>(V))3554    return -1u;3555  return DestReg == Hexagon::P0 ? Hexagon::J4_cmpeqi_tp0_jump_nt3556                                : Hexagon::J4_cmpeqi_tp1_jump_nt;3557}3558 3559// Returns -1 if there is no opcode found.3560int HexagonInstrInfo::getDuplexOpcode(const MachineInstr &MI,3561                                      bool ForBigCore) const {3562  // Static table to switch the opcodes across Tiny Core and Big Core.3563  // dup_ opcodes are Big core opcodes.3564  // NOTE: There are special instructions that need to handled later.3565  // L4_return* instructions, they will only occupy SLOT0 (on big core too).3566  // PS_jmpret - This pseudo translates to J2_jumpr which occupies only SLOT2.3567  // The compiler need to base the root instruction to L6_return_map_to_raw3568  // which can go any slot.3569  static const std::map<unsigned, unsigned> DupMap = {3570      {Hexagon::A2_add, Hexagon::dup_A2_add},3571      {Hexagon::A2_addi, Hexagon::dup_A2_addi},3572      {Hexagon::A2_andir, Hexagon::dup_A2_andir},3573      {Hexagon::A2_combineii, Hexagon::dup_A2_combineii},3574      {Hexagon::A2_sxtb, Hexagon::dup_A2_sxtb},3575      {Hexagon::A2_sxth, Hexagon::dup_A2_sxth},3576      {Hexagon::A2_tfr, Hexagon::dup_A2_tfr},3577      {Hexagon::A2_tfrsi, Hexagon::dup_A2_tfrsi},3578      {Hexagon::A2_zxtb, Hexagon::dup_A2_zxtb},3579      {Hexagon::A2_zxth, Hexagon::dup_A2_zxth},3580      {Hexagon::A4_combineii, Hexagon::dup_A4_combineii},3581      {Hexagon::A4_combineir, Hexagon::dup_A4_combineir},3582      {Hexagon::A4_combineri, Hexagon::dup_A4_combineri},3583      {Hexagon::C2_cmoveif, Hexagon::dup_C2_cmoveif},3584      {Hexagon::C2_cmoveit, Hexagon::dup_C2_cmoveit},3585      {Hexagon::C2_cmovenewif, Hexagon::dup_C2_cmovenewif},3586      {Hexagon::C2_cmovenewit, Hexagon::dup_C2_cmovenewit},3587      {Hexagon::C2_cmpeqi, Hexagon::dup_C2_cmpeqi},3588      {Hexagon::L2_deallocframe, Hexagon::dup_L2_deallocframe},3589      {Hexagon::L2_loadrb_io, Hexagon::dup_L2_loadrb_io},3590      {Hexagon::L2_loadrd_io, Hexagon::dup_L2_loadrd_io},3591      {Hexagon::L2_loadrh_io, Hexagon::dup_L2_loadrh_io},3592      {Hexagon::L2_loadri_io, Hexagon::dup_L2_loadri_io},3593      {Hexagon::L2_loadrub_io, Hexagon::dup_L2_loadrub_io},3594      {Hexagon::L2_loadruh_io, Hexagon::dup_L2_loadruh_io},3595      {Hexagon::S2_allocframe, Hexagon::dup_S2_allocframe},3596      {Hexagon::S2_storerb_io, Hexagon::dup_S2_storerb_io},3597      {Hexagon::S2_storerd_io, Hexagon::dup_S2_storerd_io},3598      {Hexagon::S2_storerh_io, Hexagon::dup_S2_storerh_io},3599      {Hexagon::S2_storeri_io, Hexagon::dup_S2_storeri_io},3600      {Hexagon::S4_storeirb_io, Hexagon::dup_S4_storeirb_io},3601      {Hexagon::S4_storeiri_io, Hexagon::dup_S4_storeiri_io},3602  };3603  unsigned OpNum = MI.getOpcode();3604  // Conversion to Big core.3605  if (ForBigCore) {3606    auto Iter = DupMap.find(OpNum);3607    if (Iter != DupMap.end())3608      return Iter->second;3609  } else { // Conversion to Tiny core.3610    for (const auto &Iter : DupMap)3611      if (Iter.second == OpNum)3612        return Iter.first;3613  }3614  return -1;3615}3616 3617int HexagonInstrInfo::getCondOpcode(int Opc, bool invertPredicate) const {3618  enum Hexagon::PredSense inPredSense;3619  inPredSense = invertPredicate ? Hexagon::PredSense_false :3620                                  Hexagon::PredSense_true;3621  int CondOpcode = Hexagon::getPredOpcode(Opc, inPredSense);3622  if (CondOpcode >= 0) // Valid Conditional opcode/instruction3623    return CondOpcode;3624 3625  llvm_unreachable("Unexpected predicable instruction");3626}3627 3628// Return the cur value instruction for a given store.3629int HexagonInstrInfo::getDotCurOp(const MachineInstr &MI) const {3630  switch (MI.getOpcode()) {3631  default: llvm_unreachable("Unknown .cur type");3632  case Hexagon::V6_vL32b_pi:3633    return Hexagon::V6_vL32b_cur_pi;3634  case Hexagon::V6_vL32b_ai:3635    return Hexagon::V6_vL32b_cur_ai;3636  case Hexagon::V6_vL32b_nt_pi:3637    return Hexagon::V6_vL32b_nt_cur_pi;3638  case Hexagon::V6_vL32b_nt_ai:3639    return Hexagon::V6_vL32b_nt_cur_ai;3640  case Hexagon::V6_vL32b_ppu:3641    return Hexagon::V6_vL32b_cur_ppu;3642  case Hexagon::V6_vL32b_nt_ppu:3643    return Hexagon::V6_vL32b_nt_cur_ppu;3644  }3645  return 0;3646}3647 3648// Return the regular version of the .cur instruction.3649int HexagonInstrInfo::getNonDotCurOp(const MachineInstr &MI) const {3650  switch (MI.getOpcode()) {3651  default: llvm_unreachable("Unknown .cur type");3652  case Hexagon::V6_vL32b_cur_pi:3653    return Hexagon::V6_vL32b_pi;3654  case Hexagon::V6_vL32b_cur_ai:3655    return Hexagon::V6_vL32b_ai;3656  case Hexagon::V6_vL32b_nt_cur_pi:3657    return Hexagon::V6_vL32b_nt_pi;3658  case Hexagon::V6_vL32b_nt_cur_ai:3659    return Hexagon::V6_vL32b_nt_ai;3660  case Hexagon::V6_vL32b_cur_ppu:3661    return Hexagon::V6_vL32b_ppu;3662  case Hexagon::V6_vL32b_nt_cur_ppu:3663    return Hexagon::V6_vL32b_nt_ppu;3664  }3665  return 0;3666}3667 3668// The diagram below shows the steps involved in the conversion of a predicated3669// store instruction to its .new predicated new-value form.3670//3671// Note: It doesn't include conditional new-value stores as they can't be3672// converted to .new predicate.3673//3674//               p.new NV store [ if(p0.new)memw(R0+#0)=R2.new ]3675//                ^           ^3676//               /             \ (not OK. it will cause new-value store to be3677//              /               X conditional on p0.new while R2 producer is3678//             /                 \ on p0)3679//            /                   \.3680//     p.new store                 p.old NV store3681// [if(p0.new)memw(R0+#0)=R2]    [if(p0)memw(R0+#0)=R2.new]3682//            ^                  ^3683//             \                /3684//              \              /3685//               \            /3686//                 p.old store3687//             [if (p0)memw(R0+#0)=R2]3688//3689// The following set of instructions further explains the scenario where3690// conditional new-value store becomes invalid when promoted to .new predicate3691// form.3692//3693// { 1) if (p0) r0 = add(r1, r2)3694//   2) p0 = cmp.eq(r3, #0) }3695//3696//   3) if (p0) memb(r1+#0) = r0  --> this instruction can't be grouped with3697// the first two instructions because in instr 1, r0 is conditional on old value3698// of p0 but its use in instr 3 is conditional on p0 modified by instr 2 which3699// is not valid for new-value stores.3700// Predicated new value stores (i.e. if (p0) memw(..)=r0.new) are excluded3701// from the "Conditional Store" list. Because a predicated new value store3702// would NOT be promoted to a double dot new store. See diagram below:3703// This function returns yes for those stores that are predicated but not3704// yet promoted to predicate dot new instructions.3705//3706//                          +---------------------+3707//                    /-----| if (p0) memw(..)=r0 |---------\~3708//                   ||     +---------------------+         ||3709//          promote  ||       /\       /\                   ||  promote3710//                   ||      /||\     /||\                  ||3711//                  \||/    demote     ||                  \||/3712//                   \/       ||       ||                   \/3713//       +-------------------------+   ||   +-------------------------+3714//       | if (p0.new) memw(..)=r0 |   ||   | if (p0) memw(..)=r0.new |3715//       +-------------------------+   ||   +-------------------------+3716//                        ||           ||         ||3717//                        ||         demote      \||/3718//                      promote        ||         \/ NOT possible3719//                        ||           ||         /\~3720//                       \||/          ||        /||\~3721//                        \/           ||         ||3722//                      +-----------------------------+3723//                      | if (p0.new) memw(..)=r0.new |3724//                      +-----------------------------+3725//                           Double Dot New Store3726//3727// Returns the most basic instruction for the .new predicated instructions and3728// new-value stores.3729// For example, all of the following instructions will be converted back to the3730// same instruction:3731// 1) if (p0.new) memw(R0+#0) = R1.new  --->3732// 2) if (p0) memw(R0+#0)= R1.new      -------> if (p0) memw(R0+#0) = R13733// 3) if (p0.new) memw(R0+#0) = R1      --->3734//3735// To understand the translation of instruction 1 to its original form, consider3736// a packet with 3 instructions.3737// { p0 = cmp.eq(R0,R1)3738//   if (p0.new) R2 = add(R3, R4)3739//   R5 = add (R3, R1)3740// }3741// if (p0) memw(R5+#0) = R2 <--- trying to include it in the previous packet3742//3743// This instruction can be part of the previous packet only if both p0 and R23744// are promoted to .new values. This promotion happens in steps, first3745// predicate register is promoted to .new and in the next iteration R2 is3746// promoted. Therefore, in case of dependence check failure (due to R5) during3747// next iteration, it should be converted back to its most basic form.3748 3749// Return the new value instruction for a given store.3750int HexagonInstrInfo::getDotNewOp(const MachineInstr &MI) const {3751  int NVOpcode = Hexagon::getNewValueOpcode(MI.getOpcode());3752  if (NVOpcode >= 0) // Valid new-value store instruction.3753    return NVOpcode;3754 3755  switch (MI.getOpcode()) {3756  default:3757    report_fatal_error(Twine("Unknown .new type: ") +3758                       std::to_string(MI.getOpcode()));3759  case Hexagon::S4_storerb_ur:3760    return Hexagon::S4_storerbnew_ur;3761 3762  case Hexagon::S2_storerb_pci:3763    return Hexagon::S2_storerb_pci;3764 3765  case Hexagon::S2_storeri_pci:3766    return Hexagon::S2_storeri_pci;3767 3768  case Hexagon::S2_storerh_pci:3769    return Hexagon::S2_storerh_pci;3770 3771  case Hexagon::S2_storerd_pci:3772    return Hexagon::S2_storerd_pci;3773 3774  case Hexagon::S2_storerf_pci:3775    return Hexagon::S2_storerf_pci;3776 3777  case Hexagon::V6_vS32b_ai:3778    return Hexagon::V6_vS32b_new_ai;3779 3780  case Hexagon::V6_vS32b_pi:3781    return Hexagon::V6_vS32b_new_pi;3782  }3783  return 0;3784}3785 3786// Returns the opcode to use when converting MI, which is a conditional jump,3787// into a conditional instruction which uses the .new value of the predicate.3788// We also use branch probabilities to add a hint to the jump.3789// If MBPI is null, all edges will be treated as equally likely for the3790// purposes of establishing a predication hint.3791int HexagonInstrInfo::getDotNewPredJumpOp(const MachineInstr &MI,3792      const MachineBranchProbabilityInfo *MBPI) const {3793  // We assume that block can have at most two successors.3794  const MachineBasicBlock *Src = MI.getParent();3795  const MachineOperand &BrTarget = MI.getOperand(1);3796  bool Taken = false;3797  const BranchProbability OneHalf(1, 2);3798 3799  auto getEdgeProbability = [MBPI] (const MachineBasicBlock *Src,3800                                    const MachineBasicBlock *Dst) {3801    if (MBPI)3802      return MBPI->getEdgeProbability(Src, Dst);3803    return BranchProbability(1, Src->succ_size());3804  };3805 3806  if (BrTarget.isMBB()) {3807    const MachineBasicBlock *Dst = BrTarget.getMBB();3808    Taken = getEdgeProbability(Src, Dst) >= OneHalf;3809  } else {3810    // The branch target is not a basic block (most likely a function).3811    // Since BPI only gives probabilities for targets that are basic blocks,3812    // try to identify another target of this branch (potentially a fall-3813    // -through) and check the probability of that target.3814    //3815    // The only handled branch combinations are:3816    // - one conditional branch,3817    // - one conditional branch followed by one unconditional branch.3818    // Otherwise, assume not-taken.3819    assert(MI.isConditionalBranch());3820    const MachineBasicBlock &B = *MI.getParent();3821    bool SawCond = false, Bad = false;3822    for (const MachineInstr &I : B) {3823      if (!I.isBranch())3824        continue;3825      if (I.isConditionalBranch()) {3826        SawCond = true;3827        if (&I != &MI) {3828          Bad = true;3829          break;3830        }3831      }3832      if (I.isUnconditionalBranch() && !SawCond) {3833        Bad = true;3834        break;3835      }3836    }3837    if (!Bad) {3838      MachineBasicBlock::const_instr_iterator It(MI);3839      MachineBasicBlock::const_instr_iterator NextIt = std::next(It);3840      if (NextIt == B.instr_end()) {3841        // If this branch is the last, look for the fall-through block.3842        for (const MachineBasicBlock *SB : B.successors()) {3843          if (!B.isLayoutSuccessor(SB))3844            continue;3845          Taken = getEdgeProbability(Src, SB) < OneHalf;3846          break;3847        }3848      } else {3849        assert(NextIt->isUnconditionalBranch());3850        // Find the first MBB operand and assume it's the target.3851        const MachineBasicBlock *BT = nullptr;3852        for (const MachineOperand &Op : NextIt->operands()) {3853          if (!Op.isMBB())3854            continue;3855          BT = Op.getMBB();3856          break;3857        }3858        Taken = BT && getEdgeProbability(Src, BT) < OneHalf;3859      }3860    } // if (!Bad)3861  }3862 3863  // The Taken flag should be set to something reasonable by this point.3864 3865  switch (MI.getOpcode()) {3866  case Hexagon::J2_jumpt:3867    return Taken ? Hexagon::J2_jumptnewpt : Hexagon::J2_jumptnew;3868  case Hexagon::J2_jumpf:3869    return Taken ? Hexagon::J2_jumpfnewpt : Hexagon::J2_jumpfnew;3870 3871  default:3872    llvm_unreachable("Unexpected jump instruction.");3873  }3874}3875 3876// Return .new predicate version for an instruction.3877int HexagonInstrInfo::getDotNewPredOp(const MachineInstr &MI,3878      const MachineBranchProbabilityInfo *MBPI) const {3879  switch (MI.getOpcode()) {3880  // Conditional Jumps3881  case Hexagon::J2_jumpt:3882  case Hexagon::J2_jumpf:3883    return getDotNewPredJumpOp(MI, MBPI);3884  }3885 3886  int NewOpcode = Hexagon::getPredNewOpcode(MI.getOpcode());3887  if (NewOpcode >= 0)3888    return NewOpcode;3889  return 0;3890}3891 3892int HexagonInstrInfo::getDotOldOp(const MachineInstr &MI) const {3893  int NewOp = MI.getOpcode();3894  if (isPredicated(NewOp) && isPredicatedNew(NewOp)) { // Get predicate old form3895    NewOp = Hexagon::getPredOldOpcode(NewOp);3896    // All Hexagon architectures have prediction bits on dot-new branches,3897    // but only Hexagon V60+ has prediction bits on dot-old ones. Make sure3898    // to pick the right opcode when converting back to dot-old.3899    if (!Subtarget.hasFeature(Hexagon::ArchV60)) {3900      switch (NewOp) {3901      case Hexagon::J2_jumptpt:3902        NewOp = Hexagon::J2_jumpt;3903        break;3904      case Hexagon::J2_jumpfpt:3905        NewOp = Hexagon::J2_jumpf;3906        break;3907      case Hexagon::J2_jumprtpt:3908        NewOp = Hexagon::J2_jumprt;3909        break;3910      case Hexagon::J2_jumprfpt:3911        NewOp = Hexagon::J2_jumprf;3912        break;3913      }3914    }3915    assert(NewOp >= 0 &&3916           "Couldn't change predicate new instruction to its old form.");3917  }3918 3919  if (isNewValueStore(NewOp)) { // Convert into non-new-value format3920    NewOp = Hexagon::getNonNVStore(NewOp);3921    assert(NewOp >= 0 && "Couldn't change new-value store to its old form.");3922  }3923 3924  if (Subtarget.hasV60Ops())3925    return NewOp;3926 3927  // Subtargets prior to V60 didn't support 'taken' forms of predicated jumps.3928  switch (NewOp) {3929  case Hexagon::J2_jumpfpt:3930    return Hexagon::J2_jumpf;3931  case Hexagon::J2_jumptpt:3932    return Hexagon::J2_jumpt;3933  case Hexagon::J2_jumprfpt:3934    return Hexagon::J2_jumprf;3935  case Hexagon::J2_jumprtpt:3936    return Hexagon::J2_jumprt;3937  }3938  return NewOp;3939}3940 3941// See if instruction could potentially be a duplex candidate.3942// If so, return its group. Zero otherwise.3943HexagonII::SubInstructionGroup HexagonInstrInfo::getDuplexCandidateGroup(3944      const MachineInstr &MI) const {3945  Register DstReg, SrcReg, Src1Reg, Src2Reg;3946  const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();3947 3948  switch (MI.getOpcode()) {3949  default:3950    return HexagonII::HSIG_None;3951  //3952  // Group L1:3953  //3954  // Rd = memw(Rs+#u4:2)3955  // Rd = memub(Rs+#u4:0)3956  case Hexagon::L2_loadri_io:3957  case Hexagon::dup_L2_loadri_io:3958    DstReg = MI.getOperand(0).getReg();3959    SrcReg = MI.getOperand(1).getReg();3960    // Special case this one from Group L2.3961    // Rd = memw(r29+#u5:2)3962    if (isIntRegForSubInst(DstReg)) {3963      if (Hexagon::IntRegsRegClass.contains(SrcReg) &&3964          HRI.getStackRegister() == SrcReg &&3965          MI.getOperand(2).isImm() &&3966          isShiftedUInt<5,2>(MI.getOperand(2).getImm()))3967        return HexagonII::HSIG_L2;3968      // Rd = memw(Rs+#u4:2)3969      if (isIntRegForSubInst(SrcReg) &&3970          (MI.getOperand(2).isImm() &&3971          isShiftedUInt<4,2>(MI.getOperand(2).getImm())))3972        return HexagonII::HSIG_L1;3973    }3974    break;3975  case Hexagon::L2_loadrub_io:3976  case Hexagon::dup_L2_loadrub_io:3977    // Rd = memub(Rs+#u4:0)3978    DstReg = MI.getOperand(0).getReg();3979    SrcReg = MI.getOperand(1).getReg();3980    if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) &&3981        MI.getOperand(2).isImm() && isUInt<4>(MI.getOperand(2).getImm()))3982      return HexagonII::HSIG_L1;3983    break;3984  //3985  // Group L2:3986  //3987  // Rd = memh/memuh(Rs+#u3:1)3988  // Rd = memb(Rs+#u3:0)3989  // Rd = memw(r29+#u5:2) - Handled above.3990  // Rdd = memd(r29+#u5:3)3991  // deallocframe3992  // [if ([!]p0[.new])] dealloc_return3993  // [if ([!]p0[.new])] jumpr r313994  case Hexagon::L2_loadrh_io:3995  case Hexagon::L2_loadruh_io:3996  case Hexagon::dup_L2_loadrh_io:3997  case Hexagon::dup_L2_loadruh_io:3998    // Rd = memh/memuh(Rs+#u3:1)3999    DstReg = MI.getOperand(0).getReg();4000    SrcReg = MI.getOperand(1).getReg();4001    if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) &&4002        MI.getOperand(2).isImm() &&4003        isShiftedUInt<3,1>(MI.getOperand(2).getImm()))4004      return HexagonII::HSIG_L2;4005    break;4006  case Hexagon::L2_loadrb_io:4007  case Hexagon::dup_L2_loadrb_io:4008    // Rd = memb(Rs+#u3:0)4009    DstReg = MI.getOperand(0).getReg();4010    SrcReg = MI.getOperand(1).getReg();4011    if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) &&4012        MI.getOperand(2).isImm() &&4013        isUInt<3>(MI.getOperand(2).getImm()))4014      return HexagonII::HSIG_L2;4015    break;4016  case Hexagon::L2_loadrd_io:4017  case Hexagon::dup_L2_loadrd_io:4018    // Rdd = memd(r29+#u5:3)4019    DstReg = MI.getOperand(0).getReg();4020    SrcReg = MI.getOperand(1).getReg();4021    if (isDblRegForSubInst(DstReg, HRI) &&4022        Hexagon::IntRegsRegClass.contains(SrcReg) &&4023        HRI.getStackRegister() == SrcReg &&4024        MI.getOperand(2).isImm() &&4025        isShiftedUInt<5,3>(MI.getOperand(2).getImm()))4026      return HexagonII::HSIG_L2;4027    break;4028  // dealloc_return is not documented in Hexagon Manual, but marked4029  // with A_SUBINSN attribute in iset_v4classic.py.4030  case Hexagon::RESTORE_DEALLOC_RET_JMP_V4:4031  case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC:4032  case Hexagon::L4_return:4033  case Hexagon::L2_deallocframe:4034  case Hexagon::dup_L2_deallocframe:4035    return HexagonII::HSIG_L2;4036  case Hexagon::EH_RETURN_JMPR:4037  case Hexagon::PS_jmpret:4038  case Hexagon::SL2_jumpr31:4039    // jumpr r314040    // Actual form JMPR implicit-def %pc, implicit %r31, implicit internal %r04041    DstReg = MI.getOperand(0).getReg();4042    if (Hexagon::IntRegsRegClass.contains(DstReg) && (Hexagon::R31 == DstReg))4043      return HexagonII::HSIG_L2;4044    break;4045  case Hexagon::PS_jmprett:4046  case Hexagon::PS_jmpretf:4047  case Hexagon::PS_jmprettnewpt:4048  case Hexagon::PS_jmpretfnewpt:4049  case Hexagon::PS_jmprettnew:4050  case Hexagon::PS_jmpretfnew:4051  case Hexagon::SL2_jumpr31_t:4052  case Hexagon::SL2_jumpr31_f:4053  case Hexagon::SL2_jumpr31_tnew:4054  case Hexagon::SL2_jumpr31_fnew:4055    DstReg = MI.getOperand(1).getReg();4056    SrcReg = MI.getOperand(0).getReg();4057    // [if ([!]p0[.new])] jumpr r314058    if ((Hexagon::PredRegsRegClass.contains(SrcReg) &&4059        (Hexagon::P0 == SrcReg)) &&4060        (Hexagon::IntRegsRegClass.contains(DstReg) && (Hexagon::R31 == DstReg)))4061      return HexagonII::HSIG_L2;4062    break;4063  case Hexagon::L4_return_t:4064  case Hexagon::L4_return_f:4065  case Hexagon::L4_return_tnew_pnt:4066  case Hexagon::L4_return_fnew_pnt:4067  case Hexagon::L4_return_tnew_pt:4068  case Hexagon::L4_return_fnew_pt:4069    // [if ([!]p0[.new])] dealloc_return4070    SrcReg = MI.getOperand(0).getReg();4071    if (Hexagon::PredRegsRegClass.contains(SrcReg) && (Hexagon::P0 == SrcReg))4072      return HexagonII::HSIG_L2;4073    break;4074  //4075  // Group S1:4076  //4077  // memw(Rs+#u4:2) = Rt4078  // memb(Rs+#u4:0) = Rt4079  case Hexagon::S2_storeri_io:4080  case Hexagon::dup_S2_storeri_io:4081    // Special case this one from Group S2.4082    // memw(r29+#u5:2) = Rt4083    Src1Reg = MI.getOperand(0).getReg();4084    Src2Reg = MI.getOperand(2).getReg();4085    if (Hexagon::IntRegsRegClass.contains(Src1Reg) &&4086        isIntRegForSubInst(Src2Reg) &&4087        HRI.getStackRegister() == Src1Reg && MI.getOperand(1).isImm() &&4088        isShiftedUInt<5,2>(MI.getOperand(1).getImm()))4089      return HexagonII::HSIG_S2;4090    // memw(Rs+#u4:2) = Rt4091    if (isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg) &&4092        MI.getOperand(1).isImm() &&4093        isShiftedUInt<4,2>(MI.getOperand(1).getImm()))4094      return HexagonII::HSIG_S1;4095    break;4096  case Hexagon::S2_storerb_io:4097  case Hexagon::dup_S2_storerb_io:4098    // memb(Rs+#u4:0) = Rt4099    Src1Reg = MI.getOperand(0).getReg();4100    Src2Reg = MI.getOperand(2).getReg();4101    if (isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg) &&4102        MI.getOperand(1).isImm() && isUInt<4>(MI.getOperand(1).getImm()))4103      return HexagonII::HSIG_S1;4104    break;4105  //4106  // Group S2:4107  //4108  // memh(Rs+#u3:1) = Rt4109  // memw(r29+#u5:2) = Rt4110  // memd(r29+#s6:3) = Rtt4111  // memw(Rs+#u4:2) = #U14112  // memb(Rs+#u4) = #U14113  // allocframe(#u5:3)4114  case Hexagon::S2_storerh_io:4115  case Hexagon::dup_S2_storerh_io:4116    // memh(Rs+#u3:1) = Rt4117    Src1Reg = MI.getOperand(0).getReg();4118    Src2Reg = MI.getOperand(2).getReg();4119    if (isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg) &&4120        MI.getOperand(1).isImm() &&4121        isShiftedUInt<3,1>(MI.getOperand(1).getImm()))4122      return HexagonII::HSIG_S1;4123    break;4124  case Hexagon::S2_storerd_io:4125  case Hexagon::dup_S2_storerd_io:4126    // memd(r29+#s6:3) = Rtt4127    Src1Reg = MI.getOperand(0).getReg();4128    Src2Reg = MI.getOperand(2).getReg();4129    if (isDblRegForSubInst(Src2Reg, HRI) &&4130        Hexagon::IntRegsRegClass.contains(Src1Reg) &&4131        HRI.getStackRegister() == Src1Reg && MI.getOperand(1).isImm() &&4132        isShiftedInt<6,3>(MI.getOperand(1).getImm()))4133      return HexagonII::HSIG_S2;4134    break;4135  case Hexagon::S4_storeiri_io:4136  case Hexagon::dup_S4_storeiri_io:4137    // memw(Rs+#u4:2) = #U14138    Src1Reg = MI.getOperand(0).getReg();4139    if (isIntRegForSubInst(Src1Reg) && MI.getOperand(1).isImm() &&4140        isShiftedUInt<4,2>(MI.getOperand(1).getImm()) &&4141        MI.getOperand(2).isImm() && isUInt<1>(MI.getOperand(2).getImm()))4142      return HexagonII::HSIG_S2;4143    break;4144  case Hexagon::S4_storeirb_io:4145  case Hexagon::dup_S4_storeirb_io:4146    // memb(Rs+#u4) = #U14147    Src1Reg = MI.getOperand(0).getReg();4148    if (isIntRegForSubInst(Src1Reg) &&4149        MI.getOperand(1).isImm() && isUInt<4>(MI.getOperand(1).getImm()) &&4150        MI.getOperand(2).isImm() && isUInt<1>(MI.getOperand(2).getImm()))4151      return HexagonII::HSIG_S2;4152    break;4153  case Hexagon::S2_allocframe:4154  case Hexagon::dup_S2_allocframe:4155    if (MI.getOperand(2).isImm() &&4156        isShiftedUInt<5,3>(MI.getOperand(2).getImm()))4157      return HexagonII::HSIG_S1;4158    break;4159  //4160  // Group A:4161  //4162  // Rx = add(Rx,#s7)4163  // Rd = Rs4164  // Rd = #u64165  // Rd = #-14166  // if ([!]P0[.new]) Rd = #04167  // Rd = add(r29,#u6:2)4168  // Rx = add(Rx,Rs)4169  // P0 = cmp.eq(Rs,#u2)4170  // Rdd = combine(#0,Rs)4171  // Rdd = combine(Rs,#0)4172  // Rdd = combine(#u2,#U2)4173  // Rd = add(Rs,#1)4174  // Rd = add(Rs,#-1)4175  // Rd = sxth/sxtb/zxtb/zxth(Rs)4176  // Rd = and(Rs,#1)4177  case Hexagon::A2_addi:4178  case Hexagon::dup_A2_addi:4179    DstReg = MI.getOperand(0).getReg();4180    SrcReg = MI.getOperand(1).getReg();4181    if (isIntRegForSubInst(DstReg)) {4182      // Rd = add(r29,#u6:2)4183      if (Hexagon::IntRegsRegClass.contains(SrcReg) &&4184        HRI.getStackRegister() == SrcReg && MI.getOperand(2).isImm() &&4185        isShiftedUInt<6,2>(MI.getOperand(2).getImm()))4186        return HexagonII::HSIG_A;4187      // Rx = add(Rx,#s7)4188      if ((DstReg == SrcReg) && MI.getOperand(2).isImm() &&4189          isInt<7>(MI.getOperand(2).getImm()))4190        return HexagonII::HSIG_A;4191      // Rd = add(Rs,#1)4192      // Rd = add(Rs,#-1)4193      if (isIntRegForSubInst(SrcReg) && MI.getOperand(2).isImm() &&4194          ((MI.getOperand(2).getImm() == 1) ||4195          (MI.getOperand(2).getImm() == -1)))4196        return HexagonII::HSIG_A;4197    }4198    break;4199  case Hexagon::A2_add:4200  case Hexagon::dup_A2_add:4201    // Rx = add(Rx,Rs)4202    DstReg = MI.getOperand(0).getReg();4203    Src1Reg = MI.getOperand(1).getReg();4204    Src2Reg = MI.getOperand(2).getReg();4205    if (isIntRegForSubInst(DstReg) && (DstReg == Src1Reg) &&4206        isIntRegForSubInst(Src2Reg))4207      return HexagonII::HSIG_A;4208    break;4209  case Hexagon::A2_andir:4210  case Hexagon::dup_A2_andir:4211    // Same as zxtb.4212    // Rd16=and(Rs16,#255)4213    // Rd16=and(Rs16,#1)4214    DstReg = MI.getOperand(0).getReg();4215    SrcReg = MI.getOperand(1).getReg();4216    if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) &&4217        MI.getOperand(2).isImm() &&4218        ((MI.getOperand(2).getImm() == 1) ||4219        (MI.getOperand(2).getImm() == 255)))4220      return HexagonII::HSIG_A;4221    break;4222  case Hexagon::A2_tfr:4223  case Hexagon::dup_A2_tfr:4224    // Rd = Rs4225    DstReg = MI.getOperand(0).getReg();4226    SrcReg = MI.getOperand(1).getReg();4227    if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg))4228      return HexagonII::HSIG_A;4229    break;4230  case Hexagon::A2_tfrsi:4231  case Hexagon::dup_A2_tfrsi:4232    // Rd = #u64233    // Do not test for #u6 size since the const is getting extended4234    // regardless and compound could be formed.4235    // Rd = #-14236    DstReg = MI.getOperand(0).getReg();4237    if (isIntRegForSubInst(DstReg))4238      return HexagonII::HSIG_A;4239    break;4240  case Hexagon::C2_cmoveit:4241  case Hexagon::C2_cmovenewit:4242  case Hexagon::C2_cmoveif:4243  case Hexagon::C2_cmovenewif:4244  case Hexagon::dup_C2_cmoveit:4245  case Hexagon::dup_C2_cmovenewit:4246  case Hexagon::dup_C2_cmoveif:4247  case Hexagon::dup_C2_cmovenewif:4248    // if ([!]P0[.new]) Rd = #04249    // Actual form:4250    // %r16 = C2_cmovenewit internal %p0, 0, implicit undef %r16;4251    DstReg = MI.getOperand(0).getReg();4252    SrcReg = MI.getOperand(1).getReg();4253    if (isIntRegForSubInst(DstReg) &&4254        Hexagon::PredRegsRegClass.contains(SrcReg) && Hexagon::P0 == SrcReg &&4255        MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 0)4256      return HexagonII::HSIG_A;4257    break;4258  case Hexagon::C2_cmpeqi:4259  case Hexagon::dup_C2_cmpeqi:4260    // P0 = cmp.eq(Rs,#u2)4261    DstReg = MI.getOperand(0).getReg();4262    SrcReg = MI.getOperand(1).getReg();4263    if (Hexagon::PredRegsRegClass.contains(DstReg) &&4264        Hexagon::P0 == DstReg && isIntRegForSubInst(SrcReg) &&4265        MI.getOperand(2).isImm() && isUInt<2>(MI.getOperand(2).getImm()))4266      return HexagonII::HSIG_A;4267    break;4268  case Hexagon::A2_combineii:4269  case Hexagon::A4_combineii:4270  case Hexagon::dup_A2_combineii:4271  case Hexagon::dup_A4_combineii:4272    // Rdd = combine(#u2,#U2)4273    DstReg = MI.getOperand(0).getReg();4274    if (isDblRegForSubInst(DstReg, HRI) &&4275        ((MI.getOperand(1).isImm() && isUInt<2>(MI.getOperand(1).getImm())) ||4276        (MI.getOperand(1).isGlobal() &&4277        isUInt<2>(MI.getOperand(1).getOffset()))) &&4278        ((MI.getOperand(2).isImm() && isUInt<2>(MI.getOperand(2).getImm())) ||4279        (MI.getOperand(2).isGlobal() &&4280        isUInt<2>(MI.getOperand(2).getOffset()))))4281      return HexagonII::HSIG_A;4282    break;4283  case Hexagon::A4_combineri:4284  case Hexagon::dup_A4_combineri:4285    // Rdd = combine(Rs,#0)4286    // Rdd = combine(Rs,#0)4287    DstReg = MI.getOperand(0).getReg();4288    SrcReg = MI.getOperand(1).getReg();4289    if (isDblRegForSubInst(DstReg, HRI) && isIntRegForSubInst(SrcReg) &&4290        ((MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 0) ||4291        (MI.getOperand(2).isGlobal() && MI.getOperand(2).getOffset() == 0)))4292      return HexagonII::HSIG_A;4293    break;4294  case Hexagon::A4_combineir:4295  case Hexagon::dup_A4_combineir:4296    // Rdd = combine(#0,Rs)4297    DstReg = MI.getOperand(0).getReg();4298    SrcReg = MI.getOperand(2).getReg();4299    if (isDblRegForSubInst(DstReg, HRI) && isIntRegForSubInst(SrcReg) &&4300        ((MI.getOperand(1).isImm() && MI.getOperand(1).getImm() == 0) ||4301        (MI.getOperand(1).isGlobal() && MI.getOperand(1).getOffset() == 0)))4302      return HexagonII::HSIG_A;4303    break;4304  case Hexagon::A2_sxtb:4305  case Hexagon::A2_sxth:4306  case Hexagon::A2_zxtb:4307  case Hexagon::A2_zxth:4308  case Hexagon::dup_A2_sxtb:4309  case Hexagon::dup_A2_sxth:4310  case Hexagon::dup_A2_zxtb:4311  case Hexagon::dup_A2_zxth:4312    // Rd = sxth/sxtb/zxtb/zxth(Rs)4313    DstReg = MI.getOperand(0).getReg();4314    SrcReg = MI.getOperand(1).getReg();4315    if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg))4316      return HexagonII::HSIG_A;4317    break;4318  }4319 4320  return HexagonII::HSIG_None;4321}4322 4323short HexagonInstrInfo::getEquivalentHWInstr(const MachineInstr &MI) const {4324  return Hexagon::getRealHWInstr(MI.getOpcode(), Hexagon::InstrType_Real);4325}4326 4327unsigned HexagonInstrInfo::getInstrTimingClassLatency(4328      const InstrItineraryData *ItinData, const MachineInstr &MI) const {4329  // Default to one cycle for no itinerary. However, an "empty" itinerary may4330  // still have a MinLatency property, which getStageLatency checks.4331  if (!ItinData)4332    return getInstrLatency(ItinData, MI);4333 4334  if (MI.isTransient())4335    return 0;4336  return ItinData->getStageLatency(MI.getDesc().getSchedClass());4337}4338 4339/// getOperandLatency - Compute and return the use operand latency of a given4340/// pair of def and use.4341/// In most cases, the static scheduling itinerary was enough to determine the4342/// operand latency. But it may not be possible for instructions with variable4343/// number of defs / uses.4344///4345/// This is a raw interface to the itinerary that may be directly overridden by4346/// a target. Use computeOperandLatency to get the best estimate of latency.4347std::optional<unsigned> HexagonInstrInfo::getOperandLatency(4348    const InstrItineraryData *ItinData, const MachineInstr &DefMI,4349    unsigned DefIdx, const MachineInstr &UseMI, unsigned UseIdx) const {4350  const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();4351 4352  // Get DefIdx and UseIdx for super registers.4353  const MachineOperand &DefMO = DefMI.getOperand(DefIdx);4354 4355  if (DefMO.isReg() && DefMO.getReg().isPhysical()) {4356    if (DefMO.isImplicit()) {4357      for (MCPhysReg SR : HRI.superregs(DefMO.getReg())) {4358        int Idx = DefMI.findRegisterDefOperandIdx(SR, &HRI, false, false);4359        if (Idx != -1) {4360          DefIdx = Idx;4361          break;4362        }4363      }4364    }4365 4366    const MachineOperand &UseMO = UseMI.getOperand(UseIdx);4367    if (UseMO.isImplicit()) {4368      for (MCPhysReg SR : HRI.superregs(UseMO.getReg())) {4369        int Idx = UseMI.findRegisterUseOperandIdx(SR, &HRI, false);4370        if (Idx != -1) {4371          UseIdx = Idx;4372          break;4373        }4374      }4375    }4376  }4377 4378  std::optional<unsigned> Latency = TargetInstrInfo::getOperandLatency(4379      ItinData, DefMI, DefIdx, UseMI, UseIdx);4380  if (Latency == 0)4381    // We should never have 0 cycle latency between two instructions unless4382    // they can be packetized together. However, this decision can't be made4383    // here.4384    Latency = 1;4385  return Latency;4386}4387 4388// inverts the predication logic.4389// p -> NotP4390// NotP -> P4391bool HexagonInstrInfo::getInvertedPredSense(4392      SmallVectorImpl<MachineOperand> &Cond) const {4393  if (Cond.empty())4394    return false;4395  unsigned Opc = getInvertedPredicatedOpcode(Cond[0].getImm());4396  Cond[0].setImm(Opc);4397  return true;4398}4399 4400unsigned HexagonInstrInfo::getInvertedPredicatedOpcode(const int Opc) const {4401  int InvPredOpcode;4402  InvPredOpcode = isPredicatedTrue(Opc) ? Hexagon::getFalsePredOpcode(Opc)4403                                        : Hexagon::getTruePredOpcode(Opc);4404  if (InvPredOpcode >= 0) // Valid instruction with the inverted predicate.4405    return InvPredOpcode;4406 4407  llvm_unreachable("Unexpected predicated instruction");4408}4409 4410// Returns the max value that doesn't need to be extended.4411int HexagonInstrInfo::getMaxValue(const MachineInstr &MI) const {4412  const uint64_t F = MI.getDesc().TSFlags;4413  unsigned isSigned = (F >> HexagonII::ExtentSignedPos)4414                    & HexagonII::ExtentSignedMask;4415  unsigned bits =  (F >> HexagonII::ExtentBitsPos)4416                    & HexagonII::ExtentBitsMask;4417 4418  if (isSigned) // if value is signed4419    return ~(-1U << (bits - 1));4420  else4421    return ~(-1U << bits);4422}4423 4424 4425bool HexagonInstrInfo::isAddrModeWithOffset(const MachineInstr &MI) const {4426  switch (MI.getOpcode()) {4427  case Hexagon::L2_loadrbgp:4428  case Hexagon::L2_loadrdgp:4429  case Hexagon::L2_loadrhgp:4430  case Hexagon::L2_loadrigp:4431  case Hexagon::L2_loadrubgp:4432  case Hexagon::L2_loadruhgp:4433  case Hexagon::S2_storerbgp:4434  case Hexagon::S2_storerbnewgp:4435  case Hexagon::S2_storerhgp:4436  case Hexagon::S2_storerhnewgp:4437  case Hexagon::S2_storerigp:4438  case Hexagon::S2_storerinewgp:4439  case Hexagon::S2_storerdgp:4440  case Hexagon::S2_storerfgp:4441    return true;4442  }4443  const uint64_t F = MI.getDesc().TSFlags;4444  unsigned addrMode =4445    ((F >> HexagonII::AddrModePos) & HexagonII::AddrModeMask);4446  // Disallow any base+offset instruction. The assembler does not yet reorder4447  // based up any zero offset instruction.4448  return (addrMode == HexagonII::BaseRegOffset ||4449          addrMode == HexagonII::BaseImmOffset ||4450          addrMode == HexagonII::BaseLongOffset);4451}4452 4453bool HexagonInstrInfo::isPureSlot0(const MachineInstr &MI) const {4454  // Workaround for the Global Scheduler. Sometimes, it creates4455  // A4_ext as a Pseudo instruction and calls this function to see if4456  // it can be added to an existing bundle. Since the instruction doesn't4457  // belong to any BB yet, we can't use getUnits API.4458  if (MI.getOpcode() == Hexagon::A4_ext)4459    return false;4460 4461  unsigned FuncUnits = getUnits(MI);4462  return HexagonFUnits::isSlot0Only(FuncUnits);4463}4464 4465bool HexagonInstrInfo::isRestrictNoSlot1Store(const MachineInstr &MI) const {4466  const uint64_t F = MI.getDesc().TSFlags;4467  return ((F >> HexagonII::RestrictNoSlot1StorePos) &4468          HexagonII::RestrictNoSlot1StoreMask);4469}4470 4471void HexagonInstrInfo::changeDuplexOpcode(MachineBasicBlock::instr_iterator MII,4472                                          bool ToBigInstrs) const {4473  int Opcode = -1;4474  if (ToBigInstrs) { // To BigCore Instr.4475    // Check if the instruction can form a Duplex.4476    if (getDuplexCandidateGroup(*MII))4477      // Get the opcode marked "dup_*" tag.4478      Opcode = getDuplexOpcode(*MII, ToBigInstrs);4479  } else // To TinyCore Instr.4480    Opcode = getDuplexOpcode(*MII, ToBigInstrs);4481 4482  // Change the opcode of the instruction.4483  if (Opcode >= 0)4484    MII->setDesc(get(Opcode));4485}4486 4487// This function is used to translate instructions to facilitate generating4488// Duplexes on TinyCore.4489void HexagonInstrInfo::translateInstrsForDup(MachineFunction &MF,4490                                             bool ToBigInstrs) const {4491  for (auto &MB : MF)4492    for (MachineBasicBlock::instr_iterator Instr = MB.instr_begin(),4493                                           End = MB.instr_end();4494         Instr != End; ++Instr)4495      changeDuplexOpcode(Instr, ToBigInstrs);4496}4497 4498// This is a specialized form of above function.4499void HexagonInstrInfo::translateInstrsForDup(4500    MachineBasicBlock::instr_iterator MII, bool ToBigInstrs) const {4501  MachineBasicBlock *MBB = MII->getParent();4502  while ((MII != MBB->instr_end()) && MII->isInsideBundle()) {4503    changeDuplexOpcode(MII, ToBigInstrs);4504    ++MII;4505  }4506}4507 4508unsigned HexagonInstrInfo::getMemAccessSize(const MachineInstr &MI) const {4509  using namespace HexagonII;4510 4511  const uint64_t F = MI.getDesc().TSFlags;4512  unsigned S = (F >> MemAccessSizePos) & MemAccesSizeMask;4513  unsigned Size = getMemAccessSizeInBytes(MemAccessSize(S));4514  if (Size != 0)4515    return Size;4516  // Y2_dcfetchbo is special4517  if (MI.getOpcode() == Hexagon::Y2_dcfetchbo)4518    return HexagonII::DoubleWordAccess;4519 4520  // Handle vector access sizes.4521  const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();4522  switch (S) {4523    case HexagonII::HVXVectorAccess:4524      return HRI.getSpillSize(Hexagon::HvxVRRegClass);4525    default:4526      llvm_unreachable("Unexpected instruction");4527  }4528}4529 4530// Returns the min value that doesn't need to be extended.4531int HexagonInstrInfo::getMinValue(const MachineInstr &MI) const {4532  const uint64_t F = MI.getDesc().TSFlags;4533  unsigned isSigned = (F >> HexagonII::ExtentSignedPos)4534                    & HexagonII::ExtentSignedMask;4535  unsigned bits =  (F >> HexagonII::ExtentBitsPos)4536                    & HexagonII::ExtentBitsMask;4537 4538  if (isSigned) // if value is signed4539    return -1U << (bits - 1);4540  else4541    return 0;4542}4543 4544// Returns opcode of the non-extended equivalent instruction.4545short HexagonInstrInfo::getNonExtOpcode(const MachineInstr &MI) const {4546  // Check if the instruction has a register form that uses register in place4547  // of the extended operand, if so return that as the non-extended form.4548  short NonExtOpcode = Hexagon::getRegForm(MI.getOpcode());4549    if (NonExtOpcode >= 0)4550      return NonExtOpcode;4551 4552  if (MI.getDesc().mayLoad() || MI.getDesc().mayStore()) {4553    // Check addressing mode and retrieve non-ext equivalent instruction.4554    switch (getAddrMode(MI)) {4555    case HexagonII::Absolute:4556      return Hexagon::changeAddrMode_abs_io(MI.getOpcode());4557    case HexagonII::BaseImmOffset:4558      return Hexagon::changeAddrMode_io_rr(MI.getOpcode());4559    case HexagonII::BaseLongOffset:4560      return Hexagon::changeAddrMode_ur_rr(MI.getOpcode());4561 4562    default:4563      return -1;4564    }4565  }4566  return -1;4567}4568 4569bool HexagonInstrInfo::getPredReg(ArrayRef<MachineOperand> Cond,4570      Register &PredReg, unsigned &PredRegPos, unsigned &PredRegFlags) const {4571  if (Cond.empty())4572    return false;4573  assert(Cond.size() == 2);4574  if (isNewValueJump(Cond[0].getImm()) || Cond[1].isMBB()) {4575    LLVM_DEBUG(dbgs() << "No predregs for new-value jumps/endloop");4576    return false;4577  }4578  PredReg = Cond[1].getReg();4579  PredRegPos = 1;4580  // See IfConversion.cpp why we add RegState::Implicit | RegState::Undef4581  PredRegFlags = 0;4582  if (Cond[1].isImplicit())4583    PredRegFlags = RegState::Implicit;4584  if (Cond[1].isUndef())4585    PredRegFlags |= RegState::Undef;4586  return true;4587}4588 4589short HexagonInstrInfo::getPseudoInstrPair(const MachineInstr &MI) const {4590  return Hexagon::getRealHWInstr(MI.getOpcode(), Hexagon::InstrType_Pseudo);4591}4592 4593short HexagonInstrInfo::getRegForm(const MachineInstr &MI) const {4594  return Hexagon::getRegForm(MI.getOpcode());4595}4596 4597// Return the number of bytes required to encode the instruction.4598// Hexagon instructions are fixed length, 4 bytes, unless they4599// use a constant extender, which requires another 4 bytes.4600// For debug instructions and prolog labels, return 0.4601unsigned HexagonInstrInfo::getSize(const MachineInstr &MI) const {4602  if (MI.isDebugInstr() || MI.isPosition())4603    return 0;4604 4605  unsigned Size = MI.getDesc().getSize();4606  if (!Size)4607    // Assume the default insn size in case it cannot be determined4608    // for whatever reason.4609    Size = HEXAGON_INSTR_SIZE;4610 4611  if (isConstExtended(MI) || isExtended(MI))4612    Size += HEXAGON_INSTR_SIZE;4613 4614  // Try and compute number of instructions in asm.4615  if (BranchRelaxAsmLarge && MI.getOpcode() == Hexagon::INLINEASM) {4616    const MachineBasicBlock &MBB = *MI.getParent();4617    const MachineFunction *MF = MBB.getParent();4618    const MCAsmInfo *MAI = MF->getTarget().getMCAsmInfo();4619 4620    // Count the number of register definitions to find the asm string.4621    unsigned NumDefs = 0;4622    for (; MI.getOperand(NumDefs).isReg() && MI.getOperand(NumDefs).isDef();4623         ++NumDefs)4624      assert(NumDefs != MI.getNumOperands()-2 && "No asm string?");4625 4626    assert(MI.getOperand(NumDefs).isSymbol() && "No asm string?");4627    // Disassemble the AsmStr and approximate number of instructions.4628    const char *AsmStr = MI.getOperand(NumDefs).getSymbolName();4629    Size = getInlineAsmLength(AsmStr, *MAI);4630  }4631 4632  return Size;4633}4634 4635uint64_t HexagonInstrInfo::getType(const MachineInstr &MI) const {4636  const uint64_t F = MI.getDesc().TSFlags;4637  return (F >> HexagonII::TypePos) & HexagonII::TypeMask;4638}4639 4640InstrStage::FuncUnits HexagonInstrInfo::getUnits(const MachineInstr &MI) const {4641  const InstrItineraryData &II = *Subtarget.getInstrItineraryData();4642  const InstrStage &IS = *II.beginStage(MI.getDesc().getSchedClass());4643 4644  return IS.getUnits();4645}4646 4647// Calculate size of the basic block without debug instructions.4648unsigned HexagonInstrInfo::nonDbgBBSize(const MachineBasicBlock *BB) const {4649  return nonDbgMICount(BB->instr_begin(), BB->instr_end());4650}4651 4652unsigned HexagonInstrInfo::nonDbgBundleSize(4653      MachineBasicBlock::const_iterator BundleHead) const {4654  assert(BundleHead->isBundle() && "Not a bundle header");4655  auto MII = BundleHead.getInstrIterator();4656  // Skip the bundle header.4657  return nonDbgMICount(++MII, getBundleEnd(BundleHead.getInstrIterator()));4658}4659 4660/// immediateExtend - Changes the instruction in place to one using an immediate4661/// extender.4662void HexagonInstrInfo::immediateExtend(MachineInstr &MI) const {4663  assert((isExtendable(MI)||isConstExtended(MI)) &&4664                               "Instruction must be extendable");4665  // Find which operand is extendable.4666  short ExtOpNum = getCExtOpNum(MI);4667  MachineOperand &MO = MI.getOperand(ExtOpNum);4668  // This needs to be something we understand.4669  assert((MO.isMBB() || MO.isImm()) &&4670         "Branch with unknown extendable field type");4671  // Mark given operand as extended.4672  MO.addTargetFlag(HexagonII::HMOTF_ConstExtended);4673}4674 4675bool HexagonInstrInfo::invertAndChangeJumpTarget(4676      MachineInstr &MI, MachineBasicBlock *NewTarget) const {4677  LLVM_DEBUG(dbgs() << "\n[invertAndChangeJumpTarget] to "4678                    << printMBBReference(*NewTarget);4679             MI.dump(););4680  assert(MI.isBranch());4681  unsigned NewOpcode = getInvertedPredicatedOpcode(MI.getOpcode());4682  int TargetPos = MI.getNumOperands() - 1;4683  // In general branch target is the last operand,4684  // but some implicit defs added at the end might change it.4685  while ((TargetPos > -1) && !MI.getOperand(TargetPos).isMBB())4686    --TargetPos;4687  assert((TargetPos >= 0) && MI.getOperand(TargetPos).isMBB());4688  MI.getOperand(TargetPos).setMBB(NewTarget);4689  if (EnableBranchPrediction && isPredicatedNew(MI)) {4690    NewOpcode = reversePrediction(NewOpcode);4691  }4692  MI.setDesc(get(NewOpcode));4693  return true;4694}4695 4696void HexagonInstrInfo::genAllInsnTimingClasses(MachineFunction &MF) const {4697  /* +++ The code below is used to generate complete set of Hexagon Insn +++ */4698  MachineFunction::iterator A = MF.begin();4699  MachineBasicBlock &B = *A;4700  MachineBasicBlock::iterator I = B.begin();4701  DebugLoc DL = I->getDebugLoc();4702  MachineInstr *NewMI;4703 4704  for (unsigned insn = TargetOpcode::GENERIC_OP_END+1;4705       insn < Hexagon::INSTRUCTION_LIST_END; ++insn) {4706    NewMI = BuildMI(B, I, DL, get(insn));4707    LLVM_DEBUG(dbgs() << "\n"4708                      << getName(NewMI->getOpcode())4709                      << "  Class: " << NewMI->getDesc().getSchedClass());4710    NewMI->eraseFromParent();4711  }4712  /* --- The code above is used to generate complete set of Hexagon Insn --- */4713}4714 4715// inverts the predication logic.4716// p -> NotP4717// NotP -> P4718bool HexagonInstrInfo::reversePredSense(MachineInstr &MI) const {4719  LLVM_DEBUG(dbgs() << "\nTrying to reverse pred. sense of:"; MI.dump());4720  MI.setDesc(get(getInvertedPredicatedOpcode(MI.getOpcode())));4721  return true;4722}4723 4724// Reverse the branch prediction.4725unsigned HexagonInstrInfo::reversePrediction(unsigned Opcode) const {4726  int PredRevOpcode = -1;4727  if (isPredictedTaken(Opcode))4728    PredRevOpcode = Hexagon::notTakenBranchPrediction(Opcode);4729  else4730    PredRevOpcode = Hexagon::takenBranchPrediction(Opcode);4731  assert(PredRevOpcode > 0);4732  return PredRevOpcode;4733}4734 4735// TODO: Add more rigorous validation.4736bool HexagonInstrInfo::validateBranchCond(const ArrayRef<MachineOperand> &Cond)4737      const {4738  return Cond.empty() || (Cond[0].isImm() && (Cond.size() != 1));4739}4740 4741void HexagonInstrInfo::4742setBundleNoShuf(MachineBasicBlock::instr_iterator MIB) const {4743  assert(MIB->isBundle());4744  MachineOperand &Operand = MIB->getOperand(0);4745  if (Operand.isImm())4746    Operand.setImm(Operand.getImm() | memShufDisabledMask);4747  else4748    MIB->addOperand(MachineOperand::CreateImm(memShufDisabledMask));4749}4750 4751bool HexagonInstrInfo::getBundleNoShuf(const MachineInstr &MIB) const {4752  assert(MIB.isBundle());4753  const MachineOperand &Operand = MIB.getOperand(0);4754  return (Operand.isImm() && (Operand.getImm() & memShufDisabledMask) != 0);4755}4756 4757bool HexagonInstrInfo::isQFPMul(const MachineInstr *MI) const {4758  return (MI->getOpcode() == Hexagon::V6_vmpy_qf16_hf ||4759          MI->getOpcode() == Hexagon::V6_vmpy_qf16_mix_hf ||4760          MI->getOpcode() == Hexagon::V6_vmpy_qf32_hf ||4761          MI->getOpcode() == Hexagon::V6_vmpy_qf32_mix_hf ||4762          MI->getOpcode() == Hexagon::V6_vmpy_qf32_sf ||4763          MI->getOpcode() == Hexagon::V6_vmpy_qf16_mix_hf ||4764          MI->getOpcode() == Hexagon::V6_vmpy_qf16 ||4765          MI->getOpcode() == Hexagon::V6_vmpy_qf32_mix_hf ||4766          MI->getOpcode() == Hexagon::V6_vmpy_qf32_qf16 ||4767          MI->getOpcode() == Hexagon::V6_vmpy_qf32);4768}4769 4770// Addressing mode relations.4771short HexagonInstrInfo::changeAddrMode_abs_io(short Opc) const {4772  return Opc >= 0 ? Hexagon::changeAddrMode_abs_io(Opc) : Opc;4773}4774 4775short HexagonInstrInfo::changeAddrMode_io_abs(short Opc) const {4776  return Opc >= 0 ? Hexagon::changeAddrMode_io_abs(Opc) : Opc;4777}4778 4779short HexagonInstrInfo::changeAddrMode_io_pi(short Opc) const {4780  return Opc >= 0 ? Hexagon::changeAddrMode_io_pi(Opc) : Opc;4781}4782 4783short HexagonInstrInfo::changeAddrMode_io_rr(short Opc) const {4784  return Opc >= 0 ? Hexagon::changeAddrMode_io_rr(Opc) : Opc;4785}4786 4787short HexagonInstrInfo::changeAddrMode_pi_io(short Opc) const {4788  return Opc >= 0 ? Hexagon::changeAddrMode_pi_io(Opc) : Opc;4789}4790 4791short HexagonInstrInfo::changeAddrMode_rr_io(short Opc) const {4792  return Opc >= 0 ? Hexagon::changeAddrMode_rr_io(Opc) : Opc;4793}4794 4795short HexagonInstrInfo::changeAddrMode_rr_ur(short Opc) const {4796  return Opc >= 0 ? Hexagon::changeAddrMode_rr_ur(Opc) : Opc;4797}4798 4799short HexagonInstrInfo::changeAddrMode_ur_rr(short Opc) const {4800  return Opc >= 0 ? Hexagon::changeAddrMode_ur_rr(Opc) : Opc;4801}4802 4803MCInst HexagonInstrInfo::getNop() const {4804  static const MCInst Nop = MCInstBuilder(Hexagon::A2_nop);4805 4806  return MCInstBuilder(Hexagon::BUNDLE)4807    .addImm(0)4808    .addInst(&Nop);4809}4810