ARMBaseInstrInfo.h revision dce4a407a24b04eebc6a376f8e62b41aaa7b071f
156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks//===-- ARMBaseInstrInfo.h - ARM Base Instruction Information ---*- C++ -*-===// 256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// 356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// The LLVM Compiler Infrastructure 456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// 556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// This file is distributed under the University of Illinois Open Source 656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// License. See LICENSE.TXT for details. 756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// 856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks//===----------------------------------------------------------------------===// 956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// 1056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// This file contains the Base ARM implementation of the TargetInstrInfo class. 117df30109963092559d3760c0661a020f9daf1030The Android Open Source Project// 127df30109963092559d3760c0661a020f9daf1030The Android Open Source Project//===----------------------------------------------------------------------===// 137df30109963092559d3760c0661a020f9daf1030The Android Open Source Project 147df30109963092559d3760c0661a020f9daf1030The Android Open Source Project#ifndef ARMBASEINSTRUCTIONINFO_H 157df30109963092559d3760c0661a020f9daf1030The Android Open Source Project#define ARMBASEINSTRUCTIONINFO_H 167df30109963092559d3760c0661a020f9daf1030The Android Open Source Project 177df30109963092559d3760c0661a020f9daf1030The Android Open Source Project#include "MCTargetDesc/ARMBaseInfo.h" 187df30109963092559d3760c0661a020f9daf1030The Android Open Source Project#include "llvm/ADT/DenseMap.h" 197df30109963092559d3760c0661a020f9daf1030The Android Open Source Project#include "llvm/ADT/SmallSet.h" 207df30109963092559d3760c0661a020f9daf1030The Android Open Source Project#include "llvm/CodeGen/MachineInstrBuilder.h" 217df30109963092559d3760c0661a020f9daf1030The Android Open Source Project#include "llvm/Target/TargetInstrInfo.h" 227df30109963092559d3760c0661a020f9daf1030The Android Open Source Project 2356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#define GET_INSTRINFO_HEADER 2456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#include "ARMGenInstrInfo.inc" 2556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 2656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksnamespace llvm { 2756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks class ARMSubtarget; 2856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks class ARMBaseRegisterInfo; 2956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 3056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksclass ARMBaseInstrInfo : public ARMGenInstrInfo { 3156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks const ARMSubtarget &Subtarget; 3256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 3356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksprotected: 3456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks // Can be only subclassed. 3556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks explicit ARMBaseInstrInfo(const ARMSubtarget &STI); 3656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 3756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparkspublic: 3856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks // Return whether the target has an explicit NOP encoding. 3956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks bool hasNOP() const; 4056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 4156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks // Return the non-pre/post incrementing version of 'Opc'. Return 0 4256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks // if there is not such an opcode. 4356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks virtual unsigned getUnindexedOpcode(unsigned Opc) const =0; 4456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 4556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks MachineInstr *convertToThreeAddress(MachineFunction::iterator &MFI, 4656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks MachineBasicBlock::iterator &MBBI, 4756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks LiveVariables *LV) const override; 4856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 4956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks virtual const ARMBaseRegisterInfo &getRegisterInfo() const = 0; 5056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks const ARMSubtarget &getSubtarget() const { return Subtarget; } 5156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 5256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks ScheduleHazardRecognizer * 5356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks CreateTargetHazardRecognizer(const TargetMachine *TM, 5456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks const ScheduleDAG *DAG) const override; 5556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 5656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks ScheduleHazardRecognizer * 5756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II, 5856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks const ScheduleDAG *DAG) const override; 5956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 6056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks // Branch analysis. 6156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, 6256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks MachineBasicBlock *&FBB, 6356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks SmallVectorImpl<MachineOperand> &Cond, 6456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks bool AllowModify = false) const override; 6556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks unsigned RemoveBranch(MachineBasicBlock &MBB) const override; 6656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 6756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks MachineBasicBlock *FBB, 6856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks const SmallVectorImpl<MachineOperand> &Cond, 6956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks DebugLoc DL) const override; 7056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 7156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks bool 7256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override; 7356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 7456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks // Predication support. 7556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks bool isPredicated(const MachineInstr *MI) const override; 7656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 7756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks ARMCC::CondCodes getPredicate(const MachineInstr *MI) const { 7856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks int PIdx = MI->findFirstPredOperandIdx(); 7956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks return PIdx != -1 ? (ARMCC::CondCodes)MI->getOperand(PIdx).getImm() 8056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks : ARMCC::AL; 8156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks } 8256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 8356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks bool PredicateInstruction(MachineInstr *MI, 8456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks const SmallVectorImpl<MachineOperand> &Pred) const override; 8556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 8656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks bool SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1, 8756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks const SmallVectorImpl<MachineOperand> &Pred2) const override; 8856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 8956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks bool DefinesPredicate(MachineInstr *MI, 9056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks std::vector<MachineOperand> &Pred) const override; 9156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 9256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks bool isPredicable(MachineInstr *MI) const override; 9356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 9456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks /// GetInstSize - Returns the size of the specified MachineInstr. 9556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks /// 9656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks virtual unsigned GetInstSizeInBytes(const MachineInstr* MI) const; 9756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 9856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks unsigned isLoadFromStackSlot(const MachineInstr *MI, 9956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks int &FrameIndex) const override; 10056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks unsigned isStoreToStackSlot(const MachineInstr *MI, 10156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks int &FrameIndex) const override; 10256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks unsigned isLoadFromStackSlotPostFE(const MachineInstr *MI, 10356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks int &FrameIndex) const override; 10456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks unsigned isStoreToStackSlotPostFE(const MachineInstr *MI, 10556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks int &FrameIndex) const override; 10656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 10756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 10856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks DebugLoc DL, unsigned DestReg, unsigned SrcReg, 10956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks bool KillSrc) const override; 11056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 11156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks void storeRegToStackSlot(MachineBasicBlock &MBB, 11256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks MachineBasicBlock::iterator MBBI, 11356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks unsigned SrcReg, bool isKill, int FrameIndex, 11456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks const TargetRegisterClass *RC, 11556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks const TargetRegisterInfo *TRI) const override; 11656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 11756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks void loadRegFromStackSlot(MachineBasicBlock &MBB, 11856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks MachineBasicBlock::iterator MBBI, 11956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks unsigned DestReg, int FrameIndex, 12056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks const TargetRegisterClass *RC, 12156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks const TargetRegisterInfo *TRI) const override; 12256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 12356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks bool expandPostRAPseudo(MachineBasicBlock::iterator MI) const override; 12456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 12556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, 12656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks unsigned DestReg, unsigned SubIdx, 12756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks const MachineInstr *Orig, 12856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks const TargetRegisterInfo &TRI) const override; 12956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 13056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks MachineInstr *duplicate(MachineInstr *Orig, 13156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks MachineFunction &MF) const override; 13256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 13356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks MachineInstr *commuteInstruction(MachineInstr*, 13456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks bool=false) const override; 13556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 13656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks const MachineInstrBuilder &AddDReg(MachineInstrBuilder &MIB, unsigned Reg, 13756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks unsigned SubIdx, unsigned State, 13856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks const TargetRegisterInfo *TRI) const; 13956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 14056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks bool produceSameValue(const MachineInstr *MI0, const MachineInstr *MI1, 14156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks const MachineRegisterInfo *MRI) const override; 14256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 14356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks /// areLoadsFromSameBasePtr - This is used by the pre-regalloc scheduler to 14456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks /// determine if two loads are loading from the same base address. It should 14556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks /// only return true if the base pointers are the same and the only 14656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks /// differences between the two addresses is the offset. It also returns the 14756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks /// offsets by reference. 14856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2, int64_t &Offset1, 14956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks int64_t &Offset2) const override; 15056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks 15156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks /// shouldScheduleLoadsNear - This is a used by the pre-regalloc scheduler to 15256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks /// determine (in conjunction with areLoadsFromSameBasePtr) if two loads 15356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks /// should be scheduled togther. On some targets if two loads are loading from 15456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks /// addresses in the same cache line, it's better if they are scheduled 15556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks /// together. This function takes two integers that represent the load offsets 15656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks /// from the common base address. It returns true if it decides it's desirable 15756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks /// to schedule the two loads together. "NumLoads" is the number of loads that 158 /// have already been scheduled after Load1. 159 bool shouldScheduleLoadsNear(SDNode *Load1, SDNode *Load2, 160 int64_t Offset1, int64_t Offset2, 161 unsigned NumLoads) const override; 162 163 bool isSchedulingBoundary(const MachineInstr *MI, 164 const MachineBasicBlock *MBB, 165 const MachineFunction &MF) const override; 166 167 bool isProfitableToIfCvt(MachineBasicBlock &MBB, 168 unsigned NumCycles, unsigned ExtraPredCycles, 169 const BranchProbability &Probability) const override; 170 171 bool isProfitableToIfCvt(MachineBasicBlock &TMBB, unsigned NumT, 172 unsigned ExtraT, MachineBasicBlock &FMBB, 173 unsigned NumF, unsigned ExtraF, 174 const BranchProbability &Probability) const override; 175 176 bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, 177 const BranchProbability &Probability) const override { 178 return NumCycles == 1; 179 } 180 181 bool isProfitableToUnpredicate(MachineBasicBlock &TMBB, 182 MachineBasicBlock &FMBB) const override; 183 184 /// analyzeCompare - For a comparison instruction, return the source registers 185 /// in SrcReg and SrcReg2 if having two register operands, and the value it 186 /// compares against in CmpValue. Return true if the comparison instruction 187 /// can be analyzed. 188 bool analyzeCompare(const MachineInstr *MI, unsigned &SrcReg, 189 unsigned &SrcReg2, int &CmpMask, 190 int &CmpValue) const override; 191 192 /// optimizeCompareInstr - Convert the instruction to set the zero flag so 193 /// that we can remove a "comparison with zero"; Remove a redundant CMP 194 /// instruction if the flags can be updated in the same way by an earlier 195 /// instruction such as SUB. 196 bool optimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg, 197 unsigned SrcReg2, int CmpMask, int CmpValue, 198 const MachineRegisterInfo *MRI) const override; 199 200 bool analyzeSelect(const MachineInstr *MI, 201 SmallVectorImpl<MachineOperand> &Cond, 202 unsigned &TrueOp, unsigned &FalseOp, 203 bool &Optimizable) const override; 204 205 MachineInstr *optimizeSelect(MachineInstr *MI, bool) const override; 206 207 /// FoldImmediate - 'Reg' is known to be defined by a move immediate 208 /// instruction, try to fold the immediate into the use instruction. 209 bool FoldImmediate(MachineInstr *UseMI, MachineInstr *DefMI, 210 unsigned Reg, MachineRegisterInfo *MRI) const override; 211 212 unsigned getNumMicroOps(const InstrItineraryData *ItinData, 213 const MachineInstr *MI) const override; 214 215 int getOperandLatency(const InstrItineraryData *ItinData, 216 const MachineInstr *DefMI, unsigned DefIdx, 217 const MachineInstr *UseMI, 218 unsigned UseIdx) const override; 219 int getOperandLatency(const InstrItineraryData *ItinData, 220 SDNode *DefNode, unsigned DefIdx, 221 SDNode *UseNode, unsigned UseIdx) const override; 222 223 /// VFP/NEON execution domains. 224 std::pair<uint16_t, uint16_t> 225 getExecutionDomain(const MachineInstr *MI) const override; 226 void setExecutionDomain(MachineInstr *MI, unsigned Domain) const override; 227 228 unsigned getPartialRegUpdateClearance(const MachineInstr*, unsigned, 229 const TargetRegisterInfo*) const override; 230 void breakPartialRegDependency(MachineBasicBlock::iterator, unsigned, 231 const TargetRegisterInfo *TRI) const override; 232 /// Get the number of addresses by LDM or VLDM or zero for unknown. 233 unsigned getNumLDMAddresses(const MachineInstr *MI) const; 234 235private: 236 unsigned getInstBundleLength(const MachineInstr *MI) const; 237 238 int getVLDMDefCycle(const InstrItineraryData *ItinData, 239 const MCInstrDesc &DefMCID, 240 unsigned DefClass, 241 unsigned DefIdx, unsigned DefAlign) const; 242 int getLDMDefCycle(const InstrItineraryData *ItinData, 243 const MCInstrDesc &DefMCID, 244 unsigned DefClass, 245 unsigned DefIdx, unsigned DefAlign) const; 246 int getVSTMUseCycle(const InstrItineraryData *ItinData, 247 const MCInstrDesc &UseMCID, 248 unsigned UseClass, 249 unsigned UseIdx, unsigned UseAlign) const; 250 int getSTMUseCycle(const InstrItineraryData *ItinData, 251 const MCInstrDesc &UseMCID, 252 unsigned UseClass, 253 unsigned UseIdx, unsigned UseAlign) const; 254 int getOperandLatency(const InstrItineraryData *ItinData, 255 const MCInstrDesc &DefMCID, 256 unsigned DefIdx, unsigned DefAlign, 257 const MCInstrDesc &UseMCID, 258 unsigned UseIdx, unsigned UseAlign) const; 259 260 unsigned getPredicationCost(const MachineInstr *MI) const override; 261 262 unsigned getInstrLatency(const InstrItineraryData *ItinData, 263 const MachineInstr *MI, 264 unsigned *PredCost = nullptr) const override; 265 266 int getInstrLatency(const InstrItineraryData *ItinData, 267 SDNode *Node) const override; 268 269 bool hasHighOperandLatency(const InstrItineraryData *ItinData, 270 const MachineRegisterInfo *MRI, 271 const MachineInstr *DefMI, unsigned DefIdx, 272 const MachineInstr *UseMI, 273 unsigned UseIdx) const override; 274 bool hasLowDefLatency(const InstrItineraryData *ItinData, 275 const MachineInstr *DefMI, 276 unsigned DefIdx) const override; 277 278 /// verifyInstruction - Perform target specific instruction verification. 279 bool verifyInstruction(const MachineInstr *MI, 280 StringRef &ErrInfo) const override; 281 282private: 283 /// Modeling special VFP / NEON fp MLA / MLS hazards. 284 285 /// MLxEntryMap - Map fp MLA / MLS to the corresponding entry in the internal 286 /// MLx table. 287 DenseMap<unsigned, unsigned> MLxEntryMap; 288 289 /// MLxHazardOpcodes - Set of add / sub and multiply opcodes that would cause 290 /// stalls when scheduled together with fp MLA / MLS opcodes. 291 SmallSet<unsigned, 16> MLxHazardOpcodes; 292 293public: 294 /// isFpMLxInstruction - Return true if the specified opcode is a fp MLA / MLS 295 /// instruction. 296 bool isFpMLxInstruction(unsigned Opcode) const { 297 return MLxEntryMap.count(Opcode); 298 } 299 300 /// isFpMLxInstruction - This version also returns the multiply opcode and the 301 /// addition / subtraction opcode to expand to. Return true for 'HasLane' for 302 /// the MLX instructions with an extra lane operand. 303 bool isFpMLxInstruction(unsigned Opcode, unsigned &MulOpc, 304 unsigned &AddSubOpc, bool &NegAcc, 305 bool &HasLane) const; 306 307 /// canCauseFpMLxStall - Return true if an instruction of the specified opcode 308 /// will cause stalls when scheduled after (within 4-cycle window) a fp 309 /// MLA / MLS instruction. 310 bool canCauseFpMLxStall(unsigned Opcode) const { 311 return MLxHazardOpcodes.count(Opcode); 312 } 313 314 /// Returns true if the instruction has a shift by immediate that can be 315 /// executed in one cycle less. 316 bool isSwiftFastImmShift(const MachineInstr *MI) const; 317}; 318 319static inline 320const MachineInstrBuilder &AddDefaultPred(const MachineInstrBuilder &MIB) { 321 return MIB.addImm((int64_t)ARMCC::AL).addReg(0); 322} 323 324static inline 325const MachineInstrBuilder &AddDefaultCC(const MachineInstrBuilder &MIB) { 326 return MIB.addReg(0); 327} 328 329static inline 330const MachineInstrBuilder &AddDefaultT1CC(const MachineInstrBuilder &MIB, 331 bool isDead = false) { 332 return MIB.addReg(ARM::CPSR, getDefRegState(true) | getDeadRegState(isDead)); 333} 334 335static inline 336const MachineInstrBuilder &AddNoT1CC(const MachineInstrBuilder &MIB) { 337 return MIB.addReg(0); 338} 339 340static inline 341bool isUncondBranchOpcode(int Opc) { 342 return Opc == ARM::B || Opc == ARM::tB || Opc == ARM::t2B; 343} 344 345static inline 346bool isCondBranchOpcode(int Opc) { 347 return Opc == ARM::Bcc || Opc == ARM::tBcc || Opc == ARM::t2Bcc; 348} 349 350static inline 351bool isJumpTableBranchOpcode(int Opc) { 352 return Opc == ARM::BR_JTr || Opc == ARM::BR_JTm || Opc == ARM::BR_JTadd || 353 Opc == ARM::tBR_JTr || Opc == ARM::t2BR_JT; 354} 355 356static inline 357bool isIndirectBranchOpcode(int Opc) { 358 return Opc == ARM::BX || Opc == ARM::MOVPCRX || Opc == ARM::tBRIND; 359} 360 361static inline bool isPopOpcode(int Opc) { 362 return Opc == ARM::tPOP_RET || Opc == ARM::LDMIA_RET || 363 Opc == ARM::t2LDMIA_RET || Opc == ARM::tPOP || Opc == ARM::LDMIA_UPD || 364 Opc == ARM::t2LDMIA_UPD || Opc == ARM::VLDMDIA_UPD; 365} 366 367static inline bool isPushOpcode(int Opc) { 368 return Opc == ARM::tPUSH || Opc == ARM::t2STMDB_UPD || 369 Opc == ARM::STMDB_UPD || Opc == ARM::VSTMDDB_UPD; 370} 371 372/// getInstrPredicate - If instruction is predicated, returns its predicate 373/// condition, otherwise returns AL. It also returns the condition code 374/// register by reference. 375ARMCC::CondCodes getInstrPredicate(const MachineInstr *MI, unsigned &PredReg); 376 377int getMatchingCondBranchOpcode(int Opc); 378 379/// Determine if MI can be folded into an ARM MOVCC instruction, and return the 380/// opcode of the SSA instruction representing the conditional MI. 381unsigned canFoldARMInstrIntoMOVCC(unsigned Reg, 382 MachineInstr *&MI, 383 const MachineRegisterInfo &MRI); 384 385/// Map pseudo instructions that imply an 'S' bit onto real opcodes. Whether 386/// the instruction is encoded with an 'S' bit is determined by the optional 387/// CPSR def operand. 388unsigned convertAddSubFlagsOpcode(unsigned OldOpc); 389 390/// emitARMRegPlusImmediate / emitT2RegPlusImmediate - Emits a series of 391/// instructions to materializea destreg = basereg + immediate in ARM / Thumb2 392/// code. 393void emitARMRegPlusImmediate(MachineBasicBlock &MBB, 394 MachineBasicBlock::iterator &MBBI, DebugLoc dl, 395 unsigned DestReg, unsigned BaseReg, int NumBytes, 396 ARMCC::CondCodes Pred, unsigned PredReg, 397 const ARMBaseInstrInfo &TII, unsigned MIFlags = 0); 398 399void emitT2RegPlusImmediate(MachineBasicBlock &MBB, 400 MachineBasicBlock::iterator &MBBI, DebugLoc dl, 401 unsigned DestReg, unsigned BaseReg, int NumBytes, 402 ARMCC::CondCodes Pred, unsigned PredReg, 403 const ARMBaseInstrInfo &TII, unsigned MIFlags = 0); 404void emitThumbRegPlusImmediate(MachineBasicBlock &MBB, 405 MachineBasicBlock::iterator &MBBI, DebugLoc dl, 406 unsigned DestReg, unsigned BaseReg, 407 int NumBytes, const TargetInstrInfo &TII, 408 const ARMBaseRegisterInfo& MRI, 409 unsigned MIFlags = 0); 410 411/// Tries to add registers to the reglist of a given base-updating 412/// push/pop instruction to adjust the stack by an additional 413/// NumBytes. This can save a few bytes per function in code-size, but 414/// obviously generates more memory traffic. As such, it only takes 415/// effect in functions being optimised for size. 416bool tryFoldSPUpdateIntoPushPop(const ARMSubtarget &Subtarget, 417 MachineFunction &MF, MachineInstr *MI, 418 unsigned NumBytes); 419 420/// rewriteARMFrameIndex / rewriteT2FrameIndex - 421/// Rewrite MI to access 'Offset' bytes from the FP. Return false if the 422/// offset could not be handled directly in MI, and return the left-over 423/// portion by reference. 424bool rewriteARMFrameIndex(MachineInstr &MI, unsigned FrameRegIdx, 425 unsigned FrameReg, int &Offset, 426 const ARMBaseInstrInfo &TII); 427 428bool rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, 429 unsigned FrameReg, int &Offset, 430 const ARMBaseInstrInfo &TII); 431 432} // End llvm namespace 433 434#endif 435