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