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