Home | History | Annotate | Line # | Download | only in AsmParser
      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/Support/Casting.h"
     21 #include "llvm/Support/SMLoc.h"
     22 #include <cassert>
     23 #include <memory>
     24 
     25 namespace llvm {
     26 
     27 /// X86Operand - Instances of this class represent a parsed X86 machine
     28 /// instruction.
     29 struct X86Operand final : public MCParsedAsmOperand {
     30   enum KindTy { Token, Register, Immediate, Memory, Prefix, DXRegister } Kind;
     31 
     32   SMLoc StartLoc, EndLoc;
     33   SMLoc OffsetOfLoc;
     34   StringRef SymName;
     35   void *OpDecl;
     36   bool AddressOf;
     37   bool CallOperand;
     38 
     39   struct TokOp {
     40     const char *Data;
     41     unsigned Length;
     42   };
     43 
     44   struct RegOp {
     45     unsigned RegNo;
     46   };
     47 
     48   struct PrefOp {
     49     unsigned Prefixes;
     50   };
     51 
     52   struct ImmOp {
     53     const MCExpr *Val;
     54     bool LocalRef;
     55   };
     56 
     57   struct MemOp {
     58     unsigned SegReg;
     59     const MCExpr *Disp;
     60     unsigned BaseReg;
     61     unsigned DefaultBaseReg;
     62     unsigned IndexReg;
     63     unsigned Scale;
     64     unsigned Size;
     65     unsigned ModeSize;
     66 
     67     /// If the memory operand is unsized and there are multiple instruction
     68     /// matches, prefer the one with this size.
     69     unsigned FrontendSize;
     70   };
     71 
     72   union {
     73     struct TokOp Tok;
     74     struct RegOp Reg;
     75     struct ImmOp Imm;
     76     struct MemOp Mem;
     77     struct PrefOp Pref;
     78   };
     79 
     80   X86Operand(KindTy K, SMLoc Start, SMLoc End)
     81       : Kind(K), StartLoc(Start), EndLoc(End), CallOperand(false) {}
     82 
     83   StringRef getSymName() override { return SymName; }
     84   void *getOpDecl() override { return OpDecl; }
     85 
     86   /// getStartLoc - Get the location of the first token of this operand.
     87   SMLoc getStartLoc() const override { return StartLoc; }
     88 
     89   /// getEndLoc - Get the location of the last token of this operand.
     90   SMLoc getEndLoc() const override { return EndLoc; }
     91 
     92   /// getLocRange - Get the range between the first and last token of this
     93   /// operand.
     94   SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
     95 
     96   /// getOffsetOfLoc - Get the location of the offset operator.
     97   SMLoc getOffsetOfLoc() const override { return OffsetOfLoc; }
     98 
     99   void print(raw_ostream &OS) const override {
    100 
    101     auto PrintImmValue = [&](const MCExpr *Val, const char *VName) {
    102       if (Val->getKind() == MCExpr::Constant) {
    103         if (auto Imm = cast<MCConstantExpr>(Val)->getValue())
    104           OS << VName << Imm;
    105       } else if (Val->getKind() == MCExpr::SymbolRef) {
    106         if (auto *SRE = dyn_cast<MCSymbolRefExpr>(Val)) {
    107           const MCSymbol &Sym = SRE->getSymbol();
    108           if (const char *SymNameStr = Sym.getName().data())
    109             OS << VName << SymNameStr;
    110         }
    111       }
    112     };
    113 
    114     switch (Kind) {
    115     case Token:
    116       OS << Tok.Data;
    117       break;
    118     case Register:
    119       OS << "Reg:" << X86IntelInstPrinter::getRegisterName(Reg.RegNo);
    120       break;
    121     case DXRegister:
    122       OS << "DXReg";
    123       break;
    124     case Immediate:
    125       PrintImmValue(Imm.Val, "Imm:");
    126       break;
    127     case Prefix:
    128       OS << "Prefix:" << Pref.Prefixes;
    129       break;
    130     case Memory:
    131       OS << "Memory: ModeSize=" << Mem.ModeSize;
    132       if (Mem.Size)
    133         OS << ",Size=" << Mem.Size;
    134       if (Mem.BaseReg)
    135         OS << ",BaseReg=" << X86IntelInstPrinter::getRegisterName(Mem.BaseReg);
    136       if (Mem.IndexReg)
    137         OS << ",IndexReg="
    138            << X86IntelInstPrinter::getRegisterName(Mem.IndexReg);
    139       if (Mem.Scale)
    140         OS << ",Scale=" << Mem.Scale;
    141       if (Mem.Disp)
    142         PrintImmValue(Mem.Disp, ",Disp=");
    143       if (Mem.SegReg)
    144         OS << ",SegReg=" << X86IntelInstPrinter::getRegisterName(Mem.SegReg);
    145       break;
    146     }
    147   }
    148 
    149   StringRef getToken() const {
    150     assert(Kind == Token && "Invalid access!");
    151     return StringRef(Tok.Data, Tok.Length);
    152   }
    153   void setTokenValue(StringRef Value) {
    154     assert(Kind == Token && "Invalid access!");
    155     Tok.Data = Value.data();
    156     Tok.Length = Value.size();
    157   }
    158 
    159   unsigned getReg() const override {
    160     assert(Kind == Register && "Invalid access!");
    161     return Reg.RegNo;
    162   }
    163 
    164   unsigned getPrefix() const {
    165     assert(Kind == Prefix && "Invalid access!");
    166     return Pref.Prefixes;
    167   }
    168 
    169   const MCExpr *getImm() const {
    170     assert(Kind == Immediate && "Invalid access!");
    171     return Imm.Val;
    172   }
    173 
    174   const MCExpr *getMemDisp() const {
    175     assert(Kind == Memory && "Invalid access!");
    176     return Mem.Disp;
    177   }
    178   unsigned getMemSegReg() const {
    179     assert(Kind == Memory && "Invalid access!");
    180     return Mem.SegReg;
    181   }
    182   unsigned getMemBaseReg() const {
    183     assert(Kind == Memory && "Invalid access!");
    184     return Mem.BaseReg;
    185   }
    186   unsigned getMemDefaultBaseReg() const {
    187     assert(Kind == Memory && "Invalid access!");
    188     return Mem.DefaultBaseReg;
    189   }
    190   unsigned getMemIndexReg() const {
    191     assert(Kind == Memory && "Invalid access!");
    192     return Mem.IndexReg;
    193   }
    194   unsigned getMemScale() const {
    195     assert(Kind == Memory && "Invalid access!");
    196     return Mem.Scale;
    197   }
    198   unsigned getMemModeSize() const {
    199     assert(Kind == Memory && "Invalid access!");
    200     return Mem.ModeSize;
    201   }
    202   unsigned getMemFrontendSize() const {
    203     assert(Kind == Memory && "Invalid access!");
    204     return Mem.FrontendSize;
    205   }
    206 
    207   bool isToken() const override {return Kind == Token; }
    208 
    209   bool isImm() const override { return Kind == Immediate; }
    210 
    211   bool isImmSExti16i8() const {
    212     if (!isImm())
    213       return false;
    214 
    215     // If this isn't a constant expr, just assume it fits and let relaxation
    216     // handle it.
    217     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    218     if (!CE)
    219       return true;
    220 
    221     // Otherwise, check the value is in a range that makes sense for this
    222     // extension.
    223     return isImmSExti16i8Value(CE->getValue());
    224   }
    225   bool isImmSExti32i8() 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 isImmSExti32i8Value(CE->getValue());
    238   }
    239   bool isImmSExti64i8() 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 isImmSExti64i8Value(CE->getValue());
    252   }
    253   bool isImmSExti64i32() 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 isImmSExti64i32Value(CE->getValue());
    266   }
    267 
    268   bool isImmUnsignedi4() const {
    269     if (!isImm()) return false;
    270     // If this isn't a constant expr, reject it. The immediate byte is shared
    271     // with a register encoding. We can't have it affected by a relocation.
    272     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    273     if (!CE) return false;
    274     return isImmUnsignedi4Value(CE->getValue());
    275   }
    276 
    277   bool isImmUnsignedi8() const {
    278     if (!isImm()) return false;
    279     // If this isn't a constant expr, just assume it fits and let relaxation
    280     // handle it.
    281     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    282     if (!CE) return true;
    283     return isImmUnsignedi8Value(CE->getValue());
    284   }
    285 
    286   bool isOffsetOfLocal() const override { return isImm() && Imm.LocalRef; }
    287 
    288   bool needAddressOf() const override { return AddressOf; }
    289 
    290   bool isMem() const override { return Kind == Memory; }
    291   bool isMemUnsized() const {
    292     return Kind == Memory && Mem.Size == 0;
    293   }
    294   bool isMem8() const {
    295     return Kind == Memory && (!Mem.Size || Mem.Size == 8);
    296   }
    297   bool isMem16() const {
    298     return Kind == Memory && (!Mem.Size || Mem.Size == 16);
    299   }
    300   bool isMem32() const {
    301     return Kind == Memory && (!Mem.Size || Mem.Size == 32);
    302   }
    303   bool isMem64() const {
    304     return Kind == Memory && (!Mem.Size || Mem.Size == 64);
    305   }
    306   bool isMem80() const {
    307     return Kind == Memory && (!Mem.Size || Mem.Size == 80);
    308   }
    309   bool isMem128() const {
    310     return Kind == Memory && (!Mem.Size || Mem.Size == 128);
    311   }
    312   bool isMem256() const {
    313     return Kind == Memory && (!Mem.Size || Mem.Size == 256);
    314   }
    315   bool isMem512() const {
    316     return Kind == Memory && (!Mem.Size || Mem.Size == 512);
    317   }
    318 
    319   bool isSibMem() const {
    320     return isMem() && Mem.BaseReg != X86::RIP && Mem.BaseReg != X86::EIP;
    321   }
    322 
    323   bool isMemIndexReg(unsigned LowR, unsigned HighR) const {
    324     assert(Kind == Memory && "Invalid access!");
    325     return Mem.IndexReg >= LowR && Mem.IndexReg <= HighR;
    326   }
    327 
    328   bool isMem64_RC128() const {
    329     return isMem64() && isMemIndexReg(X86::XMM0, X86::XMM15);
    330   }
    331   bool isMem128_RC128() const {
    332     return isMem128() && isMemIndexReg(X86::XMM0, X86::XMM15);
    333   }
    334   bool isMem128_RC256() const {
    335     return isMem128() && isMemIndexReg(X86::YMM0, X86::YMM15);
    336   }
    337   bool isMem256_RC128() const {
    338     return isMem256() && isMemIndexReg(X86::XMM0, X86::XMM15);
    339   }
    340   bool isMem256_RC256() const {
    341     return isMem256() && isMemIndexReg(X86::YMM0, X86::YMM15);
    342   }
    343 
    344   bool isMem64_RC128X() const {
    345     return isMem64() && isMemIndexReg(X86::XMM0, X86::XMM31);
    346   }
    347   bool isMem128_RC128X() const {
    348     return isMem128() && isMemIndexReg(X86::XMM0, X86::XMM31);
    349   }
    350   bool isMem128_RC256X() const {
    351     return isMem128() && isMemIndexReg(X86::YMM0, X86::YMM31);
    352   }
    353   bool isMem256_RC128X() const {
    354     return isMem256() && isMemIndexReg(X86::XMM0, X86::XMM31);
    355   }
    356   bool isMem256_RC256X() const {
    357     return isMem256() && isMemIndexReg(X86::YMM0, X86::YMM31);
    358   }
    359   bool isMem256_RC512() const {
    360     return isMem256() && isMemIndexReg(X86::ZMM0, X86::ZMM31);
    361   }
    362   bool isMem512_RC256X() const {
    363     return isMem512() && isMemIndexReg(X86::YMM0, X86::YMM31);
    364   }
    365   bool isMem512_RC512() const {
    366     return isMem512() && isMemIndexReg(X86::ZMM0, X86::ZMM31);
    367   }
    368 
    369   bool isAbsMem() const {
    370     return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
    371       !getMemIndexReg() && getMemScale() == 1;
    372   }
    373   bool isAVX512RC() const{
    374       return isImm();
    375   }
    376 
    377   bool isAbsMem16() const {
    378     return isAbsMem() && Mem.ModeSize == 16;
    379   }
    380 
    381   bool isSrcIdx() const {
    382     return !getMemIndexReg() && getMemScale() == 1 &&
    383       (getMemBaseReg() == X86::RSI || getMemBaseReg() == X86::ESI ||
    384        getMemBaseReg() == X86::SI) && isa<MCConstantExpr>(getMemDisp()) &&
    385       cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
    386   }
    387   bool isSrcIdx8() const {
    388     return isMem8() && isSrcIdx();
    389   }
    390   bool isSrcIdx16() const {
    391     return isMem16() && isSrcIdx();
    392   }
    393   bool isSrcIdx32() const {
    394     return isMem32() && isSrcIdx();
    395   }
    396   bool isSrcIdx64() const {
    397     return isMem64() && isSrcIdx();
    398   }
    399 
    400   bool isDstIdx() const {
    401     return !getMemIndexReg() && getMemScale() == 1 &&
    402       (getMemSegReg() == 0 || getMemSegReg() == X86::ES) &&
    403       (getMemBaseReg() == X86::RDI || getMemBaseReg() == X86::EDI ||
    404        getMemBaseReg() == X86::DI) && isa<MCConstantExpr>(getMemDisp()) &&
    405       cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
    406   }
    407   bool isDstIdx8() const {
    408     return isMem8() && isDstIdx();
    409   }
    410   bool isDstIdx16() const {
    411     return isMem16() && isDstIdx();
    412   }
    413   bool isDstIdx32() const {
    414     return isMem32() && isDstIdx();
    415   }
    416   bool isDstIdx64() const {
    417     return isMem64() && isDstIdx();
    418   }
    419 
    420   bool isMemOffs() const {
    421     return Kind == Memory && !getMemBaseReg() && !getMemIndexReg() &&
    422       getMemScale() == 1;
    423   }
    424 
    425   bool isMemOffs16_8() const {
    426     return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 8);
    427   }
    428   bool isMemOffs16_16() const {
    429     return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 16);
    430   }
    431   bool isMemOffs16_32() const {
    432     return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 32);
    433   }
    434   bool isMemOffs32_8() const {
    435     return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 8);
    436   }
    437   bool isMemOffs32_16() const {
    438     return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 16);
    439   }
    440   bool isMemOffs32_32() const {
    441     return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 32);
    442   }
    443   bool isMemOffs32_64() const {
    444     return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 64);
    445   }
    446   bool isMemOffs64_8() const {
    447     return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 8);
    448   }
    449   bool isMemOffs64_16() const {
    450     return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 16);
    451   }
    452   bool isMemOffs64_32() const {
    453     return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 32);
    454   }
    455   bool isMemOffs64_64() const {
    456     return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 64);
    457   }
    458 
    459   bool isPrefix() const { return Kind == Prefix; }
    460   bool isReg() const override { return Kind == Register; }
    461   bool isDXReg() const { return Kind == DXRegister; }
    462 
    463   bool isGR32orGR64() const {
    464     return Kind == Register &&
    465       (X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||
    466        X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
    467   }
    468 
    469   bool isGR16orGR32orGR64() const {
    470     return Kind == Register &&
    471       (X86MCRegisterClasses[X86::GR16RegClassID].contains(getReg()) ||
    472        X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||
    473        X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
    474   }
    475 
    476   bool isVectorReg() const {
    477     return Kind == Register &&
    478            (X86MCRegisterClasses[X86::VR64RegClassID].contains(getReg()) ||
    479             X86MCRegisterClasses[X86::VR128XRegClassID].contains(getReg()) ||
    480             X86MCRegisterClasses[X86::VR256XRegClassID].contains(getReg()) ||
    481             X86MCRegisterClasses[X86::VR512RegClassID].contains(getReg()));
    482   }
    483 
    484   bool isVK1Pair() const {
    485     return Kind == Register &&
    486       X86MCRegisterClasses[X86::VK1RegClassID].contains(getReg());
    487   }
    488 
    489   bool isVK2Pair() const {
    490     return Kind == Register &&
    491       X86MCRegisterClasses[X86::VK2RegClassID].contains(getReg());
    492   }
    493 
    494   bool isVK4Pair() const {
    495     return Kind == Register &&
    496       X86MCRegisterClasses[X86::VK4RegClassID].contains(getReg());
    497   }
    498 
    499   bool isVK8Pair() const {
    500     return Kind == Register &&
    501       X86MCRegisterClasses[X86::VK8RegClassID].contains(getReg());
    502   }
    503 
    504   bool isVK16Pair() const {
    505     return Kind == Register &&
    506       X86MCRegisterClasses[X86::VK16RegClassID].contains(getReg());
    507   }
    508 
    509   void addExpr(MCInst &Inst, const MCExpr *Expr) const {
    510     // Add as immediates when possible.
    511     if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
    512       Inst.addOperand(MCOperand::createImm(CE->getValue()));
    513     else
    514       Inst.addOperand(MCOperand::createExpr(Expr));
    515   }
    516 
    517   void addRegOperands(MCInst &Inst, unsigned N) const {
    518     assert(N == 1 && "Invalid number of operands!");
    519     Inst.addOperand(MCOperand::createReg(getReg()));
    520   }
    521 
    522   void addGR32orGR64Operands(MCInst &Inst, unsigned N) const {
    523     assert(N == 1 && "Invalid number of operands!");
    524     MCRegister RegNo = getReg();
    525     if (X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
    526       RegNo = getX86SubSuperRegister(RegNo, 32);
    527     Inst.addOperand(MCOperand::createReg(RegNo));
    528   }
    529 
    530   void addGR16orGR32orGR64Operands(MCInst &Inst, unsigned N) const {
    531     assert(N == 1 && "Invalid number of operands!");
    532     MCRegister RegNo = getReg();
    533     if (X86MCRegisterClasses[X86::GR32RegClassID].contains(RegNo) ||
    534         X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
    535       RegNo = getX86SubSuperRegister(RegNo, 16);
    536     Inst.addOperand(MCOperand::createReg(RegNo));
    537   }
    538 
    539   void addAVX512RCOperands(MCInst &Inst, unsigned N) const {
    540     assert(N == 1 && "Invalid number of operands!");
    541     addExpr(Inst, getImm());
    542   }
    543 
    544   void addImmOperands(MCInst &Inst, unsigned N) const {
    545     assert(N == 1 && "Invalid number of operands!");
    546     addExpr(Inst, getImm());
    547   }
    548 
    549   void addMaskPairOperands(MCInst &Inst, unsigned N) const {
    550     assert(N == 1 && "Invalid number of operands!");
    551     unsigned Reg = getReg();
    552     switch (Reg) {
    553     case X86::K0:
    554     case X86::K1:
    555       Reg = X86::K0_K1;
    556       break;
    557     case X86::K2:
    558     case X86::K3:
    559       Reg = X86::K2_K3;
    560       break;
    561     case X86::K4:
    562     case X86::K5:
    563       Reg = X86::K4_K5;
    564       break;
    565     case X86::K6:
    566     case X86::K7:
    567       Reg = X86::K6_K7;
    568       break;
    569     }
    570     Inst.addOperand(MCOperand::createReg(Reg));
    571   }
    572 
    573   void addMemOperands(MCInst &Inst, unsigned N) const {
    574     assert((N == 5) && "Invalid number of operands!");
    575     if (getMemBaseReg())
    576       Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
    577     else
    578       Inst.addOperand(MCOperand::createReg(getMemDefaultBaseReg()));
    579     Inst.addOperand(MCOperand::createImm(getMemScale()));
    580     Inst.addOperand(MCOperand::createReg(getMemIndexReg()));
    581     addExpr(Inst, getMemDisp());
    582     Inst.addOperand(MCOperand::createReg(getMemSegReg()));
    583   }
    584 
    585   void addAbsMemOperands(MCInst &Inst, unsigned N) const {
    586     assert((N == 1) && "Invalid number of operands!");
    587     // Add as immediates when possible.
    588     if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
    589       Inst.addOperand(MCOperand::createImm(CE->getValue()));
    590     else
    591       Inst.addOperand(MCOperand::createExpr(getMemDisp()));
    592   }
    593 
    594   void addSrcIdxOperands(MCInst &Inst, unsigned N) const {
    595     assert((N == 2) && "Invalid number of operands!");
    596     Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
    597     Inst.addOperand(MCOperand::createReg(getMemSegReg()));
    598   }
    599 
    600   void addDstIdxOperands(MCInst &Inst, unsigned N) const {
    601     assert((N == 1) && "Invalid number of operands!");
    602     Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
    603   }
    604 
    605   void addMemOffsOperands(MCInst &Inst, unsigned N) const {
    606     assert((N == 2) && "Invalid number of operands!");
    607     // Add as immediates when possible.
    608     if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
    609       Inst.addOperand(MCOperand::createImm(CE->getValue()));
    610     else
    611       Inst.addOperand(MCOperand::createExpr(getMemDisp()));
    612     Inst.addOperand(MCOperand::createReg(getMemSegReg()));
    613   }
    614 
    615   static std::unique_ptr<X86Operand> CreateToken(StringRef Str, SMLoc Loc) {
    616     SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size());
    617     auto Res = std::make_unique<X86Operand>(Token, Loc, EndLoc);
    618     Res->Tok.Data = Str.data();
    619     Res->Tok.Length = Str.size();
    620     return Res;
    621   }
    622 
    623   static std::unique_ptr<X86Operand>
    624   CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc,
    625             bool AddressOf = false, SMLoc OffsetOfLoc = SMLoc(),
    626             StringRef SymName = StringRef(), void *OpDecl = nullptr) {
    627     auto Res = std::make_unique<X86Operand>(Register, StartLoc, EndLoc);
    628     Res->Reg.RegNo = RegNo;
    629     Res->AddressOf = AddressOf;
    630     Res->OffsetOfLoc = OffsetOfLoc;
    631     Res->SymName = SymName;
    632     Res->OpDecl = OpDecl;
    633     return Res;
    634   }
    635 
    636   static std::unique_ptr<X86Operand>
    637   CreateDXReg(SMLoc StartLoc, SMLoc EndLoc) {
    638     return std::make_unique<X86Operand>(DXRegister, StartLoc, EndLoc);
    639   }
    640 
    641   static std::unique_ptr<X86Operand>
    642   CreatePrefix(unsigned Prefixes, SMLoc StartLoc, SMLoc EndLoc) {
    643     auto Res = std::make_unique<X86Operand>(Prefix, StartLoc, EndLoc);
    644     Res->Pref.Prefixes = Prefixes;
    645     return Res;
    646   }
    647 
    648   static std::unique_ptr<X86Operand> CreateImm(const MCExpr *Val,
    649                                                SMLoc StartLoc, SMLoc EndLoc,
    650                                                StringRef SymName = StringRef(),
    651                                                void *OpDecl = nullptr,
    652                                                bool GlobalRef = true) {
    653     auto Res = std::make_unique<X86Operand>(Immediate, StartLoc, EndLoc);
    654     Res->Imm.Val      = Val;
    655     Res->Imm.LocalRef = !GlobalRef;
    656     Res->SymName      = SymName;
    657     Res->OpDecl       = OpDecl;
    658     Res->AddressOf    = true;
    659     return Res;
    660   }
    661 
    662   /// Create an absolute memory operand.
    663   static std::unique_ptr<X86Operand>
    664   CreateMem(unsigned ModeSize, const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc,
    665             unsigned Size = 0, StringRef SymName = StringRef(),
    666             void *OpDecl = nullptr, unsigned FrontendSize = 0) {
    667     auto Res = std::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
    668     Res->Mem.SegReg   = 0;
    669     Res->Mem.Disp     = Disp;
    670     Res->Mem.BaseReg  = 0;
    671     Res->Mem.DefaultBaseReg = 0;
    672     Res->Mem.IndexReg = 0;
    673     Res->Mem.Scale    = 1;
    674     Res->Mem.Size     = Size;
    675     Res->Mem.ModeSize = ModeSize;
    676     Res->Mem.FrontendSize = FrontendSize;
    677     Res->SymName      = SymName;
    678     Res->OpDecl       = OpDecl;
    679     Res->AddressOf    = false;
    680     return Res;
    681   }
    682 
    683   /// Create a generalized memory operand.
    684   static std::unique_ptr<X86Operand>
    685   CreateMem(unsigned ModeSize, unsigned SegReg, const MCExpr *Disp,
    686             unsigned BaseReg, unsigned IndexReg, unsigned Scale, SMLoc StartLoc,
    687             SMLoc EndLoc, unsigned Size = 0,
    688             unsigned DefaultBaseReg = X86::NoRegister,
    689             StringRef SymName = StringRef(), void *OpDecl = nullptr,
    690             unsigned FrontendSize = 0) {
    691     // We should never just have a displacement, that should be parsed as an
    692     // absolute memory operand.
    693     assert((SegReg || BaseReg || IndexReg || DefaultBaseReg) &&
    694            "Invalid memory operand!");
    695 
    696     // The scale should always be one of {1,2,4,8}.
    697     assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
    698            "Invalid scale!");
    699     auto Res = std::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
    700     Res->Mem.SegReg   = SegReg;
    701     Res->Mem.Disp     = Disp;
    702     Res->Mem.BaseReg  = BaseReg;
    703     Res->Mem.DefaultBaseReg = DefaultBaseReg;
    704     Res->Mem.IndexReg = IndexReg;
    705     Res->Mem.Scale    = Scale;
    706     Res->Mem.Size     = Size;
    707     Res->Mem.ModeSize = ModeSize;
    708     Res->Mem.FrontendSize = FrontendSize;
    709     Res->SymName      = SymName;
    710     Res->OpDecl       = OpDecl;
    711     Res->AddressOf    = false;
    712     return Res;
    713   }
    714 };
    715 
    716 } // end namespace llvm
    717 
    718 #endif // LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H
    719