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