1//===-- MipsInstrInfo.h - Mips 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 Mips implementation of the TargetInstrInfo class.
11//
12// FIXME: We need to override TargetInstrInfo::getInlineAsmLength method in
13// order for MipsLongBranch pass to work correctly when the code has inline
14// assembly.  The returned value doesn't have to be the asm instruction's exact
15// size in bytes; MipsLongBranch only expects it to be the correct upper bound.
16//===----------------------------------------------------------------------===//
17
18#ifndef LLVM_LIB_TARGET_MIPS_MIPSINSTRINFO_H
19#define LLVM_LIB_TARGET_MIPS_MIPSINSTRINFO_H
20
21#include "Mips.h"
22#include "MipsAnalyzeImmediate.h"
23#include "MipsRegisterInfo.h"
24#include "llvm/CodeGen/MachineInstrBuilder.h"
25#include "llvm/Support/ErrorHandling.h"
26#include "llvm/Target/TargetInstrInfo.h"
27
28#define GET_INSTRINFO_HEADER
29#include "MipsGenInstrInfo.inc"
30
31namespace llvm {
32class MipsSubtarget;
33class MipsInstrInfo : public MipsGenInstrInfo {
34  virtual void anchor();
35protected:
36  const MipsSubtarget &Subtarget;
37  unsigned UncondBrOpc;
38
39public:
40  enum BranchType {
41    BT_None,       // Couldn't analyze branch.
42    BT_NoBranch,   // No branches found.
43    BT_Uncond,     // One unconditional branch.
44    BT_Cond,       // One conditional branch.
45    BT_CondUncond, // A conditional branch followed by an unconditional branch.
46    BT_Indirect    // One indirct branch.
47  };
48
49  explicit MipsInstrInfo(const MipsSubtarget &STI, unsigned UncondBrOpc);
50
51  static const MipsInstrInfo *create(MipsSubtarget &STI);
52
53  /// Branch Analysis
54  bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
55                     MachineBasicBlock *&FBB,
56                     SmallVectorImpl<MachineOperand> &Cond,
57                     bool AllowModify) const override;
58
59  unsigned RemoveBranch(MachineBasicBlock &MBB) const override;
60
61  unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
62                        MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond,
63                        DebugLoc DL) const override;
64
65  bool
66  ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override;
67
68  BranchType AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
69                           MachineBasicBlock *&FBB,
70                           SmallVectorImpl<MachineOperand> &Cond,
71                           bool AllowModify,
72                           SmallVectorImpl<MachineInstr*> &BranchInstrs) const;
73
74  /// Insert nop instruction when hazard condition is found
75  void insertNoop(MachineBasicBlock &MBB,
76                  MachineBasicBlock::iterator MI) const override;
77
78  /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info.  As
79  /// such, whenever a client has an instance of instruction info, it should
80  /// always be able to get register info as well (through this method).
81  ///
82  virtual const MipsRegisterInfo &getRegisterInfo() const = 0;
83
84  virtual unsigned getOppositeBranchOpc(unsigned Opc) const = 0;
85
86  /// Return the number of bytes of code the specified instruction may be.
87  unsigned GetInstSizeInBytes(const MachineInstr *MI) const;
88
89  void storeRegToStackSlot(MachineBasicBlock &MBB,
90                           MachineBasicBlock::iterator MBBI,
91                           unsigned SrcReg, bool isKill, int FrameIndex,
92                           const TargetRegisterClass *RC,
93                           const TargetRegisterInfo *TRI) const override {
94    storeRegToStack(MBB, MBBI, SrcReg, isKill, FrameIndex, RC, TRI, 0);
95  }
96
97  void loadRegFromStackSlot(MachineBasicBlock &MBB,
98                            MachineBasicBlock::iterator MBBI,
99                            unsigned DestReg, int FrameIndex,
100                            const TargetRegisterClass *RC,
101                            const TargetRegisterInfo *TRI) const override {
102    loadRegFromStack(MBB, MBBI, DestReg, FrameIndex, RC, TRI, 0);
103  }
104
105  virtual void storeRegToStack(MachineBasicBlock &MBB,
106                               MachineBasicBlock::iterator MI,
107                               unsigned SrcReg, bool isKill, int FrameIndex,
108                               const TargetRegisterClass *RC,
109                               const TargetRegisterInfo *TRI,
110                               int64_t Offset) const = 0;
111
112  virtual void loadRegFromStack(MachineBasicBlock &MBB,
113                                MachineBasicBlock::iterator MI,
114                                unsigned DestReg, int FrameIndex,
115                                const TargetRegisterClass *RC,
116                                const TargetRegisterInfo *TRI,
117                                int64_t Offset) const = 0;
118
119  virtual void adjustStackPtr(unsigned SP, int64_t Amount,
120                              MachineBasicBlock &MBB,
121                              MachineBasicBlock::iterator I) const = 0;
122
123  /// Create an instruction which has the same operands and memory operands
124  /// as MI but has a new opcode.
125  MachineInstrBuilder genInstrWithNewOpc(unsigned NewOpc,
126                                         MachineBasicBlock::iterator I) const;
127
128protected:
129  bool isZeroImm(const MachineOperand &op) const;
130
131  MachineMemOperand *GetMemOperand(MachineBasicBlock &MBB, int FI,
132                                   unsigned Flag) const;
133
134private:
135  virtual unsigned getAnalyzableBrOpc(unsigned Opc) const = 0;
136
137  void AnalyzeCondBr(const MachineInstr *Inst, unsigned Opc,
138                     MachineBasicBlock *&BB,
139                     SmallVectorImpl<MachineOperand> &Cond) const;
140
141  void BuildCondBr(MachineBasicBlock &MBB, MachineBasicBlock *TBB, DebugLoc DL,
142                   ArrayRef<MachineOperand> Cond) const;
143};
144
145/// Create MipsInstrInfo objects.
146const MipsInstrInfo *createMips16InstrInfo(const MipsSubtarget &STI);
147const MipsInstrInfo *createMipsSEInstrInfo(const MipsSubtarget &STI);
148
149}
150
151#endif
152