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