MachineInstrBuilder.h revision 4784f1fc73abf6005b7b7262d395af71b57b1255
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    Undef          = 0x20,
33    EarlyClobber   = 0x40,
34    ImplicitDefine = Implicit | Define,
35    ImplicitKill   = Implicit | Kill
36  };
37}
38
39class MachineInstrBuilder {
40  MachineInstr *MI;
41public:
42  explicit MachineInstrBuilder(MachineInstr *mi) : MI(mi) {}
43
44  /// Allow automatic conversion to the machine instruction we are working on.
45  ///
46  operator MachineInstr*() const { return MI; }
47  operator MachineBasicBlock::iterator() const { return MI; }
48
49  /// addReg - Add a new virtual register operand...
50  ///
51  const
52  MachineInstrBuilder &addReg(unsigned RegNo, unsigned flags = 0,
53                              unsigned SubReg = 0) const {
54    assert((flags & 0x1) == 0 &&
55           "Passing in 'true' to addReg is forbidden! Use enums instead.");
56    MI->addOperand(MachineOperand::CreateReg(RegNo,
57                                             flags & RegState::Define,
58                                             flags & RegState::Implicit,
59                                             flags & RegState::Kill,
60                                             flags & RegState::Dead,
61                                             flags & RegState::Undef,
62                                             flags & RegState::EarlyClobber,
63                                             SubReg));
64    return *this;
65  }
66
67  /// addImm - Add a new immediate operand.
68  ///
69  const MachineInstrBuilder &addImm(int64_t Val) const {
70    MI->addOperand(MachineOperand::CreateImm(Val));
71    return *this;
72  }
73
74  const MachineInstrBuilder &addFPImm(const ConstantFP *Val) const {
75    MI->addOperand(MachineOperand::CreateFPImm(Val));
76    return *this;
77  }
78
79  const MachineInstrBuilder &addMBB(MachineBasicBlock *MBB,
80                                    unsigned char TargetFlags = 0) const {
81    MI->addOperand(MachineOperand::CreateMBB(MBB, TargetFlags));
82    return *this;
83  }
84
85  const MachineInstrBuilder &addFrameIndex(unsigned Idx) const {
86    MI->addOperand(MachineOperand::CreateFI(Idx));
87    return *this;
88  }
89
90  const MachineInstrBuilder &addConstantPoolIndex(unsigned Idx,
91                                                  int Offset = 0,
92                                          unsigned char TargetFlags = 0) const {
93    MI->addOperand(MachineOperand::CreateCPI(Idx, Offset, TargetFlags));
94    return *this;
95  }
96
97  const MachineInstrBuilder &addJumpTableIndex(unsigned Idx,
98                                          unsigned char TargetFlags = 0) const {
99    MI->addOperand(MachineOperand::CreateJTI(Idx, TargetFlags));
100    return *this;
101  }
102
103  const MachineInstrBuilder &addGlobalAddress(GlobalValue *GV,
104                                              int64_t Offset = 0,
105                                          unsigned char TargetFlags = 0) const {
106    MI->addOperand(MachineOperand::CreateGA(GV, Offset, TargetFlags));
107    return *this;
108  }
109
110  const MachineInstrBuilder &addExternalSymbol(const char *FnName,
111                                               int64_t Offset = 0,
112                                          unsigned char TargetFlags = 0) const {
113    MI->addOperand(MachineOperand::CreateES(FnName, Offset, TargetFlags));
114    return *this;
115  }
116
117  const MachineInstrBuilder &addMemOperand(const MachineMemOperand &MMO) const {
118    MI->addMemOperand(*MI->getParent()->getParent(), MMO);
119    return *this;
120  }
121
122  const MachineInstrBuilder &addOperand(const MachineOperand &MO) const {
123    MI->addOperand(MO);
124    return *this;
125  }
126};
127
128/// BuildMI - Builder interface.  Specify how to create the initial instruction
129/// itself.
130///
131inline MachineInstrBuilder BuildMI(MachineFunction &MF,
132                                   DebugLoc DL,
133                                   const TargetInstrDesc &TID) {
134  return MachineInstrBuilder(MF.CreateMachineInstr(TID, DL));
135}
136
137/// BuildMI - This version of the builder sets up the first operand as a
138/// destination virtual register.
139///
140inline MachineInstrBuilder BuildMI(MachineFunction &MF,
141                                   DebugLoc DL,
142                                   const TargetInstrDesc &TID,
143                                   unsigned DestReg) {
144  return MachineInstrBuilder(MF.CreateMachineInstr(TID, DL))
145           .addReg(DestReg, RegState::Define);
146}
147
148/// BuildMI - This version of the builder inserts the newly-built
149/// instruction before the given position in the given MachineBasicBlock, and
150/// sets up the first operand as a destination virtual register.
151///
152inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
153                                   MachineBasicBlock::iterator I,
154                                   DebugLoc DL,
155                                   const TargetInstrDesc &TID,
156                                   unsigned DestReg) {
157  MachineInstr *MI = BB.getParent()->CreateMachineInstr(TID, DL);
158  BB.insert(I, MI);
159  return MachineInstrBuilder(MI).addReg(DestReg, RegState::Define);
160}
161
162/// BuildMI - This version of the builder inserts the newly-built
163/// instruction before the given position in the given MachineBasicBlock, and
164/// does NOT take a destination register.
165///
166inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
167                                   MachineBasicBlock::iterator I,
168                                   DebugLoc DL,
169                                   const TargetInstrDesc &TID) {
170  MachineInstr *MI = BB.getParent()->CreateMachineInstr(TID, DL);
171  BB.insert(I, MI);
172  return MachineInstrBuilder(MI);
173}
174
175/// BuildMI - This version of the builder inserts the newly-built
176/// instruction at the end of the given MachineBasicBlock, and does NOT take a
177/// destination register.
178///
179inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB,
180                                   DebugLoc DL,
181                                   const TargetInstrDesc &TID) {
182  return BuildMI(*BB, BB->end(), DL, TID);
183}
184
185/// BuildMI - This version of the builder inserts the newly-built
186/// instruction at the end of the given MachineBasicBlock, and sets up the first
187/// operand as a destination virtual register.
188///
189inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB,
190                                   DebugLoc DL,
191                                   const TargetInstrDesc &TID,
192                                   unsigned DestReg) {
193  return BuildMI(*BB, BB->end(), DL, TID, DestReg);
194}
195
196inline unsigned getDefRegState(bool B) {
197  return B ? RegState::Define : 0;
198}
199inline unsigned getImplRegState(bool B) {
200  return B ? RegState::Implicit : 0;
201}
202inline unsigned getKillRegState(bool B) {
203  return B ? RegState::Kill : 0;
204}
205inline unsigned getDeadRegState(bool B) {
206  return B ? RegState::Dead : 0;
207}
208inline unsigned getUndefRegState(bool B) {
209  return B ? RegState::Undef : 0;
210}
211
212} // End llvm namespace
213
214#endif
215