1//===-- X86Operand.h - Parsed X86 machine instruction --------------------===//
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#ifndef X86_OPERAND_H
11#define X86_OPERAND_H
12
13#include "X86AsmParserCommon.h"
14#include "llvm/MC/MCExpr.h"
15#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
16#include "llvm/ADT/STLExtras.h"
17
18namespace llvm {
19
20/// X86Operand - Instances of this class represent a parsed X86 machine
21/// instruction.
22struct X86Operand : public MCParsedAsmOperand {
23  enum KindTy {
24    Token,
25    Register,
26    Immediate,
27    Memory
28  } Kind;
29
30  SMLoc StartLoc, EndLoc;
31  SMLoc OffsetOfLoc;
32  StringRef SymName;
33  void *OpDecl;
34  bool AddressOf;
35
36  struct TokOp {
37    const char *Data;
38    unsigned Length;
39  };
40
41  struct RegOp {
42    unsigned RegNo;
43  };
44
45  struct ImmOp {
46    const MCExpr *Val;
47  };
48
49  struct MemOp {
50    unsigned SegReg;
51    const MCExpr *Disp;
52    unsigned BaseReg;
53    unsigned IndexReg;
54    unsigned Scale;
55    unsigned Size;
56  };
57
58  union {
59    struct TokOp Tok;
60    struct RegOp Reg;
61    struct ImmOp Imm;
62    struct MemOp Mem;
63  };
64
65  X86Operand(KindTy K, SMLoc Start, SMLoc End)
66    : Kind(K), StartLoc(Start), EndLoc(End) {}
67
68  StringRef getSymName() override { return SymName; }
69  void *getOpDecl() override { return OpDecl; }
70
71  /// getStartLoc - Get the location of the first token of this operand.
72  SMLoc getStartLoc() const override { return StartLoc; }
73  /// getEndLoc - Get the location of the last token of this operand.
74  SMLoc getEndLoc() const override { return EndLoc; }
75  /// getLocRange - Get the range between the first and last token of this
76  /// operand.
77  SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
78  /// getOffsetOfLoc - Get the location of the offset operator.
79  SMLoc getOffsetOfLoc() const override { return OffsetOfLoc; }
80
81  void print(raw_ostream &OS) const override {}
82
83  StringRef getToken() const {
84    assert(Kind == Token && "Invalid access!");
85    return StringRef(Tok.Data, Tok.Length);
86  }
87  void setTokenValue(StringRef Value) {
88    assert(Kind == Token && "Invalid access!");
89    Tok.Data = Value.data();
90    Tok.Length = Value.size();
91  }
92
93  unsigned getReg() const override {
94    assert(Kind == Register && "Invalid access!");
95    return Reg.RegNo;
96  }
97
98  const MCExpr *getImm() const {
99    assert(Kind == Immediate && "Invalid access!");
100    return Imm.Val;
101  }
102
103  const MCExpr *getMemDisp() const {
104    assert(Kind == Memory && "Invalid access!");
105    return Mem.Disp;
106  }
107  unsigned getMemSegReg() const {
108    assert(Kind == Memory && "Invalid access!");
109    return Mem.SegReg;
110  }
111  unsigned getMemBaseReg() const {
112    assert(Kind == Memory && "Invalid access!");
113    return Mem.BaseReg;
114  }
115  unsigned getMemIndexReg() const {
116    assert(Kind == Memory && "Invalid access!");
117    return Mem.IndexReg;
118  }
119  unsigned getMemScale() const {
120    assert(Kind == Memory && "Invalid access!");
121    return Mem.Scale;
122  }
123
124  bool isToken() const override {return Kind == Token; }
125
126  bool isImm() const override { return Kind == Immediate; }
127
128  bool isImmSExti16i8() const {
129    if (!isImm())
130      return false;
131
132    // If this isn't a constant expr, just assume it fits and let relaxation
133    // handle it.
134    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
135    if (!CE)
136      return true;
137
138    // Otherwise, check the value is in a range that makes sense for this
139    // extension.
140    return isImmSExti16i8Value(CE->getValue());
141  }
142  bool isImmSExti32i8() const {
143    if (!isImm())
144      return false;
145
146    // If this isn't a constant expr, just assume it fits and let relaxation
147    // handle it.
148    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
149    if (!CE)
150      return true;
151
152    // Otherwise, check the value is in a range that makes sense for this
153    // extension.
154    return isImmSExti32i8Value(CE->getValue());
155  }
156  bool isImmZExtu32u8() const {
157    if (!isImm())
158      return false;
159
160    // If this isn't a constant expr, just assume it fits and let relaxation
161    // handle it.
162    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
163    if (!CE)
164      return true;
165
166    // Otherwise, check the value is in a range that makes sense for this
167    // extension.
168    return isImmZExtu32u8Value(CE->getValue());
169  }
170  bool isImmSExti64i8() const {
171    if (!isImm())
172      return false;
173
174    // If this isn't a constant expr, just assume it fits and let relaxation
175    // handle it.
176    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
177    if (!CE)
178      return true;
179
180    // Otherwise, check the value is in a range that makes sense for this
181    // extension.
182    return isImmSExti64i8Value(CE->getValue());
183  }
184  bool isImmSExti64i32() const {
185    if (!isImm())
186      return false;
187
188    // If this isn't a constant expr, just assume it fits and let relaxation
189    // handle it.
190    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
191    if (!CE)
192      return true;
193
194    // Otherwise, check the value is in a range that makes sense for this
195    // extension.
196    return isImmSExti64i32Value(CE->getValue());
197  }
198
199  bool isOffsetOf() const override {
200    return OffsetOfLoc.getPointer();
201  }
202
203  bool needAddressOf() const override {
204    return AddressOf;
205  }
206
207  bool isMem() const override { return Kind == Memory; }
208  bool isMem8() const {
209    return Kind == Memory && (!Mem.Size || Mem.Size == 8);
210  }
211  bool isMem16() const {
212    return Kind == Memory && (!Mem.Size || Mem.Size == 16);
213  }
214  bool isMem32() const {
215    return Kind == Memory && (!Mem.Size || Mem.Size == 32);
216  }
217  bool isMem64() const {
218    return Kind == Memory && (!Mem.Size || Mem.Size == 64);
219  }
220  bool isMem80() const {
221    return Kind == Memory && (!Mem.Size || Mem.Size == 80);
222  }
223  bool isMem128() const {
224    return Kind == Memory && (!Mem.Size || Mem.Size == 128);
225  }
226  bool isMem256() const {
227    return Kind == Memory && (!Mem.Size || Mem.Size == 256);
228  }
229  bool isMem512() const {
230    return Kind == Memory && (!Mem.Size || Mem.Size == 512);
231  }
232
233  bool isMemVX32() const {
234    return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
235      getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM15;
236  }
237  bool isMemVY32() const {
238    return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
239      getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM15;
240  }
241  bool isMemVX64() const {
242    return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
243      getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM15;
244  }
245  bool isMemVY64() const {
246    return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
247      getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM15;
248  }
249  bool isMemVZ32() const {
250    return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
251      getMemIndexReg() >= X86::ZMM0 && getMemIndexReg() <= X86::ZMM31;
252  }
253  bool isMemVZ64() const {
254    return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
255      getMemIndexReg() >= X86::ZMM0 && getMemIndexReg() <= X86::ZMM31;
256  }
257
258  bool isAbsMem() const {
259    return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
260      !getMemIndexReg() && getMemScale() == 1;
261  }
262
263  bool isSrcIdx() const {
264    return !getMemIndexReg() && getMemScale() == 1 &&
265      (getMemBaseReg() == X86::RSI || getMemBaseReg() == X86::ESI ||
266       getMemBaseReg() == X86::SI) && isa<MCConstantExpr>(getMemDisp()) &&
267      cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
268  }
269  bool isSrcIdx8() const {
270    return isMem8() && isSrcIdx();
271  }
272  bool isSrcIdx16() const {
273    return isMem16() && isSrcIdx();
274  }
275  bool isSrcIdx32() const {
276    return isMem32() && isSrcIdx();
277  }
278  bool isSrcIdx64() const {
279    return isMem64() && isSrcIdx();
280  }
281
282  bool isDstIdx() const {
283    return !getMemIndexReg() && getMemScale() == 1 &&
284      (getMemSegReg() == 0 || getMemSegReg() == X86::ES) &&
285      (getMemBaseReg() == X86::RDI || getMemBaseReg() == X86::EDI ||
286       getMemBaseReg() == X86::DI) && isa<MCConstantExpr>(getMemDisp()) &&
287      cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
288  }
289  bool isDstIdx8() const {
290    return isMem8() && isDstIdx();
291  }
292  bool isDstIdx16() const {
293    return isMem16() && isDstIdx();
294  }
295  bool isDstIdx32() const {
296    return isMem32() && isDstIdx();
297  }
298  bool isDstIdx64() const {
299    return isMem64() && isDstIdx();
300  }
301
302  bool isMemOffs8() const {
303    return Kind == Memory && !getMemBaseReg() &&
304      !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 8);
305  }
306  bool isMemOffs16() const {
307    return Kind == Memory && !getMemBaseReg() &&
308      !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 16);
309  }
310  bool isMemOffs32() const {
311    return Kind == Memory && !getMemBaseReg() &&
312      !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 32);
313  }
314  bool isMemOffs64() const {
315    return Kind == Memory && !getMemBaseReg() &&
316      !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 64);
317  }
318
319  bool isReg() const override { return Kind == Register; }
320
321  bool isGR32orGR64() const {
322    return Kind == Register &&
323      (X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||
324      X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
325  }
326
327  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
328    // Add as immediates when possible.
329    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
330      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
331    else
332      Inst.addOperand(MCOperand::CreateExpr(Expr));
333  }
334
335  void addRegOperands(MCInst &Inst, unsigned N) const {
336    assert(N == 1 && "Invalid number of operands!");
337    Inst.addOperand(MCOperand::CreateReg(getReg()));
338  }
339
340  static unsigned getGR32FromGR64(unsigned RegNo) {
341    switch (RegNo) {
342    default: llvm_unreachable("Unexpected register");
343    case X86::RAX: return X86::EAX;
344    case X86::RCX: return X86::ECX;
345    case X86::RDX: return X86::EDX;
346    case X86::RBX: return X86::EBX;
347    case X86::RBP: return X86::EBP;
348    case X86::RSP: return X86::ESP;
349    case X86::RSI: return X86::ESI;
350    case X86::RDI: return X86::EDI;
351    case X86::R8: return X86::R8D;
352    case X86::R9: return X86::R9D;
353    case X86::R10: return X86::R10D;
354    case X86::R11: return X86::R11D;
355    case X86::R12: return X86::R12D;
356    case X86::R13: return X86::R13D;
357    case X86::R14: return X86::R14D;
358    case X86::R15: return X86::R15D;
359    case X86::RIP: return X86::EIP;
360    }
361  }
362
363  void addGR32orGR64Operands(MCInst &Inst, unsigned N) const {
364    assert(N == 1 && "Invalid number of operands!");
365    unsigned RegNo = getReg();
366    if (X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
367      RegNo = getGR32FromGR64(RegNo);
368    Inst.addOperand(MCOperand::CreateReg(RegNo));
369  }
370
371  void addImmOperands(MCInst &Inst, unsigned N) const {
372    assert(N == 1 && "Invalid number of operands!");
373    addExpr(Inst, getImm());
374  }
375
376  void addMemOperands(MCInst &Inst, unsigned N) const {
377    assert((N == 5) && "Invalid number of operands!");
378    Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
379    Inst.addOperand(MCOperand::CreateImm(getMemScale()));
380    Inst.addOperand(MCOperand::CreateReg(getMemIndexReg()));
381    addExpr(Inst, getMemDisp());
382    Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
383  }
384
385  void addAbsMemOperands(MCInst &Inst, unsigned N) const {
386    assert((N == 1) && "Invalid number of operands!");
387    // Add as immediates when possible.
388    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
389      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
390    else
391      Inst.addOperand(MCOperand::CreateExpr(getMemDisp()));
392  }
393
394  void addSrcIdxOperands(MCInst &Inst, unsigned N) const {
395    assert((N == 2) && "Invalid number of operands!");
396    Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
397    Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
398  }
399  void addDstIdxOperands(MCInst &Inst, unsigned N) const {
400    assert((N == 1) && "Invalid number of operands!");
401    Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
402  }
403
404  void addMemOffsOperands(MCInst &Inst, unsigned N) const {
405    assert((N == 2) && "Invalid number of operands!");
406    // Add as immediates when possible.
407    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
408      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
409    else
410      Inst.addOperand(MCOperand::CreateExpr(getMemDisp()));
411    Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
412  }
413
414  static std::unique_ptr<X86Operand> CreateToken(StringRef Str, SMLoc Loc) {
415    SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size());
416    auto Res = llvm::make_unique<X86Operand>(Token, Loc, EndLoc);
417    Res->Tok.Data = Str.data();
418    Res->Tok.Length = Str.size();
419    return Res;
420  }
421
422  static std::unique_ptr<X86Operand>
423  CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc,
424            bool AddressOf = false, SMLoc OffsetOfLoc = SMLoc(),
425            StringRef SymName = StringRef(), void *OpDecl = nullptr) {
426    auto Res = llvm::make_unique<X86Operand>(Register, StartLoc, EndLoc);
427    Res->Reg.RegNo = RegNo;
428    Res->AddressOf = AddressOf;
429    Res->OffsetOfLoc = OffsetOfLoc;
430    Res->SymName = SymName;
431    Res->OpDecl = OpDecl;
432    return Res;
433  }
434
435  static std::unique_ptr<X86Operand> CreateImm(const MCExpr *Val,
436                                               SMLoc StartLoc, SMLoc EndLoc) {
437    auto Res = llvm::make_unique<X86Operand>(Immediate, StartLoc, EndLoc);
438    Res->Imm.Val = Val;
439    return Res;
440  }
441
442  /// Create an absolute memory operand.
443  static std::unique_ptr<X86Operand>
444  CreateMem(const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc, unsigned Size = 0,
445            StringRef SymName = StringRef(), void *OpDecl = nullptr) {
446    auto Res = llvm::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
447    Res->Mem.SegReg   = 0;
448    Res->Mem.Disp     = Disp;
449    Res->Mem.BaseReg  = 0;
450    Res->Mem.IndexReg = 0;
451    Res->Mem.Scale    = 1;
452    Res->Mem.Size     = Size;
453    Res->SymName      = SymName;
454    Res->OpDecl       = OpDecl;
455    Res->AddressOf    = false;
456    return Res;
457  }
458
459  /// Create a generalized memory operand.
460  static std::unique_ptr<X86Operand>
461  CreateMem(unsigned SegReg, const MCExpr *Disp, unsigned BaseReg,
462            unsigned IndexReg, unsigned Scale, SMLoc StartLoc, SMLoc EndLoc,
463            unsigned Size = 0, StringRef SymName = StringRef(),
464            void *OpDecl = nullptr) {
465    // We should never just have a displacement, that should be parsed as an
466    // absolute memory operand.
467    assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
468
469    // The scale should always be one of {1,2,4,8}.
470    assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
471           "Invalid scale!");
472    auto Res = llvm::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
473    Res->Mem.SegReg   = SegReg;
474    Res->Mem.Disp     = Disp;
475    Res->Mem.BaseReg  = BaseReg;
476    Res->Mem.IndexReg = IndexReg;
477    Res->Mem.Scale    = Scale;
478    Res->Mem.Size     = Size;
479    Res->SymName      = SymName;
480    Res->OpDecl       = OpDecl;
481    Res->AddressOf    = false;
482    return Res;
483  }
484};
485
486} // End of namespace llvm
487
488#endif // X86_OPERAND
489