xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/X86/AsmParser/X86Operand.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- X86Operand.h - Parsed X86 machine instruction ------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H
100b57cec5SDimitry Andric #define LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H
110b57cec5SDimitry Andric 
120b57cec5SDimitry Andric #include "MCTargetDesc/X86IntelInstPrinter.h"
130b57cec5SDimitry Andric #include "MCTargetDesc/X86MCTargetDesc.h"
140b57cec5SDimitry Andric #include "X86AsmParserCommon.h"
150b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
160b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
170b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h"
180b57cec5SDimitry Andric #include "llvm/MC/MCInst.h"
190b57cec5SDimitry Andric #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
2081ad6265SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
2181ad6265SDimitry Andric #include "llvm/MC/MCSymbol.h"
220b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
230b57cec5SDimitry Andric #include "llvm/Support/SMLoc.h"
240b57cec5SDimitry Andric #include <cassert>
250b57cec5SDimitry Andric #include <memory>
260b57cec5SDimitry Andric 
270b57cec5SDimitry Andric namespace llvm {
280b57cec5SDimitry Andric 
290b57cec5SDimitry Andric /// X86Operand - Instances of this class represent a parsed X86 machine
300b57cec5SDimitry Andric /// instruction.
310b57cec5SDimitry Andric struct X86Operand final : public MCParsedAsmOperand {
320b57cec5SDimitry Andric   enum KindTy { Token, Register, Immediate, Memory, Prefix, DXRegister } Kind;
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric   SMLoc StartLoc, EndLoc;
350b57cec5SDimitry Andric   SMLoc OffsetOfLoc;
360b57cec5SDimitry Andric   StringRef SymName;
370b57cec5SDimitry Andric   void *OpDecl;
380b57cec5SDimitry Andric   bool AddressOf;
390b57cec5SDimitry Andric 
4081ad6265SDimitry Andric   /// This used for inline asm which may specify base reg and index reg for
4181ad6265SDimitry Andric   /// MemOp. e.g. ARR[eax + ecx*4], so no extra reg can be used for MemOp.
4281ad6265SDimitry Andric   bool UseUpRegs = false;
4381ad6265SDimitry Andric 
440b57cec5SDimitry Andric   struct TokOp {
450b57cec5SDimitry Andric     const char *Data;
460b57cec5SDimitry Andric     unsigned Length;
470b57cec5SDimitry Andric   };
480b57cec5SDimitry Andric 
490b57cec5SDimitry Andric   struct RegOp {
500b57cec5SDimitry Andric     unsigned RegNo;
510b57cec5SDimitry Andric   };
520b57cec5SDimitry Andric 
530b57cec5SDimitry Andric   struct PrefOp {
540b57cec5SDimitry Andric     unsigned Prefixes;
550b57cec5SDimitry Andric   };
560b57cec5SDimitry Andric 
570b57cec5SDimitry Andric   struct ImmOp {
580b57cec5SDimitry Andric     const MCExpr *Val;
59480093f4SDimitry Andric     bool LocalRef;
600b57cec5SDimitry Andric   };
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric   struct MemOp {
630b57cec5SDimitry Andric     unsigned SegReg;
640b57cec5SDimitry Andric     const MCExpr *Disp;
650b57cec5SDimitry Andric     unsigned BaseReg;
665ffd83dbSDimitry Andric     unsigned DefaultBaseReg;
670b57cec5SDimitry Andric     unsigned IndexReg;
680b57cec5SDimitry Andric     unsigned Scale;
690b57cec5SDimitry Andric     unsigned Size;
700b57cec5SDimitry Andric     unsigned ModeSize;
710b57cec5SDimitry Andric 
720b57cec5SDimitry Andric     /// If the memory operand is unsized and there are multiple instruction
730b57cec5SDimitry Andric     /// matches, prefer the one with this size.
740b57cec5SDimitry Andric     unsigned FrontendSize;
7581ad6265SDimitry Andric 
7681ad6265SDimitry Andric     /// If false, then this operand must be a memory operand for an indirect
7781ad6265SDimitry Andric     /// branch instruction. Otherwise, this operand may belong to either a
7881ad6265SDimitry Andric     /// direct or indirect branch instruction.
7981ad6265SDimitry Andric     bool MaybeDirectBranchDest;
800b57cec5SDimitry Andric   };
810b57cec5SDimitry Andric 
820b57cec5SDimitry Andric   union {
830b57cec5SDimitry Andric     struct TokOp Tok;
840b57cec5SDimitry Andric     struct RegOp Reg;
850b57cec5SDimitry Andric     struct ImmOp Imm;
860b57cec5SDimitry Andric     struct MemOp Mem;
870b57cec5SDimitry Andric     struct PrefOp Pref;
880b57cec5SDimitry Andric   };
890b57cec5SDimitry Andric 
900b57cec5SDimitry Andric   X86Operand(KindTy K, SMLoc Start, SMLoc End)
91fe6060f1SDimitry Andric       : Kind(K), StartLoc(Start), EndLoc(End), OpDecl(nullptr),
92349cc55cSDimitry Andric         AddressOf(false) {}
930b57cec5SDimitry Andric 
940b57cec5SDimitry Andric   StringRef getSymName() override { return SymName; }
950b57cec5SDimitry Andric   void *getOpDecl() override { return OpDecl; }
960b57cec5SDimitry Andric 
970b57cec5SDimitry Andric   /// getStartLoc - Get the location of the first token of this operand.
980b57cec5SDimitry Andric   SMLoc getStartLoc() const override { return StartLoc; }
990b57cec5SDimitry Andric 
1000b57cec5SDimitry Andric   /// getEndLoc - Get the location of the last token of this operand.
1010b57cec5SDimitry Andric   SMLoc getEndLoc() const override { return EndLoc; }
1020b57cec5SDimitry Andric 
1030b57cec5SDimitry Andric   /// getLocRange - Get the range between the first and last token of this
1040b57cec5SDimitry Andric   /// operand.
1050b57cec5SDimitry Andric   SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
1060b57cec5SDimitry Andric 
1070b57cec5SDimitry Andric   /// getOffsetOfLoc - Get the location of the offset operator.
1080b57cec5SDimitry Andric   SMLoc getOffsetOfLoc() const override { return OffsetOfLoc; }
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric   void print(raw_ostream &OS) const override {
1110b57cec5SDimitry Andric 
1120b57cec5SDimitry Andric     auto PrintImmValue = [&](const MCExpr *Val, const char *VName) {
1130b57cec5SDimitry Andric       if (Val->getKind() == MCExpr::Constant) {
1140b57cec5SDimitry Andric         if (auto Imm = cast<MCConstantExpr>(Val)->getValue())
1150b57cec5SDimitry Andric           OS << VName << Imm;
1160b57cec5SDimitry Andric       } else if (Val->getKind() == MCExpr::SymbolRef) {
1170b57cec5SDimitry Andric         if (auto *SRE = dyn_cast<MCSymbolRefExpr>(Val)) {
1180b57cec5SDimitry Andric           const MCSymbol &Sym = SRE->getSymbol();
119480093f4SDimitry Andric           if (const char *SymNameStr = Sym.getName().data())
120480093f4SDimitry Andric             OS << VName << SymNameStr;
1210b57cec5SDimitry Andric         }
1220b57cec5SDimitry Andric       }
1230b57cec5SDimitry Andric     };
1240b57cec5SDimitry Andric 
1250b57cec5SDimitry Andric     switch (Kind) {
1260b57cec5SDimitry Andric     case Token:
1270b57cec5SDimitry Andric       OS << Tok.Data;
1280b57cec5SDimitry Andric       break;
1290b57cec5SDimitry Andric     case Register:
1300b57cec5SDimitry Andric       OS << "Reg:" << X86IntelInstPrinter::getRegisterName(Reg.RegNo);
1310b57cec5SDimitry Andric       break;
1320b57cec5SDimitry Andric     case DXRegister:
1330b57cec5SDimitry Andric       OS << "DXReg";
1340b57cec5SDimitry Andric       break;
1350b57cec5SDimitry Andric     case Immediate:
1360b57cec5SDimitry Andric       PrintImmValue(Imm.Val, "Imm:");
1370b57cec5SDimitry Andric       break;
1380b57cec5SDimitry Andric     case Prefix:
1390b57cec5SDimitry Andric       OS << "Prefix:" << Pref.Prefixes;
1400b57cec5SDimitry Andric       break;
1410b57cec5SDimitry Andric     case Memory:
1420b57cec5SDimitry Andric       OS << "Memory: ModeSize=" << Mem.ModeSize;
1430b57cec5SDimitry Andric       if (Mem.Size)
1440b57cec5SDimitry Andric         OS << ",Size=" << Mem.Size;
1450b57cec5SDimitry Andric       if (Mem.BaseReg)
1460b57cec5SDimitry Andric         OS << ",BaseReg=" << X86IntelInstPrinter::getRegisterName(Mem.BaseReg);
1470b57cec5SDimitry Andric       if (Mem.IndexReg)
1480b57cec5SDimitry Andric         OS << ",IndexReg="
1490b57cec5SDimitry Andric            << X86IntelInstPrinter::getRegisterName(Mem.IndexReg);
1500b57cec5SDimitry Andric       if (Mem.Scale)
1510b57cec5SDimitry Andric         OS << ",Scale=" << Mem.Scale;
1520b57cec5SDimitry Andric       if (Mem.Disp)
1530b57cec5SDimitry Andric         PrintImmValue(Mem.Disp, ",Disp=");
1540b57cec5SDimitry Andric       if (Mem.SegReg)
1550b57cec5SDimitry Andric         OS << ",SegReg=" << X86IntelInstPrinter::getRegisterName(Mem.SegReg);
1560b57cec5SDimitry Andric       break;
1570b57cec5SDimitry Andric     }
1580b57cec5SDimitry Andric   }
1590b57cec5SDimitry Andric 
1600b57cec5SDimitry Andric   StringRef getToken() const {
1610b57cec5SDimitry Andric     assert(Kind == Token && "Invalid access!");
1620b57cec5SDimitry Andric     return StringRef(Tok.Data, Tok.Length);
1630b57cec5SDimitry Andric   }
1640b57cec5SDimitry Andric   void setTokenValue(StringRef Value) {
1650b57cec5SDimitry Andric     assert(Kind == Token && "Invalid access!");
1660b57cec5SDimitry Andric     Tok.Data = Value.data();
1670b57cec5SDimitry Andric     Tok.Length = Value.size();
1680b57cec5SDimitry Andric   }
1690b57cec5SDimitry Andric 
170*0fca6ea1SDimitry Andric   MCRegister getReg() const override {
1710b57cec5SDimitry Andric     assert(Kind == Register && "Invalid access!");
1720b57cec5SDimitry Andric     return Reg.RegNo;
1730b57cec5SDimitry Andric   }
1740b57cec5SDimitry Andric 
1750b57cec5SDimitry Andric   unsigned getPrefix() const {
1760b57cec5SDimitry Andric     assert(Kind == Prefix && "Invalid access!");
1770b57cec5SDimitry Andric     return Pref.Prefixes;
1780b57cec5SDimitry Andric   }
1790b57cec5SDimitry Andric 
1800b57cec5SDimitry Andric   const MCExpr *getImm() const {
1810b57cec5SDimitry Andric     assert(Kind == Immediate && "Invalid access!");
1820b57cec5SDimitry Andric     return Imm.Val;
1830b57cec5SDimitry Andric   }
1840b57cec5SDimitry Andric 
1850b57cec5SDimitry Andric   const MCExpr *getMemDisp() const {
1860b57cec5SDimitry Andric     assert(Kind == Memory && "Invalid access!");
1870b57cec5SDimitry Andric     return Mem.Disp;
1880b57cec5SDimitry Andric   }
1890b57cec5SDimitry Andric   unsigned getMemSegReg() const {
1900b57cec5SDimitry Andric     assert(Kind == Memory && "Invalid access!");
1910b57cec5SDimitry Andric     return Mem.SegReg;
1920b57cec5SDimitry Andric   }
1930b57cec5SDimitry Andric   unsigned getMemBaseReg() const {
1940b57cec5SDimitry Andric     assert(Kind == Memory && "Invalid access!");
1950b57cec5SDimitry Andric     return Mem.BaseReg;
1960b57cec5SDimitry Andric   }
1975ffd83dbSDimitry Andric   unsigned getMemDefaultBaseReg() const {
1985ffd83dbSDimitry Andric     assert(Kind == Memory && "Invalid access!");
1995ffd83dbSDimitry Andric     return Mem.DefaultBaseReg;
2005ffd83dbSDimitry Andric   }
2010b57cec5SDimitry Andric   unsigned getMemIndexReg() const {
2020b57cec5SDimitry Andric     assert(Kind == Memory && "Invalid access!");
2030b57cec5SDimitry Andric     return Mem.IndexReg;
2040b57cec5SDimitry Andric   }
2050b57cec5SDimitry Andric   unsigned getMemScale() const {
2060b57cec5SDimitry Andric     assert(Kind == Memory && "Invalid access!");
2070b57cec5SDimitry Andric     return Mem.Scale;
2080b57cec5SDimitry Andric   }
2090b57cec5SDimitry Andric   unsigned getMemModeSize() const {
2100b57cec5SDimitry Andric     assert(Kind == Memory && "Invalid access!");
2110b57cec5SDimitry Andric     return Mem.ModeSize;
2120b57cec5SDimitry Andric   }
2130b57cec5SDimitry Andric   unsigned getMemFrontendSize() const {
2140b57cec5SDimitry Andric     assert(Kind == Memory && "Invalid access!");
2150b57cec5SDimitry Andric     return Mem.FrontendSize;
2160b57cec5SDimitry Andric   }
21781ad6265SDimitry Andric   bool isMaybeDirectBranchDest() const {
21881ad6265SDimitry Andric     assert(Kind == Memory && "Invalid access!");
21981ad6265SDimitry Andric     return Mem.MaybeDirectBranchDest;
22081ad6265SDimitry Andric   }
2210b57cec5SDimitry Andric 
2220b57cec5SDimitry Andric   bool isToken() const override {return Kind == Token; }
2230b57cec5SDimitry Andric 
2240b57cec5SDimitry Andric   bool isImm() const override { return Kind == Immediate; }
2250b57cec5SDimitry Andric 
2260b57cec5SDimitry Andric   bool isImmSExti16i8() const {
2270b57cec5SDimitry Andric     if (!isImm())
2280b57cec5SDimitry Andric       return false;
2290b57cec5SDimitry Andric 
2300b57cec5SDimitry Andric     // If this isn't a constant expr, just assume it fits and let relaxation
2310b57cec5SDimitry Andric     // handle it.
2320b57cec5SDimitry Andric     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2330b57cec5SDimitry Andric     if (!CE)
2340b57cec5SDimitry Andric       return true;
2350b57cec5SDimitry Andric 
2360b57cec5SDimitry Andric     // Otherwise, check the value is in a range that makes sense for this
2370b57cec5SDimitry Andric     // extension.
2380b57cec5SDimitry Andric     return isImmSExti16i8Value(CE->getValue());
2390b57cec5SDimitry Andric   }
2400b57cec5SDimitry Andric   bool isImmSExti32i8() const {
2410b57cec5SDimitry Andric     if (!isImm())
2420b57cec5SDimitry Andric       return false;
2430b57cec5SDimitry Andric 
2440b57cec5SDimitry Andric     // If this isn't a constant expr, just assume it fits and let relaxation
2450b57cec5SDimitry Andric     // handle it.
2460b57cec5SDimitry Andric     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2470b57cec5SDimitry Andric     if (!CE)
2480b57cec5SDimitry Andric       return true;
2490b57cec5SDimitry Andric 
2500b57cec5SDimitry Andric     // Otherwise, check the value is in a range that makes sense for this
2510b57cec5SDimitry Andric     // extension.
2520b57cec5SDimitry Andric     return isImmSExti32i8Value(CE->getValue());
2530b57cec5SDimitry Andric   }
2540b57cec5SDimitry Andric   bool isImmSExti64i8() const {
2550b57cec5SDimitry Andric     if (!isImm())
2560b57cec5SDimitry Andric       return false;
2570b57cec5SDimitry Andric 
2580b57cec5SDimitry Andric     // If this isn't a constant expr, just assume it fits and let relaxation
2590b57cec5SDimitry Andric     // handle it.
2600b57cec5SDimitry Andric     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2610b57cec5SDimitry Andric     if (!CE)
2620b57cec5SDimitry Andric       return true;
2630b57cec5SDimitry Andric 
2640b57cec5SDimitry Andric     // Otherwise, check the value is in a range that makes sense for this
2650b57cec5SDimitry Andric     // extension.
2660b57cec5SDimitry Andric     return isImmSExti64i8Value(CE->getValue());
2670b57cec5SDimitry Andric   }
2680b57cec5SDimitry Andric   bool isImmSExti64i32() const {
2690b57cec5SDimitry Andric     if (!isImm())
2700b57cec5SDimitry Andric       return false;
2710b57cec5SDimitry Andric 
2720b57cec5SDimitry Andric     // If this isn't a constant expr, just assume it fits and let relaxation
2730b57cec5SDimitry Andric     // handle it.
2740b57cec5SDimitry Andric     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2750b57cec5SDimitry Andric     if (!CE)
2760b57cec5SDimitry Andric       return true;
2770b57cec5SDimitry Andric 
2780b57cec5SDimitry Andric     // Otherwise, check the value is in a range that makes sense for this
2790b57cec5SDimitry Andric     // extension.
2800b57cec5SDimitry Andric     return isImmSExti64i32Value(CE->getValue());
2810b57cec5SDimitry Andric   }
2820b57cec5SDimitry Andric 
2838bcb0991SDimitry Andric   bool isImmUnsignedi4() const {
2848bcb0991SDimitry Andric     if (!isImm()) return false;
2858bcb0991SDimitry Andric     // If this isn't a constant expr, reject it. The immediate byte is shared
2868bcb0991SDimitry Andric     // with a register encoding. We can't have it affected by a relocation.
2878bcb0991SDimitry Andric     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2888bcb0991SDimitry Andric     if (!CE) return false;
2898bcb0991SDimitry Andric     return isImmUnsignedi4Value(CE->getValue());
2908bcb0991SDimitry Andric   }
2918bcb0991SDimitry Andric 
2920b57cec5SDimitry Andric   bool isImmUnsignedi8() const {
2930b57cec5SDimitry Andric     if (!isImm()) return false;
2940b57cec5SDimitry Andric     // If this isn't a constant expr, just assume it fits and let relaxation
2950b57cec5SDimitry Andric     // handle it.
2960b57cec5SDimitry Andric     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2970b57cec5SDimitry Andric     if (!CE) return true;
2980b57cec5SDimitry Andric     return isImmUnsignedi8Value(CE->getValue());
2990b57cec5SDimitry Andric   }
3000b57cec5SDimitry Andric 
301480093f4SDimitry Andric   bool isOffsetOfLocal() const override { return isImm() && Imm.LocalRef; }
3020b57cec5SDimitry Andric 
303480093f4SDimitry Andric   bool needAddressOf() const override { return AddressOf; }
3040b57cec5SDimitry Andric 
3050b57cec5SDimitry Andric   bool isMem() const override { return Kind == Memory; }
3060b57cec5SDimitry Andric   bool isMemUnsized() const {
3070b57cec5SDimitry Andric     return Kind == Memory && Mem.Size == 0;
3080b57cec5SDimitry Andric   }
3090b57cec5SDimitry Andric   bool isMem8() const {
3100b57cec5SDimitry Andric     return Kind == Memory && (!Mem.Size || Mem.Size == 8);
3110b57cec5SDimitry Andric   }
3120b57cec5SDimitry Andric   bool isMem16() const {
3130b57cec5SDimitry Andric     return Kind == Memory && (!Mem.Size || Mem.Size == 16);
3140b57cec5SDimitry Andric   }
3150b57cec5SDimitry Andric   bool isMem32() const {
3160b57cec5SDimitry Andric     return Kind == Memory && (!Mem.Size || Mem.Size == 32);
3170b57cec5SDimitry Andric   }
3180b57cec5SDimitry Andric   bool isMem64() const {
3190b57cec5SDimitry Andric     return Kind == Memory && (!Mem.Size || Mem.Size == 64);
3200b57cec5SDimitry Andric   }
3210b57cec5SDimitry Andric   bool isMem80() const {
3220b57cec5SDimitry Andric     return Kind == Memory && (!Mem.Size || Mem.Size == 80);
3230b57cec5SDimitry Andric   }
3240b57cec5SDimitry Andric   bool isMem128() const {
3250b57cec5SDimitry Andric     return Kind == Memory && (!Mem.Size || Mem.Size == 128);
3260b57cec5SDimitry Andric   }
3270b57cec5SDimitry Andric   bool isMem256() const {
3280b57cec5SDimitry Andric     return Kind == Memory && (!Mem.Size || Mem.Size == 256);
3290b57cec5SDimitry Andric   }
3300b57cec5SDimitry Andric   bool isMem512() const {
3310b57cec5SDimitry Andric     return Kind == Memory && (!Mem.Size || Mem.Size == 512);
3320b57cec5SDimitry Andric   }
3335ffd83dbSDimitry Andric 
3345ffd83dbSDimitry Andric   bool isSibMem() const {
3355ffd83dbSDimitry Andric     return isMem() && Mem.BaseReg != X86::RIP && Mem.BaseReg != X86::EIP;
3365ffd83dbSDimitry Andric   }
3375ffd83dbSDimitry Andric 
3380b57cec5SDimitry Andric   bool isMemIndexReg(unsigned LowR, unsigned HighR) const {
3390b57cec5SDimitry Andric     assert(Kind == Memory && "Invalid access!");
3400b57cec5SDimitry Andric     return Mem.IndexReg >= LowR && Mem.IndexReg <= HighR;
3410b57cec5SDimitry Andric   }
3420b57cec5SDimitry Andric 
3430b57cec5SDimitry Andric   bool isMem64_RC128() const {
3440b57cec5SDimitry Andric     return isMem64() && isMemIndexReg(X86::XMM0, X86::XMM15);
3450b57cec5SDimitry Andric   }
3460b57cec5SDimitry Andric   bool isMem128_RC128() const {
3470b57cec5SDimitry Andric     return isMem128() && isMemIndexReg(X86::XMM0, X86::XMM15);
3480b57cec5SDimitry Andric   }
3490b57cec5SDimitry Andric   bool isMem128_RC256() const {
3500b57cec5SDimitry Andric     return isMem128() && isMemIndexReg(X86::YMM0, X86::YMM15);
3510b57cec5SDimitry Andric   }
3520b57cec5SDimitry Andric   bool isMem256_RC128() const {
3530b57cec5SDimitry Andric     return isMem256() && isMemIndexReg(X86::XMM0, X86::XMM15);
3540b57cec5SDimitry Andric   }
3550b57cec5SDimitry Andric   bool isMem256_RC256() const {
3560b57cec5SDimitry Andric     return isMem256() && isMemIndexReg(X86::YMM0, X86::YMM15);
3570b57cec5SDimitry Andric   }
3580b57cec5SDimitry Andric 
3590b57cec5SDimitry Andric   bool isMem64_RC128X() const {
3605f757f3fSDimitry Andric     return isMem64() && X86II::isXMMReg(Mem.IndexReg);
3610b57cec5SDimitry Andric   }
3620b57cec5SDimitry Andric   bool isMem128_RC128X() const {
3635f757f3fSDimitry Andric     return isMem128() && X86II::isXMMReg(Mem.IndexReg);
3640b57cec5SDimitry Andric   }
3650b57cec5SDimitry Andric   bool isMem128_RC256X() const {
3665f757f3fSDimitry Andric     return isMem128() && X86II::isYMMReg(Mem.IndexReg);
3670b57cec5SDimitry Andric   }
3680b57cec5SDimitry Andric   bool isMem256_RC128X() const {
3695f757f3fSDimitry Andric     return isMem256() && X86II::isXMMReg(Mem.IndexReg);
3700b57cec5SDimitry Andric   }
3710b57cec5SDimitry Andric   bool isMem256_RC256X() const {
3725f757f3fSDimitry Andric     return isMem256() && X86II::isYMMReg(Mem.IndexReg);
3730b57cec5SDimitry Andric   }
3740b57cec5SDimitry Andric   bool isMem256_RC512() const {
3755f757f3fSDimitry Andric     return isMem256() && X86II::isZMMReg(Mem.IndexReg);
3760b57cec5SDimitry Andric   }
3770b57cec5SDimitry Andric   bool isMem512_RC256X() const {
3785f757f3fSDimitry Andric     return isMem512() && X86II::isYMMReg(Mem.IndexReg);
3790b57cec5SDimitry Andric   }
3800b57cec5SDimitry Andric   bool isMem512_RC512() const {
3815f757f3fSDimitry Andric     return isMem512() && X86II::isZMMReg(Mem.IndexReg);
3820b57cec5SDimitry Andric   }
38306c3fb27SDimitry Andric   bool isMem512_GR16() const {
38406c3fb27SDimitry Andric     if (!isMem512())
38506c3fb27SDimitry Andric       return false;
38606c3fb27SDimitry Andric     if (getMemBaseReg() &&
38706c3fb27SDimitry Andric         !X86MCRegisterClasses[X86::GR16RegClassID].contains(getMemBaseReg()))
38806c3fb27SDimitry Andric       return false;
38906c3fb27SDimitry Andric     return true;
39006c3fb27SDimitry Andric   }
39106c3fb27SDimitry Andric   bool isMem512_GR32() const {
39206c3fb27SDimitry Andric     if (!isMem512())
39306c3fb27SDimitry Andric       return false;
39406c3fb27SDimitry Andric     if (getMemBaseReg() &&
39506c3fb27SDimitry Andric         !X86MCRegisterClasses[X86::GR32RegClassID].contains(getMemBaseReg()) &&
39606c3fb27SDimitry Andric         getMemBaseReg() != X86::EIP)
39706c3fb27SDimitry Andric       return false;
39806c3fb27SDimitry Andric     if (getMemIndexReg() &&
39906c3fb27SDimitry Andric         !X86MCRegisterClasses[X86::GR32RegClassID].contains(getMemIndexReg()) &&
40006c3fb27SDimitry Andric         getMemIndexReg() != X86::EIZ)
40106c3fb27SDimitry Andric       return false;
40206c3fb27SDimitry Andric     return true;
40306c3fb27SDimitry Andric   }
40406c3fb27SDimitry Andric   bool isMem512_GR64() const {
40506c3fb27SDimitry Andric     if (!isMem512())
40606c3fb27SDimitry Andric       return false;
40706c3fb27SDimitry Andric     if (getMemBaseReg() &&
40806c3fb27SDimitry Andric         !X86MCRegisterClasses[X86::GR64RegClassID].contains(getMemBaseReg()) &&
40906c3fb27SDimitry Andric         getMemBaseReg() != X86::RIP)
41006c3fb27SDimitry Andric       return false;
41106c3fb27SDimitry Andric     if (getMemIndexReg() &&
41206c3fb27SDimitry Andric         !X86MCRegisterClasses[X86::GR64RegClassID].contains(getMemIndexReg()) &&
41306c3fb27SDimitry Andric         getMemIndexReg() != X86::RIZ)
41406c3fb27SDimitry Andric       return false;
41506c3fb27SDimitry Andric     return true;
41606c3fb27SDimitry Andric   }
4170b57cec5SDimitry Andric 
4180b57cec5SDimitry Andric   bool isAbsMem() const {
4190b57cec5SDimitry Andric     return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
42081ad6265SDimitry Andric            !getMemIndexReg() && getMemScale() == 1 && isMaybeDirectBranchDest();
4210b57cec5SDimitry Andric   }
42281ad6265SDimitry Andric 
4230b57cec5SDimitry Andric   bool isAVX512RC() const{
4240b57cec5SDimitry Andric       return isImm();
4250b57cec5SDimitry Andric   }
4260b57cec5SDimitry Andric 
4270b57cec5SDimitry Andric   bool isAbsMem16() const {
4280b57cec5SDimitry Andric     return isAbsMem() && Mem.ModeSize == 16;
4290b57cec5SDimitry Andric   }
4300b57cec5SDimitry Andric 
43181ad6265SDimitry Andric   bool isMemUseUpRegs() const override { return UseUpRegs; }
43281ad6265SDimitry Andric 
4330b57cec5SDimitry Andric   bool isSrcIdx() const {
4340b57cec5SDimitry Andric     return !getMemIndexReg() && getMemScale() == 1 &&
4350b57cec5SDimitry Andric       (getMemBaseReg() == X86::RSI || getMemBaseReg() == X86::ESI ||
4360b57cec5SDimitry Andric        getMemBaseReg() == X86::SI) && isa<MCConstantExpr>(getMemDisp()) &&
4370b57cec5SDimitry Andric       cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
4380b57cec5SDimitry Andric   }
4390b57cec5SDimitry Andric   bool isSrcIdx8() const {
4400b57cec5SDimitry Andric     return isMem8() && isSrcIdx();
4410b57cec5SDimitry Andric   }
4420b57cec5SDimitry Andric   bool isSrcIdx16() const {
4430b57cec5SDimitry Andric     return isMem16() && isSrcIdx();
4440b57cec5SDimitry Andric   }
4450b57cec5SDimitry Andric   bool isSrcIdx32() const {
4460b57cec5SDimitry Andric     return isMem32() && isSrcIdx();
4470b57cec5SDimitry Andric   }
4480b57cec5SDimitry Andric   bool isSrcIdx64() const {
4490b57cec5SDimitry Andric     return isMem64() && isSrcIdx();
4500b57cec5SDimitry Andric   }
4510b57cec5SDimitry Andric 
4520b57cec5SDimitry Andric   bool isDstIdx() const {
4530b57cec5SDimitry Andric     return !getMemIndexReg() && getMemScale() == 1 &&
4540b57cec5SDimitry Andric       (getMemSegReg() == 0 || getMemSegReg() == X86::ES) &&
4550b57cec5SDimitry Andric       (getMemBaseReg() == X86::RDI || getMemBaseReg() == X86::EDI ||
4560b57cec5SDimitry Andric        getMemBaseReg() == X86::DI) && isa<MCConstantExpr>(getMemDisp()) &&
4570b57cec5SDimitry Andric       cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
4580b57cec5SDimitry Andric   }
4590b57cec5SDimitry Andric   bool isDstIdx8() const {
4600b57cec5SDimitry Andric     return isMem8() && isDstIdx();
4610b57cec5SDimitry Andric   }
4620b57cec5SDimitry Andric   bool isDstIdx16() const {
4630b57cec5SDimitry Andric     return isMem16() && isDstIdx();
4640b57cec5SDimitry Andric   }
4650b57cec5SDimitry Andric   bool isDstIdx32() const {
4660b57cec5SDimitry Andric     return isMem32() && isDstIdx();
4670b57cec5SDimitry Andric   }
4680b57cec5SDimitry Andric   bool isDstIdx64() const {
4690b57cec5SDimitry Andric     return isMem64() && isDstIdx();
4700b57cec5SDimitry Andric   }
4710b57cec5SDimitry Andric 
4720b57cec5SDimitry Andric   bool isMemOffs() const {
4730b57cec5SDimitry Andric     return Kind == Memory && !getMemBaseReg() && !getMemIndexReg() &&
4740b57cec5SDimitry Andric       getMemScale() == 1;
4750b57cec5SDimitry Andric   }
4760b57cec5SDimitry Andric 
4770b57cec5SDimitry Andric   bool isMemOffs16_8() const {
4780b57cec5SDimitry Andric     return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 8);
4790b57cec5SDimitry Andric   }
4800b57cec5SDimitry Andric   bool isMemOffs16_16() const {
4810b57cec5SDimitry Andric     return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 16);
4820b57cec5SDimitry Andric   }
4830b57cec5SDimitry Andric   bool isMemOffs16_32() const {
4840b57cec5SDimitry Andric     return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 32);
4850b57cec5SDimitry Andric   }
4860b57cec5SDimitry Andric   bool isMemOffs32_8() const {
4870b57cec5SDimitry Andric     return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 8);
4880b57cec5SDimitry Andric   }
4890b57cec5SDimitry Andric   bool isMemOffs32_16() const {
4900b57cec5SDimitry Andric     return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 16);
4910b57cec5SDimitry Andric   }
4920b57cec5SDimitry Andric   bool isMemOffs32_32() const {
4930b57cec5SDimitry Andric     return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 32);
4940b57cec5SDimitry Andric   }
4950b57cec5SDimitry Andric   bool isMemOffs32_64() const {
4960b57cec5SDimitry Andric     return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 64);
4970b57cec5SDimitry Andric   }
4980b57cec5SDimitry Andric   bool isMemOffs64_8() const {
4990b57cec5SDimitry Andric     return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 8);
5000b57cec5SDimitry Andric   }
5010b57cec5SDimitry Andric   bool isMemOffs64_16() const {
5020b57cec5SDimitry Andric     return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 16);
5030b57cec5SDimitry Andric   }
5040b57cec5SDimitry Andric   bool isMemOffs64_32() const {
5050b57cec5SDimitry Andric     return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 32);
5060b57cec5SDimitry Andric   }
5070b57cec5SDimitry Andric   bool isMemOffs64_64() const {
5080b57cec5SDimitry Andric     return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 64);
5090b57cec5SDimitry Andric   }
5100b57cec5SDimitry Andric 
5110b57cec5SDimitry Andric   bool isPrefix() const { return Kind == Prefix; }
5120b57cec5SDimitry Andric   bool isReg() const override { return Kind == Register; }
5130b57cec5SDimitry Andric   bool isDXReg() const { return Kind == DXRegister; }
5140b57cec5SDimitry Andric 
5150b57cec5SDimitry Andric   bool isGR32orGR64() const {
5160b57cec5SDimitry Andric     return Kind == Register &&
5170b57cec5SDimitry Andric       (X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||
5180b57cec5SDimitry Andric        X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
5190b57cec5SDimitry Andric   }
5200b57cec5SDimitry Andric 
521590d96feSDimitry Andric   bool isGR16orGR32orGR64() const {
522590d96feSDimitry Andric     return Kind == Register &&
523590d96feSDimitry Andric       (X86MCRegisterClasses[X86::GR16RegClassID].contains(getReg()) ||
524590d96feSDimitry Andric        X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||
525590d96feSDimitry Andric        X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
526590d96feSDimitry Andric   }
527590d96feSDimitry Andric 
5285ffd83dbSDimitry Andric   bool isVectorReg() const {
5295ffd83dbSDimitry Andric     return Kind == Register &&
5305ffd83dbSDimitry Andric            (X86MCRegisterClasses[X86::VR64RegClassID].contains(getReg()) ||
5315ffd83dbSDimitry Andric             X86MCRegisterClasses[X86::VR128XRegClassID].contains(getReg()) ||
5325ffd83dbSDimitry Andric             X86MCRegisterClasses[X86::VR256XRegClassID].contains(getReg()) ||
5335ffd83dbSDimitry Andric             X86MCRegisterClasses[X86::VR512RegClassID].contains(getReg()));
5345ffd83dbSDimitry Andric   }
5355ffd83dbSDimitry Andric 
5360b57cec5SDimitry Andric   bool isVK1Pair() const {
5370b57cec5SDimitry Andric     return Kind == Register &&
5380b57cec5SDimitry Andric       X86MCRegisterClasses[X86::VK1RegClassID].contains(getReg());
5390b57cec5SDimitry Andric   }
5400b57cec5SDimitry Andric 
5410b57cec5SDimitry Andric   bool isVK2Pair() const {
5420b57cec5SDimitry Andric     return Kind == Register &&
5430b57cec5SDimitry Andric       X86MCRegisterClasses[X86::VK2RegClassID].contains(getReg());
5440b57cec5SDimitry Andric   }
5450b57cec5SDimitry Andric 
5460b57cec5SDimitry Andric   bool isVK4Pair() const {
5470b57cec5SDimitry Andric     return Kind == Register &&
5480b57cec5SDimitry Andric       X86MCRegisterClasses[X86::VK4RegClassID].contains(getReg());
5490b57cec5SDimitry Andric   }
5500b57cec5SDimitry Andric 
5510b57cec5SDimitry Andric   bool isVK8Pair() const {
5520b57cec5SDimitry Andric     return Kind == Register &&
5530b57cec5SDimitry Andric       X86MCRegisterClasses[X86::VK8RegClassID].contains(getReg());
5540b57cec5SDimitry Andric   }
5550b57cec5SDimitry Andric 
5560b57cec5SDimitry Andric   bool isVK16Pair() const {
5570b57cec5SDimitry Andric     return Kind == Register &&
5580b57cec5SDimitry Andric       X86MCRegisterClasses[X86::VK16RegClassID].contains(getReg());
5590b57cec5SDimitry Andric   }
5600b57cec5SDimitry Andric 
5610b57cec5SDimitry Andric   void addExpr(MCInst &Inst, const MCExpr *Expr) const {
5620b57cec5SDimitry Andric     // Add as immediates when possible.
5630b57cec5SDimitry Andric     if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
5640b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createImm(CE->getValue()));
5650b57cec5SDimitry Andric     else
5660b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createExpr(Expr));
5670b57cec5SDimitry Andric   }
5680b57cec5SDimitry Andric 
5690b57cec5SDimitry Andric   void addRegOperands(MCInst &Inst, unsigned N) const {
5700b57cec5SDimitry Andric     assert(N == 1 && "Invalid number of operands!");
5710b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(getReg()));
5720b57cec5SDimitry Andric   }
5730b57cec5SDimitry Andric 
5740b57cec5SDimitry Andric   void addGR32orGR64Operands(MCInst &Inst, unsigned N) const {
5750b57cec5SDimitry Andric     assert(N == 1 && "Invalid number of operands!");
5768bcb0991SDimitry Andric     MCRegister RegNo = getReg();
5770b57cec5SDimitry Andric     if (X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
5780b57cec5SDimitry Andric       RegNo = getX86SubSuperRegister(RegNo, 32);
5790b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(RegNo));
5800b57cec5SDimitry Andric   }
5810b57cec5SDimitry Andric 
582590d96feSDimitry Andric   void addGR16orGR32orGR64Operands(MCInst &Inst, unsigned N) const {
583590d96feSDimitry Andric     assert(N == 1 && "Invalid number of operands!");
584590d96feSDimitry Andric     MCRegister RegNo = getReg();
585590d96feSDimitry Andric     if (X86MCRegisterClasses[X86::GR32RegClassID].contains(RegNo) ||
586590d96feSDimitry Andric         X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
587590d96feSDimitry Andric       RegNo = getX86SubSuperRegister(RegNo, 16);
588590d96feSDimitry Andric     Inst.addOperand(MCOperand::createReg(RegNo));
589590d96feSDimitry Andric   }
590590d96feSDimitry Andric 
5910b57cec5SDimitry Andric   void addAVX512RCOperands(MCInst &Inst, unsigned N) const {
5920b57cec5SDimitry Andric     assert(N == 1 && "Invalid number of operands!");
5930b57cec5SDimitry Andric     addExpr(Inst, getImm());
5940b57cec5SDimitry Andric   }
5950b57cec5SDimitry Andric 
5960b57cec5SDimitry Andric   void addImmOperands(MCInst &Inst, unsigned N) const {
5970b57cec5SDimitry Andric     assert(N == 1 && "Invalid number of operands!");
5980b57cec5SDimitry Andric     addExpr(Inst, getImm());
5990b57cec5SDimitry Andric   }
6000b57cec5SDimitry Andric 
6010b57cec5SDimitry Andric   void addMaskPairOperands(MCInst &Inst, unsigned N) const {
6020b57cec5SDimitry Andric     assert(N == 1 && "Invalid number of operands!");
6030b57cec5SDimitry Andric     unsigned Reg = getReg();
6040b57cec5SDimitry Andric     switch (Reg) {
6050b57cec5SDimitry Andric     case X86::K0:
6060b57cec5SDimitry Andric     case X86::K1:
6070b57cec5SDimitry Andric       Reg = X86::K0_K1;
6080b57cec5SDimitry Andric       break;
6090b57cec5SDimitry Andric     case X86::K2:
6100b57cec5SDimitry Andric     case X86::K3:
6110b57cec5SDimitry Andric       Reg = X86::K2_K3;
6120b57cec5SDimitry Andric       break;
6130b57cec5SDimitry Andric     case X86::K4:
6140b57cec5SDimitry Andric     case X86::K5:
6150b57cec5SDimitry Andric       Reg = X86::K4_K5;
6160b57cec5SDimitry Andric       break;
6170b57cec5SDimitry Andric     case X86::K6:
6180b57cec5SDimitry Andric     case X86::K7:
6190b57cec5SDimitry Andric       Reg = X86::K6_K7;
6200b57cec5SDimitry Andric       break;
6210b57cec5SDimitry Andric     }
6220b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Reg));
6230b57cec5SDimitry Andric   }
6240b57cec5SDimitry Andric 
6250b57cec5SDimitry Andric   void addMemOperands(MCInst &Inst, unsigned N) const {
6260b57cec5SDimitry Andric     assert((N == 5) && "Invalid number of operands!");
6275ffd83dbSDimitry Andric     if (getMemBaseReg())
6280b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
6295ffd83dbSDimitry Andric     else
6305ffd83dbSDimitry Andric       Inst.addOperand(MCOperand::createReg(getMemDefaultBaseReg()));
6310b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(getMemScale()));
6320b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(getMemIndexReg()));
6330b57cec5SDimitry Andric     addExpr(Inst, getMemDisp());
6340b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(getMemSegReg()));
6350b57cec5SDimitry Andric   }
6360b57cec5SDimitry Andric 
6370b57cec5SDimitry Andric   void addAbsMemOperands(MCInst &Inst, unsigned N) const {
6380b57cec5SDimitry Andric     assert((N == 1) && "Invalid number of operands!");
6390b57cec5SDimitry Andric     // Add as immediates when possible.
6400b57cec5SDimitry Andric     if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
6410b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createImm(CE->getValue()));
6420b57cec5SDimitry Andric     else
6430b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createExpr(getMemDisp()));
6440b57cec5SDimitry Andric   }
6450b57cec5SDimitry Andric 
6460b57cec5SDimitry Andric   void addSrcIdxOperands(MCInst &Inst, unsigned N) const {
6470b57cec5SDimitry Andric     assert((N == 2) && "Invalid number of operands!");
6480b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
6490b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(getMemSegReg()));
6500b57cec5SDimitry Andric   }
6510b57cec5SDimitry Andric 
6520b57cec5SDimitry Andric   void addDstIdxOperands(MCInst &Inst, unsigned N) const {
6530b57cec5SDimitry Andric     assert((N == 1) && "Invalid number of operands!");
6540b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
6550b57cec5SDimitry Andric   }
6560b57cec5SDimitry Andric 
6570b57cec5SDimitry Andric   void addMemOffsOperands(MCInst &Inst, unsigned N) const {
6580b57cec5SDimitry Andric     assert((N == 2) && "Invalid number of operands!");
6590b57cec5SDimitry Andric     // Add as immediates when possible.
6600b57cec5SDimitry Andric     if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
6610b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createImm(CE->getValue()));
6620b57cec5SDimitry Andric     else
6630b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createExpr(getMemDisp()));
6640b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(getMemSegReg()));
6650b57cec5SDimitry Andric   }
6660b57cec5SDimitry Andric 
6670b57cec5SDimitry Andric   static std::unique_ptr<X86Operand> CreateToken(StringRef Str, SMLoc Loc) {
6680b57cec5SDimitry Andric     SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size());
6698bcb0991SDimitry Andric     auto Res = std::make_unique<X86Operand>(Token, Loc, EndLoc);
6700b57cec5SDimitry Andric     Res->Tok.Data = Str.data();
6710b57cec5SDimitry Andric     Res->Tok.Length = Str.size();
6720b57cec5SDimitry Andric     return Res;
6730b57cec5SDimitry Andric   }
6740b57cec5SDimitry Andric 
6750b57cec5SDimitry Andric   static std::unique_ptr<X86Operand>
6760b57cec5SDimitry Andric   CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc,
6770b57cec5SDimitry Andric             bool AddressOf = false, SMLoc OffsetOfLoc = SMLoc(),
6780b57cec5SDimitry Andric             StringRef SymName = StringRef(), void *OpDecl = nullptr) {
6798bcb0991SDimitry Andric     auto Res = std::make_unique<X86Operand>(Register, StartLoc, EndLoc);
6800b57cec5SDimitry Andric     Res->Reg.RegNo = RegNo;
6810b57cec5SDimitry Andric     Res->AddressOf = AddressOf;
6820b57cec5SDimitry Andric     Res->OffsetOfLoc = OffsetOfLoc;
6830b57cec5SDimitry Andric     Res->SymName = SymName;
6840b57cec5SDimitry Andric     Res->OpDecl = OpDecl;
6850b57cec5SDimitry Andric     return Res;
6860b57cec5SDimitry Andric   }
6870b57cec5SDimitry Andric 
6880b57cec5SDimitry Andric   static std::unique_ptr<X86Operand>
6890b57cec5SDimitry Andric   CreateDXReg(SMLoc StartLoc, SMLoc EndLoc) {
6908bcb0991SDimitry Andric     return std::make_unique<X86Operand>(DXRegister, StartLoc, EndLoc);
6910b57cec5SDimitry Andric   }
6920b57cec5SDimitry Andric 
6930b57cec5SDimitry Andric   static std::unique_ptr<X86Operand>
6940b57cec5SDimitry Andric   CreatePrefix(unsigned Prefixes, SMLoc StartLoc, SMLoc EndLoc) {
6958bcb0991SDimitry Andric     auto Res = std::make_unique<X86Operand>(Prefix, StartLoc, EndLoc);
6960b57cec5SDimitry Andric     Res->Pref.Prefixes = Prefixes;
6970b57cec5SDimitry Andric     return Res;
6980b57cec5SDimitry Andric   }
6990b57cec5SDimitry Andric 
7000b57cec5SDimitry Andric   static std::unique_ptr<X86Operand> CreateImm(const MCExpr *Val,
701480093f4SDimitry Andric                                                SMLoc StartLoc, SMLoc EndLoc,
702480093f4SDimitry Andric                                                StringRef SymName = StringRef(),
703480093f4SDimitry Andric                                                void *OpDecl = nullptr,
704480093f4SDimitry Andric                                                bool GlobalRef = true) {
7058bcb0991SDimitry Andric     auto Res = std::make_unique<X86Operand>(Immediate, StartLoc, EndLoc);
7060b57cec5SDimitry Andric     Res->Imm.Val      = Val;
707480093f4SDimitry Andric     Res->Imm.LocalRef = !GlobalRef;
708480093f4SDimitry Andric     Res->SymName      = SymName;
709480093f4SDimitry Andric     Res->OpDecl       = OpDecl;
710480093f4SDimitry Andric     Res->AddressOf    = true;
7110b57cec5SDimitry Andric     return Res;
7120b57cec5SDimitry Andric   }
7130b57cec5SDimitry Andric 
7140b57cec5SDimitry Andric   /// Create an absolute memory operand.
7150b57cec5SDimitry Andric   static std::unique_ptr<X86Operand>
7160b57cec5SDimitry Andric   CreateMem(unsigned ModeSize, const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc,
7170b57cec5SDimitry Andric             unsigned Size = 0, StringRef SymName = StringRef(),
71881ad6265SDimitry Andric             void *OpDecl = nullptr, unsigned FrontendSize = 0,
71981ad6265SDimitry Andric             bool UseUpRegs = false, bool MaybeDirectBranchDest = true) {
7208bcb0991SDimitry Andric     auto Res = std::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
7210b57cec5SDimitry Andric     Res->Mem.SegReg   = 0;
7220b57cec5SDimitry Andric     Res->Mem.Disp     = Disp;
7230b57cec5SDimitry Andric     Res->Mem.BaseReg  = 0;
7245ffd83dbSDimitry Andric     Res->Mem.DefaultBaseReg = 0;
7250b57cec5SDimitry Andric     Res->Mem.IndexReg = 0;
7260b57cec5SDimitry Andric     Res->Mem.Scale    = 1;
7270b57cec5SDimitry Andric     Res->Mem.Size     = Size;
7280b57cec5SDimitry Andric     Res->Mem.ModeSize = ModeSize;
7290b57cec5SDimitry Andric     Res->Mem.FrontendSize = FrontendSize;
73081ad6265SDimitry Andric     Res->Mem.MaybeDirectBranchDest = MaybeDirectBranchDest;
73181ad6265SDimitry Andric     Res->UseUpRegs = UseUpRegs;
7320b57cec5SDimitry Andric     Res->SymName      = SymName;
7330b57cec5SDimitry Andric     Res->OpDecl       = OpDecl;
7340b57cec5SDimitry Andric     Res->AddressOf    = false;
7350b57cec5SDimitry Andric     return Res;
7360b57cec5SDimitry Andric   }
7370b57cec5SDimitry Andric 
7380b57cec5SDimitry Andric   /// Create a generalized memory operand.
7390b57cec5SDimitry Andric   static std::unique_ptr<X86Operand>
7400b57cec5SDimitry Andric   CreateMem(unsigned ModeSize, unsigned SegReg, const MCExpr *Disp,
7410b57cec5SDimitry Andric             unsigned BaseReg, unsigned IndexReg, unsigned Scale, SMLoc StartLoc,
7425ffd83dbSDimitry Andric             SMLoc EndLoc, unsigned Size = 0,
7435ffd83dbSDimitry Andric             unsigned DefaultBaseReg = X86::NoRegister,
7445ffd83dbSDimitry Andric             StringRef SymName = StringRef(), void *OpDecl = nullptr,
74581ad6265SDimitry Andric             unsigned FrontendSize = 0, bool UseUpRegs = false,
74681ad6265SDimitry Andric             bool MaybeDirectBranchDest = true) {
7470b57cec5SDimitry Andric     // We should never just have a displacement, that should be parsed as an
7480b57cec5SDimitry Andric     // absolute memory operand.
7495ffd83dbSDimitry Andric     assert((SegReg || BaseReg || IndexReg || DefaultBaseReg) &&
7505ffd83dbSDimitry Andric            "Invalid memory operand!");
7510b57cec5SDimitry Andric 
7520b57cec5SDimitry Andric     // The scale should always be one of {1,2,4,8}.
7530b57cec5SDimitry Andric     assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
7540b57cec5SDimitry Andric            "Invalid scale!");
7558bcb0991SDimitry Andric     auto Res = std::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
7560b57cec5SDimitry Andric     Res->Mem.SegReg   = SegReg;
7570b57cec5SDimitry Andric     Res->Mem.Disp     = Disp;
7580b57cec5SDimitry Andric     Res->Mem.BaseReg  = BaseReg;
7595ffd83dbSDimitry Andric     Res->Mem.DefaultBaseReg = DefaultBaseReg;
7600b57cec5SDimitry Andric     Res->Mem.IndexReg = IndexReg;
7610b57cec5SDimitry Andric     Res->Mem.Scale    = Scale;
7620b57cec5SDimitry Andric     Res->Mem.Size     = Size;
7630b57cec5SDimitry Andric     Res->Mem.ModeSize = ModeSize;
7640b57cec5SDimitry Andric     Res->Mem.FrontendSize = FrontendSize;
76581ad6265SDimitry Andric     Res->Mem.MaybeDirectBranchDest = MaybeDirectBranchDest;
76681ad6265SDimitry Andric     Res->UseUpRegs = UseUpRegs;
7670b57cec5SDimitry Andric     Res->SymName      = SymName;
7680b57cec5SDimitry Andric     Res->OpDecl       = OpDecl;
7690b57cec5SDimitry Andric     Res->AddressOf    = false;
7700b57cec5SDimitry Andric     return Res;
7710b57cec5SDimitry Andric   }
7720b57cec5SDimitry Andric };
7730b57cec5SDimitry Andric 
7740b57cec5SDimitry Andric } // end namespace llvm
7750b57cec5SDimitry Andric 
7760b57cec5SDimitry Andric #endif // LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H
777