ARMBaseInstrInfo.h revision 13fd601e0f1c6d8558c4c2b027dacd148f19e6af
131c24bf5b39cc8391d4cfdbf8cf5163975fdb81eJim Grosbach//===- ARMBaseInstrInfo.h - ARM Base Instruction Information ----*- C++ -*-===//
2334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin//
3334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin//                     The LLVM Compiler Infrastructure
4334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin//
5334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin// This file is distributed under the University of Illinois Open Source
6334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin// License. See LICENSE.TXT for details.
7334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin//
8334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin//===----------------------------------------------------------------------===//
9334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin//
10334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin// This file contains the Base ARM implementation of the TargetInstrInfo class.
11334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin//
12334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin//===----------------------------------------------------------------------===//
13334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
14334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin#ifndef ARMBASEINSTRUCTIONINFO_H
15334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin#define ARMBASEINSTRUCTIONINFO_H
16334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
17334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin#include "ARM.h"
18b8e9ac834a9c253e3f8f5caa8f229bafba0b4fcfAnton Korobeynikov#include "llvm/CodeGen/MachineInstrBuilder.h"
19b8e9ac834a9c253e3f8f5caa8f229bafba0b4fcfAnton Korobeynikov#include "llvm/Target/TargetInstrInfo.h"
2048575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng#include "llvm/ADT/DenseMap.h"
2148575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng#include "llvm/ADT/SmallSet.h"
22334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
234db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng#define GET_INSTRINFO_HEADER
244db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng#include "ARMGenInstrInfo.inc"
254db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng
26334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwinnamespace llvm {
274dbbe3433f7339ed277af55037ff6847f484e5abChris Lattner  class ARMSubtarget;
284dbbe3433f7339ed277af55037ff6847f484e5abChris Lattner  class ARMBaseRegisterInfo;
29334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
304db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Chengclass ARMBaseInstrInfo : public ARMGenInstrInfo {
314dbbe3433f7339ed277af55037ff6847f484e5abChris Lattner  const ARMSubtarget &Subtarget;
3248575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng
33334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwinprotected:
34334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  // Can be only subclassed.
35f95215f551949d5e5adfbf4753aa833b9009b77aAnton Korobeynikov  explicit ARMBaseInstrInfo(const ARMSubtarget &STI);
3648575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng
37334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwinpublic:
38334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  // Return the non-pre/post incrementing version of 'Opc'. Return 0
39334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  // if there is not such an opcode.
40334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  virtual unsigned getUnindexedOpcode(unsigned Opc) const =0;
41334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
42334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  virtual MachineInstr *convertToThreeAddress(MachineFunction::iterator &MFI,
43334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin                                              MachineBasicBlock::iterator &MBBI,
44334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin                                              LiveVariables *LV) const;
45334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
46334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  virtual const ARMBaseRegisterInfo &getRegisterInfo() const =0;
47f95215f551949d5e5adfbf4753aa833b9009b77aAnton Korobeynikov  const ARMSubtarget &getSubtarget() const { return Subtarget; }
48334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
4948575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  ScheduleHazardRecognizer *
502da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick  CreateTargetHazardRecognizer(const TargetMachine *TM,
512da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick                               const ScheduleDAG *DAG) const;
522da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick
532da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick  ScheduleHazardRecognizer *
542da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick  CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II,
552da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick                                     const ScheduleDAG *DAG) const;
5648575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng
57334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  // Branch analysis.
58334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
59334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin                             MachineBasicBlock *&FBB,
60334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin                             SmallVectorImpl<MachineOperand> &Cond,
612062875a7d8f7dd94a20d9e3a298e9e216efb4b5Chris Lattner                             bool AllowModify = false) const;
62334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  virtual unsigned RemoveBranch(MachineBasicBlock &MBB) const;
63334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
64334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin                                MachineBasicBlock *FBB,
653bf912593301152b65accb9d9c37a95172f1df5aStuart Hastings                                const SmallVectorImpl<MachineOperand> &Cond,
663bf912593301152b65accb9d9c37a95172f1df5aStuart Hastings                                DebugLoc DL) const;
67334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
68334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  virtual
69334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const;
70334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
71334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  // Predication support.
72ab331504452a833f27a030f13525b964545d768aEvan Cheng  bool isPredicated(const MachineInstr *MI) const {
73ab331504452a833f27a030f13525b964545d768aEvan Cheng    int PIdx = MI->findFirstPredOperandIdx();
74ab331504452a833f27a030f13525b964545d768aEvan Cheng    return PIdx != -1 && MI->getOperand(PIdx).getImm() != ARMCC::AL;
75ab331504452a833f27a030f13525b964545d768aEvan Cheng  }
76334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
77334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  ARMCC::CondCodes getPredicate(const MachineInstr *MI) const {
78334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    int PIdx = MI->findFirstPredOperandIdx();
79334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin    return PIdx != -1 ? (ARMCC::CondCodes)MI->getOperand(PIdx).getImm()
80334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin                      : ARMCC::AL;
81334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  }
82334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
83334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  virtual
84334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  bool PredicateInstruction(MachineInstr *MI,
85334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin                            const SmallVectorImpl<MachineOperand> &Pred) const;
86334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
87334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  virtual
88334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  bool SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1,
89334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin                         const SmallVectorImpl<MachineOperand> &Pred2) const;
90334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
91334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  virtual bool DefinesPredicate(MachineInstr *MI,
92334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin                                std::vector<MachineOperand> &Pred) const;
93334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
94ac0869dc8a7986855c5557cc67d4709600158ef5Evan Cheng  virtual bool isPredicable(MachineInstr *MI) const;
95ac0869dc8a7986855c5557cc67d4709600158ef5Evan Cheng
96334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  /// GetInstSize - Returns the size of the specified MachineInstr.
97334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  ///
98334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  virtual unsigned GetInstSizeInBytes(const MachineInstr* MI) const;
99334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
100334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  virtual unsigned isLoadFromStackSlot(const MachineInstr *MI,
101334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin                                       int &FrameIndex) const;
102334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  virtual unsigned isStoreToStackSlot(const MachineInstr *MI,
103334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin                                      int &FrameIndex) const;
10436ee0e640554b8cc6ad1658fc3049e05d9967160Jakob Stoklund Olesen  virtual unsigned isLoadFromStackSlotPostFE(const MachineInstr *MI,
10536ee0e640554b8cc6ad1658fc3049e05d9967160Jakob Stoklund Olesen                                             int &FrameIndex) const;
10636ee0e640554b8cc6ad1658fc3049e05d9967160Jakob Stoklund Olesen  virtual unsigned isStoreToStackSlotPostFE(const MachineInstr *MI,
10736ee0e640554b8cc6ad1658fc3049e05d9967160Jakob Stoklund Olesen                                            int &FrameIndex) const;
108334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
109ac2736670034e8942939b9fccf8e4618a0bda908Jakob Stoklund Olesen  virtual void copyPhysReg(MachineBasicBlock &MBB,
110ac2736670034e8942939b9fccf8e4618a0bda908Jakob Stoklund Olesen                           MachineBasicBlock::iterator I, DebugLoc DL,
111ac2736670034e8942939b9fccf8e4618a0bda908Jakob Stoklund Olesen                           unsigned DestReg, unsigned SrcReg,
112ac2736670034e8942939b9fccf8e4618a0bda908Jakob Stoklund Olesen                           bool KillSrc) const;
1135732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng
114334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  virtual void storeRegToStackSlot(MachineBasicBlock &MBB,
115334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin                                   MachineBasicBlock::iterator MBBI,
116334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin                                   unsigned SrcReg, bool isKill, int FrameIndex,
117746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng                                   const TargetRegisterClass *RC,
118746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng                                   const TargetRegisterInfo *TRI) const;
119334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
120334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin  virtual void loadRegFromStackSlot(MachineBasicBlock &MBB,
121334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin                                    MachineBasicBlock::iterator MBBI,
122334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin                                    unsigned DestReg, int FrameIndex,
123746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng                                    const TargetRegisterClass *RC,
124746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng                                    const TargetRegisterInfo *TRI) const;
125334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
12662b50656ceb854eb0be265d63b2a1d46e7400d8aEvan Cheng  virtual MachineInstr *emitFrameIndexDebugValue(MachineFunction &MF,
1278601a3d4decff0a380e059b037dabf71075497d3Evan Cheng                                                 int FrameIx,
12862b50656ceb854eb0be265d63b2a1d46e7400d8aEvan Cheng                                                 uint64_t Offset,
12962b50656ceb854eb0be265d63b2a1d46e7400d8aEvan Cheng                                                 const MDNode *MDPtr,
13062b50656ceb854eb0be265d63b2a1d46e7400d8aEvan Cheng                                                 DebugLoc DL) const;
13162b50656ceb854eb0be265d63b2a1d46e7400d8aEvan Cheng
132fdc834046efd427d474e3b899ec69354c05071e0Evan Cheng  virtual void reMaterialize(MachineBasicBlock &MBB,
133fdc834046efd427d474e3b899ec69354c05071e0Evan Cheng                             MachineBasicBlock::iterator MI,
134fdc834046efd427d474e3b899ec69354c05071e0Evan Cheng                             unsigned DestReg, unsigned SubIdx,
135d57cdd5683ea926e489067364fb7ffe5fd5d35eeEvan Cheng                             const MachineInstr *Orig,
1369edf7deb37f0f97664f279040fa15d89f32e23d9Jakob Stoklund Olesen                             const TargetRegisterInfo &TRI) const;
137fdc834046efd427d474e3b899ec69354c05071e0Evan Cheng
13830ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen  MachineInstr *duplicate(MachineInstr *Orig, MachineFunction &MF) const;
13930ac0467ced4627a9b84d8a1d3ca5e8706ddad63Jakob Stoklund Olesen
140506049f29f4f202a8e45feb916cc0264440a7f6dEvan Cheng  virtual bool produceSameValue(const MachineInstr *MI0,
1419fe2009956fc40f3aea46fb3c38dcfb61c4aca46Evan Cheng                                const MachineInstr *MI1,
1429fe2009956fc40f3aea46fb3c38dcfb61c4aca46Evan Cheng                                const MachineRegisterInfo *MRI) const;
14386050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng
1444b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  /// areLoadsFromSameBasePtr - This is used by the pre-regalloc scheduler to
1454b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  /// determine if two loads are loading from the same base address. It should
1464b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  /// only return true if the base pointers are the same and the only
1474b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  /// differences between the two addresses is the offset. It also returns the
1484b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  /// offsets by reference.
1494b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  virtual bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2,
1504b722108e2cf8e77157e0879a23789cd44829933Bill Wendling                                       int64_t &Offset1, int64_t &Offset2)const;
1514b722108e2cf8e77157e0879a23789cd44829933Bill Wendling
1524b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  /// shouldScheduleLoadsNear - This is a used by the pre-regalloc scheduler to
153f921c0fe3418f96bd1e37beb582a368d3ac24295Jim Grosbach  /// determine (in conjunction with areLoadsFromSameBasePtr) if two loads
154f921c0fe3418f96bd1e37beb582a368d3ac24295Jim Grosbach  /// should be scheduled togther. On some targets if two loads are loading from
1554b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  /// addresses in the same cache line, it's better if they are scheduled
1564b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  /// together. This function takes two integers that represent the load offsets
1574b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  /// from the common base address. It returns true if it decides it's desirable
1584b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  /// to schedule the two loads together. "NumLoads" is the number of loads that
1594b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  /// have already been scheduled after Load1.
1604b722108e2cf8e77157e0879a23789cd44829933Bill Wendling  virtual bool shouldScheduleLoadsNear(SDNode *Load1, SDNode *Load2,
1614b722108e2cf8e77157e0879a23789cd44829933Bill Wendling                                       int64_t Offset1, int64_t Offset2,
1624b722108e2cf8e77157e0879a23789cd44829933Bill Wendling                                       unsigned NumLoads) const;
1634b722108e2cf8e77157e0879a23789cd44829933Bill Wendling
16486050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng  virtual bool isSchedulingBoundary(const MachineInstr *MI,
16586050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng                                    const MachineBasicBlock *MBB,
16686050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng                                    const MachineFunction &MF) const;
16713151432edace19ee867a93b5c14573df4f75d24Evan Cheng
16813151432edace19ee867a93b5c14573df4f75d24Evan Cheng  virtual bool isProfitableToIfCvt(MachineBasicBlock &MBB,
1695876db7a66fcc4ec4444a9f3e387c1cdc8baf9e5Cameron Zwarich                                   unsigned NumCycles, unsigned ExtraPredCycles,
170f81b7f6069b27c0a515070dcb392f6828437412fJakub Staszak                                   const BranchProbability &Probability) const;
17113151432edace19ee867a93b5c14573df4f75d24Evan Cheng
1728239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng  virtual bool isProfitableToIfCvt(MachineBasicBlock &TMBB,
1738239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng                                   unsigned NumT, unsigned ExtraT,
1748239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng                                   MachineBasicBlock &FMBB,
1758239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng                                   unsigned NumF, unsigned ExtraF,
176f81b7f6069b27c0a515070dcb392f6828437412fJakub Staszak                                   const BranchProbability &Probability) const;
17713151432edace19ee867a93b5c14573df4f75d24Evan Cheng
17813151432edace19ee867a93b5c14573df4f75d24Evan Cheng  virtual bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB,
1795876db7a66fcc4ec4444a9f3e387c1cdc8baf9e5Cameron Zwarich                                         unsigned NumCycles,
180f81b7f6069b27c0a515070dcb392f6828437412fJakub Staszak                                         const BranchProbability
181f81b7f6069b27c0a515070dcb392f6828437412fJakub Staszak                                           &Probability) const {
1825876db7a66fcc4ec4444a9f3e387c1cdc8baf9e5Cameron Zwarich    return NumCycles == 1;
18313151432edace19ee867a93b5c14573df4f75d24Evan Cheng  }
184e4ddbdfd3cf031034020671d03626f0373fbd5caBill Wendling
185c98af3370f899a0d1570b1dff01a2e36632f884fBill Wendling  /// AnalyzeCompare - For a comparison instruction, return the source register
186c98af3370f899a0d1570b1dff01a2e36632f884fBill Wendling  /// in SrcReg and the value it compares against in CmpValue. Return true if
187c98af3370f899a0d1570b1dff01a2e36632f884fBill Wendling  /// the comparison instruction can be analyzed.
188c98af3370f899a0d1570b1dff01a2e36632f884fBill Wendling  virtual bool AnalyzeCompare(const MachineInstr *MI, unsigned &SrcReg,
18904ac81d5db058a3a9492e1aff1f398a8643bfda9Gabor Greif                              int &CmpMask, int &CmpValue) const;
190e4ddbdfd3cf031034020671d03626f0373fbd5caBill Wendling
191a65568676d0d9d53dd4aae8f1c58271bb4cfff10Bill Wendling  /// OptimizeCompareInstr - Convert the instruction to set the zero flag so
192e4ddbdfd3cf031034020671d03626f0373fbd5caBill Wendling  /// that we can remove a "comparison with zero".
193a65568676d0d9d53dd4aae8f1c58271bb4cfff10Bill Wendling  virtual bool OptimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg,
19404ac81d5db058a3a9492e1aff1f398a8643bfda9Gabor Greif                                    int CmpMask, int CmpValue,
195eb96a2f6c03c0ec97c56a3493ac38024afacc774Evan Cheng                                    const MachineRegisterInfo *MRI) const;
1965f54ce347368105260be2cec497b6a4199dc5789Evan Cheng
197c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng  /// FoldImmediate - 'Reg' is known to be defined by a move immediate
198c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng  /// instruction, try to fold the immediate into the use instruction.
199c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng  virtual bool FoldImmediate(MachineInstr *UseMI, MachineInstr *DefMI,
200c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng                             unsigned Reg, MachineRegisterInfo *MRI) const;
201c4af4638dfdab0dc3b6257276cfad2ee45053060Evan Cheng
2028239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng  virtual unsigned getNumMicroOps(const InstrItineraryData *ItinData,
2038239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng                                  const MachineInstr *MI) const;
204a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng
205a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng  virtual
206a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng  int getOperandLatency(const InstrItineraryData *ItinData,
207a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng                        const MachineInstr *DefMI, unsigned DefIdx,
208a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng                        const MachineInstr *UseMI, unsigned UseIdx) const;
209a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng  virtual
210a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng  int getOperandLatency(const InstrItineraryData *ItinData,
211a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng                        SDNode *DefNode, unsigned DefIdx,
212a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng                        SDNode *UseNode, unsigned UseIdx) const;
21313fd601e0f1c6d8558c4c2b027dacd148f19e6afJakob Stoklund Olesen
21413fd601e0f1c6d8558c4c2b027dacd148f19e6afJakob Stoklund Olesen  /// VFP/NEON execution domains.
21513fd601e0f1c6d8558c4c2b027dacd148f19e6afJakob Stoklund Olesen  std::pair<uint16_t, uint16_t>
21613fd601e0f1c6d8558c4c2b027dacd148f19e6afJakob Stoklund Olesen  getExecutionDomain(const MachineInstr *MI) const;
21713fd601e0f1c6d8558c4c2b027dacd148f19e6afJakob Stoklund Olesen  void setExecutionDomain(MachineInstr *MI, unsigned Domain) const;
21813fd601e0f1c6d8558c4c2b027dacd148f19e6afJakob Stoklund Olesen
219a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Chengprivate:
220344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng  int getVLDMDefCycle(const InstrItineraryData *ItinData,
221e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng                      const MCInstrDesc &DefMCID,
222344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng                      unsigned DefClass,
223344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng                      unsigned DefIdx, unsigned DefAlign) const;
224344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng  int getLDMDefCycle(const InstrItineraryData *ItinData,
225e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng                     const MCInstrDesc &DefMCID,
226344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng                     unsigned DefClass,
227344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng                     unsigned DefIdx, unsigned DefAlign) const;
228344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng  int getVSTMUseCycle(const InstrItineraryData *ItinData,
229e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng                      const MCInstrDesc &UseMCID,
230344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng                      unsigned UseClass,
231344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng                      unsigned UseIdx, unsigned UseAlign) const;
232344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng  int getSTMUseCycle(const InstrItineraryData *ItinData,
233e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng                     const MCInstrDesc &UseMCID,
234344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng                     unsigned UseClass,
235344d9db97062736cd66da6c07baa9108b6cfa419Evan Cheng                     unsigned UseIdx, unsigned UseAlign) const;
236a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng  int getOperandLatency(const InstrItineraryData *ItinData,
237e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng                        const MCInstrDesc &DefMCID,
238a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng                        unsigned DefIdx, unsigned DefAlign,
239e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng                        const MCInstrDesc &UseMCID,
240a0792de66c8364d47b0a688c7f408efb7b10f31bEvan Cheng                        unsigned UseIdx, unsigned UseAlign) const;
2412312842de0c641107dd04d7e056d02491cc781caEvan Cheng
2428239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng  int getInstrLatency(const InstrItineraryData *ItinData,
2438239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng                      const MachineInstr *MI, unsigned *PredCost = 0) const;
2448239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng
2458239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng  int getInstrLatency(const InstrItineraryData *ItinData,
2468239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng                      SDNode *Node) const;
2478239daf7c83a65a189c352cce3191cdc3bbfe151Evan Cheng
2482312842de0c641107dd04d7e056d02491cc781caEvan Cheng  bool hasHighOperandLatency(const InstrItineraryData *ItinData,
2492312842de0c641107dd04d7e056d02491cc781caEvan Cheng                             const MachineRegisterInfo *MRI,
2502312842de0c641107dd04d7e056d02491cc781caEvan Cheng                             const MachineInstr *DefMI, unsigned DefIdx,
2512312842de0c641107dd04d7e056d02491cc781caEvan Cheng                             const MachineInstr *UseMI, unsigned UseIdx) const;
252c8141dfc7f983cb04e65d8acd6bcbdc8e4b8a0aeEvan Cheng  bool hasLowDefLatency(const InstrItineraryData *ItinData,
253c8141dfc7f983cb04e65d8acd6bcbdc8e4b8a0aeEvan Cheng                        const MachineInstr *DefMI, unsigned DefIdx) const;
25448575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng
2553be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick  /// verifyInstruction - Perform target specific instruction verification.
2563be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick  bool verifyInstruction(const MachineInstr *MI, StringRef &ErrInfo) const;
2573be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick
25848575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Chengprivate:
25948575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  /// Modeling special VFP / NEON fp MLA / MLS hazards.
26048575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng
26148575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  /// MLxEntryMap - Map fp MLA / MLS to the corresponding entry in the internal
26248575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  /// MLx table.
26348575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  DenseMap<unsigned, unsigned> MLxEntryMap;
26448575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng
26548575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  /// MLxHazardOpcodes - Set of add / sub and multiply opcodes that would cause
26648575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  /// stalls when scheduled together with fp MLA / MLS opcodes.
26748575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  SmallSet<unsigned, 16> MLxHazardOpcodes;
26848575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng
26948575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Chengpublic:
27048575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  /// isFpMLxInstruction - Return true if the specified opcode is a fp MLA / MLS
27148575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  /// instruction.
27248575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  bool isFpMLxInstruction(unsigned Opcode) const {
27348575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng    return MLxEntryMap.count(Opcode);
27448575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  }
27548575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng
27648575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  /// isFpMLxInstruction - This version also returns the multiply opcode and the
27748575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  /// addition / subtraction opcode to expand to. Return true for 'HasLane' for
27848575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  /// the MLX instructions with an extra lane operand.
27948575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  bool isFpMLxInstruction(unsigned Opcode, unsigned &MulOpc,
28048575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng                          unsigned &AddSubOpc, bool &NegAcc,
28148575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng                          bool &HasLane) const;
28248575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng
28348575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  /// canCauseFpMLxStall - Return true if an instruction of the specified opcode
28448575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  /// will cause stalls when scheduled after (within 4-cycle window) a fp
28548575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  /// MLA / MLS instruction.
28648575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  bool canCauseFpMLxStall(unsigned Opcode) const {
28748575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng    return MLxHazardOpcodes.count(Opcode);
28848575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng  }
2896495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng};
2905ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng
2916495f63945e8dbde81f03a1dc2ab421993b9a495Evan Chengstatic inline
2926495f63945e8dbde81f03a1dc2ab421993b9a495Evan Chengconst MachineInstrBuilder &AddDefaultPred(const MachineInstrBuilder &MIB) {
2936495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  return MIB.addImm((int64_t)ARMCC::AL).addReg(0);
2946495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng}
2955ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng
2966495f63945e8dbde81f03a1dc2ab421993b9a495Evan Chengstatic inline
2976495f63945e8dbde81f03a1dc2ab421993b9a495Evan Chengconst MachineInstrBuilder &AddDefaultCC(const MachineInstrBuilder &MIB) {
2986495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  return MIB.addReg(0);
2996495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng}
30083e0e36be8390fee1235783731f6c64aa604b7eeEvan Cheng
3016495f63945e8dbde81f03a1dc2ab421993b9a495Evan Chengstatic inline
302e8af1f9afe5e70e1d4ec4d00a6870428dba88692Evan Chengconst MachineInstrBuilder &AddDefaultT1CC(const MachineInstrBuilder &MIB,
303e8af1f9afe5e70e1d4ec4d00a6870428dba88692Evan Cheng                                          bool isDead = false) {
304e8af1f9afe5e70e1d4ec4d00a6870428dba88692Evan Cheng  return MIB.addReg(ARM::CPSR, getDefRegState(true) | getDeadRegState(isDead));
3056495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng}
3066495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng
3076495f63945e8dbde81f03a1dc2ab421993b9a495Evan Chengstatic inline
308bc9b754091ea281e769e487f396b40f6675b9edbEvan Chengconst MachineInstrBuilder &AddNoT1CC(const MachineInstrBuilder &MIB) {
309bc9b754091ea281e769e487f396b40f6675b9edbEvan Cheng  return MIB.addReg(0);
310bc9b754091ea281e769e487f396b40f6675b9edbEvan Cheng}
311bc9b754091ea281e769e487f396b40f6675b9edbEvan Cheng
312bc9b754091ea281e769e487f396b40f6675b9edbEvan Chengstatic inline
3136495f63945e8dbde81f03a1dc2ab421993b9a495Evan Chengbool isUncondBranchOpcode(int Opc) {
3146495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  return Opc == ARM::B || Opc == ARM::tB || Opc == ARM::t2B;
315334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin}
316334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
3176495f63945e8dbde81f03a1dc2ab421993b9a495Evan Chengstatic inline
3186495f63945e8dbde81f03a1dc2ab421993b9a495Evan Chengbool isCondBranchOpcode(int Opc) {
3196495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  return Opc == ARM::Bcc || Opc == ARM::tBcc || Opc == ARM::t2Bcc;
3206495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng}
3216495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng
3226495f63945e8dbde81f03a1dc2ab421993b9a495Evan Chengstatic inline
3236495f63945e8dbde81f03a1dc2ab421993b9a495Evan Chengbool isJumpTableBranchOpcode(int Opc) {
3246495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  return Opc == ARM::BR_JTr || Opc == ARM::BR_JTm || Opc == ARM::BR_JTadd ||
3256495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    Opc == ARM::tBR_JTr || Opc == ARM::t2BR_JT;
3266495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng}
3276495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng
3288d4de5abfa1bcd974554ea14904ebf7af289e84dBob Wilsonstatic inline
3298d4de5abfa1bcd974554ea14904ebf7af289e84dBob Wilsonbool isIndirectBranchOpcode(int Opc) {
3306e46d84eea97792a66c0bb64f26aad3976a23365Bill Wendling  return Opc == ARM::BX || Opc == ARM::MOVPCRX || Opc == ARM::tBRIND;
3318d4de5abfa1bcd974554ea14904ebf7af289e84dBob Wilson}
3328d4de5abfa1bcd974554ea14904ebf7af289e84dBob Wilson
3338fb903604e83dfd63659c919042bf2bfed3c940fEvan Cheng/// getInstrPredicate - If instruction is predicated, returns its predicate
3348fb903604e83dfd63659c919042bf2bfed3c940fEvan Cheng/// condition, otherwise returns AL. It also returns the condition code
3358fb903604e83dfd63659c919042bf2bfed3c940fEvan Cheng/// register by reference.
3365adb66a646e2ec32265263739f5b01c3f50c176aEvan ChengARMCC::CondCodes getInstrPredicate(const MachineInstr *MI, unsigned &PredReg);
3378fb903604e83dfd63659c919042bf2bfed3c940fEvan Cheng
3386495f63945e8dbde81f03a1dc2ab421993b9a495Evan Chengint getMatchingCondBranchOpcode(int Opc);
3396495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng
3403be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick
3413be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick/// Map pseudo instructions that imply an 'S' bit onto real opcodes. Whether
3423be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick/// the instruction is encoded with an 'S' bit is determined by the optional
3433be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick/// CPSR def operand.
3443be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trickunsigned convertAddSubFlagsOpcode(unsigned OldOpc);
3453be654f8082dcbdff011a6716a7c90486e28fc9eAndrew Trick
3466495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng/// emitARMRegPlusImmediate / emitT2RegPlusImmediate - Emits a series of
3476495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng/// instructions to materializea destreg = basereg + immediate in ARM / Thumb2
3486495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng/// code.
3496495f63945e8dbde81f03a1dc2ab421993b9a495Evan Chengvoid emitARMRegPlusImmediate(MachineBasicBlock &MBB,
3506495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng                             MachineBasicBlock::iterator &MBBI, DebugLoc dl,
3516495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng                             unsigned DestReg, unsigned BaseReg, int NumBytes,
3526495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng                             ARMCC::CondCodes Pred, unsigned PredReg,
35357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov                             const ARMBaseInstrInfo &TII, unsigned MIFlags = 0);
3546495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng
3556495f63945e8dbde81f03a1dc2ab421993b9a495Evan Chengvoid emitT2RegPlusImmediate(MachineBasicBlock &MBB,
3566495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng                            MachineBasicBlock::iterator &MBBI, DebugLoc dl,
3576495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng                            unsigned DestReg, unsigned BaseReg, int NumBytes,
3586495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng                            ARMCC::CondCodes Pred, unsigned PredReg,
35957caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov                            const ARMBaseInstrInfo &TII, unsigned MIFlags = 0);
360e4ad387a5a88dae20f0f7578e55170bbc8eee2a9Jim Grosbachvoid emitThumbRegPlusImmediate(MachineBasicBlock &MBB,
36157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov                               MachineBasicBlock::iterator &MBBI, DebugLoc dl,
362e4ad387a5a88dae20f0f7578e55170bbc8eee2a9Jim Grosbach                               unsigned DestReg, unsigned BaseReg,
363e4ad387a5a88dae20f0f7578e55170bbc8eee2a9Jim Grosbach                               int NumBytes, const TargetInstrInfo &TII,
364e4ad387a5a88dae20f0f7578e55170bbc8eee2a9Jim Grosbach                               const ARMBaseRegisterInfo& MRI,
36557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov                               unsigned MIFlags = 0);
3666495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng
3676495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng
368764ab52dd80310a205c9888bf166d09dab858f90Jim Grosbach/// rewriteARMFrameIndex / rewriteT2FrameIndex -
369cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng/// Rewrite MI to access 'Offset' bytes from the FP. Return false if the
370cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng/// offset could not be handled directly in MI, and return the left-over
371cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng/// portion by reference.
372cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Chengbool rewriteARMFrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
373cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng                          unsigned FrameReg, int &Offset,
374cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng                          const ARMBaseInstrInfo &TII);
375cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng
376cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Chengbool rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
377cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng                         unsigned FrameReg, int &Offset,
378cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng                         const ARMBaseInstrInfo &TII);
3796495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng
3806495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng} // End llvm namespace
3816495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng
382334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin#endif
383