Path: blob/main/contrib/llvm-project/llvm/lib/Target/X86/AsmParser/X86Operand.h
35294 views
//===- X86Operand.h - Parsed X86 machine instruction ------------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#ifndef LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H9#define LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H1011#include "MCTargetDesc/X86IntelInstPrinter.h"12#include "MCTargetDesc/X86MCTargetDesc.h"13#include "X86AsmParserCommon.h"14#include "llvm/ADT/STLExtras.h"15#include "llvm/ADT/StringRef.h"16#include "llvm/MC/MCExpr.h"17#include "llvm/MC/MCInst.h"18#include "llvm/MC/MCParser/MCParsedAsmOperand.h"19#include "llvm/MC/MCRegisterInfo.h"20#include "llvm/MC/MCSymbol.h"21#include "llvm/Support/Casting.h"22#include "llvm/Support/SMLoc.h"23#include <cassert>24#include <memory>2526namespace llvm {2728/// X86Operand - Instances of this class represent a parsed X86 machine29/// instruction.30struct X86Operand final : public MCParsedAsmOperand {31enum KindTy { Token, Register, Immediate, Memory, Prefix, DXRegister } Kind;3233SMLoc StartLoc, EndLoc;34SMLoc OffsetOfLoc;35StringRef SymName;36void *OpDecl;37bool AddressOf;3839/// This used for inline asm which may specify base reg and index reg for40/// MemOp. e.g. ARR[eax + ecx*4], so no extra reg can be used for MemOp.41bool UseUpRegs = false;4243struct TokOp {44const char *Data;45unsigned Length;46};4748struct RegOp {49unsigned RegNo;50};5152struct PrefOp {53unsigned Prefixes;54};5556struct ImmOp {57const MCExpr *Val;58bool LocalRef;59};6061struct MemOp {62unsigned SegReg;63const MCExpr *Disp;64unsigned BaseReg;65unsigned DefaultBaseReg;66unsigned IndexReg;67unsigned Scale;68unsigned Size;69unsigned ModeSize;7071/// If the memory operand is unsized and there are multiple instruction72/// matches, prefer the one with this size.73unsigned FrontendSize;7475/// If false, then this operand must be a memory operand for an indirect76/// branch instruction. Otherwise, this operand may belong to either a77/// direct or indirect branch instruction.78bool MaybeDirectBranchDest;79};8081union {82struct TokOp Tok;83struct RegOp Reg;84struct ImmOp Imm;85struct MemOp Mem;86struct PrefOp Pref;87};8889X86Operand(KindTy K, SMLoc Start, SMLoc End)90: Kind(K), StartLoc(Start), EndLoc(End), OpDecl(nullptr),91AddressOf(false) {}9293StringRef getSymName() override { return SymName; }94void *getOpDecl() override { return OpDecl; }9596/// getStartLoc - Get the location of the first token of this operand.97SMLoc getStartLoc() const override { return StartLoc; }9899/// getEndLoc - Get the location of the last token of this operand.100SMLoc getEndLoc() const override { return EndLoc; }101102/// getLocRange - Get the range between the first and last token of this103/// operand.104SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }105106/// getOffsetOfLoc - Get the location of the offset operator.107SMLoc getOffsetOfLoc() const override { return OffsetOfLoc; }108109void print(raw_ostream &OS) const override {110111auto PrintImmValue = [&](const MCExpr *Val, const char *VName) {112if (Val->getKind() == MCExpr::Constant) {113if (auto Imm = cast<MCConstantExpr>(Val)->getValue())114OS << VName << Imm;115} else if (Val->getKind() == MCExpr::SymbolRef) {116if (auto *SRE = dyn_cast<MCSymbolRefExpr>(Val)) {117const MCSymbol &Sym = SRE->getSymbol();118if (const char *SymNameStr = Sym.getName().data())119OS << VName << SymNameStr;120}121}122};123124switch (Kind) {125case Token:126OS << Tok.Data;127break;128case Register:129OS << "Reg:" << X86IntelInstPrinter::getRegisterName(Reg.RegNo);130break;131case DXRegister:132OS << "DXReg";133break;134case Immediate:135PrintImmValue(Imm.Val, "Imm:");136break;137case Prefix:138OS << "Prefix:" << Pref.Prefixes;139break;140case Memory:141OS << "Memory: ModeSize=" << Mem.ModeSize;142if (Mem.Size)143OS << ",Size=" << Mem.Size;144if (Mem.BaseReg)145OS << ",BaseReg=" << X86IntelInstPrinter::getRegisterName(Mem.BaseReg);146if (Mem.IndexReg)147OS << ",IndexReg="148<< X86IntelInstPrinter::getRegisterName(Mem.IndexReg);149if (Mem.Scale)150OS << ",Scale=" << Mem.Scale;151if (Mem.Disp)152PrintImmValue(Mem.Disp, ",Disp=");153if (Mem.SegReg)154OS << ",SegReg=" << X86IntelInstPrinter::getRegisterName(Mem.SegReg);155break;156}157}158159StringRef getToken() const {160assert(Kind == Token && "Invalid access!");161return StringRef(Tok.Data, Tok.Length);162}163void setTokenValue(StringRef Value) {164assert(Kind == Token && "Invalid access!");165Tok.Data = Value.data();166Tok.Length = Value.size();167}168169MCRegister getReg() const override {170assert(Kind == Register && "Invalid access!");171return Reg.RegNo;172}173174unsigned getPrefix() const {175assert(Kind == Prefix && "Invalid access!");176return Pref.Prefixes;177}178179const MCExpr *getImm() const {180assert(Kind == Immediate && "Invalid access!");181return Imm.Val;182}183184const MCExpr *getMemDisp() const {185assert(Kind == Memory && "Invalid access!");186return Mem.Disp;187}188unsigned getMemSegReg() const {189assert(Kind == Memory && "Invalid access!");190return Mem.SegReg;191}192unsigned getMemBaseReg() const {193assert(Kind == Memory && "Invalid access!");194return Mem.BaseReg;195}196unsigned getMemDefaultBaseReg() const {197assert(Kind == Memory && "Invalid access!");198return Mem.DefaultBaseReg;199}200unsigned getMemIndexReg() const {201assert(Kind == Memory && "Invalid access!");202return Mem.IndexReg;203}204unsigned getMemScale() const {205assert(Kind == Memory && "Invalid access!");206return Mem.Scale;207}208unsigned getMemModeSize() const {209assert(Kind == Memory && "Invalid access!");210return Mem.ModeSize;211}212unsigned getMemFrontendSize() const {213assert(Kind == Memory && "Invalid access!");214return Mem.FrontendSize;215}216bool isMaybeDirectBranchDest() const {217assert(Kind == Memory && "Invalid access!");218return Mem.MaybeDirectBranchDest;219}220221bool isToken() const override {return Kind == Token; }222223bool isImm() const override { return Kind == Immediate; }224225bool isImmSExti16i8() const {226if (!isImm())227return false;228229// If this isn't a constant expr, just assume it fits and let relaxation230// handle it.231const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());232if (!CE)233return true;234235// Otherwise, check the value is in a range that makes sense for this236// extension.237return isImmSExti16i8Value(CE->getValue());238}239bool isImmSExti32i8() const {240if (!isImm())241return false;242243// If this isn't a constant expr, just assume it fits and let relaxation244// handle it.245const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());246if (!CE)247return true;248249// Otherwise, check the value is in a range that makes sense for this250// extension.251return isImmSExti32i8Value(CE->getValue());252}253bool isImmSExti64i8() const {254if (!isImm())255return false;256257// If this isn't a constant expr, just assume it fits and let relaxation258// handle it.259const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());260if (!CE)261return true;262263// Otherwise, check the value is in a range that makes sense for this264// extension.265return isImmSExti64i8Value(CE->getValue());266}267bool isImmSExti64i32() const {268if (!isImm())269return false;270271// If this isn't a constant expr, just assume it fits and let relaxation272// handle it.273const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());274if (!CE)275return true;276277// Otherwise, check the value is in a range that makes sense for this278// extension.279return isImmSExti64i32Value(CE->getValue());280}281282bool isImmUnsignedi4() const {283if (!isImm()) return false;284// If this isn't a constant expr, reject it. The immediate byte is shared285// with a register encoding. We can't have it affected by a relocation.286const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());287if (!CE) return false;288return isImmUnsignedi4Value(CE->getValue());289}290291bool isImmUnsignedi8() const {292if (!isImm()) return false;293// If this isn't a constant expr, just assume it fits and let relaxation294// handle it.295const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());296if (!CE) return true;297return isImmUnsignedi8Value(CE->getValue());298}299300bool isOffsetOfLocal() const override { return isImm() && Imm.LocalRef; }301302bool needAddressOf() const override { return AddressOf; }303304bool isMem() const override { return Kind == Memory; }305bool isMemUnsized() const {306return Kind == Memory && Mem.Size == 0;307}308bool isMem8() const {309return Kind == Memory && (!Mem.Size || Mem.Size == 8);310}311bool isMem16() const {312return Kind == Memory && (!Mem.Size || Mem.Size == 16);313}314bool isMem32() const {315return Kind == Memory && (!Mem.Size || Mem.Size == 32);316}317bool isMem64() const {318return Kind == Memory && (!Mem.Size || Mem.Size == 64);319}320bool isMem80() const {321return Kind == Memory && (!Mem.Size || Mem.Size == 80);322}323bool isMem128() const {324return Kind == Memory && (!Mem.Size || Mem.Size == 128);325}326bool isMem256() const {327return Kind == Memory && (!Mem.Size || Mem.Size == 256);328}329bool isMem512() const {330return Kind == Memory && (!Mem.Size || Mem.Size == 512);331}332333bool isSibMem() const {334return isMem() && Mem.BaseReg != X86::RIP && Mem.BaseReg != X86::EIP;335}336337bool isMemIndexReg(unsigned LowR, unsigned HighR) const {338assert(Kind == Memory && "Invalid access!");339return Mem.IndexReg >= LowR && Mem.IndexReg <= HighR;340}341342bool isMem64_RC128() const {343return isMem64() && isMemIndexReg(X86::XMM0, X86::XMM15);344}345bool isMem128_RC128() const {346return isMem128() && isMemIndexReg(X86::XMM0, X86::XMM15);347}348bool isMem128_RC256() const {349return isMem128() && isMemIndexReg(X86::YMM0, X86::YMM15);350}351bool isMem256_RC128() const {352return isMem256() && isMemIndexReg(X86::XMM0, X86::XMM15);353}354bool isMem256_RC256() const {355return isMem256() && isMemIndexReg(X86::YMM0, X86::YMM15);356}357358bool isMem64_RC128X() const {359return isMem64() && X86II::isXMMReg(Mem.IndexReg);360}361bool isMem128_RC128X() const {362return isMem128() && X86II::isXMMReg(Mem.IndexReg);363}364bool isMem128_RC256X() const {365return isMem128() && X86II::isYMMReg(Mem.IndexReg);366}367bool isMem256_RC128X() const {368return isMem256() && X86II::isXMMReg(Mem.IndexReg);369}370bool isMem256_RC256X() const {371return isMem256() && X86II::isYMMReg(Mem.IndexReg);372}373bool isMem256_RC512() const {374return isMem256() && X86II::isZMMReg(Mem.IndexReg);375}376bool isMem512_RC256X() const {377return isMem512() && X86II::isYMMReg(Mem.IndexReg);378}379bool isMem512_RC512() const {380return isMem512() && X86II::isZMMReg(Mem.IndexReg);381}382bool isMem512_GR16() const {383if (!isMem512())384return false;385if (getMemBaseReg() &&386!X86MCRegisterClasses[X86::GR16RegClassID].contains(getMemBaseReg()))387return false;388return true;389}390bool isMem512_GR32() const {391if (!isMem512())392return false;393if (getMemBaseReg() &&394!X86MCRegisterClasses[X86::GR32RegClassID].contains(getMemBaseReg()) &&395getMemBaseReg() != X86::EIP)396return false;397if (getMemIndexReg() &&398!X86MCRegisterClasses[X86::GR32RegClassID].contains(getMemIndexReg()) &&399getMemIndexReg() != X86::EIZ)400return false;401return true;402}403bool isMem512_GR64() const {404if (!isMem512())405return false;406if (getMemBaseReg() &&407!X86MCRegisterClasses[X86::GR64RegClassID].contains(getMemBaseReg()) &&408getMemBaseReg() != X86::RIP)409return false;410if (getMemIndexReg() &&411!X86MCRegisterClasses[X86::GR64RegClassID].contains(getMemIndexReg()) &&412getMemIndexReg() != X86::RIZ)413return false;414return true;415}416417bool isAbsMem() const {418return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&419!getMemIndexReg() && getMemScale() == 1 && isMaybeDirectBranchDest();420}421422bool isAVX512RC() const{423return isImm();424}425426bool isAbsMem16() const {427return isAbsMem() && Mem.ModeSize == 16;428}429430bool isMemUseUpRegs() const override { return UseUpRegs; }431432bool isSrcIdx() const {433return !getMemIndexReg() && getMemScale() == 1 &&434(getMemBaseReg() == X86::RSI || getMemBaseReg() == X86::ESI ||435getMemBaseReg() == X86::SI) && isa<MCConstantExpr>(getMemDisp()) &&436cast<MCConstantExpr>(getMemDisp())->getValue() == 0;437}438bool isSrcIdx8() const {439return isMem8() && isSrcIdx();440}441bool isSrcIdx16() const {442return isMem16() && isSrcIdx();443}444bool isSrcIdx32() const {445return isMem32() && isSrcIdx();446}447bool isSrcIdx64() const {448return isMem64() && isSrcIdx();449}450451bool isDstIdx() const {452return !getMemIndexReg() && getMemScale() == 1 &&453(getMemSegReg() == 0 || getMemSegReg() == X86::ES) &&454(getMemBaseReg() == X86::RDI || getMemBaseReg() == X86::EDI ||455getMemBaseReg() == X86::DI) && isa<MCConstantExpr>(getMemDisp()) &&456cast<MCConstantExpr>(getMemDisp())->getValue() == 0;457}458bool isDstIdx8() const {459return isMem8() && isDstIdx();460}461bool isDstIdx16() const {462return isMem16() && isDstIdx();463}464bool isDstIdx32() const {465return isMem32() && isDstIdx();466}467bool isDstIdx64() const {468return isMem64() && isDstIdx();469}470471bool isMemOffs() const {472return Kind == Memory && !getMemBaseReg() && !getMemIndexReg() &&473getMemScale() == 1;474}475476bool isMemOffs16_8() const {477return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 8);478}479bool isMemOffs16_16() const {480return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 16);481}482bool isMemOffs16_32() const {483return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 32);484}485bool isMemOffs32_8() const {486return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 8);487}488bool isMemOffs32_16() const {489return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 16);490}491bool isMemOffs32_32() const {492return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 32);493}494bool isMemOffs32_64() const {495return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 64);496}497bool isMemOffs64_8() const {498return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 8);499}500bool isMemOffs64_16() const {501return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 16);502}503bool isMemOffs64_32() const {504return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 32);505}506bool isMemOffs64_64() const {507return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 64);508}509510bool isPrefix() const { return Kind == Prefix; }511bool isReg() const override { return Kind == Register; }512bool isDXReg() const { return Kind == DXRegister; }513514bool isGR32orGR64() const {515return Kind == Register &&516(X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||517X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));518}519520bool isGR16orGR32orGR64() const {521return Kind == Register &&522(X86MCRegisterClasses[X86::GR16RegClassID].contains(getReg()) ||523X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||524X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));525}526527bool isVectorReg() const {528return Kind == Register &&529(X86MCRegisterClasses[X86::VR64RegClassID].contains(getReg()) ||530X86MCRegisterClasses[X86::VR128XRegClassID].contains(getReg()) ||531X86MCRegisterClasses[X86::VR256XRegClassID].contains(getReg()) ||532X86MCRegisterClasses[X86::VR512RegClassID].contains(getReg()));533}534535bool isVK1Pair() const {536return Kind == Register &&537X86MCRegisterClasses[X86::VK1RegClassID].contains(getReg());538}539540bool isVK2Pair() const {541return Kind == Register &&542X86MCRegisterClasses[X86::VK2RegClassID].contains(getReg());543}544545bool isVK4Pair() const {546return Kind == Register &&547X86MCRegisterClasses[X86::VK4RegClassID].contains(getReg());548}549550bool isVK8Pair() const {551return Kind == Register &&552X86MCRegisterClasses[X86::VK8RegClassID].contains(getReg());553}554555bool isVK16Pair() const {556return Kind == Register &&557X86MCRegisterClasses[X86::VK16RegClassID].contains(getReg());558}559560void addExpr(MCInst &Inst, const MCExpr *Expr) const {561// Add as immediates when possible.562if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))563Inst.addOperand(MCOperand::createImm(CE->getValue()));564else565Inst.addOperand(MCOperand::createExpr(Expr));566}567568void addRegOperands(MCInst &Inst, unsigned N) const {569assert(N == 1 && "Invalid number of operands!");570Inst.addOperand(MCOperand::createReg(getReg()));571}572573void addGR32orGR64Operands(MCInst &Inst, unsigned N) const {574assert(N == 1 && "Invalid number of operands!");575MCRegister RegNo = getReg();576if (X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))577RegNo = getX86SubSuperRegister(RegNo, 32);578Inst.addOperand(MCOperand::createReg(RegNo));579}580581void addGR16orGR32orGR64Operands(MCInst &Inst, unsigned N) const {582assert(N == 1 && "Invalid number of operands!");583MCRegister RegNo = getReg();584if (X86MCRegisterClasses[X86::GR32RegClassID].contains(RegNo) ||585X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))586RegNo = getX86SubSuperRegister(RegNo, 16);587Inst.addOperand(MCOperand::createReg(RegNo));588}589590void addAVX512RCOperands(MCInst &Inst, unsigned N) const {591assert(N == 1 && "Invalid number of operands!");592addExpr(Inst, getImm());593}594595void addImmOperands(MCInst &Inst, unsigned N) const {596assert(N == 1 && "Invalid number of operands!");597addExpr(Inst, getImm());598}599600void addMaskPairOperands(MCInst &Inst, unsigned N) const {601assert(N == 1 && "Invalid number of operands!");602unsigned Reg = getReg();603switch (Reg) {604case X86::K0:605case X86::K1:606Reg = X86::K0_K1;607break;608case X86::K2:609case X86::K3:610Reg = X86::K2_K3;611break;612case X86::K4:613case X86::K5:614Reg = X86::K4_K5;615break;616case X86::K6:617case X86::K7:618Reg = X86::K6_K7;619break;620}621Inst.addOperand(MCOperand::createReg(Reg));622}623624void addMemOperands(MCInst &Inst, unsigned N) const {625assert((N == 5) && "Invalid number of operands!");626if (getMemBaseReg())627Inst.addOperand(MCOperand::createReg(getMemBaseReg()));628else629Inst.addOperand(MCOperand::createReg(getMemDefaultBaseReg()));630Inst.addOperand(MCOperand::createImm(getMemScale()));631Inst.addOperand(MCOperand::createReg(getMemIndexReg()));632addExpr(Inst, getMemDisp());633Inst.addOperand(MCOperand::createReg(getMemSegReg()));634}635636void addAbsMemOperands(MCInst &Inst, unsigned N) const {637assert((N == 1) && "Invalid number of operands!");638// Add as immediates when possible.639if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))640Inst.addOperand(MCOperand::createImm(CE->getValue()));641else642Inst.addOperand(MCOperand::createExpr(getMemDisp()));643}644645void addSrcIdxOperands(MCInst &Inst, unsigned N) const {646assert((N == 2) && "Invalid number of operands!");647Inst.addOperand(MCOperand::createReg(getMemBaseReg()));648Inst.addOperand(MCOperand::createReg(getMemSegReg()));649}650651void addDstIdxOperands(MCInst &Inst, unsigned N) const {652assert((N == 1) && "Invalid number of operands!");653Inst.addOperand(MCOperand::createReg(getMemBaseReg()));654}655656void addMemOffsOperands(MCInst &Inst, unsigned N) const {657assert((N == 2) && "Invalid number of operands!");658// Add as immediates when possible.659if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))660Inst.addOperand(MCOperand::createImm(CE->getValue()));661else662Inst.addOperand(MCOperand::createExpr(getMemDisp()));663Inst.addOperand(MCOperand::createReg(getMemSegReg()));664}665666static std::unique_ptr<X86Operand> CreateToken(StringRef Str, SMLoc Loc) {667SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size());668auto Res = std::make_unique<X86Operand>(Token, Loc, EndLoc);669Res->Tok.Data = Str.data();670Res->Tok.Length = Str.size();671return Res;672}673674static std::unique_ptr<X86Operand>675CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc,676bool AddressOf = false, SMLoc OffsetOfLoc = SMLoc(),677StringRef SymName = StringRef(), void *OpDecl = nullptr) {678auto Res = std::make_unique<X86Operand>(Register, StartLoc, EndLoc);679Res->Reg.RegNo = RegNo;680Res->AddressOf = AddressOf;681Res->OffsetOfLoc = OffsetOfLoc;682Res->SymName = SymName;683Res->OpDecl = OpDecl;684return Res;685}686687static std::unique_ptr<X86Operand>688CreateDXReg(SMLoc StartLoc, SMLoc EndLoc) {689return std::make_unique<X86Operand>(DXRegister, StartLoc, EndLoc);690}691692static std::unique_ptr<X86Operand>693CreatePrefix(unsigned Prefixes, SMLoc StartLoc, SMLoc EndLoc) {694auto Res = std::make_unique<X86Operand>(Prefix, StartLoc, EndLoc);695Res->Pref.Prefixes = Prefixes;696return Res;697}698699static std::unique_ptr<X86Operand> CreateImm(const MCExpr *Val,700SMLoc StartLoc, SMLoc EndLoc,701StringRef SymName = StringRef(),702void *OpDecl = nullptr,703bool GlobalRef = true) {704auto Res = std::make_unique<X86Operand>(Immediate, StartLoc, EndLoc);705Res->Imm.Val = Val;706Res->Imm.LocalRef = !GlobalRef;707Res->SymName = SymName;708Res->OpDecl = OpDecl;709Res->AddressOf = true;710return Res;711}712713/// Create an absolute memory operand.714static std::unique_ptr<X86Operand>715CreateMem(unsigned ModeSize, const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc,716unsigned Size = 0, StringRef SymName = StringRef(),717void *OpDecl = nullptr, unsigned FrontendSize = 0,718bool UseUpRegs = false, bool MaybeDirectBranchDest = true) {719auto Res = std::make_unique<X86Operand>(Memory, StartLoc, EndLoc);720Res->Mem.SegReg = 0;721Res->Mem.Disp = Disp;722Res->Mem.BaseReg = 0;723Res->Mem.DefaultBaseReg = 0;724Res->Mem.IndexReg = 0;725Res->Mem.Scale = 1;726Res->Mem.Size = Size;727Res->Mem.ModeSize = ModeSize;728Res->Mem.FrontendSize = FrontendSize;729Res->Mem.MaybeDirectBranchDest = MaybeDirectBranchDest;730Res->UseUpRegs = UseUpRegs;731Res->SymName = SymName;732Res->OpDecl = OpDecl;733Res->AddressOf = false;734return Res;735}736737/// Create a generalized memory operand.738static std::unique_ptr<X86Operand>739CreateMem(unsigned ModeSize, unsigned SegReg, const MCExpr *Disp,740unsigned BaseReg, unsigned IndexReg, unsigned Scale, SMLoc StartLoc,741SMLoc EndLoc, unsigned Size = 0,742unsigned DefaultBaseReg = X86::NoRegister,743StringRef SymName = StringRef(), void *OpDecl = nullptr,744unsigned FrontendSize = 0, bool UseUpRegs = false,745bool MaybeDirectBranchDest = true) {746// We should never just have a displacement, that should be parsed as an747// absolute memory operand.748assert((SegReg || BaseReg || IndexReg || DefaultBaseReg) &&749"Invalid memory operand!");750751// The scale should always be one of {1,2,4,8}.752assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&753"Invalid scale!");754auto Res = std::make_unique<X86Operand>(Memory, StartLoc, EndLoc);755Res->Mem.SegReg = SegReg;756Res->Mem.Disp = Disp;757Res->Mem.BaseReg = BaseReg;758Res->Mem.DefaultBaseReg = DefaultBaseReg;759Res->Mem.IndexReg = IndexReg;760Res->Mem.Scale = Scale;761Res->Mem.Size = Size;762Res->Mem.ModeSize = ModeSize;763Res->Mem.FrontendSize = FrontendSize;764Res->Mem.MaybeDirectBranchDest = MaybeDirectBranchDest;765Res->UseUpRegs = UseUpRegs;766Res->SymName = SymName;767Res->OpDecl = OpDecl;768Res->AddressOf = false;769return Res;770}771};772773} // end namespace llvm774775#endif // LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H776777778