MachineInstrBuilder.h revision 94c1b08033b69495387a85124ca888d3c62f78c7
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 TargetInstrDesc;
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    ImplicitDefine = Implicit | Define,
38    ImplicitKill   = Implicit | Kill
39  };
40}
41
42class MachineInstrBuilder {
43  MachineInstr *MI;
44public:
45  MachineInstrBuilder() : MI(0) {}
46  explicit MachineInstrBuilder(MachineInstr *mi) : MI(mi) {}
47
48  /// Allow automatic conversion to the machine instruction we are working on.
49  ///
50  operator MachineInstr*() const { return MI; }
51  operator MachineBasicBlock::iterator() const { return MI; }
52
53  /// addReg - Add a new virtual register operand...
54  ///
55  const
56  MachineInstrBuilder &addReg(unsigned RegNo, unsigned flags = 0,
57                              unsigned SubReg = 0) const {
58    assert((flags & 0x1) == 0 &&
59           "Passing in 'true' to addReg is forbidden! Use enums instead.");
60    MI->addOperand(MachineOperand::CreateReg(RegNo,
61                                             flags & RegState::Define,
62                                             flags & RegState::Implicit,
63                                             flags & RegState::Kill,
64                                             flags & RegState::Dead,
65                                             flags & RegState::Undef,
66                                             flags & RegState::EarlyClobber,
67                                             SubReg,
68                                             flags & RegState::Debug));
69    return *this;
70  }
71
72  /// addImm - Add a new immediate operand.
73  ///
74  const MachineInstrBuilder &addImm(int64_t Val) const {
75    MI->addOperand(MachineOperand::CreateImm(Val));
76    return *this;
77  }
78
79  const MachineInstrBuilder &addFPImm(const ConstantFP *Val) const {
80    MI->addOperand(MachineOperand::CreateFPImm(Val));
81    return *this;
82  }
83
84  const MachineInstrBuilder &addMBB(MachineBasicBlock *MBB,
85                                    unsigned char TargetFlags = 0) const {
86    MI->addOperand(MachineOperand::CreateMBB(MBB, TargetFlags));
87    return *this;
88  }
89
90  const MachineInstrBuilder &addFrameIndex(unsigned Idx) const {
91    MI->addOperand(MachineOperand::CreateFI(Idx));
92    return *this;
93  }
94
95  const MachineInstrBuilder &addConstantPoolIndex(unsigned Idx,
96                                                  int Offset = 0,
97                                          unsigned char TargetFlags = 0) const {
98    MI->addOperand(MachineOperand::CreateCPI(Idx, Offset, TargetFlags));
99    return *this;
100  }
101
102  const MachineInstrBuilder &addJumpTableIndex(unsigned Idx,
103                                          unsigned char TargetFlags = 0) const {
104    MI->addOperand(MachineOperand::CreateJTI(Idx, TargetFlags));
105    return *this;
106  }
107
108  const MachineInstrBuilder &addGlobalAddress(const GlobalValue *GV,
109                                              int64_t Offset = 0,
110                                          unsigned char TargetFlags = 0) const {
111    MI->addOperand(MachineOperand::CreateGA(GV, Offset, TargetFlags));
112    return *this;
113  }
114
115  const MachineInstrBuilder &addExternalSymbol(const char *FnName,
116                                          unsigned char TargetFlags = 0) const {
117    MI->addOperand(MachineOperand::CreateES(FnName, TargetFlags));
118    return *this;
119  }
120
121  const MachineInstrBuilder &addMemOperand(MachineMemOperand *MMO) const {
122    MI->addMemOperand(*MI->getParent()->getParent(), MMO);
123    return *this;
124  }
125
126  const MachineInstrBuilder &setMemRefs(MachineInstr::mmo_iterator b,
127                                        MachineInstr::mmo_iterator e) const {
128    MI->setMemRefs(b, e);
129    return *this;
130  }
131
132
133  const MachineInstrBuilder &addOperand(const MachineOperand &MO) const {
134    MI->addOperand(MO);
135    return *this;
136  }
137
138  const MachineInstrBuilder &addMetadata(const MDNode *MD) const {
139    MI->addOperand(MachineOperand::CreateMetadata(MD));
140    return *this;
141  }
142
143  const MachineInstrBuilder &addSym(MCSymbol *Sym) const {
144    MI->addOperand(MachineOperand::CreateMCSymbol(Sym));
145    return *this;
146  }
147
148  const MachineInstrBuilder &setMIFlags(unsigned Flags) const {
149    MI->setFlags(Flags);
150    return *this;
151  }
152
153  const MachineInstrBuilder &setMIFlag(MachineInstr::MIFlag Flag) const {
154    MI->setFlag(Flag);
155    return *this;
156  }
157
158  // Add a displacement from an existing MachineOperand with an added offset.
159  const MachineInstrBuilder &addDisp(const MachineOperand &Disp,
160                                     int64_t off) const {
161    switch (Disp.getType()) {
162      default:
163        llvm_unreachable("Unhandled operand type in addDisp()");
164      case MachineOperand::MO_Immediate:
165        return addImm(Disp.getImm() + off);
166      case MachineOperand::MO_GlobalAddress:
167        return addGlobalAddress(Disp.getGlobal(), Disp.getOffset() + off);
168    }
169  }
170};
171
172/// BuildMI - Builder interface.  Specify how to create the initial instruction
173/// itself.
174///
175inline MachineInstrBuilder BuildMI(MachineFunction &MF,
176                                   DebugLoc DL,
177                                   const TargetInstrDesc &TID) {
178  return MachineInstrBuilder(MF.CreateMachineInstr(TID, DL));
179}
180
181/// BuildMI - This version of the builder sets up the first operand as a
182/// destination virtual register.
183///
184inline MachineInstrBuilder BuildMI(MachineFunction &MF,
185                                   DebugLoc DL,
186                                   const TargetInstrDesc &TID,
187                                   unsigned DestReg) {
188  return MachineInstrBuilder(MF.CreateMachineInstr(TID, DL))
189           .addReg(DestReg, RegState::Define);
190}
191
192/// BuildMI - This version of the builder inserts the newly-built
193/// instruction before the given position in the given MachineBasicBlock, and
194/// sets up the first operand as a destination virtual register.
195///
196inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
197                                   MachineBasicBlock::iterator I,
198                                   DebugLoc DL,
199                                   const TargetInstrDesc &TID,
200                                   unsigned DestReg) {
201  MachineInstr *MI = BB.getParent()->CreateMachineInstr(TID, DL);
202  BB.insert(I, MI);
203  return MachineInstrBuilder(MI).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/// does NOT take a destination register.
209///
210inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
211                                   MachineBasicBlock::iterator I,
212                                   DebugLoc DL,
213                                   const TargetInstrDesc &TID) {
214  MachineInstr *MI = BB.getParent()->CreateMachineInstr(TID, DL);
215  BB.insert(I, MI);
216  return MachineInstrBuilder(MI);
217}
218
219/// BuildMI - This version of the builder inserts the newly-built
220/// instruction at the end of the given MachineBasicBlock, and does NOT take a
221/// destination register.
222///
223inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB,
224                                   DebugLoc DL,
225                                   const TargetInstrDesc &TID) {
226  return BuildMI(*BB, BB->end(), DL, TID);
227}
228
229/// BuildMI - This version of the builder inserts the newly-built
230/// instruction at the end of the given MachineBasicBlock, and sets up the first
231/// operand as a destination virtual register.
232///
233inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB,
234                                   DebugLoc DL,
235                                   const TargetInstrDesc &TID,
236                                   unsigned DestReg) {
237  return BuildMI(*BB, BB->end(), DL, TID, DestReg);
238}
239
240inline unsigned getDefRegState(bool B) {
241  return B ? RegState::Define : 0;
242}
243inline unsigned getImplRegState(bool B) {
244  return B ? RegState::Implicit : 0;
245}
246inline unsigned getKillRegState(bool B) {
247  return B ? RegState::Kill : 0;
248}
249inline unsigned getDeadRegState(bool B) {
250  return B ? RegState::Dead : 0;
251}
252inline unsigned getUndefRegState(bool B) {
253  return B ? RegState::Undef : 0;
254}
255
256} // End llvm namespace
257
258#endif
259