1ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner//===- CodeGenInstruction.h - Instruction Class Wrapper ---------*- C++ -*-===//
23da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman//
3ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner//                     The LLVM Compiler Infrastructure
4ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner//
53060910e290949a9ac5eda8726d030790c4d60ffChris Lattner// This file is distributed under the University of Illinois Open Source
63060910e290949a9ac5eda8726d030790c4d60ffChris Lattner// License. See LICENSE.TXT for details.
73da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman//
8ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner//===----------------------------------------------------------------------===//
9ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner//
10ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner// This file defines a wrapper class for the 'Instruction' TableGen class.
11ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner//
12ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner//===----------------------------------------------------------------------===//
13ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner
14ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner#ifndef CODEGEN_INSTRUCTION_H
15ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner#define CODEGEN_INSTRUCTION_H
16ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner
17225549f775db61c5dba10e14758f4b43c53ef593Chris Lattner#include "llvm/ADT/StringRef.h"
1836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/CodeGen/MachineValueType.h"
19a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson#include "llvm/Support/SourceMgr.h"
20ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner#include <string>
21ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner#include <utility>
224ffd89fa4d2788611187d1a534d2ed46adf1702cChandler Carruth#include <vector>
23ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner
24ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattnernamespace llvm {
25ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner  class Record;
2665303d6bd777b76735ef179870678a1d14671c54Chris Lattner  class DagInit;
279414ae52911f1d62cabd5108e0381b9d17476157Chris Lattner  class CodeGenTarget;
284d43d0fd996a01c2cd21fd51082bc1bba783ef3cChris Lattner  class StringRef;
290c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
30c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner  class CGIOperandList {
31d41b30def3181bce4bf87e8bde664d15663165d0Jeff Cohen  public:
32a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner    class ConstraintInfo {
33a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner      enum { None, EarlyClobber, Tied } Kind;
34a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner      unsigned OtherTiedOperand;
35a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner    public:
36a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner      ConstraintInfo() : Kind(None) {}
370c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
38a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner      static ConstraintInfo getEarlyClobber() {
39a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner        ConstraintInfo I;
40a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner        I.Kind = EarlyClobber;
41e555c9f4a54fd854af13f117fc0650ada3df3d24Chris Lattner        I.OtherTiedOperand = 0;
42a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner        return I;
43a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner      }
440c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
45a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner      static ConstraintInfo getTied(unsigned Op) {
46a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner        ConstraintInfo I;
47a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner        I.Kind = Tied;
48a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner        I.OtherTiedOperand = Op;
49a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner        return I;
50a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner      }
510c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
52a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner      bool isNone() const { return Kind == None; }
53a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner      bool isEarlyClobber() const { return Kind == EarlyClobber; }
54a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner      bool isTied() const { return Kind == Tied; }
550c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
56a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner      unsigned getTiedOperand() const {
57a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner        assert(isTied());
58a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner        return OtherTiedOperand;
59a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner      }
60a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner    };
619ed2cee1057e2df3a4305b9c818aa577c8504f59Jim Grosbach
62cf03da0ce913267c4971534e8792297e06535a4eChris Lattner    /// OperandInfo - The information we keep track of for each operand in the
63cf03da0ce913267c4971534e8792297e06535a4eChris Lattner    /// operand list for a tablegen instruction.
6487c5905e0b6f551e21c9a96f1b6418920d908210Chris Lattner    struct OperandInfo {
65cf03da0ce913267c4971534e8792297e06535a4eChris Lattner      /// Rec - The definition this operand is declared as.
660e384b66a781fc0ff005f475a7ab151afa054fb0Chris Lattner      ///
6787c5905e0b6f551e21c9a96f1b6418920d908210Chris Lattner      Record *Rec;
680c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
69cf03da0ce913267c4971534e8792297e06535a4eChris Lattner      /// Name - If this operand was assigned a symbolic name, this is it,
70cf03da0ce913267c4971534e8792297e06535a4eChris Lattner      /// otherwise, it's empty.
7187c5905e0b6f551e21c9a96f1b6418920d908210Chris Lattner      std::string Name;
720c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
73cf03da0ce913267c4971534e8792297e06535a4eChris Lattner      /// PrinterMethodName - The method used to print operands of this type in
74cf03da0ce913267c4971534e8792297e06535a4eChris Lattner      /// the asmprinter.
75cf03da0ce913267c4971534e8792297e06535a4eChris Lattner      std::string PrinterMethodName;
760c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
775013f7469ec44adba127de65517e699180ee532fJim Grosbach      /// EncoderMethodName - The method used to get the machine operand value
785013f7469ec44adba127de65517e699180ee532fJim Grosbach      /// for binary encoding. "getMachineOpValue" by default.
795013f7469ec44adba127de65517e699180ee532fJim Grosbach      std::string EncoderMethodName;
800c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
815196c12e9fdec9ef3c63d96cb529c1c1cb732773Benjamin Kramer      /// OperandType - A value from MCOI::OperandType representing the type of
825196c12e9fdec9ef3c63d96cb529c1c1cb732773Benjamin Kramer      /// the operand.
835196c12e9fdec9ef3c63d96cb529c1c1cb732773Benjamin Kramer      std::string OperandType;
845196c12e9fdec9ef3c63d96cb529c1c1cb732773Benjamin Kramer
85cf03da0ce913267c4971534e8792297e06535a4eChris Lattner      /// MIOperandNo - Currently (this is meant to be phased out), some logical
86cf03da0ce913267c4971534e8792297e06535a4eChris Lattner      /// operands correspond to multiple MachineInstr operands.  In the X86
87cf03da0ce913267c4971534e8792297e06535a4eChris Lattner      /// target for example, one address operand is represented as 4
88cf03da0ce913267c4971534e8792297e06535a4eChris Lattner      /// MachineOperands.  Because of this, the operand number in the
89cf03da0ce913267c4971534e8792297e06535a4eChris Lattner      /// OperandList may not match the MachineInstr operand num.  Until it
90cf03da0ce913267c4971534e8792297e06535a4eChris Lattner      /// does, this contains the MI operand index of this operand.
91cf03da0ce913267c4971534e8792297e06535a4eChris Lattner      unsigned MIOperandNo;
92cfbf96aa9c3bd317548f72e022ba28a40353f95aChris Lattner      unsigned MINumOperands;   // The number of operands.
930c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
94f64f9a4b75d07819866bfcf918b922a76d3e1600Chris Lattner      /// DoNotEncode - Bools are set to true in this vector for each operand in
95f64f9a4b75d07819866bfcf918b922a76d3e1600Chris Lattner      /// the DisableEncoding list.  These should not be emitted by the code
96f64f9a4b75d07819866bfcf918b922a76d3e1600Chris Lattner      /// emitter.
97f64f9a4b75d07819866bfcf918b922a76d3e1600Chris Lattner      std::vector<bool> DoNotEncode;
980c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
998ef9d16d3913db11c89fc2d14899e153bdbdc91bNate Begeman      /// MIOperandInfo - Default MI operand type. Note an operand may be made
1008ef9d16d3913db11c89fc2d14899e153bdbdc91bNate Begeman      /// up of multiple MI operands.
10105bce0beee87512e52428d4b80f5a8e79a949576David Greene      DagInit *MIOperandInfo;
1020c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
1030bb75004ff6c0ad26de7610cb873f81ea26fd6caChris Lattner      /// Constraint info for this operand.  This operand can have pieces, so we
1040bb75004ff6c0ad26de7610cb873f81ea26fd6caChris Lattner      /// track constraint info for each.
105a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner      std::vector<ConstraintInfo> Constraints;
1060c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
1079ed2cee1057e2df3a4305b9c818aa577c8504f59Jim Grosbach      OperandInfo(Record *R, const std::string &N, const std::string &PMN,
1085196c12e9fdec9ef3c63d96cb529c1c1cb732773Benjamin Kramer                  const std::string &EMN, const std::string &OT, unsigned MION,
10905bce0beee87512e52428d4b80f5a8e79a949576David Greene                  unsigned MINO, DagInit *MIOI)
110c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner      : Rec(R), Name(N), PrinterMethodName(PMN), EncoderMethodName(EMN),
1115196c12e9fdec9ef3c63d96cb529c1c1cb732773Benjamin Kramer        OperandType(OT), MIOperandNo(MION), MINumOperands(MINO),
1125196c12e9fdec9ef3c63d96cb529c1c1cb732773Benjamin Kramer        MIOperandInfo(MIOI) {}
1130c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
1140c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
1159b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner      /// getTiedOperand - If this operand is tied to another one, return the
1169b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner      /// other operand number.  Otherwise, return -1.
1179b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner      int getTiedRegister() const {
1189b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner        for (unsigned j = 0, e = Constraints.size(); j != e; ++j) {
1199b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner          const CGIOperandList::ConstraintInfo &CI = Constraints[j];
1209b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner          if (CI.isTied()) return CI.getTiedOperand();
1219b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner        }
1229b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner        return -1;
1239b0d4bfca0f23d39f5f2aef6b6740267a26ee17cChris Lattner      }
12487c5905e0b6f551e21c9a96f1b6418920d908210Chris Lattner    };
1250c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
126c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner    CGIOperandList(Record *D);
1270c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
128c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner    Record *TheDef;            // The actual record containing this OperandList.
1293da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman
130cedef1ccf0d53693b5e62d524e7ba6b2122231c7Chris Lattner    /// NumDefs - Number of def operands declared, this is the number of
131cedef1ccf0d53693b5e62d524e7ba6b2122231c7Chris Lattner    /// elements in the instruction's (outs) list.
13264d80e3387f328d21cd9cc06464b5de7861e3f27Evan Cheng    ///
13364d80e3387f328d21cd9cc06464b5de7861e3f27Evan Cheng    unsigned NumDefs;
1340c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
135ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner    /// OperandList - The list of declared operands, along with their declared
136ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner    /// type (which is a record).
13787c5905e0b6f551e21c9a96f1b6418920d908210Chris Lattner    std::vector<OperandInfo> OperandList;
1380c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
139c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner    // Information gleaned from the operand list.
1405127ce09a4e4379f971280fab461a5f03befddbcEvan Cheng    bool isPredicable;
14188cc092ca5bd79480205ee7b01aa39c13f3e35d7Evan Cheng    bool hasOptionalDef;
142c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner    bool isVariadic;
1430c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
144c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner    // Provide transparent accessors to the operand list.
145a90dbc133f7bc7bf0e042fb03222bfdfafce3965Chris Lattner    bool empty() const { return OperandList.empty(); }
146c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner    unsigned size() const { return OperandList.size(); }
147c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner    const OperandInfo &operator[](unsigned i) const { return OperandList[i]; }
148c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner    OperandInfo &operator[](unsigned i) { return OperandList[i]; }
149c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner    OperandInfo &back() { return OperandList.back(); }
150c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner    const OperandInfo &back() const { return OperandList.back(); }
1510c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
152dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    typedef std::vector<OperandInfo>::iterator iterator;
153dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    typedef std::vector<OperandInfo>::const_iterator const_iterator;
154dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    iterator begin() { return OperandList.begin(); }
155dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const_iterator begin() const { return OperandList.begin(); }
156dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    iterator end() { return OperandList.end(); }
157dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const_iterator end() const { return OperandList.end(); }
1580c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
159c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner    /// getOperandNamed - Return the index of the operand with the specified
160c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner    /// non-empty name.  If the instruction does not have an operand with the
16161131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger    /// specified name, abort.
162c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner    unsigned getOperandNamed(StringRef Name) const;
1630c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
164c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner    /// hasOperandNamed - Query whether the instruction has an operand of the
165c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner    /// given name. If so, return true and set OpIdx to the index of the
166c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner    /// operand. Otherwise, return false.
167c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner    bool hasOperandNamed(StringRef Name, unsigned &OpIdx) const;
1680c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
1690bb75004ff6c0ad26de7610cb873f81ea26fd6caChris Lattner    /// ParseOperandName - Parse an operand name like "$foo" or "$foo.bar",
1700bb75004ff6c0ad26de7610cb873f81ea26fd6caChris Lattner    /// where $foo is a whole operand and $foo.bar refers to a suboperand.
17161131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger    /// This aborts if the name is invalid.  If AllowWholeOp is true, references
17261131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger    /// to operands with suboperands are allowed, otherwise not.
1730bb75004ff6c0ad26de7610cb873f81ea26fd6caChris Lattner    std::pair<unsigned,unsigned> ParseOperandName(const std::string &Op,
1740bb75004ff6c0ad26de7610cb873f81ea26fd6caChris Lattner                                                  bool AllowWholeOp = true);
1750c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
1760bb75004ff6c0ad26de7610cb873f81ea26fd6caChris Lattner    /// getFlattenedOperandNumber - Flatten a operand/suboperand pair into a
1770bb75004ff6c0ad26de7610cb873f81ea26fd6caChris Lattner    /// flat machineinstr operand #.
1780bb75004ff6c0ad26de7610cb873f81ea26fd6caChris Lattner    unsigned getFlattenedOperandNumber(std::pair<unsigned,unsigned> Op) const {
1790bb75004ff6c0ad26de7610cb873f81ea26fd6caChris Lattner      return OperandList[Op.first].MIOperandNo + Op.second;
1800bb75004ff6c0ad26de7610cb873f81ea26fd6caChris Lattner    }
1810c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
182f64f9a4b75d07819866bfcf918b922a76d3e1600Chris Lattner    /// getSubOperandNumber - Unflatten a operand number into an
183f64f9a4b75d07819866bfcf918b922a76d3e1600Chris Lattner    /// operand/suboperand pair.
184f64f9a4b75d07819866bfcf918b922a76d3e1600Chris Lattner    std::pair<unsigned,unsigned> getSubOperandNumber(unsigned Op) const {
185f64f9a4b75d07819866bfcf918b922a76d3e1600Chris Lattner      for (unsigned i = 0; ; ++i) {
186f64f9a4b75d07819866bfcf918b922a76d3e1600Chris Lattner        assert(i < OperandList.size() && "Invalid flat operand #");
187f64f9a4b75d07819866bfcf918b922a76d3e1600Chris Lattner        if (OperandList[i].MIOperandNo+OperandList[i].MINumOperands > Op)
188f64f9a4b75d07819866bfcf918b922a76d3e1600Chris Lattner          return std::make_pair(i, Op-OperandList[i].MIOperandNo);
189f64f9a4b75d07819866bfcf918b922a76d3e1600Chris Lattner      }
190f64f9a4b75d07819866bfcf918b922a76d3e1600Chris Lattner    }
1910c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
1920c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
193f64f9a4b75d07819866bfcf918b922a76d3e1600Chris Lattner    /// isFlatOperandNotEmitted - Return true if the specified flat operand #
194f64f9a4b75d07819866bfcf918b922a76d3e1600Chris Lattner    /// should not be emitted with the code emitter.
195f64f9a4b75d07819866bfcf918b922a76d3e1600Chris Lattner    bool isFlatOperandNotEmitted(unsigned FlatOpNo) const {
196f64f9a4b75d07819866bfcf918b922a76d3e1600Chris Lattner      std::pair<unsigned,unsigned> Op = getSubOperandNumber(FlatOpNo);
197f64f9a4b75d07819866bfcf918b922a76d3e1600Chris Lattner      if (OperandList[Op.first].DoNotEncode.size() > Op.second)
198f64f9a4b75d07819866bfcf918b922a76d3e1600Chris Lattner        return OperandList[Op.first].DoNotEncode[Op.second];
199f64f9a4b75d07819866bfcf918b922a76d3e1600Chris Lattner      return false;
200f64f9a4b75d07819866bfcf918b922a76d3e1600Chris Lattner    }
2010c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
202c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner    void ProcessDisableEncoding(std::string Value);
203c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner  };
2040c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
205ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner
206c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner  class CodeGenInstruction {
207c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner  public:
208c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner    Record *TheDef;            // The actual record defining this instruction.
209c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner    std::string Namespace;     // The namespace the instruction is in.
21087c5905e0b6f551e21c9a96f1b6418920d908210Chris Lattner
211c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner    /// AsmString - The format string used to emit a .s file for the
212c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner    /// instruction.
213c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner    std::string AsmString;
2149ed2cee1057e2df3a4305b9c818aa577c8504f59Jim Grosbach
215c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner    /// Operands - This is information about the (ins) and (outs) list specified
216c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner    /// to the instruction.
217c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner    CGIOperandList Operands;
218c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner
219c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner    /// ImplicitDefs/ImplicitUses - These are lists of registers that are
220c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner    /// implicitly defined and used by the instruction.
221c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner    std::vector<Record*> ImplicitDefs, ImplicitUses;
222c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner
223c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner    // Various boolean values we track for the instruction.
22436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool isReturn : 1;
22536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool isBranch : 1;
22636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool isIndirectBranch : 1;
22736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool isCompare : 1;
22836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool isMoveImm : 1;
22936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool isBitcast : 1;
23036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool isSelect : 1;
23136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool isBarrier : 1;
23236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool isCall : 1;
23336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool canFoldAsLoad : 1;
23436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool mayLoad : 1;
23536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool mayLoad_Unset : 1;
23636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool mayStore : 1;
23736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool mayStore_Unset : 1;
23836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool isPredicable : 1;
23936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool isConvertibleToThreeAddress : 1;
24036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool isCommutable : 1;
24136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool isTerminator : 1;
24236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool isReMaterializable : 1;
24336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool hasDelaySlot : 1;
24436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool usesCustomInserter : 1;
24536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool hasPostISelHook : 1;
24636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool hasCtrlDep : 1;
24736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool isNotDuplicable : 1;
24836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool hasSideEffects : 1;
24936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool hasSideEffects_Unset : 1;
25036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool neverHasSideEffects : 1;
25136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool isAsCheapAsAMove : 1;
25236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool hasExtraSrcRegAllocReq : 1;
25336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool hasExtraDefRegAllocReq : 1;
25436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool isCodeGenOnly : 1;
25536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool isPseudo : 1;
256c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner
257715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly    std::string DeprecatedReason;
258715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly    bool HasComplexDeprecationPredicate;
259715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly
260912519a72eb9ed2d8c957ae8b08d95d9e080dac8Jakob Stoklund Olesen    /// Are there any undefined flags?
261912519a72eb9ed2d8c957ae8b08d95d9e080dac8Jakob Stoklund Olesen    bool hasUndefFlags() const {
262912519a72eb9ed2d8c957ae8b08d95d9e080dac8Jakob Stoklund Olesen      return mayLoad_Unset || mayStore_Unset || hasSideEffects_Unset;
263912519a72eb9ed2d8c957ae8b08d95d9e080dac8Jakob Stoklund Olesen    }
264912519a72eb9ed2d8c957ae8b08d95d9e080dac8Jakob Stoklund Olesen
265912519a72eb9ed2d8c957ae8b08d95d9e080dac8Jakob Stoklund Olesen    // The record used to infer instruction flags, or NULL if no flag values
266912519a72eb9ed2d8c957ae8b08d95d9e080dac8Jakob Stoklund Olesen    // have been inferred.
267912519a72eb9ed2d8c957ae8b08d95d9e080dac8Jakob Stoklund Olesen    Record *InferredFrom;
268c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner
269c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner    CodeGenInstruction(Record *R);
27001855071e24e0e3e75306b82267d3ad0b13a0c15Jim Grosbach
2719414ae52911f1d62cabd5108e0381b9d17476157Chris Lattner    /// HasOneImplicitDefWithKnownVT - If the instruction has at least one
2729414ae52911f1d62cabd5108e0381b9d17476157Chris Lattner    /// implicit def and it has a known VT, return the VT, otherwise return
2739414ae52911f1d62cabd5108e0381b9d17476157Chris Lattner    /// MVT::Other.
2749ed2cee1057e2df3a4305b9c818aa577c8504f59Jim Grosbach    MVT::SimpleValueType
2759414ae52911f1d62cabd5108e0381b9d17476157Chris Lattner      HasOneImplicitDefWithKnownVT(const CodeGenTarget &TargetInfo) const;
2760c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
2770c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
2784d43d0fd996a01c2cd21fd51082bc1bba783ef3cChris Lattner    /// FlattenAsmStringVariants - Flatten the specified AsmString to only
2794d43d0fd996a01c2cd21fd51082bc1bba783ef3cChris Lattner    /// include text from the specified variant, returning the new string.
2804d43d0fd996a01c2cd21fd51082bc1bba783ef3cChris Lattner    static std::string FlattenAsmStringVariants(StringRef AsmString,
2814d43d0fd996a01c2cd21fd51082bc1bba783ef3cChris Lattner                                                unsigned Variant);
282ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner  };
2830c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
2840c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
285c76e80ded753b78a72be0db40fcdba543435d818Chris Lattner  /// CodeGenInstAlias - This represents an InstAlias definition.
286c76e80ded753b78a72be0db40fcdba543435d818Chris Lattner  class CodeGenInstAlias {
287c76e80ded753b78a72be0db40fcdba543435d818Chris Lattner  public:
288c76e80ded753b78a72be0db40fcdba543435d818Chris Lattner    Record *TheDef;            // The actual record defining this InstAlias.
2890c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
290c76e80ded753b78a72be0db40fcdba543435d818Chris Lattner    /// AsmString - The format string used to emit a .s file for the
291c76e80ded753b78a72be0db40fcdba543435d818Chris Lattner    /// instruction.
292c76e80ded753b78a72be0db40fcdba543435d818Chris Lattner    std::string AsmString;
2930c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
294b501d4f673c0db267a76800339f9943f2ce6fe33Chris Lattner    /// Result - The result instruction.
29505bce0beee87512e52428d4b80f5a8e79a949576David Greene    DagInit *Result;
2960c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
297225549f775db61c5dba10e14758f4b43c53ef593Chris Lattner    /// ResultInst - The instruction generated by the alias (decoded from
298225549f775db61c5dba10e14758f4b43c53ef593Chris Lattner    /// Result).
299225549f775db61c5dba10e14758f4b43c53ef593Chris Lattner    CodeGenInstruction *ResultInst;
3000c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
3010c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
302225549f775db61c5dba10e14758f4b43c53ef593Chris Lattner    struct ResultOperand {
30398c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner    private:
3047e8921b0d17db6a2a0f98dcc791f136750b825c9Owen Anderson      std::string Name;
305225549f775db61c5dba10e14758f4b43c53ef593Chris Lattner      Record *R;
3060c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
30798c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      int64_t Imm;
3080c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach    public:
30998c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      enum {
31098c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner        K_Record,
31190fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner        K_Imm,
31290fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner        K_Reg
31398c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      } Kind;
3140c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
3157e8921b0d17db6a2a0f98dcc791f136750b825c9Owen Anderson      ResultOperand(std::string N, Record *r) : Name(N), R(r), Kind(K_Record) {}
31698c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      ResultOperand(int64_t I) : Imm(I), Kind(K_Imm) {}
31790fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner      ResultOperand(Record *r) : R(r), Kind(K_Reg) {}
31898c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner
31998c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      bool isRecord() const { return Kind == K_Record; }
32098c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      bool isImm() const { return Kind == K_Imm; }
32190fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner      bool isReg() const { return Kind == K_Reg; }
3220c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
32398c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      StringRef getName() const { assert(isRecord()); return Name; }
32498c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      Record *getRecord() const { assert(isRecord()); return R; }
32598c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      int64_t getImm() const { assert(isImm()); return Imm; }
32690fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner      Record *getRegister() const { assert(isReg()); return R; }
327dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
328dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      unsigned getMINumOperands() const;
329225549f775db61c5dba10e14758f4b43c53ef593Chris Lattner    };
3300c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
331225549f775db61c5dba10e14758f4b43c53ef593Chris Lattner    /// ResultOperands - The decoded operands for the result instruction.
332225549f775db61c5dba10e14758f4b43c53ef593Chris Lattner    std::vector<ResultOperand> ResultOperands;
3335e8f2a65ca2044815039129610876dfc4de3ebfaBob Wilson
334a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    /// ResultInstOperandIndex - For each operand, this vector holds a pair of
335a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    /// indices to identify the corresponding operand in the result
336a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    /// instruction.  The first index specifies the operand and the second
337a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    /// index specifies the suboperand.  If there are no suboperands or if all
338a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    /// of them are matched by the operand, the second value should be -1.
339a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson    std::vector<std::pair<unsigned, int> > ResultInstOperandIndex;
3400c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach
341dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    CodeGenInstAlias(Record *R, unsigned Variant, CodeGenTarget &T);
342a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson
34305bce0beee87512e52428d4b80f5a8e79a949576David Greene    bool tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo,
344376a8a773e38fdcd9102a40e08ab1e0661d645d9Jakob Stoklund Olesen                         Record *InstOpRec, bool hasSubOps, ArrayRef<SMLoc> Loc,
345a49c7dfb360154070c08b8eb94ad31711d1babaeBob Wilson                         CodeGenTarget &T, ResultOperand &ResOp);
3460c4d44aa7ae109dfbc0551dbe77e4e0f903b38aeJim Grosbach  };
347c76e80ded753b78a72be0db40fcdba543435d818Chris Lattner}
348ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner
349ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner#endif
350