xref: /freebsd/contrib/llvm-project/llvm/lib/Target/X86/AsmParser/X86Operand.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===- X86Operand.h - Parsed X86 machine instruction ------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H
10 #define LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H
11 
12 #include "MCTargetDesc/X86IntelInstPrinter.h"
13 #include "MCTargetDesc/X86MCTargetDesc.h"
14 #include "X86AsmParserCommon.h"
15 #include "llvm/ADT/STLExtras.h"
16 #include "llvm/ADT/StringRef.h"
17 #include "llvm/MC/MCExpr.h"
18 #include "llvm/MC/MCInst.h"
19 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
20 #include "llvm/MC/MCRegisterInfo.h"
21 #include "llvm/MC/MCSymbol.h"
22 #include "llvm/Support/Casting.h"
23 #include "llvm/Support/SMLoc.h"
24 #include <cassert>
25 #include <memory>
26 
27 namespace llvm {
28 
29 /// X86Operand - Instances of this class represent a parsed X86 machine
30 /// instruction.
31 struct X86Operand final : public MCParsedAsmOperand {
32   enum KindTy { Token, Register, Immediate, Memory, Prefix, DXRegister } Kind;
33 
34   SMLoc StartLoc, EndLoc;
35   SMLoc OffsetOfLoc;
36   StringRef SymName;
37   void *OpDecl;
38   bool AddressOf;
39 
40   /// This used for inline asm which may specify base reg and index reg for
41   /// MemOp. e.g. ARR[eax + ecx*4], so no extra reg can be used for MemOp.
42   bool UseUpRegs = false;
43 
44   struct TokOp {
45     const char *Data;
46     unsigned Length;
47   };
48 
49   struct RegOp {
50     MCRegister RegNo;
51   };
52 
53   struct PrefOp {
54     unsigned Prefixes;
55   };
56 
57   struct ImmOp {
58     const MCExpr *Val;
59     bool LocalRef;
60   };
61 
62   struct MemOp {
63     MCRegister SegReg;
64     const MCExpr *Disp;
65     MCRegister BaseReg;
66     MCRegister DefaultBaseReg;
67     MCRegister IndexReg;
68     unsigned Scale;
69     unsigned Size;
70     unsigned ModeSize;
71 
72     /// If the memory operand is unsized and there are multiple instruction
73     /// matches, prefer the one with this size.
74     unsigned FrontendSize;
75 
76     /// If false, then this operand must be a memory operand for an indirect
77     /// branch instruction. Otherwise, this operand may belong to either a
78     /// direct or indirect branch instruction.
79     bool MaybeDirectBranchDest;
80   };
81 
82   union {
83     struct TokOp Tok;
84     struct RegOp Reg;
85     struct ImmOp Imm;
86     struct MemOp Mem;
87     struct PrefOp Pref;
88   };
89 
X86Operandfinal90   X86Operand(KindTy K, SMLoc Start, SMLoc End)
91       : Kind(K), StartLoc(Start), EndLoc(End), OpDecl(nullptr),
92         AddressOf(false) {}
93 
getSymNamefinal94   StringRef getSymName() override { return SymName; }
getOpDeclfinal95   void *getOpDecl() override { return OpDecl; }
96 
97   /// getStartLoc - Get the location of the first token of this operand.
getStartLocfinal98   SMLoc getStartLoc() const override { return StartLoc; }
99 
100   /// getEndLoc - Get the location of the last token of this operand.
getEndLocfinal101   SMLoc getEndLoc() const override { return EndLoc; }
102 
103   /// getLocRange - Get the range between the first and last token of this
104   /// operand.
getLocRangefinal105   SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
106 
107   /// getOffsetOfLoc - Get the location of the offset operator.
getOffsetOfLocfinal108   SMLoc getOffsetOfLoc() const override { return OffsetOfLoc; }
109 
printfinal110   void print(raw_ostream &OS, const MCAsmInfo &) const override {
111     auto PrintImmValue = [&](const MCExpr *Val, const char *VName) {
112       if (Val->getKind() == MCExpr::Constant) {
113         if (auto Imm = cast<MCConstantExpr>(Val)->getValue())
114           OS << VName << Imm;
115       } else if (Val->getKind() == MCExpr::SymbolRef) {
116         if (auto *SRE = dyn_cast<MCSymbolRefExpr>(Val)) {
117           const MCSymbol &Sym = SRE->getSymbol();
118           if (const char *SymNameStr = Sym.getName().data())
119             OS << VName << SymNameStr;
120         }
121       }
122     };
123 
124     switch (Kind) {
125     case Token:
126       OS << Tok.Data;
127       break;
128     case Register:
129       OS << "Reg:" << X86IntelInstPrinter::getRegisterName(Reg.RegNo);
130       break;
131     case DXRegister:
132       OS << "DXReg";
133       break;
134     case Immediate:
135       PrintImmValue(Imm.Val, "Imm:");
136       break;
137     case Prefix:
138       OS << "Prefix:" << Pref.Prefixes;
139       break;
140     case Memory:
141       OS << "Memory: ModeSize=" << Mem.ModeSize;
142       if (Mem.Size)
143         OS << ",Size=" << Mem.Size;
144       if (Mem.BaseReg)
145         OS << ",BaseReg=" << X86IntelInstPrinter::getRegisterName(Mem.BaseReg);
146       if (Mem.IndexReg)
147         OS << ",IndexReg="
148            << X86IntelInstPrinter::getRegisterName(Mem.IndexReg);
149       if (Mem.Scale)
150         OS << ",Scale=" << Mem.Scale;
151       if (Mem.Disp)
152         PrintImmValue(Mem.Disp, ",Disp=");
153       if (Mem.SegReg)
154         OS << ",SegReg=" << X86IntelInstPrinter::getRegisterName(Mem.SegReg);
155       break;
156     }
157   }
158 
getTokenfinal159   StringRef getToken() const {
160     assert(Kind == Token && "Invalid access!");
161     return StringRef(Tok.Data, Tok.Length);
162   }
setTokenValuefinal163   void setTokenValue(StringRef Value) {
164     assert(Kind == Token && "Invalid access!");
165     Tok.Data = Value.data();
166     Tok.Length = Value.size();
167   }
168 
getRegfinal169   MCRegister getReg() const override {
170     assert(Kind == Register && "Invalid access!");
171     return Reg.RegNo;
172   }
173 
getPrefixfinal174   unsigned getPrefix() const {
175     assert(Kind == Prefix && "Invalid access!");
176     return Pref.Prefixes;
177   }
178 
getImmfinal179   const MCExpr *getImm() const {
180     assert(Kind == Immediate && "Invalid access!");
181     return Imm.Val;
182   }
183 
getMemDispfinal184   const MCExpr *getMemDisp() const {
185     assert(Kind == Memory && "Invalid access!");
186     return Mem.Disp;
187   }
getMemSegRegfinal188   MCRegister getMemSegReg() const {
189     assert(Kind == Memory && "Invalid access!");
190     return Mem.SegReg;
191   }
getMemBaseRegfinal192   MCRegister getMemBaseReg() const {
193     assert(Kind == Memory && "Invalid access!");
194     return Mem.BaseReg;
195   }
getMemDefaultBaseRegfinal196   MCRegister getMemDefaultBaseReg() const {
197     assert(Kind == Memory && "Invalid access!");
198     return Mem.DefaultBaseReg;
199   }
getMemIndexRegfinal200   MCRegister getMemIndexReg() const {
201     assert(Kind == Memory && "Invalid access!");
202     return Mem.IndexReg;
203   }
getMemScalefinal204   unsigned getMemScale() const {
205     assert(Kind == Memory && "Invalid access!");
206     return Mem.Scale;
207   }
getMemModeSizefinal208   unsigned getMemModeSize() const {
209     assert(Kind == Memory && "Invalid access!");
210     return Mem.ModeSize;
211   }
getMemFrontendSizefinal212   unsigned getMemFrontendSize() const {
213     assert(Kind == Memory && "Invalid access!");
214     return Mem.FrontendSize;
215   }
isMaybeDirectBranchDestfinal216   bool isMaybeDirectBranchDest() const {
217     assert(Kind == Memory && "Invalid access!");
218     return Mem.MaybeDirectBranchDest;
219   }
220 
isTokenfinal221   bool isToken() const override {return Kind == Token; }
222 
isImmfinal223   bool isImm() const override { return Kind == Immediate; }
224 
isImmSExti16i8final225   bool isImmSExti16i8() const {
226     if (!isImm())
227       return false;
228 
229     // If this isn't a constant expr, just assume it fits and let relaxation
230     // handle it.
231     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
232     if (!CE)
233       return true;
234 
235     // Otherwise, check the value is in a range that makes sense for this
236     // extension.
237     return isImmSExti16i8Value(CE->getValue());
238   }
isImmSExti32i8final239   bool isImmSExti32i8() const {
240     if (!isImm())
241       return false;
242 
243     // If this isn't a constant expr, just assume it fits and let relaxation
244     // handle it.
245     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
246     if (!CE)
247       return true;
248 
249     // Otherwise, check the value is in a range that makes sense for this
250     // extension.
251     return isImmSExti32i8Value(CE->getValue());
252   }
isImmSExti64i8final253   bool isImmSExti64i8() const {
254     if (!isImm())
255       return false;
256 
257     // If this isn't a constant expr, just assume it fits and let relaxation
258     // handle it.
259     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
260     if (!CE)
261       return true;
262 
263     // Otherwise, check the value is in a range that makes sense for this
264     // extension.
265     return isImmSExti64i8Value(CE->getValue());
266   }
isImmSExti64i32final267   bool isImmSExti64i32() const {
268     if (!isImm())
269       return false;
270 
271     // If this isn't a constant expr, just assume it fits and let relaxation
272     // handle it.
273     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
274     if (!CE)
275       return true;
276 
277     // Otherwise, check the value is in a range that makes sense for this
278     // extension.
279     return isImmSExti64i32Value(CE->getValue());
280   }
281 
isImmUnsignedi4final282   bool isImmUnsignedi4() const {
283     if (!isImm()) return false;
284     // If this isn't a constant expr, reject it. The immediate byte is shared
285     // with a register encoding. We can't have it affected by a relocation.
286     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
287     if (!CE) return false;
288     return isImmUnsignedi4Value(CE->getValue());
289   }
290 
isImmUnsignedi8final291   bool isImmUnsignedi8() const {
292     if (!isImm()) return false;
293     // If this isn't a constant expr, just assume it fits and let relaxation
294     // handle it.
295     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
296     if (!CE) return true;
297     return isImmUnsignedi8Value(CE->getValue());
298   }
299 
isOffsetOfLocalfinal300   bool isOffsetOfLocal() const override { return isImm() && Imm.LocalRef; }
301 
needAddressOffinal302   bool needAddressOf() const override { return AddressOf; }
303 
isMemfinal304   bool isMem() const override { return Kind == Memory; }
isMemUnsizedfinal305   bool isMemUnsized() const {
306     return Kind == Memory && Mem.Size == 0;
307   }
isMem8final308   bool isMem8() const {
309     return Kind == Memory && (!Mem.Size || Mem.Size == 8);
310   }
isMem16final311   bool isMem16() const {
312     return Kind == Memory && (!Mem.Size || Mem.Size == 16);
313   }
isMem32final314   bool isMem32() const {
315     return Kind == Memory && (!Mem.Size || Mem.Size == 32);
316   }
isMem64final317   bool isMem64() const {
318     return Kind == Memory && (!Mem.Size || Mem.Size == 64);
319   }
isMem80final320   bool isMem80() const {
321     return Kind == Memory && (!Mem.Size || Mem.Size == 80);
322   }
isMem128final323   bool isMem128() const {
324     return Kind == Memory && (!Mem.Size || Mem.Size == 128);
325   }
isMem256final326   bool isMem256() const {
327     return Kind == Memory && (!Mem.Size || Mem.Size == 256);
328   }
isMem512final329   bool isMem512() const {
330     return Kind == Memory && (!Mem.Size || Mem.Size == 512);
331   }
332 
isSibMemfinal333   bool isSibMem() const {
334     return isMem() && Mem.BaseReg != X86::RIP && Mem.BaseReg != X86::EIP;
335   }
336 
isMemIndexRegfinal337   bool isMemIndexReg(unsigned LowR, unsigned HighR) const {
338     assert(Kind == Memory && "Invalid access!");
339     return Mem.IndexReg >= LowR && Mem.IndexReg <= HighR;
340   }
341 
isMem32_RC128final342   bool isMem32_RC128() const {
343     return isMem32() && isMemIndexReg(X86::XMM0, X86::XMM15);
344   }
isMem64_RC128final345   bool isMem64_RC128() const {
346     return isMem64() && isMemIndexReg(X86::XMM0, X86::XMM15);
347   }
isMem32_RC256final348   bool isMem32_RC256() const {
349     return isMem32() && isMemIndexReg(X86::YMM0, X86::YMM15);
350   }
isMem64_RC256final351   bool isMem64_RC256() const {
352     return isMem64() && isMemIndexReg(X86::YMM0, X86::YMM15);
353   }
354 
isMem32_RC128Xfinal355   bool isMem32_RC128X() const {
356     return isMem32() && X86II::isXMMReg(Mem.IndexReg);
357   }
isMem64_RC128Xfinal358   bool isMem64_RC128X() const {
359     return isMem64() && X86II::isXMMReg(Mem.IndexReg);
360   }
isMem32_RC256Xfinal361   bool isMem32_RC256X() const {
362     return isMem32() && X86II::isYMMReg(Mem.IndexReg);
363   }
isMem64_RC256Xfinal364   bool isMem64_RC256X() const {
365     return isMem64() && X86II::isYMMReg(Mem.IndexReg);
366   }
isMem32_RC512final367   bool isMem32_RC512() const {
368     return isMem32() && X86II::isZMMReg(Mem.IndexReg);
369   }
isMem64_RC512final370   bool isMem64_RC512() const {
371     return isMem64() && X86II::isZMMReg(Mem.IndexReg);
372   }
373 
isMem512_GR16final374   bool isMem512_GR16() const {
375     if (!isMem512())
376       return false;
377     if (getMemBaseReg() &&
378         !X86MCRegisterClasses[X86::GR16RegClassID].contains(getMemBaseReg()))
379       return false;
380     return true;
381   }
isMem512_GR32final382   bool isMem512_GR32() const {
383     if (!isMem512())
384       return false;
385     if (getMemBaseReg() &&
386         !X86MCRegisterClasses[X86::GR32RegClassID].contains(getMemBaseReg()) &&
387         getMemBaseReg() != X86::EIP)
388       return false;
389     if (getMemIndexReg() &&
390         !X86MCRegisterClasses[X86::GR32RegClassID].contains(getMemIndexReg()) &&
391         getMemIndexReg() != X86::EIZ)
392       return false;
393     return true;
394   }
isMem512_GR64final395   bool isMem512_GR64() const {
396     if (!isMem512())
397       return false;
398     if (getMemBaseReg() &&
399         !X86MCRegisterClasses[X86::GR64RegClassID].contains(getMemBaseReg()) &&
400         getMemBaseReg() != X86::RIP)
401       return false;
402     if (getMemIndexReg() &&
403         !X86MCRegisterClasses[X86::GR64RegClassID].contains(getMemIndexReg()) &&
404         getMemIndexReg() != X86::RIZ)
405       return false;
406     return true;
407   }
408 
isAbsMemfinal409   bool isAbsMem() const {
410     return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
411            !getMemIndexReg() && getMemScale() == 1 && isMaybeDirectBranchDest();
412   }
413 
isAVX512RCfinal414   bool isAVX512RC() const{
415       return isImm();
416   }
417 
isAbsMemMode16final418   bool isAbsMemMode16() const { return isAbsMem() && Mem.ModeSize == 16; }
419 
isDispImm8final420   bool isDispImm8() const {
421     if (auto *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
422       return isImmSExti64i8Value(CE->getValue());
423     return true;
424   }
425 
isAbsMem8final426   bool isAbsMem8() const { return isAbsMem() && isMem8() && isDispImm8(); }
427 
isMemUseUpRegsfinal428   bool isMemUseUpRegs() const override { return UseUpRegs; }
429 
isSrcIdxfinal430   bool isSrcIdx() const {
431     return !getMemIndexReg() && getMemScale() == 1 &&
432       (getMemBaseReg() == X86::RSI || getMemBaseReg() == X86::ESI ||
433        getMemBaseReg() == X86::SI) && isa<MCConstantExpr>(getMemDisp()) &&
434       cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
435   }
isSrcIdx8final436   bool isSrcIdx8() const {
437     return isMem8() && isSrcIdx();
438   }
isSrcIdx16final439   bool isSrcIdx16() const {
440     return isMem16() && isSrcIdx();
441   }
isSrcIdx32final442   bool isSrcIdx32() const {
443     return isMem32() && isSrcIdx();
444   }
isSrcIdx64final445   bool isSrcIdx64() const {
446     return isMem64() && isSrcIdx();
447   }
448 
isDstIdxfinal449   bool isDstIdx() const {
450     return !getMemIndexReg() && getMemScale() == 1 &&
451            (!getMemSegReg() || getMemSegReg() == X86::ES) &&
452            (getMemBaseReg() == X86::RDI || getMemBaseReg() == X86::EDI ||
453             getMemBaseReg() == X86::DI) &&
454            isa<MCConstantExpr>(getMemDisp()) &&
455            cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
456   }
isDstIdx8final457   bool isDstIdx8() const {
458     return isMem8() && isDstIdx();
459   }
isDstIdx16final460   bool isDstIdx16() const {
461     return isMem16() && isDstIdx();
462   }
isDstIdx32final463   bool isDstIdx32() const {
464     return isMem32() && isDstIdx();
465   }
isDstIdx64final466   bool isDstIdx64() const {
467     return isMem64() && isDstIdx();
468   }
469 
isMemOffsfinal470   bool isMemOffs() const {
471     return Kind == Memory && !getMemBaseReg() && !getMemIndexReg() &&
472       getMemScale() == 1;
473   }
474 
isMemOffs16_8final475   bool isMemOffs16_8() const {
476     return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 8);
477   }
isMemOffs16_16final478   bool isMemOffs16_16() const {
479     return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 16);
480   }
isMemOffs16_32final481   bool isMemOffs16_32() const {
482     return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 32);
483   }
isMemOffs32_8final484   bool isMemOffs32_8() const {
485     return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 8);
486   }
isMemOffs32_16final487   bool isMemOffs32_16() const {
488     return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 16);
489   }
isMemOffs32_32final490   bool isMemOffs32_32() const {
491     return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 32);
492   }
isMemOffs32_64final493   bool isMemOffs32_64() const {
494     return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 64);
495   }
isMemOffs64_8final496   bool isMemOffs64_8() const {
497     return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 8);
498   }
isMemOffs64_16final499   bool isMemOffs64_16() const {
500     return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 16);
501   }
isMemOffs64_32final502   bool isMemOffs64_32() const {
503     return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 32);
504   }
isMemOffs64_64final505   bool isMemOffs64_64() const {
506     return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 64);
507   }
508 
isPrefixfinal509   bool isPrefix() const { return Kind == Prefix; }
isRegfinal510   bool isReg() const override { return Kind == Register; }
isDXRegfinal511   bool isDXReg() const { return Kind == DXRegister; }
512 
isGR32orGR64final513   bool isGR32orGR64() const {
514     return Kind == Register &&
515       (X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||
516        X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
517   }
518 
isGR16orGR32orGR64final519   bool isGR16orGR32orGR64() const {
520     return Kind == Register &&
521       (X86MCRegisterClasses[X86::GR16RegClassID].contains(getReg()) ||
522        X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||
523        X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
524   }
525 
isVectorRegfinal526   bool isVectorReg() const {
527     return Kind == Register &&
528            (X86MCRegisterClasses[X86::VR64RegClassID].contains(getReg()) ||
529             X86MCRegisterClasses[X86::VR128XRegClassID].contains(getReg()) ||
530             X86MCRegisterClasses[X86::VR256XRegClassID].contains(getReg()) ||
531             X86MCRegisterClasses[X86::VR512RegClassID].contains(getReg()));
532   }
533 
isVK1Pairfinal534   bool isVK1Pair() const {
535     return Kind == Register &&
536       X86MCRegisterClasses[X86::VK1RegClassID].contains(getReg());
537   }
538 
isVK2Pairfinal539   bool isVK2Pair() const {
540     return Kind == Register &&
541       X86MCRegisterClasses[X86::VK2RegClassID].contains(getReg());
542   }
543 
isVK4Pairfinal544   bool isVK4Pair() const {
545     return Kind == Register &&
546       X86MCRegisterClasses[X86::VK4RegClassID].contains(getReg());
547   }
548 
isVK8Pairfinal549   bool isVK8Pair() const {
550     return Kind == Register &&
551       X86MCRegisterClasses[X86::VK8RegClassID].contains(getReg());
552   }
553 
isVK16Pairfinal554   bool isVK16Pair() const {
555     return Kind == Register &&
556       X86MCRegisterClasses[X86::VK16RegClassID].contains(getReg());
557   }
558 
addExprfinal559   void addExpr(MCInst &Inst, const MCExpr *Expr) const {
560     // Add as immediates when possible.
561     if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
562       Inst.addOperand(MCOperand::createImm(CE->getValue()));
563     else
564       Inst.addOperand(MCOperand::createExpr(Expr));
565   }
566 
addRegOperandsfinal567   void addRegOperands(MCInst &Inst, unsigned N) const {
568     assert(N == 1 && "Invalid number of operands!");
569     Inst.addOperand(MCOperand::createReg(getReg()));
570   }
571 
addGR32orGR64Operandsfinal572   void addGR32orGR64Operands(MCInst &Inst, unsigned N) const {
573     assert(N == 1 && "Invalid number of operands!");
574     MCRegister RegNo = getReg();
575     if (X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
576       RegNo = getX86SubSuperRegister(RegNo, 32);
577     Inst.addOperand(MCOperand::createReg(RegNo));
578   }
579 
addGR16orGR32orGR64Operandsfinal580   void addGR16orGR32orGR64Operands(MCInst &Inst, unsigned N) const {
581     assert(N == 1 && "Invalid number of operands!");
582     MCRegister RegNo = getReg();
583     if (X86MCRegisterClasses[X86::GR32RegClassID].contains(RegNo) ||
584         X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
585       RegNo = getX86SubSuperRegister(RegNo, 16);
586     Inst.addOperand(MCOperand::createReg(RegNo));
587   }
588 
addAVX512RCOperandsfinal589   void addAVX512RCOperands(MCInst &Inst, unsigned N) const {
590     assert(N == 1 && "Invalid number of operands!");
591     addExpr(Inst, getImm());
592   }
593 
addImmOperandsfinal594   void addImmOperands(MCInst &Inst, unsigned N) const {
595     assert(N == 1 && "Invalid number of operands!");
596     addExpr(Inst, getImm());
597   }
598 
addMaskPairOperandsfinal599   void addMaskPairOperands(MCInst &Inst, unsigned N) const {
600     assert(N == 1 && "Invalid number of operands!");
601     MCRegister Reg = getReg();
602     switch (Reg.id()) {
603     case X86::K0:
604     case X86::K1:
605       Reg = X86::K0_K1;
606       break;
607     case X86::K2:
608     case X86::K3:
609       Reg = X86::K2_K3;
610       break;
611     case X86::K4:
612     case X86::K5:
613       Reg = X86::K4_K5;
614       break;
615     case X86::K6:
616     case X86::K7:
617       Reg = X86::K6_K7;
618       break;
619     }
620     Inst.addOperand(MCOperand::createReg(Reg));
621   }
622 
isTILEPairfinal623   bool isTILEPair() const {
624     return Kind == Register &&
625            X86MCRegisterClasses[X86::TILERegClassID].contains(getReg());
626   }
627 
addTILEPairOperandsfinal628   void addTILEPairOperands(MCInst &Inst, unsigned N) const {
629     assert(N == 1 && "Invalid number of operands!");
630     MCRegister Reg = getReg();
631     switch (Reg.id()) {
632     default:
633       llvm_unreachable("Invalid tile register!");
634     case X86::TMM0:
635     case X86::TMM1:
636       Reg = X86::TMM0_TMM1;
637       break;
638     case X86::TMM2:
639     case X86::TMM3:
640       Reg = X86::TMM2_TMM3;
641       break;
642     case X86::TMM4:
643     case X86::TMM5:
644       Reg = X86::TMM4_TMM5;
645       break;
646     case X86::TMM6:
647     case X86::TMM7:
648       Reg = X86::TMM6_TMM7;
649       break;
650     }
651     Inst.addOperand(MCOperand::createReg(Reg));
652   }
653 
addMemOperandsfinal654   void addMemOperands(MCInst &Inst, unsigned N) const {
655     assert((N == 5) && "Invalid number of operands!");
656     if (getMemBaseReg())
657       Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
658     else
659       Inst.addOperand(MCOperand::createReg(getMemDefaultBaseReg()));
660     Inst.addOperand(MCOperand::createImm(getMemScale()));
661     Inst.addOperand(MCOperand::createReg(getMemIndexReg()));
662     addExpr(Inst, getMemDisp());
663     Inst.addOperand(MCOperand::createReg(getMemSegReg()));
664   }
665 
addAbsMemOperandsfinal666   void addAbsMemOperands(MCInst &Inst, unsigned N) const {
667     assert((N == 1) && "Invalid number of operands!");
668     // Add as immediates when possible.
669     if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
670       Inst.addOperand(MCOperand::createImm(CE->getValue()));
671     else
672       Inst.addOperand(MCOperand::createExpr(getMemDisp()));
673   }
674 
addSrcIdxOperandsfinal675   void addSrcIdxOperands(MCInst &Inst, unsigned N) const {
676     assert((N == 2) && "Invalid number of operands!");
677     Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
678     Inst.addOperand(MCOperand::createReg(getMemSegReg()));
679   }
680 
addDstIdxOperandsfinal681   void addDstIdxOperands(MCInst &Inst, unsigned N) const {
682     assert((N == 1) && "Invalid number of operands!");
683     Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
684   }
685 
addMemOffsOperandsfinal686   void addMemOffsOperands(MCInst &Inst, unsigned N) const {
687     assert((N == 2) && "Invalid number of operands!");
688     // Add as immediates when possible.
689     if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
690       Inst.addOperand(MCOperand::createImm(CE->getValue()));
691     else
692       Inst.addOperand(MCOperand::createExpr(getMemDisp()));
693     Inst.addOperand(MCOperand::createReg(getMemSegReg()));
694   }
695 
CreateTokenfinal696   static std::unique_ptr<X86Operand> CreateToken(StringRef Str, SMLoc Loc) {
697     SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size());
698     auto Res = std::make_unique<X86Operand>(Token, Loc, EndLoc);
699     Res->Tok.Data = Str.data();
700     Res->Tok.Length = Str.size();
701     return Res;
702   }
703 
704   static std::unique_ptr<X86Operand>
705   CreateReg(MCRegister Reg, SMLoc StartLoc, SMLoc EndLoc,
706             bool AddressOf = false, SMLoc OffsetOfLoc = SMLoc(),
707             StringRef SymName = StringRef(), void *OpDecl = nullptr) {
708     auto Res = std::make_unique<X86Operand>(Register, StartLoc, EndLoc);
709     Res->Reg.RegNo = Reg;
710     Res->AddressOf = AddressOf;
711     Res->OffsetOfLoc = OffsetOfLoc;
712     Res->SymName = SymName;
713     Res->OpDecl = OpDecl;
714     return Res;
715   }
716 
717   static std::unique_ptr<X86Operand>
CreateDXRegfinal718   CreateDXReg(SMLoc StartLoc, SMLoc EndLoc) {
719     return std::make_unique<X86Operand>(DXRegister, StartLoc, EndLoc);
720   }
721 
722   static std::unique_ptr<X86Operand>
CreatePrefixfinal723   CreatePrefix(unsigned Prefixes, SMLoc StartLoc, SMLoc EndLoc) {
724     auto Res = std::make_unique<X86Operand>(Prefix, StartLoc, EndLoc);
725     Res->Pref.Prefixes = Prefixes;
726     return Res;
727   }
728 
729   static std::unique_ptr<X86Operand> CreateImm(const MCExpr *Val,
730                                                SMLoc StartLoc, SMLoc EndLoc,
731                                                StringRef SymName = StringRef(),
732                                                void *OpDecl = nullptr,
733                                                bool GlobalRef = true) {
734     auto Res = std::make_unique<X86Operand>(Immediate, StartLoc, EndLoc);
735     Res->Imm.Val      = Val;
736     Res->Imm.LocalRef = !GlobalRef;
737     Res->SymName      = SymName;
738     Res->OpDecl       = OpDecl;
739     Res->AddressOf    = true;
740     return Res;
741   }
742 
743   /// Create an absolute memory operand.
744   static std::unique_ptr<X86Operand>
745   CreateMem(unsigned ModeSize, const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc,
746             unsigned Size = 0, StringRef SymName = StringRef(),
747             void *OpDecl = nullptr, unsigned FrontendSize = 0,
748             bool UseUpRegs = false, bool MaybeDirectBranchDest = true) {
749     auto Res = std::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
750     Res->Mem.SegReg = MCRegister();
751     Res->Mem.Disp     = Disp;
752     Res->Mem.BaseReg = MCRegister();
753     Res->Mem.DefaultBaseReg = MCRegister();
754     Res->Mem.IndexReg = MCRegister();
755     Res->Mem.Scale    = 1;
756     Res->Mem.Size     = Size;
757     Res->Mem.ModeSize = ModeSize;
758     Res->Mem.FrontendSize = FrontendSize;
759     Res->Mem.MaybeDirectBranchDest = MaybeDirectBranchDest;
760     Res->UseUpRegs = UseUpRegs;
761     Res->SymName      = SymName;
762     Res->OpDecl       = OpDecl;
763     Res->AddressOf    = false;
764     return Res;
765   }
766 
767   /// Create a generalized memory operand.
768   static std::unique_ptr<X86Operand>
769   CreateMem(unsigned ModeSize, MCRegister SegReg, const MCExpr *Disp,
770             MCRegister BaseReg, MCRegister IndexReg, unsigned Scale,
771             SMLoc StartLoc, SMLoc EndLoc, unsigned Size = 0,
772             MCRegister DefaultBaseReg = MCRegister(),
773             StringRef SymName = StringRef(), void *OpDecl = nullptr,
774             unsigned FrontendSize = 0, bool UseUpRegs = false,
775             bool MaybeDirectBranchDest = true) {
776     // We should never just have a displacement, that should be parsed as an
777     // absolute memory operand.
778     assert((SegReg || BaseReg || IndexReg || DefaultBaseReg) &&
779            "Invalid memory operand!");
780 
781     // The scale should always be one of {1,2,4,8}.
782     assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
783            "Invalid scale!");
784     auto Res = std::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
785     Res->Mem.SegReg   = SegReg;
786     Res->Mem.Disp     = Disp;
787     Res->Mem.BaseReg  = BaseReg;
788     Res->Mem.DefaultBaseReg = DefaultBaseReg;
789     Res->Mem.IndexReg = IndexReg;
790     Res->Mem.Scale    = Scale;
791     Res->Mem.Size     = Size;
792     Res->Mem.ModeSize = ModeSize;
793     Res->Mem.FrontendSize = FrontendSize;
794     Res->Mem.MaybeDirectBranchDest = MaybeDirectBranchDest;
795     Res->UseUpRegs = UseUpRegs;
796     Res->SymName      = SymName;
797     Res->OpDecl       = OpDecl;
798     Res->AddressOf    = false;
799     return Res;
800   }
801 };
802 
803 } // end namespace llvm
804 
805 #endif // LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H
806