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