f008b2036c6d57f80e3bc7125aff3597130b9f28
[oota-llvm.git] / include / llvm / MC / MCInst.h
1 //===-- llvm/MC/MCInst.h - MCInst class -------------------------*- 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 contains the declaration of the MCInst and MCOperand classes, which
11 // is the basic representation used to represent low-level machine code
12 // instructions.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #ifndef LLVM_MC_MCINST_H
17 #define LLVM_MC_MCINST_H
18
19 #include "llvm/ADT/APFloat.h"
20 #include "llvm/ADT/SmallVector.h"
21 #include "llvm/ADT/StringRef.h"
22 #include "llvm/System/DataTypes.h"
23
24 namespace llvm {
25 class raw_ostream;
26 class MCAsmInfo;
27 class MCInstPrinter;
28 class MCExpr;
29
30 /// MCOperand - Instances of this class represent operands of the MCInst class.
31 /// This is a simple discriminated union.
32 class MCOperand {
33   enum MachineOperandType {
34     kInvalid,                 ///< Uninitialized.
35     kRegister,                ///< Register operand.
36     kImmediate,               ///< Immediate operand.
37     kFPImmediate,             ///< Floating-point immediate operand.
38     kExpr                     ///< Relocatable immediate operand.
39   };
40   unsigned char Kind;
41
42   union {
43     unsigned RegVal;
44     int64_t ImmVal;
45     const MCExpr *ExprVal;
46   };
47   // This can't go in the union due to the non-trivial copy constructor
48   // of APFloat. It's still only valid for Kind == kFPImmediate, though.
49   APFloat FPImmVal;
50 public:
51
52   MCOperand() : Kind(kInvalid), FPImmVal(0.0) {}
53
54   bool isValid() const { return Kind != kInvalid; }
55   bool isReg() const { return Kind == kRegister; }
56   bool isImm() const { return Kind == kImmediate; }
57   bool isFPImm() const { return Kind == kFPImmediate; }
58   bool isExpr() const { return Kind == kExpr; }
59
60   /// getReg - Returns the register number.
61   unsigned getReg() const {
62     assert(isReg() && "This is not a register operand!");
63     return RegVal;
64   }
65
66   /// setReg - Set the register number.
67   void setReg(unsigned Reg) {
68     assert(isReg() && "This is not a register operand!");
69     RegVal = Reg;
70   }
71
72   int64_t getImm() const {
73     assert(isImm() && "This is not an immediate");
74     return ImmVal;
75   }
76   void setImm(int64_t Val) {
77     assert(isImm() && "This is not an immediate");
78     ImmVal = Val;
79   }
80
81   const APFloat &getFPImm() const {
82     assert(isFPImm() && "This is not an FP immediate");
83     return FPImmVal;
84   }
85
86   void setFPImm(const APFloat &Val) {
87     assert(isFPImm() && "This is not an FP immediate");
88     FPImmVal = Val;
89   }
90
91   const MCExpr *getExpr() const {
92     assert(isExpr() && "This is not an expression");
93     return ExprVal;
94   }
95   void setExpr(const MCExpr *Val) {
96     assert(isExpr() && "This is not an expression");
97     ExprVal = Val;
98   }
99
100   static MCOperand CreateReg(unsigned Reg) {
101     MCOperand Op;
102     Op.Kind = kRegister;
103     Op.RegVal = Reg;
104     return Op;
105   }
106   static MCOperand CreateImm(int64_t Val) {
107     MCOperand Op;
108     Op.Kind = kImmediate;
109     Op.ImmVal = Val;
110     return Op;
111   }
112   static MCOperand CreateFPImm(const APFloat &Val) {
113     MCOperand Op;
114     Op.Kind = kFPImmediate;
115     Op.FPImmVal = Val;
116     return Op;
117   }
118   static MCOperand CreateExpr(const MCExpr *Val) {
119     MCOperand Op;
120     Op.Kind = kExpr;
121     Op.ExprVal = Val;
122     return Op;
123   }
124
125   void print(raw_ostream &OS, const MCAsmInfo *MAI) const;
126   void dump() const;
127 };
128
129
130 /// MCInst - Instances of this class represent a single low-level machine
131 /// instruction.
132 class MCInst {
133   unsigned Opcode;
134   SmallVector<MCOperand, 8> Operands;
135 public:
136   MCInst() : Opcode(0) {}
137
138   void setOpcode(unsigned Op) { Opcode = Op; }
139
140   unsigned getOpcode() const { return Opcode; }
141
142   const MCOperand &getOperand(unsigned i) const { return Operands[i]; }
143   MCOperand &getOperand(unsigned i) { return Operands[i]; }
144   unsigned getNumOperands() const { return Operands.size(); }
145
146   void addOperand(const MCOperand &Op) {
147     Operands.push_back(Op);
148   }
149
150   void print(raw_ostream &OS, const MCAsmInfo *MAI) const;
151   void dump() const;
152
153   /// \brief Dump the MCInst as prettily as possible using the additional MC
154   /// structures, if given. Operators are separated by the \arg Separator
155   /// string.
156   void dump_pretty(raw_ostream &OS, const MCAsmInfo *MAI = 0,
157                    const MCInstPrinter *Printer = 0,
158                    StringRef Separator = " ") const;
159 };
160
161
162 } // end namespace llvm
163
164 #endif