MachineInstrBuilder.h revision 4efea94fa54d0e8687b965fdf3ba46022c8e15c4
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#include "llvm/Support/ErrorHandling.h"
22
23namespace llvm {
24
25class MCInstrDesc;
26class MDNode;
27
28namespace RegState {
29  enum {
30    Define         = 0x2,
31    Implicit       = 0x4,
32    Kill           = 0x8,
33    Dead           = 0x10,
34    Undef          = 0x20,
35    EarlyClobber   = 0x40,
36    Debug          = 0x80,
37    InternalRead   = 0x100,
38    DefineNoRead   = Define | Undef,
39    ImplicitDefine = Implicit | Define,
40    ImplicitKill   = Implicit | Kill
41  };
42}
43
44class MachineInstrBuilder {
45  MachineInstr *MI;
46public:
47  MachineInstrBuilder() : MI(0) {}
48  explicit MachineInstrBuilder(MachineInstr *mi) : MI(mi) {}
49
50  /// Allow automatic conversion to the machine instruction we are working on.
51  ///
52  operator MachineInstr*() const { return MI; }
53  MachineInstr *operator->() const { return MI; }
54  operator MachineBasicBlock::iterator() const { return MI; }
55
56  /// addReg - Add a new virtual register operand...
57  ///
58  const
59  MachineInstrBuilder &addReg(unsigned RegNo, unsigned flags = 0,
60                              unsigned SubReg = 0) const {
61    assert((flags & 0x1) == 0 &&
62           "Passing in 'true' to addReg is forbidden! Use enums instead.");
63    MI->addOperand(MachineOperand::CreateReg(RegNo,
64                                             flags & RegState::Define,
65                                             flags & RegState::Implicit,
66                                             flags & RegState::Kill,
67                                             flags & RegState::Dead,
68                                             flags & RegState::Undef,
69                                             flags & RegState::EarlyClobber,
70                                             SubReg,
71                                             flags & RegState::Debug,
72                                             flags & RegState::InternalRead));
73    return *this;
74  }
75
76  /// addImm - Add a new immediate operand.
77  ///
78  const MachineInstrBuilder &addImm(int64_t Val) const {
79    MI->addOperand(MachineOperand::CreateImm(Val));
80    return *this;
81  }
82
83  const MachineInstrBuilder &addCImm(const ConstantInt *Val) const {
84    MI->addOperand(MachineOperand::CreateCImm(Val));
85    return *this;
86  }
87
88  const MachineInstrBuilder &addFPImm(const ConstantFP *Val) const {
89    MI->addOperand(MachineOperand::CreateFPImm(Val));
90    return *this;
91  }
92
93  const MachineInstrBuilder &addMBB(MachineBasicBlock *MBB,
94                                    unsigned char TargetFlags = 0) const {
95    MI->addOperand(MachineOperand::CreateMBB(MBB, TargetFlags));
96    return *this;
97  }
98
99  const MachineInstrBuilder &addFrameIndex(int Idx) const {
100    MI->addOperand(MachineOperand::CreateFI(Idx));
101    return *this;
102  }
103
104  const MachineInstrBuilder &addConstantPoolIndex(unsigned Idx,
105                                                  int Offset = 0,
106                                          unsigned char TargetFlags = 0) const {
107    MI->addOperand(MachineOperand::CreateCPI(Idx, Offset, TargetFlags));
108    return *this;
109  }
110
111  const MachineInstrBuilder &addJumpTableIndex(unsigned Idx,
112                                          unsigned char TargetFlags = 0) const {
113    MI->addOperand(MachineOperand::CreateJTI(Idx, TargetFlags));
114    return *this;
115  }
116
117  const MachineInstrBuilder &addGlobalAddress(const GlobalValue *GV,
118                                              int64_t Offset = 0,
119                                          unsigned char TargetFlags = 0) const {
120    MI->addOperand(MachineOperand::CreateGA(GV, Offset, TargetFlags));
121    return *this;
122  }
123
124  const MachineInstrBuilder &addExternalSymbol(const char *FnName,
125                                          unsigned char TargetFlags = 0) const {
126    MI->addOperand(MachineOperand::CreateES(FnName, TargetFlags));
127    return *this;
128  }
129
130  const MachineInstrBuilder &addRegMask(const uint32_t *Mask) const {
131    MI->addOperand(MachineOperand::CreateRegMask(Mask));
132    return *this;
133  }
134
135  const MachineInstrBuilder &addMemOperand(MachineMemOperand *MMO) const {
136    MI->addMemOperand(*MI->getParent()->getParent(), MMO);
137    return *this;
138  }
139
140  const MachineInstrBuilder &setMemRefs(MachineInstr::mmo_iterator b,
141                                        MachineInstr::mmo_iterator e) const {
142    MI->setMemRefs(b, e);
143    return *this;
144  }
145
146
147  const MachineInstrBuilder &addOperand(const MachineOperand &MO) const {
148    MI->addOperand(MO);
149    return *this;
150  }
151
152  const MachineInstrBuilder &addMetadata(const MDNode *MD) const {
153    MI->addOperand(MachineOperand::CreateMetadata(MD));
154    return *this;
155  }
156
157  const MachineInstrBuilder &addSym(MCSymbol *Sym) const {
158    MI->addOperand(MachineOperand::CreateMCSymbol(Sym));
159    return *this;
160  }
161
162  const MachineInstrBuilder &setMIFlags(unsigned Flags) const {
163    MI->setFlags(Flags);
164    return *this;
165  }
166
167  const MachineInstrBuilder &setMIFlag(MachineInstr::MIFlag Flag) const {
168    MI->setFlag(Flag);
169    return *this;
170  }
171
172  // Add a displacement from an existing MachineOperand with an added offset.
173  const MachineInstrBuilder &addDisp(const MachineOperand &Disp,
174                                     int64_t off) const {
175    switch (Disp.getType()) {
176      default:
177        llvm_unreachable("Unhandled operand type in addDisp()");
178      case MachineOperand::MO_Immediate:
179        return addImm(Disp.getImm() + off);
180      case MachineOperand::MO_GlobalAddress:
181        return addGlobalAddress(Disp.getGlobal(), Disp.getOffset() + off);
182    }
183  }
184};
185
186/// BuildMI - Builder interface.  Specify how to create the initial instruction
187/// itself.
188///
189inline MachineInstrBuilder BuildMI(MachineFunction &MF,
190                                   DebugLoc DL,
191                                   const MCInstrDesc &MCID) {
192  return MachineInstrBuilder(MF.CreateMachineInstr(MCID, DL));
193}
194
195/// BuildMI - This version of the builder sets up the first operand as a
196/// destination virtual register.
197///
198inline MachineInstrBuilder BuildMI(MachineFunction &MF,
199                                   DebugLoc DL,
200                                   const MCInstrDesc &MCID,
201                                   unsigned DestReg) {
202  return MachineInstrBuilder(MF.CreateMachineInstr(MCID, DL))
203           .addReg(DestReg, RegState::Define);
204}
205
206/// BuildMI - This version of the builder inserts the newly-built
207/// instruction before the given position in the given MachineBasicBlock, and
208/// sets up the first operand as a destination virtual register.
209///
210inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
211                                   MachineBasicBlock::iterator I,
212                                   DebugLoc DL,
213                                   const MCInstrDesc &MCID,
214                                   unsigned DestReg) {
215  MachineInstr *MI = BB.getParent()->CreateMachineInstr(MCID, DL);
216  BB.insert(I, MI);
217  return MachineInstrBuilder(MI).addReg(DestReg, RegState::Define);
218}
219
220inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
221                                   MachineBasicBlock::instr_iterator I,
222                                   DebugLoc DL,
223                                   const MCInstrDesc &MCID,
224                                   unsigned DestReg) {
225  MachineInstr *MI = BB.getParent()->CreateMachineInstr(MCID, DL);
226  BB.insert(I, MI);
227  return MachineInstrBuilder(MI).addReg(DestReg, RegState::Define);
228}
229
230inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
231                                   MachineInstr *I,
232                                   DebugLoc DL,
233                                   const MCInstrDesc &MCID,
234                                   unsigned DestReg) {
235  if (I->isInsideBundle()) {
236    MachineBasicBlock::instr_iterator MII = I;
237    return BuildMI(BB, MII, DL, MCID, DestReg);
238  }
239
240  MachineBasicBlock::iterator MII = I;
241  return BuildMI(BB, MII, DL, MCID, DestReg);
242}
243
244/// BuildMI - This version of the builder inserts the newly-built
245/// instruction before the given position in the given MachineBasicBlock, and
246/// does NOT take a destination register.
247///
248inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
249                                   MachineBasicBlock::iterator I,
250                                   DebugLoc DL,
251                                   const MCInstrDesc &MCID) {
252  MachineInstr *MI = BB.getParent()->CreateMachineInstr(MCID, DL);
253  BB.insert(I, MI);
254  return MachineInstrBuilder(MI);
255}
256
257inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
258                                   MachineBasicBlock::instr_iterator I,
259                                   DebugLoc DL,
260                                   const MCInstrDesc &MCID) {
261  MachineInstr *MI = BB.getParent()->CreateMachineInstr(MCID, DL);
262  BB.insert(I, MI);
263  return MachineInstrBuilder(MI);
264}
265
266inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
267                                   MachineInstr *I,
268                                   DebugLoc DL,
269                                   const MCInstrDesc &MCID) {
270  if (I->isInsideBundle()) {
271    MachineBasicBlock::instr_iterator MII = I;
272    return BuildMI(BB, MII, DL, MCID);
273  }
274
275  MachineBasicBlock::iterator MII = I;
276  return BuildMI(BB, MII, DL, MCID);
277}
278
279/// BuildMI - This version of the builder inserts the newly-built
280/// instruction at the end of the given MachineBasicBlock, and does NOT take a
281/// destination register.
282///
283inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB,
284                                   DebugLoc DL,
285                                   const MCInstrDesc &MCID) {
286  return BuildMI(*BB, BB->end(), DL, MCID);
287}
288
289/// BuildMI - This version of the builder inserts the newly-built
290/// instruction at the end of the given MachineBasicBlock, and sets up the first
291/// operand as a destination virtual register.
292///
293inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB,
294                                   DebugLoc DL,
295                                   const MCInstrDesc &MCID,
296                                   unsigned DestReg) {
297  return BuildMI(*BB, BB->end(), DL, MCID, DestReg);
298}
299
300inline unsigned getDefRegState(bool B) {
301  return B ? RegState::Define : 0;
302}
303inline unsigned getImplRegState(bool B) {
304  return B ? RegState::Implicit : 0;
305}
306inline unsigned getKillRegState(bool B) {
307  return B ? RegState::Kill : 0;
308}
309inline unsigned getDeadRegState(bool B) {
310  return B ? RegState::Dead : 0;
311}
312inline unsigned getUndefRegState(bool B) {
313  return B ? RegState::Undef : 0;
314}
315inline unsigned getInternalReadRegState(bool B) {
316  return B ? RegState::InternalRead : 0;
317}
318
319} // End llvm namespace
320
321#endif
322