1235633Sdim//===-- MipsInstrInfo.h - Mips Instruction Information ----------*- C++ -*-===//
2193323Sed//
3193323Sed//                     The LLVM Compiler Infrastructure
4193323Sed//
5193323Sed// This file is distributed under the University of Illinois Open Source
6193323Sed// License. See LICENSE.TXT for details.
7193323Sed//
8193323Sed//===----------------------------------------------------------------------===//
9193323Sed//
10193323Sed// This file contains the Mips implementation of the TargetInstrInfo class.
11193323Sed//
12193323Sed//===----------------------------------------------------------------------===//
13193323Sed
14193323Sed#ifndef MIPSINSTRUCTIONINFO_H
15193323Sed#define MIPSINSTRUCTIONINFO_H
16193323Sed
17193323Sed#include "Mips.h"
18245431Sdim#include "MipsAnalyzeImmediate.h"
19235633Sdim#include "MipsRegisterInfo.h"
20263509Sdim#include "llvm/CodeGen/MachineInstrBuilder.h"
21198090Srdivacky#include "llvm/Support/ErrorHandling.h"
22193323Sed#include "llvm/Target/TargetInstrInfo.h"
23193323Sed
24224145Sdim#define GET_INSTRINFO_HEADER
25224145Sdim#include "MipsGenInstrInfo.inc"
26224145Sdim
27193323Sednamespace llvm {
28193323Sed
29224145Sdimclass MipsInstrInfo : public MipsGenInstrInfo {
30263509Sdim  virtual void anchor();
31245431Sdimprotected:
32193323Sed  MipsTargetMachine &TM;
33235633Sdim  unsigned UncondBrOpc;
34245431Sdim
35193323Sedpublic:
36252723Sdim  enum BranchType {
37252723Sdim    BT_None,       // Couldn't analyze branch.
38252723Sdim    BT_NoBranch,   // No branches found.
39252723Sdim    BT_Uncond,     // One unconditional branch.
40252723Sdim    BT_Cond,       // One conditional branch.
41252723Sdim    BT_CondUncond, // A conditional branch followed by an unconditional branch.
42252723Sdim    BT_Indirect    // One indirct branch.
43252723Sdim  };
44252723Sdim
45245431Sdim  explicit MipsInstrInfo(MipsTargetMachine &TM, unsigned UncondBrOpc);
46193323Sed
47245431Sdim  static const MipsInstrInfo *create(MipsTargetMachine &TM);
48193323Sed
49193323Sed  /// Branch Analysis
50193323Sed  virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
51193323Sed                             MachineBasicBlock *&FBB,
52193323Sed                             SmallVectorImpl<MachineOperand> &Cond,
53193323Sed                             bool AllowModify) const;
54245431Sdim
55193323Sed  virtual unsigned RemoveBranch(MachineBasicBlock &MBB) const;
56221345Sdim
57193323Sed  virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
58193323Sed                                MachineBasicBlock *FBB,
59210299Sed                                const SmallVectorImpl<MachineOperand> &Cond,
60210299Sed                                DebugLoc DL) const;
61193323Sed
62245431Sdim  virtual
63245431Sdim  bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const;
64193323Sed
65252723Sdim  BranchType AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
66252723Sdim                           MachineBasicBlock *&FBB,
67252723Sdim                           SmallVectorImpl<MachineOperand> &Cond,
68252723Sdim                           bool AllowModify,
69252723Sdim                           SmallVectorImpl<MachineInstr*> &BranchInstrs) const;
70252723Sdim
71193323Sed  /// Insert nop instruction when hazard condition is found
72221345Sdim  virtual void insertNoop(MachineBasicBlock &MBB,
73193323Sed                          MachineBasicBlock::iterator MI) const;
74245431Sdim
75245431Sdim  /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info.  As
76245431Sdim  /// such, whenever a client has an instance of instruction info, it should
77245431Sdim  /// always be able to get register info as well (through this method).
78245431Sdim  ///
79245431Sdim  virtual const MipsRegisterInfo &getRegisterInfo() const = 0;
80245431Sdim
81263509Sdim  virtual unsigned getOppositeBranchOpc(unsigned Opc) const = 0;
82245431Sdim
83245431Sdim  /// Return the number of bytes of code the specified instruction may be.
84245431Sdim  unsigned GetInstSizeInBytes(const MachineInstr *MI) const;
85245431Sdim
86252723Sdim  virtual void storeRegToStackSlot(MachineBasicBlock &MBB,
87252723Sdim                                   MachineBasicBlock::iterator MBBI,
88252723Sdim                                   unsigned SrcReg, bool isKill, int FrameIndex,
89252723Sdim                                   const TargetRegisterClass *RC,
90252723Sdim                                   const TargetRegisterInfo *TRI) const {
91252723Sdim    storeRegToStack(MBB, MBBI, SrcReg, isKill, FrameIndex, RC, TRI, 0);
92252723Sdim  }
93252723Sdim
94252723Sdim  virtual void loadRegFromStackSlot(MachineBasicBlock &MBB,
95252723Sdim                                    MachineBasicBlock::iterator MBBI,
96252723Sdim                                    unsigned DestReg, int FrameIndex,
97252723Sdim                                    const TargetRegisterClass *RC,
98252723Sdim                                    const TargetRegisterInfo *TRI) const {
99252723Sdim    loadRegFromStack(MBB, MBBI, DestReg, FrameIndex, RC, TRI, 0);
100252723Sdim  }
101252723Sdim
102252723Sdim  virtual void storeRegToStack(MachineBasicBlock &MBB,
103252723Sdim                               MachineBasicBlock::iterator MI,
104252723Sdim                               unsigned SrcReg, bool isKill, int FrameIndex,
105252723Sdim                               const TargetRegisterClass *RC,
106252723Sdim                               const TargetRegisterInfo *TRI,
107252723Sdim                               int64_t Offset) const = 0;
108252723Sdim
109252723Sdim  virtual void loadRegFromStack(MachineBasicBlock &MBB,
110252723Sdim                                MachineBasicBlock::iterator MI,
111252723Sdim                                unsigned DestReg, int FrameIndex,
112252723Sdim                                const TargetRegisterClass *RC,
113252723Sdim                                const TargetRegisterInfo *TRI,
114252723Sdim                                int64_t Offset) const = 0;
115252723Sdim
116263509Sdim  /// Create an instruction which has the same operands and memory operands
117263509Sdim  /// as MI but has a new opcode.
118263509Sdim  MachineInstrBuilder genInstrWithNewOpc(unsigned NewOpc,
119263509Sdim                                         MachineBasicBlock::iterator I) const;
120263509Sdim
121245431Sdimprotected:
122245431Sdim  bool isZeroImm(const MachineOperand &op) const;
123245431Sdim
124245431Sdim  MachineMemOperand *GetMemOperand(MachineBasicBlock &MBB, int FI,
125245431Sdim                                   unsigned Flag) const;
126245431Sdim
127245431Sdimprivate:
128263509Sdim  virtual unsigned getAnalyzableBrOpc(unsigned Opc) const = 0;
129245431Sdim
130245431Sdim  void AnalyzeCondBr(const MachineInstr *Inst, unsigned Opc,
131245431Sdim                     MachineBasicBlock *&BB,
132245431Sdim                     SmallVectorImpl<MachineOperand> &Cond) const;
133245431Sdim
134245431Sdim  void BuildCondBr(MachineBasicBlock &MBB, MachineBasicBlock *TBB, DebugLoc DL,
135245431Sdim                   const SmallVectorImpl<MachineOperand>& Cond) const;
136193323Sed};
137193323Sed
138245431Sdim/// Create MipsInstrInfo objects.
139245431Sdimconst MipsInstrInfo *createMips16InstrInfo(MipsTargetMachine &TM);
140245431Sdimconst MipsInstrInfo *createMipsSEInstrInfo(MipsTargetMachine &TM);
141245431Sdim
142193323Sed}
143193323Sed
144193323Sed#endif
145