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