MachineInstrBuilder.h revision 9a96c425db72bc6e879e8445e3a3bf1f1e556b56
1//===-- CodeGen/MachineInstBuilder.h - Simplify creation of MIs -*- 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 exposes a function named BuildMI, which is useful for dramatically
11// simplifying how MachineInstr's are created.  It allows use of code like this:
12//
13//   M = BuildMI(X86::ADDrr8, 2).addReg(argVal1).addReg(argVal2);
14//
15//===----------------------------------------------------------------------===//
16
17#ifndef LLVM_CODEGEN_MACHINEINSTRBUILDER_H
18#define LLVM_CODEGEN_MACHINEINSTRBUILDER_H
19
20#include "llvm/CodeGen/MachineFunction.h"
21
22namespace llvm {
23
24class TargetInstrDesc;
25
26namespace RegState {
27  enum {
28    Define         = 0x2,
29    Implicit       = 0x4,
30    Kill           = 0x8,
31    Dead           = 0x10,
32    EarlyClobber   = 0x20,
33    ImplicitDefine = Implicit | Define,
34    ImplicitKill   = Implicit | Kill
35  };
36}
37
38class MachineInstrBuilder {
39  MachineInstr *MI;
40public:
41  explicit MachineInstrBuilder(MachineInstr *mi) : MI(mi) {}
42
43  /// Allow automatic conversion to the machine instruction we are working on.
44  ///
45  operator MachineInstr*() const { return MI; }
46  operator MachineBasicBlock::iterator() const { return MI; }
47
48  /// addReg - Add a new virtual register operand...
49  ///
50  const
51  MachineInstrBuilder &addReg(unsigned RegNo, unsigned flags = 0,
52                              unsigned SubReg = 0) const {
53    assert((flags & 0x1) == 0 &&
54           "Passing in 'true' to addReg is forbidden! Use enums instead.");
55    MI->addOperand(MachineOperand::CreateReg(RegNo,
56                                             flags & RegState::Define,
57                                             flags & RegState::Implicit,
58                                             flags & RegState::Kill,
59                                             flags & RegState::Dead,
60                                             SubReg,
61                                             flags & RegState::EarlyClobber));
62    return *this;
63  }
64
65  /// addImm - Add a new immediate operand.
66  ///
67  const MachineInstrBuilder &addImm(int64_t Val) const {
68    MI->addOperand(MachineOperand::CreateImm(Val));
69    return *this;
70  }
71
72  const MachineInstrBuilder &addFPImm(const ConstantFP *Val) const {
73    MI->addOperand(MachineOperand::CreateFPImm(Val));
74    return *this;
75  }
76
77  const MachineInstrBuilder &addMBB(MachineBasicBlock *MBB,
78                                    unsigned char TargetFlags = 0) const {
79    MI->addOperand(MachineOperand::CreateMBB(MBB, TargetFlags));
80    return *this;
81  }
82
83  const MachineInstrBuilder &addFrameIndex(unsigned Idx) const {
84    MI->addOperand(MachineOperand::CreateFI(Idx));
85    return *this;
86  }
87
88  const MachineInstrBuilder &addConstantPoolIndex(unsigned Idx,
89                                                  int Offset = 0,
90                                          unsigned char TargetFlags = 0) const {
91    MI->addOperand(MachineOperand::CreateCPI(Idx, Offset, TargetFlags));
92    return *this;
93  }
94
95  const MachineInstrBuilder &addJumpTableIndex(unsigned Idx,
96                                          unsigned char TargetFlags = 0) const {
97    MI->addOperand(MachineOperand::CreateJTI(Idx, TargetFlags));
98    return *this;
99  }
100
101  const MachineInstrBuilder &addGlobalAddress(GlobalValue *GV,
102                                              int64_t Offset = 0,
103                                          unsigned char TargetFlags = 0) const {
104    MI->addOperand(MachineOperand::CreateGA(GV, Offset, TargetFlags));
105    return *this;
106  }
107
108  const MachineInstrBuilder &addExternalSymbol(const char *FnName,
109                                               int64_t Offset = 0,
110                                          unsigned char TargetFlags = 0) const {
111    MI->addOperand(MachineOperand::CreateES(FnName, Offset, TargetFlags));
112    return *this;
113  }
114
115  const MachineInstrBuilder &addMemOperand(const MachineMemOperand &MMO) const {
116    MI->addMemOperand(*MI->getParent()->getParent(), MMO);
117    return *this;
118  }
119
120  const MachineInstrBuilder &addOperand(const MachineOperand &MO) const {
121    if (MO.isReg())
122      return addReg(MO.getReg(),
123                    (MO.isDef() ? RegState::Define : 0) |
124                    (MO.isImplicit() ? RegState::Implicit : 0) |
125                    (MO.isKill() ? RegState::Kill : 0) |
126                    (MO.isDead() ? RegState::Dead : 0) |
127                    (MO.isEarlyClobber() ? RegState::EarlyClobber : 0),
128                    MO.getSubReg());
129    if (MO.isImm())
130      return addImm(MO.getImm());
131    if (MO.isFI())
132      return addFrameIndex(MO.getIndex());
133    if (MO.isGlobal())
134      return addGlobalAddress(MO.getGlobal(), MO.getOffset(),
135                              MO.getTargetFlags());
136    if (MO.isCPI())
137      return addConstantPoolIndex(MO.getIndex(), MO.getOffset(),
138                                  MO.getTargetFlags());
139    if (MO.isSymbol())
140      return addExternalSymbol(MO.getSymbolName(), MO.getOffset(),
141                               MO.getTargetFlags());
142    if (MO.isJTI())
143      return addJumpTableIndex(MO.getIndex(),
144                               MO.getTargetFlags());
145
146    assert(0 && "Unknown operand for MachineInstrBuilder::AddOperand!");
147    return *this;
148  }
149};
150
151/// BuildMI - Builder interface.  Specify how to create the initial instruction
152/// itself.
153///
154inline MachineInstrBuilder BuildMI(MachineFunction &MF,
155                                   DebugLoc DL,
156                                   const TargetInstrDesc &TID) {
157  return MachineInstrBuilder(MF.CreateMachineInstr(TID, DL));
158}
159
160/// BuildMI - This version of the builder sets up the first operand as a
161/// destination virtual register.
162///
163inline MachineInstrBuilder BuildMI(MachineFunction &MF,
164                                   DebugLoc DL,
165                                   const TargetInstrDesc &TID,
166                                   unsigned DestReg) {
167  return MachineInstrBuilder(MF.CreateMachineInstr(TID, DL))
168           .addReg(DestReg, RegState::Define);
169}
170
171/// BuildMI - This version of the builder inserts the newly-built
172/// instruction before the given position in the given MachineBasicBlock, and
173/// sets up the first operand as a destination virtual register.
174///
175inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
176                                   MachineBasicBlock::iterator I,
177                                   DebugLoc DL,
178                                   const TargetInstrDesc &TID,
179                                   unsigned DestReg) {
180  MachineInstr *MI = BB.getParent()->CreateMachineInstr(TID, DL);
181  BB.insert(I, MI);
182  return MachineInstrBuilder(MI).addReg(DestReg, RegState::Define);
183}
184
185/// BuildMI - This version of the builder inserts the newly-built
186/// instruction before the given position in the given MachineBasicBlock, and
187/// does NOT take a destination register.
188///
189inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
190                                   MachineBasicBlock::iterator I,
191                                   DebugLoc DL,
192                                   const TargetInstrDesc &TID) {
193  MachineInstr *MI = BB.getParent()->CreateMachineInstr(TID, DL);
194  BB.insert(I, MI);
195  return MachineInstrBuilder(MI);
196}
197
198/// BuildMI - This version of the builder inserts the newly-built
199/// instruction at the end of the given MachineBasicBlock, and does NOT take a
200/// destination register.
201///
202inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB,
203                                   DebugLoc DL,
204                                   const TargetInstrDesc &TID) {
205  return BuildMI(*BB, BB->end(), DL, TID);
206}
207
208/// BuildMI - This version of the builder inserts the newly-built
209/// instruction at the end of the given MachineBasicBlock, and sets up the first
210/// operand as a destination virtual register.
211///
212inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB,
213                                   DebugLoc DL,
214                                   const TargetInstrDesc &TID,
215                                   unsigned DestReg) {
216  return BuildMI(*BB, BB->end(), DL, TID, DestReg);
217}
218
219inline unsigned getDefRegState(bool B) {
220  return B ? RegState::Define : 0;
221}
222inline unsigned getImplRegState(bool B) {
223  return B ? RegState::Implicit : 0;
224}
225inline unsigned getKillRegState(bool B) {
226  return B ? RegState::Kill : 0;
227}
228inline unsigned getDeadRegState(bool B) {
229  return B ? RegState::Dead : 0;
230}
231
232} // End llvm namespace
233
234#endif
235