Home | History | Annotate | Download | only in CodeGen
      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 
     23 namespace llvm {
     24 
     25 class MCInstrDesc;
     26 class MDNode;
     27 
     28 namespace 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 
     42 class MachineInstrBuilder {
     43   MachineInstr *MI;
     44 public:
     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 ///
    181 inline 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 ///
    190 inline 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 ///
    202 inline 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 ///
    216 inline 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 ///
    229 inline 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 ///
    239 inline 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 
    246 inline unsigned getDefRegState(bool B) {
    247   return B ? RegState::Define : 0;
    248 }
    249 inline unsigned getImplRegState(bool B) {
    250   return B ? RegState::Implicit : 0;
    251 }
    252 inline unsigned getKillRegState(bool B) {
    253   return B ? RegState::Kill : 0;
    254 }
    255 inline unsigned getDeadRegState(bool B) {
    256   return B ? RegState::Dead : 0;
    257 }
    258 inline unsigned getUndefRegState(bool B) {
    259   return B ? RegState::Undef : 0;
    260 }
    261 
    262 } // End llvm namespace
    263 
    264 #endif
    265