AArch64InstrInfo.h revision 8a1773694c6d9b1277647440583811ad3d85c6a4
16f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//===- AArch64InstrInfo.h - AArch64 Instruction Information -----*- C++ -*-===// 26f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// 36f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// The LLVM Compiler Infrastructure 46f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// 56f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// This file is distributed under the University of Illinois Open Source 66f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// License. See LICENSE.TXT for details. 76f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// 86f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//===----------------------------------------------------------------------===// 96f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// 106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// This file contains the AArch64 implementation of the TargetInstrInfo class. 116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// 126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//===----------------------------------------------------------------------===// 136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#ifndef LLVM_TARGET_AArch64INSTRINFO_H 156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define LLVM_TARGET_AArch64INSTRINFO_H 166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "AArch64.h" 186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "AArch64RegisterInfo.h" 196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "llvm/Target/TargetInstrInfo.h" 206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define GET_INSTRINFO_HEADER 226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "AArch64GenInstrInfo.inc" 236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgnamespace llvm { 256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgclass AArch64Subtarget; 276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgclass AArch64TargetMachine; 286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgclass AArch64InstrInfo : public AArch64GenInstrInfo { 306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Reserve bits in the MachineMemOperand target hint flags, starting at 1. 316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // They will be shifted into MOTargetHintStart when accessed. 326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org enum TargetMemOperandFlags { 336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org MOSuppressPair = 1 346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org }; 356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const AArch64RegisterInfo RI; 376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const AArch64Subtarget &Subtarget; 386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgpublic: 406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org explicit AArch64InstrInfo(const AArch64Subtarget &STI); 416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As 436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /// such, whenever a client has an instance of instruction info, it should 446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /// always be able to get register info as well (through this method). 456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const AArch64RegisterInfo &getRegisterInfo() const { return RI; } 466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org unsigned GetInstSizeInBytes(const MachineInstr *MI) const; 486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bool isAsCheapAsAMove(const MachineInstr *MI) const override; 506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bool isCoalescableExtInstr(const MachineInstr &MI, unsigned &SrcReg, 526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org unsigned &DstReg, unsigned &SubIdx) const override; 536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org unsigned isLoadFromStackSlot(const MachineInstr *MI, 556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int &FrameIndex) const override; 566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org unsigned isStoreToStackSlot(const MachineInstr *MI, 576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int &FrameIndex) const override; 586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /// Returns true if there is a shiftable register and that the shift value 606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /// is non-zero. 616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bool hasShiftedReg(const MachineInstr *MI) const; 626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /// Returns true if there is an extendable register and that the extending 646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /// value is non-zero. 656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bool hasExtendedReg(const MachineInstr *MI) const; 666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /// \brief Does this instruction set its full destination register to zero? 686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bool isGPRZero(const MachineInstr *MI) const; 696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /// \brief Does this instruction rename a GPR without modifying bits? 716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bool isGPRCopy(const MachineInstr *MI) const; 726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /// \brief Does this instruction rename an FPR without modifying bits? 746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bool isFPRCopy(const MachineInstr *MI) const; 756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /// Return true if this is load/store scales or extends its register offset. 776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /// This refers to scaling a dynamic index as opposed to scaled immediates. 786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /// MI should be a memory op that allows scaled addressing. 796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bool isScaledAddr(const MachineInstr *MI) const; 806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /// Return true if pairing the given load or store is hinted to be 826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /// unprofitable. 836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bool isLdStPairSuppressed(const MachineInstr *MI) const; 846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /// Hint that pairing the given load or store is unprofitable. 866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org void suppressLdStPair(MachineInstr *MI) const; 876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bool getLdStBaseRegImmOfs(MachineInstr *LdSt, unsigned &BaseReg, 896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org unsigned &Offset, 906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const TargetRegisterInfo *TRI) const override; 916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bool enableClusterLoads() const override { return true; } 936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bool shouldClusterLoads(MachineInstr *FirstLdSt, MachineInstr *SecondLdSt, 956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org unsigned NumLoads) const override; 966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bool shouldScheduleAdjacent(MachineInstr *First, 986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org MachineInstr *Second) const override; 996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org MachineInstr *emitFrameIndexDebugValue(MachineFunction &MF, int FrameIx, 1016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint64_t Offset, const MDNode *MDPtr, 1026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org DebugLoc DL) const; 1036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org void copyPhysRegTuple(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 1046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org DebugLoc DL, unsigned DestReg, unsigned SrcReg, 1056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bool KillSrc, unsigned Opcode, 1066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org llvm::ArrayRef<unsigned> Indices) const; 1076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 1086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org DebugLoc DL, unsigned DestReg, unsigned SrcReg, 1096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bool KillSrc) const override; 1106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org void storeRegToStackSlot(MachineBasicBlock &MBB, 1126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org MachineBasicBlock::iterator MBBI, unsigned SrcReg, 1136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bool isKill, int FrameIndex, 1146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const TargetRegisterClass *RC, 1156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const TargetRegisterInfo *TRI) const override; 1166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org void loadRegFromStackSlot(MachineBasicBlock &MBB, 1186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org MachineBasicBlock::iterator MBBI, unsigned DestReg, 1196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int FrameIndex, const TargetRegisterClass *RC, 1206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const TargetRegisterInfo *TRI) const override; 1216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org MachineInstr * 1236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI, 1246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const SmallVectorImpl<unsigned> &Ops, 1256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int FrameIndex) const override; 1266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, 1286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org MachineBasicBlock *&FBB, 1296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org SmallVectorImpl<MachineOperand> &Cond, 1306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bool AllowModify = false) const override; 1316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org unsigned RemoveBranch(MachineBasicBlock &MBB) const override; 1326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 1336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org MachineBasicBlock *FBB, 1346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const SmallVectorImpl<MachineOperand> &Cond, 1356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org DebugLoc DL) const override; 1366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bool 1376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override; 1386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bool canInsertSelect(const MachineBasicBlock &, 139 const SmallVectorImpl<MachineOperand> &Cond, unsigned, 140 unsigned, int &, int &, int &) const override; 141 void insertSelect(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, 142 DebugLoc DL, unsigned DstReg, 143 const SmallVectorImpl<MachineOperand> &Cond, 144 unsigned TrueReg, unsigned FalseReg) const override; 145 void getNoopForMachoTarget(MCInst &NopInst) const override; 146 147 /// analyzeCompare - For a comparison instruction, return the source registers 148 /// in SrcReg and SrcReg2, and the value it compares against in CmpValue. 149 /// Return true if the comparison instruction can be analyzed. 150 bool analyzeCompare(const MachineInstr *MI, unsigned &SrcReg, 151 unsigned &SrcReg2, int &CmpMask, 152 int &CmpValue) const override; 153 /// optimizeCompareInstr - Convert the instruction supplying the argument to 154 /// the comparison into one that sets the zero bit in the flags register. 155 bool optimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg, 156 unsigned SrcReg2, int CmpMask, int CmpValue, 157 const MachineRegisterInfo *MRI) const override; 158 159private: 160 void instantiateCondBranch(MachineBasicBlock &MBB, DebugLoc DL, 161 MachineBasicBlock *TBB, 162 const SmallVectorImpl<MachineOperand> &Cond) const; 163}; 164 165/// emitFrameOffset - Emit instructions as needed to set DestReg to SrcReg 166/// plus Offset. This is intended to be used from within the prolog/epilog 167/// insertion (PEI) pass, where a virtual scratch register may be allocated 168/// if necessary, to be replaced by the scavenger at the end of PEI. 169void emitFrameOffset(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 170 DebugLoc DL, unsigned DestReg, unsigned SrcReg, int Offset, 171 const TargetInstrInfo *TII, 172 MachineInstr::MIFlag = MachineInstr::NoFlags, 173 bool SetNZCV = false); 174 175/// rewriteAArch64FrameIndex - Rewrite MI to access 'Offset' bytes from the 176/// FP. Return false if the offset could not be handled directly in MI, and 177/// return the left-over portion by reference. 178bool rewriteAArch64FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, 179 unsigned FrameReg, int &Offset, 180 const AArch64InstrInfo *TII); 181 182/// \brief Use to report the frame offset status in isAArch64FrameOffsetLegal. 183enum AArch64FrameOffsetStatus { 184 AArch64FrameOffsetCannotUpdate = 0x0, ///< Offset cannot apply. 185 AArch64FrameOffsetIsLegal = 0x1, ///< Offset is legal. 186 AArch64FrameOffsetCanUpdate = 0x2 ///< Offset can apply, at least partly. 187}; 188 189/// \brief Check if the @p Offset is a valid frame offset for @p MI. 190/// The returned value reports the validity of the frame offset for @p MI. 191/// It uses the values defined by AArch64FrameOffsetStatus for that. 192/// If result == AArch64FrameOffsetCannotUpdate, @p MI cannot be updated to 193/// use an offset.eq 194/// If result & AArch64FrameOffsetIsLegal, @p Offset can completely be 195/// rewriten in @p MI. 196/// If result & AArch64FrameOffsetCanUpdate, @p Offset contains the 197/// amount that is off the limit of the legal offset. 198/// If set, @p OutUseUnscaledOp will contain the whether @p MI should be 199/// turned into an unscaled operator, which opcode is in @p OutUnscaledOp. 200/// If set, @p EmittableOffset contains the amount that can be set in @p MI 201/// (possibly with @p OutUnscaledOp if OutUseUnscaledOp is true) and that 202/// is a legal offset. 203int isAArch64FrameOffsetLegal(const MachineInstr &MI, int &Offset, 204 bool *OutUseUnscaledOp = nullptr, 205 unsigned *OutUnscaledOp = nullptr, 206 int *EmittableOffset = nullptr); 207 208static inline bool isUncondBranchOpcode(int Opc) { return Opc == AArch64::B; } 209 210static inline bool isCondBranchOpcode(int Opc) { 211 switch (Opc) { 212 case AArch64::Bcc: 213 case AArch64::CBZW: 214 case AArch64::CBZX: 215 case AArch64::CBNZW: 216 case AArch64::CBNZX: 217 case AArch64::TBZW: 218 case AArch64::TBZX: 219 case AArch64::TBNZW: 220 case AArch64::TBNZX: 221 return true; 222 default: 223 return false; 224 } 225} 226 227static inline bool isIndirectBranchOpcode(int Opc) { return Opc == AArch64::BR; } 228 229} // end namespace llvm 230 231#endif 232