1249259Sdim//===- AArch64InstrInfo.h - AArch64 Instruction Information -----*- C++ -*-===// 2249259Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6249259Sdim// 7249259Sdim//===----------------------------------------------------------------------===// 8249259Sdim// 9249259Sdim// This file contains the AArch64 implementation of the TargetInstrInfo class. 10249259Sdim// 11249259Sdim//===----------------------------------------------------------------------===// 12249259Sdim 13280031Sdim#ifndef LLVM_LIB_TARGET_AARCH64_AARCH64INSTRINFO_H 14280031Sdim#define LLVM_LIB_TARGET_AARCH64_AARCH64INSTRINFO_H 15249259Sdim 16276479Sdim#include "AArch64.h" 17276479Sdim#include "AArch64RegisterInfo.h" 18360784Sdim#include "AArch64StackOffset.h" 19353358Sdim#include "llvm/ADT/Optional.h" 20280031Sdim#include "llvm/CodeGen/MachineCombinerPattern.h" 21327952Sdim#include "llvm/CodeGen/TargetInstrInfo.h" 22249259Sdim 23249259Sdim#define GET_INSTRINFO_HEADER 24249259Sdim#include "AArch64GenInstrInfo.inc" 25249259Sdim 26249259Sdimnamespace llvm { 27249259Sdim 28249259Sdimclass AArch64Subtarget; 29276479Sdimclass AArch64TargetMachine; 30249259Sdim 31321369Sdimstatic const MachineMemOperand::Flags MOSuppressPair = 32321369Sdim MachineMemOperand::MOTargetFlag1; 33321369Sdimstatic const MachineMemOperand::Flags MOStridedAccess = 34321369Sdim MachineMemOperand::MOTargetFlag2; 35321369Sdim 36321369Sdim#define FALKOR_STRIDED_ACCESS_MD "falkor.strided.access" 37321369Sdim 38314564Sdimclass AArch64InstrInfo final : public AArch64GenInstrInfo { 39249259Sdim const AArch64RegisterInfo RI; 40249259Sdim const AArch64Subtarget &Subtarget; 41276479Sdim 42249259Sdimpublic: 43276479Sdim explicit AArch64InstrInfo(const AArch64Subtarget &STI); 44249259Sdim 45249259Sdim /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As 46249259Sdim /// such, whenever a client has an instance of instruction info, it should 47249259Sdim /// always be able to get register info as well (through this method). 48276479Sdim const AArch64RegisterInfo &getRegisterInfo() const { return RI; } 49249259Sdim 50314564Sdim unsigned getInstSizeInBytes(const MachineInstr &MI) const override; 51249259Sdim 52309124Sdim bool isAsCheapAsAMove(const MachineInstr &MI) const override; 53280031Sdim 54276479Sdim bool isCoalescableExtInstr(const MachineInstr &MI, unsigned &SrcReg, 55276479Sdim unsigned &DstReg, unsigned &SubIdx) const override; 56249259Sdim 57280031Sdim bool 58353358Sdim areMemAccessesTriviallyDisjoint(const MachineInstr &MIa, 59360784Sdim const MachineInstr &MIb) const override; 60280031Sdim 61309124Sdim unsigned isLoadFromStackSlot(const MachineInstr &MI, 62276479Sdim int &FrameIndex) const override; 63309124Sdim unsigned isStoreToStackSlot(const MachineInstr &MI, 64276479Sdim int &FrameIndex) const override; 65276479Sdim 66341825Sdim /// Does this instruction set its full destination register to zero? 67341825Sdim static bool isGPRZero(const MachineInstr &MI); 68276479Sdim 69341825Sdim /// Does this instruction rename a GPR without modifying bits? 70341825Sdim static bool isGPRCopy(const MachineInstr &MI); 71276479Sdim 72341825Sdim /// Does this instruction rename an FPR without modifying bits? 73341825Sdim static bool isFPRCopy(const MachineInstr &MI); 74276479Sdim 75276479Sdim /// Return true if pairing the given load or store is hinted to be 76276479Sdim /// unprofitable. 77341825Sdim static bool isLdStPairSuppressed(const MachineInstr &MI); 78276479Sdim 79321369Sdim /// Return true if the given load or store is a strided memory access. 80341825Sdim static bool isStridedAccess(const MachineInstr &MI); 81321369Sdim 82309124Sdim /// Return true if this is an unscaled load/store. 83341825Sdim static bool isUnscaledLdSt(unsigned Opc); 84341825Sdim static bool isUnscaledLdSt(MachineInstr &MI) { 85341825Sdim return isUnscaledLdSt(MI.getOpcode()); 86341825Sdim } 87309124Sdim 88353358Sdim /// Returns the unscaled load/store for the scaled load/store opcode, 89353358Sdim /// if there is a corresponding unscaled variant available. 90353358Sdim static Optional<unsigned> getUnscaledLdSt(unsigned Opc); 91353358Sdim 92360784Sdim /// Scaling factor for (scaled or unscaled) load or store. 93360784Sdim static int getMemScale(unsigned Opc); 94360784Sdim static int getMemScale(const MachineInstr &MI) { 95360784Sdim return getMemScale(MI.getOpcode()); 96360784Sdim } 97353358Sdim 98360784Sdim 99353358Sdim /// Returns the index for the immediate for a given instruction. 100353358Sdim static unsigned getLoadStoreImmIdx(unsigned Opc); 101353358Sdim 102341825Sdim /// Return true if pairing the given load or store may be paired with another. 103341825Sdim static bool isPairableLdStInst(const MachineInstr &MI); 104309124Sdim 105341825Sdim /// Return the opcode that set flags when possible. The caller is 106321369Sdim /// responsible for ensuring the opc has a flag setting equivalent. 107341825Sdim static unsigned convertToFlagSettingOpc(unsigned Opc, bool &Is64Bit); 108321369Sdim 109309124Sdim /// Return true if this is a load/store that can be potentially paired/merged. 110353358Sdim bool isCandidateToMergeOrPair(const MachineInstr &MI) const; 111309124Sdim 112276479Sdim /// Hint that pairing the given load or store is unprofitable. 113341825Sdim static void suppressLdStPair(MachineInstr &MI); 114276479Sdim 115353358Sdim bool getMemOperandWithOffset(const MachineInstr &MI, 116353358Sdim const MachineOperand *&BaseOp, 117344779Sdim int64_t &Offset, 118344779Sdim const TargetRegisterInfo *TRI) const override; 119276479Sdim 120353358Sdim bool getMemOperandWithOffsetWidth(const MachineInstr &MI, 121353358Sdim const MachineOperand *&BaseOp, 122344779Sdim int64_t &Offset, unsigned &Width, 123344779Sdim const TargetRegisterInfo *TRI) const; 124280031Sdim 125321369Sdim /// Return the immediate offset of the base register in a load/store \p LdSt. 126321369Sdim MachineOperand &getMemOpBaseRegImmOfsOffsetOperand(MachineInstr &LdSt) const; 127321369Sdim 128341825Sdim /// Returns true if opcode \p Opc is a memory operation. If it is, set 129321369Sdim /// \p Scale, \p Width, \p MinOffset, and \p MaxOffset accordingly. 130321369Sdim /// 131321369Sdim /// For unscaled instructions, \p Scale is set to 1. 132353358Sdim static bool getMemOpInfo(unsigned Opcode, unsigned &Scale, unsigned &Width, 133353358Sdim int64_t &MinOffset, int64_t &MaxOffset); 134321369Sdim 135353358Sdim bool shouldClusterMemOps(const MachineOperand &BaseOp1, 136353358Sdim const MachineOperand &BaseOp2, 137309124Sdim unsigned NumLoads) const override; 138276479Sdim 139276479Sdim void copyPhysRegTuple(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 140360784Sdim const DebugLoc &DL, MCRegister DestReg, 141360784Sdim MCRegister SrcReg, bool KillSrc, unsigned Opcode, 142276479Sdim llvm::ArrayRef<unsigned> Indices) const; 143344779Sdim void copyGPRRegTuple(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 144344779Sdim DebugLoc DL, unsigned DestReg, unsigned SrcReg, 145344779Sdim bool KillSrc, unsigned Opcode, unsigned ZeroReg, 146344779Sdim llvm::ArrayRef<unsigned> Indices) const; 147276479Sdim void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 148360784Sdim const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg, 149276479Sdim bool KillSrc) const override; 150276479Sdim 151249259Sdim void storeRegToStackSlot(MachineBasicBlock &MBB, 152276479Sdim MachineBasicBlock::iterator MBBI, unsigned SrcReg, 153276479Sdim bool isKill, int FrameIndex, 154249259Sdim const TargetRegisterClass *RC, 155276479Sdim const TargetRegisterInfo *TRI) const override; 156276479Sdim 157249259Sdim void loadRegFromStackSlot(MachineBasicBlock &MBB, 158276479Sdim MachineBasicBlock::iterator MBBI, unsigned DestReg, 159276479Sdim int FrameIndex, const TargetRegisterClass *RC, 160276479Sdim const TargetRegisterInfo *TRI) const override; 161249259Sdim 162314564Sdim // This tells target independent code that it is okay to pass instructions 163314564Sdim // with subreg operands to foldMemoryOperandImpl. 164314564Sdim bool isSubregFoldable() const override { return true; } 165314564Sdim 166280031Sdim using TargetInstrInfo::foldMemoryOperandImpl; 167309124Sdim MachineInstr * 168309124Sdim foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI, 169309124Sdim ArrayRef<unsigned> Ops, 170309124Sdim MachineBasicBlock::iterator InsertPt, int FrameIndex, 171353358Sdim LiveIntervals *LIS = nullptr, 172353358Sdim VirtRegMap *VRM = nullptr) const override; 173276479Sdim 174314564Sdim /// \returns true if a branch from an instruction with opcode \p BranchOpc 175314564Sdim /// bytes is capable of jumping to a position \p BrOffset bytes away. 176314564Sdim bool isBranchOffsetInRange(unsigned BranchOpc, 177314564Sdim int64_t BrOffset) const override; 178314564Sdim 179314564Sdim MachineBasicBlock *getBranchDestBlock(const MachineInstr &MI) const override; 180314564Sdim 181309124Sdim bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, 182249259Sdim MachineBasicBlock *&FBB, 183249259Sdim SmallVectorImpl<MachineOperand> &Cond, 184276479Sdim bool AllowModify = false) const override; 185314564Sdim unsigned removeBranch(MachineBasicBlock &MBB, 186314564Sdim int *BytesRemoved = nullptr) const override; 187314564Sdim unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 188288943Sdim MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond, 189314564Sdim const DebugLoc &DL, 190314564Sdim int *BytesAdded = nullptr) const override; 191276479Sdim bool 192314564Sdim reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override; 193288943Sdim bool canInsertSelect(const MachineBasicBlock &, ArrayRef<MachineOperand> Cond, 194288943Sdim unsigned, unsigned, int &, int &, int &) const override; 195276479Sdim void insertSelect(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, 196309124Sdim const DebugLoc &DL, unsigned DstReg, 197309124Sdim ArrayRef<MachineOperand> Cond, unsigned TrueReg, 198309124Sdim unsigned FalseReg) const override; 199321369Sdim void getNoop(MCInst &NopInst) const override; 200249259Sdim 201344779Sdim bool isSchedulingBoundary(const MachineInstr &MI, 202344779Sdim const MachineBasicBlock *MBB, 203344779Sdim const MachineFunction &MF) const override; 204344779Sdim 205276479Sdim /// analyzeCompare - For a comparison instruction, return the source registers 206276479Sdim /// in SrcReg and SrcReg2, and the value it compares against in CmpValue. 207276479Sdim /// Return true if the comparison instruction can be analyzed. 208309124Sdim bool analyzeCompare(const MachineInstr &MI, unsigned &SrcReg, 209276479Sdim unsigned &SrcReg2, int &CmpMask, 210276479Sdim int &CmpValue) const override; 211276479Sdim /// optimizeCompareInstr - Convert the instruction supplying the argument to 212276479Sdim /// the comparison into one that sets the zero bit in the flags register. 213309124Sdim bool optimizeCompareInstr(MachineInstr &CmpInstr, unsigned SrcReg, 214276479Sdim unsigned SrcReg2, int CmpMask, int CmpValue, 215276479Sdim const MachineRegisterInfo *MRI) const override; 216309124Sdim bool optimizeCondBranch(MachineInstr &MI) const override; 217309124Sdim 218309124Sdim /// Return true when a code sequence can improve throughput. It 219309124Sdim /// should be called only for instructions in loops. 220309124Sdim /// \param Pattern - combiner pattern 221309124Sdim bool isThroughputPattern(MachineCombinerPattern Pattern) const override; 222288943Sdim /// Return true when there is potentially a faster code sequence 223321369Sdim /// for an instruction chain ending in ``Root``. All potential patterns are 224321369Sdim /// listed in the ``Patterns`` array. 225327952Sdim bool getMachineCombinerPatterns( 226327952Sdim MachineInstr &Root, 227327952Sdim SmallVectorImpl<MachineCombinerPattern> &Patterns) const override; 228296417Sdim /// Return true when Inst is associative and commutative so that it can be 229296417Sdim /// reassociated. 230296417Sdim bool isAssociativeAndCommutative(const MachineInstr &Inst) const override; 231288943Sdim /// When getMachineCombinerPatterns() finds patterns, this function generates 232288943Sdim /// the instructions that could replace the original code sequence 233280031Sdim void genAlternativeCodeSequence( 234296417Sdim MachineInstr &Root, MachineCombinerPattern Pattern, 235280031Sdim SmallVectorImpl<MachineInstr *> &InsInstrs, 236280031Sdim SmallVectorImpl<MachineInstr *> &DelInstrs, 237280031Sdim DenseMap<unsigned, unsigned> &InstrIdxForVirtReg) const override; 238309124Sdim /// AArch64 supports MachineCombiner. 239280031Sdim bool useMachineCombiner() const override; 240280031Sdim 241309124Sdim bool expandPostRAPseudo(MachineInstr &MI) const override; 242296417Sdim 243296417Sdim std::pair<unsigned, unsigned> 244296417Sdim decomposeMachineOperandsTargetFlags(unsigned TF) const override; 245296417Sdim ArrayRef<std::pair<unsigned, const char *>> 246296417Sdim getSerializableDirectMachineOperandTargetFlags() const override; 247296417Sdim ArrayRef<std::pair<unsigned, const char *>> 248296417Sdim getSerializableBitmaskMachineOperandTargetFlags() const override; 249321369Sdim ArrayRef<std::pair<MachineMemOperand::Flags, const char *>> 250321369Sdim getSerializableMachineMemOperandTargetFlags() const override; 251296417Sdim 252327952Sdim bool isFunctionSafeToOutlineFrom(MachineFunction &MF, 253327952Sdim bool OutlineFromLinkOnceODRs) const override; 254341825Sdim outliner::OutlinedFunction getOutliningCandidateInfo( 255341825Sdim std::vector<outliner::Candidate> &RepeatedSequenceLocs) const override; 256341825Sdim outliner::InstrType 257341825Sdim getOutliningType(MachineBasicBlock::iterator &MIT, unsigned Flags) const override; 258344779Sdim bool isMBBSafeToOutlineFrom(MachineBasicBlock &MBB, 259344779Sdim unsigned &Flags) const override; 260341825Sdim void buildOutlinedFrame(MachineBasicBlock &MBB, MachineFunction &MF, 261341825Sdim const outliner::OutlinedFunction &OF) const override; 262321369Sdim MachineBasicBlock::iterator 263321369Sdim insertOutlinedCall(Module &M, MachineBasicBlock &MBB, 264327952Sdim MachineBasicBlock::iterator &It, MachineFunction &MF, 265341825Sdim const outliner::Candidate &C) const override; 266341825Sdim bool shouldOutlineFromFunctionByDefault(MachineFunction &MF) const override; 267321369Sdim /// Returns true if the instruction has a shift by immediate that can be 268321369Sdim /// executed in one cycle less. 269344779Sdim static bool isFalkorShiftExtFast(const MachineInstr &MI); 270344779Sdim /// Return true if the instructions is a SEH instruciton used for unwinding 271344779Sdim /// on Windows. 272344779Sdim static bool isSEHInstruction(const MachineInstr &MI); 273327952Sdim 274360784Sdim Optional<RegImmPair> isAddImmediate(const MachineInstr &MI, 275360784Sdim Register Reg) const override; 276360784Sdim 277360784Sdim Optional<ParamLoadedValue> describeLoadedValue(const MachineInstr &MI, 278360784Sdim Register Reg) const override; 279360784Sdim 280344779Sdim#define GET_INSTRINFO_HELPER_DECLS 281344779Sdim#include "AArch64GenInstrInfo.inc" 282344779Sdim 283353358Sdimprotected: 284360784Sdim /// If the specific machine instruction is an instruction that moves/copies 285360784Sdim /// value from one register to another register return destination and source 286360784Sdim /// registers as machine operands. 287360784Sdim Optional<DestSourcePair> 288360784Sdim isCopyInstrImpl(const MachineInstr &MI) const override; 289353358Sdim 290276479Sdimprivate: 291341825Sdim /// Sets the offsets on outlined instructions in \p MBB which use SP 292321369Sdim /// so that they will be valid post-outlining. 293321369Sdim /// 294321369Sdim /// \param MBB A \p MachineBasicBlock in an outlined function. 295321369Sdim void fixupPostOutline(MachineBasicBlock &MBB) const; 296321369Sdim 297309124Sdim void instantiateCondBranch(MachineBasicBlock &MBB, const DebugLoc &DL, 298276479Sdim MachineBasicBlock *TBB, 299288943Sdim ArrayRef<MachineOperand> Cond) const; 300309124Sdim bool substituteCmpToZero(MachineInstr &CmpInstr, unsigned SrcReg, 301309124Sdim const MachineRegisterInfo *MRI) const; 302341825Sdim 303341825Sdim /// Returns an unused general-purpose register which can be used for 304341825Sdim /// constructing an outlined call if one exists. Returns 0 otherwise. 305341825Sdim unsigned findRegisterToSaveLRTo(const outliner::Candidate &C) const; 306276479Sdim}; 307249259Sdim 308276479Sdim/// emitFrameOffset - Emit instructions as needed to set DestReg to SrcReg 309276479Sdim/// plus Offset. This is intended to be used from within the prolog/epilog 310276479Sdim/// insertion (PEI) pass, where a virtual scratch register may be allocated 311276479Sdim/// if necessary, to be replaced by the scavenger at the end of PEI. 312276479Sdimvoid emitFrameOffset(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 313309124Sdim const DebugLoc &DL, unsigned DestReg, unsigned SrcReg, 314360784Sdim StackOffset Offset, const TargetInstrInfo *TII, 315276479Sdim MachineInstr::MIFlag = MachineInstr::NoFlags, 316353358Sdim bool SetNZCV = false, bool NeedsWinCFI = false, 317353358Sdim bool *HasWinCFI = nullptr); 318249259Sdim 319276479Sdim/// rewriteAArch64FrameIndex - Rewrite MI to access 'Offset' bytes from the 320276479Sdim/// FP. Return false if the offset could not be handled directly in MI, and 321276479Sdim/// return the left-over portion by reference. 322276479Sdimbool rewriteAArch64FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, 323360784Sdim unsigned FrameReg, StackOffset &Offset, 324327952Sdim const AArch64InstrInfo *TII); 325249259Sdim 326341825Sdim/// Use to report the frame offset status in isAArch64FrameOffsetLegal. 327276479Sdimenum AArch64FrameOffsetStatus { 328276479Sdim AArch64FrameOffsetCannotUpdate = 0x0, ///< Offset cannot apply. 329276479Sdim AArch64FrameOffsetIsLegal = 0x1, ///< Offset is legal. 330276479Sdim AArch64FrameOffsetCanUpdate = 0x2 ///< Offset can apply, at least partly. 331249259Sdim}; 332249259Sdim 333341825Sdim/// Check if the @p Offset is a valid frame offset for @p MI. 334276479Sdim/// The returned value reports the validity of the frame offset for @p MI. 335276479Sdim/// It uses the values defined by AArch64FrameOffsetStatus for that. 336276479Sdim/// If result == AArch64FrameOffsetCannotUpdate, @p MI cannot be updated to 337276479Sdim/// use an offset.eq 338276479Sdim/// If result & AArch64FrameOffsetIsLegal, @p Offset can completely be 339321369Sdim/// rewritten in @p MI. 340276479Sdim/// If result & AArch64FrameOffsetCanUpdate, @p Offset contains the 341276479Sdim/// amount that is off the limit of the legal offset. 342276479Sdim/// If set, @p OutUseUnscaledOp will contain the whether @p MI should be 343276479Sdim/// turned into an unscaled operator, which opcode is in @p OutUnscaledOp. 344276479Sdim/// If set, @p EmittableOffset contains the amount that can be set in @p MI 345276479Sdim/// (possibly with @p OutUnscaledOp if OutUseUnscaledOp is true) and that 346276479Sdim/// is a legal offset. 347360784Sdimint isAArch64FrameOffsetLegal(const MachineInstr &MI, StackOffset &Offset, 348327952Sdim bool *OutUseUnscaledOp = nullptr, 349327952Sdim unsigned *OutUnscaledOp = nullptr, 350360784Sdim int64_t *EmittableOffset = nullptr); 351249259Sdim 352276479Sdimstatic inline bool isUncondBranchOpcode(int Opc) { return Opc == AArch64::B; } 353249259Sdim 354276479Sdimstatic inline bool isCondBranchOpcode(int Opc) { 355276479Sdim switch (Opc) { 356276479Sdim case AArch64::Bcc: 357276479Sdim case AArch64::CBZW: 358276479Sdim case AArch64::CBZX: 359276479Sdim case AArch64::CBNZW: 360276479Sdim case AArch64::CBNZX: 361276479Sdim case AArch64::TBZW: 362276479Sdim case AArch64::TBZX: 363276479Sdim case AArch64::TBNZW: 364276479Sdim case AArch64::TBNZX: 365276479Sdim return true; 366276479Sdim default: 367276479Sdim return false; 368276479Sdim } 369276479Sdim} 370249259Sdim 371327952Sdimstatic inline bool isIndirectBranchOpcode(int Opc) { 372327952Sdim return Opc == AArch64::BR; 373327952Sdim} 374249259Sdim 375341825Sdim// struct TSFlags { 376341825Sdim#define TSFLAG_ELEMENT_SIZE_TYPE(X) (X) // 3-bits 377341825Sdim#define TSFLAG_DESTRUCTIVE_INST_TYPE(X) ((X) << 3) // 1-bit 378341825Sdim// } 379341825Sdim 380341825Sdimnamespace AArch64 { 381341825Sdim 382341825Sdimenum ElementSizeType { 383341825Sdim ElementSizeMask = TSFLAG_ELEMENT_SIZE_TYPE(0x7), 384341825Sdim ElementSizeNone = TSFLAG_ELEMENT_SIZE_TYPE(0x0), 385341825Sdim ElementSizeB = TSFLAG_ELEMENT_SIZE_TYPE(0x1), 386341825Sdim ElementSizeH = TSFLAG_ELEMENT_SIZE_TYPE(0x2), 387341825Sdim ElementSizeS = TSFLAG_ELEMENT_SIZE_TYPE(0x3), 388341825Sdim ElementSizeD = TSFLAG_ELEMENT_SIZE_TYPE(0x4), 389341825Sdim}; 390341825Sdim 391341825Sdimenum DestructiveInstType { 392341825Sdim DestructiveInstTypeMask = TSFLAG_DESTRUCTIVE_INST_TYPE(0x1), 393341825Sdim NotDestructive = TSFLAG_DESTRUCTIVE_INST_TYPE(0x0), 394341825Sdim Destructive = TSFLAG_DESTRUCTIVE_INST_TYPE(0x1), 395341825Sdim}; 396341825Sdim 397341825Sdim#undef TSFLAG_ELEMENT_SIZE_TYPE 398341825Sdim#undef TSFLAG_DESTRUCTIVE_INST_TYPE 399341825Sdim} 400341825Sdim 401276479Sdim} // end namespace llvm 402249259Sdim 403249259Sdim#endif 404