ARMBaseInstrInfo.h revision e4345c9977e65b14fa4b93d19c7e67a7b15f7f40
1//===- ARMBaseInstrInfo.h - ARM Base Instruction Information ----*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file contains the Base ARM implementation of the TargetInstrInfo class. 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef ARMBASEINSTRUCTIONINFO_H 15#define ARMBASEINSTRUCTIONINFO_H 16 17#include "ARM.h" 18#include "llvm/CodeGen/MachineInstrBuilder.h" 19#include "llvm/Target/TargetInstrInfo.h" 20#include "llvm/ADT/DenseMap.h" 21#include "llvm/ADT/SmallSet.h" 22 23namespace llvm { 24 class ARMSubtarget; 25 class ARMBaseRegisterInfo; 26 27/// ARMII - This namespace holds all of the target specific flags that 28/// instruction info tracks. 29/// 30namespace ARMII { 31 enum { 32 //===------------------------------------------------------------------===// 33 // Instruction Flags. 34 35 //===------------------------------------------------------------------===// 36 // This four-bit field describes the addressing mode used. 37 38 AddrModeMask = 0x1f, 39 AddrModeNone = 0, 40 AddrMode1 = 1, 41 AddrMode2 = 2, 42 AddrMode3 = 3, 43 AddrMode4 = 4, 44 AddrMode5 = 5, 45 AddrMode6 = 6, 46 AddrModeT1_1 = 7, 47 AddrModeT1_2 = 8, 48 AddrModeT1_4 = 9, 49 AddrModeT1_s = 10, // i8 * 4 for pc and sp relative data 50 AddrModeT2_i12 = 11, 51 AddrModeT2_i8 = 12, 52 AddrModeT2_so = 13, 53 AddrModeT2_pc = 14, // +/- i12 for pc relative data 54 AddrModeT2_i8s4 = 15, // i8 * 4 55 AddrMode_i12 = 16, 56 57 // Size* - Flags to keep track of the size of an instruction. 58 SizeShift = 5, 59 SizeMask = 7 << SizeShift, 60 SizeSpecial = 1, // 0 byte pseudo or special case. 61 Size8Bytes = 2, 62 Size4Bytes = 3, 63 Size2Bytes = 4, 64 65 // IndexMode - Unindex, pre-indexed, or post-indexed are valid for load 66 // and store ops only. Generic "updating" flag is used for ld/st multiple. 67 IndexModeShift = 8, 68 IndexModeMask = 3 << IndexModeShift, 69 IndexModePre = 1, 70 IndexModePost = 2, 71 IndexModeUpd = 3, 72 73 //===------------------------------------------------------------------===// 74 // Instruction encoding formats. 75 // 76 FormShift = 10, 77 FormMask = 0x3f << FormShift, 78 79 // Pseudo instructions 80 Pseudo = 0 << FormShift, 81 82 // Multiply instructions 83 MulFrm = 1 << FormShift, 84 85 // Branch instructions 86 BrFrm = 2 << FormShift, 87 BrMiscFrm = 3 << FormShift, 88 89 // Data Processing instructions 90 DPFrm = 4 << FormShift, 91 DPSoRegFrm = 5 << FormShift, 92 93 // Load and Store 94 LdFrm = 6 << FormShift, 95 StFrm = 7 << FormShift, 96 LdMiscFrm = 8 << FormShift, 97 StMiscFrm = 9 << FormShift, 98 LdStMulFrm = 10 << FormShift, 99 100 LdStExFrm = 11 << FormShift, 101 102 // Miscellaneous arithmetic instructions 103 ArithMiscFrm = 12 << FormShift, 104 SatFrm = 13 << FormShift, 105 106 // Extend instructions 107 ExtFrm = 14 << FormShift, 108 109 // VFP formats 110 VFPUnaryFrm = 15 << FormShift, 111 VFPBinaryFrm = 16 << FormShift, 112 VFPConv1Frm = 17 << FormShift, 113 VFPConv2Frm = 18 << FormShift, 114 VFPConv3Frm = 19 << FormShift, 115 VFPConv4Frm = 20 << FormShift, 116 VFPConv5Frm = 21 << FormShift, 117 VFPLdStFrm = 22 << FormShift, 118 VFPLdStMulFrm = 23 << FormShift, 119 VFPMiscFrm = 24 << FormShift, 120 121 // Thumb format 122 ThumbFrm = 25 << FormShift, 123 124 // Miscelleaneous format 125 MiscFrm = 26 << FormShift, 126 127 // NEON formats 128 NGetLnFrm = 27 << FormShift, 129 NSetLnFrm = 28 << FormShift, 130 NDupFrm = 29 << FormShift, 131 NLdStFrm = 30 << FormShift, 132 N1RegModImmFrm= 31 << FormShift, 133 N2RegFrm = 32 << FormShift, 134 NVCVTFrm = 33 << FormShift, 135 NVDupLnFrm = 34 << FormShift, 136 N2RegVShLFrm = 35 << FormShift, 137 N2RegVShRFrm = 36 << FormShift, 138 N3RegFrm = 37 << FormShift, 139 N3RegVShFrm = 38 << FormShift, 140 NVExtFrm = 39 << FormShift, 141 NVMulSLFrm = 40 << FormShift, 142 NVTBLFrm = 41 << FormShift, 143 144 //===------------------------------------------------------------------===// 145 // Misc flags. 146 147 // UnaryDP - Indicates this is a unary data processing instruction, i.e. 148 // it doesn't have a Rn operand. 149 UnaryDP = 1 << 16, 150 151 // Xform16Bit - Indicates this Thumb2 instruction may be transformed into 152 // a 16-bit Thumb instruction if certain conditions are met. 153 Xform16Bit = 1 << 17, 154 155 //===------------------------------------------------------------------===// 156 // Code domain. 157 DomainShift = 18, 158 DomainMask = 7 << DomainShift, 159 DomainGeneral = 0 << DomainShift, 160 DomainVFP = 1 << DomainShift, 161 DomainNEON = 2 << DomainShift, 162 DomainNEONA8 = 4 << DomainShift, 163 164 //===------------------------------------------------------------------===// 165 // Field shifts - such shifts are used to set field while generating 166 // machine instructions. 167 // 168 // FIXME: This list will need adjusting/fixing as the MC code emitter 169 // takes shape and the ARMCodeEmitter.cpp bits go away. 170 ShiftTypeShift = 4, 171 172 M_BitShift = 5, 173 ShiftImmShift = 5, 174 ShiftShift = 7, 175 N_BitShift = 7, 176 ImmHiShift = 8, 177 SoRotImmShift = 8, 178 RegRsShift = 8, 179 ExtRotImmShift = 10, 180 RegRdLoShift = 12, 181 RegRdShift = 12, 182 RegRdHiShift = 16, 183 RegRnShift = 16, 184 S_BitShift = 20, 185 W_BitShift = 21, 186 AM3_I_BitShift = 22, 187 D_BitShift = 22, 188 U_BitShift = 23, 189 P_BitShift = 24, 190 I_BitShift = 25, 191 CondShift = 28 192 }; 193} 194 195class ARMBaseInstrInfo : public TargetInstrInfoImpl { 196 const ARMSubtarget &Subtarget; 197 198protected: 199 // Can be only subclassed. 200 explicit ARMBaseInstrInfo(const ARMSubtarget &STI); 201 202public: 203 // Return the non-pre/post incrementing version of 'Opc'. Return 0 204 // if there is not such an opcode. 205 virtual unsigned getUnindexedOpcode(unsigned Opc) const =0; 206 207 virtual MachineInstr *convertToThreeAddress(MachineFunction::iterator &MFI, 208 MachineBasicBlock::iterator &MBBI, 209 LiveVariables *LV) const; 210 211 virtual const ARMBaseRegisterInfo &getRegisterInfo() const =0; 212 const ARMSubtarget &getSubtarget() const { return Subtarget; } 213 214 ScheduleHazardRecognizer * 215 CreateTargetHazardRecognizer(const TargetMachine *TM, 216 const ScheduleDAG *DAG) const; 217 218 ScheduleHazardRecognizer * 219 CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II, 220 const ScheduleDAG *DAG) const; 221 222 // Branch analysis. 223 virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, 224 MachineBasicBlock *&FBB, 225 SmallVectorImpl<MachineOperand> &Cond, 226 bool AllowModify = false) const; 227 virtual unsigned RemoveBranch(MachineBasicBlock &MBB) const; 228 virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 229 MachineBasicBlock *FBB, 230 const SmallVectorImpl<MachineOperand> &Cond, 231 DebugLoc DL) const; 232 233 virtual 234 bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const; 235 236 // Predication support. 237 bool isPredicated(const MachineInstr *MI) const { 238 int PIdx = MI->findFirstPredOperandIdx(); 239 return PIdx != -1 && MI->getOperand(PIdx).getImm() != ARMCC::AL; 240 } 241 242 ARMCC::CondCodes getPredicate(const MachineInstr *MI) const { 243 int PIdx = MI->findFirstPredOperandIdx(); 244 return PIdx != -1 ? (ARMCC::CondCodes)MI->getOperand(PIdx).getImm() 245 : ARMCC::AL; 246 } 247 248 virtual 249 bool PredicateInstruction(MachineInstr *MI, 250 const SmallVectorImpl<MachineOperand> &Pred) const; 251 252 virtual 253 bool SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1, 254 const SmallVectorImpl<MachineOperand> &Pred2) const; 255 256 virtual bool DefinesPredicate(MachineInstr *MI, 257 std::vector<MachineOperand> &Pred) const; 258 259 virtual bool isPredicable(MachineInstr *MI) const; 260 261 /// GetInstSize - Returns the size of the specified MachineInstr. 262 /// 263 virtual unsigned GetInstSizeInBytes(const MachineInstr* MI) const; 264 265 virtual unsigned isLoadFromStackSlot(const MachineInstr *MI, 266 int &FrameIndex) const; 267 virtual unsigned isStoreToStackSlot(const MachineInstr *MI, 268 int &FrameIndex) const; 269 270 virtual void copyPhysReg(MachineBasicBlock &MBB, 271 MachineBasicBlock::iterator I, DebugLoc DL, 272 unsigned DestReg, unsigned SrcReg, 273 bool KillSrc) const; 274 275 virtual void storeRegToStackSlot(MachineBasicBlock &MBB, 276 MachineBasicBlock::iterator MBBI, 277 unsigned SrcReg, bool isKill, int FrameIndex, 278 const TargetRegisterClass *RC, 279 const TargetRegisterInfo *TRI) const; 280 281 virtual void loadRegFromStackSlot(MachineBasicBlock &MBB, 282 MachineBasicBlock::iterator MBBI, 283 unsigned DestReg, int FrameIndex, 284 const TargetRegisterClass *RC, 285 const TargetRegisterInfo *TRI) const; 286 287 virtual MachineInstr *emitFrameIndexDebugValue(MachineFunction &MF, 288 int FrameIx, 289 uint64_t Offset, 290 const MDNode *MDPtr, 291 DebugLoc DL) const; 292 293 virtual void reMaterialize(MachineBasicBlock &MBB, 294 MachineBasicBlock::iterator MI, 295 unsigned DestReg, unsigned SubIdx, 296 const MachineInstr *Orig, 297 const TargetRegisterInfo &TRI) const; 298 299 MachineInstr *duplicate(MachineInstr *Orig, MachineFunction &MF) const; 300 301 virtual bool produceSameValue(const MachineInstr *MI0, 302 const MachineInstr *MI1, 303 const MachineRegisterInfo *MRI) const; 304 305 /// areLoadsFromSameBasePtr - This is used by the pre-regalloc scheduler to 306 /// determine if two loads are loading from the same base address. It should 307 /// only return true if the base pointers are the same and the only 308 /// differences between the two addresses is the offset. It also returns the 309 /// offsets by reference. 310 virtual bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2, 311 int64_t &Offset1, int64_t &Offset2)const; 312 313 /// shouldScheduleLoadsNear - This is a used by the pre-regalloc scheduler to 314 /// determine (in conjuction with areLoadsFromSameBasePtr) if two loads should 315 /// be scheduled togther. On some targets if two loads are loading from 316 /// addresses in the same cache line, it's better if they are scheduled 317 /// together. This function takes two integers that represent the load offsets 318 /// from the common base address. It returns true if it decides it's desirable 319 /// to schedule the two loads together. "NumLoads" is the number of loads that 320 /// have already been scheduled after Load1. 321 virtual bool shouldScheduleLoadsNear(SDNode *Load1, SDNode *Load2, 322 int64_t Offset1, int64_t Offset2, 323 unsigned NumLoads) const; 324 325 virtual bool isSchedulingBoundary(const MachineInstr *MI, 326 const MachineBasicBlock *MBB, 327 const MachineFunction &MF) const; 328 329 virtual bool isProfitableToIfCvt(MachineBasicBlock &MBB, 330 unsigned NumCyles, unsigned ExtraPredCycles, 331 float Prob, float Confidence) const; 332 333 virtual bool isProfitableToIfCvt(MachineBasicBlock &TMBB, 334 unsigned NumT, unsigned ExtraT, 335 MachineBasicBlock &FMBB, 336 unsigned NumF, unsigned ExtraF, 337 float Probability, float Confidence) const; 338 339 virtual bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB, 340 unsigned NumCyles, 341 float Probability, 342 float Confidence) const { 343 return NumCyles == 1; 344 } 345 346 /// AnalyzeCompare - For a comparison instruction, return the source register 347 /// in SrcReg and the value it compares against in CmpValue. Return true if 348 /// the comparison instruction can be analyzed. 349 virtual bool AnalyzeCompare(const MachineInstr *MI, unsigned &SrcReg, 350 int &CmpMask, int &CmpValue) const; 351 352 /// OptimizeCompareInstr - Convert the instruction to set the zero flag so 353 /// that we can remove a "comparison with zero". 354 virtual bool OptimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg, 355 int CmpMask, int CmpValue, 356 const MachineRegisterInfo *MRI) const; 357 358 /// FoldImmediate - 'Reg' is known to be defined by a move immediate 359 /// instruction, try to fold the immediate into the use instruction. 360 virtual bool FoldImmediate(MachineInstr *UseMI, MachineInstr *DefMI, 361 unsigned Reg, MachineRegisterInfo *MRI) const; 362 363 virtual unsigned getNumMicroOps(const InstrItineraryData *ItinData, 364 const MachineInstr *MI) const; 365 366 virtual 367 int getOperandLatency(const InstrItineraryData *ItinData, 368 const MachineInstr *DefMI, unsigned DefIdx, 369 const MachineInstr *UseMI, unsigned UseIdx) const; 370 virtual 371 int getOperandLatency(const InstrItineraryData *ItinData, 372 SDNode *DefNode, unsigned DefIdx, 373 SDNode *UseNode, unsigned UseIdx) const; 374private: 375 int getVLDMDefCycle(const InstrItineraryData *ItinData, 376 const TargetInstrDesc &DefTID, 377 unsigned DefClass, 378 unsigned DefIdx, unsigned DefAlign) const; 379 int getLDMDefCycle(const InstrItineraryData *ItinData, 380 const TargetInstrDesc &DefTID, 381 unsigned DefClass, 382 unsigned DefIdx, unsigned DefAlign) const; 383 int getVSTMUseCycle(const InstrItineraryData *ItinData, 384 const TargetInstrDesc &UseTID, 385 unsigned UseClass, 386 unsigned UseIdx, unsigned UseAlign) const; 387 int getSTMUseCycle(const InstrItineraryData *ItinData, 388 const TargetInstrDesc &UseTID, 389 unsigned UseClass, 390 unsigned UseIdx, unsigned UseAlign) const; 391 int getOperandLatency(const InstrItineraryData *ItinData, 392 const TargetInstrDesc &DefTID, 393 unsigned DefIdx, unsigned DefAlign, 394 const TargetInstrDesc &UseTID, 395 unsigned UseIdx, unsigned UseAlign) const; 396 397 int getInstrLatency(const InstrItineraryData *ItinData, 398 const MachineInstr *MI, unsigned *PredCost = 0) const; 399 400 int getInstrLatency(const InstrItineraryData *ItinData, 401 SDNode *Node) const; 402 403 bool hasHighOperandLatency(const InstrItineraryData *ItinData, 404 const MachineRegisterInfo *MRI, 405 const MachineInstr *DefMI, unsigned DefIdx, 406 const MachineInstr *UseMI, unsigned UseIdx) const; 407 bool hasLowDefLatency(const InstrItineraryData *ItinData, 408 const MachineInstr *DefMI, unsigned DefIdx) const; 409 410private: 411 /// Modeling special VFP / NEON fp MLA / MLS hazards. 412 413 /// MLxEntryMap - Map fp MLA / MLS to the corresponding entry in the internal 414 /// MLx table. 415 DenseMap<unsigned, unsigned> MLxEntryMap; 416 417 /// MLxHazardOpcodes - Set of add / sub and multiply opcodes that would cause 418 /// stalls when scheduled together with fp MLA / MLS opcodes. 419 SmallSet<unsigned, 16> MLxHazardOpcodes; 420 421public: 422 /// isFpMLxInstruction - Return true if the specified opcode is a fp MLA / MLS 423 /// instruction. 424 bool isFpMLxInstruction(unsigned Opcode) const { 425 return MLxEntryMap.count(Opcode); 426 } 427 428 /// isFpMLxInstruction - This version also returns the multiply opcode and the 429 /// addition / subtraction opcode to expand to. Return true for 'HasLane' for 430 /// the MLX instructions with an extra lane operand. 431 bool isFpMLxInstruction(unsigned Opcode, unsigned &MulOpc, 432 unsigned &AddSubOpc, bool &NegAcc, 433 bool &HasLane) const; 434 435 /// canCauseFpMLxStall - Return true if an instruction of the specified opcode 436 /// will cause stalls when scheduled after (within 4-cycle window) a fp 437 /// MLA / MLS instruction. 438 bool canCauseFpMLxStall(unsigned Opcode) const { 439 return MLxHazardOpcodes.count(Opcode); 440 } 441}; 442 443static inline 444const MachineInstrBuilder &AddDefaultPred(const MachineInstrBuilder &MIB) { 445 return MIB.addImm((int64_t)ARMCC::AL).addReg(0); 446} 447 448static inline 449const MachineInstrBuilder &AddDefaultCC(const MachineInstrBuilder &MIB) { 450 return MIB.addReg(0); 451} 452 453static inline 454const MachineInstrBuilder &AddDefaultT1CC(const MachineInstrBuilder &MIB, 455 bool isDead = false) { 456 return MIB.addReg(ARM::CPSR, getDefRegState(true) | getDeadRegState(isDead)); 457} 458 459static inline 460const MachineInstrBuilder &AddNoT1CC(const MachineInstrBuilder &MIB) { 461 return MIB.addReg(0); 462} 463 464static inline 465bool isUncondBranchOpcode(int Opc) { 466 return Opc == ARM::B || Opc == ARM::tB || Opc == ARM::t2B; 467} 468 469static inline 470bool isCondBranchOpcode(int Opc) { 471 return Opc == ARM::Bcc || Opc == ARM::tBcc || Opc == ARM::t2Bcc; 472} 473 474static inline 475bool isJumpTableBranchOpcode(int Opc) { 476 return Opc == ARM::BR_JTr || Opc == ARM::BR_JTm || Opc == ARM::BR_JTadd || 477 Opc == ARM::tBR_JTr || Opc == ARM::t2BR_JT; 478} 479 480static inline 481bool isIndirectBranchOpcode(int Opc) { 482 return Opc == ARM::BX || Opc == ARM::MOVPCRX || Opc == ARM::tBRIND; 483} 484 485/// getInstrPredicate - If instruction is predicated, returns its predicate 486/// condition, otherwise returns AL. It also returns the condition code 487/// register by reference. 488ARMCC::CondCodes getInstrPredicate(const MachineInstr *MI, unsigned &PredReg); 489 490int getMatchingCondBranchOpcode(int Opc); 491 492/// emitARMRegPlusImmediate / emitT2RegPlusImmediate - Emits a series of 493/// instructions to materializea destreg = basereg + immediate in ARM / Thumb2 494/// code. 495void emitARMRegPlusImmediate(MachineBasicBlock &MBB, 496 MachineBasicBlock::iterator &MBBI, DebugLoc dl, 497 unsigned DestReg, unsigned BaseReg, int NumBytes, 498 ARMCC::CondCodes Pred, unsigned PredReg, 499 const ARMBaseInstrInfo &TII, unsigned MIFlags = 0); 500 501void emitT2RegPlusImmediate(MachineBasicBlock &MBB, 502 MachineBasicBlock::iterator &MBBI, DebugLoc dl, 503 unsigned DestReg, unsigned BaseReg, int NumBytes, 504 ARMCC::CondCodes Pred, unsigned PredReg, 505 const ARMBaseInstrInfo &TII, unsigned MIFlags = 0); 506void emitThumbRegPlusImmediate(MachineBasicBlock &MBB, 507 MachineBasicBlock::iterator &MBBI, DebugLoc dl, 508 unsigned DestReg, unsigned BaseReg, 509 int NumBytes, const TargetInstrInfo &TII, 510 const ARMBaseRegisterInfo& MRI, 511 unsigned MIFlags = 0); 512 513 514/// rewriteARMFrameIndex / rewriteT2FrameIndex - 515/// Rewrite MI to access 'Offset' bytes from the FP. Return false if the 516/// offset could not be handled directly in MI, and return the left-over 517/// portion by reference. 518bool rewriteARMFrameIndex(MachineInstr &MI, unsigned FrameRegIdx, 519 unsigned FrameReg, int &Offset, 520 const ARMBaseInstrInfo &TII); 521 522bool rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, 523 unsigned FrameReg, int &Offset, 524 const ARMBaseInstrInfo &TII); 525 526} // End llvm namespace 527 528#endif 529