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 MIPSINSTRUCTIONINFO_H
19#define MIPSINSTRUCTIONINFO_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 {
32
33class MipsInstrInfo : public MipsGenInstrInfo {
34  virtual void anchor();
35protected:
36  MipsTargetMachine &TM;
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(MipsTargetMachine &TM, unsigned UncondBrOpc);
50
51  static const MipsInstrInfo *create(MipsTargetMachine &TM);
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,
63                        const SmallVectorImpl<MachineOperand> &Cond,
64                        DebugLoc DL) const override;
65
66  bool
67  ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override;
68
69  BranchType AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
70                           MachineBasicBlock *&FBB,
71                           SmallVectorImpl<MachineOperand> &Cond,
72                           bool AllowModify,
73                           SmallVectorImpl<MachineInstr*> &BranchInstrs) const;
74
75  /// Insert nop instruction when hazard condition is found
76  void insertNoop(MachineBasicBlock &MBB,
77                  MachineBasicBlock::iterator MI) const override;
78
79  /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info.  As
80  /// such, whenever a client has an instance of instruction info, it should
81  /// always be able to get register info as well (through this method).
82  ///
83  virtual const MipsRegisterInfo &getRegisterInfo() const = 0;
84
85  virtual unsigned getOppositeBranchOpc(unsigned Opc) const = 0;
86
87  /// Return the number of bytes of code the specified instruction may be.
88  unsigned GetInstSizeInBytes(const MachineInstr *MI) const;
89
90  void storeRegToStackSlot(MachineBasicBlock &MBB,
91                           MachineBasicBlock::iterator MBBI,
92                           unsigned SrcReg, bool isKill, int FrameIndex,
93                           const TargetRegisterClass *RC,
94                           const TargetRegisterInfo *TRI) const override {
95    storeRegToStack(MBB, MBBI, SrcReg, isKill, FrameIndex, RC, TRI, 0);
96  }
97
98  void loadRegFromStackSlot(MachineBasicBlock &MBB,
99                            MachineBasicBlock::iterator MBBI,
100                            unsigned DestReg, int FrameIndex,
101                            const TargetRegisterClass *RC,
102                            const TargetRegisterInfo *TRI) const override {
103    loadRegFromStack(MBB, MBBI, DestReg, FrameIndex, RC, TRI, 0);
104  }
105
106  virtual void storeRegToStack(MachineBasicBlock &MBB,
107                               MachineBasicBlock::iterator MI,
108                               unsigned SrcReg, bool isKill, int FrameIndex,
109                               const TargetRegisterClass *RC,
110                               const TargetRegisterInfo *TRI,
111                               int64_t Offset) const = 0;
112
113  virtual void loadRegFromStack(MachineBasicBlock &MBB,
114                                MachineBasicBlock::iterator MI,
115                                unsigned DestReg, int FrameIndex,
116                                const TargetRegisterClass *RC,
117                                const TargetRegisterInfo *TRI,
118                                int64_t Offset) const = 0;
119
120  /// Create an instruction which has the same operands and memory operands
121  /// as MI but has a new opcode.
122  MachineInstrBuilder genInstrWithNewOpc(unsigned NewOpc,
123                                         MachineBasicBlock::iterator I) const;
124
125protected:
126  bool isZeroImm(const MachineOperand &op) const;
127
128  MachineMemOperand *GetMemOperand(MachineBasicBlock &MBB, int FI,
129                                   unsigned Flag) const;
130
131private:
132  virtual unsigned getAnalyzableBrOpc(unsigned Opc) const = 0;
133
134  void AnalyzeCondBr(const MachineInstr *Inst, unsigned Opc,
135                     MachineBasicBlock *&BB,
136                     SmallVectorImpl<MachineOperand> &Cond) const;
137
138  void BuildCondBr(MachineBasicBlock &MBB, MachineBasicBlock *TBB, DebugLoc DL,
139                   const SmallVectorImpl<MachineOperand>& Cond) const;
140};
141
142/// Create MipsInstrInfo objects.
143const MipsInstrInfo *createMips16InstrInfo(MipsTargetMachine &TM);
144const MipsInstrInfo *createMipsSEInstrInfo(MipsTargetMachine &TM);
145
146}
147
148#endif
149