1475370b036a9e355b51c899465efc00532bb3c41Chris Lattner//===-- llvm/MC/MCInst.h - MCInst class -------------------------*- C++ -*-===//
2475370b036a9e355b51c899465efc00532bb3c41Chris Lattner//
3475370b036a9e355b51c899465efc00532bb3c41Chris Lattner//                     The LLVM Compiler Infrastructure
4475370b036a9e355b51c899465efc00532bb3c41Chris Lattner//
5475370b036a9e355b51c899465efc00532bb3c41Chris Lattner// This file is distributed under the University of Illinois Open Source
6475370b036a9e355b51c899465efc00532bb3c41Chris Lattner// License. See LICENSE.TXT for details.
7475370b036a9e355b51c899465efc00532bb3c41Chris Lattner//
8475370b036a9e355b51c899465efc00532bb3c41Chris Lattner//===----------------------------------------------------------------------===//
9475370b036a9e355b51c899465efc00532bb3c41Chris Lattner//
10475370b036a9e355b51c899465efc00532bb3c41Chris Lattner// This file contains the declaration of the MCInst and MCOperand classes, which
11475370b036a9e355b51c899465efc00532bb3c41Chris Lattner// is the basic representation used to represent low-level machine code
12475370b036a9e355b51c899465efc00532bb3c41Chris Lattner// instructions.
13475370b036a9e355b51c899465efc00532bb3c41Chris Lattner//
14475370b036a9e355b51c899465efc00532bb3c41Chris Lattner//===----------------------------------------------------------------------===//
15475370b036a9e355b51c899465efc00532bb3c41Chris Lattner
16475370b036a9e355b51c899465efc00532bb3c41Chris Lattner#ifndef LLVM_MC_MCINST_H
17475370b036a9e355b51c899465efc00532bb3c41Chris Lattner#define LLVM_MC_MCINST_H
18475370b036a9e355b51c899465efc00532bb3c41Chris Lattner
19475370b036a9e355b51c899465efc00532bb3c41Chris Lattner#include "llvm/ADT/SmallVector.h"
2067c076cf59d14fc96feb5c915447f8ea79cf8325Daniel Dunbar#include "llvm/ADT/StringRef.h"
211f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/DataTypes.h"
2282f4ce5081fc9cfbf34bbe61eb0412e7ca4dc3dfJim Grosbach#include "llvm/Support/SMLoc.h"
23475370b036a9e355b51c899465efc00532bb3c41Chris Lattner
24475370b036a9e355b51c899465efc00532bb3c41Chris Lattnernamespace llvm {
254b770c20778ccb5d2f304fa73e0522a7ab8c4623Daniel Dunbarclass raw_ostream;
26684c593d05db0bd277268fc9d8c05bce138c745aChris Lattnerclass MCAsmInfo;
2767c076cf59d14fc96feb5c915447f8ea79cf8325Daniel Dunbarclass MCInstPrinter;
288c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbarclass MCExpr;
297b672fe03b6f1734ac545e3aceb6d90bed3f0406Owen Andersonclass MCInst;
30475370b036a9e355b51c899465efc00532bb3c41Chris Lattner
31475370b036a9e355b51c899465efc00532bb3c41Chris Lattner/// MCOperand - Instances of this class represent operands of the MCInst class.
32475370b036a9e355b51c899465efc00532bb3c41Chris Lattner/// This is a simple discriminated union.
33475370b036a9e355b51c899465efc00532bb3c41Chris Lattnerclass MCOperand {
34475370b036a9e355b51c899465efc00532bb3c41Chris Lattner  enum MachineOperandType {
35475370b036a9e355b51c899465efc00532bb3c41Chris Lattner    kInvalid,                 ///< Uninitialized.
36475370b036a9e355b51c899465efc00532bb3c41Chris Lattner    kRegister,                ///< Register operand.
37c12430644a9f49a056286f8ebe0e55ccc23bdde0Chris Lattner    kImmediate,               ///< Immediate operand.
3826edbcb8d5da5fb65816a97f740c9868fa798df4Jim Grosbach    kFPImmediate,             ///< Floating-point immediate operand.
397b672fe03b6f1734ac545e3aceb6d90bed3f0406Owen Anderson    kExpr,                    ///< Relocatable immediate operand.
407b672fe03b6f1734ac545e3aceb6d90bed3f0406Owen Anderson    kInst                     ///< Sub-instruction operand.
41475370b036a9e355b51c899465efc00532bb3c41Chris Lattner  };
42475370b036a9e355b51c899465efc00532bb3c41Chris Lattner  unsigned char Kind;
430dd2c9331887b9d0aa06b1e201c5eda4361365fcJim Grosbach
44475370b036a9e355b51c899465efc00532bb3c41Chris Lattner  union {
45475370b036a9e355b51c899465efc00532bb3c41Chris Lattner    unsigned RegVal;
46bb5d44d7c496f9576e7b1fcfa3f51f544512d158Chris Lattner    int64_t ImmVal;
47a8e47b3319db56675f8e80f4bb015c163110b902Jim Grosbach    double FPImmVal;
488c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar    const MCExpr *ExprVal;
497b672fe03b6f1734ac545e3aceb6d90bed3f0406Owen Anderson    const MCInst *InstVal;
50475370b036a9e355b51c899465efc00532bb3c41Chris Lattner  };
51475370b036a9e355b51c899465efc00532bb3c41Chris Lattnerpublic:
520dd2c9331887b9d0aa06b1e201c5eda4361365fcJim Grosbach
5326edbcb8d5da5fb65816a97f740c9868fa798df4Jim Grosbach  MCOperand() : Kind(kInvalid), FPImmVal(0.0) {}
54475370b036a9e355b51c899465efc00532bb3c41Chris Lattner
55e303503da3dd928b70ab371161e33b515e8dfc95Daniel Dunbar  bool isValid() const { return Kind != kInvalid; }
56475370b036a9e355b51c899465efc00532bb3c41Chris Lattner  bool isReg() const { return Kind == kRegister; }
57475370b036a9e355b51c899465efc00532bb3c41Chris Lattner  bool isImm() const { return Kind == kImmediate; }
5826edbcb8d5da5fb65816a97f740c9868fa798df4Jim Grosbach  bool isFPImm() const { return Kind == kFPImmediate; }
598c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar  bool isExpr() const { return Kind == kExpr; }
607b672fe03b6f1734ac545e3aceb6d90bed3f0406Owen Anderson  bool isInst() const { return Kind == kInst; }
610dd2c9331887b9d0aa06b1e201c5eda4361365fcJim Grosbach
62475370b036a9e355b51c899465efc00532bb3c41Chris Lattner  /// getReg - Returns the register number.
63475370b036a9e355b51c899465efc00532bb3c41Chris Lattner  unsigned getReg() const {
64475370b036a9e355b51c899465efc00532bb3c41Chris Lattner    assert(isReg() && "This is not a register operand!");
65475370b036a9e355b51c899465efc00532bb3c41Chris Lattner    return RegVal;
66475370b036a9e355b51c899465efc00532bb3c41Chris Lattner  }
67475370b036a9e355b51c899465efc00532bb3c41Chris Lattner
68475370b036a9e355b51c899465efc00532bb3c41Chris Lattner  /// setReg - Set the register number.
69475370b036a9e355b51c899465efc00532bb3c41Chris Lattner  void setReg(unsigned Reg) {
70475370b036a9e355b51c899465efc00532bb3c41Chris Lattner    assert(isReg() && "This is not a register operand!");
71475370b036a9e355b51c899465efc00532bb3c41Chris Lattner    RegVal = Reg;
72475370b036a9e355b51c899465efc00532bb3c41Chris Lattner  }
730dd2c9331887b9d0aa06b1e201c5eda4361365fcJim Grosbach
74bb5d44d7c496f9576e7b1fcfa3f51f544512d158Chris Lattner  int64_t getImm() const {
75475370b036a9e355b51c899465efc00532bb3c41Chris Lattner    assert(isImm() && "This is not an immediate");
76475370b036a9e355b51c899465efc00532bb3c41Chris Lattner    return ImmVal;
77475370b036a9e355b51c899465efc00532bb3c41Chris Lattner  }
78bb5d44d7c496f9576e7b1fcfa3f51f544512d158Chris Lattner  void setImm(int64_t Val) {
79475370b036a9e355b51c899465efc00532bb3c41Chris Lattner    assert(isImm() && "This is not an immediate");
80475370b036a9e355b51c899465efc00532bb3c41Chris Lattner    ImmVal = Val;
81475370b036a9e355b51c899465efc00532bb3c41Chris Lattner  }
820dd2c9331887b9d0aa06b1e201c5eda4361365fcJim Grosbach
836dbe29e34e0017dac703f951429964d9c95b528cJim Grosbach  double getFPImm() const {
8426edbcb8d5da5fb65816a97f740c9868fa798df4Jim Grosbach    assert(isFPImm() && "This is not an FP immediate");
8526edbcb8d5da5fb65816a97f740c9868fa798df4Jim Grosbach    return FPImmVal;
8626edbcb8d5da5fb65816a97f740c9868fa798df4Jim Grosbach  }
8726edbcb8d5da5fb65816a97f740c9868fa798df4Jim Grosbach
88a8e47b3319db56675f8e80f4bb015c163110b902Jim Grosbach  void setFPImm(double Val) {
8926edbcb8d5da5fb65816a97f740c9868fa798df4Jim Grosbach    assert(isFPImm() && "This is not an FP immediate");
9026edbcb8d5da5fb65816a97f740c9868fa798df4Jim Grosbach    FPImmVal = Val;
9126edbcb8d5da5fb65816a97f740c9868fa798df4Jim Grosbach  }
9226edbcb8d5da5fb65816a97f740c9868fa798df4Jim Grosbach
938c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar  const MCExpr *getExpr() const {
948c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar    assert(isExpr() && "This is not an expression");
958c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar    return ExprVal;
96e303503da3dd928b70ab371161e33b515e8dfc95Daniel Dunbar  }
978c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar  void setExpr(const MCExpr *Val) {
988c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar    assert(isExpr() && "This is not an expression");
998c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar    ExprVal = Val;
100e303503da3dd928b70ab371161e33b515e8dfc95Daniel Dunbar  }
1010dd2c9331887b9d0aa06b1e201c5eda4361365fcJim Grosbach
1027b672fe03b6f1734ac545e3aceb6d90bed3f0406Owen Anderson  const MCInst *getInst() const {
1037b672fe03b6f1734ac545e3aceb6d90bed3f0406Owen Anderson    assert(isInst() && "This is not a sub-instruction");
1047b672fe03b6f1734ac545e3aceb6d90bed3f0406Owen Anderson    return InstVal;
1057b672fe03b6f1734ac545e3aceb6d90bed3f0406Owen Anderson  }
1067b672fe03b6f1734ac545e3aceb6d90bed3f0406Owen Anderson  void setInst(const MCInst *Val) {
1077b672fe03b6f1734ac545e3aceb6d90bed3f0406Owen Anderson    assert(isInst() && "This is not a sub-instruction");
1087b672fe03b6f1734ac545e3aceb6d90bed3f0406Owen Anderson    InstVal = Val;
1097b672fe03b6f1734ac545e3aceb6d90bed3f0406Owen Anderson  }
1107b672fe03b6f1734ac545e3aceb6d90bed3f0406Owen Anderson
111cdcb388a589846e7e7ca8c88f77cf53933539074Daniel Dunbar  static MCOperand CreateReg(unsigned Reg) {
112cdcb388a589846e7e7ca8c88f77cf53933539074Daniel Dunbar    MCOperand Op;
113cdcb388a589846e7e7ca8c88f77cf53933539074Daniel Dunbar    Op.Kind = kRegister;
114cdcb388a589846e7e7ca8c88f77cf53933539074Daniel Dunbar    Op.RegVal = Reg;
115cdcb388a589846e7e7ca8c88f77cf53933539074Daniel Dunbar    return Op;
116475370b036a9e355b51c899465efc00532bb3c41Chris Lattner  }
117cdcb388a589846e7e7ca8c88f77cf53933539074Daniel Dunbar  static MCOperand CreateImm(int64_t Val) {
118cdcb388a589846e7e7ca8c88f77cf53933539074Daniel Dunbar    MCOperand Op;
119cdcb388a589846e7e7ca8c88f77cf53933539074Daniel Dunbar    Op.Kind = kImmediate;
120cdcb388a589846e7e7ca8c88f77cf53933539074Daniel Dunbar    Op.ImmVal = Val;
121cdcb388a589846e7e7ca8c88f77cf53933539074Daniel Dunbar    return Op;
122475370b036a9e355b51c899465efc00532bb3c41Chris Lattner  }
123a8e47b3319db56675f8e80f4bb015c163110b902Jim Grosbach  static MCOperand CreateFPImm(double Val) {
12426edbcb8d5da5fb65816a97f740c9868fa798df4Jim Grosbach    MCOperand Op;
12526edbcb8d5da5fb65816a97f740c9868fa798df4Jim Grosbach    Op.Kind = kFPImmediate;
12626edbcb8d5da5fb65816a97f740c9868fa798df4Jim Grosbach    Op.FPImmVal = Val;
12726edbcb8d5da5fb65816a97f740c9868fa798df4Jim Grosbach    return Op;
12826edbcb8d5da5fb65816a97f740c9868fa798df4Jim Grosbach  }
1298c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar  static MCOperand CreateExpr(const MCExpr *Val) {
130cdcb388a589846e7e7ca8c88f77cf53933539074Daniel Dunbar    MCOperand Op;
1318c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar    Op.Kind = kExpr;
1328c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar    Op.ExprVal = Val;
133cdcb388a589846e7e7ca8c88f77cf53933539074Daniel Dunbar    return Op;
134e303503da3dd928b70ab371161e33b515e8dfc95Daniel Dunbar  }
1357b672fe03b6f1734ac545e3aceb6d90bed3f0406Owen Anderson  static MCOperand CreateInst(const MCInst *Val) {
1367b672fe03b6f1734ac545e3aceb6d90bed3f0406Owen Anderson    MCOperand Op;
1377b672fe03b6f1734ac545e3aceb6d90bed3f0406Owen Anderson    Op.Kind = kInst;
1387b672fe03b6f1734ac545e3aceb6d90bed3f0406Owen Anderson    Op.InstVal = Val;
1397b672fe03b6f1734ac545e3aceb6d90bed3f0406Owen Anderson    return Op;
1407b672fe03b6f1734ac545e3aceb6d90bed3f0406Owen Anderson  }
1414b770c20778ccb5d2f304fa73e0522a7ab8c4623Daniel Dunbar
142684c593d05db0bd277268fc9d8c05bce138c745aChris Lattner  void print(raw_ostream &OS, const MCAsmInfo *MAI) const;
1434b770c20778ccb5d2f304fa73e0522a7ab8c4623Daniel Dunbar  void dump() const;
144475370b036a9e355b51c899465efc00532bb3c41Chris Lattner};
145475370b036a9e355b51c899465efc00532bb3c41Chris Lattner
146b006337bb8217d5c3def4001cbd978a848557882Benjamin Kramertemplate <> struct isPodLike<MCOperand> { static const bool value = true; };
1470dd2c9331887b9d0aa06b1e201c5eda4361365fcJim Grosbach
148475370b036a9e355b51c899465efc00532bb3c41Chris Lattner/// MCInst - Instances of this class represent a single low-level machine
1490dd2c9331887b9d0aa06b1e201c5eda4361365fcJim Grosbach/// instruction.
150475370b036a9e355b51c899465efc00532bb3c41Chris Lattnerclass MCInst {
151475370b036a9e355b51c899465efc00532bb3c41Chris Lattner  unsigned Opcode;
15282f4ce5081fc9cfbf34bbe61eb0412e7ca4dc3dfJim Grosbach  SMLoc Loc;
153475370b036a9e355b51c899465efc00532bb3c41Chris Lattner  SmallVector<MCOperand, 8> Operands;
154475370b036a9e355b51c899465efc00532bb3c41Chris Lattnerpublic:
155892e44a07c2422dedff9c5f0532286e677a64842Chris Lattner  MCInst() : Opcode(0) {}
1560dd2c9331887b9d0aa06b1e201c5eda4361365fcJim Grosbach
157bb5d44d7c496f9576e7b1fcfa3f51f544512d158Chris Lattner  void setOpcode(unsigned Op) { Opcode = Op; }
158d5fb7906130989a579d1bfe4490b414331e94feeChris Lattner  unsigned getOpcode() const { return Opcode; }
15965c060064d129e1bacc9204fd032fe81c4c669c4Chris Lattner
16082f4ce5081fc9cfbf34bbe61eb0412e7ca4dc3dfJim Grosbach  void setLoc(SMLoc loc) { Loc = loc; }
16182f4ce5081fc9cfbf34bbe61eb0412e7ca4dc3dfJim Grosbach  SMLoc getLoc() const { return Loc; }
16282f4ce5081fc9cfbf34bbe61eb0412e7ca4dc3dfJim Grosbach
163d5fb7906130989a579d1bfe4490b414331e94feeChris Lattner  const MCOperand &getOperand(unsigned i) const { return Operands[i]; }
164c12430644a9f49a056286f8ebe0e55ccc23bdde0Chris Lattner  MCOperand &getOperand(unsigned i) { return Operands[i]; }
165f28d6311896d7de6221465c3918fdc5cbd7d5a6fChris Lattner  unsigned getNumOperands() const { return Operands.size(); }
1660dd2c9331887b9d0aa06b1e201c5eda4361365fcJim Grosbach
167bb5d44d7c496f9576e7b1fcfa3f51f544512d158Chris Lattner  void addOperand(const MCOperand &Op) {
168bb5d44d7c496f9576e7b1fcfa3f51f544512d158Chris Lattner    Operands.push_back(Op);
169bb5d44d7c496f9576e7b1fcfa3f51f544512d158Chris Lattner  }
1704b770c20778ccb5d2f304fa73e0522a7ab8c4623Daniel Dunbar
17198c5ddabca1debf935a07d14d0cbc9732374bdb8Owen Anderson  void clear() { Operands.clear(); }
17256cb3e3ccbc766086841d04fb8f136c7b4718dd5Owen Anderson  size_t size() { return Operands.size(); }
17356cb3e3ccbc766086841d04fb8f136c7b4718dd5Owen Anderson
1740437ef6510795353a405cd6e119a2175d65fe0d1Jim Grosbach  typedef SmallVectorImpl<MCOperand>::iterator iterator;
17556cb3e3ccbc766086841d04fb8f136c7b4718dd5Owen Anderson  iterator begin() { return Operands.begin(); }
17656cb3e3ccbc766086841d04fb8f136c7b4718dd5Owen Anderson  iterator end()   { return Operands.end();   }
17756cb3e3ccbc766086841d04fb8f136c7b4718dd5Owen Anderson  iterator insert(iterator I, const MCOperand &Op) {
17856cb3e3ccbc766086841d04fb8f136c7b4718dd5Owen Anderson    return Operands.insert(I, Op);
17956cb3e3ccbc766086841d04fb8f136c7b4718dd5Owen Anderson  }
180423b81e6924f882f8b1cf7a7d4126b25b5f915aaOwen Anderson
181684c593d05db0bd277268fc9d8c05bce138c745aChris Lattner  void print(raw_ostream &OS, const MCAsmInfo *MAI) const;
1824b770c20778ccb5d2f304fa73e0522a7ab8c4623Daniel Dunbar  void dump() const;
18367c076cf59d14fc96feb5c915447f8ea79cf8325Daniel Dunbar
18467c076cf59d14fc96feb5c915447f8ea79cf8325Daniel Dunbar  /// \brief Dump the MCInst as prettily as possible using the additional MC
185c5252da873d547a19069eaf9030fec203f128f66Dmitri Gribenko  /// structures, if given. Operators are separated by the \p Separator
18667c076cf59d14fc96feb5c915447f8ea79cf8325Daniel Dunbar  /// string.
187dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void dump_pretty(raw_ostream &OS, const MCAsmInfo *MAI = nullptr,
188dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                   const MCInstPrinter *Printer = nullptr,
18967c076cf59d14fc96feb5c915447f8ea79cf8325Daniel Dunbar                   StringRef Separator = " ") const;
190475370b036a9e355b51c899465efc00532bb3c41Chris Lattner};
191475370b036a9e355b51c899465efc00532bb3c41Chris Lattner
1926313944845265dbf38e68046a047d78162f5b89eJim Grosbachinline raw_ostream& operator<<(raw_ostream &OS, const MCOperand &MO) {
193dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MO.print(OS, nullptr);
1946313944845265dbf38e68046a047d78162f5b89eJim Grosbach  return OS;
1956313944845265dbf38e68046a047d78162f5b89eJim Grosbach}
1966313944845265dbf38e68046a047d78162f5b89eJim Grosbach
197069594a94f485729e82aec29d2e8d16eb47744faJim Grosbachinline raw_ostream& operator<<(raw_ostream &OS, const MCInst &MI) {
198dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MI.print(OS, nullptr);
199069594a94f485729e82aec29d2e8d16eb47744faJim Grosbach  return OS;
200069594a94f485729e82aec29d2e8d16eb47744faJim Grosbach}
201475370b036a9e355b51c899465efc00532bb3c41Chris Lattner
202475370b036a9e355b51c899465efc00532bb3c41Chris Lattner} // end namespace llvm
203475370b036a9e355b51c899465efc00532bb3c41Chris Lattner
204475370b036a9e355b51c899465efc00532bb3c41Chris Lattner#endif
205