ARMInstrInfo.h revision 195098
198524Sfenner//===- ARMInstrInfo.h - ARM Instruction Information -------------*- C++ -*-===//
298524Sfenner//
398524Sfenner//                     The LLVM Compiler Infrastructure
498524Sfenner//
598524Sfenner// This file is distributed under the University of Illinois Open Source
698524Sfenner// License. See LICENSE.TXT for details.
798524Sfenner//
898524Sfenner//===----------------------------------------------------------------------===//
998524Sfenner//
1098524Sfenner// This file contains the ARM implementation of the TargetInstrInfo class.
1198524Sfenner//
1298524Sfenner//===----------------------------------------------------------------------===//
1398524Sfenner
1498524Sfenner#ifndef ARMINSTRUCTIONINFO_H
1598524Sfenner#define ARMINSTRUCTIONINFO_H
1698524Sfenner
1798524Sfenner#include "llvm/Target/TargetInstrInfo.h"
1898524Sfenner#include "ARMRegisterInfo.h"
1998524Sfenner#include "ARM.h"
20127668Sbms
2198524Sfennernamespace llvm {
2298524Sfenner  class ARMSubtarget;
2398524Sfenner
24127668Sbms/// ARMII - This namespace holds all of the target specific flags that
25190207Srpaulo/// instruction info tracks.
2698524Sfenner///
2798524Sfennernamespace ARMII {
2898524Sfenner  enum {
2998524Sfenner    //===------------------------------------------------------------------===//
3098524Sfenner    // Instruction Flags.
3198524Sfenner
32127668Sbms    //===------------------------------------------------------------------===//
3398524Sfenner    // This four-bit field describes the addressing mode used.
3498524Sfenner
3598524Sfenner    AddrModeMask  = 0xf,
3698524Sfenner    AddrModeNone  = 0,
3798524Sfenner    AddrMode1     = 1,
38214478Srpaulo    AddrMode2     = 2,
3998524Sfenner    AddrMode3     = 3,
4098524Sfenner    AddrMode4     = 4,
41127668Sbms    AddrMode5     = 5,
4298524Sfenner    AddrModeT1    = 6,
4398524Sfenner    AddrModeT2    = 7,
4498524Sfenner    AddrModeT4    = 8,
4598524Sfenner    AddrModeTs    = 9,  // i8 * 4 for pc and sp relative data
4698524Sfenner
4798524Sfenner    // Size* - Flags to keep track of the size of an instruction.
4898524Sfenner    SizeShift     = 4,
4998524Sfenner    SizeMask      = 7 << SizeShift,
5098524Sfenner    SizeSpecial   = 1,   // 0 byte pseudo or special case.
5198524Sfenner    Size8Bytes    = 2,
5298524Sfenner    Size4Bytes    = 3,
5398524Sfenner    Size2Bytes    = 4,
5498524Sfenner
5598524Sfenner    // IndexMode - Unindex, pre-indexed, or post-indexed. Only valid for load
5698524Sfenner    // and store ops
5798524Sfenner    IndexModeShift = 7,
5898524Sfenner    IndexModeMask  = 3 << IndexModeShift,
5998524Sfenner    IndexModePre   = 1,
6098524Sfenner    IndexModePost  = 2,
6198524Sfenner
6298524Sfenner    //===------------------------------------------------------------------===//
6398524Sfenner    // Misc flags.
6498524Sfenner
6598524Sfenner    // UnaryDP - Indicates this is a unary data processing instruction, i.e.
6698524Sfenner    // it doesn't have a Rn operand.
6798524Sfenner    UnaryDP       = 1 << 9,
6898524Sfenner
6998524Sfenner    //===------------------------------------------------------------------===//
7098524Sfenner    // Instruction encoding formats.
7198524Sfenner    //
7298524Sfenner    FormShift     = 10,
7398524Sfenner    FormMask      = 0x1f << FormShift,
7498524Sfenner
7598524Sfenner    // Pseudo instructions
7698524Sfenner    Pseudo        = 0  << FormShift,
7798524Sfenner
7898524Sfenner    // Multiply instructions
7998524Sfenner    MulFrm        = 1  << FormShift,
8098524Sfenner
8198524Sfenner    // Branch instructions
8298524Sfenner    BrFrm         = 2  << FormShift,
8398524Sfenner    BrMiscFrm     = 3  << FormShift,
8498524Sfenner
8598524Sfenner    // Data Processing instructions
8698524Sfenner    DPFrm         = 4  << FormShift,
8798524Sfenner    DPSoRegFrm    = 5  << FormShift,
8898524Sfenner
8998524Sfenner    // Load and Store
9098524Sfenner    LdFrm         = 6  << FormShift,
9198524Sfenner    StFrm         = 7  << FormShift,
9298524Sfenner    LdMiscFrm     = 8  << FormShift,
9398524Sfenner    StMiscFrm     = 9  << FormShift,
9498524Sfenner    LdStMulFrm    = 10 << FormShift,
9598524Sfenner
9698524Sfenner    // Miscellaneous arithmetic instructions
9798524Sfenner    ArithMiscFrm  = 11 << FormShift,
9898524Sfenner
9998524Sfenner    // Extend instructions
10098524Sfenner    ExtFrm        = 12 << FormShift,
10198524Sfenner
10298524Sfenner    // VFP formats
10398524Sfenner    VFPUnaryFrm   = 13 << FormShift,
10498524Sfenner    VFPBinaryFrm  = 14 << FormShift,
105127668Sbms    VFPConv1Frm   = 15 << FormShift,
106127668Sbms    VFPConv2Frm   = 16 << FormShift,
107146773Ssam    VFPConv3Frm   = 17 << FormShift,
10898524Sfenner    VFPConv4Frm   = 18 << FormShift,
10998524Sfenner    VFPConv5Frm   = 19 << FormShift,
110127668Sbms    VFPLdStFrm    = 20 << FormShift,
111127668Sbms    VFPLdStMulFrm = 21 << FormShift,
11298524Sfenner    VFPMiscFrm    = 22 << FormShift,
11398524Sfenner
11498524Sfenner    // Thumb format
11598524Sfenner    ThumbFrm      = 23 << FormShift,
11698524Sfenner
11798524Sfenner    // NEON format
11898524Sfenner    NEONFrm       = 24 << FormShift,
11998524Sfenner    NEONGetLnFrm  = 25 << FormShift,
12098524Sfenner    NEONSetLnFrm  = 26 << FormShift,
12198524Sfenner    NEONDupFrm    = 27 << FormShift,
12298524Sfenner
123127668Sbms    //===------------------------------------------------------------------===//
12498524Sfenner    // Field shifts - such shifts are used to set field while generating
12598524Sfenner    // machine instructions.
12698524Sfenner    M_BitShift     = 5,
12798524Sfenner    ShiftImmShift  = 5,
12898524Sfenner    ShiftShift     = 7,
12998524Sfenner    N_BitShift     = 7,
13098524Sfenner    ImmHiShift     = 8,
13198524Sfenner    SoRotImmShift  = 8,
13298524Sfenner    RegRsShift     = 8,
13398524Sfenner    ExtRotImmShift = 10,
13498524Sfenner    RegRdLoShift   = 12,
13598524Sfenner    RegRdShift     = 12,
13698524Sfenner    RegRdHiShift   = 16,
13798524Sfenner    RegRnShift     = 16,
13898524Sfenner    S_BitShift     = 20,
13998524Sfenner    W_BitShift     = 21,
14098524Sfenner    AM3_I_BitShift = 22,
14198524Sfenner    D_BitShift     = 22,
14298524Sfenner    U_BitShift     = 23,
14398524Sfenner    P_BitShift     = 24,
14498524Sfenner    I_BitShift     = 25,
145127668Sbms    CondShift      = 28
14698524Sfenner  };
14798524Sfenner}
14898524Sfenner
14998524Sfennerclass ARMBaseInstrInfo : public TargetInstrInfoImpl {
15098524Sfenner  const ARMRegisterInfo RI;
15198524Sfennerprotected:
152127668Sbms  // Can be only subclassed.
15398524Sfenner  explicit ARMBaseInstrInfo(const ARMSubtarget &STI);
15498524Sfennerpublic:
155214478Srpaulo
15698524Sfenner  /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info.  As
15798524Sfenner  /// such, whenever a client has an instance of instruction info, it should
15898524Sfenner  /// always be able to get register info as well (through this method).
159214478Srpaulo  ///
16098524Sfenner  virtual const ARMRegisterInfo &getRegisterInfo() const { return RI; }
16198524Sfenner
16298524Sfenner  void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
16398524Sfenner                     unsigned DestReg, const MachineInstr *Orig) const;
16498524Sfenner
16598524Sfenner  virtual MachineInstr *convertToThreeAddress(MachineFunction::iterator &MFI,
16698524Sfenner                                              MachineBasicBlock::iterator &MBBI,
16798524Sfenner                                              LiveVariables *LV) const;
16898524Sfenner
169127668Sbms  // Branch analysis.
17098524Sfenner  virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
17198524Sfenner                             MachineBasicBlock *&FBB,
17298524Sfenner                             SmallVectorImpl<MachineOperand> &Cond,
17398524Sfenner                             bool AllowModify) const;
17498524Sfenner  virtual unsigned RemoveBranch(MachineBasicBlock &MBB) const;
175127668Sbms  virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
176127668Sbms                                MachineBasicBlock *FBB,
177127668Sbms                            const SmallVectorImpl<MachineOperand> &Cond) const;
178127668Sbms
179127668Sbms  virtual bool canFoldMemoryOperand(const MachineInstr *MI,
180127668Sbms                                    const SmallVectorImpl<unsigned> &Ops) const;
18198524Sfenner
182127668Sbms  virtual bool BlockHasNoFallThrough(const MachineBasicBlock &MBB) const;
18398524Sfenner  virtual
184127668Sbms  bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const;
185127668Sbms
186127668Sbms  // Predication support.
187127668Sbms  virtual bool isPredicated(const MachineInstr *MI) const;
188127668Sbms
189127668Sbms  ARMCC::CondCodes getPredicate(const MachineInstr *MI) const {
190127668Sbms    int PIdx = MI->findFirstPredOperandIdx();
191146773Ssam    return PIdx != -1 ? (ARMCC::CondCodes)MI->getOperand(PIdx).getImm()
192127668Sbms                      : ARMCC::AL;
193127668Sbms  }
194127668Sbms
195127668Sbms  virtual
196127668Sbms  bool PredicateInstruction(MachineInstr *MI,
197127668Sbms                            const SmallVectorImpl<MachineOperand> &Pred) const;
198127668Sbms
199127668Sbms  virtual
200127668Sbms  bool SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1,
201127668Sbms                         const SmallVectorImpl<MachineOperand> &Pred2) const;
202127668Sbms
203127668Sbms  virtual bool DefinesPredicate(MachineInstr *MI,
204127668Sbms                                std::vector<MachineOperand> &Pred) const;
205127668Sbms
206127668Sbms  /// GetInstSize - Returns the size of the specified MachineInstr.
207127668Sbms  ///
208127668Sbms  virtual unsigned GetInstSizeInBytes(const MachineInstr* MI) const;
209127668Sbms};
210127668Sbms
21198524Sfennerclass ARMInstrInfo : public ARMBaseInstrInfo {
21298524Sfennerpublic:
213127668Sbms  explicit ARMInstrInfo(const ARMSubtarget &STI);
214127668Sbms
215127668Sbms  /// Return true if the instruction is a register to register move and return
216127668Sbms  /// the source and dest operands and their sub-register indices by reference.
217127668Sbms  virtual bool isMoveInstr(const MachineInstr &MI,
218127668Sbms                           unsigned &SrcReg, unsigned &DstReg,
219127668Sbms                           unsigned &SrcSubIdx, unsigned &DstSubIdx) const;
220127668Sbms
221127668Sbms  virtual unsigned isLoadFromStackSlot(const MachineInstr *MI,
222127668Sbms                                       int &FrameIndex) const;
223127668Sbms  virtual unsigned isStoreToStackSlot(const MachineInstr *MI,
224127668Sbms                                      int &FrameIndex) const;
225127668Sbms
226127668Sbms  virtual bool copyRegToReg(MachineBasicBlock &MBB,
227127668Sbms                            MachineBasicBlock::iterator I,
228127668Sbms                            unsigned DestReg, unsigned SrcReg,
229127668Sbms                            const TargetRegisterClass *DestRC,
230127668Sbms                            const TargetRegisterClass *SrcRC) const;
231127668Sbms  virtual void storeRegToStackSlot(MachineBasicBlock &MBB,
232127668Sbms                                   MachineBasicBlock::iterator MBBI,
233127668Sbms                                   unsigned SrcReg, bool isKill, int FrameIndex,
234127668Sbms                                   const TargetRegisterClass *RC) const;
235127668Sbms
236127668Sbms  virtual void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, bool isKill,
237127668Sbms                              SmallVectorImpl<MachineOperand> &Addr,
238127668Sbms                              const TargetRegisterClass *RC,
239127668Sbms                              SmallVectorImpl<MachineInstr*> &NewMIs) const;
240127668Sbms
241127668Sbms  virtual void loadRegFromStackSlot(MachineBasicBlock &MBB,
24298524Sfenner                                    MachineBasicBlock::iterator MBBI,
24398524Sfenner                                    unsigned DestReg, int FrameIndex,
244127668Sbms                                    const TargetRegisterClass *RC) const;
24598524Sfenner
24698524Sfenner  virtual void loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
24798524Sfenner                               SmallVectorImpl<MachineOperand> &Addr,
24898524Sfenner                               const TargetRegisterClass *RC,
24998524Sfenner                               SmallVectorImpl<MachineInstr*> &NewMIs) const;
25098524Sfenner
25198524Sfenner  virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
25298524Sfenner                                              MachineInstr* MI,
25398524Sfenner                                           const SmallVectorImpl<unsigned> &Ops,
25498524Sfenner                                              int FrameIndex) const;
255127668Sbms
25698524Sfenner  virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
25798524Sfenner                                              MachineInstr* MI,
25898524Sfenner                                           const SmallVectorImpl<unsigned> &Ops,
25998524Sfenner                                              MachineInstr* LoadMI) const {
26098524Sfenner    return 0;
26198524Sfenner  }
26298524Sfenner};
263146773Ssam
26498524Sfenner}
26598524Sfenner
26698524Sfenner#endif
26798524Sfenner